// include: shell.js
// The Module object: Our interface to the outside world. We import
// and export values on it. There are various ways Module can be used:
// 1. Not defined. We create it here
// 2. A function parameter, function(Module) { ..generated code.. }
// 3. pre-run appended it, var Module = {}; ..generated code..
// 4. External script tag defines var Module.
// We need to check if Module already exists (e.g. case 3 above).
// Substitution will be replaced with actual code on later stage of the build,
// this way Closure Compiler will not mangle it (e.g. case 4. above).
// Note that if you want to run closure, and also to use Module
// after the generated code, you will need to define var Module = {};
// before the code. Then that object will be used in the code, and you
// can continue to use Module afterwards as well.
var Module = typeof Module != 'undefined' ? Module : { } ;
// --pre-jses are emitted after the Module integration code, so that they can
// refer to Module (if they choose; they can also define Module)
if ( ! Module . expectedDataFileDownloads ) {
Module . expectedDataFileDownloads = 0 ;
}
Module . expectedDataFileDownloads ++ ;
( function ( ) {
// Do not attempt to redownload the virtual filesystem data when in a pthread or a Wasm Worker context.
if ( Module [ 'ENVIRONMENT_IS_PTHREAD' ] || Module [ '$ww' ] ) return ;
var loadPackage = function ( metadata ) {
var PACKAGE _PATH = '' ;
if ( typeof window === 'object' ) {
PACKAGE _PATH = window [ 'encodeURIComponent' ] ( window . location . pathname . toString ( ) . substring ( 0 , window . location . pathname . toString ( ) . lastIndexOf ( '/' ) ) + '/' ) ;
} else if ( typeof process === 'undefined' && typeof location !== 'undefined' ) {
// web worker
PACKAGE _PATH = encodeURIComponent ( location . pathname . toString ( ) . substring ( 0 , location . pathname . toString ( ) . lastIndexOf ( '/' ) ) + '/' ) ;
}
var PACKAGE _NAME = 'pge.data' ;
var REMOTE _PACKAGE _BASE = 'pge.data' ;
if ( typeof Module [ 'locateFilePackage' ] === 'function' && ! Module [ 'locateFile' ] ) {
Module [ 'locateFile' ] = Module [ 'locateFilePackage' ] ;
err ( 'warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)' ) ;
}
var REMOTE _PACKAGE _NAME = Module [ 'locateFile' ] ? Module [ 'locateFile' ] ( REMOTE _PACKAGE _BASE , '' ) : REMOTE _PACKAGE _BASE ;
var REMOTE _PACKAGE _SIZE = metadata [ 'remote_package_size' ] ;
function fetchRemotePackage ( packageName , packageSize , callback , errback ) {
if ( typeof process === 'object' && typeof process . versions === 'object' && typeof process . versions . node === 'string' ) {
require ( 'fs' ) . readFile ( packageName , function ( err , contents ) {
if ( err ) {
errback ( err ) ;
} else {
callback ( contents . buffer ) ;
}
} ) ;
return ;
}
var xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , packageName , true ) ;
xhr . responseType = 'arraybuffer' ;
xhr . onprogress = function ( event ) {
var url = packageName ;
var size = packageSize ;
if ( event . total ) size = event . total ;
if ( event . loaded ) {
if ( ! xhr . addedTotal ) {
xhr . addedTotal = true ;
if ( ! Module . dataFileDownloads ) Module . dataFileDownloads = { } ;
Module . dataFileDownloads [ url ] = {
loaded : event . loaded ,
total : size
} ;
} else {
Module . dataFileDownloads [ url ] . loaded = event . loaded ;
}
var total = 0 ;
var loaded = 0 ;
var num = 0 ;
for ( var download in Module . dataFileDownloads ) {
var data = Module . dataFileDownloads [ download ] ;
total += data . total ;
loaded += data . loaded ;
num ++ ;
}
total = Math . ceil ( total * Module . expectedDataFileDownloads / num ) ;
if ( Module [ 'setStatus' ] ) Module [ 'setStatus' ] ( ` Downloading data... ( ${ loaded } / ${ total } ) ` ) ;
} else if ( ! Module . dataFileDownloads ) {
if ( Module [ 'setStatus' ] ) Module [ 'setStatus' ] ( 'Downloading data...' ) ;
}
} ;
xhr . onerror = function ( event ) {
throw new Error ( "NetworkError for: " + packageName ) ;
}
xhr . onload = function ( event ) {
if ( xhr . status == 200 || xhr . status == 304 || xhr . status == 206 || ( xhr . status == 0 && xhr . response ) ) { // file URLs can return 0
var packageData = xhr . response ;
callback ( packageData ) ;
} else {
throw new Error ( xhr . statusText + " : " + xhr . responseURL ) ;
}
} ;
xhr . send ( null ) ;
} ;
function handleError ( error ) {
console . error ( 'package error:' , error ) ;
} ;
var fetchedCallback = null ;
var fetched = Module [ 'getPreloadedPackage' ] ? Module [ 'getPreloadedPackage' ] ( REMOTE _PACKAGE _NAME , REMOTE _PACKAGE _SIZE ) : null ;
if ( ! fetched ) fetchRemotePackage ( REMOTE _PACKAGE _NAME , REMOTE _PACKAGE _SIZE , function ( data ) {
if ( fetchedCallback ) {
fetchedCallback ( data ) ;
fetchedCallback = null ;
} else {
fetched = data ;
}
} , handleError ) ;
function runWithFS ( ) {
function assert ( check , msg ) {
if ( ! check ) throw msg + new Error ( ) . stack ;
}
Module [ 'FS_createPath' ] ( "/" , "assets" , true , true ) ;
/** @constructor */
function DataRequest ( start , end , audio ) {
this . start = start ;
this . end = end ;
this . audio = audio ;
}
DataRequest . prototype = {
requests : { } ,
open : function ( mode , name ) {
this . name = name ;
this . requests [ name ] = this ;
Module [ 'addRunDependency' ] ( ` fp ${ this . name } ` ) ;
} ,
send : function ( ) { } ,
onload : function ( ) {
var byteArray = this . byteArray . subarray ( this . start , this . end ) ;
this . finish ( byteArray ) ;
} ,
finish : function ( byteArray ) {
var that = this ;
// canOwn this data in the filesystem, it is a slide into the heap that will never change
Module [ 'FS_createDataFile' ] ( this . name , null , byteArray , true , true , true ) ;
Module [ 'removeRunDependency' ] ( ` fp ${ that . name } ` ) ;
this . requests [ this . name ] = null ;
}
} ;
var files = metadata [ 'files' ] ;
for ( var i = 0 ; i < files . length ; ++ i ) {
new DataRequest ( files [ i ] [ 'start' ] , files [ i ] [ 'end' ] , files [ i ] [ 'audio' ] || 0 ) . open ( 'GET' , files [ i ] [ 'filename' ] ) ;
}
function processPackageData ( arrayBuffer ) {
assert ( arrayBuffer , 'Loading data file failed.' ) ;
assert ( arrayBuffer . constructor . name === ArrayBuffer . name , 'bad input to processPackageData' ) ;
var byteArray = new Uint8Array ( arrayBuffer ) ;
var curr ;
// Reuse the bytearray from the XHR as the source for file reads.
DataRequest . prototype . byteArray = byteArray ;
var files = metadata [ 'files' ] ;
for ( var i = 0 ; i < files . length ; ++ i ) {
DataRequest . prototype . requests [ files [ i ] . filename ] . onload ( ) ;
} Module [ 'removeRunDependency' ] ( 'datafile_pge.data' ) ;
} ;
Module [ 'addRunDependency' ] ( 'datafile_pge.data' ) ;
if ( ! Module . preloadResults ) Module . preloadResults = { } ;
Module . preloadResults [ PACKAGE _NAME ] = { fromCache : false } ;
if ( fetched ) {
processPackageData ( fetched ) ;
fetched = null ;
} else {
fetchedCallback = processPackageData ;
}
}
if ( Module [ 'calledRun' ] ) {
runWithFS ( ) ;
} else {
if ( ! Module [ 'preRun' ] ) Module [ 'preRun' ] = [ ] ;
Module [ "preRun" ] . push ( runWithFS ) ; // FS is not initialized yet, wait for it
}
}
loadPackage ( { "files" : [ { "filename" : "/assets/MAINICON.ico" , "start" : 0 , "end" : 766 } , { "filename" : "/assets/atk.png" , "start" : 766 , "end" : 1443 } , { "filename" : "/assets/attackLine.png" , "start" : 1443 , "end" : 2084 } , { "filename" : "/assets/bit_restorer.png" , "start" : 2084 , "end" : 11632 } , { "filename" : "/assets/corrupter.png" , "start" : 11632 , "end" : 22695 } , { "filename" : "/assets/cosmos.mp3" , "start" : 22695 , "end" : 9174299 , "audio" : 1 } , { "filename" : "/assets/down_arrow.png" , "start" : 9174299 , "end" : 9174940 } , { "filename" : "/assets/gravity.mp3" , "start" : 9174940 , "end" : 16853462 , "audio" : 1 } , { "filename" : "/assets/left_shifter.png" , "start" : 16853462 , "end" : 16862667 } , { "filename" : "/assets/machine2.wav" , "start" : 16862667 , "end" : 16941275 , "audio" : 1 } , { "filename" : "/assets/material.png" , "start" : 16941275 , "end" : 16941970 } , { "filename" : "/assets/memory_collection_point.png" , "start" : 16941970 , "end" : 16942916 } , { "filename" : "/assets/memory_collection_point_highlight.png" , "start" : 16942916 , "end" : 16954993 } , { "filename" : "/assets/memory_swapper.png" , "start" : 16954993 , "end" : 16966443 } , { "filename" : "/assets/minimap_hud.png" , "start" : 16966443 , "end" : 16969901 } , { "filename" : "/assets/outline.png" , "start" : 16969901 , "end" : 16970510 } , { "filename" : "/assets/prc.png" , "start" : 16970510 , "end" : 16979813 } , { "filename" : "/assets/prc_icon.png" , "start" : 16979813 , "end" : 16980565 } , { "filename" : "/assets/ram_bank.png" , "start" : 16980565 , "end" : 16982829 } , { "filename" : "/assets/range_indicator.png" , "start" : 16982829 , "end" : 16991864 } , { "filename" : "/assets/red_x.png" , "start" : 16991864 , "end" : 16992476 } , { "filename" : "/assets/right_shifter.png" , "start" : 16992476 , "end" : 17001700 } , { "filename" : "/assets/rld.png" , "start" : 17001700 , "end" : 17009371 } , { "filename" : "/assets/rld_icon.png" , "start" : 17009371 , "end" : 17010037 } , { "filename" : "/assets/rng.png" , "start" : 17010037 , "end" : 17019169 } , { "filename" : "/assets/rng_icon.png" , "start" : 17019169 , "end" : 17019876 } , { "filename" : "/assets/selection_circle.png" , "start" : 17019876 , "end" : 17020555 } , { "filename" : "/assets/shell.png" , "start" : 17020555 , "end" : 17027429 } , { "filename" : "/assets/sonar.wav" , "start" : 17027429 , "end" : 17283917 , "audio" : 1 } , { "filename" : "/assets/spd.png" , "start" : 17283917 , "end" : 17292459 } , { "filename" : "/assets/spd_icon.png" , "start" : 17292459 , "end" : 17293150 } , { "filename" : "/assets/targetLine.png" , "start" : 17293150 , "end" : 17293772 } , { "filename" : "/assets/tile.png" , "start" : 17293772 , "end" : 17295107 } , { "filename" : "/assets/unit.png" , "start" : 17295107 , "end" : 17295837 } ] , "remote_package_size" : 17295837 } ) ;
} ) ( ) ;
// All the pre-js content up to here must remain later on, we need to run
// it.
if ( Module [ 'ENVIRONMENT_IS_PTHREAD' ] || Module [ '$ww' ] ) Module [ 'preRun' ] = [ ] ;
var necessaryPreJSTasks = Module [ 'preRun' ] . slice ( ) ;
if ( ! Module [ 'preRun' ] ) throw 'Module.preRun should exist because file support used it; did a pre-js delete it?' ;
necessaryPreJSTasks . forEach ( function ( task ) {
if ( Module [ 'preRun' ] . indexOf ( task ) < 0 ) throw 'All preRun tasks that exist before user pre-js code should remain after; did you replace Module or modify Module.preRun?' ;
} ) ;
// Sometimes an existing Module object exists with properties
// meant to overwrite the default module functionality. Here
// we collect those properties and reapply _after_ we configure
// the current environment's defaults to avoid having to be so
// defensive during initialization.
var moduleOverrides = Object . assign ( { } , Module ) ;
var arguments _ = [ ] ;
var thisProgram = './this.program' ;
var quit _ = ( status , toThrow ) => {
throw toThrow ;
} ;
// Determine the runtime environment we are in. You can customize this by
// setting the ENVIRONMENT setting at compile time (see settings.js).
// Attempt to auto-detect the environment
var ENVIRONMENT _IS _WEB = typeof window == 'object' ;
var ENVIRONMENT _IS _WORKER = typeof importScripts == 'function' ;
// N.b. Electron.js environment is simultaneously a NODE-environment, but
// also a web environment.
var ENVIRONMENT _IS _NODE = typeof process == 'object' && typeof process . versions == 'object' && typeof process . versions . node == 'string' ;
var ENVIRONMENT _IS _SHELL = ! ENVIRONMENT _IS _WEB && ! ENVIRONMENT _IS _NODE && ! ENVIRONMENT _IS _WORKER ;
if ( Module [ 'ENVIRONMENT' ] ) {
throw new Error ( 'Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)' ) ;
}
// `/` should be present at the end if `scriptDirectory` is not empty
var scriptDirectory = '' ;
function locateFile ( path ) {
if ( Module [ 'locateFile' ] ) {
return Module [ 'locateFile' ] ( path , scriptDirectory ) ;
}
return scriptDirectory + path ;
}
// Hooks that are implemented differently in different runtime environments.
var read _ ,
readAsync ,
readBinary ,
setWindowTitle ;
if ( ENVIRONMENT _IS _NODE ) {
if ( typeof process == 'undefined' || ! process . release || process . release . name !== 'node' ) throw new Error ( 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' ) ;
var nodeVersion = process . versions . node ;
var numericVersion = nodeVersion . split ( '.' ) . slice ( 0 , 3 ) ;
numericVersion = ( numericVersion [ 0 ] * 10000 ) + ( numericVersion [ 1 ] * 100 ) + ( numericVersion [ 2 ] . split ( '-' ) [ 0 ] * 1 ) ;
var minVersion = 101900 ;
if ( numericVersion < 101900 ) {
throw new Error ( 'This emscripten-generated code requires node v10.19.19.0 (detected v' + nodeVersion + ')' ) ;
}
// `require()` is no-op in an ESM module, use `createRequire()` to construct
// the require()` function. This is only necessary for multi-environment
// builds, `-sENVIRONMENT=node` emits a static import declaration instead.
// TODO: Swap all `require()`'s with `import()`'s?
// These modules will usually be used on Node.js. Load them eagerly to avoid
// the complexity of lazy-loading.
var fs = require ( 'fs' ) ;
var nodePath = require ( 'path' ) ;
if ( ENVIRONMENT _IS _WORKER ) {
scriptDirectory = nodePath . dirname ( scriptDirectory ) + '/' ;
} else {
scriptDirectory = _ _dirname + '/' ;
}
// include: node_shell_read.js
read _ = ( filename , binary ) => {
// We need to re-wrap `file://` strings to URLs. Normalizing isn't
// necessary in that case, the path should already be absolute.
filename = isFileURI ( filename ) ? new URL ( filename ) : nodePath . normalize ( filename ) ;
return fs . readFileSync ( filename , binary ? undefined : 'utf8' ) ;
} ;
readBinary = ( filename ) => {
var ret = read _ ( filename , true ) ;
if ( ! ret . buffer ) {
ret = new Uint8Array ( ret ) ;
}
assert ( ret . buffer ) ;
return ret ;
} ;
readAsync = ( filename , onload , onerror , binary = true ) => {
// See the comment in the `read_` function.
filename = isFileURI ( filename ) ? new URL ( filename ) : nodePath . normalize ( filename ) ;
fs . readFile ( filename , binary ? undefined : 'utf8' , ( err , data ) => {
if ( err ) onerror ( err ) ;
else onload ( binary ? data . buffer : data ) ;
} ) ;
} ;
// end include: node_shell_read.js
if ( ! Module [ 'thisProgram' ] && process . argv . length > 1 ) {
thisProgram = process . argv [ 1 ] . replace ( /\\/g , '/' ) ;
}
arguments _ = process . argv . slice ( 2 ) ;
if ( typeof module != 'undefined' ) {
module [ 'exports' ] = Module ;
}
process . on ( 'uncaughtException' , ( ex ) => {
// suppress ExitStatus exceptions from showing an error
if ( ex !== 'unwind' && ! ( ex instanceof ExitStatus ) && ! ( ex . context instanceof ExitStatus ) ) {
throw ex ;
}
} ) ;
// Without this older versions of node (< v15) will log unhandled rejections
// but return 0, which is not normally the desired behaviour. This is
// not be needed with node v15 and about because it is now the default
// behaviour:
// See https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
var nodeMajor = process . versions . node . split ( "." ) [ 0 ] ;
if ( nodeMajor < 15 ) {
process . on ( 'unhandledRejection' , ( reason ) => { throw reason ; } ) ;
}
quit _ = ( status , toThrow ) => {
process . exitCode = status ;
throw toThrow ;
} ;
Module [ 'inspect' ] = ( ) => '[Emscripten Module object]' ;
} else
if ( ENVIRONMENT _IS _SHELL ) {
if ( ( typeof process == 'object' && typeof require === 'function' ) || typeof window == 'object' || typeof importScripts == 'function' ) throw new Error ( 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' ) ;
if ( typeof read != 'undefined' ) {
read _ = ( f ) => {
return read ( f ) ;
} ;
}
readBinary = ( f ) => {
let data ;
if ( typeof readbuffer == 'function' ) {
return new Uint8Array ( readbuffer ( f ) ) ;
}
data = read ( f , 'binary' ) ;
assert ( typeof data == 'object' ) ;
return data ;
} ;
readAsync = ( f , onload , onerror ) => {
setTimeout ( ( ) => onload ( readBinary ( f ) ) , 0 ) ;
} ;
if ( typeof clearTimeout == 'undefined' ) {
globalThis . clearTimeout = ( id ) => { } ;
}
if ( typeof scriptArgs != 'undefined' ) {
arguments _ = scriptArgs ;
} else if ( typeof arguments != 'undefined' ) {
arguments _ = arguments ;
}
if ( typeof quit == 'function' ) {
quit _ = ( status , toThrow ) => {
// Unlike node which has process.exitCode, d8 has no such mechanism. So we
// have no way to set the exit code and then let the program exit with
// that code when it naturally stops running (say, when all setTimeouts
// have completed). For that reason, we must call `quit` - the only way to
// set the exit code - but quit also halts immediately. To increase
// consistency with node (and the web) we schedule the actual quit call
// using a setTimeout to give the current stack and any exception handlers
// a chance to run. This enables features such as addOnPostRun (which
// expected to be able to run code after main returns).
setTimeout ( ( ) => {
if ( ! ( toThrow instanceof ExitStatus ) ) {
let toLog = toThrow ;
if ( toThrow && typeof toThrow == 'object' && toThrow . stack ) {
toLog = [ toThrow , toThrow . stack ] ;
}
err ( ` exiting due to exception: ${ toLog } ` ) ;
}
quit ( status ) ;
} ) ;
throw toThrow ;
} ;
}
if ( typeof print != 'undefined' ) {
// Prefer to use print/printErr where they exist, as they usually work better.
if ( typeof console == 'undefined' ) console = /** @type{!Console} */ ( { } ) ;
console . log = /** @type{!function(this:Console, ...*): undefined} */ ( print ) ;
console . warn = console . error = /** @type{!function(this:Console, ...*): undefined} */ ( typeof printErr != 'undefined' ? printErr : print ) ;
}
} else
// Note that this includes Node.js workers when relevant (pthreads is enabled).
// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
// ENVIRONMENT_IS_NODE.
if ( ENVIRONMENT _IS _WEB || ENVIRONMENT _IS _WORKER ) {
if ( ENVIRONMENT _IS _WORKER ) { // Check worker, not web, since window could be polyfilled
scriptDirectory = self . location . href ;
} else if ( typeof document != 'undefined' && document . currentScript ) { // web
scriptDirectory = document . currentScript . src ;
}
// blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
// otherwise, slice off the final part of the url to find the script directory.
// if scriptDirectory does not contain a slash, lastIndexOf will return -1,
// and scriptDirectory will correctly be replaced with an empty string.
// If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
// they are removed because they could contain a slash.
if ( scriptDirectory . indexOf ( 'blob:' ) !== 0 ) {
scriptDirectory = scriptDirectory . substr ( 0 , scriptDirectory . replace ( /[?#].*/ , "" ) . lastIndexOf ( '/' ) + 1 ) ;
} else {
scriptDirectory = '' ;
}
if ( ! ( typeof window == 'object' || typeof importScripts == 'function' ) ) throw new Error ( 'not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)' ) ;
// Differentiate the Web Worker from the Node Worker case, as reading must
// be done differently.
{
// include: web_or_worker_shell_read.js
read _ = ( url ) => {
var xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , url , false ) ;
xhr . send ( null ) ;
return xhr . responseText ;
}
if ( ENVIRONMENT _IS _WORKER ) {
readBinary = ( url ) => {
var xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , url , false ) ;
xhr . responseType = 'arraybuffer' ;
xhr . send ( null ) ;
return new Uint8Array ( /** @type{!ArrayBuffer} */ ( xhr . response ) ) ;
} ;
}
readAsync = ( url , onload , onerror ) => {
var xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , url , true ) ;
xhr . responseType = 'arraybuffer' ;
xhr . onload = ( ) => {
if ( xhr . status == 200 || ( xhr . status == 0 && xhr . response ) ) { // file URLs can return 0
onload ( xhr . response ) ;
return ;
}
onerror ( ) ;
} ;
xhr . onerror = onerror ;
xhr . send ( null ) ;
}
// end include: web_or_worker_shell_read.js
}
setWindowTitle = ( title ) => document . title = title ;
} else
{
throw new Error ( 'environment detection error' ) ;
}
var out = Module [ 'print' ] || console . log . bind ( console ) ;
var err = Module [ 'printErr' ] || console . error . bind ( console ) ;
// Merge back in the overrides
Object . assign ( Module , moduleOverrides ) ;
// Free the object hierarchy contained in the overrides, this lets the GC
// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
moduleOverrides = null ;
checkIncomingModuleAPI ( ) ;
// Emit code to handle expected values on the Module object. This applies Module.x
// to the proper local x. This has two benefits: first, we only emit it if it is
// expected to arrive, and second, by using a local everywhere else that can be
// minified.
if ( Module [ 'arguments' ] ) arguments _ = Module [ 'arguments' ] ; legacyModuleProp ( 'arguments' , 'arguments_' ) ;
if ( Module [ 'thisProgram' ] ) thisProgram = Module [ 'thisProgram' ] ; legacyModuleProp ( 'thisProgram' , 'thisProgram' ) ;
if ( Module [ 'quit' ] ) quit _ = Module [ 'quit' ] ; legacyModuleProp ( 'quit' , 'quit_' ) ;
// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
// Assertions on removed incoming Module JS APIs.
assert ( typeof Module [ 'memoryInitializerPrefixURL' ] == 'undefined' , 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead' ) ;
assert ( typeof Module [ 'pthreadMainPrefixURL' ] == 'undefined' , 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead' ) ;
assert ( typeof Module [ 'cdInitializerPrefixURL' ] == 'undefined' , 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead' ) ;
assert ( typeof Module [ 'filePackagePrefixURL' ] == 'undefined' , 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead' ) ;
assert ( typeof Module [ 'read' ] == 'undefined' , 'Module.read option was removed (modify read_ in JS)' ) ;
assert ( typeof Module [ 'readAsync' ] == 'undefined' , 'Module.readAsync option was removed (modify readAsync in JS)' ) ;
assert ( typeof Module [ 'readBinary' ] == 'undefined' , 'Module.readBinary option was removed (modify readBinary in JS)' ) ;
assert ( typeof Module [ 'setWindowTitle' ] == 'undefined' , 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)' ) ;
assert ( typeof Module [ 'TOTAL_MEMORY' ] == 'undefined' , 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY' ) ;
legacyModuleProp ( 'read' , 'read_' ) ;
legacyModuleProp ( 'readAsync' , 'readAsync' ) ;
legacyModuleProp ( 'readBinary' , 'readBinary' ) ;
legacyModuleProp ( 'setWindowTitle' , 'setWindowTitle' ) ;
var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js' ;
var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js' ;
var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js' ;
var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js' ;
assert ( ! ENVIRONMENT _IS _SHELL , "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable." ) ;
// end include: shell.js
// include: preamble.js
// === Preamble library stuff ===
// Documentation for the public APIs defined in this file must be updated in:
// site/source/docs/api_reference/preamble.js.rst
// A prebuilt local version of the documentation is available at:
// site/build/text/docs/api_reference/preamble.js.txt
// You can also build docs locally as HTML or other formats in site/
// An online HTML version (which may be of a different version of Emscripten)
// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
var wasmBinary ;
if ( Module [ 'wasmBinary' ] ) wasmBinary = Module [ 'wasmBinary' ] ; legacyModuleProp ( 'wasmBinary' , 'wasmBinary' ) ;
var noExitRuntime = Module [ 'noExitRuntime' ] || true ; legacyModuleProp ( 'noExitRuntime' , 'noExitRuntime' ) ;
if ( typeof WebAssembly != 'object' ) {
abort ( 'no native wasm support detected' ) ;
}
// Wasm globals
var wasmMemory ;
//========================================
// Runtime essentials
//========================================
// whether we are quitting the application. no code should run after this.
// set in exit() and abort()
var ABORT = false ;
// set by exit() and abort(). Passed to 'onExit' handler.
// NOTE: This is also used as the process return code code in shell environments
// but only when noExitRuntime is false.
var EXITSTATUS ;
/** @type {function(*, string=)} */
function assert ( condition , text ) {
if ( ! condition ) {
abort ( 'Assertion failed' + ( text ? ': ' + text : '' ) ) ;
}
}
// We used to include malloc/free by default in the past. Show a helpful error in
// builds with assertions.
// Memory management
var HEAP ,
/** @type {!Int8Array} */
HEAP8 ,
/** @type {!Uint8Array} */
HEAPU8 ,
/** @type {!Int16Array} */
HEAP16 ,
/** @type {!Uint16Array} */
HEAPU16 ,
/** @type {!Int32Array} */
HEAP32 ,
/** @type {!Uint32Array} */
HEAPU32 ,
/** @type {!Float32Array} */
HEAPF32 ,
/** @type {!Float64Array} */
HEAPF64 ;
function updateMemoryViews ( ) {
var b = wasmMemory . buffer ;
Module [ 'HEAP8' ] = HEAP8 = new Int8Array ( b ) ;
Module [ 'HEAP16' ] = HEAP16 = new Int16Array ( b ) ;
Module [ 'HEAP32' ] = HEAP32 = new Int32Array ( b ) ;
Module [ 'HEAPU8' ] = HEAPU8 = new Uint8Array ( b ) ;
Module [ 'HEAPU16' ] = HEAPU16 = new Uint16Array ( b ) ;
Module [ 'HEAPU32' ] = HEAPU32 = new Uint32Array ( b ) ;
Module [ 'HEAPF32' ] = HEAPF32 = new Float32Array ( b ) ;
Module [ 'HEAPF64' ] = HEAPF64 = new Float64Array ( b ) ;
}
assert ( ! Module [ 'STACK_SIZE' ] , 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time' )
assert ( typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array . prototype . subarray != undefined && Int32Array . prototype . set != undefined ,
'JS engine does not provide full typed array support' ) ;
// If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY
assert ( ! Module [ 'wasmMemory' ] , 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally' ) ;
assert ( ! Module [ 'INITIAL_MEMORY' ] , 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically' ) ;
// include: runtime_init_table.js
// In regular non-RELOCATABLE mode the table is exported
// from the wasm module and this will be assigned once
// the exports are available.
var wasmTable ;
// end include: runtime_init_table.js
// include: runtime_stack_check.js
// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
function writeStackCookie ( ) {
var max = _emscripten _stack _get _end ( ) ;
assert ( ( max & 3 ) == 0 ) ;
// If the stack ends at address zero we write our cookies 4 bytes into the
// stack. This prevents interference with the (separate) address-zero check
// below.
if ( max == 0 ) {
max += 4 ;
}
// The stack grow downwards towards _emscripten_stack_get_end.
// We write cookies to the final two words in the stack and detect if they are
// ever overwritten.
HEAPU32 [ ( ( max ) >> 2 ) ] = 0x02135467 ;
HEAPU32 [ ( ( ( max ) + ( 4 ) ) >> 2 ) ] = 0x89BACDFE ;
// Also test the global address 0 for integrity.
HEAPU32 [ 0 ] = 0x63736d65 ; /* 'emsc' */
}
function checkStackCookie ( ) {
if ( ABORT ) return ;
var max = _emscripten _stack _get _end ( ) ;
// See writeStackCookie().
if ( max == 0 ) {
max += 4 ;
}
var cookie1 = HEAPU32 [ ( ( max ) >> 2 ) ] ;
var cookie2 = HEAPU32 [ ( ( ( max ) + ( 4 ) ) >> 2 ) ] ;
if ( cookie1 != 0x02135467 || cookie2 != 0x89BACDFE ) {
abort ( ` Stack overflow! Stack cookie has been overwritten at ${ ptrToString ( max ) } , expected hex dwords 0x89BACDFE and 0x2135467, but received ${ ptrToString ( cookie2 ) } ${ ptrToString ( cookie1 ) } ` ) ;
}
// Also test the global address 0 for integrity.
if ( HEAPU32 [ 0 ] !== 0x63736d65 /* 'emsc' */ ) {
abort ( 'Runtime error: The application has corrupted its heap memory area (address zero)!' ) ;
}
}
// end include: runtime_stack_check.js
// include: runtime_assertions.js
// Endianness check
( function ( ) {
var h16 = new Int16Array ( 1 ) ;
var h8 = new Int8Array ( h16 . buffer ) ;
h16 [ 0 ] = 0x6373 ;
if ( h8 [ 0 ] !== 0x73 || h8 [ 1 ] !== 0x63 ) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)' ;
} ) ( ) ;
// end include: runtime_assertions.js
var _ _ATPRERUN _ _ = [ ] ; // functions called before the runtime is initialized
var _ _ATINIT _ _ = [ ] ; // functions called during startup
var _ _ATMAIN _ _ = [ ] ; // functions called when main() is to be run
var _ _ATEXIT _ _ = [ ] ; // functions called during shutdown
var _ _ATPOSTRUN _ _ = [ ] ; // functions called after the main() is called
var runtimeInitialized = false ;
var runtimeKeepaliveCounter = 0 ;
function keepRuntimeAlive ( ) {
return noExitRuntime || runtimeKeepaliveCounter > 0 ;
}
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 ( ) {
assert ( ! runtimeInitialized ) ;
runtimeInitialized = true ;
checkStackCookie ( ) ;
if ( ! Module [ "noFSInit" ] && ! FS . init . initialized )
FS . init ( ) ;
FS . ignorePermissions = false ;
TTY . init ( ) ;
callRuntimeCallbacks ( _ _ATINIT _ _ ) ;
}
function preMain ( ) {
checkStackCookie ( ) ;
callRuntimeCallbacks ( _ _ATMAIN _ _ ) ;
}
function postRun ( ) {
checkStackCookie ( ) ;
if ( Module [ 'postRun' ] ) {
if ( typeof Module [ 'postRun' ] == 'function' ) Module [ 'postRun' ] = [ Module [ 'postRun' ] ] ;
while ( Module [ 'postRun' ] . length ) {
addOnPostRun ( Module [ 'postRun' ] . shift ( ) ) ;
}
}
callRuntimeCallbacks ( _ _ATPOSTRUN _ _ ) ;
}
function addOnPreRun ( cb ) {
_ _ATPRERUN _ _ . unshift ( cb ) ;
}
function addOnInit ( cb ) {
_ _ATINIT _ _ . unshift ( cb ) ;
}
function addOnPreMain ( cb ) {
_ _ATMAIN _ _ . unshift ( cb ) ;
}
function addOnExit ( cb ) {
}
function addOnPostRun ( cb ) {
_ _ATPOSTRUN _ _ . unshift ( cb ) ;
}
// include: runtime_math.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
assert ( Math . imul , 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' ) ;
assert ( Math . fround , 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' ) ;
assert ( Math . clz32 , 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' ) ;
assert ( Math . trunc , 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill' ) ;
// end include: runtime_math.js
// A counter of dependencies for calling run(). If we need to
// do asynchronous work before running, increment this and
// decrement it. Incrementing must happen in a place like
// Module.preRun (used by emcc to add file preloading).
// Note that you can add dependencies in preRun, even though
// it happens right before run - run will be postponed until
// the dependencies are met.
var runDependencies = 0 ;
var runDependencyWatcher = null ;
var dependenciesFulfilled = null ; // overridden to take different actions when all run dependencies are fulfilled
var runDependencyTracking = { } ;
function getUniqueRunDependency ( id ) {
var orig = id ;
while ( 1 ) {
if ( ! runDependencyTracking [ id ] ) return id ;
id = orig + Math . random ( ) ;
}
}
function addRunDependency ( id ) {
runDependencies ++ ;
if ( Module [ 'monitorRunDependencies' ] ) {
Module [ 'monitorRunDependencies' ] ( runDependencies ) ;
}
if ( id ) {
assert ( ! runDependencyTracking [ id ] ) ;
runDependencyTracking [ id ] = 1 ;
if ( runDependencyWatcher === null && typeof setInterval != 'undefined' ) {
// Check for missing dependencies every few seconds
runDependencyWatcher = setInterval ( ( ) => {
if ( ABORT ) {
clearInterval ( runDependencyWatcher ) ;
runDependencyWatcher = null ;
return ;
}
var shown = false ;
for ( var dep in runDependencyTracking ) {
if ( ! shown ) {
shown = true ;
err ( 'still waiting on run dependencies:' ) ;
}
err ( 'dependency: ' + dep ) ;
}
if ( shown ) {
err ( '(end of list)' ) ;
}
} , 10000 ) ;
}
} else {
err ( 'warning: run dependency added without ID' ) ;
}
}
function removeRunDependency ( id ) {
runDependencies -- ;
if ( Module [ 'monitorRunDependencies' ] ) {
Module [ 'monitorRunDependencies' ] ( runDependencies ) ;
}
if ( id ) {
assert ( runDependencyTracking [ id ] ) ;
delete runDependencyTracking [ id ] ;
} else {
err ( 'warning: run dependency removed without ID' ) ;
}
if ( runDependencies == 0 ) {
if ( runDependencyWatcher !== null ) {
clearInterval ( runDependencyWatcher ) ;
runDependencyWatcher = null ;
}
if ( dependenciesFulfilled ) {
var callback = dependenciesFulfilled ;
dependenciesFulfilled = null ;
callback ( ) ; // can add another dependenciesFulfilled
}
}
}
/** @param {string|number=} what */
function abort ( what ) {
if ( Module [ 'onAbort' ] ) {
Module [ 'onAbort' ] ( what ) ;
}
what = 'Aborted(' + what + ')' ;
// TODO(sbc): Should we remove printing and leave it up to whoever
// catches the exception?
err ( what ) ;
ABORT = true ;
EXITSTATUS = 1 ;
// Use a wasm runtime error, because a JS error might be seen as a foreign
// exception, which means we'd run destructors on it. We need the error to
// simply make the program stop.
// FIXME This approach does not work in Wasm EH because it currently does not assume
// all RuntimeErrors are from traps; it decides whether a RuntimeError is from
// a trap or not based on a hidden field within the object. So at the moment
// we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
// allows this in the wasm spec.
// Suppress closure compiler warning here. Closure compiler's builtin extern
// defintion for WebAssembly.RuntimeError claims it takes no arguments even
// though it can.
// TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
/** @suppress {checkTypes} */
var e = new WebAssembly . RuntimeError ( what ) ;
// Throw the error whether or not MODULARIZE is set because abort is used
// in code paths apart from instantiation where an exception is expected
// to be thrown when abort is called.
throw e ;
}
// include: memoryprofiler.js
// end include: memoryprofiler.js
// include: URIUtils.js
// Prefix of data URIs emitted by SINGLE_FILE and related options.
var dataURIPrefix = 'data:application/octet-stream;base64,' ;
// Indicates whether filename is a base64 data URI.
function isDataURI ( filename ) {
// Prefix of data URIs emitted by SINGLE_FILE and related options.
return filename . startsWith ( dataURIPrefix ) ;
}
// Indicates whether filename is delivered via file protocol (as opposed to http/https)
function isFileURI ( filename ) {
return filename . startsWith ( 'file://' ) ;
}
// end include: URIUtils.js
/** @param {boolean=} fixedasm */
function createExportWrapper ( name , fixedasm ) {
return function ( ) {
var displayName = name ;
var asm = fixedasm ;
if ( ! fixedasm ) {
asm = Module [ 'asm' ] ;
}
assert ( runtimeInitialized , 'native function `' + displayName + '` called before runtime initialization' ) ;
if ( ! asm [ name ] ) {
assert ( asm [ name ] , 'exported native function `' + displayName + '` not found' ) ;
}
return asm [ name ] . apply ( null , arguments ) ;
} ;
}
// include: runtime_exceptions.js
// end include: runtime_exceptions.js
var wasmBinaryFile ;
wasmBinaryFile = 'pge.wasm' ;
if ( ! isDataURI ( wasmBinaryFile ) ) {
wasmBinaryFile = locateFile ( wasmBinaryFile ) ;
}
function getBinary ( file ) {
try {
if ( file == wasmBinaryFile && wasmBinary ) {
return new Uint8Array ( wasmBinary ) ;
}
if ( readBinary ) {
return readBinary ( file ) ;
}
throw "both async and sync fetching of the wasm failed" ;
}
catch ( err ) {
abort ( err ) ;
}
}
function getBinaryPromise ( binaryFile ) {
// If we don't have the binary yet, try to load it asynchronously.
// Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
// See https://github.com/github/fetch/pull/92#issuecomment-140665932
// Cordova or Electron apps are typically loaded from a file:// url.
// So use fetch if it is available and the url is not a file, otherwise fall back to XHR.
if ( ! wasmBinary && ( ENVIRONMENT _IS _WEB || ENVIRONMENT _IS _WORKER ) ) {
if ( typeof fetch == 'function'
&& ! isFileURI ( binaryFile )
) {
return fetch ( binaryFile , { credentials : 'same-origin' } ) . then ( ( response ) => {
if ( ! response [ 'ok' ] ) {
throw "failed to load wasm binary file at '" + binaryFile + "'" ;
}
return response [ 'arrayBuffer' ] ( ) ;
} ) . catch ( ( ) => getBinary ( binaryFile ) ) ;
}
else {
if ( readAsync ) {
// fetch is not available or url is file => try XHR (readAsync uses XHR internally)
return new Promise ( ( resolve , reject ) => {
readAsync ( binaryFile , ( response ) => resolve ( new Uint8Array ( /** @type{!ArrayBuffer} */ ( response ) ) ) , reject )
} ) ;
}
}
}
// Otherwise, getBinary should be able to get it synchronously
return Promise . resolve ( ) . then ( ( ) => getBinary ( binaryFile ) ) ;
}
function instantiateArrayBuffer ( binaryFile , imports , receiver ) {
return getBinaryPromise ( binaryFile ) . then ( ( binary ) => {
return WebAssembly . instantiate ( binary , imports ) ;
} ) . then ( ( instance ) => {
return instance ;
} ) . then ( receiver , ( reason ) => {
err ( 'failed to asynchronously prepare wasm: ' + reason ) ;
// Warn on some common problems.
if ( isFileURI ( wasmBinaryFile ) ) {
err ( 'warning: Loading from a file URI (' + wasmBinaryFile + ') is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing' ) ;
}
abort ( reason ) ;
} ) ;
}
function instantiateAsync ( binary , binaryFile , imports , callback ) {
if ( ! binary &&
typeof WebAssembly . instantiateStreaming == 'function' &&
! isDataURI ( binaryFile ) &&
// Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
! isFileURI ( binaryFile ) &&
// Avoid instantiateStreaming() on Node.js environment for now, as while
// Node.js v18.1.0 implements it, it does not have a full fetch()
// implementation yet.
//
// Reference:
// https://github.com/emscripten-core/emscripten/pull/16917
! ENVIRONMENT _IS _NODE &&
typeof fetch == 'function' ) {
return fetch ( binaryFile , { credentials : 'same-origin' } ) . then ( ( response ) => {
// Suppress closure warning here since the upstream definition for
// instantiateStreaming only allows Promise<Repsponse> rather than
// an actual Response.
// TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
/** @suppress {checkTypes} */
var result = WebAssembly . instantiateStreaming ( response , imports ) ;
return result . then (
callback ,
function ( reason ) {
// We expect the most common failure cause to be a bad MIME type for the binary,
// in which case falling back to ArrayBuffer instantiation should work.
err ( 'wasm streaming compile failed: ' + reason ) ;
err ( 'falling back to ArrayBuffer instantiation' ) ;
return instantiateArrayBuffer ( binaryFile , imports , callback ) ;
} ) ;
} ) ;
} else {
return instantiateArrayBuffer ( binaryFile , imports , callback ) ;
}
}
// Create the wasm instance.
// Receives the wasm imports, returns the exports.
function createWasm ( ) {
// prepare imports
var info = {
'env' : wasmImports ,
'wasi_snapshot_preview1' : wasmImports ,
} ;
// Load the wasm module and create an instance of using native support in the JS engine.
// handle a generated wasm instance, receiving its exports and
// performing other necessary setup
/** @param {WebAssembly.Module=} module*/
function receiveInstance ( instance , module ) {
var exports = instance . exports ;
Module [ 'asm' ] = exports ;
wasmMemory = Module [ 'asm' ] [ 'memory' ] ;
assert ( wasmMemory , "memory not found in wasm exports" ) ;
// This assertion doesn't hold when emscripten is run in --post-link
// mode.
// TODO(sbc): Read INITIAL_MEMORY out of the wasm file in post-link mode.
//assert(wasmMemory.buffer.byteLength === 16777216);
updateMemoryViews ( ) ;
wasmTable = Module [ 'asm' ] [ '__indirect_function_table' ] ;
assert ( wasmTable , "table not found in wasm exports" ) ;
addOnInit ( Module [ 'asm' ] [ '__wasm_call_ctors' ] ) ;
removeRunDependency ( 'wasm-instantiate' ) ;
return exports ;
}
// wait for the pthread pool (if any)
addRunDependency ( 'wasm-instantiate' ) ;
// Prefer streaming instantiation if available.
// Async compilation can be confusing when an error on the page overwrites Module
// (for example, if the order of elements is wrong, and the one defining Module is
// later), so we save Module and check it later.
var trueModule = Module ;
function receiveInstantiationResult ( result ) {
// 'result' is a ResultObject object which has both the module and instance.
// receiveInstance() will swap in the exports (to Module.asm) so they can be called
assert ( Module === trueModule , 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?' ) ;
trueModule = null ;
// TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
// When the regression is fixed, can restore the above PTHREADS-enabled path.
receiveInstance ( result [ 'instance' ] ) ;
}
// User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
// to manually instantiate the Wasm module themselves. This allows pages to
// run the instantiation parallel to any other async startup actions they are
// performing.
// Also pthreads and wasm workers initialize the wasm instance through this
// path.
if ( Module [ 'instantiateWasm' ] ) {
try {
return Module [ 'instantiateWasm' ] ( info , receiveInstance ) ;
} catch ( e ) {
err ( 'Module.instantiateWasm callback failed with error: ' + e ) ;
return false ;
}
}
instantiateAsync ( wasmBinary , wasmBinaryFile , info , receiveInstantiationResult ) ;
return { } ; // no exports yet; we'll fill them in later
}
// Globals used by JS i64 conversions (see makeSetValue)
var tempDouble ;
var tempI64 ;
// include: runtime_debug.js
function legacyModuleProp ( prop , newName ) {
if ( ! Object . getOwnPropertyDescriptor ( Module , prop ) ) {
Object . defineProperty ( Module , prop , {
configurable : true ,
get : function ( ) {
abort ( 'Module.' + prop + ' has been replaced with plain ' + newName + ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)' ) ;
}
} ) ;
}
}
function ignoredModuleProp ( prop ) {
if ( Object . getOwnPropertyDescriptor ( Module , prop ) ) {
abort ( '`Module.' + prop + '` was supplied but `' + prop + '` not included in INCOMING_MODULE_JS_API' ) ;
}
}
// forcing the filesystem exports a few things by default
function isExportedByForceFilesystem ( name ) {
return name === 'FS_createPath' ||
name === 'FS_createDataFile' ||
name === 'FS_createPreloadedFile' ||
name === 'FS_unlink' ||
name === 'addRunDependency' ||
// The old FS has some functionality that WasmFS lacks.
name === 'FS_createLazyFile' ||
name === 'FS_createDevice' ||
name === 'removeRunDependency' ;
}
function missingGlobal ( sym , msg ) {
if ( typeof globalThis !== 'undefined' ) {
Object . defineProperty ( globalThis , sym , {
configurable : true ,
get : function ( ) {
warnOnce ( '`' + sym + '` is not longer defined by emscripten. ' + msg ) ;
return undefined ;
}
} ) ;
}
}
missingGlobal ( 'buffer' , 'Please use HEAP8.buffer or wasmMemory.buffer' ) ;
function missingLibrarySymbol ( sym ) {
if ( typeof globalThis !== 'undefined' && ! Object . getOwnPropertyDescriptor ( globalThis , sym ) ) {
Object . defineProperty ( globalThis , sym , {
configurable : true ,
get : function ( ) {
// Can't `abort()` here because it would break code that does runtime
// checks. e.g. `if (typeof SDL === 'undefined')`.
var msg = '`' + sym + '` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line' ;
// DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
// library.js, which means $name for a JS name with no prefix, or name
// for a JS name like _name.
var librarySymbol = sym ;
if ( ! librarySymbol . startsWith ( '_' ) ) {
librarySymbol = '$' + sym ;
}
msg += " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=" + librarySymbol + ")" ;
if ( isExportedByForceFilesystem ( sym ) ) {
msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you' ;
}
warnOnce ( msg ) ;
return undefined ;
}
} ) ;
}
// Any symbol that is not included from the JS libary is also (by definition)
// not exported on the Module object.
unexportedRuntimeSymbol ( sym ) ;
}
function unexportedRuntimeSymbol ( sym ) {
if ( ! Object . getOwnPropertyDescriptor ( Module , sym ) ) {
Object . defineProperty ( Module , sym , {
configurable : true ,
get : function ( ) {
var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)" ;
if ( isExportedByForceFilesystem ( sym ) ) {
msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you' ;
}
abort ( msg ) ;
}
} ) ;
}
}
// Used by XXXXX_DEBUG settings to output debug messages.
function dbg ( text ) {
// TODO(sbc): Make this configurable somehow. Its not always convenient for
// logging to show up as warnings.
console . warn . apply ( console , arguments ) ;
}
// end include: runtime_debug.js
// === Body ===
var ASM _CONSTS = {
5371644 : ( ) => { return Module . canvas . getBoundingClientRect ( ) . left } ,
5371696 : ( ) => { return Module . canvas . getBoundingClientRect ( ) . top } ,
5371747 : ( ) => { return Module . olc _MOUSEX ; } ,
5371775 : ( ) => { return Module . olc _MOUSEY ; } ,
5371803 : ( ) => { return Module . olc _MOUSEDOWN } ,
5371833 : ( ) => { return Module . olc _MOUSEUP } ,
5371861 : ( ) => { Module . olc _MOUSEDOWN = - 1 } ,
5371887 : ( ) => { Module . olc _MOUSEUP = - 1 } ,
5371911 : ( ) => { window . onunload = Module . _olc _OnPageUnload ; } ,
5371955 : ( $0 , $1 ) => { Module . olc _AspectRatio = $0 / $1 ; Module . olc _MOUSEDOWN = - 1 ; Module . olc _MOUSEUP = - 1 ; onmousemove = function ( e ) { Module . olc _MOUSEX = e . clientX ; Module . olc _MOUSEY = e . clientY ; } ; onmousedown = function ( e ) { Module . olc _MOUSEDOWN = e . button ; } ; onmouseup = function ( e ) { Module . olc _MOUSEUP = e . button ; } ; ontouchmove = function ( e ) { Module . olc _MOUSEX = e . touches [ 0 ] . clientX ; Module . olc _MOUSEY = e . touches [ 0 ] . clientY ; } ; ontouchstart = function ( e ) { Module . olc _MOUSEX = e . touches [ 0 ] . clientX ; Module . olc _MOUSEY = e . touches [ 0 ] . clientY ; } ; Module . olc _AssumeDefaultShells = ( document . querySelectorAll ( '.emscripten' ) . length >= 3 ) ? true : false ; var olc _ResizeHandler = function ( ) { let isFullscreen = ( document . fullscreenElement != null ) ; let width = ( isFullscreen ) ? window . innerWidth : Module . canvas . parentNode . clientWidth ; let height = ( isFullscreen ) ? window . innerHeight : Module . canvas . parentNode . clientHeight ; let viewWidth = width ; let viewHeight = width / Module . olc _AspectRatio ; if ( viewHeight > height ) { viewWidth = height * Module . olc _AspectRatio ; viewHeight = height ; } viewWidth = parseInt ( viewWidth ) ; viewHeight = parseInt ( viewHeight ) ; setTimeout ( function ( ) { if ( Module . olc _AssumeDefaultShells ) Module . canvas . parentNode . setAttribute ( 'style' , 'width: 100%; height: 70vh; margin-left: auto; margin-right: auto;' ) ; Module . canvas . setAttribute ( 'width' , viewWidth ) ; Module . canvas . setAttribute ( 'height' , viewHeight ) ; Module . canvas . setAttribute ( 'style' , ` width: ${ viewWidth } px; height: ${ viewHeight } px; ` ) ; Module . _olc _PGE _UpdateWindowSize ( viewWidth , viewHeight ) ; Module . canvas . focus ( ) ; } , 200 ) ; } ; var olc _Init = function ( ) { if ( Module . olc _AspectRatio === undefined ) { setTimeout ( function ( ) { Module . olc _Init ( ) ; } , 50 ) ; return ; } let resizeObserver = new ResizeObserver ( function ( entries ) { Module . olc _ResizeHandler ( ) ; } ) . observe ( Module . canvas . parentNode ) ; let mutationObserver = new MutationObserver ( function ( mutationsList , observer ) { setTimeout ( function ( ) { Module . olc _ResizeHandler ( ) ; } , 200 ) ; } ) . observe ( Module . canvas . parentNode , { attributes : false , childList : true , subtree : false } ) ; window . addEventListener ( 'fullscreenchange' , function ( e ) { setTimeout ( function ( ) { Module . olc _ResizeHandler ( ) ; } , 200 ) ; } ) ; } ; Module . olc _ResizeHandler = ( Module . olc _ResizeHandler != undefined ) ? Module . olc _ResizeHandler : olc _ResizeHandler ; Module . olc _Init = ( Module . olc _Init != undefined ) ? Module . olc _Init : olc _Init ; Module . olc _Init ( ) ; } ,
5374349 : ( ) => { if ( typeof ( AudioContext ) !== 'undefined' ) { return true ; } else if ( typeof ( webkitAudioContext ) !== 'undefined' ) { return true ; } return false ; } ,
5374496 : ( ) => { if ( ( typeof ( navigator . mediaDevices ) !== 'undefined' ) && ( typeof ( navigator . mediaDevices . getUserMedia ) !== 'undefined' ) ) { return true ; } else if ( typeof ( navigator . webkitGetUserMedia ) !== 'undefined' ) { return true ; } return false ; } ,
5374730 : ( $0 ) => { if ( typeof ( Module [ 'SDL2' ] ) === 'undefined' ) { Module [ 'SDL2' ] = { } ; } var SDL2 = Module [ 'SDL2' ] ; if ( ! $0 ) { SDL2 . audio = { } ; } else { SDL2 . capture = { } ; } if ( ! SDL2 . audioContext ) { if ( typeof ( AudioContext ) !== 'undefined' ) { SDL2 . audioContext = new AudioContext ( ) ; } else if ( typeof ( webkitAudioContext ) !== 'undefined' ) { SDL2 . audioContext = new webkitAudioContext ( ) ; } if ( SDL2 . audioContext ) { autoResumeAudioContext ( SDL2 . audioContext ) ; } } return SDL2 . audioContext === undefined ? - 1 : 0 ; } ,
5375223 : ( ) => { var SDL2 = Module [ 'SDL2' ] ; return SDL2 . audioContext . sampleRate ; } ,
5375291 : ( $0 , $1 , $2 , $3 ) => { var SDL2 = Module [ 'SDL2' ] ; var have _microphone = function ( stream ) { if ( SDL2 . capture . silenceTimer !== undefined ) { clearTimeout ( SDL2 . capture . silenceTimer ) ; SDL2 . capture . silenceTimer = undefined ; } SDL2 . capture . mediaStreamNode = SDL2 . audioContext . createMediaStreamSource ( stream ) ; SDL2 . capture . scriptProcessorNode = SDL2 . audioContext . createScriptProcessor ( $1 , $0 , 1 ) ; SDL2 . capture . scriptProcessorNode . onaudioprocess = function ( audioProcessingEvent ) { if ( ( SDL2 === undefined ) || ( SDL2 . capture === undefined ) ) { return ; } audioProcessingEvent . outputBuffer . getChannelData ( 0 ) . fill ( 0.0 ) ; SDL2 . capture . currentCaptureBuffer = audioProcessingEvent . inputBuffer ; dynCall ( 'vi' , $2 , [ $3 ] ) ; } ; SDL2 . capture . mediaStreamNode . connect ( SDL2 . capture . scriptProcessorNode ) ; SDL2 . capture . scriptProcessorNode . connect ( SDL2 . audioContext . destination ) ; SDL2 . capture . stream = stream ; } ; var no _microphone = function ( error ) { } ; SDL2 . capture . silenceBuffer = SDL2 . audioContext . createBuffer ( $0 , $1 , SDL2 . audioContext . sampleRate ) ; SDL2 . capture . silenceBuffer . getChannelData ( 0 ) . fill ( 0.0 ) ; var silence _callback = function ( ) { SDL2 . capture . currentCaptureBuffer = SDL2 . capture . silenceBuffer ; dynCall ( 'vi' , $2 , [ $3 ] ) ; } ; SDL2 . capture . silenceTimer = setTimeout ( silence _callback , ( $1 / SDL2 . audioContext . sampleRate ) * 1000 ) ; if ( ( navigator . mediaDevices !== undefined ) && ( navigator . mediaDevices . getUserMedia !== undefined ) ) { navigator . mediaDevices . getUserMedia ( { audio : true , video : false } ) . then ( have _microphone ) . catch ( no _microphone ) ; } else if ( navigator . webkitGetUserMedia !== undefined ) { navigator . webkitGetUserMedia ( { audio : true , video : false } , have _microphone , no _microphone ) ; } } ,
5376943 : ( $0 , $1 , $2 , $3 ) => { var SDL2 = Module [ 'SDL2' ] ; SDL2 . audio . scriptProcessorNode = SDL2 . audioContext [ 'createScriptProcessor' ] ( $1 , 0 , $0 ) ; SDL2 . audio . scriptProcessorNode [ 'onaudioprocess' ] = function ( e ) { if ( ( SDL2 === undefined ) || ( SDL2 . audio === undefined ) ) { return ; } SDL2 . audio . currentOutputBuffer = e [ 'outputBuffer' ] ; dynCall ( 'vi' , $2 , [ $3 ] ) ; } ; SDL2 . audio . scriptProcessorNode [ 'connect' ] ( SDL2 . audioContext [ 'destination' ] ) ; } ,
5377353 : ( $0 , $1 ) => { var SDL2 = Module [ 'SDL2' ] ; var numChannels = SDL2 . capture . currentCaptureBuffer . numberOfChannels ; for ( var c = 0 ; c < numChannels ; ++ c ) { var channelData = SDL2 . capture . currentCaptureBuffer . getChannelData ( c ) ; if ( channelData . length != $1 ) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData . length + ' samples vs expected ' + $1 + ' samples!' ; } if ( numChannels == 1 ) { for ( var j = 0 ; j < $1 ; ++ j ) { setValue ( $0 + ( j * 4 ) , channelData [ j ] , 'float' ) ; } } else { for ( var j = 0 ; j < $1 ; ++ j ) { setValue ( $0 + ( ( ( j * numChannels ) + c ) * 4 ) , channelData [ j ] , 'float' ) ; } } } } ,
5377958 : ( $0 , $1 ) => { var SDL2 = Module [ 'SDL2' ] ; var numChannels = SDL2 . audio . currentOutputBuffer [ 'numberOfChannels' ] ; for ( var c = 0 ; c < numChannels ; ++ c ) { var channelData = SDL2 . audio . currentOutputBuffer [ 'getChannelData' ] ( c ) ; if ( channelData . length != $1 ) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData . length + ' samples vs expected ' + $1 + ' samples!' ; } for ( var j = 0 ; j < $1 ; ++ j ) { channelData [ j ] = HEAPF32 [ $0 + ( ( j * numChannels + c ) << 2 ) >> 2 ] ; } } } ,
5378438 : ( $0 ) => { var SDL2 = Module [ 'SDL2' ] ; if ( $0 ) { if ( SDL2 . capture . silenceTimer !== undefined ) { clearTimeout ( SDL2 . capture . silenceTimer ) ; } if ( SDL2 . capture . stream !== undefined ) { var tracks = SDL2 . capture . stream . getAudioTracks ( ) ; for ( var i = 0 ; i < tracks . length ; i ++ ) { SDL2 . capture . stream . removeTrack ( tracks [ i ] ) ; } SDL2 . capture . stream = undefined ; } if ( SDL2 . capture . scriptProcessorNode !== undefined ) { SDL2 . capture . scriptProcessorNode . onaudioprocess = function ( audioProcessingEvent ) { } ; SDL2 . capture . scriptProcessorNode . disconnect ( ) ; SDL2 . capture . scriptProcessorNode = undefined ; } if ( SDL2 . capture . mediaStreamNode !== undefined ) { SDL2 . capture . mediaStreamNode . disconnect ( ) ; SDL2 . capture . mediaStreamNode = undefined ; } if ( SDL2 . capture . silenceBuffer !== undefined ) { SDL2 . capture . silenceBuffer = undefined } SDL2 . capture = undefined ; } else { if ( SDL2 . audio . scriptProcessorNode != undefined ) { SDL2 . audio . scriptProcessorNode . disconnect ( ) ; SDL2 . audio . scriptProcessorNode = undefined ; } SDL2 . audio = undefined ; } if ( ( SDL2 . audioContext !== undefined ) && ( SDL2 . audio === undefined ) && ( SDL2 . capture === undefined ) ) { SDL2 . audioContext . close ( ) ; SDL2 . audioContext = undefined ; } } ,
5379610 : ( $0 , $1 , $2 ) => { var w = $0 ; var h = $1 ; var pixels = $2 ; if ( ! Module [ 'SDL2' ] ) Module [ 'SDL2' ] = { } ; var SDL2 = Module [ 'SDL2' ] ; if ( SDL2 . ctxCanvas !== Module [ 'canvas' ] ) { SDL2 . ctx = Module [ 'createContext' ] ( Module [ 'canvas' ] , false , true ) ; SDL2 . ctxCanvas = Module [ 'canvas' ] ; } if ( SDL2 . w !== w || SDL2 . h !== h || SDL2 . imageCtx !== SDL2 . ctx ) { SDL2 . image = SDL2 . ctx . createImageData ( w , h ) ; SDL2 . w = w ; SDL2 . h = h ; SDL2 . imageCtx = SDL2 . ctx ; } var data = SDL2 . image . data ; var src = pixels >> 2 ; var dst = 0 ; var num ; if ( typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray ) { num = data . length ; while ( dst < num ) { var val = HEAP32 [ src ] ; data [ dst ] = val & 0xff ; data [ dst + 1 ] = ( val >> 8 ) & 0xff ; data [ dst + 2 ] = ( val >> 16 ) & 0xff ; data [ dst + 3 ] = 0xff ; src ++ ; dst += 4 ; } } else { if ( SDL2 . data32Data !== data ) { SDL2 . data32 = new Int32Array ( data . buffer ) ; SDL2 . data8 = new Uint8Array ( data . buffer ) ; SDL2 . data32Data = data ; } var data32 = SDL2 . data32 ; num = data32 . length ; data32 . set ( HEAP32 . subarray ( src , src + num ) ) ; var data8 = SDL2 . data8 ; var i = 3 ; var j = i + 4 * num ; if ( num % 8 == 0 ) { while ( i < j ) { data8 [ i ] = 0xff ; i = i + 4 | 0 ; data8 [ i ] = 0xff ; i = i + 4 | 0 ; data8 [ i ] = 0xff ; i = i + 4 | 0 ; data8 [ i ] = 0xff ; i = i + 4 | 0 ; data8 [ i ] = 0xff ; i = i + 4 | 0 ; data8 [ i ] = 0xff ; i = i + 4 | 0 ; data8 [ i ] = 0xff ; i = i + 4 | 0 ; data8 [ i ] = 0xff ; i = i + 4 | 0 ; } } else { while ( i < j ) { data8 [ i ] = 0xff ; i = i + 4 | 0 ; } } } SDL2 . ctx . putImageData ( SDL2 . image , 0 , 0 ) ; } ,
5381079 : ( $0 , $1 , $2 , $3 , $4 ) => { var w = $0 ; var h = $1 ; var hot _x = $2 ; var hot _y = $3 ; var pixels = $4 ; var canvas = document . createElement ( "canvas" ) ; canvas . width = w ; canvas . height = h ; var ctx = canvas . getContext ( "2d" ) ; var image = ctx . createImageData ( w , h ) ; var data = image . data ; var src = pixels >> 2 ; var dst = 0 ; var num ; if ( typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray ) { num = data . length ; while ( dst < num ) { var val = HEAP32 [ src ] ; data [ dst ] = val & 0xff ; data [ dst + 1 ] = ( val >> 8 ) & 0xff ; data [ dst + 2 ] = ( val >> 16 ) & 0xff ; data [ dst + 3 ] = ( val >> 24 ) & 0xff ; src ++ ; dst += 4 ; } } else { var data32 = new Int32Array ( data . buffer ) ; num = data32 . length ; data32 . set ( HEAP32 . subarray ( src , src + num ) ) ; } ctx . putImageData ( image , 0 , 0 ) ; var url = hot _x === 0 && hot _y === 0 ? "url(" + canvas . toDataURL ( ) + "), auto" : "url(" + canvas . toDataURL ( ) + ") " + hot _x + " " + hot _y + ", auto" ; var urlBuf = _malloc ( url . length + 1 ) ; stringToUTF8 ( url , urlBuf , url . length + 1 ) ; return urlBuf ; } ,
5382068 : ( $0 ) => { if ( Module [ 'canvas' ] ) { Module [ 'canvas' ] . style [ 'cursor' ] = UTF8ToString ( $0 ) ; } } ,
5382151 : ( ) => { if ( Module [ 'canvas' ] ) { Module [ 'canvas' ] . style [ 'cursor' ] = 'none' ; } } ,
5382220 : ( ) => { return window . innerWidth ; } ,
5382250 : ( ) => { return window . innerHeight ; }
} ;
// end include: preamble.js
/** @constructor */
function ExitStatus ( status ) {
this . name = 'ExitStatus' ;
this . message = ` Program terminated with exit( ${ status } ) ` ;
this . status = status ;
}
function listenOnce ( object , event , func ) {
object . addEventListener ( event , func , { 'once' : true } ) ;
}
/** @param {Object=} elements */
function autoResumeAudioContext ( ctx , elements ) {
if ( ! elements ) {
elements = [ document , document . getElementById ( 'canvas' ) ] ;
}
[ 'keydown' , 'mousedown' , 'touchstart' ] . forEach ( ( event ) => {
elements . forEach ( ( element ) => {
if ( element ) {
listenOnce ( element , event , ( ) => {
if ( ctx . state === 'suspended' ) ctx . resume ( ) ;
} ) ;
}
} ) ;
} ) ;
}
function callRuntimeCallbacks ( callbacks ) {
while ( callbacks . length > 0 ) {
// Pass the module as the first argument.
callbacks . shift ( ) ( Module ) ;
}
}
function dynCallLegacy ( sig , ptr , args ) {
assert ( ( 'dynCall_' + sig ) in Module , ` bad function pointer type - dynCall function not found for sig ' ${ sig } ' ` ) ;
if ( args && args . length ) {
// j (64-bit integer) must be passed in as two numbers [low 32, high 32].
assert ( args . length === sig . substring ( 1 ) . replace ( /j/g , '--' ) . length ) ;
} else {
assert ( sig . length == 1 ) ;
}
var f = Module [ 'dynCall_' + sig ] ;
return args && args . length ? f . apply ( null , [ ptr ] . concat ( args ) ) : f . call ( null , ptr ) ;
}
var wasmTableMirror = [ ] ;
function getWasmTableEntry ( funcPtr ) {
var func = wasmTableMirror [ funcPtr ] ;
if ( ! func ) {
if ( funcPtr >= wasmTableMirror . length ) wasmTableMirror . length = funcPtr + 1 ;
wasmTableMirror [ funcPtr ] = func = wasmTable . get ( funcPtr ) ;
}
assert ( wasmTable . get ( funcPtr ) == func , "JavaScript-side Wasm function table mirror is out of date!" ) ;
return func ;
}
/** @param {Object=} args */
function dynCall ( sig , ptr , args ) {
// Without WASM_BIGINT support we cannot directly call function with i64 as
// part of thier signature, so we rely the dynCall functions generated by
// wasm-emscripten-finalize
if ( sig . includes ( 'j' ) ) {
return dynCallLegacy ( sig , ptr , args ) ;
}
assert ( getWasmTableEntry ( ptr ) , ` missing table entry in dynCall: ${ ptr } ` ) ;
var rtn = getWasmTableEntry ( ptr ) . apply ( null , args ) ;
return rtn ;
}
/ * *
* @ param { number } ptr
* @ param { string } type
* /
function getValue ( ptr , type = 'i8' ) {
if ( type . endsWith ( '*' ) ) type = '*' ;
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 ) ] ;
case '*' : return HEAPU32 [ ( ( ptr ) >> 2 ) ] ;
default : abort ( ` invalid type for getValue: ${ type } ` ) ;
}
}
function ptrToString ( ptr ) {
assert ( typeof ptr === 'number' ) ;
return '0x' + ptr . toString ( 16 ) . padStart ( 8 , '0' ) ;
}
/ * *
* @ param { number } ptr
* @ param { number } value
* @ param { string } type
* /
function setValue ( ptr , value , type = 'i8' ) {
if ( type . endsWith ( '*' ) ) type = '*' ;
switch ( type ) {
case 'i1' : HEAP8 [ ( ( ptr ) >> 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.0 ? ( tempDouble > 0.0 ? ( + ( Math . floor ( ( tempDouble ) / 4294967296.0 ) ) ) >>> 0 : ( ~ ~ ( ( + ( Math . ceil ( ( tempDouble - + ( ( ( ~ ~ ( tempDouble ) ) ) >>> 0 ) ) / 4294967296.0 ) ) ) ) ) >>> 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 ;
case '*' : HEAPU32 [ ( ( ptr ) >> 2 ) ] = value ; break ;
default : abort ( ` invalid type for setValue: ${ type } ` ) ;
}
}
function warnOnce ( text ) {
if ( ! warnOnce . shown ) warnOnce . shown = { } ;
if ( ! warnOnce . shown [ text ] ) {
warnOnce . shown [ text ] = 1 ;
if ( ENVIRONMENT _IS _NODE ) text = 'warning: ' + text ;
err ( text ) ;
}
}
var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder ( 'utf8' ) : undefined ;
/ * *
* Given a pointer 'idx' to a null - terminated UTF8 - encoded string in the given
* array that contains uint8 values , returns a copy of that string as a
* Javascript String object .
* heapOrArray is either a regular array , or a JavaScript typed array view .
* @ param { number } idx
* @ param { number = } maxBytesToRead
* @ return { string }
* /
function UTF8ArrayToString ( heapOrArray , idx , maxBytesToRead ) {
var endIdx = idx + maxBytesToRead ;
var endPtr = idx ;
// TextDecoder needs to know the byte length in advance, it doesn't stop on
// null terminator by itself. Also, use the length info to avoid running tiny
// strings through TextDecoder, since .subarray() allocates garbage.
// (As a tiny code save trick, compare endPtr against endIdx using a negation,
// so that undefined means Infinity)
while ( heapOrArray [ endPtr ] && ! ( endPtr >= endIdx ) ) ++ endPtr ;
if ( endPtr - idx > 16 && heapOrArray . buffer && UTF8Decoder ) {
return UTF8Decoder . decode ( heapOrArray . subarray ( idx , endPtr ) ) ;
}
var str = '' ;
// If building with TextDecoder, we have already computed the string length
// above, so test loop end condition against that
while ( idx < endPtr ) {
// For UTF8 byte structure, see:
// http://en.wikipedia.org/wiki/UTF-8#Description
// https://www.ietf.org/rfc/rfc2279.txt
// https://tools.ietf.org/html/rfc3629
var u0 = heapOrArray [ idx ++ ] ;
if ( ! ( u0 & 0x80 ) ) { str += String . fromCharCode ( u0 ) ; continue ; }
var u1 = heapOrArray [ idx ++ ] & 63 ;
if ( ( u0 & 0xE0 ) == 0xC0 ) { str += String . fromCharCode ( ( ( u0 & 31 ) << 6 ) | u1 ) ; continue ; }
var u2 = heapOrArray [ idx ++ ] & 63 ;
if ( ( u0 & 0xF0 ) == 0xE0 ) {
u0 = ( ( u0 & 15 ) << 12 ) | ( u1 << 6 ) | u2 ;
} else {
if ( ( u0 & 0xF8 ) != 0xF0 ) warnOnce ( 'Invalid UTF-8 leading byte ' + ptrToString ( u0 ) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!' ) ;
u0 = ( ( u0 & 7 ) << 18 ) | ( u1 << 12 ) | ( u2 << 6 ) | ( heapOrArray [ idx ++ ] & 63 ) ;
}
if ( u0 < 0x10000 ) {
str += String . fromCharCode ( u0 ) ;
} else {
var ch = u0 - 0x10000 ;
str += String . fromCharCode ( 0xD800 | ( ch >> 10 ) , 0xDC00 | ( ch & 0x3FF ) ) ;
}
}
return str ;
}
/ * *
* Given a pointer 'ptr' to a null - terminated UTF8 - encoded string in the
* emscripten HEAP , returns a copy of that string as a Javascript String object .
*
* @ param { number } ptr
* @ param { number = } maxBytesToRead - An optional length that specifies the
* maximum number of bytes to read . You can omit this parameter to scan the
* string until the first 0 byte . If maxBytesToRead is passed , and the string
* at [ ptr , ptr + maxBytesToReadr [ contains a null byte in the middle , then the
* string will cut short at that byte index ( i . e . maxBytesToRead will not
* produce a string of exact length [ ptr , ptr + maxBytesToRead [ ) N . B . mixing
* frequent uses of UTF8ToString ( ) with and without maxBytesToRead may throw
* JS JIT optimizations off , so it is worth to consider consistently using one
* @ return { string }
* /
function UTF8ToString ( ptr , maxBytesToRead ) {
assert ( typeof ptr == 'number' ) ;
return ptr ? UTF8ArrayToString ( HEAPU8 , ptr , maxBytesToRead ) : '' ;
}
function _ _ _assert _fail ( condition , filename , line , func ) {
abort ( ` Assertion failed: ${ UTF8ToString ( condition ) } , at: ` + [ filename ? UTF8ToString ( filename ) : 'unknown filename' , line , func ? UTF8ToString ( func ) : 'unknown function' ] ) ;
}
/** @constructor */
function ExceptionInfo ( excPtr ) {
this . excPtr = excPtr ;
this . ptr = excPtr - 24 ;
this . set _type = function ( type ) {
HEAPU32 [ ( ( ( this . ptr ) + ( 4 ) ) >> 2 ) ] = type ;
} ;
this . get _type = function ( ) {
return HEAPU32 [ ( ( ( this . ptr ) + ( 4 ) ) >> 2 ) ] ;
} ;
this . set _destructor = function ( destructor ) {
HEAPU32 [ ( ( ( this . ptr ) + ( 8 ) ) >> 2 ) ] = destructor ;
} ;
this . get _destructor = function ( ) {
return HEAPU32 [ ( ( ( this . ptr ) + ( 8 ) ) >> 2 ) ] ;
} ;
this . set _caught = function ( caught ) {
caught = caught ? 1 : 0 ;
HEAP8 [ ( ( ( this . ptr ) + ( 12 ) ) >> 0 ) ] = caught ;
} ;
this . get _caught = function ( ) {
return HEAP8 [ ( ( ( this . ptr ) + ( 12 ) ) >> 0 ) ] != 0 ;
} ;
this . set _rethrown = function ( rethrown ) {
rethrown = rethrown ? 1 : 0 ;
HEAP8 [ ( ( ( this . ptr ) + ( 13 ) ) >> 0 ) ] = rethrown ;
} ;
this . get _rethrown = function ( ) {
return HEAP8 [ ( ( ( this . ptr ) + ( 13 ) ) >> 0 ) ] != 0 ;
} ;
// Initialize native structure fields. Should be called once after allocated.
this . init = function ( type , destructor ) {
this . set _adjusted _ptr ( 0 ) ;
this . set _type ( type ) ;
this . set _destructor ( destructor ) ;
}
this . set _adjusted _ptr = function ( adjustedPtr ) {
HEAPU32 [ ( ( ( this . ptr ) + ( 16 ) ) >> 2 ) ] = adjustedPtr ;
} ;
this . get _adjusted _ptr = function ( ) {
return HEAPU32 [ ( ( ( this . ptr ) + ( 16 ) ) >> 2 ) ] ;
} ;
// Get pointer which is expected to be received by catch clause in C++ code. It may be adjusted
// when the pointer is casted to some of the exception object base classes (e.g. when virtual
// inheritance is used). When a pointer is thrown this method should return the thrown pointer
// itself.
this . get _exception _ptr = function ( ) {
// Work around a fastcomp bug, this code is still included for some reason in a build without
// exceptions support.
var isPointer = _ _ _cxa _is _pointer _type ( this . get _type ( ) ) ;
if ( isPointer ) {
return HEAPU32 [ ( ( this . excPtr ) >> 2 ) ] ;
}
var adjusted = this . get _adjusted _ptr ( ) ;
if ( adjusted !== 0 ) return adjusted ;
return this . excPtr ;
} ;
}
var exceptionLast = 0 ;
var uncaughtExceptionCount = 0 ;
function _ _ _cxa _throw ( ptr , type , destructor ) {
var info = new ExceptionInfo ( ptr ) ;
// Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception.
info . init ( type , destructor ) ;
exceptionLast = ptr ;
uncaughtExceptionCount ++ ;
assert ( false , 'Exception thrown, but exception catching is not enabled. Compile with -sNO_DISABLE_EXCEPTION_CATCHING or -sEXCEPTION_CATCHING_ALLOWED=[..] to catch.' ) ;
}
function setErrNo ( value ) {
HEAP32 [ ( ( _ _ _errno _location ( ) ) >> 2 ) ] = value ;
return value ;
}
var PATH = { isAbs : ( path ) => path . charAt ( 0 ) === '/' , splitPath : ( filename ) => {
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/ ;
return splitPathRe . exec ( filename ) . slice ( 1 ) ;
} , normalizeArray : ( parts , allowAboveRoot ) => {
// if the path tries to go above the root, `up` ends up > 0
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 the path is allowed to go above the root, restore leading ..s
if ( allowAboveRoot ) {
for ( ; up ; up -- ) {
parts . unshift ( '..' ) ;
}
}
return parts ;
} , normalize : ( path ) => {
var isAbsolute = PATH . isAbs ( path ) ,
trailingSlash = path . substr ( - 1 ) === '/' ;
// Normalize the path
path = PATH . normalizeArray ( path . split ( '/' ) . filter ( ( p ) => ! ! p ) , ! isAbsolute ) . join ( '/' ) ;
if ( ! path && ! isAbsolute ) {
path = '.' ;
}
if ( path && trailingSlash ) {
path += '/' ;
}
return ( isAbsolute ? '/' : '' ) + path ;
} , dirname : ( path ) => {
var result = PATH . splitPath ( path ) ,
root = result [ 0 ] ,
dir = result [ 1 ] ;
if ( ! root && ! dir ) {
// No dirname whatsoever
return '.' ;
}
if ( dir ) {
// It has a dirname, strip trailing slash
dir = dir . substr ( 0 , dir . length - 1 ) ;
}
return root + dir ;
} , basename : ( path ) => {
// EMSCRIPTEN return '/'' for '/', not an empty string
if ( path === '/' ) return '/' ;
path = PATH . normalize ( path ) ;
path = path . replace ( /\/$/ , "" ) ;
var lastSlash = path . lastIndexOf ( '/' ) ;
if ( lastSlash === - 1 ) return path ;
return path . substr ( lastSlash + 1 ) ;
} , join : function ( ) {
var paths = Array . prototype . slice . call ( arguments ) ;
return PATH . normalize ( paths . join ( '/' ) ) ;
} , join2 : ( l , r ) => {
return PATH . normalize ( l + '/' + r ) ;
} } ;
function initRandomFill ( ) {
if ( typeof crypto == 'object' && typeof crypto [ 'getRandomValues' ] == 'function' ) {
// for modern web browsers
return ( view ) => crypto . getRandomValues ( view ) ;
} else
if ( ENVIRONMENT _IS _NODE ) {
// for nodejs with or without crypto support included
try {
var crypto _module = require ( 'crypto' ) ;
var randomFillSync = crypto _module [ 'randomFillSync' ] ;
if ( randomFillSync ) {
// nodejs with LTS crypto support
return ( view ) => crypto _module [ 'randomFillSync' ] ( view ) ;
}
// very old nodejs with the original crypto API
var randomBytes = crypto _module [ 'randomBytes' ] ;
return ( view ) => (
view . set ( randomBytes ( view . byteLength ) ) ,
// Return the original view to match modern native implementations.
view
) ;
} catch ( e ) {
// nodejs doesn't have crypto support
}
}
// we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
abort ( "no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };" ) ;
}
function randomFill ( view ) {
// Lazily init on the first invocation.
return ( randomFill = initRandomFill ( ) ) ( view ) ;
}
var PATH _FS = { resolve : function ( ) {
var resolvedPath = '' ,
resolvedAbsolute = false ;
for ( var i = arguments . length - 1 ; i >= - 1 && ! resolvedAbsolute ; i -- ) {
var path = ( i >= 0 ) ? arguments [ i ] : FS . cwd ( ) ;
// Skip empty and invalid entries
if ( typeof path != 'string' ) {
throw new TypeError ( 'Arguments to path.resolve must be strings' ) ;
} else if ( ! path ) {
return '' ; // an invalid portion invalidates the whole thing
}
resolvedPath = path + '/' + resolvedPath ;
resolvedAbsolute = PATH . isAbs ( path ) ;
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
resolvedPath = PATH . normalizeArray ( resolvedPath . split ( '/' ) . filter ( ( p ) => ! ! p ) , ! resolvedAbsolute ) . join ( '/' ) ;
return ( ( resolvedAbsolute ? '/' : '' ) + resolvedPath ) || '.' ;
} , relative : ( from , to ) => {
from = PATH _FS . resolve ( from ) . substr ( 1 ) ;
to = PATH _FS . resolve ( to ) . substr ( 1 ) ;
function trim ( arr ) {
var start = 0 ;
for ( ; start < arr . length ; start ++ ) {
if ( arr [ start ] !== '' ) break ;
}
var end = arr . length - 1 ;
for ( ; end >= 0 ; end -- ) {
if ( arr [ end ] !== '' ) break ;
}
if ( start > end ) return [ ] ;
return arr . slice ( start , end - start + 1 ) ;
}
var fromParts = trim ( from . split ( '/' ) ) ;
var toParts = trim ( to . split ( '/' ) ) ;
var length = Math . min ( fromParts . length , toParts . length ) ;
var samePartsLength = length ;
for ( var i = 0 ; i < length ; i ++ ) {
if ( fromParts [ i ] !== toParts [ i ] ) {
samePartsLength = i ;
break ;
}
}
var outputParts = [ ] ;
for ( var i = samePartsLength ; i < fromParts . length ; i ++ ) {
outputParts . push ( '..' ) ;
}
outputParts = outputParts . concat ( toParts . slice ( samePartsLength ) ) ;
return outputParts . join ( '/' ) ;
} } ;
function lengthBytesUTF8 ( str ) {
var len = 0 ;
for ( var i = 0 ; i < str . length ; ++ i ) {
// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
// unit, not a Unicode code point of the character! So decode
// UTF16->UTF32->UTF8.
// See http://unicode.org/faq/utf_bom.html#utf16-3
var c = str . charCodeAt ( i ) ; // possibly a lead surrogate
if ( c <= 0x7F ) {
len ++ ;
} else if ( c <= 0x7FF ) {
len += 2 ;
} else if ( c >= 0xD800 && c <= 0xDFFF ) {
len += 4 ; ++ i ;
} else {
len += 3 ;
}
}
return len ;
}
function stringToUTF8Array ( str , heap , outIdx , maxBytesToWrite ) {
assert ( typeof str === 'string' ) ;
// Parameter maxBytesToWrite is not optional. Negative values, 0, null,
// undefined and false each don't write out any bytes.
if ( ! ( maxBytesToWrite > 0 ) )
return 0 ;
var startIdx = outIdx ;
var endIdx = outIdx + maxBytesToWrite - 1 ; // -1 for string null terminator.
for ( var i = 0 ; i < str . length ; ++ i ) {
// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
// unit, not a Unicode code point of the character! So decode
// UTF16->UTF32->UTF8.
// See http://unicode.org/faq/utf_bom.html#utf16-3
// For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
// and https://www.ietf.org/rfc/rfc2279.txt
// and https://tools.ietf.org/html/rfc3629
var u = str . charCodeAt ( i ) ; // possibly a lead surrogate
if ( u >= 0xD800 && u <= 0xDFFF ) {
var u1 = str . charCodeAt ( ++ i ) ;
u = 0x10000 + ( ( u & 0x3FF ) << 10 ) | ( u1 & 0x3FF ) ;
}
if ( u <= 0x7F ) {
if ( outIdx >= endIdx ) break ;
heap [ outIdx ++ ] = u ;
} else if ( u <= 0x7FF ) {
if ( outIdx + 1 >= endIdx ) break ;
heap [ outIdx ++ ] = 0xC0 | ( u >> 6 ) ;
heap [ outIdx ++ ] = 0x80 | ( u & 63 ) ;
} else if ( u <= 0xFFFF ) {
if ( outIdx + 2 >= endIdx ) break ;
heap [ outIdx ++ ] = 0xE0 | ( u >> 12 ) ;
heap [ outIdx ++ ] = 0x80 | ( ( u >> 6 ) & 63 ) ;
heap [ outIdx ++ ] = 0x80 | ( u & 63 ) ;
} else {
if ( outIdx + 3 >= endIdx ) break ;
if ( u > 0x10FFFF ) warnOnce ( 'Invalid Unicode code point ' + ptrToString ( u ) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).' ) ;
heap [ outIdx ++ ] = 0xF0 | ( u >> 18 ) ;
heap [ outIdx ++ ] = 0x80 | ( ( u >> 12 ) & 63 ) ;
heap [ outIdx ++ ] = 0x80 | ( ( u >> 6 ) & 63 ) ;
heap [ outIdx ++ ] = 0x80 | ( u & 63 ) ;
}
}
// Null-terminate the pointer to the buffer.
heap [ outIdx ] = 0 ;
return outIdx - startIdx ;
}
/** @type {function(string, boolean=, number=)} */
function intArrayFromString ( stringy , dontAddNull , length ) {
var len = length > 0 ? length : lengthBytesUTF8 ( stringy ) + 1 ;
var u8array = new Array ( len ) ;
var numBytesWritten = stringToUTF8Array ( stringy , u8array , 0 , u8array . length ) ;
if ( dontAddNull ) u8array . length = numBytesWritten ;
return u8array ;
}
var TTY = { ttys : [ ] , init : function ( ) {
// https://github.com/emscripten-core/emscripten/pull/1555
// if (ENVIRONMENT_IS_NODE) {
// // currently, FS.init does not distinguish if process.stdin is a file or TTY
// // device, it always assumes it's a TTY device. because of this, we're forcing
// // process.stdin to UTF8 encoding to at least make stdin reading compatible
// // with text files until FS.init can be refactored.
// process.stdin.setEncoding('utf8');
// }
} , shutdown : function ( ) {
// https://github.com/emscripten-core/emscripten/pull/1555
// if (ENVIRONMENT_IS_NODE) {
// // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
// // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
// // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
// // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
// // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
// process.stdin.pause();
// }
} , 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 ) {
// flush any pending line data
stream . tty . ops . fsync ( stream . tty ) ;
} , fsync : function ( stream ) {
stream . tty . ops . fsync ( stream . tty ) ;
} , read : function ( stream , buffer , offset , length , pos /* ignored */ ) {
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 ) {
// we will read data by chunks of BUFSIZE
var BUFSIZE = 256 ;
var buf = Buffer . alloc ( BUFSIZE ) ;
var bytesRead = 0 ;
try {
bytesRead = fs . readSync ( process . stdin . fd , buf , 0 , BUFSIZE , - 1 ) ;
} catch ( e ) {
// Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,
// reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.
if ( e . toString ( ) . includes ( 'EOF' ) ) 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' ) {
// Browser.
result = window . prompt ( 'Input: ' ) ; // returns null on cancel
if ( result !== null ) {
result += '\n' ;
}
} else if ( typeof readline == 'function' ) {
// Command line.
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 ) ; // val == 0 would cut text output off in the middle.
}
} , fsync : function ( tty ) {
if ( tty . output && tty . output . length > 0 ) {
out ( UTF8ArrayToString ( tty . output , 0 ) ) ;
tty . output = [ ] ;
}
} } , default _tty1 _ops : { put _char : function ( tty , val ) {
if ( val === null || val === 10 ) {
err ( UTF8ArrayToString ( tty . output , 0 ) ) ;
tty . output = [ ] ;
} else {
if ( val != 0 ) tty . output . push ( val ) ;
}
} , fsync : function ( tty ) {
if ( tty . output && tty . output . length > 0 ) {
err ( UTF8ArrayToString ( tty . output , 0 ) ) ;
tty . output = [ ] ;
}
} } } ;
function zeroMemory ( address , size ) {
HEAPU8 . fill ( 0 , address , address + size ) ;
return address ;
}
function alignMemory ( size , alignment ) {
assert ( alignment , "alignment argument is required" ) ;
return Math . ceil ( size / alignment ) * alignment ;
}
function mmapAlloc ( size ) {
abort ( 'internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported' ) ;
}
var MEMFS = { ops _table : null , mount : function ( mount ) {
return MEMFS . createNode ( null , '/' , 16384 | 511 /* 0777 */ , 0 ) ;
} , createNode : function ( parent , name , mode , dev ) {
if ( FS . isBlkdev ( mode ) || FS . isFIFO ( mode ) ) {
// no supported
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 ; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
// When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
// for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
// penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
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 ( ) ;
// add the new node to the parent
if ( parent ) {
parent . contents [ name ] = node ;
parent . timestamp = node . timestamp ;
}
return node ;
} , getFileDataAsTypedArray : function ( node ) {
if ( ! node . contents ) return new Uint8Array ( 0 ) ;
if ( node . contents . subarray ) return node . contents . subarray ( 0 , node . usedBytes ) ; // Make sure to not return excess unused bytes.
return new Uint8Array ( node . contents ) ;
} , expandFileStorage : function ( node , newCapacity ) {
var prevCapacity = node . contents ? node . contents . length : 0 ;
if ( prevCapacity >= newCapacity ) return ; // No need to expand, the storage was already large enough.
// Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
// For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
// avoid overshooting the allocation cap by a very large margin.
var CAPACITY _DOUBLING _MAX = 1024 * 1024 ;
newCapacity = Math . max ( newCapacity , ( prevCapacity * ( prevCapacity < CAPACITY _DOUBLING _MAX ? 2.0 : 1.125 ) ) >>> 0 ) ;
if ( prevCapacity != 0 ) newCapacity = Math . max ( newCapacity , 256 ) ; // At minimum allocate 256b for each file when expanding.
var oldContents = node . contents ;
node . contents = new Uint8Array ( newCapacity ) ; // Allocate new storage.
if ( node . usedBytes > 0 ) node . contents . set ( oldContents . subarray ( 0 , node . usedBytes ) , 0 ) ; // Copy old data over to the new storage.
} , resizeFileStorage : function ( node , newSize ) {
if ( node . usedBytes == newSize ) return ;
if ( newSize == 0 ) {
node . contents = null ; // Fully decommit when requesting a resize to zero.
node . usedBytes = 0 ;
} else {
var oldContents = node . contents ;
node . contents = new Uint8Array ( newSize ) ; // Allocate new storage.
if ( oldContents ) {
node . contents . set ( oldContents . subarray ( 0 , Math . min ( newSize , node . usedBytes ) ) ) ; // Copy old data over to the new storage.
}
node . usedBytes = newSize ;
}
} , node _ops : { getattr : function ( node ) {
var attr = { } ;
// device numbers reuse inode numbers.
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 ) ;
// NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
// but this is not required by the standard.
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 we're overwriting a directory at new_name, make sure it's empty.
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 ) ;
}
}
}
// do the internal rewiring
delete old _node . parent . contents [ old _node . name ] ;
old _node . parent . timestamp = Date . now ( )
old _node . name = new _name ;
new _dir . contents [ new _name ] = old _node ;
new _dir . timestamp = old _node . parent . timestamp ;
old _node . parent = new _dir ;
} , unlink : function ( parent , name ) {
delete parent . contents [ name ] ;
parent . timestamp = Date . now ( ) ;
} , rmdir : function ( parent , name ) {
var node = FS . lookupNode ( parent , name ) ;
for ( var i in node . contents ) {
throw new FS . ErrnoError ( 55 ) ;
}
delete parent . contents [ name ] ;
parent . timestamp = Date . now ( ) ;
} , readdir : function ( node ) {
var entries = [ '.' , '..' ] ;
for ( var key in node . contents ) {
if ( ! node . contents . hasOwnProperty ( key ) ) {
continue ;
}
entries . push ( key ) ;
}
return entries ;
} , symlink : function ( parent , newname , oldpath ) {
var node = MEMFS . createNode ( parent , newname , 511 /* 0777 */ | 40960 , 0 ) ;
node . link = oldpath ;
return node ;
} , readlink : function ( node ) {
if ( ! FS . isLink ( node . mode ) ) {
throw new FS . ErrnoError ( 28 ) ;
}
return node . link ;
} } , stream _ops : { read : function ( stream , buffer , offset , length , position ) {
var contents = stream . node . contents ;
if ( position >= stream . node . usedBytes ) return 0 ;
var size = Math . min ( stream . node . usedBytes - position , length ) ;
assert ( size >= 0 ) ;
if ( size > 8 && contents . subarray ) { // non-trivial, and typed array
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 ) {
// The data buffer should be a typed array view
assert ( ! ( buffer instanceof ArrayBuffer ) ) ;
// If the buffer is located in main memory (HEAP), and if
// memory can grow, we can't hold on to references of the
// memory buffer, as they may get invalidated. That means we
// need to do copy its contents.
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 ) ) { // This write is from a typed array to a typed array?
if ( canOwn ) {
assert ( position === 0 , 'canOwn must imply no weird position inside the file' ) ;
node . contents = buffer . subarray ( offset , offset + length ) ;
node . usedBytes = length ;
return length ;
} else if ( node . usedBytes === 0 && position === 0 ) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
node . contents = buffer . slice ( offset , offset + length ) ;
node . usedBytes = length ;
return length ;
} else if ( position + length <= node . usedBytes ) { // Writing to an already allocated and used subrange of the file?
node . contents . set ( buffer . subarray ( offset , offset + length ) , position ) ;
return length ;
}
}
// Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
MEMFS . expandFileStorage ( node , position + length ) ;
if ( node . contents . subarray && buffer . subarray ) {
// Use typed array write which is available.
node . contents . set ( buffer . subarray ( offset , offset + length ) , position ) ;
} else {
for ( var i = 0 ; i < length ; i ++ ) {
node . contents [ position + i ] = buffer [ offset + i ] ; // Or fall back to manual write if not.
}
}
node . usedBytes = Math . max ( node . usedBytes , position + length ) ;
return length ;
} , llseek : function ( stream , offset , whence ) {
var position = offset ;
if ( whence === 1 ) {
position += stream . position ;
} else if ( whence === 2 ) {
if ( FS . isFile ( stream . node . mode ) ) {
position += stream . node . usedBytes ;
}
}
if ( position < 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
return position ;
} , allocate : function ( stream , offset , length ) {
MEMFS . expandFileStorage ( stream . node , offset + length ) ;
stream . node . usedBytes = Math . max ( stream . node . usedBytes , offset + length ) ;
} , mmap : function ( stream , length , position , prot , flags ) {
if ( ! FS . isFile ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 43 ) ;
}
var ptr ;
var allocated ;
var contents = stream . node . contents ;
// Only make a new copy when MAP_PRIVATE is specified.
if ( ! ( flags & 2 ) && contents . buffer === HEAP8 . buffer ) {
// We can't emulate MAP_SHARED when the file is not backed by the
// buffer we're mapping to (e.g. the HEAP buffer).
allocated = false ;
ptr = contents . byteOffset ;
} else {
// Try to avoid unnecessary slices.
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 ) {
MEMFS . stream _ops . write ( stream , buffer , 0 , length , offset , false ) ;
// should we check if bytesWritten and length are the same?
return 0 ;
} } } ;
/** @param {boolean=} noRunDep */
function asyncLoad ( url , onload , onerror , noRunDep ) {
var dep = ! noRunDep ? getUniqueRunDependency ( ` al ${ url } ` ) : '' ;
readAsync ( url , ( arrayBuffer ) => {
assert ( arrayBuffer , ` Loading data file " ${ url } " failed (no arrayBuffer). ` ) ;
onload ( new Uint8Array ( arrayBuffer ) ) ;
if ( dep ) removeRunDependency ( dep ) ;
} , ( event ) => {
if ( onerror ) {
onerror ( ) ;
} else {
throw ` Loading data file " ${ url } " failed. ` ;
}
} ) ;
if ( dep ) addRunDependency ( dep ) ;
}
var preloadPlugins = Module [ 'preloadPlugins' ] || [ ] ;
function FS _handledByPreloadPlugin ( byteArray , fullname , finish , onerror ) {
// Ensure plugins are ready.
if ( typeof Browser != 'undefined' ) Browser . init ( ) ;
var handled = false ;
preloadPlugins . forEach ( function ( plugin ) {
if ( handled ) return ;
if ( plugin [ 'canHandle' ] ( fullname ) ) {
plugin [ 'handle' ] ( byteArray , fullname , finish , onerror ) ;
handled = true ;
}
} ) ;
return handled ;
}
function FS _createPreloadedFile ( parent , name , url , canRead , canWrite , onload , onerror , dontCreateFile , canOwn , preFinish ) {
// TODO we should allow people to just pass in a complete filename instead
// of parent and name being that we just join them anyways
var fullname = name ? PATH _FS . resolve ( PATH . join2 ( parent , name ) ) : parent ;
var dep = getUniqueRunDependency ( ` cp ${ fullname } ` ) ; // might have several active requests for the same fullname
function processData ( byteArray ) {
function finish ( byteArray ) {
if ( preFinish ) preFinish ( ) ;
if ( ! dontCreateFile ) {
FS . createDataFile ( parent , name , byteArray , canRead , canWrite , canOwn ) ;
}
if ( onload ) onload ( ) ;
removeRunDependency ( dep ) ;
}
if ( FS _handledByPreloadPlugin ( byteArray , fullname , finish , ( ) => {
if ( onerror ) onerror ( ) ;
removeRunDependency ( dep ) ;
} ) ) {
return ;
}
finish ( byteArray ) ;
}
addRunDependency ( dep ) ;
if ( typeof url == 'string' ) {
asyncLoad ( url , ( byteArray ) => processData ( byteArray ) , onerror ) ;
} else {
processData ( url ) ;
}
}
function FS _modeStringToFlags ( str ) {
var flagModes = {
'r' : 0 ,
'r+' : 2 ,
'w' : 512 | 64 | 1 ,
'w+' : 512 | 64 | 2 ,
'a' : 1024 | 64 | 1 ,
'a+' : 1024 | 64 | 2 ,
} ;
var flags = flagModes [ str ] ;
if ( typeof flags == 'undefined' ) {
throw new Error ( ` Unknown file open mode: ${ str } ` ) ;
}
return flags ;
}
function FS _getMode ( canRead , canWrite ) {
var mode = 0 ;
if ( canRead ) mode |= 292 | 73 ;
if ( canWrite ) mode |= 146 ;
return mode ;
}
var ERRNO _MESSAGES = { 0 : "Success" , 1 : "Arg list too long" , 2 : "Permission denied" , 3 : "Address already in use" , 4 : "Address not available" , 5 : "Address family not supported by protocol family" , 6 : "No more processes" , 7 : "Socket already connected" , 8 : "Bad file number" , 9 : "Trying to read unreadable message" , 10 : "Mount device busy" , 11 : "Operation canceled" , 12 : "No children" , 13 : "Connection aborted" , 14 : "Connection refused" , 15 : "Connection reset by peer" , 16 : "File locking deadlock error" , 17 : "Destination address required" , 18 : "Math arg out of domain of func" , 19 : "Quota exceeded" , 20 : "File exists" , 21 : "Bad address" , 22 : "File too large" , 23 : "Host is unreachable" , 24 : "Identifier removed" , 25 : "Illegal byte sequence" , 26 : "Connection already in progress" , 27 : "Interrupted system call" , 28 : "Invalid argument" , 29 : "I/O error" , 30 : "Socket is already connected" , 31 : "Is a directory" , 32 : "Too many symbolic links" , 33 : "Too many open files" , 34 : "Too many links" , 35 : "Message too long" , 36 : "Multihop attempted" , 37 : "File or path name too long" , 38 : "Network interface is not configured" , 39 : "Connection reset by network" , 40 : "Network is unreachable" , 41 : "Too many open files in system" , 42 : "No buffer space available" , 43 : "No such device" , 44 : "No such file or directory" , 45 : "Exec format error" , 46 : "No record locks available" , 47 : "The link has been severed" , 48 : "Not enough core" , 49 : "No message of desired type" , 50 : "Protocol not available" , 51 : "No space left on device" , 52 : "Function not implemented" , 53 : "Socket is not connected" , 54 : "Not a directory" , 55 : "Directory not empty" , 56 : "State not recoverable" , 57 : "Socket operation on non-socket" , 59 : "Not a typewriter" , 60 : "No such device or address" , 61 : "Value too large for defined data type" , 62 : "Previous owner died" , 63 : "Not super-user" , 64 : "Broken pipe" , 65 : "Protocol error" , 66 : "Unknown protocol" , 67 : "Protocol wrong type for socket" , 68 : "Math result not representable" , 69 : "Read only file system" , 70 : "Illegal seek" , 71 : "No such process" , 72 : "Stale file handle" , 73 : "Connection timed out" , 74 : "Text file busy" , 75 : "Cross-device link" , 100 : "Device not a stream" , 101 : "Bad font file fmt" , 102 : "Invalid slot" , 103 : "Invalid request code" , 104 : "No anode" , 105 : "Block device required" , 106 : "Channel number out of range" , 107 : "Level 3 halted" , 108 : "Level 3 reset" , 109 : "Link number out of range" , 110 : "Protocol driver not attached" , 111 : "No CSI structure available" , 112 : "Level 2 halted" , 113 : "Invalid exchange" , 114 : "Invalid request descriptor" , 115 : "Exchange full" , 116 : "No data (for no delay io)" , 117 : "Timer expired" , 118 : "Out of streams resources" , 119 : "Machine is not on the network" , 120 : "Package not installed" , 121 : "The object is remote" , 122 : "Advertise error" , 123 : "Srmount error" , 124 : "Communication error on send" , 125 : "Cross mount point (not really error)" , 126 : "Given log. name not unique" , 127 : "f.d. invalid for this operation" , 128 : "Remote address changed" , 129 : "Can access a needed shared lib" , 130 : "Accessing a corrupted shared lib" , 131 : ".lib section in a.out corrupted" , 132 : "Attempting to link in too many libs" , 133 : "Attempting to exec a shared library" , 135 : "Streams pipe error" , 136 : "Too many users" , 137 : "Socket type not supported" , 138 : "Not supported" , 139 : "Protocol family not supported" , 140 : "Can't send after socket shutdown" , 141 : "Too many references" , 142 : "Host is down" , 148 : "No medium (in tape drive)" , 156 : "Level 2 not synchronized" } ;
var ERRNO _CODES = { } ;
function demangle ( func ) {
warnOnce ( 'warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling' ) ;
return func ;
}
function demangleAll ( text ) {
var regex =
/\b_Z[\w\d_]+/g ;
return text . replace ( regex ,
function ( x ) {
var y = demangle ( x ) ;
return x === y ? x : ( y + ' [' + x + ']' ) ;
} ) ;
}
var FS = { root : null , mounts : [ ] , devices : { } , streams : [ ] , nextInode : 1 , nameTable : null , currentPath : "/" , initialized : false , ignorePermissions : true , ErrnoError : null , genericErrors : { } , filesystems : null , syncFSRequests : 0 , lookupPath : ( path , opts = { } ) => {
path = PATH _FS . resolve ( path ) ;
if ( ! path ) return { path : '' , node : null } ;
var defaults = {
follow _mount : true ,
recurse _count : 0
} ;
opts = Object . assign ( defaults , opts )
if ( opts . recurse _count > 8 ) { // max recursive lookup of 8
throw new FS . ErrnoError ( 32 ) ;
}
// split the absolute path
var parts = path . split ( '/' ) . filter ( ( p ) => ! ! p ) ;
// start at the root
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 ) {
// stop resolving
break ;
}
current = FS . lookupNode ( current , parts [ i ] ) ;
current _path = PATH . join2 ( current _path , parts [ i ] ) ;
// jump to the mount's root node if this is a mountpoint
if ( FS . isMountpoint ( current ) ) {
if ( ! islast || ( islast && opts . follow _mount ) ) {
current = current . mounted . root ;
}
}
// by default, lookupPath will not follow a symlink if it is the final path component.
// setting opts.follow = true will override this behavior.
if ( ! islast || opts . follow ) {
var count = 0 ;
while ( FS . isLink ( current . mode ) ) {
var link = FS . readlink ( current _path ) ;
current _path = PATH _FS . resolve ( PATH . dirname ( current _path ) , link ) ;
var lookup = FS . lookupPath ( current _path , { recurse _count : opts . recurse _count + 1 } ) ;
current = lookup . node ;
if ( count ++ > 40 ) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
throw new FS . ErrnoError ( 32 ) ;
}
}
}
}
return { path : current _path , node : current } ;
} , getPath : ( node ) => {
var path ;
while ( true ) {
if ( FS . isRoot ( node ) ) {
var mount = node . mount . mountpoint ;
if ( ! path ) return mount ;
return mount [ mount . length - 1 ] !== '/' ? ` ${ mount } / ${ path } ` : mount + path ;
}
path = path ? ` ${ node . name } / ${ path } ` : node . name ;
node = node . parent ;
}
} , hashName : ( parentid , name ) => {
var hash = 0 ;
for ( var i = 0 ; i < name . length ; i ++ ) {
hash = ( ( hash << 5 ) - hash + name . charCodeAt ( i ) ) | 0 ;
}
return ( ( parentid + hash ) >>> 0 ) % FS . nameTable . length ;
} , hashAddNode : ( node ) => {
var hash = FS . hashName ( node . parent . id , node . name ) ;
node . name _next = FS . nameTable [ hash ] ;
FS . nameTable [ hash ] = node ;
} , hashRemoveNode : ( node ) => {
var hash = FS . hashName ( node . parent . id , node . name ) ;
if ( FS . nameTable [ hash ] === node ) {
FS . nameTable [ hash ] = node . name _next ;
} else {
var current = FS . nameTable [ hash ] ;
while ( current ) {
if ( current . name _next === node ) {
current . name _next = node . name _next ;
break ;
}
current = current . name _next ;
}
}
} , lookupNode : ( parent , name ) => {
var errCode = FS . mayLookup ( parent ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode , parent ) ;
}
var hash = FS . hashName ( parent . id , name ) ;
for ( var node = FS . nameTable [ hash ] ; node ; node = node . name _next ) {
var nodeName = node . name ;
if ( node . parent . id === parent . id && nodeName === name ) {
return node ;
}
}
// if we failed to find it in the cache, call into the VFS
return FS . lookup ( parent , name ) ;
} , createNode : ( parent , name , mode , rdev ) => {
assert ( typeof parent == 'object' )
var node = new FS . FSNode ( parent , name , mode , rdev ) ;
FS . hashAddNode ( node ) ;
return node ;
} , destroyNode : ( node ) => {
FS . hashRemoveNode ( node ) ;
} , isRoot : ( node ) => {
return node === node . parent ;
} , isMountpoint : ( node ) => {
return ! ! node . mounted ;
} , isFile : ( mode ) => {
return ( mode & 61440 ) === 32768 ;
} , isDir : ( mode ) => {
return ( mode & 61440 ) === 16384 ;
} , isLink : ( mode ) => {
return ( mode & 61440 ) === 40960 ;
} , isChrdev : ( mode ) => {
return ( mode & 61440 ) === 8192 ;
} , isBlkdev : ( mode ) => {
return ( mode & 61440 ) === 24576 ;
} , isFIFO : ( mode ) => {
return ( mode & 61440 ) === 4096 ;
} , isSocket : ( mode ) => {
return ( mode & 49152 ) === 49152 ;
} , flagsToPermissionString : ( flag ) => {
var perms = [ 'r' , 'w' , 'rw' ] [ flag & 3 ] ;
if ( ( flag & 512 ) ) {
perms += 'w' ;
}
return perms ;
} , nodePermissions : ( node , perms ) => {
if ( FS . ignorePermissions ) {
return 0 ;
}
// return 0 if any user, group or owner bits are set.
if ( perms . includes ( 'r' ) && ! ( node . mode & 292 ) ) {
return 2 ;
} else if ( perms . includes ( 'w' ) && ! ( node . mode & 146 ) ) {
return 2 ;
} else if ( perms . includes ( 'x' ) && ! ( node . mode & 73 ) ) {
return 2 ;
}
return 0 ;
} , mayLookup : ( dir ) => {
var errCode = FS . nodePermissions ( dir , 'x' ) ;
if ( errCode ) return errCode ;
if ( ! dir . node _ops . lookup ) return 2 ;
return 0 ;
} , mayCreate : ( dir , name ) => {
try {
var node = FS . lookupNode ( dir , name ) ;
return 20 ;
} catch ( e ) {
}
return FS . nodePermissions ( dir , 'wx' ) ;
} , mayDelete : ( dir , name , isdir ) => {
var node ;
try {
node = FS . lookupNode ( dir , name ) ;
} catch ( e ) {
return e . errno ;
}
var errCode = FS . nodePermissions ( dir , 'wx' ) ;
if ( errCode ) {
return errCode ;
}
if ( isdir ) {
if ( ! FS . isDir ( node . mode ) ) {
return 54 ;
}
if ( FS . isRoot ( node ) || FS . getPath ( node ) === FS . cwd ( ) ) {
return 10 ;
}
} else {
if ( FS . isDir ( node . mode ) ) {
return 31 ;
}
}
return 0 ;
} , mayOpen : ( node , flags ) => {
if ( ! node ) {
return 44 ;
}
if ( FS . isLink ( node . mode ) ) {
return 32 ;
} else if ( FS . isDir ( node . mode ) ) {
if ( FS . flagsToPermissionString ( flags ) !== 'r' || // opening for write
( flags & 512 ) ) { // TODO: check for O_SEARCH? (== search for dir only)
return 31 ;
}
}
return FS . nodePermissions ( node , FS . flagsToPermissionString ( flags ) ) ;
} , MAX _OPEN _FDS : 4096 , nextfd : ( ) => {
for ( var fd = 0 ; fd <= FS . MAX _OPEN _FDS ; fd ++ ) {
if ( ! FS . streams [ fd ] ) {
return fd ;
}
}
throw new FS . ErrnoError ( 33 ) ;
} , getStream : ( fd ) => FS . streams [ fd ] , createStream : ( stream , fd = - 1 ) => {
if ( ! FS . FSStream ) {
FS . FSStream = /** @constructor */ function ( ) {
this . shared = { } ;
} ;
FS . FSStream . prototype = { } ;
Object . defineProperties ( FS . FSStream . prototype , {
object : {
/** @this {FS.FSStream} */
get : function ( ) { return this . node ; } ,
/** @this {FS.FSStream} */
set : function ( val ) { this . node = val ; }
} ,
isRead : {
/** @this {FS.FSStream} */
get : function ( ) { return ( this . flags & 2097155 ) !== 1 ; }
} ,
isWrite : {
/** @this {FS.FSStream} */
get : function ( ) { return ( this . flags & 2097155 ) !== 0 ; }
} ,
isAppend : {
/** @this {FS.FSStream} */
get : function ( ) { return ( this . flags & 1024 ) ; }
} ,
flags : {
/** @this {FS.FSStream} */
get : function ( ) { return this . shared . flags ; } ,
/** @this {FS.FSStream} */
set : function ( val ) { this . shared . flags = val ; } ,
} ,
position : {
/** @this {FS.FSStream} */
get : function ( ) { return this . shared . position ; } ,
/** @this {FS.FSStream} */
set : function ( val ) { this . shared . position = val ; } ,
} ,
} ) ;
}
// clone it, so we can return an instance of FSStream
stream = Object . assign ( new FS . FSStream ( ) , stream ) ;
if ( fd == - 1 ) {
fd = FS . nextfd ( ) ;
}
stream . fd = fd ;
FS . streams [ fd ] = stream ;
return stream ;
} , closeStream : ( fd ) => {
FS . streams [ fd ] = null ;
} , chrdev _stream _ops : { open : ( stream ) => {
var device = FS . getDevice ( stream . node . rdev ) ;
// override node's stream ops with the device's
stream . stream _ops = device . stream _ops ;
// forward the open call
if ( stream . stream _ops . open ) {
stream . stream _ops . open ( stream ) ;
}
} , llseek : ( ) => {
throw new FS . ErrnoError ( 70 ) ;
} } , major : ( dev ) => ( ( dev ) >> 8 ) , minor : ( dev ) => ( ( dev ) & 0xff ) , makedev : ( ma , mi ) => ( ( ma ) << 8 | ( mi ) ) , registerDevice : ( dev , ops ) => {
FS . devices [ dev ] = { stream _ops : ops } ;
} , getDevice : ( dev ) => FS . devices [ dev ] , getMounts : ( mount ) => {
var mounts = [ ] ;
var check = [ mount ] ;
while ( check . length ) {
var m = check . pop ( ) ;
mounts . push ( m ) ;
check . push . apply ( check , m . mounts ) ;
}
return mounts ;
} , syncfs : ( populate , callback ) => {
if ( typeof populate == 'function' ) {
callback = populate ;
populate = false ;
}
FS . syncFSRequests ++ ;
if ( FS . syncFSRequests > 1 ) {
err ( ` warning: ${ FS . syncFSRequests } FS.syncfs operations in flight at once, probably just doing extra work ` ) ;
}
var mounts = FS . getMounts ( FS . root . mount ) ;
var completed = 0 ;
function doCallback ( errCode ) {
assert ( FS . syncFSRequests > 0 ) ;
FS . syncFSRequests -- ;
return callback ( errCode ) ;
}
function done ( errCode ) {
if ( errCode ) {
if ( ! done . errored ) {
done . errored = true ;
return doCallback ( errCode ) ;
}
return ;
}
if ( ++ completed >= mounts . length ) {
doCallback ( null ) ;
}
} ;
// sync all mounts
mounts . forEach ( ( mount ) => {
if ( ! mount . type . syncfs ) {
return done ( null ) ;
}
mount . type . syncfs ( mount , populate , done ) ;
} ) ;
} , mount : ( type , opts , mountpoint ) => {
if ( typeof type == 'string' ) {
// The filesystem was not included, and instead we have an error
// message stored in the variable.
throw type ;
}
var root = mountpoint === '/' ;
var pseudo = ! mountpoint ;
var node ;
if ( root && FS . root ) {
throw new FS . ErrnoError ( 10 ) ;
} else if ( ! root && ! pseudo ) {
var lookup = FS . lookupPath ( mountpoint , { follow _mount : false } ) ;
mountpoint = lookup . path ; // use the absolute 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 : [ ]
} ;
// create a root node for the fs
var mountRoot = type . mount ( mount ) ;
mountRoot . mount = mount ;
mount . root = mountRoot ;
if ( root ) {
FS . root = mountRoot ;
} else if ( node ) {
// set as a mountpoint
node . mounted = mount ;
// add the new mount to the current mount's children
if ( node . mount ) {
node . mount . mounts . push ( mount ) ;
}
}
return mountRoot ;
} , unmount : ( mountpoint ) => {
var lookup = FS . lookupPath ( mountpoint , { follow _mount : false } ) ;
if ( ! FS . isMountpoint ( lookup . node ) ) {
throw new FS . ErrnoError ( 28 ) ;
}
// destroy the nodes for this mount, and all its child mounts
var node = lookup . node ;
var mount = node . mounted ;
var mounts = FS . getMounts ( mount ) ;
Object . keys ( FS . nameTable ) . forEach ( ( hash ) => {
var current = FS . nameTable [ hash ] ;
while ( current ) {
var next = current . name _next ;
if ( mounts . includes ( current . mount ) ) {
FS . destroyNode ( current ) ;
}
current = next ;
}
} ) ;
// no longer a mountpoint
node . mounted = null ;
// remove this mount from the child mounts
var idx = node . mount . mounts . indexOf ( mount ) ;
assert ( idx !== - 1 ) ;
node . mount . mounts . splice ( idx , 1 ) ;
} , lookup : ( parent , name ) => {
return parent . node _ops . lookup ( parent , name ) ;
} , mknod : ( path , mode , dev ) => {
var lookup = FS . lookupPath ( path , { parent : true } ) ;
var parent = lookup . node ;
var name = PATH . basename ( path ) ;
if ( ! name || name === '.' || name === '..' ) {
throw new FS . ErrnoError ( 28 ) ;
}
var errCode = FS . mayCreate ( parent , name ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
if ( ! parent . node _ops . mknod ) {
throw new FS . ErrnoError ( 63 ) ;
}
return parent . node _ops . mknod ( parent , name , mode , dev ) ;
} , create : ( path , mode ) => {
mode = mode !== undefined ? mode : 438 /* 0666 */ ;
mode &= 4095 ;
mode |= 32768 ;
return FS . mknod ( path , mode , 0 ) ;
} , mkdir : ( path , mode ) => {
mode = mode !== undefined ? mode : 511 /* 0777 */ ;
mode &= 511 | 512 ;
mode |= 16384 ;
return FS . mknod ( path , mode , 0 ) ;
} , mkdirTree : ( path , mode ) => {
var dirs = path . split ( '/' ) ;
var d = '' ;
for ( var i = 0 ; i < dirs . length ; ++ i ) {
if ( ! dirs [ i ] ) continue ;
d += '/' + dirs [ i ] ;
try {
FS . mkdir ( d , mode ) ;
} catch ( e ) {
if ( e . errno != 20 ) throw e ;
}
}
} , mkdev : ( path , mode , dev ) => {
if ( typeof dev == 'undefined' ) {
dev = mode ;
mode = 438 /* 0666 */ ;
}
mode |= 8192 ;
return FS . mknod ( path , mode , dev ) ;
} , symlink : ( oldpath , newpath ) => {
if ( ! PATH _FS . resolve ( oldpath ) ) {
throw new FS . ErrnoError ( 44 ) ;
}
var lookup = FS . lookupPath ( newpath , { parent : true } ) ;
var parent = lookup . node ;
if ( ! parent ) {
throw new FS . ErrnoError ( 44 ) ;
}
var newname = PATH . basename ( newpath ) ;
var errCode = FS . mayCreate ( parent , newname ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
if ( ! parent . node _ops . symlink ) {
throw new FS . ErrnoError ( 63 ) ;
}
return parent . node _ops . symlink ( parent , newname , oldpath ) ;
} , rename : ( old _path , new _path ) => {
var old _dirname = PATH . dirname ( old _path ) ;
var new _dirname = PATH . dirname ( new _path ) ;
var old _name = PATH . basename ( old _path ) ;
var new _name = PATH . basename ( new _path ) ;
// parents must exist
var lookup , old _dir , new _dir ;
// let the errors from non existant directories percolate up
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 ) ;
// need to be part of the same mount
if ( old _dir . mount !== new _dir . mount ) {
throw new FS . ErrnoError ( 75 ) ;
}
// source must exist
var old _node = FS . lookupNode ( old _dir , old _name ) ;
// old path should not be an ancestor of the new path
var relative = PATH _FS . relative ( old _path , new _dirname ) ;
if ( relative . charAt ( 0 ) !== '.' ) {
throw new FS . ErrnoError ( 28 ) ;
}
// new path should not be an ancestor of the old path
relative = PATH _FS . relative ( new _path , old _dirname ) ;
if ( relative . charAt ( 0 ) !== '.' ) {
throw new FS . ErrnoError ( 55 ) ;
}
// see if the new path already exists
var new _node ;
try {
new _node = FS . lookupNode ( new _dir , new _name ) ;
} catch ( e ) {
// not fatal
}
// early out if nothing needs to change
if ( old _node === new _node ) {
return ;
}
// we'll need to delete the old entry
var isdir = FS . isDir ( old _node . mode ) ;
var errCode = FS . mayDelete ( old _dir , old _name , isdir ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
// need delete permissions if we'll be overwriting.
// need create permissions if new doesn't already exist.
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 we are going to change the parent, check write permissions
if ( new _dir !== old _dir ) {
errCode = FS . nodePermissions ( old _dir , 'w' ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
}
// remove the node from the lookup hash
FS . hashRemoveNode ( old _node ) ;
// do the underlying fs rename
try {
old _dir . node _ops . rename ( old _node , new _dir , new _name ) ;
} catch ( e ) {
throw e ;
} finally {
// add the node back to the hash (in case node_ops.rename
// changed its name)
FS . hashAddNode ( old _node ) ;
}
} , rmdir : ( path ) => {
var lookup = FS . lookupPath ( path , { parent : true } ) ;
var parent = lookup . node ;
var name = PATH . basename ( path ) ;
var node = FS . lookupNode ( parent , name ) ;
var errCode = FS . mayDelete ( parent , name , true ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
if ( ! parent . node _ops . rmdir ) {
throw new FS . ErrnoError ( 63 ) ;
}
if ( FS . isMountpoint ( node ) ) {
throw new FS . ErrnoError ( 10 ) ;
}
parent . node _ops . rmdir ( parent , name ) ;
FS . destroyNode ( node ) ;
} , readdir : ( path ) => {
var lookup = FS . lookupPath ( path , { follow : true } ) ;
var node = lookup . node ;
if ( ! node . node _ops . readdir ) {
throw new FS . ErrnoError ( 54 ) ;
}
return node . node _ops . readdir ( node ) ;
} , unlink : ( path ) => {
var lookup = FS . lookupPath ( path , { parent : true } ) ;
var parent = lookup . node ;
if ( ! parent ) {
throw new FS . ErrnoError ( 44 ) ;
}
var name = PATH . basename ( path ) ;
var node = FS . lookupNode ( parent , name ) ;
var errCode = FS . mayDelete ( parent , name , false ) ;
if ( errCode ) {
// According to POSIX, we should map EISDIR to EPERM, but
// we instead do what Linux does (and we must, as we use
// the musl linux libc).
throw new FS . ErrnoError ( errCode ) ;
}
if ( ! parent . node _ops . unlink ) {
throw new FS . ErrnoError ( 63 ) ;
}
if ( FS . isMountpoint ( node ) ) {
throw new FS . ErrnoError ( 10 ) ;
}
parent . node _ops . unlink ( parent , name ) ;
FS . destroyNode ( node ) ;
} , readlink : ( path ) => {
var lookup = FS . lookupPath ( path ) ;
var link = lookup . node ;
if ( ! link ) {
throw new FS . ErrnoError ( 44 ) ;
}
if ( ! link . node _ops . readlink ) {
throw new FS . ErrnoError ( 28 ) ;
}
return PATH _FS . resolve ( FS . getPath ( link . parent ) , link . node _ops . readlink ( link ) ) ;
} , stat : ( path , dontFollow ) => {
var lookup = FS . lookupPath ( path , { follow : ! dontFollow } ) ;
var node = lookup . node ;
if ( ! node ) {
throw new FS . ErrnoError ( 44 ) ;
}
if ( ! node . node _ops . getattr ) {
throw new FS . ErrnoError ( 63 ) ;
}
return node . node _ops . getattr ( node ) ;
} , lstat : ( path ) => {
return FS . stat ( path , true ) ;
} , chmod : ( path , mode , dontFollow ) => {
var node ;
if ( typeof path == 'string' ) {
var lookup = FS . lookupPath ( path , { follow : ! dontFollow } ) ;
node = lookup . node ;
} else {
node = path ;
}
if ( ! node . node _ops . setattr ) {
throw new FS . ErrnoError ( 63 ) ;
}
node . node _ops . setattr ( node , {
mode : ( mode & 4095 ) | ( node . mode & ~ 4095 ) ,
timestamp : Date . now ( )
} ) ;
} , lchmod : ( path , mode ) => {
FS . chmod ( path , mode , true ) ;
} , fchmod : ( fd , mode ) => {
var stream = FS . getStream ( fd ) ;
if ( ! stream ) {
throw new FS . ErrnoError ( 8 ) ;
}
FS . chmod ( stream . node , mode ) ;
} , chown : ( path , uid , gid , dontFollow ) => {
var node ;
if ( typeof path == 'string' ) {
var lookup = FS . lookupPath ( path , { follow : ! dontFollow } ) ;
node = lookup . node ;
} else {
node = path ;
}
if ( ! node . node _ops . setattr ) {
throw new FS . ErrnoError ( 63 ) ;
}
node . node _ops . setattr ( node , {
timestamp : Date . now ( )
// we ignore the uid / gid for now
} ) ;
} , lchown : ( path , uid , gid ) => {
FS . chown ( path , uid , gid , true ) ;
} , fchown : ( fd , uid , gid ) => {
var stream = FS . getStream ( fd ) ;
if ( ! stream ) {
throw new FS . ErrnoError ( 8 ) ;
}
FS . chown ( stream . node , uid , gid ) ;
} , truncate : ( path , len ) => {
if ( len < 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
var node ;
if ( typeof path == 'string' ) {
var lookup = FS . lookupPath ( path , { follow : true } ) ;
node = lookup . node ;
} else {
node = path ;
}
if ( ! node . node _ops . setattr ) {
throw new FS . ErrnoError ( 63 ) ;
}
if ( FS . isDir ( node . mode ) ) {
throw new FS . ErrnoError ( 31 ) ;
}
if ( ! FS . isFile ( node . mode ) ) {
throw new FS . ErrnoError ( 28 ) ;
}
var errCode = FS . nodePermissions ( node , 'w' ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
node . node _ops . setattr ( node , {
size : len ,
timestamp : Date . now ( )
} ) ;
} , ftruncate : ( fd , len ) => {
var stream = FS . getStream ( fd ) ;
if ( ! stream ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ( stream . flags & 2097155 ) === 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
FS . truncate ( stream . node , len ) ;
} , utime : ( path , atime , mtime ) => {
var lookup = FS . lookupPath ( path , { follow : true } ) ;
var node = lookup . node ;
node . node _ops . setattr ( node , {
timestamp : Math . max ( atime , mtime )
} ) ;
} , open : ( path , flags , mode ) => {
if ( path === "" ) {
throw new FS . ErrnoError ( 44 ) ;
}
flags = typeof flags == 'string' ? FS _modeStringToFlags ( flags ) : flags ;
mode = typeof mode == 'undefined' ? 438 /* 0666 */ : 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 ) {
// ignore
}
}
// perhaps we need to create the node
var created = false ;
if ( ( flags & 64 ) ) {
if ( node ) {
// if O_CREAT and O_EXCL are set, error out if the node already exists
if ( ( flags & 128 ) ) {
throw new FS . ErrnoError ( 20 ) ;
}
} else {
// node doesn't exist, try to create it
node = FS . mknod ( path , mode , 0 ) ;
created = true ;
}
}
if ( ! node ) {
throw new FS . ErrnoError ( 44 ) ;
}
// can't truncate a device
if ( FS . isChrdev ( node . mode ) ) {
flags &= ~ 512 ;
}
// if asked only for a directory, then this must be one
if ( ( flags & 65536 ) && ! FS . isDir ( node . mode ) ) {
throw new FS . ErrnoError ( 54 ) ;
}
// check permissions, if this is not a file we just created now (it is ok to
// create and write to a file with read-only permissions; it is read-only
// for later use)
if ( ! created ) {
var errCode = FS . mayOpen ( node , flags ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
}
// do truncation if necessary
if ( ( flags & 512 ) && ! created ) {
FS . truncate ( node , 0 ) ;
}
// we've already handled these, don't pass down to the underlying vfs
flags &= ~ ( 128 | 512 | 131072 ) ;
// register the stream with the filesystem
var stream = FS . createStream ( {
node : node ,
path : FS . getPath ( node ) , // we want the absolute path to the node
flags : flags ,
seekable : true ,
position : 0 ,
stream _ops : node . stream _ops ,
// used by the file family libc calls (fopen, fwrite, ferror, etc.)
ungotten : [ ] ,
error : false
} ) ;
// call the new stream's open function
if ( stream . stream _ops . open ) {
stream . stream _ops . open ( stream ) ;
}
if ( Module [ 'logReadFiles' ] && ! ( flags & 1 ) ) {
if ( ! FS . readFiles ) FS . readFiles = { } ;
if ( ! ( path in FS . readFiles ) ) {
FS . readFiles [ path ] = 1 ;
}
}
return stream ;
} , close : ( stream ) => {
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( stream . getdents ) stream . getdents = null ; // free readdir state
try {
if ( stream . stream _ops . close ) {
stream . stream _ops . close ( stream ) ;
}
} catch ( e ) {
throw e ;
} finally {
FS . closeStream ( stream . fd ) ;
}
stream . fd = null ;
} , isClosed : ( stream ) => {
return stream . fd === null ;
} , llseek : ( stream , offset , whence ) => {
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ! stream . seekable || ! stream . stream _ops . llseek ) {
throw new FS . ErrnoError ( 70 ) ;
}
if ( whence != 0 && whence != 1 && whence != 2 ) {
throw new FS . ErrnoError ( 28 ) ;
}
stream . position = stream . stream _ops . llseek ( stream , offset , whence ) ;
stream . ungotten = [ ] ;
return stream . position ;
} , read : ( stream , buffer , offset , length , position ) => {
if ( length < 0 || position < 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ( stream . flags & 2097155 ) === 1 ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( FS . isDir ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 31 ) ;
}
if ( ! stream . stream _ops . read ) {
throw new FS . ErrnoError ( 28 ) ;
}
var seeking = typeof position != 'undefined' ;
if ( ! seeking ) {
position = stream . position ;
} else if ( ! stream . seekable ) {
throw new FS . ErrnoError ( 70 ) ;
}
var bytesRead = stream . stream _ops . read ( stream , buffer , offset , length , position ) ;
if ( ! seeking ) stream . position += bytesRead ;
return bytesRead ;
} , write : ( stream , buffer , offset , length , position , canOwn ) => {
if ( length < 0 || position < 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ( stream . flags & 2097155 ) === 0 ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( FS . isDir ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 31 ) ;
}
if ( ! stream . stream _ops . write ) {
throw new FS . ErrnoError ( 28 ) ;
}
if ( stream . seekable && stream . flags & 1024 ) {
// seek to the end before writing in append mode
FS . llseek ( stream , 0 , 2 ) ;
}
var seeking = typeof position != 'undefined' ;
if ( ! seeking ) {
position = stream . position ;
} else if ( ! stream . seekable ) {
throw new FS . ErrnoError ( 70 ) ;
}
var bytesWritten = stream . stream _ops . write ( stream , buffer , offset , length , position , canOwn ) ;
if ( ! seeking ) stream . position += bytesWritten ;
return bytesWritten ;
} , allocate : ( stream , offset , length ) => {
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( offset < 0 || length <= 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
if ( ( stream . flags & 2097155 ) === 0 ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ! FS . isFile ( stream . node . mode ) && ! FS . isDir ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 43 ) ;
}
if ( ! stream . stream _ops . allocate ) {
throw new FS . ErrnoError ( 138 ) ;
}
stream . stream _ops . allocate ( stream , offset , length ) ;
} , mmap : ( stream , length , position , prot , flags ) => {
// User requests writing to file (prot & PROT_WRITE != 0).
// Checking if we have permissions to write to the file unless
// MAP_PRIVATE flag is set. According to POSIX spec it is possible
// to write to file opened in read-only mode with MAP_PRIVATE flag,
// as all modifications will be visible only in the memory of
// the current process.
if ( ( prot & 2 ) !== 0
&& ( flags & 2 ) === 0
&& ( stream . flags & 2097155 ) !== 2 ) {
throw new FS . ErrnoError ( 2 ) ;
}
if ( ( stream . flags & 2097155 ) === 1 ) {
throw new FS . ErrnoError ( 2 ) ;
}
if ( ! stream . stream _ops . mmap ) {
throw new FS . ErrnoError ( 43 ) ;
}
return stream . stream _ops . mmap ( stream , length , position , prot , flags ) ;
} , msync : ( stream , buffer , offset , length , mmapFlags ) => {
if ( ! stream . stream _ops . msync ) {
return 0 ;
}
return stream . stream _ops . msync ( stream , buffer , offset , length , mmapFlags ) ;
} , munmap : ( stream ) => 0 , ioctl : ( stream , cmd , arg ) => {
if ( ! stream . stream _ops . ioctl ) {
throw new FS . ErrnoError ( 59 ) ;
}
return stream . stream _ops . ioctl ( stream , cmd , arg ) ;
} , readFile : ( path , opts = { } ) => {
opts . flags = opts . flags || 0 ;
opts . encoding = opts . encoding || 'binary' ;
if ( opts . encoding !== 'utf8' && opts . encoding !== 'binary' ) {
throw new Error ( ` Invalid encoding type " ${ opts . encoding } " ` ) ;
}
var ret ;
var stream = FS . open ( path , opts . flags ) ;
var stat = FS . stat ( path ) ;
var length = stat . size ;
var buf = new Uint8Array ( length ) ;
FS . read ( stream , buf , 0 , length , 0 ) ;
if ( opts . encoding === 'utf8' ) {
ret = UTF8ArrayToString ( buf , 0 ) ;
} else if ( opts . encoding === 'binary' ) {
ret = buf ;
}
FS . close ( stream ) ;
return ret ;
} , writeFile : ( path , data , opts = { } ) => {
opts . flags = opts . flags || 577 ;
var stream = FS . open ( path , opts . flags , opts . mode ) ;
if ( typeof data == 'string' ) {
var buf = new Uint8Array ( lengthBytesUTF8 ( data ) + 1 ) ;
var actualNumBytes = stringToUTF8Array ( data , buf , 0 , buf . length ) ;
FS . write ( stream , buf , 0 , actualNumBytes , undefined , opts . canOwn ) ;
} else if ( ArrayBuffer . isView ( data ) ) {
FS . write ( stream , data , 0 , data . byteLength , undefined , opts . canOwn ) ;
} else {
throw new Error ( 'Unsupported data type' ) ;
}
FS . close ( stream ) ;
} , cwd : ( ) => FS . currentPath , chdir : ( path ) => {
var lookup = FS . lookupPath ( path , { follow : true } ) ;
if ( lookup . node === null ) {
throw new FS . ErrnoError ( 44 ) ;
}
if ( ! FS . isDir ( lookup . node . mode ) ) {
throw new FS . ErrnoError ( 54 ) ;
}
var errCode = FS . nodePermissions ( lookup . node , 'x' ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
FS . currentPath = lookup . path ;
} , createDefaultDirectories : ( ) => {
FS . mkdir ( '/tmp' ) ;
FS . mkdir ( '/home' ) ;
FS . mkdir ( '/home/web_user' ) ;
} , createDefaultDevices : ( ) => {
// create /dev
FS . mkdir ( '/dev' ) ;
// setup /dev/null
FS . registerDevice ( FS . makedev ( 1 , 3 ) , {
read : ( ) => 0 ,
write : ( stream , buffer , offset , length , pos ) => length ,
} ) ;
FS . mkdev ( '/dev/null' , FS . makedev ( 1 , 3 ) ) ;
// setup /dev/tty and /dev/tty1
// stderr needs to print output using err() rather than out()
// so we register a second tty just for it.
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 ) ) ;
// setup /dev/[u]random
// use a buffer to avoid overhead of individual crypto calls per byte
var randomBuffer = new Uint8Array ( 1024 ) , randomLeft = 0 ;
var randomByte = ( ) => {
if ( randomLeft === 0 ) {
randomLeft = randomFill ( randomBuffer ) . byteLength ;
}
return randomBuffer [ -- randomLeft ] ;
} ;
FS . createDevice ( '/dev' , 'random' , randomByte ) ;
FS . createDevice ( '/dev' , 'urandom' , randomByte ) ;
// we're not going to emulate the actual shm device,
// just create the tmp dirs that reside in it commonly
FS . mkdir ( '/dev/shm' ) ;
FS . mkdir ( '/dev/shm/tmp' ) ;
} , createSpecialDirectories : ( ) => {
// create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
// name of the stream for fd 6 (see test_unistd_ttyname)
FS . mkdir ( '/proc' ) ;
var proc _self = FS . mkdir ( '/proc/self' ) ;
FS . mkdir ( '/proc/self/fd' ) ;
FS . mount ( {
mount : ( ) => {
var node = FS . createNode ( proc _self , 'fd' , 16384 | 511 /* 0777 */ , 73 ) ;
node . node _ops = {
lookup : ( parent , name ) => {
var fd = + name ;
var stream = FS . getStream ( fd ) ;
if ( ! stream ) throw new FS . ErrnoError ( 8 ) ;
var ret = {
parent : null ,
mount : { mountpoint : 'fake' } ,
node _ops : { readlink : ( ) => stream . path } ,
} ;
ret . parent = ret ; // make it look like a simple root node
return ret ;
}
} ;
return node ;
}
} , { } , '/proc/self/fd' ) ;
} , createStandardStreams : ( ) => {
// TODO deprecate the old functionality of a single
// input / output callback and that utilizes FS.createDevice
// and instead require a unique set of stream ops
// by default, we symlink the standard streams to the
// default tty devices. however, if the standard streams
// have been overwritten we create a unique device for
// them instead.
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' ) ;
}
// open default streams for the stdin, stdout and stderr devices
var stdin = FS . open ( '/dev/stdin' , 0 ) ;
var stdout = FS . open ( '/dev/stdout' , 1 ) ;
var stderr = FS . open ( '/dev/stderr' , 1 ) ;
assert ( stdin . fd === 0 , ` invalid handle for stdin ( ${ stdin . fd } ) ` ) ;
assert ( stdout . fd === 1 , ` invalid handle for stdout ( ${ stdout . fd } ) ` ) ;
assert ( stderr . fd === 2 , ` invalid handle for stderr ( ${ stderr . fd } ) ` ) ;
} , ensureErrnoError : ( ) => {
if ( FS . ErrnoError ) return ;
FS . ErrnoError = /** @this{Object} */ function ErrnoError ( errno , node ) {
// We set the `name` property to be able to identify `FS.ErrnoError`
// - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway.
// - when using PROXYFS, an error can come from an underlying FS
// as different FS objects have their own FS.ErrnoError each,
// the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs.
// we'll use the reliable test `err.name == "ErrnoError"` instead
this . name = 'ErrnoError' ;
this . node = node ;
this . setErrno = /** @this{Object} */ 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 ] ;
// Try to get a maximally helpful stack trace. On Node.js, getting Error.stack
// now ensures it shows what we want.
if ( this . stack ) {
// Define the stack property for Node.js 4, which otherwise errors on the next line.
Object . defineProperty ( this , "stack" , { value : ( new Error ) . stack , writable : true } ) ;
this . stack = demangleAll ( this . stack ) ;
}
} ;
FS . ErrnoError . prototype = new Error ( ) ;
FS . ErrnoError . prototype . constructor = FS . ErrnoError ;
// Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
[ 44 ] . forEach ( ( code ) => {
FS . genericErrors [ code ] = new FS . ErrnoError ( code ) ;
FS . genericErrors [ code ] . stack = '<generic error, no stack>' ;
} ) ;
} , staticInit : ( ) => {
FS . ensureErrnoError ( ) ;
FS . nameTable = new Array ( 4096 ) ;
FS . mount ( MEMFS , { } , '/' ) ;
FS . createDefaultDirectories ( ) ;
FS . createDefaultDevices ( ) ;
FS . createSpecialDirectories ( ) ;
FS . filesystems = {
'MEMFS' : MEMFS ,
} ;
} , init : ( input , output , error ) => {
assert ( ! FS . init . initialized , 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)' ) ;
FS . init . initialized = true ;
FS . ensureErrnoError ( ) ;
// Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
Module [ 'stdin' ] = input || Module [ 'stdin' ] ;
Module [ 'stdout' ] = output || Module [ 'stdout' ] ;
Module [ 'stderr' ] = error || Module [ 'stderr' ] ;
FS . createStandardStreams ( ) ;
} , quit : ( ) => {
FS . init . initialized = false ;
// force-flush all streams, so we get musl std streams printed out
_fflush ( 0 ) ;
// close all of our streams
for ( var i = 0 ; i < FS . streams . length ; i ++ ) {
var stream = FS . streams [ i ] ;
if ( ! stream ) {
continue ;
}
FS . close ( stream ) ;
}
} , findObject : ( path , dontResolveLastLink ) => {
var ret = FS . analyzePath ( path , dontResolveLastLink ) ;
if ( ! ret . exists ) {
return null ;
}
return ret . object ;
} , analyzePath : ( path , dontResolveLastLink ) => {
// operate from within the context of the symlink's target
try {
var lookup = FS . lookupPath ( path , { follow : ! dontResolveLastLink } ) ;
path = lookup . path ;
} catch ( e ) {
}
var ret = {
isRoot : false , exists : false , error : 0 , name : null , path : null , object : null ,
parentExists : false , parentPath : null , parentObject : null
} ;
try {
var lookup = FS . lookupPath ( path , { parent : true } ) ;
ret . parentExists = true ;
ret . parentPath = lookup . path ;
ret . parentObject = lookup . node ;
ret . name = PATH . basename ( path ) ;
lookup = FS . lookupPath ( path , { follow : ! dontResolveLastLink } ) ;
ret . exists = true ;
ret . path = lookup . path ;
ret . object = lookup . node ;
ret . name = lookup . node . name ;
ret . isRoot = lookup . path === '/' ;
} catch ( e ) {
ret . error = e . errno ;
} ;
return ret ;
} , createPath : ( parent , path , canRead , canWrite ) => {
parent = typeof parent == 'string' ? parent : FS . getPath ( parent ) ;
var parts = path . split ( '/' ) . reverse ( ) ;
while ( parts . length ) {
var part = parts . pop ( ) ;
if ( ! part ) continue ;
var current = PATH . join2 ( parent , part ) ;
try {
FS . mkdir ( current ) ;
} catch ( e ) {
// ignore EEXIST
}
parent = current ;
}
return current ;
} , createFile : ( parent , name , properties , canRead , canWrite ) => {
var path = PATH . join2 ( typeof parent == 'string' ? parent : FS . getPath ( parent ) , name ) ;
var mode = FS _getMode ( canRead , canWrite ) ;
return FS . create ( path , mode ) ;
} , createDataFile : ( parent , name , data , canRead , canWrite , canOwn ) => {
var path = name ;
if ( parent ) {
parent = typeof parent == 'string' ? parent : FS . getPath ( parent ) ;
path = name ? PATH . join2 ( parent , name ) : parent ;
}
var mode = FS _getMode ( canRead , canWrite ) ;
var node = FS . create ( path , mode ) ;
if ( data ) {
if ( typeof data == 'string' ) {
var arr = new Array ( data . length ) ;
for ( var i = 0 , len = data . length ; i < len ; ++ i ) arr [ i ] = data . charCodeAt ( i ) ;
data = arr ;
}
// make sure we can write to the file
FS . chmod ( node , mode | 146 ) ;
var stream = FS . open ( node , 577 ) ;
FS . write ( stream , data , 0 , data . length , 0 , canOwn ) ;
FS . close ( stream ) ;
FS . chmod ( node , mode ) ;
}
return node ;
} , createDevice : ( parent , name , input , output ) => {
var path = PATH . join2 ( typeof parent == 'string' ? parent : FS . getPath ( parent ) , name ) ;
var mode = FS _getMode ( ! ! input , ! ! output ) ;
if ( ! FS . createDevice . major ) FS . createDevice . major = 64 ;
var dev = FS . makedev ( FS . createDevice . major ++ , 0 ) ;
// Create a fake device that a set of stream ops to emulate
// the old behavior.
FS . registerDevice ( dev , {
open : ( stream ) => {
stream . seekable = false ;
} ,
close : ( stream ) => {
// flush any pending line data
if ( output && output . buffer && output . buffer . length ) {
output ( 10 ) ;
}
} ,
read : ( stream , buffer , offset , length , pos /* ignored */ ) => {
var bytesRead = 0 ;
for ( var i = 0 ; i < length ; i ++ ) {
var result ;
try {
result = input ( ) ;
} catch ( e ) {
throw new FS . ErrnoError ( 29 ) ;
}
if ( result === undefined && bytesRead === 0 ) {
throw new FS . ErrnoError ( 6 ) ;
}
if ( result === null || result === undefined ) break ;
bytesRead ++ ;
buffer [ offset + i ] = result ;
}
if ( bytesRead ) {
stream . node . timestamp = Date . now ( ) ;
}
return bytesRead ;
} ,
write : ( stream , buffer , offset , length , pos ) => {
for ( var i = 0 ; i < length ; i ++ ) {
try {
output ( buffer [ offset + i ] ) ;
} catch ( e ) {
throw new FS . ErrnoError ( 29 ) ;
}
}
if ( length ) {
stream . node . timestamp = Date . now ( ) ;
}
return i ;
}
} ) ;
return FS . mkdev ( path , mode , dev ) ;
} , forceLoadFile : ( obj ) => {
if ( obj . isDevice || obj . isFolder || obj . link || obj . contents ) return true ;
if ( typeof XMLHttpRequest != 'undefined' ) {
throw new Error ( "Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread." ) ;
} else if ( read _ ) {
// Command-line.
try {
// WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
// read() will try to parse UTF8.
obj . contents = intArrayFromString ( read _ ( obj . url ) , true ) ;
obj . usedBytes = obj . contents . length ;
} catch ( e ) {
throw new FS . ErrnoError ( 29 ) ;
}
} else {
throw new Error ( 'Cannot load without read() or XMLHttpRequest.' ) ;
}
} , createLazyFile : ( parent , name , url , canRead , canWrite ) => {
// Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
/** @constructor */
function LazyUint8Array ( ) {
this . lengthKnown = false ;
this . chunks = [ ] ; // Loaded chunks. Index is the chunk number
}
LazyUint8Array . prototype . get = /** @this{Object} */ 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 ( ) {
// Find length
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 ; // Chunk size in bytes
if ( ! hasByteServing ) chunkSize = datalength ;
// Function to get a range from the remote URL.
var doXHR = ( from , to ) => {
if ( from > to ) throw new Error ( "invalid range (" + from + ", " + to + ") or no bytes requested!" ) ;
if ( to > datalength - 1 ) throw new Error ( "only " + datalength + " bytes available! programmer error!" ) ;
// TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
var xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , url , false ) ;
if ( datalength !== chunkSize ) xhr . setRequestHeader ( "Range" , "bytes=" + from + "-" + to ) ;
// Some hints to the browser that we want binary data.
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 ( /** @type{Array<number>} */ ( xhr . response || [ ] ) ) ;
}
return intArrayFromString ( xhr . responseText || '' , true ) ;
} ;
var lazyArray = this ;
lazyArray . setDataGetter ( ( chunkNum ) => {
var start = chunkNum * chunkSize ;
var end = ( chunkNum + 1 ) * chunkSize - 1 ; // including this byte
end = Math . min ( end , datalength - 1 ) ; // if datalength-1 is selected, this is the last block
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 ) {
// if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
chunkSize = datalength = 1 ; // this will force getter(0)/doXHR do download the whole file
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 : /** @this{Object} */ function ( ) {
if ( ! this . lengthKnown ) {
this . cacheLength ( ) ;
}
return this . _length ;
}
} ,
chunkSize : {
get : /** @this{Object} */ 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 ) ;
// This is a total hack, but I want to get this lazy file code out of the
// core of MEMFS. If we want to keep this lazy file concept I feel it should
// be its own thin LAZYFS proxying calls to MEMFS.
if ( properties . contents ) {
node . contents = properties . contents ;
} else if ( properties . url ) {
node . contents = null ;
node . url = properties . url ;
}
// Add a function that defers querying the file size until it is asked the first time.
Object . defineProperties ( node , {
usedBytes : {
get : /** @this {FSNode} */ function ( ) { return this . contents . length ; }
}
} ) ;
// override each stream op with one that tries to force load the lazy file first
var stream _ops = { } ;
var keys = Object . keys ( node . stream _ops ) ;
keys . forEach ( ( key ) => {
var fn = node . stream _ops [ key ] ;
stream _ops [ key ] = function forceLoadLazyFile ( ) {
FS . forceLoadFile ( node ) ;
return fn . apply ( null , arguments ) ;
} ;
} ) ;
function writeChunks ( stream , buffer , offset , length , position ) {
var contents = stream . node . contents ;
if ( position >= contents . length )
return 0 ;
var size = Math . min ( contents . length - position , length ) ;
assert ( size >= 0 ) ;
if ( contents . slice ) { // normal array
for ( var i = 0 ; i < size ; i ++ ) {
buffer [ offset + i ] = contents [ position + i ] ;
}
} else {
for ( var i = 0 ; i < size ; i ++ ) { // LazyUint8Array from sync binary XHR
buffer [ offset + i ] = contents . get ( position + i ) ;
}
}
return size ;
}
// use a custom read function
stream _ops . read = ( stream , buffer , offset , length , position ) => {
FS . forceLoadFile ( node ) ;
return writeChunks ( stream , buffer , offset , length , position )
} ;
// use a custom mmap function
stream _ops . mmap = ( stream , length , position , prot , flags ) => {
FS . forceLoadFile ( node ) ;
var ptr = mmapAlloc ( length ) ;
if ( ! ptr ) {
throw new FS . ErrnoError ( 48 ) ;
}
writeChunks ( stream , HEAP8 , ptr , length , position ) ;
return { ptr : ptr , allocated : true } ;
} ;
node . stream _ops = stream _ops ;
return node ;
} , absolutePath : ( ) => {
abort ( 'FS.absolutePath has been removed; use PATH_FS.resolve instead' ) ;
} , createFolder : ( ) => {
abort ( 'FS.createFolder has been removed; use FS.mkdir instead' ) ;
} , createLink : ( ) => {
abort ( 'FS.createLink has been removed; use FS.symlink instead' ) ;
} , joinPath : ( ) => {
abort ( 'FS.joinPath has been removed; use PATH.join instead' ) ;
} , mmapAlloc : ( ) => {
abort ( 'FS.mmapAlloc has been replaced by the top level function mmapAlloc' ) ;
} , standardizePath : ( ) => {
abort ( 'FS.standardizePath has been removed; use PATH.normalize instead' ) ;
} } ;
var SYSCALLS = { DEFAULT _POLLMASK : 5 , calculateAt : function ( dirfd , path , allowEmpty ) {
if ( PATH . isAbs ( path ) ) {
return path ;
}
// relative path
var dir ;
if ( dirfd === - 100 ) {
dir = FS . cwd ( ) ;
} else {
var dirstream = SYSCALLS . getStreamFromFD ( dirfd ) ;
dir = dirstream . path ;
}
if ( path . length == 0 ) {
if ( ! allowEmpty ) {
throw new FS . ErrnoError ( 44 ) ; ;
}
return dir ;
}
return PATH . join2 ( dir , path ) ;
} , doStat : function ( func , path , buf ) {
try {
var stat = func ( path ) ;
} catch ( e ) {
if ( e && e . node && PATH . normalize ( path ) !== PATH . normalize ( FS . getPath ( e . node ) ) ) {
// an error occurred while trying to look up the path; we should just report ENOTDIR
return - 54 ;
}
throw e ;
}
HEAP32 [ ( ( buf ) >> 2 ) ] = stat . dev ;
HEAP32 [ ( ( ( buf ) + ( 8 ) ) >> 2 ) ] = stat . ino ;
HEAP32 [ ( ( ( buf ) + ( 12 ) ) >> 2 ) ] = stat . mode ;
HEAPU32 [ ( ( ( buf ) + ( 16 ) ) >> 2 ) ] = stat . nlink ;
HEAP32 [ ( ( ( buf ) + ( 20 ) ) >> 2 ) ] = stat . uid ;
HEAP32 [ ( ( ( buf ) + ( 24 ) ) >> 2 ) ] = stat . gid ;
HEAP32 [ ( ( ( buf ) + ( 28 ) ) >> 2 ) ] = stat . rdev ;
( tempI64 = [ stat . size >>> 0 , ( tempDouble = stat . size , ( + ( Math . abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( + ( Math . floor ( ( tempDouble ) / 4294967296.0 ) ) ) >>> 0 : ( ~ ~ ( ( + ( Math . ceil ( ( tempDouble - + ( ( ( ~ ~ ( tempDouble ) ) ) >>> 0 ) ) / 4294967296.0 ) ) ) ) ) >>> 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 ;
var atime = stat . atime . getTime ( ) ;
var mtime = stat . mtime . getTime ( ) ;
var ctime = stat . ctime . getTime ( ) ;
( tempI64 = [ Math . floor ( atime / 1000 ) >>> 0 , ( tempDouble = Math . floor ( atime / 1000 ) , ( + ( Math . abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( + ( Math . floor ( ( tempDouble ) / 4294967296.0 ) ) ) >>> 0 : ( ~ ~ ( ( + ( Math . ceil ( ( tempDouble - + ( ( ( ~ ~ ( tempDouble ) ) ) >>> 0 ) ) / 4294967296.0 ) ) ) ) ) >>> 0 ) : 0 ) ] , HEAP32 [ ( ( ( buf ) + ( 56 ) ) >> 2 ) ] = tempI64 [ 0 ] , HEAP32 [ ( ( ( buf ) + ( 60 ) ) >> 2 ) ] = tempI64 [ 1 ] ) ;
HEAPU32 [ ( ( ( buf ) + ( 64 ) ) >> 2 ) ] = ( atime % 1000 ) * 1000 ;
( tempI64 = [ Math . floor ( mtime / 1000 ) >>> 0 , ( tempDouble = Math . floor ( mtime / 1000 ) , ( + ( Math . abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( + ( Math . floor ( ( tempDouble ) / 4294967296.0 ) ) ) >>> 0 : ( ~ ~ ( ( + ( Math . ceil ( ( tempDouble - + ( ( ( ~ ~ ( tempDouble ) ) ) >>> 0 ) ) / 4294967296.0 ) ) ) ) ) >>> 0 ) : 0 ) ] , HEAP32 [ ( ( ( buf ) + ( 72 ) ) >> 2 ) ] = tempI64 [ 0 ] , HEAP32 [ ( ( ( buf ) + ( 76 ) ) >> 2 ) ] = tempI64 [ 1 ] ) ;
HEAPU32 [ ( ( ( buf ) + ( 80 ) ) >> 2 ) ] = ( mtime % 1000 ) * 1000 ;
( tempI64 = [ Math . floor ( ctime / 1000 ) >>> 0 , ( tempDouble = Math . floor ( ctime / 1000 ) , ( + ( Math . abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( + ( Math . floor ( ( tempDouble ) / 4294967296.0 ) ) ) >>> 0 : ( ~ ~ ( ( + ( Math . ceil ( ( tempDouble - + ( ( ( ~ ~ ( tempDouble ) ) ) >>> 0 ) ) / 4294967296.0 ) ) ) ) ) >>> 0 ) : 0 ) ] , HEAP32 [ ( ( ( buf ) + ( 88 ) ) >> 2 ) ] = tempI64 [ 0 ] , HEAP32 [ ( ( ( buf ) + ( 92 ) ) >> 2 ) ] = tempI64 [ 1 ] ) ;
HEAPU32 [ ( ( ( buf ) + ( 96 ) ) >> 2 ) ] = ( ctime % 1000 ) * 1000 ;
( tempI64 = [ stat . ino >>> 0 , ( tempDouble = stat . ino , ( + ( Math . abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( + ( Math . floor ( ( tempDouble ) / 4294967296.0 ) ) ) >>> 0 : ( ~ ~ ( ( + ( Math . ceil ( ( tempDouble - + ( ( ( ~ ~ ( tempDouble ) ) ) >>> 0 ) ) / 4294967296.0 ) ) ) ) ) >>> 0 ) : 0 ) ] , HEAP32 [ ( ( ( buf ) + ( 104 ) ) >> 2 ) ] = tempI64 [ 0 ] , HEAP32 [ ( ( ( buf ) + ( 108 ) ) >> 2 ) ] = tempI64 [ 1 ] ) ;
return 0 ;
} , doMsync : function ( addr , stream , len , flags , offset ) {
if ( ! FS . isFile ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 43 ) ;
}
if ( flags & 2 ) {
// MAP_PRIVATE calls need not to be synced back to underlying fs
return 0 ;
}
var buffer = HEAPU8 . slice ( addr , addr + len ) ;
FS . msync ( stream , buffer , offset , len , flags ) ;
} , varargs : undefined , get : function ( ) {
assert ( SYSCALLS . varargs != undefined ) ;
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 ;
} } ;
function _ _ _syscall _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 . createStream ( stream , arg ) ;
return newStream . fd ;
}
case 1 :
case 2 :
return 0 ; // FD_CLOEXEC makes no sense for a single process.
case 3 :
return stream . flags ;
case 4 : {
var arg = SYSCALLS . get ( ) ;
stream . flags |= arg ;
return 0 ;
}
case 5 :
/* case 5: Currently in musl F_GETLK64 has same value as F_GETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */ {
var arg = SYSCALLS . get ( ) ;
var offset = 0 ;
// We're always unlocked.
HEAP16 [ ( ( ( arg ) + ( offset ) ) >> 1 ) ] = 2 ;
return 0 ;
}
case 6 :
case 7 :
/* case 6: Currently in musl F_SETLK64 has same value as F_SETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
/* case 7: Currently in musl F_SETLKW64 has same value as F_SETLKW, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
return 0 ; // Pretend that the locking is successful.
case 16 :
case 8 :
return - 28 ; // These are for sockets. We don't have them fully implemented yet.
case 9 :
// musl trusts getown return values, due to a bug where they must be, as they overlap with errors. just return -1 here, so fcntl() returns that, and we set errno ourselves.
setErrNo ( 28 ) ;
return - 1 ;
default : {
return - 28 ;
}
}
} catch ( e ) {
if ( typeof FS == 'undefined' || ! ( e . name === 'ErrnoError' ) ) throw e ;
return - e . errno ;
}
}
function _ _ _syscall _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 ; // no-op, not actually adjusting terminal settings
}
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 ; // not supported
}
case 21531 : {
var argp = SYSCALLS . get ( ) ;
return FS . ioctl ( stream , op , argp ) ;
}
case 21523 : {
// TODO: in theory we should write to the winsize struct that gets
// passed in, but for now musl doesn't read anything on it
if ( ! stream . tty ) return - 59 ;
return 0 ;
}
case 21524 : {
// TODO: technically, this ioctl call should change the window size.
// but, since emscripten doesn't have any concept of a terminal window
// yet, we'll just silently throw it away as we do TIOCGWINSZ
if ( ! stream . tty ) return - 59 ;
return 0 ;
}
default : return - 28 ; // not supported
}
} catch ( e ) {
if ( typeof FS == 'undefined' || ! ( e . name === 'ErrnoError' ) ) throw e ;
return - e . errno ;
}
}
function _ _ _syscall _openat ( dirfd , path , flags , varargs ) {
SYSCALLS . varargs = varargs ;
try {
path = SYSCALLS . getStr ( path ) ;
path = SYSCALLS . calculateAt ( dirfd , path ) ;
var mode = varargs ? SYSCALLS . get ( ) : 0 ;
return FS . open ( path , flags , mode ) . fd ;
} catch ( e ) {
if ( typeof FS == 'undefined' || ! ( e . name === 'ErrnoError' ) ) throw e ;
return - e . errno ;
}
}
var nowIsMonotonic = true ; ;
function _ _emscripten _get _now _is _monotonic ( ) {
return nowIsMonotonic ;
}
function _ _emscripten _throw _longjmp ( ) {
throw Infinity ;
}
function _abort ( ) {
abort ( 'native code called abort()' ) ;
}
function _emscripten _set _main _loop _timing ( mode , value ) {
Browser . mainLoop . timingMode = mode ;
Browser . mainLoop . timingValue = value ;
if ( ! Browser . mainLoop . func ) {
err ( 'emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.' ) ;
return 1 ; // Return non-zero on failure, can't set timing mode when there is no main loop.
}
if ( ! Browser . mainLoop . running ) {
Browser . mainLoop . running = true ;
}
if ( mode == 0 ) {
Browser . mainLoop . scheduler = function Browser _mainLoop _scheduler _setTimeout ( ) {
var timeUntilNextTick = Math . max ( 0 , Browser . mainLoop . tickStartTime + value - _emscripten _get _now ( ) ) | 0 ;
setTimeout ( Browser . mainLoop . runner , timeUntilNextTick ) ; // doing this each time means that on exception, we stop
} ;
Browser . mainLoop . method = 'timeout' ;
} else if ( mode == 1 ) {
Browser . mainLoop . scheduler = function Browser _mainLoop _scheduler _rAF ( ) {
Browser . requestAnimationFrame ( Browser . mainLoop . runner ) ;
} ;
Browser . mainLoop . method = 'rAF' ;
} else if ( mode == 2 ) {
if ( typeof setImmediate == 'undefined' ) {
// Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed)
var setImmediates = [ ] ;
var emscriptenMainLoopMessageId = 'setimmediate' ;
/** @param {Event} event */
var Browser _setImmediate _messageHandler = ( event ) => {
// When called in current thread or Worker, the main loop ID is structured slightly different to accommodate for --proxy-to-worker runtime listening to Worker events,
// so check for both cases.
if ( event . data === emscriptenMainLoopMessageId || event . data . target === emscriptenMainLoopMessageId ) {
event . stopPropagation ( ) ;
setImmediates . shift ( ) ( ) ;
}
} ;
addEventListener ( "message" , Browser _setImmediate _messageHandler , true ) ;
setImmediate = /** @type{function(function(): ?, ...?): number} */ ( function Browser _emulated _setImmediate ( func ) {
setImmediates . push ( func ) ;
if ( ENVIRONMENT _IS _WORKER ) {
if ( Module [ 'setImmediates' ] === undefined ) Module [ 'setImmediates' ] = [ ] ;
Module [ 'setImmediates' ] . push ( func ) ;
postMessage ( { target : emscriptenMainLoopMessageId } ) ; // In --proxy-to-worker, route the message via proxyClient.js
} else postMessage ( emscriptenMainLoopMessageId , "*" ) ; // On the main thread, can just send the message to itself.
} )
}
Browser . mainLoop . scheduler = function Browser _mainLoop _scheduler _setImmediate ( ) {
setImmediate ( Browser . mainLoop . runner ) ;
} ;
Browser . mainLoop . method = 'immediate' ;
}
return 0 ;
}
var _emscripten _get _now ;
// The performance global was added to node in v16.0.0:
// https://nodejs.org/api/globals.html#performance
if ( ENVIRONMENT _IS _NODE ) {
global . performance = require ( 'perf_hooks' ) . performance ;
}
// Modern environment where performance.now() is supported:
// N.B. a shorter form "_emscripten_get_now = performance.now;" is
// unfortunately not allowed even in current browsers (e.g. FF Nightly 75).
_emscripten _get _now = ( ) => performance . now ( ) ;
;
/ * *
* @ param { number = } arg
* @ param { boolean = } noSetTiming
* /
function setMainLoop ( browserIterationFunc , fps , simulateInfiniteLoop , arg , noSetTiming ) {
assert ( ! Browser . mainLoop . func , 'emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.' ) ;
Browser . mainLoop . func = browserIterationFunc ;
Browser . mainLoop . arg = arg ;
var thisMainLoopId = Browser . mainLoop . currentlyRunningMainloop ;
function checkIsRunning ( ) {
if ( thisMainLoopId < Browser . mainLoop . currentlyRunningMainloop ) {
return false ;
}
return true ;
}
// We create the loop runner here but it is not actually running until
// _emscripten_set_main_loop_timing is called (which might happen a
// later time). This member signifies that the current runner has not
// yet been started so that we can call runtimeKeepalivePush when it
// gets it timing set for the first time.
Browser . mainLoop . running = false ;
Browser . mainLoop . runner = function Browser _mainLoop _runner ( ) {
if ( ABORT ) return ;
if ( Browser . mainLoop . queue . length > 0 ) {
var start = Date . now ( ) ;
var blocker = Browser . mainLoop . queue . shift ( ) ;
blocker . func ( blocker . arg ) ;
if ( Browser . mainLoop . remainingBlockers ) {
var remaining = Browser . mainLoop . remainingBlockers ;
var next = remaining % 1 == 0 ? remaining - 1 : Math . floor ( remaining ) ;
if ( blocker . counted ) {
Browser . mainLoop . remainingBlockers = next ;
} else {
// not counted, but move the progress along a tiny bit
next = next + 0.5 ; // do not steal all the next one's progress
Browser . mainLoop . remainingBlockers = ( 8 * remaining + next ) / 9 ;
}
}
out ( 'main loop blocker "' + blocker . name + '" took ' + ( Date . now ( ) - start ) + ' ms' ) ; //, left: ' + Browser.mainLoop.remainingBlockers);
Browser . mainLoop . updateStatus ( ) ;
// catches pause/resume main loop from blocker execution
if ( ! checkIsRunning ( ) ) return ;
setTimeout ( Browser . mainLoop . runner , 0 ) ;
return ;
}
// catch pauses from non-main loop sources
if ( ! checkIsRunning ( ) ) return ;
// Implement very basic swap interval control
Browser . mainLoop . currentFrameNumber = Browser . mainLoop . currentFrameNumber + 1 | 0 ;
if ( Browser . mainLoop . timingMode == 1 && Browser . mainLoop . timingValue > 1 && Browser . mainLoop . currentFrameNumber % Browser . mainLoop . timingValue != 0 ) {
// Not the scheduled time to render this frame - skip.
Browser . mainLoop . scheduler ( ) ;
return ;
} else if ( Browser . mainLoop . timingMode == 0 ) {
Browser . mainLoop . tickStartTime = _emscripten _get _now ( ) ;
}
// Signal GL rendering layer that processing of a new frame is about to start. This helps it optimize
// VBO double-buffering and reduce GPU stalls.
if ( Browser . mainLoop . method === 'timeout' && Module . ctx ) {
warnOnce ( 'Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!' ) ;
Browser . mainLoop . method = '' ; // just warn once per call to set main loop
}
Browser . mainLoop . runIter ( browserIterationFunc ) ;
checkStackCookie ( ) ;
// catch pauses from the main loop itself
if ( ! checkIsRunning ( ) ) return ;
// Queue new audio data. This is important to be right after the main loop invocation, so that we will immediately be able
// to queue the newest produced audio samples.
// TODO: Consider adding pre- and post- rAF callbacks so that GL.newRenderingFrameStarted() and SDL.audio.queueNewAudioData()
// do not need to be hardcoded into this function, but can be more generic.
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 , 1000.0 / fps ) ;
} else {
// Do rAF by rendering each frame (no decimating)
_emscripten _set _main _loop _timing ( 1 , 1 ) ;
}
Browser . mainLoop . scheduler ( ) ;
}
if ( simulateInfiniteLoop ) {
throw 'unwind' ;
}
}
function handleException ( e ) {
// Certain exception types we do not treat as errors since they are used for
// internal control flow.
// 1. ExitStatus, which is thrown by exit()
// 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
// that wish to return to JS event loop.
if ( e instanceof ExitStatus || e == 'unwind' ) {
return EXITSTATUS ;
}
checkStackCookie ( ) ;
if ( e instanceof WebAssembly . RuntimeError ) {
if ( _emscripten _stack _get _current ( ) <= 0 ) {
err ( 'Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 5242880)' ) ;
}
}
quit _ ( 1 , e ) ;
}
function _proc _exit ( code ) {
EXITSTATUS = code ;
if ( ! keepRuntimeAlive ( ) ) {
if ( Module [ 'onExit' ] ) Module [ 'onExit' ] ( code ) ;
ABORT = true ;
}
quit _ ( code , new ExitStatus ( code ) ) ;
}
/** @suppress {duplicate } */
/** @param {boolean|number=} implicit */
function exitJS ( status , implicit ) {
EXITSTATUS = status ;
checkUnflushedContent ( ) ;
// if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
if ( keepRuntimeAlive ( ) && ! implicit ) {
var msg = ` program exited (with status: ${ status } ), but keepRuntimeAlive() is set (counter= ${ runtimeKeepaliveCounter } ) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown) ` ;
err ( msg ) ;
}
_proc _exit ( status ) ;
}
var _exit = exitJS ;
function maybeExit ( ) {
if ( ! keepRuntimeAlive ( ) ) {
try {
_exit ( EXITSTATUS ) ;
} catch ( e ) {
handleException ( e ) ;
}
}
}
function callUserCallback ( func ) {
if ( ABORT ) {
err ( 'user callback triggered after runtime exited or application aborted. Ignoring.' ) ;
return ;
}
try {
func ( ) ;
maybeExit ( ) ;
} catch ( e ) {
handleException ( e ) ;
}
}
/** @param {number=} timeout */
function safeSetTimeout ( func , timeout ) {
return setTimeout ( ( ) => {
callUserCallback ( func ) ;
} , timeout ) ;
}
var Browser = { mainLoop : { running : false , scheduler : null , method : "" , currentlyRunningMainloop : 0 , func : null , arg : 0 , timingMode : 0 , timingValue : 0 , currentFrameNumber : 0 , queue : [ ] , pause : function ( ) {
Browser . mainLoop . scheduler = null ;
// Incrementing this signals the previous main loop that it's now become old, and it must return.
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 ;
// do not set timing and call scheduler, we will do it on the next lines
setMainLoop ( func , 0 , false , Browser . mainLoop . arg , true ) ;
_emscripten _set _main _loop _timing ( timingMode , timingValue ) ;
Browser . mainLoop . scheduler ( ) ;
} , updateStatus : function ( ) {
if ( Module [ 'setStatus' ] ) {
var message = Module [ 'statusMessage' ] || 'Please wait...' ;
var remaining = Browser . mainLoop . remainingBlockers ;
var expected = Browser . mainLoop . expectedBlockers ;
if ( remaining ) {
if ( remaining < expected ) {
Module [ 'setStatus' ] ( message + ' (' + ( expected - remaining ) + '/' + expected + ')' ) ;
} else {
Module [ 'setStatus' ] ( message ) ;
}
} else {
Module [ 'setStatus' ] ( '' ) ;
}
}
} , runIter : function ( func ) {
if ( ABORT ) return ;
if ( Module [ 'preMainLoop' ] ) {
var preRet = Module [ 'preMainLoop' ] ( ) ;
if ( preRet === false ) {
return ; // |return false| skips a frame
}
}
callUserCallback ( func ) ;
if ( Module [ 'postMainLoop' ] ) Module [ 'postMainLoop' ] ( ) ;
} } , isFullscreen : false , pointerLock : false , moduleContextCreatedCallbacks : [ ] , workers : [ ] , init : function ( ) {
if ( Browser . initted ) return ;
Browser . initted = true ;
// Support for plugins that can process preloaded files. You can add more of these to
// your app by creating and appending to preloadPlugins.
//
// Each plugin is asked if it can handle a file based on the file's name. If it can,
// it is given the file's raw data. When it is done, it calls a callback with the file's
// (possibly modified) data. For example, a plugin might decompress a file, or it
// might create some side data structure for use later (like an Image element, etc.).
var imagePlugin = { } ;
imagePlugin [ 'canHandle' ] = function imagePlugin _canHandle ( name ) {
return ! Module . noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i . test ( name ) ;
} ;
imagePlugin [ 'handle' ] = function imagePlugin _handle ( byteArray , name , onload , onerror ) {
var b = new Blob ( [ byteArray ] , { type : Browser . getMimetype ( name ) } ) ;
if ( b . size !== byteArray . length ) { // Safari bug #118630
// Safari's Blob can only take an ArrayBuffer
b = new Blob ( [ ( new Uint8Array ( byteArray ) ) . buffer ] , { type : Browser . getMimetype ( name ) } ) ;
}
var url = URL . createObjectURL ( b ) ;
assert ( typeof url == 'string' , 'createObjectURL must return a url as a string' ) ;
var img = new Image ( ) ;
img . onload = ( ) => {
assert ( img . complete , 'Image ' + name + ' could not be decoded' ) ;
var canvas = /** @type {!HTMLCanvasElement} */ ( document . createElement ( 'canvas' ) ) ;
canvas . width = img . width ;
canvas . height = img . height ;
var ctx = canvas . getContext ( '2d' ) ;
ctx . drawImage ( img , 0 , 0 ) ;
preloadedImages [ name ] = canvas ;
URL . revokeObjectURL ( url ) ;
if ( onload ) onload ( byteArray ) ;
} ;
img . onerror = ( event ) => {
out ( 'Image ' + url + ' could not be decoded' ) ;
if ( onerror ) onerror ( ) ;
} ;
img . src = url ;
} ;
preloadPlugins . push ( imagePlugin ) ;
var audioPlugin = { } ;
audioPlugin [ 'canHandle' ] = function audioPlugin _canHandle ( name ) {
return ! Module . noAudioDecoding && name . substr ( - 4 ) in { '.ogg' : 1 , '.wav' : 1 , '.mp3' : 1 } ;
} ;
audioPlugin [ 'handle' ] = function audioPlugin _handle ( byteArray , name , onload , onerror ) {
var done = false ;
function finish ( audio ) {
if ( done ) return ;
done = true ;
preloadedAudios [ name ] = audio ;
if ( onload ) onload ( byteArray ) ;
}
function fail ( ) {
if ( done ) return ;
done = true ;
preloadedAudios [ name ] = new Audio ( ) ; // empty shim
if ( onerror ) onerror ( ) ;
}
var b = new Blob ( [ byteArray ] , { type : Browser . getMimetype ( name ) } ) ;
var url = URL . createObjectURL ( b ) ; // XXX we never revoke this!
assert ( typeof url == 'string' , 'createObjectURL must return a url as a string' ) ;
var audio = new Audio ( ) ;
audio . addEventListener ( 'canplaythrough' , ( ) => finish ( audio ) , false ) ; // use addEventListener due to chromium bug 124926
audio . onerror = function audio _onerror ( event ) {
if ( done ) return ;
err ( 'warning: browser could not fully decode audio ' + name + ', trying slower base64 approach' ) ;
function encode64 ( data ) {
var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' ;
var PAD = '=' ;
var ret = '' ;
var leftchar = 0 ;
var leftbits = 0 ;
for ( var i = 0 ; i < data . length ; i ++ ) {
leftchar = ( leftchar << 8 ) | data [ i ] ;
leftbits += 8 ;
while ( leftbits >= 6 ) {
var curr = ( leftchar >> ( leftbits - 6 ) ) & 0x3f ;
leftbits -= 6 ;
ret += BASE [ curr ] ;
}
}
if ( leftbits == 2 ) {
ret += BASE [ ( leftchar & 3 ) << 4 ] ;
ret += PAD + PAD ;
} else if ( leftbits == 4 ) {
ret += BASE [ ( leftchar & 0xf ) << 2 ] ;
ret += PAD ;
}
return ret ;
}
audio . src = 'data:audio/x-' + name . substr ( - 3 ) + ';base64,' + encode64 ( byteArray ) ;
finish ( audio ) ; // we don't wait for confirmation this worked - but it's worth trying
} ;
audio . src = url ;
// workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
safeSetTimeout ( ( ) => {
finish ( audio ) ; // try to use it even though it is not necessarily ready to play
} , 10000 ) ;
} ;
preloadPlugins . push ( audioPlugin ) ;
// Canvas event setup
function pointerLockChange ( ) {
Browser . pointerLock = document [ 'pointerLockElement' ] === Module [ 'canvas' ] ||
document [ 'mozPointerLockElement' ] === Module [ 'canvas' ] ||
document [ 'webkitPointerLockElement' ] === Module [ 'canvas' ] ||
document [ 'msPointerLockElement' ] === Module [ 'canvas' ] ;
}
var canvas = Module [ 'canvas' ] ;
if ( canvas ) {
// forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
// Module['forcedAspectRatio'] = 4 / 3;
canvas . requestPointerLock = canvas [ 'requestPointerLock' ] ||
canvas [ 'mozRequestPointerLock' ] ||
canvas [ 'webkitRequestPointerLock' ] ||
canvas [ 'msRequestPointerLock' ] ||
( ( ) => { } ) ;
canvas . exitPointerLock = document [ 'exitPointerLock' ] ||
document [ 'mozExitPointerLock' ] ||
document [ 'webkitExitPointerLock' ] ||
document [ 'msExitPointerLock' ] ||
( ( ) => { } ) ; // no-op if function does not exist
canvas . exitPointerLock = canvas . exitPointerLock . bind ( document ) ;
document . addEventListener ( 'pointerlockchange' , pointerLockChange , false ) ;
document . addEventListener ( 'mozpointerlockchange' , pointerLockChange , false ) ;
document . addEventListener ( 'webkitpointerlockchange' , pointerLockChange , false ) ;
document . addEventListener ( 'mspointerlockchange' , pointerLockChange , false ) ;
if ( Module [ 'elementPointerLock' ] ) {
canvas . addEventListener ( "click" , ( ev ) => {
if ( ! Browser . pointerLock && Module [ 'canvas' ] . requestPointerLock ) {
Module [ 'canvas' ] . requestPointerLock ( ) ;
ev . preventDefault ( ) ;
}
} , false ) ;
}
}
} , createContext : function ( /** @type {HTMLCanvasElement} */ canvas , useWebGL , setInModule , webGLContextAttributes ) {
if ( useWebGL && Module . ctx && canvas == Module . canvas ) return Module . ctx ; // no need to recreate GL context if it's already been created for this canvas.
var ctx ;
var contextHandle ;
if ( useWebGL ) {
// For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults.
var contextAttributes = {
antialias : false ,
alpha : false ,
majorVersion : 2 ,
} ;
if ( webGLContextAttributes ) {
for ( var attribute in webGLContextAttributes ) {
contextAttributes [ attribute ] = webGLContextAttributes [ attribute ] ;
}
}
// This check of existence of GL is here to satisfy Closure compiler, which yells if variable GL is referenced below but GL object is not
// actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function
// Browser.createContext() should not even be emitted.
if ( typeof GL != 'undefined' ) {
contextHandle = GL . createContext ( canvas , contextAttributes ) ;
if ( contextHandle ) {
ctx = GL . getContext ( contextHandle ) . GLctx ;
}
}
} else {
ctx = canvas . getContext ( '2d' ) ;
}
if ( ! ctx ) return null ;
if ( setInModule ) {
if ( ! useWebGL ) assert ( typeof GLctx == 'undefined' , 'cannot set in module if GLctx is used, but we are a non-GL context that would replace it' ) ;
Module . ctx = ctx ;
if ( useWebGL ) GL . makeContextCurrent ( contextHandle ) ;
Module . useWebGL = useWebGL ;
Browser . moduleContextCreatedCallbacks . forEach ( ( callback ) => callback ( ) ) ;
Browser . init ( ) ;
}
return ctx ;
} , destroyContext : function ( canvas , useWebGL , setInModule ) { } , fullscreenHandlersInstalled : false , lockPointer : undefined , resizeCanvas : undefined , requestFullscreen : function ( lockPointer , resizeCanvas ) {
Browser . lockPointer = lockPointer ;
Browser . resizeCanvas = resizeCanvas ;
if ( typeof Browser . lockPointer == 'undefined' ) Browser . lockPointer = true ;
if ( typeof Browser . resizeCanvas == 'undefined' ) Browser . resizeCanvas = false ;
var canvas = Module [ 'canvas' ] ;
function fullscreenChange ( ) {
Browser . isFullscreen = false ;
var canvasContainer = canvas . parentNode ;
if ( ( document [ 'fullscreenElement' ] || document [ 'mozFullScreenElement' ] ||
document [ 'msFullscreenElement' ] || document [ 'webkitFullscreenElement' ] ||
document [ 'webkitCurrentFullScreenElement' ] ) === canvasContainer ) {
canvas . exitFullscreen = Browser . exitFullscreen ;
if ( Browser . lockPointer ) canvas . requestPointerLock ( ) ;
Browser . isFullscreen = true ;
if ( Browser . resizeCanvas ) {
Browser . setFullscreenCanvasSize ( ) ;
} else {
Browser . updateCanvasDimensions ( canvas ) ;
}
} else {
// remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
canvasContainer . parentNode . insertBefore ( canvas , canvasContainer ) ;
canvasContainer . parentNode . removeChild ( canvasContainer ) ;
if ( Browser . resizeCanvas ) {
Browser . setWindowedCanvasSize ( ) ;
} else {
Browser . updateCanvasDimensions ( canvas ) ;
}
}
if ( Module [ 'onFullScreen' ] ) Module [ 'onFullScreen' ] ( Browser . isFullscreen ) ;
if ( Module [ 'onFullscreen' ] ) Module [ 'onFullscreen' ] ( Browser . isFullscreen ) ;
}
if ( ! Browser . fullscreenHandlersInstalled ) {
Browser . fullscreenHandlersInstalled = true ;
document . addEventListener ( 'fullscreenchange' , fullscreenChange , false ) ;
document . addEventListener ( 'mozfullscreenchange' , fullscreenChange , false ) ;
document . addEventListener ( 'webkitfullscreenchange' , fullscreenChange , false ) ;
document . addEventListener ( 'MSFullscreenChange' , fullscreenChange , false ) ;
}
// create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
var canvasContainer = document . createElement ( "div" ) ;
canvas . parentNode . insertBefore ( canvasContainer , canvas ) ;
canvasContainer . appendChild ( canvas ) ;
// use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
canvasContainer . requestFullscreen = canvasContainer [ 'requestFullscreen' ] ||
canvasContainer [ 'mozRequestFullScreen' ] ||
canvasContainer [ 'msRequestFullscreen' ] ||
( canvasContainer [ 'webkitRequestFullscreen' ] ? ( ) => canvasContainer [ 'webkitRequestFullscreen' ] ( Element [ 'ALLOW_KEYBOARD_INPUT' ] ) : null ) ||
( canvasContainer [ 'webkitRequestFullScreen' ] ? ( ) => canvasContainer [ 'webkitRequestFullScreen' ] ( Element [ 'ALLOW_KEYBOARD_INPUT' ] ) : null ) ;
canvasContainer . requestFullscreen ( ) ;
} , requestFullScreen : function ( ) {
abort ( 'Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)' ) ;
} , exitFullscreen : function ( ) {
// This is workaround for chrome. Trying to exit from fullscreen
// not in fullscreen state will cause "TypeError: Document not active"
// in chrome. See https://github.com/emscripten-core/emscripten/pull/8236
if ( ! Browser . isFullscreen ) {
return false ;
}
var CFS = document [ 'exitFullscreen' ] ||
document [ 'cancelFullScreen' ] ||
document [ 'mozCancelFullScreen' ] ||
document [ 'msExitFullscreen' ] ||
document [ 'webkitCancelFullScreen' ] ||
( ( ) => { } ) ;
CFS . apply ( document , [ ] ) ;
return true ;
} , nextRAF : 0 , fakeRequestAnimationFrame : function ( func ) {
// try to keep 60fps between calls to here
var now = Date . now ( ) ;
if ( Browser . nextRAF === 0 ) {
Browser . nextRAF = now + 1000 / 60 ;
} else {
while ( now + 2 >= Browser . nextRAF ) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0
Browser . nextRAF += 1000 / 60 ;
}
}
var delay = Math . max ( Browser . nextRAF - now , 0 ) ;
setTimeout ( func , delay ) ;
} , requestAnimationFrame : function ( func ) {
if ( typeof requestAnimationFrame == 'function' ) {
requestAnimationFrame ( func ) ;
return ;
}
var RAF = Browser . fakeRequestAnimationFrame ;
RAF ( func ) ;
} , safeSetTimeout : function ( func , timeout ) {
// Legacy function, this is used by the SDL2 port so we need to keep it
// around at least until that is updated.
// See https://github.com/libsdl-org/SDL/pull/6304
return safeSetTimeout ( func , timeout ) ;
} , safeRequestAnimationFrame : function ( func ) {
return Browser . requestAnimationFrame ( ( ) => {
callUserCallback ( func ) ;
} ) ;
} , getMimetype : function ( name ) {
return {
'jpg' : 'image/jpeg' ,
'jpeg' : 'image/jpeg' ,
'png' : 'image/png' ,
'bmp' : 'image/bmp' ,
'ogg' : 'audio/ogg' ,
'wav' : 'audio/wav' ,
'mp3' : 'audio/mpeg'
} [ name . substr ( name . lastIndexOf ( '.' ) + 1 ) ] ;
} , getUserMedia : function ( func ) {
if ( ! window . getUserMedia ) {
window . getUserMedia = navigator [ 'getUserMedia' ] ||
navigator [ 'mozGetUserMedia' ] ;
}
window . getUserMedia ( func ) ;
} , getMovementX : function ( event ) {
return event [ 'movementX' ] ||
event [ 'mozMovementX' ] ||
event [ 'webkitMovementX' ] ||
0 ;
} , getMovementY : function ( event ) {
return event [ 'movementY' ] ||
event [ 'mozMovementY' ] ||
event [ 'webkitMovementY' ] ||
0 ;
} , getMouseWheelDelta : function ( event ) {
var delta = 0 ;
switch ( event . type ) {
case 'DOMMouseScroll' :
// 3 lines make up a step
delta = event . detail / 3 ;
break ;
case 'mousewheel' :
// 120 units make up a step
delta = event . wheelDelta / 120 ;
break ;
case 'wheel' :
delta = event . deltaY
switch ( event . deltaMode ) {
case 0 :
// DOM_DELTA_PIXEL: 100 pixels make up a step
delta /= 100 ;
break ;
case 1 :
// DOM_DELTA_LINE: 3 lines make up a step
delta /= 3 ;
break ;
case 2 :
// DOM_DELTA_PAGE: A page makes up 80 steps
delta *= 80 ;
break ;
default :
throw 'unrecognized mouse wheel delta mode: ' + event . deltaMode ;
}
break ;
default :
throw 'unrecognized mouse wheel event: ' + event . type ;
}
return delta ;
} , mouseX : 0 , mouseY : 0 , mouseMovementX : 0 , mouseMovementY : 0 , touches : { } , lastTouches : { } , calculateMouseEvent : function ( event ) { // event should be mousemove, mousedown or mouseup
if ( Browser . pointerLock ) {
// When the pointer is locked, calculate the coordinates
// based on the movement of the mouse.
// Workaround for Firefox bug 764498
if ( event . type != 'mousemove' &&
( 'mozMovementX' in event ) ) {
Browser . mouseMovementX = Browser . mouseMovementY = 0 ;
} else {
Browser . mouseMovementX = Browser . getMovementX ( event ) ;
Browser . mouseMovementY = Browser . getMovementY ( event ) ;
}
// check if SDL is available
if ( typeof SDL != "undefined" ) {
Browser . mouseX = SDL . mouseX + Browser . mouseMovementX ;
Browser . mouseY = SDL . mouseY + Browser . mouseMovementY ;
} else {
// just add the mouse delta to the current absolut mouse position
// FIXME: ideally this should be clamped against the canvas size and zero
Browser . mouseX += Browser . mouseMovementX ;
Browser . mouseY += Browser . mouseMovementY ;
}
} else {
// Otherwise, calculate the movement based on the changes
// in the coordinates.
var rect = Module [ "canvas" ] . getBoundingClientRect ( ) ;
var cw = Module [ "canvas" ] . width ;
var ch = Module [ "canvas" ] . height ;
// Neither .scrollX or .pageXOffset are defined in a spec, but
// we prefer .scrollX because it is currently in a spec draft.
// (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
var scrollX = ( ( typeof window . scrollX != 'undefined' ) ? window . scrollX : window . pageXOffset ) ;
var scrollY = ( ( typeof window . scrollY != 'undefined' ) ? window . scrollY : window . pageYOffset ) ;
// If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset
// and we have no viable fallback.
assert ( ( typeof scrollX != 'undefined' ) && ( typeof scrollY != 'undefined' ) , 'Unable to retrieve scroll position, mouse positions likely broken.' ) ;
if ( event . type === 'touchstart' || event . type === 'touchend' || event . type === 'touchmove' ) {
var touch = event . touch ;
if ( touch === undefined ) {
return ; // the "touch" property is only defined in SDL
}
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 ) ;
// the canvas might be CSS-scaled compared to its backbuffer;
// SDL-using content will want mouse coordinates in terms
// of backbuffer units.
x = x * ( cw / rect . width ) ;
y = y * ( ch / rect . height ) ;
Browser . mouseMovementX = x - Browser . mouseX ;
Browser . mouseMovementY = y - Browser . mouseY ;
Browser . mouseX = x ;
Browser . mouseY = y ;
}
} , resizeListeners : [ ] , updateResizeListeners : function ( ) {
var canvas = Module [ 'canvas' ] ;
Browser . resizeListeners . forEach ( ( listener ) => listener ( canvas . width , canvas . height ) ) ;
} , setCanvasSize : function ( width , height , noUpdates ) {
var canvas = Module [ 'canvas' ] ;
Browser . updateCanvasDimensions ( canvas , width , height ) ;
if ( ! noUpdates ) Browser . updateResizeListeners ( ) ;
} , windowedWidth : 0 , windowedHeight : 0 , setFullscreenCanvasSize : function ( ) {
// check if SDL is available
if ( typeof SDL != "undefined" ) {
var flags = HEAPU32 [ ( ( SDL . screen ) >> 2 ) ] ;
flags = flags | 0x00800000 ; // set SDL_FULLSCREEN flag
HEAP32 [ ( ( SDL . screen ) >> 2 ) ] = flags ;
}
Browser . updateCanvasDimensions ( Module [ 'canvas' ] ) ;
Browser . updateResizeListeners ( ) ;
} , setWindowedCanvasSize : function ( ) {
// check if SDL is available
if ( typeof SDL != "undefined" ) {
var flags = HEAPU32 [ ( ( SDL . screen ) >> 2 ) ] ;
flags = flags & ~ 0x00800000 ; // clear SDL_FULLSCREEN flag
HEAP32 [ ( ( SDL . screen ) >> 2 ) ] = flags ;
}
Browser . updateCanvasDimensions ( Module [ 'canvas' ] ) ;
Browser . updateResizeListeners ( ) ;
} , updateCanvasDimensions : function ( canvas , wNative , hNative ) {
if ( wNative && hNative ) {
canvas . widthNative = wNative ;
canvas . heightNative = hNative ;
} else {
wNative = canvas . widthNative ;
hNative = canvas . heightNative ;
}
var w = wNative ;
var h = hNative ;
if ( Module [ 'forcedAspectRatio' ] && Module [ 'forcedAspectRatio' ] > 0 ) {
if ( w / h < Module [ 'forcedAspectRatio' ] ) {
w = Math . round ( h * Module [ 'forcedAspectRatio' ] ) ;
} else {
h = Math . round ( w / Module [ 'forcedAspectRatio' ] ) ;
}
}
if ( ( ( document [ 'fullscreenElement' ] || document [ 'mozFullScreenElement' ] ||
document [ 'msFullscreenElement' ] || document [ 'webkitFullscreenElement' ] ||
document [ 'webkitCurrentFullScreenElement' ] ) === canvas . parentNode ) && ( typeof screen != 'undefined' ) ) {
var factor = Math . min ( screen . width / w , screen . height / h ) ;
w = Math . round ( w * factor ) ;
h = Math . round ( h * factor ) ;
}
if ( Browser . resizeCanvas ) {
if ( canvas . width != w ) canvas . width = w ;
if ( canvas . height != h ) canvas . height = h ;
if ( typeof canvas . style != 'undefined' ) {
canvas . style . removeProperty ( "width" ) ;
canvas . style . removeProperty ( "height" ) ;
}
} else {
if ( canvas . width != wNative ) canvas . width = wNative ;
if ( canvas . height != hNative ) canvas . height = hNative ;
if ( typeof canvas . style != 'undefined' ) {
if ( w != wNative || h != hNative ) {
canvas . style . setProperty ( "width" , w + "px" , "important" ) ;
canvas . style . setProperty ( "height" , h + "px" , "important" ) ;
} else {
canvas . style . removeProperty ( "width" ) ;
canvas . style . removeProperty ( "height" ) ;
}
}
}
} } ;
var EGL = { errorCode : 12288 , defaultDisplayInitialized : false , currentContext : 0 , currentReadSurface : 0 , currentDrawSurface : 0 , contextAttributes : { alpha : false , depth : false , stencil : false , antialias : false } , stringCache : { } , setErrorCode : function ( code ) {
EGL . errorCode = code ;
} , chooseConfig : function ( display , attribList , config , config _size , numConfigs ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
if ( attribList ) {
// read attribList if it is non-null
for ( ; ; ) {
var param = HEAP32 [ ( ( attribList ) >> 2 ) ] ;
if ( param == 0x3021 /*EGL_ALPHA_SIZE*/ ) {
var alphaSize = HEAP32 [ ( ( ( attribList ) + ( 4 ) ) >> 2 ) ] ;
EGL . contextAttributes . alpha = ( alphaSize > 0 ) ;
} else if ( param == 0x3025 /*EGL_DEPTH_SIZE*/ ) {
var depthSize = HEAP32 [ ( ( ( attribList ) + ( 4 ) ) >> 2 ) ] ;
EGL . contextAttributes . depth = ( depthSize > 0 ) ;
} else if ( param == 0x3026 /*EGL_STENCIL_SIZE*/ ) {
var stencilSize = HEAP32 [ ( ( ( attribList ) + ( 4 ) ) >> 2 ) ] ;
EGL . contextAttributes . stencil = ( stencilSize > 0 ) ;
} else if ( param == 0x3031 /*EGL_SAMPLES*/ ) {
var samples = HEAP32 [ ( ( ( attribList ) + ( 4 ) ) >> 2 ) ] ;
EGL . contextAttributes . antialias = ( samples > 0 ) ;
} else if ( param == 0x3032 /*EGL_SAMPLE_BUFFERS*/ ) {
var samples = HEAP32 [ ( ( ( attribList ) + ( 4 ) ) >> 2 ) ] ;
EGL . contextAttributes . antialias = ( samples == 1 ) ;
} else if ( param == 0x3100 /*EGL_CONTEXT_PRIORITY_LEVEL_IMG*/ ) {
var requestedPriority = HEAP32 [ ( ( ( attribList ) + ( 4 ) ) >> 2 ) ] ;
EGL . contextAttributes . lowLatency = ( requestedPriority != 0x3103 /*EGL_CONTEXT_PRIORITY_LOW_IMG*/ ) ;
} else if ( param == 0x3038 /*EGL_NONE*/ ) {
break ;
}
attribList += 8 ;
}
}
if ( ( ! config || ! config _size ) && ! numConfigs ) {
EGL . setErrorCode ( 0x300C /* EGL_BAD_PARAMETER */ ) ;
return 0 ;
}
if ( numConfigs ) {
HEAP32 [ ( ( numConfigs ) >> 2 ) ] = 1 ; // Total number of supported configs: 1.
}
if ( config && config _size > 0 ) {
HEAP32 [ ( ( config ) >> 2 ) ] = 62002 ;
}
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 ;
} } ;
function _eglBindAPI ( api ) {
if ( api == 0x30A0 /* EGL_OPENGL_ES_API */ ) {
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 ;
}
// if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) {
EGL . setErrorCode ( 0x300C /* EGL_BAD_PARAMETER */ ) ;
return 0 ;
}
function _eglChooseConfig ( display , attrib _list , configs , config _size , numConfigs ) {
return EGL . chooseConfig ( display , attrib _list , configs , config _size , numConfigs ) ;
}
function webgl _enable _WEBGL _draw _instanced _base _vertex _base _instance ( ctx ) {
// Closure is expected to be allowed to minify the '.dibvbi' property, so not accessing it quoted.
return ! ! ( ctx . dibvbi = ctx . getExtension ( 'WEBGL_draw_instanced_base_vertex_base_instance' ) ) ;
}
function webgl _enable _WEBGL _multi _draw _instanced _base _vertex _base _instance ( ctx ) {
// Closure is expected to be allowed to minify the '.mdibvbi' property, so not accessing it quoted.
return ! ! ( ctx . mdibvbi = ctx . getExtension ( 'WEBGL_multi_draw_instanced_base_vertex_base_instance' ) ) ;
}
function webgl _enable _WEBGL _multi _draw ( ctx ) {
// Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted.
return ! ! ( ctx . multiDrawWebgl = ctx . getExtension ( 'WEBGL_multi_draw' ) ) ;
}
var GL = { counter : 1 , buffers : [ ] , programs : [ ] , framebuffers : [ ] , renderbuffers : [ ] , textures : [ ] , shaders : [ ] , vaos : [ ] , contexts : [ ] , offscreenCanvases : { } , queries : [ ] , samplers : [ ] , transformFeedbacks : [ ] , syncs : [ ] , stringCache : { } , stringiCache : { } , unpackAlignment : 4 , recordError : function recordError ( errorCode ) {
if ( ! GL . lastError ) {
GL . lastError = errorCode ;
}
} , getNewId : function ( table ) {
var ret = GL . counter ++ ;
for ( var i = table . length ; i < ret ; i ++ ) {
table [ i ] = null ;
}
return ret ;
} , getSource : function ( shader , count , string , length ) {
var source = '' ;
for ( var i = 0 ; i < count ; ++ i ) {
var len = length ? HEAP32 [ ( ( ( length ) + ( i * 4 ) ) >> 2 ) ] : - 1 ;
source += UTF8ToString ( HEAP32 [ ( ( ( string ) + ( i * 4 ) ) >> 2 ) ] , len < 0 ? undefined : len ) ;
}
return source ;
} , createContext : function ( /** @type {HTMLCanvasElement} */ canvas , webGLContextAttributes ) {
// BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL context on a canvas,
// calling .getContext() will always return that context independent of which 'webgl' or 'webgl2'
// context version was passed. See https://bugs.webkit.org/show_bug.cgi?id=222758 and
// https://github.com/emscripten-core/emscripten/issues/13295.
// TODO: Once the bug is fixed and shipped in Safari, adjust the Safari version field in above check.
if ( ! canvas . getContextSafariWebGL2Fixed ) {
canvas . getContextSafariWebGL2Fixed = canvas . getContext ;
/** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */
function fixedGetContext ( ver , attrs ) {
var gl = canvas . getContextSafariWebGL2Fixed ( ver , attrs ) ;
return ( ( ver == 'webgl' ) == ( gl instanceof WebGLRenderingContext ) ) ? gl : null ;
}
canvas . getContext = fixedGetContext ;
}
var ctx = canvas . getContext ( "webgl2" , webGLContextAttributes ) ;
if ( ! ctx ) return 0 ;
var handle = GL . registerContext ( ctx , webGLContextAttributes ) ;
return handle ;
} , registerContext : function ( ctx , webGLContextAttributes ) {
// without pthreads a context is just an integer ID
var handle = GL . getNewId ( GL . contexts ) ;
var context = {
handle : handle ,
attributes : webGLContextAttributes ,
version : webGLContextAttributes . majorVersion ,
GLctx : ctx
} ;
// Store the created context object so that we can access the context given a canvas without having to pass the parameters again.
if ( ctx . canvas ) ctx . canvas . GLctxObject = context ;
GL . contexts [ handle ] = context ;
if ( typeof webGLContextAttributes . enableExtensionsByDefault == 'undefined' || webGLContextAttributes . enableExtensionsByDefault ) {
GL . initExtensions ( context ) ;
}
return handle ;
} , makeContextCurrent : function ( contextHandle ) {
GL . currentContext = GL . contexts [ contextHandle ] ; // Active Emscripten GL layer context object.
Module . ctx = GLctx = GL . currentContext && GL . currentContext . GLctx ; // Active WebGL context object.
return ! ( contextHandle && ! GLctx ) ;
} , getContext : function ( contextHandle ) {
return GL . contexts [ contextHandle ] ;
} , deleteContext : function ( contextHandle ) {
if ( GL . currentContext === GL . contexts [ contextHandle ] ) GL . currentContext = null ;
if ( typeof JSEvents == 'object' ) JSEvents . removeAllHandlersOnTarget ( GL . contexts [ contextHandle ] . GLctx . canvas ) ; // Release all JS event handlers on the DOM element that the GL context is associated with since the context is now deleted.
if ( GL . contexts [ contextHandle ] && GL . contexts [ contextHandle ] . GLctx . canvas ) GL . contexts [ contextHandle ] . GLctx . canvas . GLctxObject = undefined ; // Make sure the canvas object no longer refers to the context object so there are no GC surprises.
GL . contexts [ contextHandle ] = null ;
} , initExtensions : function ( context ) {
// If this function is called without a specific context object, init the extensions of the currently active context.
if ( ! context ) context = GL . currentContext ;
if ( context . initExtensionsDone ) return ;
context . initExtensionsDone = true ;
var GLctx = context . GLctx ;
// Detect the presence of a few extensions manually, this GL interop layer itself will need to know if they exist.
// Extensions that are available from WebGL >= 2 (no-op if called on a WebGL 1 context active)
webgl _enable _WEBGL _draw _instanced _base _vertex _base _instance ( GLctx ) ;
webgl _enable _WEBGL _multi _draw _instanced _base _vertex _base _instance ( GLctx ) ;
// On WebGL 2, EXT_disjoint_timer_query is replaced with an alternative
// that's based on core APIs, and exposes only the queryCounterEXT()
// entrypoint.
if ( context . version >= 2 ) {
GLctx . disjointTimerQueryExt = GLctx . getExtension ( "EXT_disjoint_timer_query_webgl2" ) ;
}
// However, Firefox exposes the WebGL 1 version on WebGL 2 as well and
// thus we look for the WebGL 1 version again if the WebGL 2 version
// isn't present. https://bugzilla.mozilla.org/show_bug.cgi?id=1328882
if ( context . version < 2 || ! GLctx . disjointTimerQueryExt )
{
GLctx . disjointTimerQueryExt = GLctx . getExtension ( "EXT_disjoint_timer_query" ) ;
}
webgl _enable _WEBGL _multi _draw ( GLctx ) ;
// .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
var exts = GLctx . getSupportedExtensions ( ) || [ ] ;
exts . forEach ( function ( ext ) {
// WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders are not enabled by default.
if ( ! ext . includes ( 'lose_context' ) && ! ext . includes ( 'debug' ) ) {
// Call .getExtension() to enable that extension permanently.
GLctx . getExtension ( ext ) ;
}
} ) ;
} } ;
function _eglCreateContext ( display , config , hmm , contextAttribs ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
// EGL 1.4 spec says default EGL_CONTEXT_CLIENT_VERSION is GLES1, but this is not supported by Emscripten.
// So user must pass EGL_CONTEXT_CLIENT_VERSION == 2 to initialize EGL.
var glesContextVersion = 1 ;
for ( ; ; ) {
var param = HEAP32 [ ( ( contextAttribs ) >> 2 ) ] ;
if ( param == 0x3098 /*EGL_CONTEXT_CLIENT_VERSION*/ ) {
glesContextVersion = HEAP32 [ ( ( ( contextAttribs ) + ( 4 ) ) >> 2 ) ] ;
} else if ( param == 0x3038 /*EGL_NONE*/ ) {
break ;
} else {
/* EGL1.4 specifies only EGL_CONTEXT_CLIENT_VERSION as supported attribute */
EGL . setErrorCode ( 0x3004 /*EGL_BAD_ATTRIBUTE*/ ) ;
return 0 ;
}
contextAttribs += 8 ;
}
if ( glesContextVersion < 2 || glesContextVersion > 3 ) {
EGL . setErrorCode ( 0x3005 /* EGL_BAD_CONFIG */ ) ;
return 0 ; /* EGL_NO_CONTEXT */
}
EGL . contextAttributes . majorVersion = glesContextVersion - 1 ; // WebGL 1 is GLES 2, WebGL2 is GLES3
EGL . contextAttributes . minorVersion = 0 ;
EGL . context = GL . createContext ( Module [ 'canvas' ] , EGL . contextAttributes ) ;
if ( EGL . context != 0 ) {
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
// Run callbacks so that GL emulation works
GL . makeContextCurrent ( EGL . context ) ;
Module . useWebGL = true ;
Browser . moduleContextCreatedCallbacks . forEach ( function ( callback ) { callback ( ) } ) ;
// Note: This function only creates a context, but it shall not make it active.
GL . makeContextCurrent ( null ) ;
return 62004 ; // Magic ID for Emscripten EGLContext
} else {
EGL . setErrorCode ( 0x3009 /* EGL_BAD_MATCH */ ) ; // By the EGL 1.4 spec, an implementation that does not support GLES2 (WebGL in this case), this error code is set.
return 0 ; /* EGL_NO_CONTEXT */
}
}
function _eglCreateWindowSurface ( display , config , win , attrib _list ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
if ( config != 62002 /* Magic ID for the only EGLConfig supported by Emscripten */ ) {
EGL . setErrorCode ( 0x3005 /* EGL_BAD_CONFIG */ ) ;
return 0 ;
}
// TODO: Examine attrib_list! Parameters that can be present there are:
// - EGL_RENDER_BUFFER (must be EGL_BACK_BUFFER)
// - EGL_VG_COLORSPACE (can't be set)
// - EGL_VG_ALPHA_FORMAT (can't be set)
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 62006 ; /* Magic ID for Emscripten 'default surface' */
}
function _eglDestroyContext ( display , context ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
if ( context != 62004 /* Magic ID for Emscripten EGLContext */ ) {
EGL . setErrorCode ( 0x3006 /* EGL_BAD_CONTEXT */ ) ;
return 0 ;
}
GL . deleteContext ( EGL . context ) ;
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
if ( EGL . currentContext == context ) {
EGL . currentContext = 0 ;
}
return 1 /* EGL_TRUE */ ;
}
function _eglDestroySurface ( display , surface ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
if ( surface != 62006 /* Magic ID for the only EGLSurface supported by Emscripten */ ) {
EGL . setErrorCode ( 0x300D /* EGL_BAD_SURFACE */ ) ;
return 1 ;
}
if ( EGL . currentReadSurface == surface ) {
EGL . currentReadSurface = 0 ;
}
if ( EGL . currentDrawSurface == surface ) {
EGL . currentDrawSurface = 0 ;
}
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 ; /* Magic ID for Emscripten 'default surface' */
}
function _eglGetConfigAttrib ( display , config , attribute , value ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
if ( config != 62002 /* Magic ID for the only EGLConfig supported by Emscripten */ ) {
EGL . setErrorCode ( 0x3005 /* EGL_BAD_CONFIG */ ) ;
return 0 ;
}
if ( ! value ) {
EGL . setErrorCode ( 0x300C /* EGL_BAD_PARAMETER */ ) ;
return 0 ;
}
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
switch ( attribute ) {
case 0x3020 : // EGL_BUFFER_SIZE
HEAP32 [ ( ( value ) >> 2 ) ] = EGL . contextAttributes . alpha ? 32 : 24 ;
return 1 ;
case 0x3021 : // EGL_ALPHA_SIZE
HEAP32 [ ( ( value ) >> 2 ) ] = EGL . contextAttributes . alpha ? 8 : 0 ;
return 1 ;
case 0x3022 : // EGL_BLUE_SIZE
HEAP32 [ ( ( value ) >> 2 ) ] = 8 ;
return 1 ;
case 0x3023 : // EGL_GREEN_SIZE
HEAP32 [ ( ( value ) >> 2 ) ] = 8 ;
return 1 ;
case 0x3024 : // EGL_RED_SIZE
HEAP32 [ ( ( value ) >> 2 ) ] = 8 ;
return 1 ;
case 0x3025 : // EGL_DEPTH_SIZE
HEAP32 [ ( ( value ) >> 2 ) ] = EGL . contextAttributes . depth ? 24 : 0 ;
return 1 ;
case 0x3026 : // EGL_STENCIL_SIZE
HEAP32 [ ( ( value ) >> 2 ) ] = EGL . contextAttributes . stencil ? 8 : 0 ;
return 1 ;
case 0x3027 : // EGL_CONFIG_CAVEAT
// We can return here one of EGL_NONE (0x3038), EGL_SLOW_CONFIG (0x3050) or EGL_NON_CONFORMANT_CONFIG (0x3051).
HEAP32 [ ( ( value ) >> 2 ) ] = 0x3038 ;
return 1 ;
case 0x3028 : // EGL_CONFIG_ID
HEAP32 [ ( ( value ) >> 2 ) ] = 62002 ;
return 1 ;
case 0x3029 : // EGL_LEVEL
HEAP32 [ ( ( value ) >> 2 ) ] = 0 ;
return 1 ;
case 0x302A : // EGL_MAX_PBUFFER_HEIGHT
HEAP32 [ ( ( value ) >> 2 ) ] = 4096 ;
return 1 ;
case 0x302B : // EGL_MAX_PBUFFER_PIXELS
HEAP32 [ ( ( value ) >> 2 ) ] = 16777216 ;
return 1 ;
case 0x302C : // EGL_MAX_PBUFFER_WIDTH
HEAP32 [ ( ( value ) >> 2 ) ] = 4096 ;
return 1 ;
case 0x302D : // EGL_NATIVE_RENDERABLE
HEAP32 [ ( ( value ) >> 2 ) ] = 0 ;
return 1 ;
case 0x302E : // EGL_NATIVE_VISUAL_ID
HEAP32 [ ( ( value ) >> 2 ) ] = 0 ;
return 1 ;
case 0x302F : // EGL_NATIVE_VISUAL_TYPE
HEAP32 [ ( ( value ) >> 2 ) ] = 0x3038 ;
return 1 ;
case 0x3031 : // EGL_SAMPLES
HEAP32 [ ( ( value ) >> 2 ) ] = EGL . contextAttributes . antialias ? 4 : 0 ;
return 1 ;
case 0x3032 : // EGL_SAMPLE_BUFFERS
HEAP32 [ ( ( value ) >> 2 ) ] = EGL . contextAttributes . antialias ? 1 : 0 ;
return 1 ;
case 0x3033 : // EGL_SURFACE_TYPE
HEAP32 [ ( ( value ) >> 2 ) ] = 0x4 ;
return 1 ;
case 0x3034 : // EGL_TRANSPARENT_TYPE
// If this returns EGL_TRANSPARENT_RGB (0x3052), transparency is used through color-keying. No such thing applies to Emscripten canvas.
HEAP32 [ ( ( value ) >> 2 ) ] = 0x3038 ;
return 1 ;
case 0x3035 : // EGL_TRANSPARENT_BLUE_VALUE
case 0x3036 : // EGL_TRANSPARENT_GREEN_VALUE
case 0x3037 : // EGL_TRANSPARENT_RED_VALUE
// "If EGL_TRANSPARENT_TYPE is EGL_NONE, then the values for EGL_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_GREEN_VALUE, and EGL_TRANSPARENT_BLUE_VALUE are undefined."
HEAP32 [ ( ( value ) >> 2 ) ] = - 1 ;
return 1 ;
case 0x3039 : // EGL_BIND_TO_TEXTURE_RGB
case 0x303A : // EGL_BIND_TO_TEXTURE_RGBA
HEAP32 [ ( ( value ) >> 2 ) ] = 0 ;
return 1 ;
case 0x303B : // EGL_MIN_SWAP_INTERVAL
HEAP32 [ ( ( value ) >> 2 ) ] = 0 ;
return 1 ;
case 0x303C : // EGL_MAX_SWAP_INTERVAL
HEAP32 [ ( ( value ) >> 2 ) ] = 1 ;
return 1 ;
case 0x303D : // EGL_LUMINANCE_SIZE
case 0x303E : // EGL_ALPHA_MASK_SIZE
HEAP32 [ ( ( value ) >> 2 ) ] = 0 ;
return 1 ;
case 0x303F : // EGL_COLOR_BUFFER_TYPE
// EGL has two types of buffers: EGL_RGB_BUFFER and EGL_LUMINANCE_BUFFER.
HEAP32 [ ( ( value ) >> 2 ) ] = 0x308E ;
return 1 ;
case 0x3040 : // EGL_RENDERABLE_TYPE
// A bit combination of EGL_OPENGL_ES_BIT,EGL_OPENVG_BIT,EGL_OPENGL_ES2_BIT and EGL_OPENGL_BIT.
HEAP32 [ ( ( value ) >> 2 ) ] = 0x4 ;
return 1 ;
case 0x3042 : // EGL_CONFORMANT
// "EGL_CONFORMANT is a mask indicating if a client API context created with respect to the corresponding EGLConfig will pass the required conformance tests for that API."
HEAP32 [ ( ( value ) >> 2 ) ] = 0 ;
return 1 ;
default :
EGL . setErrorCode ( 0x3004 /* EGL_BAD_ATTRIBUTE */ ) ;
return 0 ;
}
}
function _eglGetDisplay ( nativeDisplayType ) {
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
// Note: As a 'conformant' implementation of EGL, we would prefer to init here only if the user
// calls this function with EGL_DEFAULT_DISPLAY. Other display IDs would be preferred to be unsupported
// and EGL_NO_DISPLAY returned. Uncomment the following code lines to do this.
// Instead, an alternative route has been preferred, namely that the Emscripten EGL implementation
// "emulates" X11, and eglGetDisplay is expected to accept/receive a pointer to an X11 Display object.
// Therefore, be lax and allow anything to be passed in, and return the magic handle to our default EGLDisplay object.
// if (nativeDisplayType == 0 /* EGL_DEFAULT_DISPLAY */) {
return 62000 ; // Magic ID for Emscripten 'default display'
// }
// else
// return 0; // EGL_NO_DISPLAY
}
function _eglGetError ( ) {
return EGL . errorCode ;
}
function _eglInitialize ( display , majorVersion , minorVersion ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
if ( majorVersion ) {
HEAP32 [ ( ( majorVersion ) >> 2 ) ] = 1 ; // Advertise EGL Major version: '1'
}
if ( minorVersion ) {
HEAP32 [ ( ( minorVersion ) >> 2 ) ] = 4 ; // Advertise EGL Minor version: '4'
}
EGL . defaultDisplayInitialized = true ;
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 ;
}
function _eglMakeCurrent ( display , draw , read , context ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 /* EGL_FALSE */ ;
}
//\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
if ( context != 0 && context != 62004 /* Magic ID for Emscripten EGLContext */ ) {
EGL . setErrorCode ( 0x3006 /* EGL_BAD_CONTEXT */ ) ;
return 0 ;
}
if ( ( read != 0 && read != 62006 ) || ( draw != 0 && draw != 62006 /* Magic ID for Emscripten 'default surface' */ ) ) {
EGL . setErrorCode ( 0x300D /* EGL_BAD_SURFACE */ ) ;
return 0 ;
}
GL . makeContextCurrent ( context ? EGL . context : null ) ;
EGL . currentContext = context ;
EGL . currentDrawSurface = draw ;
EGL . currentReadSurface = read ;
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 /* EGL_TRUE */ ;
}
function stringToUTF8 ( str , outPtr , maxBytesToWrite ) {
assert ( typeof maxBytesToWrite == 'number' , 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!' ) ;
return stringToUTF8Array ( str , HEAPU8 , outPtr , maxBytesToWrite ) ;
}
function stringToNewUTF8 ( str ) {
var size = lengthBytesUTF8 ( str ) + 1 ;
var ret = _malloc ( size ) ;
if ( ret ) stringToUTF8 ( str , ret , size ) ;
return ret ;
}
function _eglQueryString ( display , name ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
//\todo An EGL_NOT_INITIALIZED error is generated if EGL is not initialized for dpy.
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
if ( EGL . stringCache [ name ] ) return EGL . stringCache [ name ] ;
var ret ;
switch ( name ) {
case 0x3053 /* EGL_VENDOR */ : ret = stringToNewUTF8 ( "Emscripten" ) ; break ;
case 0x3054 /* EGL_VERSION */ : ret = stringToNewUTF8 ( "1.4 Emscripten EGL" ) ; break ;
case 0x3055 /* EGL_EXTENSIONS */ : ret = stringToNewUTF8 ( "" ) ; break ; // Currently not supporting any EGL extensions.
case 0x308D /* EGL_CLIENT_APIS */ : ret = stringToNewUTF8 ( "OpenGL_ES" ) ; break ;
default :
EGL . setErrorCode ( 0x300C /* EGL_BAD_PARAMETER */ ) ;
return 0 ;
}
EGL . stringCache [ name ] = ret ;
return ret ;
}
function _eglSwapBuffers ( dpy , surface ) {
if ( ! EGL . defaultDisplayInitialized ) {
EGL . setErrorCode ( 0x3001 /* EGL_NOT_INITIALIZED */ ) ;
} else if ( ! Module . ctx ) {
EGL . setErrorCode ( 0x3002 /* EGL_BAD_ACCESS */ ) ;
} else if ( Module . ctx . isContextLost ( ) ) {
EGL . setErrorCode ( 0x300E /* EGL_CONTEXT_LOST */ ) ;
} else {
// According to documentation this does an implicit flush.
// Due to discussion at https://github.com/emscripten-core/emscripten/pull/1871
// the flush was removed since this _may_ result in slowing code down.
//_glFlush();
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 /* EGL_TRUE */ ;
}
return 0 /* EGL_FALSE */ ;
}
function _eglSwapInterval ( display , interval ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
if ( interval == 0 ) _emscripten _set _main _loop _timing ( 0 , 0 ) ;
else _emscripten _set _main _loop _timing ( 1 , interval ) ;
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 ;
}
function _eglTerminate ( display ) {
if ( display != 62000 /* Magic ID for Emscripten 'default display' */ ) {
EGL . setErrorCode ( 0x3008 /* EGL_BAD_DISPLAY */ ) ;
return 0 ;
}
EGL . currentContext = 0 ;
EGL . currentReadSurface = 0 ;
EGL . currentDrawSurface = 0 ;
EGL . defaultDisplayInitialized = false ;
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 ;
}
/** @suppress {duplicate } */
function _eglWaitClient ( ) {
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 ;
}
var _eglWaitGL = _eglWaitClient ;
function _eglWaitNative ( nativeEngineId ) {
EGL . setErrorCode ( 0x3000 /* EGL_SUCCESS */ ) ;
return 1 ;
}
var readEmAsmArgsArray = [ ] ;
function readEmAsmArgs ( sigPtr , buf ) {
// Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array.
assert ( Array . isArray ( readEmAsmArgsArray ) ) ;
// The input buffer is allocated on the stack, so it must be stack-aligned.
assert ( buf % 16 == 0 ) ;
readEmAsmArgsArray . length = 0 ;
var ch ;
// Most arguments are i32s, so shift the buffer pointer so it is a plain
// index into HEAP32.
buf >>= 2 ;
while ( ch = HEAPU8 [ sigPtr ++ ] ) {
var chr = String . fromCharCode ( ch ) ;
var validChars = [ 'd' , 'f' , 'i' ] ;
assert ( validChars . includes ( chr ) , ` Invalid character ${ ch } (" ${ chr } ") in readEmAsmArgs! Use only [ ${ validChars } ], and do not specify "v" for void return argument. ` ) ;
// Floats are always passed as doubles, and doubles and int64s take up 8
// bytes (two 32-bit slots) in memory, align reads to these:
buf += ( ch != 105 /*i*/ ) & buf ;
readEmAsmArgsArray . push (
ch == 105 /*i*/ ? HEAP32 [ buf ] :
HEAPF64 [ buf ++ >> 1 ]
) ;
++ buf ;
}
return readEmAsmArgsArray ;
}
function runEmAsmFunction ( code , sigPtr , argbuf ) {
var args = readEmAsmArgs ( sigPtr , argbuf ) ;
if ( ! ASM _CONSTS . hasOwnProperty ( code ) ) abort ( ` No EM_ASM constant found at address ${ code } ` ) ;
return ASM _CONSTS [ code ] . apply ( null , args ) ;
}
function _emscripten _asm _const _int ( code , sigPtr , argbuf ) {
return runEmAsmFunction ( code , sigPtr , argbuf ) ;
}
function runMainThreadEmAsm ( code , sigPtr , argbuf , sync ) {
var args = readEmAsmArgs ( sigPtr , argbuf ) ;
if ( ! ASM _CONSTS . hasOwnProperty ( code ) ) abort ( ` No EM_ASM constant found at address ${ code } ` ) ;
return ASM _CONSTS [ code ] . apply ( null , args ) ;
}
function _emscripten _asm _const _int _sync _on _main _thread ( code , sigPtr , argbuf ) {
return runMainThreadEmAsm ( code , sigPtr , argbuf , 1 ) ;
}
function _emscripten _cancel _main _loop ( ) {
Browser . mainLoop . pause ( ) ;
Browser . mainLoop . func = null ;
}
function _emscripten _date _now ( ) {
return Date . now ( ) ;
}
function withStackSave ( f ) {
var stack = stackSave ( ) ;
var ret = f ( ) ;
stackRestore ( stack ) ;
return ret ;
}
var JSEvents = { inEventHandler : 0 , removeAllEventListeners : function ( ) {
for ( var i = JSEvents . eventHandlers . length - 1 ; i >= 0 ; -- i ) {
JSEvents . _removeHandler ( i ) ;
}
JSEvents . eventHandlers = [ ] ;
JSEvents . deferredCalls = [ ] ;
} , registerRemoveEventListeners : function ( ) {
if ( ! JSEvents . removeEventListenersRegistered ) {
_ _ATEXIT _ _ . push ( JSEvents . removeAllEventListeners ) ;
JSEvents . removeEventListenersRegistered = true ;
}
} , deferredCalls : [ ] , deferCall : function ( targetFunction , precedence , argsList ) {
function arraysHaveEqualContent ( arrA , arrB ) {
if ( arrA . length != arrB . length ) return false ;
for ( var i in arrA ) {
if ( arrA [ i ] != arrB [ i ] ) return false ;
}
return true ;
}
// Test if the given call was already queued, and if so, don't add it again.
for ( var i in JSEvents . deferredCalls ) {
var call = JSEvents . deferredCalls [ i ] ;
if ( call . targetFunction == targetFunction && arraysHaveEqualContent ( call . argsList , argsList ) ) {
return ;
}
}
JSEvents . deferredCalls . push ( {
targetFunction : targetFunction ,
precedence : precedence ,
argsList : argsList
} ) ;
JSEvents . deferredCalls . sort ( function ( x , y ) { return x . precedence < y . precedence ; } ) ;
} , removeDeferredCalls : function ( targetFunction ) {
for ( var i = 0 ; i < JSEvents . deferredCalls . length ; ++ i ) {
if ( JSEvents . deferredCalls [ i ] . targetFunction == targetFunction ) {
JSEvents . deferredCalls . splice ( i , 1 ) ;
-- i ;
}
}
} , canPerformEventHandlerRequests : function ( ) {
return JSEvents . inEventHandler && JSEvents . currentEventHandler . allowsDeferredCalls ;
} , runDeferredCalls : function ( ) {
if ( ! JSEvents . canPerformEventHandlerRequests ( ) ) {
return ;
}
for ( var i = 0 ; i < JSEvents . deferredCalls . length ; ++ i ) {
var call = JSEvents . deferredCalls [ i ] ;
JSEvents . deferredCalls . splice ( i , 1 ) ;
-- i ;
call . targetFunction . apply ( null , call . argsList ) ;
}
} , eventHandlers : [ ] , removeAllHandlersOnTarget : function ( target , eventTypeString ) {
for ( var i = 0 ; i < JSEvents . eventHandlers . length ; ++ i ) {
if ( JSEvents . eventHandlers [ i ] . target == target &&
( ! eventTypeString || eventTypeString == JSEvents . eventHandlers [ i ] . eventTypeString ) ) {
JSEvents . _removeHandler ( i -- ) ;
}
}
} , _removeHandler : function ( i ) {
var h = JSEvents . eventHandlers [ i ] ;
h . target . removeEventListener ( h . eventTypeString , h . eventListenerFunc , h . useCapture ) ;
JSEvents . eventHandlers . splice ( i , 1 ) ;
} , registerOrRemoveHandler : function ( eventHandler ) {
if ( ! eventHandler . target ) {
err ( 'registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:' ) ;
console . dir ( eventHandler ) ;
return - 4 ;
}
var jsEventHandler = function jsEventHandler ( event ) {
// Increment nesting count for the event handler.
++ JSEvents . inEventHandler ;
JSEvents . currentEventHandler = eventHandler ;
// Process any old deferred calls the user has placed.
JSEvents . runDeferredCalls ( ) ;
// Process the actual event, calls back to user C code handler.
eventHandler . handlerFunc ( event ) ;
// Process any new deferred calls that were placed right now from this event handler.
JSEvents . runDeferredCalls ( ) ;
// Out of event handler - restore nesting count.
-- JSEvents . inEventHandler ;
} ;
if ( eventHandler . callbackfunc ) {
eventHandler . eventListenerFunc = jsEventHandler ;
eventHandler . target . addEventListener ( eventHandler . eventTypeString , jsEventHandler , eventHandler . useCapture ) ;
JSEvents . eventHandlers . push ( eventHandler ) ;
JSEvents . registerRemoveEventListeners ( ) ;
} else {
for ( var i = 0 ; i < JSEvents . eventHandlers . length ; ++ i ) {
if ( JSEvents . eventHandlers [ i ] . target == eventHandler . target
&& JSEvents . eventHandlers [ i ] . eventTypeString == eventHandler . eventTypeString ) {
JSEvents . _removeHandler ( i -- ) ;
}
}
}
return 0 ;
} , getNodeNameForTarget : function ( target ) {
if ( ! target ) return '' ;
if ( target == window ) return '#window' ;
if ( target == screen ) return '#screen' ;
return ( target && target . nodeName ) ? target . nodeName : '' ;
} , fullscreenEnabled : function ( ) {
return document . fullscreenEnabled
// Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled.
// TODO: If Safari at some point ships with unprefixed version, update the version check above.
|| document . webkitFullscreenEnabled
;
} } ;
var currentFullscreenStrategy = { } ;
function maybeCStringToJsString ( cString ) {
// "cString > 2" checks if the input is a number, and isn't of the special
// values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2).
// In other words, if cString > 2 then it's a pointer to a valid place in
// memory, and points to a C string.
return cString > 2 ? UTF8ToString ( cString ) : cString ;
}
var specialHTMLTargets = [ 0 , typeof document != 'undefined' ? document : 0 , typeof window != 'undefined' ? window : 0 ] ;
function findEventTarget ( target ) {
target = maybeCStringToJsString ( target ) ;
var domElement = specialHTMLTargets [ target ] || ( typeof document != 'undefined' ? document . querySelector ( target ) : undefined ) ;
return domElement ;
}
function findCanvasEventTarget ( target ) { return findEventTarget ( target ) ; }
function _emscripten _get _canvas _element _size ( target , width , height ) {
var canvas = findCanvasEventTarget ( target ) ;
if ( ! canvas ) return - 4 ;
HEAP32 [ ( ( width ) >> 2 ) ] = canvas . width ;
HEAP32 [ ( ( height ) >> 2 ) ] = canvas . height ;
}
function stringToUTF8OnStack ( str ) {
var size = lengthBytesUTF8 ( str ) + 1 ;
var ret = stackAlloc ( size ) ;
stringToUTF8 ( str , ret , size ) ;
return ret ;
}
function getCanvasElementSize ( target ) {
return withStackSave ( function ( ) {
var w = stackAlloc ( 8 ) ;
var h = w + 4 ;
var targetInt = stringToUTF8OnStack ( target . id ) ;
var ret = _emscripten _get _canvas _element _size ( targetInt , w , h ) ;
var size = [ HEAP32 [ ( ( w ) >> 2 ) ] , HEAP32 [ ( ( h ) >> 2 ) ] ] ;
return size ;
} ) ;
}
function _emscripten _set _canvas _element _size ( target , width , height ) {
var canvas = findCanvasEventTarget ( target ) ;
if ( ! canvas ) return - 4 ;
canvas . width = width ;
canvas . height = height ;
return 0 ;
}
function setCanvasElementSize ( target , width , height ) {
if ( ! target . controlTransferredOffscreen ) {
target . width = width ;
target . height = height ;
} else {
// This function is being called from high-level JavaScript code instead of asm.js/Wasm,
// and it needs to synchronously proxy over to another thread, so marshal the string onto the heap to do the call.
withStackSave ( function ( ) {
var targetInt = stringToUTF8OnStack ( target . id ) ;
_emscripten _set _canvas _element _size ( targetInt , width , height ) ;
} ) ;
}
}
function registerRestoreOldStyle ( canvas ) {
var canvasSize = getCanvasElementSize ( canvas ) ;
var oldWidth = canvasSize [ 0 ] ;
var oldHeight = canvasSize [ 1 ] ;
var oldCssWidth = canvas . style . width ;
var oldCssHeight = canvas . style . height ;
var oldBackgroundColor = canvas . style . backgroundColor ; // Chrome reads color from here.
var oldDocumentBackgroundColor = document . body . style . backgroundColor ; // IE11 reads color from here.
// Firefox always has black background color.
var oldPaddingLeft = canvas . style . paddingLeft ; // Chrome, FF, Safari
var oldPaddingRight = canvas . style . paddingRight ;
var oldPaddingTop = canvas . style . paddingTop ;
var oldPaddingBottom = canvas . style . paddingBottom ;
var oldMarginLeft = canvas . style . marginLeft ; // IE11
var oldMarginRight = canvas . style . marginRight ;
var oldMarginTop = canvas . style . marginTop ;
var oldMarginBottom = canvas . style . marginBottom ;
var oldDocumentBodyMargin = document . body . style . margin ;
var oldDocumentOverflow = document . documentElement . style . overflow ; // Chrome, Firefox
var oldDocumentScroll = document . body . scroll ; // IE
var oldImageRendering = canvas . style . imageRendering ;
function restoreOldStyle ( ) {
var fullscreenElement = document . fullscreenElement
|| document . webkitFullscreenElement
;
if ( ! fullscreenElement ) {
document . removeEventListener ( 'fullscreenchange' , restoreOldStyle ) ;
// Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
// As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
document . removeEventListener ( 'webkitfullscreenchange' , restoreOldStyle ) ;
setCanvasElementSize ( canvas , oldWidth , oldHeight ) ;
canvas . style . width = oldCssWidth ;
canvas . style . height = oldCssHeight ;
canvas . style . backgroundColor = oldBackgroundColor ; // Chrome
// IE11 hack: assigning 'undefined' or an empty string to document.body.style.backgroundColor has no effect, so first assign back the default color
// before setting the undefined value. Setting undefined value is also important, or otherwise we would later treat that as something that the user
// had explicitly set so subsequent fullscreen transitions would not set background color properly.
if ( ! oldDocumentBackgroundColor ) document . body . style . backgroundColor = 'white' ;
document . body . style . backgroundColor = oldDocumentBackgroundColor ; // IE11
canvas . style . paddingLeft = oldPaddingLeft ; // Chrome, FF, Safari
canvas . style . paddingRight = oldPaddingRight ;
canvas . style . paddingTop = oldPaddingTop ;
canvas . style . paddingBottom = oldPaddingBottom ;
canvas . style . marginLeft = oldMarginLeft ; // IE11
canvas . style . marginRight = oldMarginRight ;
canvas . style . marginTop = oldMarginTop ;
canvas . style . marginBottom = oldMarginBottom ;
document . body . style . margin = oldDocumentBodyMargin ;
document . documentElement . style . overflow = oldDocumentOverflow ; // Chrome, Firefox
document . body . scroll = oldDocumentScroll ; // IE
canvas . style . imageRendering = oldImageRendering ;
if ( canvas . GLctxObject ) canvas . GLctxObject . GLctx . viewport ( 0 , 0 , oldWidth , oldHeight ) ;
if ( currentFullscreenStrategy . canvasResizedCallback ) {
getWasmTableEntry ( currentFullscreenStrategy . canvasResizedCallback ) ( 37 , 0 , currentFullscreenStrategy . canvasResizedCallbackUserData ) ;
}
}
}
document . addEventListener ( 'fullscreenchange' , restoreOldStyle ) ;
// Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
// As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
document . addEventListener ( 'webkitfullscreenchange' , restoreOldStyle ) ;
return restoreOldStyle ;
}
function setLetterbox ( element , topBottom , leftRight ) {
// Cannot use margin to specify letterboxes in FF or Chrome, since those ignore margins in fullscreen mode.
element . style . paddingLeft = element . style . paddingRight = leftRight + 'px' ;
element . style . paddingTop = element . style . paddingBottom = topBottom + 'px' ;
}
function getBoundingClientRect ( e ) {
return specialHTMLTargets . indexOf ( e ) < 0 ? e . getBoundingClientRect ( ) : { 'left' : 0 , 'top' : 0 } ;
}
function JSEvents _resizeCanvasForFullscreen ( target , strategy ) {
var restoreOldStyle = registerRestoreOldStyle ( target ) ;
var cssWidth = strategy . softFullscreen ? innerWidth : screen . width ;
var cssHeight = strategy . softFullscreen ? innerHeight : screen . height ;
var rect = getBoundingClientRect ( target ) ;
var windowedCssWidth = rect . width ;
var windowedCssHeight = rect . height ;
var canvasSize = getCanvasElementSize ( target ) ;
var windowedRttWidth = canvasSize [ 0 ] ;
var windowedRttHeight = canvasSize [ 1 ] ;
if ( strategy . scaleMode == 3 ) {
setLetterbox ( target , ( cssHeight - windowedCssHeight ) / 2 , ( cssWidth - windowedCssWidth ) / 2 ) ;
cssWidth = windowedCssWidth ;
cssHeight = windowedCssHeight ;
} else if ( strategy . scaleMode == 2 ) {
if ( cssWidth * windowedRttHeight < windowedRttWidth * cssHeight ) {
var desiredCssHeight = windowedRttHeight * cssWidth / windowedRttWidth ;
setLetterbox ( target , ( cssHeight - desiredCssHeight ) / 2 , 0 ) ;
cssHeight = desiredCssHeight ;
} else {
var desiredCssWidth = windowedRttWidth * cssHeight / windowedRttHeight ;
setLetterbox ( target , 0 , ( cssWidth - desiredCssWidth ) / 2 ) ;
cssWidth = desiredCssWidth ;
}
}
// If we are adding padding, must choose a background color or otherwise Chrome will give the
// padding a default white color. Do it only if user has not customized their own background color.
if ( ! target . style . backgroundColor ) target . style . backgroundColor = 'black' ;
// IE11 does the same, but requires the color to be set in the document body.
if ( ! document . body . style . backgroundColor ) document . body . style . backgroundColor = 'black' ; // IE11
// Firefox always shows black letterboxes independent of style color.
target . style . width = cssWidth + 'px' ;
target . style . height = cssHeight + 'px' ;
if ( strategy . filteringMode == 1 ) {
target . style . imageRendering = 'optimizeSpeed' ;
target . style . imageRendering = '-moz-crisp-edges' ;
target . style . imageRendering = '-o-crisp-edges' ;
target . style . imageRendering = '-webkit-optimize-contrast' ;
target . style . imageRendering = 'optimize-contrast' ;
target . style . imageRendering = 'crisp-edges' ;
target . style . imageRendering = 'pixelated' ;
}
var dpiScale = ( strategy . canvasResolutionScaleMode == 2 ) ? devicePixelRatio : 1 ;
if ( strategy . canvasResolutionScaleMode != 0 ) {
var newWidth = ( cssWidth * dpiScale ) | 0 ;
var newHeight = ( cssHeight * dpiScale ) | 0 ;
setCanvasElementSize ( target , newWidth , newHeight ) ;
if ( target . GLctxObject ) target . GLctxObject . GLctx . viewport ( 0 , 0 , newWidth , newHeight ) ;
}
return restoreOldStyle ;
}
function JSEvents _requestFullscreen ( target , strategy ) {
// EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE is a mode where no extra logic is performed to the DOM elements.
if ( strategy . scaleMode != 0 || strategy . canvasResolutionScaleMode != 0 ) {
JSEvents _resizeCanvasForFullscreen ( target , strategy ) ;
}
if ( target . requestFullscreen ) {
target . requestFullscreen ( ) ;
} else if ( target . webkitRequestFullscreen ) {
target . webkitRequestFullscreen ( Element . ALLOW _KEYBOARD _INPUT ) ;
} else {
return JSEvents . fullscreenEnabled ( ) ? - 3 : - 1 ;
}
currentFullscreenStrategy = strategy ;
if ( strategy . canvasResizedCallback ) {
getWasmTableEntry ( strategy . canvasResizedCallback ) ( 37 , 0 , strategy . canvasResizedCallbackUserData ) ;
}
return 0 ;
}
function _emscripten _exit _fullscreen ( ) {
if ( ! JSEvents . fullscreenEnabled ( ) ) return - 1 ;
// Make sure no queued up calls will fire after this.
JSEvents . removeDeferredCalls ( JSEvents _requestFullscreen ) ;
var d = specialHTMLTargets [ 1 ] ;
if ( d . exitFullscreen ) {
d . fullscreenElement && d . exitFullscreen ( ) ;
} else if ( d . webkitExitFullscreen ) {
d . webkitFullscreenElement && d . webkitExitFullscreen ( ) ;
} else {
return - 1 ;
}
return 0 ;
}
function requestPointerLock ( target ) {
if ( target . requestPointerLock ) {
target . requestPointerLock ( ) ;
} else {
// document.body is known to accept pointer lock, so use that to differentiate if the user passed a bad element,
// or if the whole browser just doesn't support the feature.
if ( document . body . requestPointerLock
) {
return - 3 ;
}
return - 1 ;
}
return 0 ;
}
function _emscripten _exit _pointerlock ( ) {
// Make sure no queued up calls will fire after this.
JSEvents . removeDeferredCalls ( requestPointerLock ) ;
if ( document . exitPointerLock ) {
document . exitPointerLock ( ) ;
} else {
return - 1 ;
}
return 0 ;
}
function _emscripten _get _device _pixel _ratio ( ) {
return ( typeof devicePixelRatio == 'number' && devicePixelRatio ) || 1.0 ;
}
function _emscripten _get _element _css _size ( target , width , height ) {
target = findEventTarget ( target ) ;
if ( ! target ) return - 4 ;
var rect = getBoundingClientRect ( target ) ;
HEAPF64 [ ( ( width ) >> 3 ) ] = rect . width ;
HEAPF64 [ ( ( height ) >> 3 ) ] = rect . height ;
return 0 ;
}
function fillGamepadEventData ( eventStruct , e ) {
HEAPF64 [ ( ( eventStruct ) >> 3 ) ] = e . timestamp ;
for ( var i = 0 ; i < e . axes . length ; ++ i ) {
HEAPF64 [ ( ( ( eventStruct + i * 8 ) + ( 16 ) ) >> 3 ) ] = e . axes [ i ] ;
}
for ( var i = 0 ; i < e . buttons . length ; ++ i ) {
if ( typeof e . buttons [ i ] == 'object' ) {
HEAPF64 [ ( ( ( eventStruct + i * 8 ) + ( 528 ) ) >> 3 ) ] = e . buttons [ i ] . value ;
} else {
HEAPF64 [ ( ( ( eventStruct + i * 8 ) + ( 528 ) ) >> 3 ) ] = e . buttons [ i ] ;
}
}
for ( var i = 0 ; i < e . buttons . length ; ++ i ) {
if ( typeof e . buttons [ i ] == 'object' ) {
HEAP32 [ ( ( ( eventStruct + i * 4 ) + ( 1040 ) ) >> 2 ) ] = e . buttons [ i ] . pressed ;
} else {
// Assigning a boolean to HEAP32, that's ok, but Closure would like to warn about it:
/** @suppress {checkTypes} */
HEAP32 [ ( ( ( eventStruct + i * 4 ) + ( 1040 ) ) >> 2 ) ] = e . buttons [ i ] == 1 ;
}
}
HEAP32 [ ( ( ( eventStruct ) + ( 1296 ) ) >> 2 ) ] = e . connected ;
HEAP32 [ ( ( ( eventStruct ) + ( 1300 ) ) >> 2 ) ] = e . index ;
HEAP32 [ ( ( ( eventStruct ) + ( 8 ) ) >> 2 ) ] = e . axes . length ;
HEAP32 [ ( ( ( eventStruct ) + ( 12 ) ) >> 2 ) ] = e . buttons . length ;
stringToUTF8 ( e . id , eventStruct + 1304 , 64 ) ;
stringToUTF8 ( e . mapping , eventStruct + 1368 , 64 ) ;
}
function _emscripten _get _gamepad _status ( index , gamepadState ) {
if ( ! JSEvents . lastGamepadState ) throw 'emscripten_get_gamepad_status() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!' ;
// INVALID_PARAM is returned on a Gamepad index that never was there.
if ( index < 0 || index >= JSEvents . lastGamepadState . length ) return - 5 ;
// NO_DATA is returned on a Gamepad index that was removed.
// For previously disconnected gamepads there should be an empty slot (null/undefined/false) at the index.
// This is because gamepads must keep their original position in the array.
// For example, removing the first of two gamepads produces [null/undefined/false, gamepad].
if ( ! JSEvents . lastGamepadState [ index ] ) return - 7 ;
fillGamepadEventData ( gamepadState , JSEvents . lastGamepadState [ index ] ) ;
return 0 ;
}
function _emscripten _get _num _gamepads ( ) {
if ( ! JSEvents . lastGamepadState ) throw 'emscripten_get_num_gamepads() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!' ;
// N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS.
// Otherwise the following line will throw an exception.
return JSEvents . lastGamepadState . length ;
}
function _emscripten _get _screen _size ( width , height ) {
HEAP32 [ ( ( width ) >> 2 ) ] = screen . width ;
HEAP32 [ ( ( height ) >> 2 ) ] = screen . height ;
}
/** @suppress {duplicate } */
function _glActiveTexture ( x0 ) { GLctx . activeTexture ( x0 ) }
var _emscripten _glActiveTexture = _glActiveTexture ;
/** @suppress {duplicate } */
function _glAttachShader ( program , shader ) {
GLctx . attachShader ( GL . programs [ program ] , GL . shaders [ shader ] ) ;
}
var _emscripten _glAttachShader = _glAttachShader ;
/** @suppress {duplicate } */
function _glBeginQuery ( target , id ) {
GLctx . beginQuery ( target , GL . queries [ id ] ) ;
}
var _emscripten _glBeginQuery = _glBeginQuery ;
/** @suppress {duplicate } */
function _glBeginQueryEXT ( target , id ) {
GLctx . disjointTimerQueryExt [ 'beginQueryEXT' ] ( target , GL . queries [ id ] ) ;
}
var _emscripten _glBeginQueryEXT = _glBeginQueryEXT ;
/** @suppress {duplicate } */
function _glBeginTransformFeedback ( x0 ) { GLctx . beginTransformFeedback ( x0 ) }
var _emscripten _glBeginTransformFeedback = _glBeginTransformFeedback ;
/** @suppress {duplicate } */
function _glBindAttribLocation ( program , index , name ) {
GLctx . bindAttribLocation ( GL . programs [ program ] , index , UTF8ToString ( name ) ) ;
}
var _emscripten _glBindAttribLocation = _glBindAttribLocation ;
/** @suppress {duplicate } */
function _glBindBuffer ( target , buffer ) {
if ( target == 0x88EB /*GL_PIXEL_PACK_BUFFER*/ ) {
// In WebGL 2 glReadPixels entry point, we need to use a different WebGL 2 API function call when a buffer is bound to
// GL_PIXEL_PACK_BUFFER_BINDING point, so must keep track whether that binding point is non-null to know what is
// the proper API function to call.
GLctx . currentPixelPackBufferBinding = buffer ;
} else if ( target == 0x88EC /*GL_PIXEL_UNPACK_BUFFER*/ ) {
// In WebGL 2 gl(Compressed)Tex(Sub)Image[23]D entry points, we need to
// use a different WebGL 2 API function call when a buffer is bound to
// GL_PIXEL_UNPACK_BUFFER_BINDING point, so must keep track whether that
// binding point is non-null to know what is the proper API function to
// call.
GLctx . currentPixelUnpackBufferBinding = buffer ;
}
GLctx . bindBuffer ( target , GL . buffers [ buffer ] ) ;
}
var _emscripten _glBindBuffer = _glBindBuffer ;
/** @suppress {duplicate } */
function _glBindBufferBase ( target , index , buffer ) {
GLctx . bindBufferBase ( target , index , GL . buffers [ buffer ] ) ;
}
var _emscripten _glBindBufferBase = _glBindBufferBase ;
/** @suppress {duplicate } */
function _glBindBufferRange ( target , index , buffer , offset , ptrsize ) {
GLctx . bindBufferRange ( target , index , GL . buffers [ buffer ] , offset , ptrsize ) ;
}
var _emscripten _glBindBufferRange = _glBindBufferRange ;
/** @suppress {duplicate } */
function _glBindFramebuffer ( target , framebuffer ) {
GLctx . bindFramebuffer ( target , GL . framebuffers [ framebuffer ] ) ;
}
var _emscripten _glBindFramebuffer = _glBindFramebuffer ;
/** @suppress {duplicate } */
function _glBindRenderbuffer ( target , renderbuffer ) {
GLctx . bindRenderbuffer ( target , GL . renderbuffers [ renderbuffer ] ) ;
}
var _emscripten _glBindRenderbuffer = _glBindRenderbuffer ;
/** @suppress {duplicate } */
function _glBindSampler ( unit , sampler ) {
GLctx . bindSampler ( unit , GL . samplers [ sampler ] ) ;
}
var _emscripten _glBindSampler = _glBindSampler ;
/** @suppress {duplicate } */
function _glBindTexture ( target , texture ) {
GLctx . bindTexture ( target , GL . textures [ texture ] ) ;
}
var _emscripten _glBindTexture = _glBindTexture ;
/** @suppress {duplicate } */
function _glBindTransformFeedback ( target , id ) {
GLctx . bindTransformFeedback ( target , GL . transformFeedbacks [ id ] ) ;
}
var _emscripten _glBindTransformFeedback = _glBindTransformFeedback ;
/** @suppress {duplicate } */
function _glBindVertexArray ( vao ) {
GLctx . bindVertexArray ( GL . vaos [ vao ] ) ;
}
var _emscripten _glBindVertexArray = _glBindVertexArray ;
/** @suppress {duplicate } */
var _glBindVertexArrayOES = _glBindVertexArray ;
var _emscripten _glBindVertexArrayOES = _glBindVertexArrayOES ;
/** @suppress {duplicate } */
function _glBlendColor ( x0 , x1 , x2 , x3 ) { GLctx . blendColor ( x0 , x1 , x2 , x3 ) }
var _emscripten _glBlendColor = _glBlendColor ;
/** @suppress {duplicate } */
function _glBlendEquation ( x0 ) { GLctx . blendEquation ( x0 ) }
var _emscripten _glBlendEquation = _glBlendEquation ;
/** @suppress {duplicate } */
function _glBlendEquationSeparate ( x0 , x1 ) { GLctx . blendEquationSeparate ( x0 , x1 ) }
var _emscripten _glBlendEquationSeparate = _glBlendEquationSeparate ;
/** @suppress {duplicate } */
function _glBlendFunc ( x0 , x1 ) { GLctx . blendFunc ( x0 , x1 ) }
var _emscripten _glBlendFunc = _glBlendFunc ;
/** @suppress {duplicate } */
function _glBlendFuncSeparate ( x0 , x1 , x2 , x3 ) { GLctx . blendFuncSeparate ( x0 , x1 , x2 , x3 ) }
var _emscripten _glBlendFuncSeparate = _glBlendFuncSeparate ;
/** @suppress {duplicate } */
function _glBlitFramebuffer ( x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 ) { GLctx . blitFramebuffer ( x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 ) }
var _emscripten _glBlitFramebuffer = _glBlitFramebuffer ;
/** @suppress {duplicate } */
function _glBufferData ( target , size , data , usage ) {
if ( true ) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
// If size is zero, WebGL would interpret uploading the whole input arraybuffer (starting from given offset), which would
// not make sense in WebAssembly, so avoid uploading if size is zero. However we must still call bufferData to establish a
// backing storage of zero bytes.
if ( data && size ) {
GLctx . bufferData ( target , HEAPU8 , usage , data , size ) ;
} else {
GLctx . bufferData ( target , size , usage ) ;
}
} else {
// N.b. here first form specifies a heap subarray, second form an integer size, so the ?: code here is polymorphic. It is advised to avoid
// randomly mixing both uses in calling code, to avoid any potential JS engine JIT issues.
GLctx . bufferData ( target , data ? HEAPU8 . subarray ( data , data + size ) : size , usage ) ;
}
}
var _emscripten _glBufferData = _glBufferData ;
/** @suppress {duplicate } */
function _glBufferSubData ( target , offset , size , data ) {
if ( true ) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
size && GLctx . bufferSubData ( target , offset , HEAPU8 , data , size ) ;
return ;
}
GLctx . bufferSubData ( target , offset , HEAPU8 . subarray ( data , data + size ) ) ;
}
var _emscripten _glBufferSubData = _glBufferSubData ;
/** @suppress {duplicate } */
function _glCheckFramebufferStatus ( x0 ) { return GLctx . checkFramebufferStatus ( x0 ) }
var _emscripten _glCheckFramebufferStatus = _glCheckFramebufferStatus ;
/** @suppress {duplicate } */
function _glClear ( x0 ) { GLctx . clear ( x0 ) }
var _emscripten _glClear = _glClear ;
/** @suppress {duplicate } */
function _glClearBufferfi ( x0 , x1 , x2 , x3 ) { GLctx . clearBufferfi ( x0 , x1 , x2 , x3 ) }
var _emscripten _glClearBufferfi = _glClearBufferfi ;
/** @suppress {duplicate } */
function _glClearBufferfv ( buffer , drawbuffer , value ) {
GLctx . clearBufferfv ( buffer , drawbuffer , HEAPF32 , value >> 2 ) ;
}
var _emscripten _glClearBufferfv = _glClearBufferfv ;
/** @suppress {duplicate } */
function _glClearBufferiv ( buffer , drawbuffer , value ) {
GLctx . clearBufferiv ( buffer , drawbuffer , HEAP32 , value >> 2 ) ;
}
var _emscripten _glClearBufferiv = _glClearBufferiv ;
/** @suppress {duplicate } */
function _glClearBufferuiv ( buffer , drawbuffer , value ) {
GLctx . clearBufferuiv ( buffer , drawbuffer , HEAPU32 , value >> 2 ) ;
}
var _emscripten _glClearBufferuiv = _glClearBufferuiv ;
/** @suppress {duplicate } */
function _glClearColor ( x0 , x1 , x2 , x3 ) { GLctx . clearColor ( x0 , x1 , x2 , x3 ) }
var _emscripten _glClearColor = _glClearColor ;
/** @suppress {duplicate } */
function _glClearDepthf ( x0 ) { GLctx . clearDepth ( x0 ) }
var _emscripten _glClearDepthf = _glClearDepthf ;
/** @suppress {duplicate } */
function _glClearStencil ( x0 ) { GLctx . clearStencil ( x0 ) }
var _emscripten _glClearStencil = _glClearStencil ;
function convertI32PairToI53 ( lo , hi ) {
// This function should not be getting called with too large unsigned numbers
// in high part (if hi >= 0x7FFFFFFFF, one should have been calling
// convertU32PairToI53())
assert ( hi === ( hi | 0 ) ) ;
return ( lo >>> 0 ) + hi * 4294967296 ;
}
/** @suppress {duplicate } */
function _glClientWaitSync ( sync , flags , timeout _low , timeout _high ) {
// WebGL2 vs GLES3 differences: in GLES3, the timeout parameter is a uint64, where 0xFFFFFFFFFFFFFFFFULL means GL_TIMEOUT_IGNORED.
// In JS, there's no 64-bit value types, so instead timeout is taken to be signed, and GL_TIMEOUT_IGNORED is given value -1.
// Inherently the value accepted in the timeout is lossy, and can't take in arbitrary u64 bit pattern (but most likely doesn't matter)
// See https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.15
var timeout = convertI32PairToI53 ( timeout _low , timeout _high ) ;
return GLctx . clientWaitSync ( GL . syncs [ sync ] , flags , timeout ) ;
}
var _emscripten _glClientWaitSync = _glClientWaitSync ;
/** @suppress {duplicate } */
function _glColorMask ( red , green , blue , alpha ) {
GLctx . colorMask ( ! ! red , ! ! green , ! ! blue , ! ! alpha ) ;
}
var _emscripten _glColorMask = _glColorMask ;
/** @suppress {duplicate } */
function _glCompileShader ( shader ) {
GLctx . compileShader ( GL . shaders [ shader ] ) ;
}
var _emscripten _glCompileShader = _glCompileShader ;
/** @suppress {duplicate } */
function _glCompressedTexImage2D ( target , level , internalFormat , width , height , border , imageSize , data ) {
if ( true ) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
if ( GLctx . currentPixelUnpackBufferBinding || ! imageSize ) {
GLctx . compressedTexImage2D ( target , level , internalFormat , width , height , border , imageSize , data ) ;
} else {
GLctx . compressedTexImage2D ( target , level , internalFormat , width , height , border , HEAPU8 , data , imageSize ) ;
}
return ;
}
GLctx . compressedTexImage2D ( target , level , internalFormat , width , height , border , data ? HEAPU8 . subarray ( ( data ) , ( data + imageSize ) ) : null ) ;
}
var _emscripten _glCompressedTexImage2D = _glCompressedTexImage2D ;
/** @suppress {duplicate } */
function _glCompressedTexImage3D ( target , level , internalFormat , width , height , depth , border , imageSize , data ) {
if ( GLctx . currentPixelUnpackBufferBinding ) {
GLctx . compressedTexImage3D ( target , level , internalFormat , width , height , depth , border , imageSize , data ) ;
} else {
GLctx . compressedTexImage3D ( target , level , internalFormat , width , height , depth , border , HEAPU8 , data , imageSize ) ;
}
}
var _emscripten _glCompressedTexImage3D = _glCompressedTexImage3D ;
/** @suppress {duplicate } */
function _glCompressedTexSubImage2D ( target , level , xoffset , yoffset , width , height , format , imageSize , data ) {
if ( true ) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
if ( GLctx . currentPixelUnpackBufferBinding || ! imageSize ) {
GLctx . compressedTexSubImage2D ( target , level , xoffset , yoffset , width , height , format , imageSize , data ) ;
} else {
GLctx . compressedTexSubImage2D ( target , level , xoffset , yoffset , width , height , format , HEAPU8 , data , imageSize ) ;
}
return ;
}
GLctx . compressedTexSubImage2D ( target , level , xoffset , yoffset , width , height , format , data ? HEAPU8 . subarray ( ( data ) , ( data + imageSize ) ) : null ) ;
}
var _emscripten _glCompressedTexSubImage2D = _glCompressedTexSubImage2D ;
/** @suppress {duplicate } */
function _glCompressedTexSubImage3D ( target , level , xoffset , yoffset , zoffset , width , height , depth , format , imageSize , data ) {
if ( GLctx . currentPixelUnpackBufferBinding ) {
GLctx . compressedTexSubImage3D ( target , level , xoffset , yoffset , zoffset , width , height , depth , format , imageSize , data ) ;
} else {
GLctx . compressedTexSubImage3D ( target , level , xoffset , yoffset , zoffset , width , height , depth , format , HEAPU8 , data , imageSize ) ;
}
}
var _emscripten _glCompressedTexSubImage3D = _glCompressedTexSubImage3D ;
/** @suppress {duplicate } */
function _glCopyBufferSubData ( x0 , x1 , x2 , x3 , x4 ) { GLctx . copyBufferSubData ( x0 , x1 , x2 , x3 , x4 ) }
var _emscripten _glCopyBufferSubData = _glCopyBufferSubData ;
/** @suppress {duplicate } */
function _glCopyTexImage2D ( x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 ) { GLctx . copyTexImage2D ( x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 ) }
var _emscripten _glCopyTexImage2D = _glCopyTexImage2D ;
/** @suppress {duplicate } */
function _glCopyTexSubImage2D ( x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 ) { GLctx . copyTexSubImage2D ( x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 ) }
var _emscripten _glCopyTexSubImage2D = _glCopyTexSubImage2D ;
/** @suppress {duplicate } */
function _glCopyTexSubImage3D ( x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 ) { GLctx . copyTexSubImage3D ( x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 ) }
var _emscripten _glCopyTexSubImage3D = _glCopyTexSubImage3D ;
/** @suppress {duplicate } */
function _glCreateProgram ( ) {
var id = GL . getNewId ( GL . programs ) ;
var program = GLctx . createProgram ( ) ;
// Store additional information needed for each shader program:
program . name = id ;
// Lazy cache results of glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH)
program . maxUniformLength = program . maxAttributeLength = program . maxUniformBlockNameLength = 0 ;
program . uniformIdCounter = 1 ;
GL . programs [ id ] = program ;
return id ;
}
var _emscripten _glCreateProgram = _glCreateProgram ;
/** @suppress {duplicate } */
function _glCreateShader ( shaderType ) {
var id = GL . getNewId ( GL . shaders ) ;
GL . shaders [ id ] = GLctx . createShader ( shaderType ) ;
return id ;
}
var _emscripten _glCreateShader = _glCreateShader ;
/** @suppress {duplicate } */
function _glCullFace ( x0 ) { GLctx . cullFace ( x0 ) }
var _emscripten _glCullFace = _glCullFace ;
/** @suppress {duplicate } */
function _glDeleteBuffers ( n , buffers ) {
for ( var i = 0 ; i < n ; i ++ ) {
var id = HEAP32 [ ( ( ( buffers ) + ( i * 4 ) ) >> 2 ) ] ;
var buffer = GL . buffers [ id ] ;
// From spec: "glDeleteBuffers silently ignores 0's and names that do not
// correspond to existing buffer objects."
if ( ! buffer ) continue ;
GLctx . deleteBuffer ( buffer ) ;
buffer . name = 0 ;
GL . buffers [ id ] = null ;
if ( id == GLctx . currentPixelPackBufferBinding ) GLctx . currentPixelPackBufferBinding = 0 ;
if ( id == GLctx . currentPixelUnpackBufferBinding ) GLctx . currentPixelUnpackBufferBinding = 0 ;
}
}
var _emscripten _glDeleteBuffers = _glDeleteBuffers ;
/** @suppress {duplicate } */
function _glDeleteFramebuffers ( n , framebuffers ) {
for ( var i = 0 ; i < n ; ++ i ) {
var id = HEAP32 [ ( ( ( framebuffers ) + ( i * 4 ) ) >> 2 ) ] ;
var framebuffer = GL . framebuffers [ id ] ;
if ( ! framebuffer ) continue ; // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects".
GLctx . deleteFramebuffer ( framebuffer ) ;
framebuffer . name = 0 ;
GL . framebuffers [ id ] = null ;
}
}
var _emscripten _glDeleteFramebuffers = _glDeleteFramebuffers ;
/** @suppress {duplicate } */
function _glDeleteProgram ( id ) {
if ( ! id ) return ;
var program = GL . programs [ id ] ;
if ( ! program ) { // glDeleteProgram actually signals an error when deleting a nonexisting object, unlike some other GL delete functions.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
GLctx . deleteProgram ( program ) ;
program . name = 0 ;
GL . programs [ id ] = null ;
}
var _emscripten _glDeleteProgram = _glDeleteProgram ;
/** @suppress {duplicate } */
function _glDeleteQueries ( n , ids ) {
for ( var i = 0 ; i < n ; i ++ ) {
var id = HEAP32 [ ( ( ( ids ) + ( i * 4 ) ) >> 2 ) ] ;
var query = GL . queries [ id ] ;
if ( ! query ) continue ; // GL spec: "unused names in ids are ignored, as is the name zero."
GLctx . deleteQuery ( query ) ;
GL . queries [ id ] = null ;
}
}
var _emscripten _glDeleteQueries = _glDeleteQueries ;
/** @suppress {duplicate } */
function _glDeleteQueriesEXT ( n , ids ) {
for ( var i = 0 ; i < n ; i ++ ) {
var id = HEAP32 [ ( ( ( ids ) + ( i * 4 ) ) >> 2 ) ] ;
var query = GL . queries [ id ] ;
if ( ! query ) continue ; // GL spec: "unused names in ids are ignored, as is the name zero."
GLctx . disjointTimerQueryExt [ 'deleteQueryEXT' ] ( query ) ;
GL . queries [ id ] = null ;
}
}
var _emscripten _glDeleteQueriesEXT = _glDeleteQueriesEXT ;
/** @suppress {duplicate } */
function _glDeleteRenderbuffers ( n , renderbuffers ) {
for ( var i = 0 ; i < n ; i ++ ) {
var id = HEAP32 [ ( ( ( renderbuffers ) + ( i * 4 ) ) >> 2 ) ] ;
var renderbuffer = GL . renderbuffers [ id ] ;
if ( ! renderbuffer ) continue ; // GL spec: "glDeleteRenderbuffers silently ignores 0s and names that do not correspond to existing renderbuffer objects".
GLctx . deleteRenderbuffer ( renderbuffer ) ;
renderbuffer . name = 0 ;
GL . renderbuffers [ id ] = null ;
}
}
var _emscripten _glDeleteRenderbuffers = _glDeleteRenderbuffers ;
/** @suppress {duplicate } */
function _glDeleteSamplers ( n , samplers ) {
for ( var i = 0 ; i < n ; i ++ ) {
var id = HEAP32 [ ( ( ( samplers ) + ( i * 4 ) ) >> 2 ) ] ;
var sampler = GL . samplers [ id ] ;
if ( ! sampler ) continue ;
GLctx . deleteSampler ( sampler ) ;
sampler . name = 0 ;
GL . samplers [ id ] = null ;
}
}
var _emscripten _glDeleteSamplers = _glDeleteSamplers ;
/** @suppress {duplicate } */
function _glDeleteShader ( id ) {
if ( ! id ) return ;
var shader = GL . shaders [ id ] ;
if ( ! shader ) { // glDeleteShader actually signals an error when deleting a nonexisting object, unlike some other GL delete functions.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
GLctx . deleteShader ( shader ) ;
GL . shaders [ id ] = null ;
}
var _emscripten _glDeleteShader = _glDeleteShader ;
/** @suppress {duplicate } */
function _glDeleteSync ( id ) {
if ( ! id ) return ;
var sync = GL . syncs [ id ] ;
if ( ! sync ) { // glDeleteSync signals an error when deleting a nonexisting object, unlike some other GL delete functions.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
GLctx . deleteSync ( sync ) ;
sync . name = 0 ;
GL . syncs [ id ] = null ;
}
var _emscripten _glDeleteSync = _glDeleteSync ;
/** @suppress {duplicate } */
function _glDeleteTextures ( n , textures ) {
for ( var i = 0 ; i < n ; i ++ ) {
var id = HEAP32 [ ( ( ( textures ) + ( i * 4 ) ) >> 2 ) ] ;
var texture = GL . textures [ id ] ;
if ( ! texture ) continue ; // GL spec: "glDeleteTextures silently ignores 0s and names that do not correspond to existing textures".
GLctx . deleteTexture ( texture ) ;
texture . name = 0 ;
GL . textures [ id ] = null ;
}
}
var _emscripten _glDeleteTextures = _glDeleteTextures ;
/** @suppress {duplicate } */
function _glDeleteTransformFeedbacks ( n , ids ) {
for ( var i = 0 ; i < n ; i ++ ) {
var id = HEAP32 [ ( ( ( ids ) + ( i * 4 ) ) >> 2 ) ] ;
var transformFeedback = GL . transformFeedbacks [ id ] ;
if ( ! transformFeedback ) continue ; // GL spec: "unused names in ids are ignored, as is the name zero."
GLctx . deleteTransformFeedback ( transformFeedback ) ;
transformFeedback . name = 0 ;
GL . transformFeedbacks [ id ] = null ;
}
}
var _emscripten _glDeleteTransformFeedbacks = _glDeleteTransformFeedbacks ;
/** @suppress {duplicate } */
function _glDeleteVertexArrays ( n , vaos ) {
for ( var i = 0 ; i < n ; i ++ ) {
var id = HEAP32 [ ( ( ( vaos ) + ( i * 4 ) ) >> 2 ) ] ;
GLctx . deleteVertexArray ( GL . vaos [ id ] ) ;
GL . vaos [ id ] = null ;
}
}
var _emscripten _glDeleteVertexArrays = _glDeleteVertexArrays ;
/** @suppress {duplicate } */
var _glDeleteVertexArraysOES = _glDeleteVertexArrays ;
var _emscripten _glDeleteVertexArraysOES = _glDeleteVertexArraysOES ;
/** @suppress {duplicate } */
function _glDepthFunc ( x0 ) { GLctx . depthFunc ( x0 ) }
var _emscripten _glDepthFunc = _glDepthFunc ;
/** @suppress {duplicate } */
function _glDepthMask ( flag ) {
GLctx . depthMask ( ! ! flag ) ;
}
var _emscripten _glDepthMask = _glDepthMask ;
/** @suppress {duplicate } */
function _glDepthRangef ( x0 , x1 ) { GLctx . depthRange ( x0 , x1 ) }
var _emscripten _glDepthRangef = _glDepthRangef ;
/** @suppress {duplicate } */
function _glDetachShader ( program , shader ) {
GLctx . detachShader ( GL . programs [ program ] , GL . shaders [ shader ] ) ;
}
var _emscripten _glDetachShader = _glDetachShader ;
/** @suppress {duplicate } */
function _glDisable ( x0 ) { GLctx . disable ( x0 ) }
var _emscripten _glDisable = _glDisable ;
/** @suppress {duplicate } */
function _glDisableVertexAttribArray ( index ) {
GLctx . disableVertexAttribArray ( index ) ;
}
var _emscripten _glDisableVertexAttribArray = _glDisableVertexAttribArray ;
/** @suppress {duplicate } */
function _glDrawArrays ( mode , first , count ) {
GLctx . drawArrays ( mode , first , count ) ;
}
var _emscripten _glDrawArrays = _glDrawArrays ;
/** @suppress {duplicate } */
function _glDrawArraysInstanced ( mode , first , count , primcount ) {
GLctx . drawArraysInstanced ( mode , first , count , primcount ) ;
}
var _emscripten _glDrawArraysInstanced = _glDrawArraysInstanced ;
/** @suppress {duplicate } */
var _glDrawArraysInstancedANGLE = _glDrawArraysInstanced ;
var _emscripten _glDrawArraysInstancedANGLE = _glDrawArraysInstancedANGLE ;
/** @suppress {duplicate } */
var _glDrawArraysInstancedARB = _glDrawArraysInstanced ;
var _emscripten _glDrawArraysInstancedARB = _glDrawArraysInstancedARB ;
/** @suppress {duplicate } */
var _glDrawArraysInstancedEXT = _glDrawArraysInstanced ;
var _emscripten _glDrawArraysInstancedEXT = _glDrawArraysInstancedEXT ;
/** @suppress {duplicate } */
var _glDrawArraysInstancedNV = _glDrawArraysInstanced ;
var _emscripten _glDrawArraysInstancedNV = _glDrawArraysInstancedNV ;
var tempFixedLengthArray = [ ] ;
/** @suppress {duplicate } */
function _glDrawBuffers ( n , bufs ) {
var bufArray = tempFixedLengthArray [ n ] ;
for ( var i = 0 ; i < n ; i ++ ) {
bufArray [ i ] = HEAP32 [ ( ( ( bufs ) + ( i * 4 ) ) >> 2 ) ] ;
}
GLctx . drawBuffers ( bufArray ) ;
}
var _emscripten _glDrawBuffers = _glDrawBuffers ;
/** @suppress {duplicate } */
var _glDrawBuffersEXT = _glDrawBuffers ;
var _emscripten _glDrawBuffersEXT = _glDrawBuffersEXT ;
/** @suppress {duplicate } */
var _glDrawBuffersWEBGL = _glDrawBuffers ;
var _emscripten _glDrawBuffersWEBGL = _glDrawBuffersWEBGL ;
/** @suppress {duplicate } */
function _glDrawElements ( mode , count , type , indices ) {
GLctx . drawElements ( mode , count , type , indices ) ;
}
var _emscripten _glDrawElements = _glDrawElements ;
/** @suppress {duplicate } */
function _glDrawElementsInstanced ( mode , count , type , indices , primcount ) {
GLctx . drawElementsInstanced ( mode , count , type , indices , primcount ) ;
}
var _emscripten _glDrawElementsInstanced = _glDrawElementsInstanced ;
/** @suppress {duplicate } */
var _glDrawElementsInstancedANGLE = _glDrawElementsInstanced ;
var _emscripten _glDrawElementsInstancedANGLE = _glDrawElementsInstancedANGLE ;
/** @suppress {duplicate } */
var _glDrawElementsInstancedARB = _glDrawElementsInstanced ;
var _emscripten _glDrawElementsInstancedARB = _glDrawElementsInstancedARB ;
/** @suppress {duplicate } */
var _glDrawElementsInstancedEXT = _glDrawElementsInstanced ;
var _emscripten _glDrawElementsInstancedEXT = _glDrawElementsInstancedEXT ;
/** @suppress {duplicate } */
var _glDrawElementsInstancedNV = _glDrawElementsInstanced ;
var _emscripten _glDrawElementsInstancedNV = _glDrawElementsInstancedNV ;
/** @suppress {duplicate } */
function _glDrawRangeElements ( mode , start , end , count , type , indices ) {
// TODO: This should be a trivial pass-though function registered at the bottom of this page as
// glFuncs[6][1] += ' drawRangeElements';
// but due to https://bugzilla.mozilla.org/show_bug.cgi?id=1202427,
// we work around by ignoring the range.
_glDrawElements ( mode , count , type , indices ) ;
}
var _emscripten _glDrawRangeElements = _glDrawRangeElements ;
/** @suppress {duplicate } */
function _glEnable ( x0 ) { GLctx . enable ( x0 ) }
var _emscripten _glEnable = _glEnable ;
/** @suppress {duplicate } */
function _glEnableVertexAttribArray ( index ) {
GLctx . enableVertexAttribArray ( index ) ;
}
var _emscripten _glEnableVertexAttribArray = _glEnableVertexAttribArray ;
/** @suppress {duplicate } */
function _glEndQuery ( x0 ) { GLctx . endQuery ( x0 ) }
var _emscripten _glEndQuery = _glEndQuery ;
/** @suppress {duplicate } */
function _glEndQueryEXT ( target ) {
GLctx . disjointTimerQueryExt [ 'endQueryEXT' ] ( target ) ;
}
var _emscripten _glEndQueryEXT = _glEndQueryEXT ;
/** @suppress {duplicate } */
function _glEndTransformFeedback ( ) { GLctx . endTransformFeedback ( ) }
var _emscripten _glEndTransformFeedback = _glEndTransformFeedback ;
/** @suppress {duplicate } */
function _glFenceSync ( condition , flags ) {
var sync = GLctx . fenceSync ( condition , flags ) ;
if ( sync ) {
var id = GL . getNewId ( GL . syncs ) ;
sync . name = id ;
GL . syncs [ id ] = sync ;
return id ;
}
return 0 ; // Failed to create a sync object
}
var _emscripten _glFenceSync = _glFenceSync ;
/** @suppress {duplicate } */
function _glFinish ( ) { GLctx . finish ( ) }
var _emscripten _glFinish = _glFinish ;
/** @suppress {duplicate } */
function _glFlush ( ) { GLctx . flush ( ) }
var _emscripten _glFlush = _glFlush ;
/** @suppress {duplicate } */
function _glFramebufferRenderbuffer ( target , attachment , renderbuffertarget , renderbuffer ) {
GLctx . framebufferRenderbuffer ( target , attachment , renderbuffertarget ,
GL . renderbuffers [ renderbuffer ] ) ;
}
var _emscripten _glFramebufferRenderbuffer = _glFramebufferRenderbuffer ;
/** @suppress {duplicate } */
function _glFramebufferTexture2D ( target , attachment , textarget , texture , level ) {
GLctx . framebufferTexture2D ( target , attachment , textarget ,
GL . textures [ texture ] , level ) ;
}
var _emscripten _glFramebufferTexture2D = _glFramebufferTexture2D ;
/** @suppress {duplicate } */
function _glFramebufferTextureLayer ( target , attachment , texture , level , layer ) {
GLctx . framebufferTextureLayer ( target , attachment , GL . textures [ texture ] , level , layer ) ;
}
var _emscripten _glFramebufferTextureLayer = _glFramebufferTextureLayer ;
/** @suppress {duplicate } */
function _glFrontFace ( x0 ) { GLctx . frontFace ( x0 ) }
var _emscripten _glFrontFace = _glFrontFace ;
function _ _glGenObject ( n , buffers , createFunction , objectTable
) {
for ( var i = 0 ; i < n ; i ++ ) {
var buffer = GLctx [ createFunction ] ( ) ;
var id = buffer && GL . getNewId ( objectTable ) ;
if ( buffer ) {
buffer . name = id ;
objectTable [ id ] = buffer ;
} else {
GL . recordError ( 0x502 /* GL_INVALID_OPERATION */ ) ;
}
HEAP32 [ ( ( ( buffers ) + ( i * 4 ) ) >> 2 ) ] = id ;
}
}
/** @suppress {duplicate } */
function _glGenBuffers ( n , buffers ) {
_ _glGenObject ( n , buffers , 'createBuffer' , GL . buffers
) ;
}
var _emscripten _glGenBuffers = _glGenBuffers ;
/** @suppress {duplicate } */
function _glGenFramebuffers ( n , ids ) {
_ _glGenObject ( n , ids , 'createFramebuffer' , GL . framebuffers
) ;
}
var _emscripten _glGenFramebuffers = _glGenFramebuffers ;
/** @suppress {duplicate } */
function _glGenQueries ( n , ids ) {
_ _glGenObject ( n , ids , 'createQuery' , GL . queries
) ;
}
var _emscripten _glGenQueries = _glGenQueries ;
/** @suppress {duplicate } */
function _glGenQueriesEXT ( n , ids ) {
for ( var i = 0 ; i < n ; i ++ ) {
var query = GLctx . disjointTimerQueryExt [ 'createQueryEXT' ] ( ) ;
if ( ! query ) {
GL . recordError ( 0x502 /* GL_INVALID_OPERATION */ ) ;
while ( i < n ) HEAP32 [ ( ( ( ids ) + ( i ++ * 4 ) ) >> 2 ) ] = 0 ;
return ;
}
var id = GL . getNewId ( GL . queries ) ;
query . name = id ;
GL . queries [ id ] = query ;
HEAP32 [ ( ( ( ids ) + ( i * 4 ) ) >> 2 ) ] = id ;
}
}
var _emscripten _glGenQueriesEXT = _glGenQueriesEXT ;
/** @suppress {duplicate } */
function _glGenRenderbuffers ( n , renderbuffers ) {
_ _glGenObject ( n , renderbuffers , 'createRenderbuffer' , GL . renderbuffers
) ;
}
var _emscripten _glGenRenderbuffers = _glGenRenderbuffers ;
/** @suppress {duplicate } */
function _glGenSamplers ( n , samplers ) {
_ _glGenObject ( n , samplers , 'createSampler' , GL . samplers
) ;
}
var _emscripten _glGenSamplers = _glGenSamplers ;
/** @suppress {duplicate } */
function _glGenTextures ( n , textures ) {
_ _glGenObject ( n , textures , 'createTexture' , GL . textures
) ;
}
var _emscripten _glGenTextures = _glGenTextures ;
/** @suppress {duplicate } */
function _glGenTransformFeedbacks ( n , ids ) {
_ _glGenObject ( n , ids , 'createTransformFeedback' , GL . transformFeedbacks
) ;
}
var _emscripten _glGenTransformFeedbacks = _glGenTransformFeedbacks ;
/** @suppress {duplicate } */
function _glGenVertexArrays ( n , arrays ) {
_ _glGenObject ( n , arrays , 'createVertexArray' , GL . vaos
) ;
}
var _emscripten _glGenVertexArrays = _glGenVertexArrays ;
/** @suppress {duplicate } */
var _glGenVertexArraysOES = _glGenVertexArrays ;
var _emscripten _glGenVertexArraysOES = _glGenVertexArraysOES ;
/** @suppress {duplicate } */
function _glGenerateMipmap ( x0 ) { GLctx . generateMipmap ( x0 ) }
var _emscripten _glGenerateMipmap = _glGenerateMipmap ;
function _ _glGetActiveAttribOrUniform ( funcName , program , index , bufSize , length , size , type , name ) {
program = GL . programs [ program ] ;
var info = GLctx [ funcName ] ( program , index ) ;
if ( info ) { // If an error occurs, nothing will be written to length, size and type and name.
var numBytesWrittenExclNull = name && stringToUTF8 ( info . name , name , bufSize ) ;
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = numBytesWrittenExclNull ;
if ( size ) HEAP32 [ ( ( size ) >> 2 ) ] = info . size ;
if ( type ) HEAP32 [ ( ( type ) >> 2 ) ] = info . type ;
}
}
/** @suppress {duplicate } */
function _glGetActiveAttrib ( program , index , bufSize , length , size , type , name ) {
_ _glGetActiveAttribOrUniform ( 'getActiveAttrib' , program , index , bufSize , length , size , type , name ) ;
}
var _emscripten _glGetActiveAttrib = _glGetActiveAttrib ;
/** @suppress {duplicate } */
function _glGetActiveUniform ( program , index , bufSize , length , size , type , name ) {
_ _glGetActiveAttribOrUniform ( 'getActiveUniform' , program , index , bufSize , length , size , type , name ) ;
}
var _emscripten _glGetActiveUniform = _glGetActiveUniform ;
/** @suppress {duplicate } */
function _glGetActiveUniformBlockName ( program , uniformBlockIndex , bufSize , length , uniformBlockName ) {
program = GL . programs [ program ] ;
var result = GLctx . getActiveUniformBlockName ( program , uniformBlockIndex ) ;
if ( ! result ) return ; // If an error occurs, nothing will be written to uniformBlockName or length.
if ( uniformBlockName && bufSize > 0 ) {
var numBytesWrittenExclNull = stringToUTF8 ( result , uniformBlockName , bufSize ) ;
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = numBytesWrittenExclNull ;
} else {
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = 0 ;
}
}
var _emscripten _glGetActiveUniformBlockName = _glGetActiveUniformBlockName ;
/** @suppress {duplicate } */
function _glGetActiveUniformBlockiv ( program , uniformBlockIndex , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if params == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
program = GL . programs [ program ] ;
if ( pname == 0x8A41 /* GL_UNIFORM_BLOCK_NAME_LENGTH */ ) {
var name = GLctx . getActiveUniformBlockName ( program , uniformBlockIndex ) ;
HEAP32 [ ( ( params ) >> 2 ) ] = name . length + 1 ;
return ;
}
var result = GLctx . getActiveUniformBlockParameter ( program , uniformBlockIndex , pname ) ;
if ( result === null ) return ; // If an error occurs, nothing should be written to params.
if ( pname == 0x8A43 /*GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES*/ ) {
for ( var i = 0 ; i < result . length ; i ++ ) {
HEAP32 [ ( ( ( params ) + ( i * 4 ) ) >> 2 ) ] = result [ i ] ;
}
} else {
HEAP32 [ ( ( params ) >> 2 ) ] = result ;
}
}
var _emscripten _glGetActiveUniformBlockiv = _glGetActiveUniformBlockiv ;
/** @suppress {duplicate } */
function _glGetActiveUniformsiv ( program , uniformCount , uniformIndices , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if params == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
if ( uniformCount > 0 && uniformIndices == 0 ) {
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
program = GL . programs [ program ] ;
var ids = [ ] ;
for ( var i = 0 ; i < uniformCount ; i ++ ) {
ids . push ( HEAP32 [ ( ( ( uniformIndices ) + ( i * 4 ) ) >> 2 ) ] ) ;
}
var result = GLctx . getActiveUniforms ( program , ids , pname ) ;
if ( ! result ) return ; // GL spec: If an error is generated, nothing is written out to params.
var len = result . length ;
for ( var i = 0 ; i < len ; i ++ ) {
HEAP32 [ ( ( ( params ) + ( i * 4 ) ) >> 2 ) ] = result [ i ] ;
}
}
var _emscripten _glGetActiveUniformsiv = _glGetActiveUniformsiv ;
/** @suppress {duplicate } */
function _glGetAttachedShaders ( program , maxCount , count , shaders ) {
var result = GLctx . getAttachedShaders ( GL . programs [ program ] ) ;
var len = result . length ;
if ( len > maxCount ) {
len = maxCount ;
}
HEAP32 [ ( ( count ) >> 2 ) ] = len ;
for ( var i = 0 ; i < len ; ++ i ) {
var id = GL . shaders . indexOf ( result [ i ] ) ;
HEAP32 [ ( ( ( shaders ) + ( i * 4 ) ) >> 2 ) ] = id ;
}
}
var _emscripten _glGetAttachedShaders = _glGetAttachedShaders ;
/** @suppress {duplicate } */
function _glGetAttribLocation ( program , name ) {
return GLctx . getAttribLocation ( GL . programs [ program ] , UTF8ToString ( name ) ) ;
}
var _emscripten _glGetAttribLocation = _glGetAttribLocation ;
function readI53FromI64 ( ptr ) {
return HEAPU32 [ ptr >> 2 ] + HEAP32 [ ptr + 4 >> 2 ] * 4294967296 ;
}
function readI53FromU64 ( ptr ) {
return HEAPU32 [ ptr >> 2 ] + HEAPU32 [ ptr + 4 >> 2 ] * 4294967296 ;
}
function writeI53ToI64 ( ptr , num ) {
HEAPU32 [ ptr >> 2 ] = num ;
HEAPU32 [ ptr + 4 >> 2 ] = ( num - HEAPU32 [ ptr >> 2 ] ) / 4294967296 ;
var deserialized = ( num >= 0 ) ? readI53FromU64 ( ptr ) : readI53FromI64 ( ptr ) ;
if ( deserialized != num ) warnOnce ( 'writeI53ToI64() out of range: serialized JS Number ' + num + ' to Wasm heap as bytes lo=' + ptrToString ( HEAPU32 [ ptr >> 2 ] ) + ', hi=' + ptrToString ( HEAPU32 [ ptr + 4 >> 2 ] ) + ', which deserializes back to ' + deserialized + ' instead!' ) ;
}
function emscriptenWebGLGet ( name _ , p , type ) {
// Guard against user passing a null pointer.
// Note that GLES2 spec does not say anything about how passing a null pointer should be treated.
// Testing on desktop core GL 3, the application crashes on glGetIntegerv to a null pointer, but
// better to report an error instead of doing anything random.
if ( ! p ) {
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
var ret = undefined ;
switch ( name _ ) { // Handle a few trivial GLES values
case 0x8DFA : // GL_SHADER_COMPILER
ret = 1 ;
break ;
case 0x8DF8 : // GL_SHADER_BINARY_FORMATS
if ( type != 0 && type != 1 ) {
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
}
return ; // Do not write anything to the out pointer, since no binary formats are supported.
case 0x87FE : // GL_NUM_PROGRAM_BINARY_FORMATS
case 0x8DF9 : // GL_NUM_SHADER_BINARY_FORMATS
ret = 0 ;
break ;
case 0x86A2 : // GL_NUM_COMPRESSED_TEXTURE_FORMATS
// WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be queried for length),
// so implement it ourselves to allow C++ GLES2 code get the length.
var formats = GLctx . getParameter ( 0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/ ) ;
ret = formats ? formats . length : 0 ;
break ;
case 0x821D : // GL_NUM_EXTENSIONS
if ( GL . currentContext . version < 2 ) {
GL . recordError ( 0x502 /* GL_INVALID_OPERATION */ ) ; // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context
return ;
}
// .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
var exts = GLctx . getSupportedExtensions ( ) || [ ] ;
ret = 2 * exts . length ; // each extension is duplicated, first in unprefixed WebGL form, and then a second time with "GL_" prefix.
break ;
case 0x821B : // GL_MAJOR_VERSION
case 0x821C : // GL_MINOR_VERSION
if ( GL . currentContext . version < 2 ) {
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
return ;
}
ret = name _ == 0x821B ? 3 : 0 ; // return version 3.0
break ;
}
if ( ret === undefined ) {
var result = GLctx . getParameter ( name _ ) ;
switch ( typeof result ) {
case "number" :
ret = result ;
break ;
case "boolean" :
ret = result ? 1 : 0 ;
break ;
case "string" :
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
return ;
case "object" :
if ( result === null ) {
// null is a valid result for some (e.g., which buffer is bound - perhaps nothing is bound), but otherwise
// can mean an invalid name_, which we need to report as an error
switch ( name _ ) {
case 0x8894 : // ARRAY_BUFFER_BINDING
case 0x8B8D : // CURRENT_PROGRAM
case 0x8895 : // ELEMENT_ARRAY_BUFFER_BINDING
case 0x8CA6 : // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING
case 0x8CA7 : // RENDERBUFFER_BINDING
case 0x8069 : // TEXTURE_BINDING_2D
case 0x85B5 : // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES
case 0x8F36 : // COPY_READ_BUFFER_BINDING or COPY_READ_BUFFER
case 0x8F37 : // COPY_WRITE_BUFFER_BINDING or COPY_WRITE_BUFFER
case 0x88ED : // PIXEL_PACK_BUFFER_BINDING
case 0x88EF : // PIXEL_UNPACK_BUFFER_BINDING
case 0x8CAA : // READ_FRAMEBUFFER_BINDING
case 0x8919 : // SAMPLER_BINDING
case 0x8C1D : // TEXTURE_BINDING_2D_ARRAY
case 0x806A : // TEXTURE_BINDING_3D
case 0x8E25 : // TRANSFORM_FEEDBACK_BINDING
case 0x8C8F : // TRANSFORM_FEEDBACK_BUFFER_BINDING
case 0x8A28 : // UNIFORM_BUFFER_BINDING
case 0x8514 : { // TEXTURE_BINDING_CUBE_MAP
ret = 0 ;
break ;
}
default : {
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
return ;
}
}
} else if ( result instanceof Float32Array ||
result instanceof Uint32Array ||
result instanceof Int32Array ||
result instanceof Array ) {
for ( var i = 0 ; i < result . length ; ++ i ) {
switch ( type ) {
case 0 : HEAP32 [ ( ( ( p ) + ( i * 4 ) ) >> 2 ) ] = result [ i ] ; break ;
case 2 : HEAPF32 [ ( ( ( p ) + ( i * 4 ) ) >> 2 ) ] = result [ i ] ; break ;
case 4 : HEAP8 [ ( ( ( p ) + ( i ) ) >> 0 ) ] = result [ i ] ? 1 : 0 ; break ;
}
}
return ;
} else {
try {
ret = result . name | 0 ;
} catch ( e ) {
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
err ( 'GL_INVALID_ENUM in glGet' + type + 'v: Unknown object returned from WebGL getParameter(' + name _ + ')! (error: ' + e + ')' ) ;
return ;
}
}
break ;
default :
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
err ( 'GL_INVALID_ENUM in glGet' + type + 'v: Native code calling glGet' + type + 'v(' + name _ + ') and it returns ' + result + ' of type ' + typeof ( result ) + '!' ) ;
return ;
}
}
switch ( type ) {
case 1 : writeI53ToI64 ( p , ret ) ; break ;
case 0 : HEAP32 [ ( ( p ) >> 2 ) ] = ret ; break ;
case 2 : HEAPF32 [ ( ( p ) >> 2 ) ] = ret ; break ;
case 4 : HEAP8 [ ( ( p ) >> 0 ) ] = ret ? 1 : 0 ; break ;
}
}
/** @suppress {duplicate } */
function _glGetBooleanv ( name _ , p ) {
emscriptenWebGLGet ( name _ , p , 4 ) ;
}
var _emscripten _glGetBooleanv = _glGetBooleanv ;
/** @suppress {duplicate } */
function _glGetBufferParameteri64v ( target , value , data ) {
if ( ! data ) {
// GLES2 specification does not specify how to behave if data is a null pointer. Since calling this function does not make sense
// if data == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
writeI53ToI64 ( data , GLctx . getBufferParameter ( target , value ) ) ;
}
var _emscripten _glGetBufferParameteri64v = _glGetBufferParameteri64v ;
/** @suppress {duplicate } */
function _glGetBufferParameteriv ( target , value , data ) {
if ( ! data ) {
// GLES2 specification does not specify how to behave if data is a null pointer. Since calling this function does not make sense
// if data == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAP32 [ ( ( data ) >> 2 ) ] = GLctx . getBufferParameter ( target , value ) ;
}
var _emscripten _glGetBufferParameteriv = _glGetBufferParameteriv ;
/** @suppress {duplicate } */
function _glGetError ( ) {
var error = GLctx . getError ( ) || GL . lastError ;
GL . lastError = 0 /*GL_NO_ERROR*/ ;
return error ;
}
var _emscripten _glGetError = _glGetError ;
/** @suppress {duplicate } */
function _glGetFloatv ( name _ , p ) {
emscriptenWebGLGet ( name _ , p , 2 ) ;
}
var _emscripten _glGetFloatv = _glGetFloatv ;
/** @suppress {duplicate } */
function _glGetFragDataLocation ( program , name ) {
return GLctx . getFragDataLocation ( GL . programs [ program ] , UTF8ToString ( name ) ) ;
}
var _emscripten _glGetFragDataLocation = _glGetFragDataLocation ;
/** @suppress {duplicate } */
function _glGetFramebufferAttachmentParameteriv ( target , attachment , pname , params ) {
var result = GLctx . getFramebufferAttachmentParameter ( target , attachment , pname ) ;
if ( result instanceof WebGLRenderbuffer ||
result instanceof WebGLTexture ) {
result = result . name | 0 ;
}
HEAP32 [ ( ( params ) >> 2 ) ] = result ;
}
var _emscripten _glGetFramebufferAttachmentParameteriv = _glGetFramebufferAttachmentParameteriv ;
function emscriptenWebGLGetIndexed ( target , index , data , type ) {
if ( ! data ) {
// GLES2 specification does not specify how to behave if data is a null pointer. Since calling this function does not make sense
// if data == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
var result = GLctx . getIndexedParameter ( target , index ) ;
var ret ;
switch ( typeof result ) {
case 'boolean' :
ret = result ? 1 : 0 ;
break ;
case 'number' :
ret = result ;
break ;
case 'object' :
if ( result === null ) {
switch ( target ) {
case 0x8C8F : // TRANSFORM_FEEDBACK_BUFFER_BINDING
case 0x8A28 : // UNIFORM_BUFFER_BINDING
ret = 0 ;
break ;
default : {
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
return ;
}
}
} else if ( result instanceof WebGLBuffer ) {
ret = result . name | 0 ;
} else {
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
return ;
}
break ;
default :
GL . recordError ( 0x500 ) ; // GL_INVALID_ENUM
return ;
}
switch ( type ) {
case 1 : writeI53ToI64 ( data , ret ) ; break ;
case 0 : HEAP32 [ ( ( data ) >> 2 ) ] = ret ; break ;
case 2 : HEAPF32 [ ( ( data ) >> 2 ) ] = ret ; break ;
case 4 : HEAP8 [ ( ( data ) >> 0 ) ] = ret ? 1 : 0 ; break ;
default : throw 'internal emscriptenWebGLGetIndexed() error, bad type: ' + type ;
}
}
/** @suppress {duplicate } */
function _glGetInteger64i _v ( target , index , data ) {
emscriptenWebGLGetIndexed ( target , index , data , 1 ) ;
}
var _emscripten _glGetInteger64i _v = _glGetInteger64i _v ;
/** @suppress {duplicate } */
function _glGetInteger64v ( name _ , p ) {
emscriptenWebGLGet ( name _ , p , 1 ) ;
}
var _emscripten _glGetInteger64v = _glGetInteger64v ;
/** @suppress {duplicate } */
function _glGetIntegeri _v ( target , index , data ) {
emscriptenWebGLGetIndexed ( target , index , data , 0 ) ;
}
var _emscripten _glGetIntegeri _v = _glGetIntegeri _v ;
/** @suppress {duplicate } */
function _glGetIntegerv ( name _ , p ) {
emscriptenWebGLGet ( name _ , p , 0 ) ;
}
var _emscripten _glGetIntegerv = _glGetIntegerv ;
/** @suppress {duplicate } */
function _glGetInternalformativ ( target , internalformat , pname , bufSize , params ) {
if ( bufSize < 0 ) {
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
if ( ! params ) {
// GLES3 specification does not specify how to behave if values is a null pointer. Since calling this function does not make sense
// if values == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
var ret = GLctx . getInternalformatParameter ( target , internalformat , pname ) ;
if ( ret === null ) return ;
for ( var i = 0 ; i < ret . length && i < bufSize ; ++ i ) {
HEAP32 [ ( ( ( params ) + ( i * 4 ) ) >> 2 ) ] = ret [ i ] ;
}
}
var _emscripten _glGetInternalformativ = _glGetInternalformativ ;
/** @suppress {duplicate } */
function _glGetProgramBinary ( program , bufSize , length , binaryFormat , binary ) {
GL . recordError ( 0x502 /*GL_INVALID_OPERATION*/ ) ;
}
var _emscripten _glGetProgramBinary = _glGetProgramBinary ;
/** @suppress {duplicate } */
function _glGetProgramInfoLog ( program , maxLength , length , infoLog ) {
var log = GLctx . getProgramInfoLog ( GL . programs [ program ] ) ;
if ( log === null ) log = '(unknown error)' ;
var numBytesWrittenExclNull = ( maxLength > 0 && infoLog ) ? stringToUTF8 ( log , infoLog , maxLength ) : 0 ;
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = numBytesWrittenExclNull ;
}
var _emscripten _glGetProgramInfoLog = _glGetProgramInfoLog ;
/** @suppress {duplicate } */
function _glGetProgramiv ( program , pname , p ) {
if ( ! p ) {
// GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
if ( program >= GL . counter ) {
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
program = GL . programs [ program ] ;
if ( pname == 0x8B84 ) { // GL_INFO_LOG_LENGTH
var log = GLctx . getProgramInfoLog ( program ) ;
if ( log === null ) log = '(unknown error)' ;
HEAP32 [ ( ( p ) >> 2 ) ] = log . length + 1 ;
} else if ( pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */ ) {
if ( ! program . maxUniformLength ) {
for ( var i = 0 ; i < GLctx . getProgramParameter ( program , 0x8B86 /*GL_ACTIVE_UNIFORMS*/ ) ; ++ i ) {
program . maxUniformLength = Math . max ( program . maxUniformLength , GLctx . getActiveUniform ( program , i ) . name . length + 1 ) ;
}
}
HEAP32 [ ( ( p ) >> 2 ) ] = program . maxUniformLength ;
} else if ( pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */ ) {
if ( ! program . maxAttributeLength ) {
for ( var i = 0 ; i < GLctx . getProgramParameter ( program , 0x8B89 /*GL_ACTIVE_ATTRIBUTES*/ ) ; ++ i ) {
program . maxAttributeLength = Math . max ( program . maxAttributeLength , GLctx . getActiveAttrib ( program , i ) . name . length + 1 ) ;
}
}
HEAP32 [ ( ( p ) >> 2 ) ] = program . maxAttributeLength ;
} else if ( pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */ ) {
if ( ! program . maxUniformBlockNameLength ) {
for ( var i = 0 ; i < GLctx . getProgramParameter ( program , 0x8A36 /*GL_ACTIVE_UNIFORM_BLOCKS*/ ) ; ++ i ) {
program . maxUniformBlockNameLength = Math . max ( program . maxUniformBlockNameLength , GLctx . getActiveUniformBlockName ( program , i ) . length + 1 ) ;
}
}
HEAP32 [ ( ( p ) >> 2 ) ] = program . maxUniformBlockNameLength ;
} else {
HEAP32 [ ( ( p ) >> 2 ) ] = GLctx . getProgramParameter ( program , pname ) ;
}
}
var _emscripten _glGetProgramiv = _glGetProgramiv ;
/** @suppress {duplicate } */
function _glGetQueryObjecti64vEXT ( id , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
var query = GL . queries [ id ] ;
var param ;
if ( GL . currentContext . version < 2 )
{
param = GLctx . disjointTimerQueryExt [ 'getQueryObjectEXT' ] ( query , pname ) ;
}
else {
param = GLctx . getQueryParameter ( query , pname ) ;
}
var ret ;
if ( typeof param == 'boolean' ) {
ret = param ? 1 : 0 ;
} else {
ret = param ;
}
writeI53ToI64 ( params , ret ) ;
}
var _emscripten _glGetQueryObjecti64vEXT = _glGetQueryObjecti64vEXT ;
/** @suppress {duplicate } */
function _glGetQueryObjectivEXT ( id , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
var query = GL . queries [ id ] ;
var param = GLctx . disjointTimerQueryExt [ 'getQueryObjectEXT' ] ( query , pname ) ;
var ret ;
if ( typeof param == 'boolean' ) {
ret = param ? 1 : 0 ;
} else {
ret = param ;
}
HEAP32 [ ( ( params ) >> 2 ) ] = ret ;
}
var _emscripten _glGetQueryObjectivEXT = _glGetQueryObjectivEXT ;
/** @suppress {duplicate } */
var _glGetQueryObjectui64vEXT = _glGetQueryObjecti64vEXT ;
var _emscripten _glGetQueryObjectui64vEXT = _glGetQueryObjectui64vEXT ;
/** @suppress {duplicate } */
function _glGetQueryObjectuiv ( id , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
var query = GL . queries [ id ] ;
var param = GLctx . getQueryParameter ( query , pname ) ;
var ret ;
if ( typeof param == 'boolean' ) {
ret = param ? 1 : 0 ;
} else {
ret = param ;
}
HEAP32 [ ( ( params ) >> 2 ) ] = ret ;
}
var _emscripten _glGetQueryObjectuiv = _glGetQueryObjectuiv ;
/** @suppress {duplicate } */
var _glGetQueryObjectuivEXT = _glGetQueryObjectivEXT ;
var _emscripten _glGetQueryObjectuivEXT = _glGetQueryObjectuivEXT ;
/** @suppress {duplicate } */
function _glGetQueryiv ( target , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAP32 [ ( ( params ) >> 2 ) ] = GLctx . getQuery ( target , pname ) ;
}
var _emscripten _glGetQueryiv = _glGetQueryiv ;
/** @suppress {duplicate } */
function _glGetQueryivEXT ( target , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAP32 [ ( ( params ) >> 2 ) ] = GLctx . disjointTimerQueryExt [ 'getQueryEXT' ] ( target , pname ) ;
}
var _emscripten _glGetQueryivEXT = _glGetQueryivEXT ;
/** @suppress {duplicate } */
function _glGetRenderbufferParameteriv ( target , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if params == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAP32 [ ( ( params ) >> 2 ) ] = GLctx . getRenderbufferParameter ( target , pname ) ;
}
var _emscripten _glGetRenderbufferParameteriv = _glGetRenderbufferParameteriv ;
/** @suppress {duplicate } */
function _glGetSamplerParameterfv ( sampler , pname , params ) {
if ( ! params ) {
// GLES3 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAPF32 [ ( ( params ) >> 2 ) ] = GLctx . getSamplerParameter ( GL . samplers [ sampler ] , pname ) ;
}
var _emscripten _glGetSamplerParameterfv = _glGetSamplerParameterfv ;
/** @suppress {duplicate } */
function _glGetSamplerParameteriv ( sampler , pname , params ) {
if ( ! params ) {
// GLES3 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAP32 [ ( ( params ) >> 2 ) ] = GLctx . getSamplerParameter ( GL . samplers [ sampler ] , pname ) ;
}
var _emscripten _glGetSamplerParameteriv = _glGetSamplerParameteriv ;
/** @suppress {duplicate } */
function _glGetShaderInfoLog ( shader , maxLength , length , infoLog ) {
var log = GLctx . getShaderInfoLog ( GL . shaders [ shader ] ) ;
if ( log === null ) log = '(unknown error)' ;
var numBytesWrittenExclNull = ( maxLength > 0 && infoLog ) ? stringToUTF8 ( log , infoLog , maxLength ) : 0 ;
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = numBytesWrittenExclNull ;
}
var _emscripten _glGetShaderInfoLog = _glGetShaderInfoLog ;
/** @suppress {duplicate } */
function _glGetShaderPrecisionFormat ( shaderType , precisionType , range , precision ) {
var result = GLctx . getShaderPrecisionFormat ( shaderType , precisionType ) ;
HEAP32 [ ( ( range ) >> 2 ) ] = result . rangeMin ;
HEAP32 [ ( ( ( range ) + ( 4 ) ) >> 2 ) ] = result . rangeMax ;
HEAP32 [ ( ( precision ) >> 2 ) ] = result . precision ;
}
var _emscripten _glGetShaderPrecisionFormat = _glGetShaderPrecisionFormat ;
/** @suppress {duplicate } */
function _glGetShaderSource ( shader , bufSize , length , source ) {
var result = GLctx . getShaderSource ( GL . shaders [ shader ] ) ;
if ( ! result ) return ; // If an error occurs, nothing will be written to length or source.
var numBytesWrittenExclNull = ( bufSize > 0 && source ) ? stringToUTF8 ( result , source , bufSize ) : 0 ;
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = numBytesWrittenExclNull ;
}
var _emscripten _glGetShaderSource = _glGetShaderSource ;
/** @suppress {duplicate } */
function _glGetShaderiv ( shader , pname , p ) {
if ( ! p ) {
// GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
if ( pname == 0x8B84 ) { // GL_INFO_LOG_LENGTH
var log = GLctx . getShaderInfoLog ( GL . shaders [ shader ] ) ;
if ( log === null ) log = '(unknown error)' ;
// The GLES2 specification says that if the shader has an empty info log,
// a value of 0 is returned. Otherwise the log has a null char appended.
// (An empty string is falsey, so we can just check that instead of
// looking at log.length.)
var logLength = log ? log . length + 1 : 0 ;
HEAP32 [ ( ( p ) >> 2 ) ] = logLength ;
} else if ( pname == 0x8B88 ) { // GL_SHADER_SOURCE_LENGTH
var source = GLctx . getShaderSource ( GL . shaders [ shader ] ) ;
// source may be a null, or the empty string, both of which are falsey
// values that we report a 0 length for.
var sourceLength = source ? source . length + 1 : 0 ;
HEAP32 [ ( ( p ) >> 2 ) ] = sourceLength ;
} else {
HEAP32 [ ( ( p ) >> 2 ) ] = GLctx . getShaderParameter ( GL . shaders [ shader ] , pname ) ;
}
}
var _emscripten _glGetShaderiv = _glGetShaderiv ;
/** @suppress {duplicate } */
function _glGetString ( name _ ) {
var ret = GL . stringCache [ name _ ] ;
if ( ! ret ) {
switch ( name _ ) {
case 0x1F03 /* GL_EXTENSIONS */ :
var exts = GLctx . getSupportedExtensions ( ) || [ ] ; // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
exts = exts . concat ( exts . map ( function ( e ) { return "GL_" + e ; } ) ) ;
ret = stringToNewUTF8 ( exts . join ( ' ' ) ) ;
break ;
case 0x1F00 /* GL_VENDOR */ :
case 0x1F01 /* GL_RENDERER */ :
case 0x9245 /* UNMASKED_VENDOR_WEBGL */ :
case 0x9246 /* UNMASKED_RENDERER_WEBGL */ :
var s = GLctx . getParameter ( name _ ) ;
if ( ! s ) {
GL . recordError ( 0x500 /*GL_INVALID_ENUM*/ ) ;
}
ret = s && stringToNewUTF8 ( s ) ;
break ;
case 0x1F02 /* GL_VERSION */ :
var glVersion = GLctx . getParameter ( 0x1F02 /*GL_VERSION*/ ) ;
// return GLES version string corresponding to the version of the WebGL context
if ( true ) glVersion = 'OpenGL ES 3.0 (' + glVersion + ')' ;
else
{
glVersion = 'OpenGL ES 2.0 (' + glVersion + ')' ;
}
ret = stringToNewUTF8 ( glVersion ) ;
break ;
case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */ :
var glslVersion = GLctx . getParameter ( 0x8B8C /*GL_SHADING_LANGUAGE_VERSION*/ ) ;
// extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...'
var ver _re = /^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/ ;
var ver _num = glslVersion . match ( ver _re ) ;
if ( ver _num !== null ) {
if ( ver _num [ 1 ] . length == 3 ) ver _num [ 1 ] = ver _num [ 1 ] + '0' ; // ensure minor version has 2 digits
glslVersion = 'OpenGL ES GLSL ES ' + ver _num [ 1 ] + ' (' + glslVersion + ')' ;
}
ret = stringToNewUTF8 ( glslVersion ) ;
break ;
default :
GL . recordError ( 0x500 /*GL_INVALID_ENUM*/ ) ;
// fall through
}
GL . stringCache [ name _ ] = ret ;
}
return ret ;
}
var _emscripten _glGetString = _glGetString ;
/** @suppress {duplicate } */
function _glGetStringi ( name , index ) {
if ( GL . currentContext . version < 2 ) {
GL . recordError ( 0x502 /* GL_INVALID_OPERATION */ ) ; // Calling GLES3/WebGL2 function with a GLES2/WebGL1 context
return 0 ;
}
var stringiCache = GL . stringiCache [ name ] ;
if ( stringiCache ) {
if ( index < 0 || index >= stringiCache . length ) {
GL . recordError ( 0x501 /*GL_INVALID_VALUE*/ ) ;
return 0 ;
}
return stringiCache [ index ] ;
}
switch ( name ) {
case 0x1F03 /* GL_EXTENSIONS */ :
var exts = GLctx . getSupportedExtensions ( ) || [ ] ; // .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
exts = exts . concat ( exts . map ( function ( e ) { return "GL_" + e ; } ) ) ;
exts = exts . map ( function ( e ) { return stringToNewUTF8 ( e ) ; } ) ;
stringiCache = GL . stringiCache [ name ] = exts ;
if ( index < 0 || index >= stringiCache . length ) {
GL . recordError ( 0x501 /*GL_INVALID_VALUE*/ ) ;
return 0 ;
}
return stringiCache [ index ] ;
default :
GL . recordError ( 0x500 /*GL_INVALID_ENUM*/ ) ;
return 0 ;
}
}
var _emscripten _glGetStringi = _glGetStringi ;
/** @suppress {duplicate } */
function _glGetSynciv ( sync , pname , bufSize , length , values ) {
if ( bufSize < 0 ) {
// GLES3 specification does not specify how to behave if bufSize < 0, however in the spec wording for glGetInternalformativ, it does say that GL_INVALID_VALUE should be raised,
// so raise GL_INVALID_VALUE here as well.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
if ( ! values ) {
// GLES3 specification does not specify how to behave if values is a null pointer. Since calling this function does not make sense
// if values == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
var ret = GLctx . getSyncParameter ( GL . syncs [ sync ] , pname ) ;
if ( ret !== null ) {
HEAP32 [ ( ( values ) >> 2 ) ] = ret ;
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = 1 ; // Report a single value outputted.
}
}
var _emscripten _glGetSynciv = _glGetSynciv ;
/** @suppress {duplicate } */
function _glGetTexParameterfv ( target , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAPF32 [ ( ( params ) >> 2 ) ] = GLctx . getTexParameter ( target , pname ) ;
}
var _emscripten _glGetTexParameterfv = _glGetTexParameterfv ;
/** @suppress {duplicate } */
function _glGetTexParameteriv ( target , pname , params ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if p == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAP32 [ ( ( params ) >> 2 ) ] = GLctx . getTexParameter ( target , pname ) ;
}
var _emscripten _glGetTexParameteriv = _glGetTexParameteriv ;
/** @suppress {duplicate } */
function _glGetTransformFeedbackVarying ( program , index , bufSize , length , size , type , name ) {
program = GL . programs [ program ] ;
var info = GLctx . getTransformFeedbackVarying ( program , index ) ;
if ( ! info ) return ; // If an error occurred, the return parameters length, size, type and name will be unmodified.
if ( name && bufSize > 0 ) {
var numBytesWrittenExclNull = stringToUTF8 ( info . name , name , bufSize ) ;
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = numBytesWrittenExclNull ;
} else {
if ( length ) HEAP32 [ ( ( length ) >> 2 ) ] = 0 ;
}
if ( size ) HEAP32 [ ( ( size ) >> 2 ) ] = info . size ;
if ( type ) HEAP32 [ ( ( type ) >> 2 ) ] = info . type ;
}
var _emscripten _glGetTransformFeedbackVarying = _glGetTransformFeedbackVarying ;
/** @suppress {duplicate } */
function _glGetUniformBlockIndex ( program , uniformBlockName ) {
return GLctx . getUniformBlockIndex ( GL . programs [ program ] , UTF8ToString ( uniformBlockName ) ) ;
}
var _emscripten _glGetUniformBlockIndex = _glGetUniformBlockIndex ;
/** @suppress {duplicate } */
function _glGetUniformIndices ( program , uniformCount , uniformNames , uniformIndices ) {
if ( ! uniformIndices ) {
// GLES2 specification does not specify how to behave if uniformIndices is a null pointer. Since calling this function does not make sense
// if uniformIndices == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
if ( uniformCount > 0 && ( uniformNames == 0 || uniformIndices == 0 ) ) {
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
program = GL . programs [ program ] ;
var names = [ ] ;
for ( var i = 0 ; i < uniformCount ; i ++ )
names . push ( UTF8ToString ( HEAP32 [ ( ( ( uniformNames ) + ( i * 4 ) ) >> 2 ) ] ) ) ;
var result = GLctx . getUniformIndices ( program , names ) ;
if ( ! result ) return ; // GL spec: If an error is generated, nothing is written out to uniformIndices.
var len = result . length ;
for ( var i = 0 ; i < len ; i ++ ) {
HEAP32 [ ( ( ( uniformIndices ) + ( i * 4 ) ) >> 2 ) ] = result [ i ] ;
}
}
var _emscripten _glGetUniformIndices = _glGetUniformIndices ;
/** @suppress {checkTypes} */
function jstoi _q ( str ) {
return parseInt ( str ) ;
}
/** @noinline */
function webglGetLeftBracePos ( name ) {
return name . slice ( - 1 ) == ']' && name . lastIndexOf ( '[' ) ;
}
function webglPrepareUniformLocationsBeforeFirstUse ( program ) {
var uniformLocsById = program . uniformLocsById , // Maps GLuint -> WebGLUniformLocation
uniformSizeAndIdsByName = program . uniformSizeAndIdsByName , // Maps name -> [uniform array length, GLuint]
i , j ;
// On the first time invocation of glGetUniformLocation on this shader program:
// initialize cache data structures and discover which uniforms are arrays.
if ( ! uniformLocsById ) {
// maps GLint integer locations to WebGLUniformLocations
program . uniformLocsById = uniformLocsById = { } ;
// maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations
program . uniformArrayNamesById = { } ;
for ( i = 0 ; i < GLctx . getProgramParameter ( program , 0x8B86 /*GL_ACTIVE_UNIFORMS*/ ) ; ++ i ) {
var u = GLctx . getActiveUniform ( program , i ) ;
var nm = u . name ;
var sz = u . size ;
var lb = webglGetLeftBracePos ( nm ) ;
var arrayName = lb > 0 ? nm . slice ( 0 , lb ) : nm ;
// Assign a new location.
var id = program . uniformIdCounter ;
program . uniformIdCounter += sz ;
// Eagerly get the location of the uniformArray[0] base element.
// The remaining indices >0 will be left for lazy evaluation to
// improve performance. Those may never be needed to fetch, if the
// application fills arrays always in full starting from the first
// element of the array.
uniformSizeAndIdsByName [ arrayName ] = [ sz , id ] ;
// Store placeholder integers in place that highlight that these
// >0 index locations are array indices pending population.
for ( j = 0 ; j < sz ; ++ j ) {
uniformLocsById [ id ] = j ;
program . uniformArrayNamesById [ id ++ ] = arrayName ;
}
}
}
}
/** @suppress {duplicate } */
function _glGetUniformLocation ( program , name ) {
name = UTF8ToString ( name ) ;
if ( program = GL . programs [ program ] ) {
webglPrepareUniformLocationsBeforeFirstUse ( program ) ;
var uniformLocsById = program . uniformLocsById ; // Maps GLuint -> WebGLUniformLocation
var arrayIndex = 0 ;
var uniformBaseName = name ;
// Invariant: when populating integer IDs for uniform locations, we must maintain the precondition that
// arrays reside in contiguous addresses, i.e. for a 'vec4 colors[10];', colors[4] must be at location colors[0]+4.
// However, user might call glGetUniformLocation(program, "colors") for an array, so we cannot discover based on the user
// input arguments whether the uniform we are dealing with is an array. The only way to discover which uniforms are arrays
// is to enumerate over all the active uniforms in the program.
var leftBrace = webglGetLeftBracePos ( name ) ;
// If user passed an array accessor "[index]", parse the array index off the accessor.
if ( leftBrace > 0 ) {
arrayIndex = jstoi _q ( name . slice ( leftBrace + 1 ) ) >>> 0 ; // "index]", coerce parseInt(']') with >>>0 to treat "foo[]" as "foo[0]" and foo[-1] as unsigned out-of-bounds.
uniformBaseName = name . slice ( 0 , leftBrace ) ;
}
// Have we cached the location of this uniform before?
var sizeAndId = program . uniformSizeAndIdsByName [ uniformBaseName ] ; // A pair [array length, GLint of the uniform location]
// If an uniform with this name exists, and if its index is within the array limits (if it's even an array),
// query the WebGLlocation, or return an existing cached location.
if ( sizeAndId && arrayIndex < sizeAndId [ 0 ] ) {
arrayIndex += sizeAndId [ 1 ] ; // Add the base location of the uniform to the array index offset.
if ( ( uniformLocsById [ arrayIndex ] = uniformLocsById [ arrayIndex ] || GLctx . getUniformLocation ( program , name ) ) ) {
return arrayIndex ;
}
}
}
else {
// N.b. we are currently unable to distinguish between GL program IDs that never existed vs GL program IDs that have been deleted,
// so report GL_INVALID_VALUE in both cases.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
}
return - 1 ;
}
var _emscripten _glGetUniformLocation = _glGetUniformLocation ;
function webglGetUniformLocation ( location ) {
var p = GLctx . currentProgram ;
if ( p ) {
var webglLoc = p . uniformLocsById [ location ] ;
// p.uniformLocsById[location] stores either an integer, or a WebGLUniformLocation.
// If an integer, we have not yet bound the location, so do it now. The integer value specifies the array index
// we should bind to.
if ( typeof webglLoc == 'number' ) {
p . uniformLocsById [ location ] = webglLoc = GLctx . getUniformLocation ( p , p . uniformArrayNamesById [ location ] + ( webglLoc > 0 ? '[' + webglLoc + ']' : '' ) ) ;
}
// Else an already cached WebGLUniformLocation, return it.
return webglLoc ;
} else {
GL . recordError ( 0x502 /*GL_INVALID_OPERATION*/ ) ;
}
}
/** @suppress{checkTypes} */
function emscriptenWebGLGetUniform ( program , location , params , type ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if params == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
program = GL . programs [ program ] ;
webglPrepareUniformLocationsBeforeFirstUse ( program ) ;
var data = GLctx . getUniform ( program , webglGetUniformLocation ( location ) ) ;
if ( typeof data == 'number' || typeof data == 'boolean' ) {
switch ( type ) {
case 0 : HEAP32 [ ( ( params ) >> 2 ) ] = data ; break ;
case 2 : HEAPF32 [ ( ( params ) >> 2 ) ] = data ; break ;
}
} else {
for ( var i = 0 ; i < data . length ; i ++ ) {
switch ( type ) {
case 0 : HEAP32 [ ( ( ( params ) + ( i * 4 ) ) >> 2 ) ] = data [ i ] ; break ;
case 2 : HEAPF32 [ ( ( ( params ) + ( i * 4 ) ) >> 2 ) ] = data [ i ] ; break ;
}
}
}
}
/** @suppress {duplicate } */
function _glGetUniformfv ( program , location , params ) {
emscriptenWebGLGetUniform ( program , location , params , 2 ) ;
}
var _emscripten _glGetUniformfv = _glGetUniformfv ;
/** @suppress {duplicate } */
function _glGetUniformiv ( program , location , params ) {
emscriptenWebGLGetUniform ( program , location , params , 0 ) ;
}
var _emscripten _glGetUniformiv = _glGetUniformiv ;
/** @suppress {duplicate } */
function _glGetUniformuiv ( program , location , params ) {
emscriptenWebGLGetUniform ( program , location , params , 0 ) ;
}
var _emscripten _glGetUniformuiv = _glGetUniformuiv ;
/** @suppress{checkTypes} */
function emscriptenWebGLGetVertexAttrib ( index , pname , params , type ) {
if ( ! params ) {
// GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense
// if params == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
var data = GLctx . getVertexAttrib ( index , pname ) ;
if ( pname == 0x889F /*VERTEX_ATTRIB_ARRAY_BUFFER_BINDING*/ ) {
HEAP32 [ ( ( params ) >> 2 ) ] = data && data [ "name" ] ;
} else if ( typeof data == 'number' || typeof data == 'boolean' ) {
switch ( type ) {
case 0 : HEAP32 [ ( ( params ) >> 2 ) ] = data ; break ;
case 2 : HEAPF32 [ ( ( params ) >> 2 ) ] = data ; break ;
case 5 : HEAP32 [ ( ( params ) >> 2 ) ] = Math . fround ( data ) ; break ;
}
} else {
for ( var i = 0 ; i < data . length ; i ++ ) {
switch ( type ) {
case 0 : HEAP32 [ ( ( ( params ) + ( i * 4 ) ) >> 2 ) ] = data [ i ] ; break ;
case 2 : HEAPF32 [ ( ( ( params ) + ( i * 4 ) ) >> 2 ) ] = data [ i ] ; break ;
case 5 : HEAP32 [ ( ( ( params ) + ( i * 4 ) ) >> 2 ) ] = Math . fround ( data [ i ] ) ; break ;
}
}
}
}
/** @suppress {duplicate } */
function _glGetVertexAttribIiv ( index , pname , params ) {
// N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttribI4iv(),
// otherwise the results are undefined. (GLES3 spec 6.1.12)
emscriptenWebGLGetVertexAttrib ( index , pname , params , 0 ) ;
}
var _emscripten _glGetVertexAttribIiv = _glGetVertexAttribIiv ;
/** @suppress {duplicate } */
var _glGetVertexAttribIuiv = _glGetVertexAttribIiv ;
var _emscripten _glGetVertexAttribIuiv = _glGetVertexAttribIuiv ;
/** @suppress {duplicate } */
function _glGetVertexAttribPointerv ( index , pname , pointer ) {
if ( ! pointer ) {
// GLES2 specification does not specify how to behave if pointer is a null pointer. Since calling this function does not make sense
// if pointer == null, issue a GL error to notify user about it.
GL . recordError ( 0x501 /* GL_INVALID_VALUE */ ) ;
return ;
}
HEAP32 [ ( ( pointer ) >> 2 ) ] = GLctx . getVertexAttribOffset ( index , pname ) ;
}
var _emscripten _glGetVertexAttribPointerv = _glGetVertexAttribPointerv ;
/** @suppress {duplicate } */
function _glGetVertexAttribfv ( index , pname , params ) {
// N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttrib*f(),
// otherwise the results are undefined. (GLES3 spec 6.1.12)
emscriptenWebGLGetVertexAttrib ( index , pname , params , 2 ) ;
}
var _emscripten _glGetVertexAttribfv = _glGetVertexAttribfv ;
/** @suppress {duplicate } */
function _glGetVertexAttribiv ( index , pname , params ) {
// N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttrib*f(),
// otherwise the results are undefined. (GLES3 spec 6.1.12)
emscriptenWebGLGetVertexAttrib ( index , pname , params , 5 ) ;
}
var _emscripten _glGetVertexAttribiv = _glGetVertexAttribiv ;
/** @suppress {duplicate } */
function _glHint ( x0 , x1 ) { GLctx . hint ( x0 , x1 ) }
var _emscripten _glHint = _glHint ;
/** @suppress {duplicate } */
function _glInvalidateFramebuffer ( target , numAttachments , attachments ) {
var list = tempFixedLengthArray [ numAttachments ] ;
for ( var i = 0 ; i < numAttachments ; i ++ ) {
list [ i ] = HEAP32 [ ( ( ( attachments ) + ( i * 4 ) ) >> 2 ) ] ;
}
GLctx . invalidateFramebuffer ( target , list ) ;
}
var _emscripten _glInvalidateFramebuffer = _glInvalidateFramebuffer ;
/** @suppress {duplicate } */
function _glInvalidateSubFramebuffer ( target , numAttachments , attachments , x , y , width , height ) {
var list = tempFixedLengthArray [ numAttachments ] ;
for ( var i = 0 ; i < numAttachments ; i ++ ) {
list [ i ] = HEAP32 [ ( ( ( attachments ) + ( i * 4 ) ) >> 2 ) ] ;
}
GLctx . invalidateSubFramebuffer ( target , list , x , y , width , height ) ;
}
var _emscripten _glInvalidateSubFramebuffer = _glInvalidateSubFramebuffer ;
/** @suppress {duplicate } */
function _glIsBuffer ( buffer ) {
var b = GL . buffers [ buffer ] ;
if ( ! b ) return 0 ;
return GLctx . isBuffer ( b ) ;
}
var _emscripten _glIsBuffer = _glIsBuffer ;
/** @suppress {duplicate } */
function _glIsEnabled ( x0 ) { return GLctx . isEnabled ( x0 ) }
var _emscripten _glIsEnabled = _glIsEnabled ;
/** @suppress {duplicate } */
function _glIsFramebuffer ( framebuffer ) {
var fb = GL . framebuffers [ framebuffer ] ;
if ( ! fb ) return 0 ;
return GLctx . isFramebuffer ( fb ) ;
}
var _emscripten _glIsFramebuffer = _glIsFramebuffer ;
/** @suppress {duplicate } */
function _glIsProgram ( program ) {
program = GL . programs [ program ] ;
if ( ! program ) return 0 ;
return GLctx . isProgram ( program ) ;
}
var _emscripten _glIsProgram = _glIsProgram ;
/** @suppress {duplicate } */
function _glIsQuery ( id ) {
var query = GL . queries [ id ] ;
if ( ! query ) return 0 ;
return GLctx . isQuery ( query ) ;
}
var _emscripten _glIsQuery = _glIsQuery ;
/** @suppress {duplicate } */
function _glIsQueryEXT ( id ) {
var query = GL . queries [ id ] ;
if ( ! query ) return 0 ;
return GLctx . disjointTimerQueryExt [ 'isQueryEXT' ] ( query ) ;
}
var _emscripten _glIsQueryEXT = _glIsQueryEXT ;
/** @suppress {duplicate } */
function _glIsRenderbuffer ( renderbuffer ) {
var rb = GL . renderbuffers [ renderbuffer ] ;
if ( ! rb ) return 0 ;
return GLctx . isRenderbuffer ( rb ) ;
}
var _emscripten _glIsRenderbuffer = _glIsRenderbuffer ;
/** @suppress {duplicate } */
function _glIsSampler ( id ) {
var sampler = GL . samplers [ id ] ;
if ( ! sampler ) return 0 ;
return GLctx . isSampler ( sampler ) ;
}
var _emscripten _glIsSampler = _glIsSampler ;
/** @suppress {duplicate } */
function _glIsShader ( shader ) {
var s = GL . shaders [ shader ] ;
if ( ! s ) return 0 ;
return GLctx . isShader ( s ) ;
}
var _emscripten _glIsShader = _glIsShader ;
/** @suppress {duplicate } */
function _glIsSync ( sync ) {
return GLctx . isSync ( GL . syncs [ sync ] ) ;
}
var _emscripten _glIsSync = _glIsSync ;
/** @suppress {duplicate } */
function _glIsTexture ( id ) {
var texture = GL . textures [ id ] ;
if ( ! texture ) return 0 ;
return GLctx . isTexture ( texture ) ;
}
var _emscripten _glIsTexture = _glIsTexture ;
/** @suppress {duplicate } */
function _glIsTransformFeedback ( id ) {
return GLctx . isTransformFeedback ( GL . transformFeedbacks [ id ] ) ;
}
var _emscripten _glIsTransformFeedback = _glIsTransformFeedback ;
/** @suppress {duplicate } */
function _glIsVertexArray ( array ) {
var vao = GL . vaos [ array ] ;
if ( ! vao ) return 0 ;
return GLctx . isVertexArray ( vao ) ;
}
var _emscripten _glIsVertexArray = _glIsVertexArray ;
/** @suppress {duplicate } */
var _glIsVertexArrayOES = _glIsVertexArray ;
var _emscripten _glIsVertexArrayOES = _glIsVertexArrayOES ;
/** @suppress {duplicate } */
function _glLineWidth ( x0 ) { GLctx . lineWidth ( x0 ) }
var _emscripten _glLineWidth = _glLineWidth ;
/** @suppress {duplicate } */
function _glLinkProgram ( program ) {
program = GL . programs [ program ] ;
GLctx . linkProgram ( program ) ;
// Invalidate earlier computed uniform->ID mappings, those have now become stale
program . uniformLocsById = 0 ; // Mark as null-like so that glGetUniformLocation() knows to populate this again.
program . uniformSizeAndIdsByName = { } ;
}
var _emscripten _glLinkProgram = _glLinkProgram ;
/** @suppress {duplicate } */
function _glPauseTransformFeedback ( ) { GLctx . pauseTransformFeedback ( ) }
var _emscripten _glPauseTransformFeedback = _glPauseTransformFeedback ;
/** @suppress {duplicate } */
function _glPixelStorei ( pname , param ) {
if ( pname == 0xCF5 /* GL_UNPACK_ALIGNMENT */ ) {
GL . unpackAlignment = param ;
}
GLctx . pixelStorei ( pname , param ) ;
}
var _emscripten _glPixelStorei = _glPixelStorei ;
/** @suppress {duplicate } */
function _glPolygonOffset ( x0 , x1 ) { GLctx . polygonOffset ( x0 , x1 ) }
var _emscripten _glPolygonOffset = _glPolygonOffset ;
/** @suppress {duplicate } */
function _glProgramBinary ( program , binaryFormat , binary , length ) {
GL . recordError ( 0x500 /*GL_INVALID_ENUM*/ ) ;
}
var _emscripten _glProgramBinary = _glProgramBinary ;
/** @suppress {duplicate } */
function _glProgramParameteri ( program , pname , value ) {
GL . recordError ( 0x500 /*GL_INVALID_ENUM*/ ) ;
}
var _emscripten _glProgramParameteri = _glProgramParameteri ;
/** @suppress {duplicate } */
function _glQueryCounterEXT ( id , target ) {
GLctx . disjointTimerQueryExt [ 'queryCounterEXT' ] ( GL . queries [ id ] , target ) ;
}
var _emscripten _glQueryCounterEXT = _glQueryCounterEXT ;
/** @suppress {duplicate } */
function _glReadBuffer ( x0 ) { GLctx . readBuffer ( x0 ) }
var _emscripten _glReadBuffer = _glReadBuffer ;
function computeUnpackAlignedImageSize ( width , height , sizePerPixel , alignment ) {
function roundedToNextMultipleOf ( x , y ) {
return ( x + y - 1 ) & - y ;
}
var plainRowSize = width * sizePerPixel ;
var alignedRowSize = roundedToNextMultipleOf ( plainRowSize , alignment ) ;
return height * alignedRowSize ;
}
function colorChannelsInGlTextureFormat ( format ) {
// Micro-optimizations for size: map format to size by subtracting smallest enum value (0x1902) from all values first.
// Also omit the most common size value (1) from the list, which is assumed by formats not on the list.
var colorChannels = {
// 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1,
// 0x1906 /* GL_ALPHA */ - 0x1902: 1,
5 : 3 ,
6 : 4 ,
// 0x1909 /* GL_LUMINANCE */ - 0x1902: 1,
8 : 2 ,
29502 : 3 ,
29504 : 4 ,
// 0x1903 /* GL_RED */ - 0x1902: 1,
26917 : 2 ,
26918 : 2 ,
// 0x8D94 /* GL_RED_INTEGER */ - 0x1902: 1,
29846 : 3 ,
29847 : 4
} ;
return colorChannels [ format - 0x1902 ] || 1 ;
}
function heapObjectForWebGLType ( type ) {
// Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare
// smaller values for the heap, for shorter generated code size.
// Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16.
// (since most types are HEAPU16)
type -= 0x1400 ;
if ( type == 0 ) return HEAP8 ;
if ( type == 1 ) return HEAPU8 ;
if ( type == 2 ) return HEAP16 ;
if ( type == 4 ) return HEAP32 ;
if ( type == 6 ) return HEAPF32 ;
if ( type == 5
|| type == 28922
|| type == 28520
|| type == 30779
|| type == 30782
)
return HEAPU32 ;
return HEAPU16 ;
}
function heapAccessShiftForWebGLHeap ( heap ) {
return 31 - Math . clz32 ( heap . BYTES _PER _ELEMENT ) ;
}
function emscriptenWebGLGetTexPixelData ( type , format , width , height , pixels , internalFormat ) {
var heap = heapObjectForWebGLType ( type ) ;
var shift = heapAccessShiftForWebGLHeap ( heap ) ;
var byteSize = 1 << shift ;
var sizePerPixel = colorChannelsInGlTextureFormat ( format ) * byteSize ;
var bytes = computeUnpackAlignedImageSize ( width , height , sizePerPixel , GL . unpackAlignment ) ;
return heap . subarray ( pixels >> shift , pixels + bytes >> shift ) ;
}
/** @suppress {duplicate } */
function _glReadPixels ( x , y , width , height , format , type , pixels ) {
if ( true ) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
if ( GLctx . currentPixelPackBufferBinding ) {
GLctx . readPixels ( x , y , width , height , format , type , pixels ) ;
} else {
var heap = heapObjectForWebGLType ( type ) ;
GLctx . readPixels ( x , y , width , height , format , type , heap , pixels >> heapAccessShiftForWebGLHeap ( heap ) ) ;
}
return ;
}
var pixelData = emscriptenWebGLGetTexPixelData ( type , format , width , height , pixels , format ) ;
if ( ! pixelData ) {
GL . recordError ( 0x500 /*GL_INVALID_ENUM*/ ) ;
return ;
}
GLctx . readPixels ( x , y , width , height , format , type , pixelData ) ;
}
var _emscripten _glReadPixels = _glReadPixels ;
/** @suppress {duplicate } */
function _glReleaseShaderCompiler ( ) {
// NOP (as allowed by GLES 2.0 spec)
}
var _emscripten _glReleaseShaderCompiler = _glReleaseShaderCompiler ;
/** @suppress {duplicate } */
function _glRenderbufferStorage ( x0 , x1 , x2 , x3 ) { GLctx . renderbufferStorage ( x0 , x1 , x2 , x3 ) }
var _emscripten _glRenderbufferStorage = _glRenderbufferStorage ;
/** @suppress {duplicate } */
function _glRenderbufferStorageMultisample ( x0 , x1 , x2 , x3 , x4 ) { GLctx . renderbufferStorageMultisample ( x0 , x1 , x2 , x3 , x4 ) }
var _emscripten _glRenderbufferStorageMultisample = _glRenderbufferStorageMultisample ;
/** @suppress {duplicate } */
function _glResumeTransformFeedback ( ) { GLctx . resumeTransformFeedback ( ) }
var _emscripten _glResumeTransformFeedback = _glResumeTransformFeedback ;
/** @suppress {duplicate } */
function _glSampleCoverage ( value , invert ) {
GLctx . sampleCoverage ( value , ! ! invert ) ;
}
var _emscripten _glSampleCoverage = _glSampleCoverage ;
/** @suppress {duplicate } */
function _glSamplerParameterf ( sampler , pname , param ) {
GLctx . samplerParameterf ( GL . samplers [ sampler ] , pname , param ) ;
}
var _emscripten _glSamplerParameterf = _glSamplerParameterf ;
/** @suppress {duplicate } */
function _glSamplerParameterfv ( sampler , pname , params ) {
var param = HEAPF32 [ ( ( params ) >> 2 ) ] ;
GLctx . samplerParameterf ( GL . samplers [ sampler ] , pname , param ) ;
}
var _emscripten _glSamplerParameterfv = _glSamplerParameterfv ;
/** @suppress {duplicate } */
function _glSamplerParameteri ( sampler , pname , param ) {
GLctx . samplerParameteri ( GL . samplers [ sampler ] , pname , param ) ;
}
var _emscripten _glSamplerParameteri = _glSamplerParameteri ;
/** @suppress {duplicate } */
function _glSamplerParameteriv ( sampler , pname , params ) {
var param = HEAP32 [ ( ( params ) >> 2 ) ] ;
GLctx . samplerParameteri ( GL . samplers [ sampler ] , pname , param ) ;
}
var _emscripten _glSamplerParameteriv = _glSamplerParameteriv ;
/** @suppress {duplicate } */
function _glScissor ( x0 , x1 , x2 , x3 ) { GLctx . scissor ( x0 , x1 , x2 , x3 ) }
var _emscripten _glScissor = _glScissor ;
/** @suppress {duplicate } */
function _glShaderBinary ( count , shaders , binaryformat , binary , length ) {
GL . recordError ( 0x500 /*GL_INVALID_ENUM*/ ) ;
}
var _emscripten _glShaderBinary = _glShaderBinary ;
/** @suppress {duplicate } */
function _glShaderSource ( shader , count , string , length ) {
var source = GL . getSource ( shader , count , string , length ) ;
GLctx . shaderSource ( GL . shaders [ shader ] , source ) ;
}
var _emscripten _glShaderSource = _glShaderSource ;
/** @suppress {duplicate } */
function _glStencilFunc ( x0 , x1 , x2 ) { GLctx . stencilFunc ( x0 , x1 , x2 ) }
var _emscripten _glStencilFunc = _glStencilFunc ;
/** @suppress {duplicate } */
function _glStencilFuncSeparate ( x0 , x1 , x2 , x3 ) { GLctx . stencilFuncSeparate ( x0 , x1 , x2 , x3 ) }
var _emscripten _glStencilFuncSeparate = _glStencilFuncSeparate ;
/** @suppress {duplicate } */
function _glStencilMask ( x0 ) { GLctx . stencilMask ( x0 ) }
var _emscripten _glStencilMask = _glStencilMask ;
/** @suppress {duplicate } */
function _glStencilMaskSeparate ( x0 , x1 ) { GLctx . stencilMaskSeparate ( x0 , x1 ) }
var _emscripten _glStencilMaskSeparate = _glStencilMaskSeparate ;
/** @suppress {duplicate } */
function _glStencilOp ( x0 , x1 , x2 ) { GLctx . stencilOp ( x0 , x1 , x2 ) }
var _emscripten _glStencilOp = _glStencilOp ;
/** @suppress {duplicate } */
function _glStencilOpSeparate ( x0 , x1 , x2 , x3 ) { GLctx . stencilOpSeparate ( x0 , x1 , x2 , x3 ) }
var _emscripten _glStencilOpSeparate = _glStencilOpSeparate ;
/** @suppress {duplicate } */
function _glTexImage2D ( target , level , internalFormat , width , height , border , format , type , pixels ) {
if ( true ) {
// WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
if ( GLctx . currentPixelUnpackBufferBinding ) {
GLctx . texImage2D ( target , level , internalFormat , width , height , border , format , type , pixels ) ;
} else if ( pixels ) {
var heap = heapObjectForWebGLType ( type ) ;
GLctx . texImage2D ( target , level , internalFormat , width , height , border , format , type , heap , pixels >> heapAccessShiftForWebGLHeap ( heap ) ) ;
} else {
GLctx . texImage2D ( target , level , internalFormat , width , height , border , format , type , null ) ;
}
return ;
}
GLctx . texImage2D ( target , level , internalFormat , width , height , border , format , type , pixels ? emscriptenWebGLGetTexPixelData ( type , format , width , height , pixels , internalFormat ) : null ) ;
}
var _emscripten _glTexImage2D = _glTexImage2D ;
/** @suppress {duplicate } */
function _glTexImage3D ( target , level , internalFormat , width , height , depth , border , format , type , pixels ) {
if ( GLctx . currentPixelUnpackBufferBinding ) {
GLctx . texImage3D ( target , level , internalFormat , width , height , depth , border , format , type , pixels ) ;
} else if ( pixels ) {
var heap = heapObjectForWebGLType ( type ) ;
GLctx . texImage3D ( target , level , internalFormat , width , height , depth , border , format , type , heap , pixels >> heapAccessShiftForWebGLHeap ( heap ) ) ;
} else {
GLctx . texImage3D ( target , level , internalFormat , width , height , depth , border , format , type , null ) ;
}
}
var _emscripten _glTexImage3D = _glTexImage3D ;
/** @suppress {duplicate } */
function _glTexParameterf ( x0 , x1 , x2 ) { GLctx . texParameterf ( x0 , x1 , x2 ) }
var _emscripten _glTexParameterf = _glTexParameterf ;
/** @suppress {duplicate } */
function _glTexParameterfv ( target , pname , params ) {
var param = HEAPF32 [ ( ( params ) >> 2 ) ] ;
GLctx . texParameterf ( target , pname , param ) ;
}
var _emscripten _glTexParameterfv = _glTexParameterfv ;
/** @suppress {duplicate } */
function _glTexParameteri ( x0 , x1 , x2 ) { GLctx . texParameteri ( x0 , x1 , x2 ) }
var _emscripten _glTexParameteri = _glTexParameteri ;
/** @suppress {duplicate } */
function _glTexParameteriv ( target , pname , params ) {
var param = HEAP32 [ ( ( params ) >> 2 ) ] ;
GLctx . texParameteri ( target , pname , param ) ;
}
var _emscripten _glTexParameteriv = _glTexParameteriv ;
/** @suppress {duplicate } */
function _glTexStorage2D ( x0 , x1 , x2 , x3 , x4 ) { GLctx . texStorage2D ( x0 , x1 , x2 , x3 , x4 ) }
var _emscripten _glTexStorage2D = _glTexStorage2D ;
/** @suppress {duplicate } */
function _glTexStorage3D ( x0 , x1 , x2 , x3 , x4 , x5 ) { GLctx . texStorage3D ( x0 , x1 , x2 , x3 , x4 , x5 ) }
var _emscripten _glTexStorage3D = _glTexStorage3D ;
/** @suppress {duplicate } */
function _glTexSubImage2D ( target , level , xoffset , yoffset , width , height , format , type , pixels ) {
if ( true ) {
// WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible.
if ( GLctx . currentPixelUnpackBufferBinding ) {
GLctx . texSubImage2D ( target , level , xoffset , yoffset , width , height , format , type , pixels ) ;
} else if ( pixels ) {
var heap = heapObjectForWebGLType ( type ) ;
GLctx . texSubImage2D ( target , level , xoffset , yoffset , width , height , format , type , heap , pixels >> heapAccessShiftForWebGLHeap ( heap ) ) ;
} else {
GLctx . texSubImage2D ( target , level , xoffset , yoffset , width , height , format , type , null ) ;
}
return ;
}
var pixelData = null ;
if ( pixels ) pixelData = emscriptenWebGLGetTexPixelData ( type , format , width , height , pixels , 0 ) ;
GLctx . texSubImage2D ( target , level , xoffset , yoffset , width , height , format , type , pixelData ) ;
}
var _emscripten _glTexSubImage2D = _glTexSubImage2D ;
/** @suppress {duplicate } */
function _glTexSubImage3D ( target , level , xoffset , yoffset , zoffset , width , height , depth , format , type , pixels ) {
if ( GLctx . currentPixelUnpackBufferBinding ) {
GLctx . texSubImage3D ( target , level , xoffset , yoffset , zoffset , width , height , depth , format , type , pixels ) ;
} else if ( pixels ) {
var heap = heapObjectForWebGLType ( type ) ;
GLctx . texSubImage3D ( target , level , xoffset , yoffset , zoffset , width , height , depth , format , type , heap , pixels >> heapAccessShiftForWebGLHeap ( heap ) ) ;
} else {
GLctx . texSubImage3D ( target , level , xoffset , yoffset , zoffset , width , height , depth , format , type , null ) ;
}
}
var _emscripten _glTexSubImage3D = _glTexSubImage3D ;
/** @suppress {duplicate } */
function _glTransformFeedbackVaryings ( program , count , varyings , bufferMode ) {
program = GL . programs [ program ] ;
var vars = [ ] ;
for ( var i = 0 ; i < count ; i ++ )
vars . push ( UTF8ToString ( HEAP32 [ ( ( ( varyings ) + ( i * 4 ) ) >> 2 ) ] ) ) ;
GLctx . transformFeedbackVaryings ( program , vars , bufferMode ) ;
}
var _emscripten _glTransformFeedbackVaryings = _glTransformFeedbackVaryings ;
/** @suppress {duplicate } */
function _glUniform1f ( location , v0 ) {
GLctx . uniform1f ( webglGetUniformLocation ( location ) , v0 ) ;
}
var _emscripten _glUniform1f = _glUniform1f ;
/** @suppress {duplicate } */
function _glUniform1fv ( location , count , value ) {
count && GLctx . uniform1fv ( webglGetUniformLocation ( location ) , HEAPF32 , value >> 2 , count ) ;
}
var _emscripten _glUniform1fv = _glUniform1fv ;
/** @suppress {duplicate } */
function _glUniform1i ( location , v0 ) {
GLctx . uniform1i ( webglGetUniformLocation ( location ) , v0 ) ;
}
var _emscripten _glUniform1i = _glUniform1i ;
/** @suppress {duplicate } */
function _glUniform1iv ( location , count , value ) {
count && GLctx . uniform1iv ( webglGetUniformLocation ( location ) , HEAP32 , value >> 2 , count ) ;
}
var _emscripten _glUniform1iv = _glUniform1iv ;
/** @suppress {duplicate } */
function _glUniform1ui ( location , v0 ) {
GLctx . uniform1ui ( webglGetUniformLocation ( location ) , v0 ) ;
}
var _emscripten _glUniform1ui = _glUniform1ui ;
/** @suppress {duplicate } */
function _glUniform1uiv ( location , count , value ) {
count && GLctx . uniform1uiv ( webglGetUniformLocation ( location ) , HEAPU32 , value >> 2 , count ) ;
}
var _emscripten _glUniform1uiv = _glUniform1uiv ;
/** @suppress {duplicate } */
function _glUniform2f ( location , v0 , v1 ) {
GLctx . uniform2f ( webglGetUniformLocation ( location ) , v0 , v1 ) ;
}
var _emscripten _glUniform2f = _glUniform2f ;
/** @suppress {duplicate } */
function _glUniform2fv ( location , count , value ) {
count && GLctx . uniform2fv ( webglGetUniformLocation ( location ) , HEAPF32 , value >> 2 , count * 2 ) ;
}
var _emscripten _glUniform2fv = _glUniform2fv ;
/** @suppress {duplicate } */
function _glUniform2i ( location , v0 , v1 ) {
GLctx . uniform2i ( webglGetUniformLocation ( location ) , v0 , v1 ) ;
}
var _emscripten _glUniform2i = _glUniform2i ;
/** @suppress {duplicate } */
function _glUniform2iv ( location , count , value ) {
count && GLctx . uniform2iv ( webglGetUniformLocation ( location ) , HEAP32 , value >> 2 , count * 2 ) ;
}
var _emscripten _glUniform2iv = _glUniform2iv ;
/** @suppress {duplicate } */
function _glUniform2ui ( location , v0 , v1 ) {
GLctx . uniform2ui ( webglGetUniformLocation ( location ) , v0 , v1 ) ;
}
var _emscripten _glUniform2ui = _glUniform2ui ;
/** @suppress {duplicate } */
function _glUniform2uiv ( location , count , value ) {
count && GLctx . uniform2uiv ( webglGetUniformLocation ( location ) , HEAPU32 , value >> 2 , count * 2 ) ;
}
var _emscripten _glUniform2uiv = _glUniform2uiv ;
/** @suppress {duplicate } */
function _glUniform3f ( location , v0 , v1 , v2 ) {
GLctx . uniform3f ( webglGetUniformLocation ( location ) , v0 , v1 , v2 ) ;
}
var _emscripten _glUniform3f = _glUniform3f ;
/** @suppress {duplicate } */
function _glUniform3fv ( location , count , value ) {
count && GLctx . uniform3fv ( webglGetUniformLocation ( location ) , HEAPF32 , value >> 2 , count * 3 ) ;
}
var _emscripten _glUniform3fv = _glUniform3fv ;
/** @suppress {duplicate } */
function _glUniform3i ( location , v0 , v1 , v2 ) {
GLctx . uniform3i ( webglGetUniformLocation ( location ) , v0 , v1 , v2 ) ;
}
var _emscripten _glUniform3i = _glUniform3i ;
/** @suppress {duplicate } */
function _glUniform3iv ( location , count , value ) {
count && GLctx . uniform3iv ( webglGetUniformLocation ( location ) , HEAP32 , value >> 2 , count * 3 ) ;
}
var _emscripten _glUniform3iv = _glUniform3iv ;
/** @suppress {duplicate } */
function _glUniform3ui ( location , v0 , v1 , v2 ) {
GLctx . uniform3ui ( webglGetUniformLocation ( location ) , v0 , v1 , v2 ) ;
}
var _emscripten _glUniform3ui = _glUniform3ui ;
/** @suppress {duplicate } */
function _glUniform3uiv ( location , count , value ) {
count && GLctx . uniform3uiv ( webglGetUniformLocation ( location ) , HEAPU32 , value >> 2 , count * 3 ) ;
}
var _emscripten _glUniform3uiv = _glUniform3uiv ;
/** @suppress {duplicate } */
function _glUniform4f ( location , v0 , v1 , v2 , v3 ) {
GLctx . uniform4f ( webglGetUniformLocation ( location ) , v0 , v1 , v2 , v3 ) ;
}
var _emscripten _glUniform4f = _glUniform4f ;
/** @suppress {duplicate } */
function _glUniform4fv ( location , count , value ) {
count && GLctx . uniform4fv ( webglGetUniformLocation ( location ) , HEAPF32 , value >> 2 , count * 4 ) ;
}
var _emscripten _glUniform4fv = _glUniform4fv ;
/** @suppress {duplicate } */
function _glUniform4i ( location , v0 , v1 , v2 , v3 ) {
GLctx . uniform4i ( webglGetUniformLocation ( location ) , v0 , v1 , v2 , v3 ) ;
}
var _emscripten _glUniform4i = _glUniform4i ;
/** @suppress {duplicate } */
function _glUniform4iv ( location , count , value ) {
count && GLctx . uniform4iv ( webglGetUniformLocation ( location ) , HEAP32 , value >> 2 , count * 4 ) ;
}
var _emscripten _glUniform4iv = _glUniform4iv ;
/** @suppress {duplicate } */
function _glUniform4ui ( location , v0 , v1 , v2 , v3 ) {
GLctx . uniform4ui ( webglGetUniformLocation ( location ) , v0 , v1 , v2 , v3 ) ;
}
var _emscripten _glUniform4ui = _glUniform4ui ;
/** @suppress {duplicate } */
function _glUniform4uiv ( location , count , value ) {
count && GLctx . uniform4uiv ( webglGetUniformLocation ( location ) , HEAPU32 , value >> 2 , count * 4 ) ;
}
var _emscripten _glUniform4uiv = _glUniform4uiv ;
/** @suppress {duplicate } */
function _glUniformBlockBinding ( program , uniformBlockIndex , uniformBlockBinding ) {
program = GL . programs [ program ] ;
GLctx . uniformBlockBinding ( program , uniformBlockIndex , uniformBlockBinding ) ;
}
var _emscripten _glUniformBlockBinding = _glUniformBlockBinding ;
/** @suppress {duplicate } */
function _glUniformMatrix2fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix2fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 4 ) ;
}
var _emscripten _glUniformMatrix2fv = _glUniformMatrix2fv ;
/** @suppress {duplicate } */
function _glUniformMatrix2x3fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix2x3fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 6 ) ;
}
var _emscripten _glUniformMatrix2x3fv = _glUniformMatrix2x3fv ;
/** @suppress {duplicate } */
function _glUniformMatrix2x4fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix2x4fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 8 ) ;
}
var _emscripten _glUniformMatrix2x4fv = _glUniformMatrix2x4fv ;
/** @suppress {duplicate } */
function _glUniformMatrix3fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix3fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 9 ) ;
}
var _emscripten _glUniformMatrix3fv = _glUniformMatrix3fv ;
/** @suppress {duplicate } */
function _glUniformMatrix3x2fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix3x2fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 6 ) ;
}
var _emscripten _glUniformMatrix3x2fv = _glUniformMatrix3x2fv ;
/** @suppress {duplicate } */
function _glUniformMatrix3x4fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix3x4fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 12 ) ;
}
var _emscripten _glUniformMatrix3x4fv = _glUniformMatrix3x4fv ;
/** @suppress {duplicate } */
function _glUniformMatrix4fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix4fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 16 ) ;
}
var _emscripten _glUniformMatrix4fv = _glUniformMatrix4fv ;
/** @suppress {duplicate } */
function _glUniformMatrix4x2fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix4x2fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 8 ) ;
}
var _emscripten _glUniformMatrix4x2fv = _glUniformMatrix4x2fv ;
/** @suppress {duplicate } */
function _glUniformMatrix4x3fv ( location , count , transpose , value ) {
count && GLctx . uniformMatrix4x3fv ( webglGetUniformLocation ( location ) , ! ! transpose , HEAPF32 , value >> 2 , count * 12 ) ;
}
var _emscripten _glUniformMatrix4x3fv = _glUniformMatrix4x3fv ;
/** @suppress {duplicate } */
function _glUseProgram ( program ) {
program = GL . programs [ program ] ;
GLctx . useProgram ( program ) ;
// Record the currently active program so that we can access the uniform
// mapping table of that program.
GLctx . currentProgram = program ;
}
var _emscripten _glUseProgram = _glUseProgram ;
/** @suppress {duplicate } */
function _glValidateProgram ( program ) {
GLctx . validateProgram ( GL . programs [ program ] ) ;
}
var _emscripten _glValidateProgram = _glValidateProgram ;
/** @suppress {duplicate } */
function _glVertexAttrib1f ( x0 , x1 ) { GLctx . vertexAttrib1f ( x0 , x1 ) }
var _emscripten _glVertexAttrib1f = _glVertexAttrib1f ;
/** @suppress {duplicate } */
function _glVertexAttrib1fv ( index , v ) {
GLctx . vertexAttrib1f ( index , HEAPF32 [ v >> 2 ] ) ;
}
var _emscripten _glVertexAttrib1fv = _glVertexAttrib1fv ;
/** @suppress {duplicate } */
function _glVertexAttrib2f ( x0 , x1 , x2 ) { GLctx . vertexAttrib2f ( x0 , x1 , x2 ) }
var _emscripten _glVertexAttrib2f = _glVertexAttrib2f ;
/** @suppress {duplicate } */
function _glVertexAttrib2fv ( index , v ) {
GLctx . vertexAttrib2f ( index , HEAPF32 [ v >> 2 ] , HEAPF32 [ v + 4 >> 2 ] ) ;
}
var _emscripten _glVertexAttrib2fv = _glVertexAttrib2fv ;
/** @suppress {duplicate } */
function _glVertexAttrib3f ( x0 , x1 , x2 , x3 ) { GLctx . vertexAttrib3f ( x0 , x1 , x2 , x3 ) }
var _emscripten _glVertexAttrib3f = _glVertexAttrib3f ;
/** @suppress {duplicate } */
function _glVertexAttrib3fv ( index , v ) {
GLctx . vertexAttrib3f ( index , HEAPF32 [ v >> 2 ] , HEAPF32 [ v + 4 >> 2 ] , HEAPF32 [ v + 8 >> 2 ] ) ;
}
var _emscripten _glVertexAttrib3fv = _glVertexAttrib3fv ;
/** @suppress {duplicate } */
function _glVertexAttrib4f ( x0 , x1 , x2 , x3 , x4 ) { GLctx . vertexAttrib4f ( x0 , x1 , x2 , x3 , x4 ) }
var _emscripten _glVertexAttrib4f = _glVertexAttrib4f ;
/** @suppress {duplicate } */
function _glVertexAttrib4fv ( index , v ) {
GLctx . vertexAttrib4f ( index , HEAPF32 [ v >> 2 ] , HEAPF32 [ v + 4 >> 2 ] , HEAPF32 [ v + 8 >> 2 ] , HEAPF32 [ v + 12 >> 2 ] ) ;
}
var _emscripten _glVertexAttrib4fv = _glVertexAttrib4fv ;
/** @suppress {duplicate } */
function _glVertexAttribDivisor ( index , divisor ) {
GLctx . vertexAttribDivisor ( index , divisor ) ;
}
var _emscripten _glVertexAttribDivisor = _glVertexAttribDivisor ;
/** @suppress {duplicate } */
var _glVertexAttribDivisorANGLE = _glVertexAttribDivisor ;
var _emscripten _glVertexAttribDivisorANGLE = _glVertexAttribDivisorANGLE ;
/** @suppress {duplicate } */
var _glVertexAttribDivisorARB = _glVertexAttribDivisor ;
var _emscripten _glVertexAttribDivisorARB = _glVertexAttribDivisorARB ;
/** @suppress {duplicate } */
var _glVertexAttribDivisorEXT = _glVertexAttribDivisor ;
var _emscripten _glVertexAttribDivisorEXT = _glVertexAttribDivisorEXT ;
/** @suppress {duplicate } */
var _glVertexAttribDivisorNV = _glVertexAttribDivisor ;
var _emscripten _glVertexAttribDivisorNV = _glVertexAttribDivisorNV ;
/** @suppress {duplicate } */
function _glVertexAttribI4i ( x0 , x1 , x2 , x3 , x4 ) { GLctx . vertexAttribI4i ( x0 , x1 , x2 , x3 , x4 ) }
var _emscripten _glVertexAttribI4i = _glVertexAttribI4i ;
/** @suppress {duplicate } */
function _glVertexAttribI4iv ( index , v ) {
GLctx . vertexAttribI4i ( index , HEAP32 [ v >> 2 ] , HEAP32 [ v + 4 >> 2 ] , HEAP32 [ v + 8 >> 2 ] , HEAP32 [ v + 12 >> 2 ] ) ;
}
var _emscripten _glVertexAttribI4iv = _glVertexAttribI4iv ;
/** @suppress {duplicate } */
function _glVertexAttribI4ui ( x0 , x1 , x2 , x3 , x4 ) { GLctx . vertexAttribI4ui ( x0 , x1 , x2 , x3 , x4 ) }
var _emscripten _glVertexAttribI4ui = _glVertexAttribI4ui ;
/** @suppress {duplicate } */
function _glVertexAttribI4uiv ( index , v ) {
GLctx . vertexAttribI4ui ( index , HEAPU32 [ v >> 2 ] , HEAPU32 [ v + 4 >> 2 ] , HEAPU32 [ v + 8 >> 2 ] , HEAPU32 [ v + 12 >> 2 ] ) ;
}
var _emscripten _glVertexAttribI4uiv = _glVertexAttribI4uiv ;
/** @suppress {duplicate } */
function _glVertexAttribIPointer ( index , size , type , stride , ptr ) {
GLctx . vertexAttribIPointer ( index , size , type , stride , ptr ) ;
}
var _emscripten _glVertexAttribIPointer = _glVertexAttribIPointer ;
/** @suppress {duplicate } */
function _glVertexAttribPointer ( index , size , type , normalized , stride , ptr ) {
GLctx . vertexAttribPointer ( index , size , type , ! ! normalized , stride , ptr ) ;
}
var _emscripten _glVertexAttribPointer = _glVertexAttribPointer ;
/** @suppress {duplicate } */
function _glViewport ( x0 , x1 , x2 , x3 ) { GLctx . viewport ( x0 , x1 , x2 , x3 ) }
var _emscripten _glViewport = _glViewport ;
/** @suppress {duplicate } */
function _glWaitSync ( sync , flags , timeout _low , timeout _high ) {
// See WebGL2 vs GLES3 difference on GL_TIMEOUT_IGNORED above (https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.15)
var timeout = convertI32PairToI53 ( timeout _low , timeout _high ) ;
GLctx . waitSync ( GL . syncs [ sync ] , flags , timeout ) ;
}
var _emscripten _glWaitSync = _glWaitSync ;
function _emscripten _has _asyncify ( ) {
return 0 ;
}
function _emscripten _memcpy _big ( dest , src , num ) {
HEAPU8 . copyWithin ( dest , src , src + num ) ;
}
function doRequestFullscreen ( target , strategy ) {
if ( ! JSEvents . fullscreenEnabled ( ) ) return - 1 ;
target = findEventTarget ( target ) ;
if ( ! target ) return - 4 ;
if ( ! target . requestFullscreen
&& ! target . webkitRequestFullscreen
) {
return - 3 ;
}
var canPerformRequests = JSEvents . canPerformEventHandlerRequests ( ) ;
// Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so.
if ( ! canPerformRequests ) {
if ( strategy . deferUntilInEventHandler ) {
JSEvents . deferCall ( JSEvents _requestFullscreen , 1 /* priority over pointer lock */ , [ target , strategy ] ) ;
return 1 ;
}
return - 2 ;
}
return JSEvents _requestFullscreen ( target , strategy ) ;
}
function _emscripten _request _fullscreen _strategy ( target , deferUntilInEventHandler , fullscreenStrategy ) {
var strategy = {
scaleMode : HEAP32 [ ( ( fullscreenStrategy ) >> 2 ) ] ,
canvasResolutionScaleMode : HEAP32 [ ( ( ( fullscreenStrategy ) + ( 4 ) ) >> 2 ) ] ,
filteringMode : HEAP32 [ ( ( ( fullscreenStrategy ) + ( 8 ) ) >> 2 ) ] ,
deferUntilInEventHandler : deferUntilInEventHandler ,
canvasResizedCallback : HEAP32 [ ( ( ( fullscreenStrategy ) + ( 12 ) ) >> 2 ) ] ,
canvasResizedCallbackUserData : HEAP32 [ ( ( ( fullscreenStrategy ) + ( 16 ) ) >> 2 ) ]
} ;
return doRequestFullscreen ( target , strategy ) ;
}
function _emscripten _request _pointerlock ( target , deferUntilInEventHandler ) {
target = findEventTarget ( target ) ;
if ( ! target ) return - 4 ;
if ( ! target . requestPointerLock
) {
return - 1 ;
}
var canPerformRequests = JSEvents . canPerformEventHandlerRequests ( ) ;
// Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so.
if ( ! canPerformRequests ) {
if ( deferUntilInEventHandler ) {
JSEvents . deferCall ( requestPointerLock , 2 /* priority below fullscreen */ , [ target ] ) ;
return 1 ;
}
return - 2 ;
}
return requestPointerLock ( target ) ;
}
function getHeapMax ( ) {
// Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
// full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
// for any code that deals with heap sizes, which would require special
// casing all heap size related code to treat 0 specially.
return 2147483648 ;
}
function emscripten _realloc _buffer ( size ) {
var b = wasmMemory . buffer ;
try {
// round size grow request up to wasm page size (fixed 64KB per spec)
wasmMemory . grow ( ( size - b . byteLength + 65535 ) >>> 16 ) ; // .grow() takes a delta compared to the previous size
updateMemoryViews ( ) ;
return 1 /*success*/ ;
} catch ( e ) {
err ( ` emscripten_realloc_buffer: Attempted to grow heap from ${ b . byteLength } bytes to ${ size } bytes, but got error: ${ e } ` ) ;
}
// implicit 0 return to save code size (caller will cast "undefined" into 0
// anyhow)
}
function _emscripten _resize _heap ( requestedSize ) {
var oldSize = HEAPU8 . length ;
requestedSize = requestedSize >>> 0 ;
// With multithreaded builds, races can happen (another thread might increase the size
// in between), so return a failure, and let the caller retry.
assert ( requestedSize > oldSize ) ;
// Memory resize rules:
// 1. Always increase heap size to at least the requested size, rounded up
// to next page multiple.
// 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
// geometrically: increase the heap size according to
// MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
// overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
// 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
// linearly: increase the heap size by at least
// MEMORY_GROWTH_LINEAR_STEP bytes.
// 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
// MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
// 4. If we were unable to allocate as much memory, it may be due to
// over-eager decision to excessively reserve due to (3) above.
// Hence if an allocation fails, cut down on the amount of excess
// growth, in an attempt to succeed to perform a smaller allocation.
// A limit is set for how much we can grow. We should not exceed that
// (the wasm binary specifies it, so if we tried, we'd fail anyhow).
var maxHeapSize = getHeapMax ( ) ;
if ( requestedSize > maxHeapSize ) {
err ( ` Cannot enlarge memory, asked to go up to ${ requestedSize } bytes, but the limit is ${ maxHeapSize } bytes! ` ) ;
return false ;
}
var alignUp = ( x , multiple ) => x + ( multiple - x % multiple ) % multiple ;
// Loop through potential heap size increases. If we attempt a too eager
// reservation that fails, cut down on the attempted size and reserve a
// smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
for ( var cutDown = 1 ; cutDown <= 4 ; cutDown *= 2 ) {
var overGrownHeapSize = oldSize * ( 1 + 0.2 / cutDown ) ; // ensure geometric growth
// but limit overreserving (default to capping at +96MB overgrowth at most)
overGrownHeapSize = Math . min ( overGrownHeapSize , requestedSize + 100663296 ) ;
var newSize = Math . min ( maxHeapSize , alignUp ( Math . max ( requestedSize , overGrownHeapSize ) , 65536 ) ) ;
var replacement = emscripten _realloc _buffer ( newSize ) ;
if ( replacement ) {
return true ;
}
}
err ( ` Failed to grow the heap from ${ oldSize } bytes to ${ newSize } bytes, not enough memory! ` ) ;
return false ;
}
function _emscripten _sample _gamepad _data ( ) {
return ( JSEvents . lastGamepadState = ( navigator . getGamepads ? navigator . getGamepads ( ) : ( navigator . webkitGetGamepads ? navigator . webkitGetGamepads ( ) : null ) ) )
? 0 : - 1 ;
}
function registerBeforeUnloadEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString ) {
var beforeUnloadEventHandlerFunc = function ( e = event ) {
// Note: This is always called on the main browser thread, since it needs synchronously return a value!
var confirmationMessage = getWasmTableEntry ( callbackfunc ) ( eventTypeId , 0 , userData ) ;
if ( confirmationMessage ) {
confirmationMessage = UTF8ToString ( confirmationMessage ) ;
}
if ( confirmationMessage ) {
e . preventDefault ( ) ;
e . returnValue = confirmationMessage ;
return confirmationMessage ;
}
} ;
var eventHandler = {
target : findEventTarget ( target ) ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : beforeUnloadEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _beforeunload _callback _on _thread ( userData , callbackfunc , targetThread ) {
if ( typeof onbeforeunload == 'undefined' ) return - 1 ;
// beforeunload callback can only be registered on the main browser thread, because the page will go away immediately after returning from the handler,
// and there is no time to start proxying it anywhere.
if ( targetThread !== 1 ) return - 5 ;
return registerBeforeUnloadEventCallback ( 2 , userData , true , callbackfunc , 28 , "beforeunload" ) ;
}
function registerFocusEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . focusEvent ) JSEvents . focusEvent = _malloc ( 256 ) ;
var focusEventHandlerFunc = function ( e = event ) {
var nodeName = JSEvents . getNodeNameForTarget ( e . target ) ;
var id = e . target . id ? e . target . id : '' ;
var focusEvent = JSEvents . focusEvent ;
stringToUTF8 ( nodeName , focusEvent + 0 , 128 ) ;
stringToUTF8 ( id , focusEvent + 128 , 128 ) ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , focusEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : findEventTarget ( target ) ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : focusEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _blur _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerFocusEventCallback ( target , userData , useCapture , callbackfunc , 12 , "blur" , targetThread ) ;
}
function _emscripten _set _element _css _size ( target , width , height ) {
target = findEventTarget ( target ) ;
if ( ! target ) return - 4 ;
target . style . width = width + "px" ;
target . style . height = height + "px" ;
return 0 ;
}
function _emscripten _set _focus _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerFocusEventCallback ( target , userData , useCapture , callbackfunc , 13 , "focus" , targetThread ) ;
}
function fillFullscreenChangeEventData ( eventStruct ) {
var fullscreenElement = document . fullscreenElement || document . mozFullScreenElement || document . webkitFullscreenElement || document . msFullscreenElement ;
var isFullscreen = ! ! fullscreenElement ;
// Assigning a boolean to HEAP32 with expected type coercion.
/** @suppress{checkTypes} */
HEAP32 [ ( ( eventStruct ) >> 2 ) ] = isFullscreen ;
HEAP32 [ ( ( ( eventStruct ) + ( 4 ) ) >> 2 ) ] = JSEvents . fullscreenEnabled ( ) ;
// If transitioning to fullscreen, report info about the element that is now fullscreen.
// If transitioning to windowed mode, report info about the element that just was fullscreen.
var reportedElement = isFullscreen ? fullscreenElement : JSEvents . previousFullscreenElement ;
var nodeName = JSEvents . getNodeNameForTarget ( reportedElement ) ;
var id = ( reportedElement && reportedElement . id ) ? reportedElement . id : '' ;
stringToUTF8 ( nodeName , eventStruct + 8 , 128 ) ;
stringToUTF8 ( id , eventStruct + 136 , 128 ) ;
HEAP32 [ ( ( ( eventStruct ) + ( 264 ) ) >> 2 ) ] = reportedElement ? reportedElement . clientWidth : 0 ;
HEAP32 [ ( ( ( eventStruct ) + ( 268 ) ) >> 2 ) ] = reportedElement ? reportedElement . clientHeight : 0 ;
HEAP32 [ ( ( ( eventStruct ) + ( 272 ) ) >> 2 ) ] = screen . width ;
HEAP32 [ ( ( ( eventStruct ) + ( 276 ) ) >> 2 ) ] = screen . height ;
if ( isFullscreen ) {
JSEvents . previousFullscreenElement = fullscreenElement ;
}
}
function registerFullscreenChangeEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . fullscreenChangeEvent ) JSEvents . fullscreenChangeEvent = _malloc ( 280 ) ;
var fullscreenChangeEventhandlerFunc = function ( e = event ) {
var fullscreenChangeEvent = JSEvents . fullscreenChangeEvent ;
fillFullscreenChangeEventData ( fullscreenChangeEvent ) ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , fullscreenChangeEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : target ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : fullscreenChangeEventhandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _fullscreenchange _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
if ( ! JSEvents . fullscreenEnabled ( ) ) return - 1 ;
target = findEventTarget ( target ) ;
if ( ! target ) return - 4 ;
// Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813)
// As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version.
registerFullscreenChangeEventCallback ( target , userData , useCapture , callbackfunc , 19 , "webkitfullscreenchange" , targetThread ) ;
return registerFullscreenChangeEventCallback ( target , userData , useCapture , callbackfunc , 19 , "fullscreenchange" , targetThread ) ;
}
function registerGamepadEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . gamepadEvent ) JSEvents . gamepadEvent = _malloc ( 1432 ) ;
var gamepadEventHandlerFunc = function ( e = event ) {
var gamepadEvent = JSEvents . gamepadEvent ;
fillGamepadEventData ( gamepadEvent , e [ "gamepad" ] ) ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , gamepadEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : findEventTarget ( target ) ,
allowsDeferredCalls : true ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : gamepadEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _gamepadconnected _callback _on _thread ( userData , useCapture , callbackfunc , targetThread ) {
if ( ! navigator . getGamepads && ! navigator . webkitGetGamepads ) return - 1 ;
return registerGamepadEventCallback ( 2 , userData , useCapture , callbackfunc , 26 , "gamepadconnected" , targetThread ) ;
}
function _emscripten _set _gamepaddisconnected _callback _on _thread ( userData , useCapture , callbackfunc , targetThread ) {
if ( ! navigator . getGamepads && ! navigator . webkitGetGamepads ) return - 1 ;
return registerGamepadEventCallback ( 2 , userData , useCapture , callbackfunc , 27 , "gamepaddisconnected" , targetThread ) ;
}
function registerKeyEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . keyEvent ) JSEvents . keyEvent = _malloc ( 176 ) ;
var keyEventHandlerFunc = function ( e ) {
assert ( e ) ;
var keyEventData = JSEvents . keyEvent ;
HEAPF64 [ ( ( keyEventData ) >> 3 ) ] = e . timeStamp ;
var idx = keyEventData >> 2 ;
HEAP32 [ idx + 2 ] = e . location ;
HEAP32 [ idx + 3 ] = e . ctrlKey ;
HEAP32 [ idx + 4 ] = e . shiftKey ;
HEAP32 [ idx + 5 ] = e . altKey ;
HEAP32 [ idx + 6 ] = e . metaKey ;
HEAP32 [ idx + 7 ] = e . repeat ;
HEAP32 [ idx + 8 ] = e . charCode ;
HEAP32 [ idx + 9 ] = e . keyCode ;
HEAP32 [ idx + 10 ] = e . which ;
stringToUTF8 ( e . key || '' , keyEventData + 44 , 32 ) ;
stringToUTF8 ( e . code || '' , keyEventData + 76 , 32 ) ;
stringToUTF8 ( e . char || '' , keyEventData + 108 , 32 ) ;
stringToUTF8 ( e . locale || '' , keyEventData + 140 , 32 ) ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , keyEventData , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : findEventTarget ( target ) ,
allowsDeferredCalls : true ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : keyEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _keydown _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerKeyEventCallback ( target , userData , useCapture , callbackfunc , 2 , "keydown" , targetThread ) ;
}
function _emscripten _set _keypress _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerKeyEventCallback ( target , userData , useCapture , callbackfunc , 1 , "keypress" , targetThread ) ;
}
function _emscripten _set _keyup _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerKeyEventCallback ( target , userData , useCapture , callbackfunc , 3 , "keyup" , targetThread ) ;
}
function _emscripten _set _main _loop ( func , fps , simulateInfiniteLoop ) {
var browserIterationFunc = getWasmTableEntry ( func ) ;
setMainLoop ( browserIterationFunc , fps , simulateInfiniteLoop ) ;
}
function fillMouseEventData ( eventStruct , e , target ) {
assert ( eventStruct % 4 == 0 ) ;
HEAPF64 [ ( ( eventStruct ) >> 3 ) ] = e . timeStamp ;
var idx = eventStruct >> 2 ;
HEAP32 [ idx + 2 ] = e . screenX ;
HEAP32 [ idx + 3 ] = e . screenY ;
HEAP32 [ idx + 4 ] = e . clientX ;
HEAP32 [ idx + 5 ] = e . clientY ;
HEAP32 [ idx + 6 ] = e . ctrlKey ;
HEAP32 [ idx + 7 ] = e . shiftKey ;
HEAP32 [ idx + 8 ] = e . altKey ;
HEAP32 [ idx + 9 ] = e . metaKey ;
HEAP16 [ idx * 2 + 20 ] = e . button ;
HEAP16 [ idx * 2 + 21 ] = e . buttons ;
HEAP32 [ idx + 11 ] = e [ "movementX" ]
;
HEAP32 [ idx + 12 ] = e [ "movementY" ]
;
var rect = getBoundingClientRect ( target ) ;
HEAP32 [ idx + 13 ] = e . clientX - rect . left ;
HEAP32 [ idx + 14 ] = e . clientY - rect . top ;
}
function registerMouseEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . mouseEvent ) JSEvents . mouseEvent = _malloc ( 72 ) ;
target = findEventTarget ( target ) ;
var mouseEventHandlerFunc = function ( e = event ) {
// TODO: Make this access thread safe, or this could update live while app is reading it.
fillMouseEventData ( JSEvents . mouseEvent , e , target ) ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , JSEvents . mouseEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : target ,
allowsDeferredCalls : eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave' , // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : mouseEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _mousedown _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerMouseEventCallback ( target , userData , useCapture , callbackfunc , 5 , "mousedown" , targetThread ) ;
}
function _emscripten _set _mouseenter _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerMouseEventCallback ( target , userData , useCapture , callbackfunc , 33 , "mouseenter" , targetThread ) ;
}
function _emscripten _set _mouseleave _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerMouseEventCallback ( target , userData , useCapture , callbackfunc , 34 , "mouseleave" , targetThread ) ;
}
function _emscripten _set _mousemove _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerMouseEventCallback ( target , userData , useCapture , callbackfunc , 8 , "mousemove" , targetThread ) ;
}
function _emscripten _set _mouseup _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerMouseEventCallback ( target , userData , useCapture , callbackfunc , 6 , "mouseup" , targetThread ) ;
}
function fillPointerlockChangeEventData ( eventStruct ) {
var pointerLockElement = document . pointerLockElement || document . mozPointerLockElement || document . webkitPointerLockElement || document . msPointerLockElement ;
var isPointerlocked = ! ! pointerLockElement ;
// Assigning a boolean to HEAP32 with expected type coercion.
/** @suppress{checkTypes} */
HEAP32 [ ( ( eventStruct ) >> 2 ) ] = isPointerlocked ;
var nodeName = JSEvents . getNodeNameForTarget ( pointerLockElement ) ;
var id = ( pointerLockElement && pointerLockElement . id ) ? pointerLockElement . id : '' ;
stringToUTF8 ( nodeName , eventStruct + 4 , 128 ) ;
stringToUTF8 ( id , eventStruct + 132 , 128 ) ;
}
function registerPointerlockChangeEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . pointerlockChangeEvent ) JSEvents . pointerlockChangeEvent = _malloc ( 260 ) ;
var pointerlockChangeEventHandlerFunc = function ( e = event ) {
var pointerlockChangeEvent = JSEvents . pointerlockChangeEvent ;
fillPointerlockChangeEventData ( pointerlockChangeEvent ) ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , pointerlockChangeEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : target ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : pointerlockChangeEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
/** @suppress {missingProperties} */
function _emscripten _set _pointerlockchange _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
// TODO: Currently not supported in pthreads or in --proxy-to-worker mode. (In pthreads mode, document object is not defined)
if ( ! document || ! document . body || ( ! document . body . requestPointerLock && ! document . body . mozRequestPointerLock && ! document . body . webkitRequestPointerLock && ! document . body . msRequestPointerLock ) ) {
return - 1 ;
}
target = findEventTarget ( target ) ;
if ( ! target ) return - 4 ;
registerPointerlockChangeEventCallback ( target , userData , useCapture , callbackfunc , 20 , "mozpointerlockchange" , targetThread ) ;
registerPointerlockChangeEventCallback ( target , userData , useCapture , callbackfunc , 20 , "webkitpointerlockchange" , targetThread ) ;
registerPointerlockChangeEventCallback ( target , userData , useCapture , callbackfunc , 20 , "mspointerlockchange" , targetThread ) ;
return registerPointerlockChangeEventCallback ( target , userData , useCapture , callbackfunc , 20 , "pointerlockchange" , targetThread ) ;
}
function registerUiEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . uiEvent ) JSEvents . uiEvent = _malloc ( 36 ) ;
target = findEventTarget ( target ) ;
var uiEventHandlerFunc = function ( e = event ) {
if ( e . target != target ) {
// Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that
// was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log
// message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print,
// causing a new scroll, etc..
return ;
}
var b = document . body ; // Take document.body to a variable, Closure compiler does not outline access to it on its own.
if ( ! b ) {
// During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown
return ;
}
var uiEvent = JSEvents . uiEvent ;
HEAP32 [ ( ( uiEvent ) >> 2 ) ] = e . detail ;
HEAP32 [ ( ( ( uiEvent ) + ( 4 ) ) >> 2 ) ] = b . clientWidth ;
HEAP32 [ ( ( ( uiEvent ) + ( 8 ) ) >> 2 ) ] = b . clientHeight ;
HEAP32 [ ( ( ( uiEvent ) + ( 12 ) ) >> 2 ) ] = innerWidth ;
HEAP32 [ ( ( ( uiEvent ) + ( 16 ) ) >> 2 ) ] = innerHeight ;
HEAP32 [ ( ( ( uiEvent ) + ( 20 ) ) >> 2 ) ] = outerWidth ;
HEAP32 [ ( ( ( uiEvent ) + ( 24 ) ) >> 2 ) ] = outerHeight ;
HEAP32 [ ( ( ( uiEvent ) + ( 28 ) ) >> 2 ) ] = pageXOffset ;
HEAP32 [ ( ( ( uiEvent ) + ( 32 ) ) >> 2 ) ] = pageYOffset ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , uiEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : target ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : uiEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _resize _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerUiEventCallback ( target , userData , useCapture , callbackfunc , 10 , "resize" , targetThread ) ;
}
function registerTouchEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . touchEvent ) JSEvents . touchEvent = _malloc ( 1696 ) ;
target = findEventTarget ( target ) ;
var touchEventHandlerFunc = function ( e ) {
assert ( e ) ;
var t , touches = { } , et = e . touches ;
// To ease marshalling different kinds of touches that browser reports (all touches are listed in e.touches,
// only changed touches in e.changedTouches, and touches on target at a.targetTouches), mark a boolean in
// each Touch object so that we can later loop only once over all touches we see to marshall over to Wasm.
for ( var i = 0 ; i < et . length ; ++ i ) {
t = et [ i ] ;
// Browser might recycle the generated Touch objects between each frame (Firefox on Android), so reset any
// changed/target states we may have set from previous frame.
t . isChanged = t . onTarget = 0 ;
touches [ t . identifier ] = t ;
}
// Mark which touches are part of the changedTouches list.
for ( var i = 0 ; i < e . changedTouches . length ; ++ i ) {
t = e . changedTouches [ i ] ;
t . isChanged = 1 ;
touches [ t . identifier ] = t ;
}
// Mark which touches are part of the targetTouches list.
for ( var i = 0 ; i < e . targetTouches . length ; ++ i ) {
touches [ e . targetTouches [ i ] . identifier ] . onTarget = 1 ;
}
var touchEvent = JSEvents . touchEvent ;
HEAPF64 [ ( ( touchEvent ) >> 3 ) ] = e . timeStamp ;
var idx = touchEvent >> 2 ; // Pre-shift the ptr to index to HEAP32 to save code size
HEAP32 [ idx + 3 ] = e . ctrlKey ;
HEAP32 [ idx + 4 ] = e . shiftKey ;
HEAP32 [ idx + 5 ] = e . altKey ;
HEAP32 [ idx + 6 ] = e . metaKey ;
idx += 7 ; // Advance to the start of the touch array.
var targetRect = getBoundingClientRect ( target ) ;
var numTouches = 0 ;
for ( var i in touches ) {
t = touches [ i ] ;
HEAP32 [ idx + 0 ] = t . identifier ;
HEAP32 [ idx + 1 ] = t . screenX ;
HEAP32 [ idx + 2 ] = t . screenY ;
HEAP32 [ idx + 3 ] = t . clientX ;
HEAP32 [ idx + 4 ] = t . clientY ;
HEAP32 [ idx + 5 ] = t . pageX ;
HEAP32 [ idx + 6 ] = t . pageY ;
HEAP32 [ idx + 7 ] = t . isChanged ;
HEAP32 [ idx + 8 ] = t . onTarget ;
HEAP32 [ idx + 9 ] = t . clientX - targetRect . left ;
HEAP32 [ idx + 10 ] = t . clientY - targetRect . top ;
idx += 13 ;
if ( ++ numTouches > 31 ) {
break ;
}
}
HEAP32 [ ( ( ( touchEvent ) + ( 8 ) ) >> 2 ) ] = numTouches ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , touchEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : target ,
allowsDeferredCalls : eventTypeString == 'touchstart' || eventTypeString == 'touchend' ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : touchEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _touchcancel _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerTouchEventCallback ( target , userData , useCapture , callbackfunc , 25 , "touchcancel" , targetThread ) ;
}
function _emscripten _set _touchend _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerTouchEventCallback ( target , userData , useCapture , callbackfunc , 23 , "touchend" , targetThread ) ;
}
function _emscripten _set _touchmove _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerTouchEventCallback ( target , userData , useCapture , callbackfunc , 24 , "touchmove" , targetThread ) ;
}
function _emscripten _set _touchstart _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
return registerTouchEventCallback ( target , userData , useCapture , callbackfunc , 22 , "touchstart" , targetThread ) ;
}
function fillVisibilityChangeEventData ( eventStruct ) {
var visibilityStates = [ "hidden" , "visible" , "prerender" , "unloaded" ] ;
var visibilityState = visibilityStates . indexOf ( document . visibilityState ) ;
// Assigning a boolean to HEAP32 with expected type coercion.
/** @suppress{checkTypes} */
HEAP32 [ ( ( eventStruct ) >> 2 ) ] = document . hidden ;
HEAP32 [ ( ( ( eventStruct ) + ( 4 ) ) >> 2 ) ] = visibilityState ;
}
function registerVisibilityChangeEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . visibilityChangeEvent ) JSEvents . visibilityChangeEvent = _malloc ( 8 ) ;
var visibilityChangeEventHandlerFunc = function ( e = event ) {
var visibilityChangeEvent = JSEvents . visibilityChangeEvent ;
fillVisibilityChangeEventData ( visibilityChangeEvent ) ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , visibilityChangeEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : target ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : visibilityChangeEventHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _visibilitychange _callback _on _thread ( userData , useCapture , callbackfunc , targetThread ) {
if ( ! specialHTMLTargets [ 1 ] ) {
return - 4 ;
}
return registerVisibilityChangeEventCallback ( specialHTMLTargets [ 1 ] , userData , useCapture , callbackfunc , 21 , "visibilitychange" , targetThread ) ;
}
function registerWheelEventCallback ( target , userData , useCapture , callbackfunc , eventTypeId , eventTypeString , targetThread ) {
if ( ! JSEvents . wheelEvent ) JSEvents . wheelEvent = _malloc ( 104 ) ;
// The DOM Level 3 events spec event 'wheel'
var wheelHandlerFunc = function ( e = event ) {
var wheelEvent = JSEvents . wheelEvent ;
fillMouseEventData ( wheelEvent , e , target ) ;
HEAPF64 [ ( ( ( wheelEvent ) + ( 72 ) ) >> 3 ) ] = e [ "deltaX" ] ;
HEAPF64 [ ( ( ( wheelEvent ) + ( 80 ) ) >> 3 ) ] = e [ "deltaY" ] ;
HEAPF64 [ ( ( ( wheelEvent ) + ( 88 ) ) >> 3 ) ] = e [ "deltaZ" ] ;
HEAP32 [ ( ( ( wheelEvent ) + ( 96 ) ) >> 2 ) ] = e [ "deltaMode" ] ;
if ( getWasmTableEntry ( callbackfunc ) ( eventTypeId , wheelEvent , userData ) ) e . preventDefault ( ) ;
} ;
var eventHandler = {
target : target ,
allowsDeferredCalls : true ,
eventTypeString : eventTypeString ,
callbackfunc : callbackfunc ,
handlerFunc : wheelHandlerFunc ,
useCapture : useCapture
} ;
return JSEvents . registerOrRemoveHandler ( eventHandler ) ;
}
function _emscripten _set _wheel _callback _on _thread ( target , userData , useCapture , callbackfunc , targetThread ) {
target = findEventTarget ( target ) ;
if ( ! target ) return - 4 ;
if ( typeof target . onwheel != 'undefined' ) {
return registerWheelEventCallback ( target , userData , useCapture , callbackfunc , 9 , "wheel" , targetThread ) ;
} else {
return - 1 ;
}
}
function _emscripten _set _window _title ( title ) {
setWindowTitle ( UTF8ToString ( title ) ) ;
}
function _emscripten _sleep ( ) {
throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_sleep' ;
}
var ENV = { } ;
function getExecutableName ( ) {
return thisProgram || './this.program' ;
}
function getEnvStrings ( ) {
if ( ! getEnvStrings . strings ) {
// Default values.
// Browser language detection #8751
var lang = ( ( typeof navigator == 'object' && navigator . languages && navigator . languages [ 0 ] ) || 'C' ) . replace ( '-' , '_' ) + '.UTF-8' ;
var env = {
'USER' : 'web_user' ,
'LOGNAME' : 'web_user' ,
'PATH' : '/' ,
'PWD' : '/' ,
'HOME' : '/home/web_user' ,
'LANG' : lang ,
'_' : getExecutableName ( )
} ;
// Apply the user-provided values, if any.
for ( var x in ENV ) {
// x is a key in ENV; if ENV[x] is undefined, that means it was
// explicitly set to be so. We allow user code to do that to
// force variables with default values to remain unset.
if ( ENV [ x ] === undefined ) delete env [ x ] ;
else env [ x ] = ENV [ x ] ;
}
var strings = [ ] ;
for ( var x in env ) {
strings . push ( ` ${ x } = ${ env [ x ] } ` ) ;
}
getEnvStrings . strings = strings ;
}
return getEnvStrings . strings ;
}
function stringToAscii ( str , buffer ) {
for ( var i = 0 ; i < str . length ; ++ i ) {
assert ( str . charCodeAt ( i ) === ( str . charCodeAt ( i ) & 0xff ) ) ;
HEAP8 [ ( ( buffer ++ ) >> 0 ) ] = str . charCodeAt ( i ) ;
}
// Null-terminate the string
HEAP8 [ ( ( buffer ) >> 0 ) ] = 0 ;
}
function _environ _get ( _ _environ , environ _buf ) {
var bufSize = 0 ;
getEnvStrings ( ) . forEach ( function ( string , i ) {
var ptr = environ _buf + bufSize ;
HEAPU32 [ ( ( ( _ _environ ) + ( i * 4 ) ) >> 2 ) ] = ptr ;
stringToAscii ( string , ptr ) ;
bufSize += string . length + 1 ;
} ) ;
return 0 ;
}
function _environ _sizes _get ( penviron _count , penviron _buf _size ) {
var strings = getEnvStrings ( ) ;
HEAPU32 [ ( ( penviron _count ) >> 2 ) ] = strings . length ;
var bufSize = 0 ;
strings . forEach ( function ( string ) {
bufSize += string . length + 1 ;
} ) ;
HEAPU32 [ ( ( penviron _buf _size ) >> 2 ) ] = bufSize ;
return 0 ;
}
function _fd _close ( fd ) {
try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
FS . close ( stream ) ;
return 0 ;
} catch ( e ) {
if ( typeof FS == 'undefined' || ! ( e . name === 'ErrnoError' ) ) throw e ;
return e . errno ;
}
}
/** @param {number=} offset */
function doReadv ( stream , iov , iovcnt , offset ) {
var ret = 0 ;
for ( var i = 0 ; i < iovcnt ; i ++ ) {
var ptr = HEAPU32 [ ( ( iov ) >> 2 ) ] ;
var len = HEAPU32 [ ( ( ( iov ) + ( 4 ) ) >> 2 ) ] ;
iov += 8 ;
var curr = FS . read ( stream , HEAP8 , ptr , len , offset ) ;
if ( curr < 0 ) return - 1 ;
ret += curr ;
if ( curr < len ) break ; // nothing more to read
if ( typeof offset !== 'undefined' ) {
offset += curr ;
}
}
return ret ;
}
function _fd _read ( fd , iov , iovcnt , pnum ) {
try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
var num = doReadv ( stream , iov , iovcnt ) ;
HEAPU32 [ ( ( pnum ) >> 2 ) ] = num ;
return 0 ;
} catch ( e ) {
if ( typeof FS == 'undefined' || ! ( e . name === 'ErrnoError' ) ) throw e ;
return e . errno ;
}
}
function convertI32PairToI53Checked ( lo , hi ) {
assert ( lo == ( lo >>> 0 ) || lo == ( lo | 0 ) ) ; // lo should either be a i32 or a u32
assert ( hi === ( hi | 0 ) ) ; // hi should be a i32
return ( ( hi + 0x200000 ) >>> 0 < 0x400001 - ! ! lo ) ? ( lo >>> 0 ) + hi * 4294967296 : NaN ;
}
function _fd _seek ( fd , offset _low , offset _high , whence , newOffset ) {
try {
var offset = convertI32PairToI53Checked ( offset _low , offset _high ) ; if ( isNaN ( offset ) ) return 61 ;
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
FS . llseek ( stream , offset , whence ) ;
( tempI64 = [ stream . position >>> 0 , ( tempDouble = stream . position , ( + ( Math . abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( + ( Math . floor ( ( tempDouble ) / 4294967296.0 ) ) ) >>> 0 : ( ~ ~ ( ( + ( Math . ceil ( ( tempDouble - + ( ( ( ~ ~ ( tempDouble ) ) ) >>> 0 ) ) / 4294967296.0 ) ) ) ) ) >>> 0 ) : 0 ) ] , HEAP32 [ ( ( newOffset ) >> 2 ) ] = tempI64 [ 0 ] , HEAP32 [ ( ( ( newOffset ) + ( 4 ) ) >> 2 ) ] = tempI64 [ 1 ] ) ;
if ( stream . getdents && offset === 0 && whence === 0 ) stream . getdents = null ; // reset readdir state
return 0 ;
} catch ( e ) {
if ( typeof FS == 'undefined' || ! ( e . name === 'ErrnoError' ) ) throw e ;
return e . errno ;
}
}
/** @param {number=} offset */
function doWritev ( stream , iov , iovcnt , offset ) {
var ret = 0 ;
for ( var i = 0 ; i < iovcnt ; i ++ ) {
var ptr = HEAPU32 [ ( ( iov ) >> 2 ) ] ;
var len = HEAPU32 [ ( ( ( iov ) + ( 4 ) ) >> 2 ) ] ;
iov += 8 ;
var curr = FS . write ( stream , HEAP8 , ptr , len , offset ) ;
if ( curr < 0 ) return - 1 ;
ret += curr ;
if ( typeof offset !== 'undefined' ) {
offset += curr ;
}
}
return ret ;
}
function _fd _write ( fd , iov , iovcnt , pnum ) {
try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
var num = doWritev ( stream , iov , iovcnt ) ;
HEAPU32 [ ( ( pnum ) >> 2 ) ] = num ;
return 0 ;
} catch ( e ) {
if ( typeof FS == 'undefined' || ! ( e . name === 'ErrnoError' ) ) throw e ;
return e . errno ;
}
}
function isLeapYear ( year ) {
return year % 4 === 0 && ( year % 100 !== 0 || year % 400 === 0 ) ;
}
function arraySum ( array , index ) {
var sum = 0 ;
for ( var i = 0 ; i <= index ; sum += array [ i ++ ] ) {
// no-op
}
return sum ;
}
var MONTH _DAYS _LEAP = [ 31 , 29 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ] ;
var MONTH _DAYS _REGULAR = [ 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ] ;
function addDays ( date , days ) {
var newDate = new Date ( date . getTime ( ) ) ;
while ( days > 0 ) {
var leap = isLeapYear ( newDate . getFullYear ( ) ) ;
var currentMonth = newDate . getMonth ( ) ;
var daysInCurrentMonth = ( leap ? MONTH _DAYS _LEAP : MONTH _DAYS _REGULAR ) [ currentMonth ] ;
if ( days > daysInCurrentMonth - newDate . getDate ( ) ) {
// we spill over to next month
days -= ( daysInCurrentMonth - newDate . getDate ( ) + 1 ) ;
newDate . setDate ( 1 ) ;
if ( currentMonth < 11 ) {
newDate . setMonth ( currentMonth + 1 )
} else {
newDate . setMonth ( 0 ) ;
newDate . setFullYear ( newDate . getFullYear ( ) + 1 ) ;
}
} else {
// we stay in current month
newDate . setDate ( newDate . getDate ( ) + days ) ;
return newDate ;
}
}
return newDate ;
}
function writeArrayToMemory ( array , buffer ) {
assert ( array . length >= 0 , 'writeArrayToMemory array must have a length (should be an array or typed array)' )
HEAP8 . set ( array , buffer ) ;
}
function _strftime ( s , maxsize , format , tm ) {
// size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
var tm _zone = HEAP32 [ ( ( ( tm ) + ( 40 ) ) >> 2 ) ] ;
var date = {
tm _sec : HEAP32 [ ( ( tm ) >> 2 ) ] ,
tm _min : HEAP32 [ ( ( ( tm ) + ( 4 ) ) >> 2 ) ] ,
tm _hour : HEAP32 [ ( ( ( tm ) + ( 8 ) ) >> 2 ) ] ,
tm _mday : HEAP32 [ ( ( ( tm ) + ( 12 ) ) >> 2 ) ] ,
tm _mon : HEAP32 [ ( ( ( tm ) + ( 16 ) ) >> 2 ) ] ,
tm _year : HEAP32 [ ( ( ( tm ) + ( 20 ) ) >> 2 ) ] ,
tm _wday : HEAP32 [ ( ( ( tm ) + ( 24 ) ) >> 2 ) ] ,
tm _yday : HEAP32 [ ( ( ( tm ) + ( 28 ) ) >> 2 ) ] ,
tm _isdst : HEAP32 [ ( ( ( tm ) + ( 32 ) ) >> 2 ) ] ,
tm _gmtoff : HEAP32 [ ( ( ( tm ) + ( 36 ) ) >> 2 ) ] ,
tm _zone : tm _zone ? UTF8ToString ( tm _zone ) : ''
} ;
var pattern = UTF8ToString ( format ) ;
// expand format
var EXPANSION _RULES _1 = {
'%c' : '%a %b %d %H:%M:%S %Y' , // Replaced by the locale's appropriate date and time representation - e.g., Mon Aug 3 14:02:01 2013
'%D' : '%m/%d/%y' , // Equivalent to %m / %d / %y
'%F' : '%Y-%m-%d' , // Equivalent to %Y - %m - %d
'%h' : '%b' , // Equivalent to %b
'%r' : '%I:%M:%S %p' , // Replaced by the time in a.m. and p.m. notation
'%R' : '%H:%M' , // Replaced by the time in 24-hour notation
'%T' : '%H:%M:%S' , // Replaced by the time
'%x' : '%m/%d/%y' , // Replaced by the locale's appropriate date representation
'%X' : '%H:%M:%S' , // Replaced by the locale's appropriate time representation
// Modified Conversion Specifiers
'%Ec' : '%c' , // Replaced by the locale's alternative appropriate date and time representation.
'%EC' : '%C' , // Replaced by the name of the base year (period) in the locale's alternative representation.
'%Ex' : '%m/%d/%y' , // Replaced by the locale's alternative date representation.
'%EX' : '%H:%M:%S' , // Replaced by the locale's alternative time representation.
'%Ey' : '%y' , // Replaced by the offset from %EC (year only) in the locale's alternative representation.
'%EY' : '%Y' , // Replaced by the full alternative year representation.
'%Od' : '%d' , // Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading zeros if there is any alternative symbol for zero; otherwise, with leading <space> characters.
'%Oe' : '%e' , // Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading <space> characters.
'%OH' : '%H' , // Replaced by the hour (24-hour clock) using the locale's alternative numeric symbols.
'%OI' : '%I' , // Replaced by the hour (12-hour clock) using the locale's alternative numeric symbols.
'%Om' : '%m' , // Replaced by the month using the locale's alternative numeric symbols.
'%OM' : '%M' , // Replaced by the minutes using the locale's alternative numeric symbols.
'%OS' : '%S' , // Replaced by the seconds using the locale's alternative numeric symbols.
'%Ou' : '%u' , // Replaced by the weekday as a number in the locale's alternative representation (Monday=1).
'%OU' : '%U' , // Replaced by the week number of the year (Sunday as the first day of the week, rules corresponding to %U ) using the locale's alternative numeric symbols.
'%OV' : '%V' , // Replaced by the week number of the year (Monday as the first day of the week, rules corresponding to %V ) using the locale's alternative numeric symbols.
'%Ow' : '%w' , // Replaced by the number of the weekday (Sunday=0) using the locale's alternative numeric symbols.
'%OW' : '%W' , // Replaced by the week number of the year (Monday as the first day of the week) using the locale's alternative numeric symbols.
'%Oy' : '%y' , // Replaced by the year (offset from %C ) using the locale's alternative numeric symbols.
} ;
for ( var rule in EXPANSION _RULES _1 ) {
pattern = pattern . replace ( new RegExp ( rule , 'g' ) , EXPANSION _RULES _1 [ rule ] ) ;
}
var WEEKDAYS = [ 'Sunday' , 'Monday' , 'Tuesday' , 'Wednesday' , 'Thursday' , 'Friday' , 'Saturday' ] ;
var MONTHS = [ 'January' , 'February' , 'March' , 'April' , 'May' , 'June' , 'July' , 'August' , 'September' , 'October' , 'November' , 'December' ] ;
function leadingSomething ( value , digits , character ) {
var str = typeof value == 'number' ? value . toString ( ) : ( value || '' ) ;
while ( str . length < digits ) {
str = character [ 0 ] + str ;
}
return str ;
}
function leadingNulls ( value , digits ) {
return leadingSomething ( value , digits , '0' ) ;
}
function compareByDay ( date1 , date2 ) {
function sgn ( value ) {
return value < 0 ? - 1 : ( value > 0 ? 1 : 0 ) ;
}
var compare ;
if ( ( compare = sgn ( date1 . getFullYear ( ) - date2 . getFullYear ( ) ) ) === 0 ) {
if ( ( compare = sgn ( date1 . getMonth ( ) - date2 . getMonth ( ) ) ) === 0 ) {
compare = sgn ( date1 . getDate ( ) - date2 . getDate ( ) ) ;
}
}
return compare ;
}
function getFirstWeekStartDate ( janFourth ) {
switch ( janFourth . getDay ( ) ) {
case 0 : // Sunday
return new Date ( janFourth . getFullYear ( ) - 1 , 11 , 29 ) ;
case 1 : // Monday
return janFourth ;
case 2 : // Tuesday
return new Date ( janFourth . getFullYear ( ) , 0 , 3 ) ;
case 3 : // Wednesday
return new Date ( janFourth . getFullYear ( ) , 0 , 2 ) ;
case 4 : // Thursday
return new Date ( janFourth . getFullYear ( ) , 0 , 1 ) ;
case 5 : // Friday
return new Date ( janFourth . getFullYear ( ) - 1 , 11 , 31 ) ;
case 6 : // Saturday
return new Date ( janFourth . getFullYear ( ) - 1 , 11 , 30 ) ;
}
}
function getWeekBasedYear ( date ) {
var thisDate = addDays ( new Date ( date . tm _year + 1900 , 0 , 1 ) , date . tm _yday ) ;
var janFourthThisYear = new Date ( thisDate . getFullYear ( ) , 0 , 4 ) ;
var janFourthNextYear = new Date ( thisDate . getFullYear ( ) + 1 , 0 , 4 ) ;
var firstWeekStartThisYear = getFirstWeekStartDate ( janFourthThisYear ) ;
var firstWeekStartNextYear = getFirstWeekStartDate ( janFourthNextYear ) ;
if ( compareByDay ( firstWeekStartThisYear , thisDate ) <= 0 ) {
// this date is after the start of the first week of this year
if ( compareByDay ( firstWeekStartNextYear , thisDate ) <= 0 ) {
return thisDate . getFullYear ( ) + 1 ;
}
return thisDate . getFullYear ( ) ;
}
return thisDate . getFullYear ( ) - 1 ;
}
var EXPANSION _RULES _2 = {
'%a' : function ( date ) {
return WEEKDAYS [ date . tm _wday ] . substring ( 0 , 3 ) ;
} ,
'%A' : function ( date ) {
return WEEKDAYS [ date . tm _wday ] ;
} ,
'%b' : function ( date ) {
return MONTHS [ date . tm _mon ] . substring ( 0 , 3 ) ;
} ,
'%B' : function ( date ) {
return MONTHS [ date . tm _mon ] ;
} ,
'%C' : function ( date ) {
var year = date . tm _year + 1900 ;
return leadingNulls ( ( year / 100 ) | 0 , 2 ) ;
} ,
'%d' : function ( date ) {
return leadingNulls ( date . tm _mday , 2 ) ;
} ,
'%e' : function ( date ) {
return leadingSomething ( date . tm _mday , 2 , ' ' ) ;
} ,
'%g' : function ( date ) {
// %g, %G, and %V give values according to the ISO 8601:2000 standard week-based year.
// In this system, weeks begin on a Monday and week 1 of the year is the week that includes
// January 4th, which is also the week that includes the first Thursday of the year, and
// is also the first week that contains at least four days in the year.
// If the first Monday of January is the 2nd, 3rd, or 4th, the preceding days are part of
// the last week of the preceding year; thus, for Saturday 2nd January 1999,
// %G is replaced by 1998 and %V is replaced by 53. If December 29th, 30th,
// or 31st is a Monday, it and any following days are part of week 1 of the following year.
// Thus, for Tuesday 30th December 1997, %G is replaced by 1998 and %V is replaced by 01.
return getWeekBasedYear ( date ) . toString ( ) . substring ( 2 ) ;
} ,
'%G' : function ( date ) {
return getWeekBasedYear ( date ) ;
} ,
'%H' : function ( date ) {
return leadingNulls ( date . tm _hour , 2 ) ;
} ,
'%I' : function ( date ) {
var twelveHour = date . tm _hour ;
if ( twelveHour == 0 ) twelveHour = 12 ;
else if ( twelveHour > 12 ) twelveHour -= 12 ;
return leadingNulls ( twelveHour , 2 ) ;
} ,
'%j' : function ( date ) {
// Day of the year (001-366)
return leadingNulls ( date . tm _mday + arraySum ( isLeapYear ( date . tm _year + 1900 ) ? MONTH _DAYS _LEAP : MONTH _DAYS _REGULAR , date . tm _mon - 1 ) , 3 ) ;
} ,
'%m' : function ( date ) {
return leadingNulls ( date . tm _mon + 1 , 2 ) ;
} ,
'%M' : function ( date ) {
return leadingNulls ( date . tm _min , 2 ) ;
} ,
'%n' : function ( ) {
return '\n' ;
} ,
'%p' : function ( date ) {
if ( date . tm _hour >= 0 && date . tm _hour < 12 ) {
return 'AM' ;
}
return 'PM' ;
} ,
'%S' : function ( date ) {
return leadingNulls ( date . tm _sec , 2 ) ;
} ,
'%t' : function ( ) {
return '\t' ;
} ,
'%u' : function ( date ) {
return date . tm _wday || 7 ;
} ,
'%U' : function ( date ) {
var days = date . tm _yday + 7 - date . tm _wday ;
return leadingNulls ( Math . floor ( days / 7 ) , 2 ) ;
} ,
'%V' : function ( date ) {
// Replaced by the week number of the year (Monday as the first day of the week)
// as a decimal number [01,53]. If the week containing 1 January has four
// or more days in the new year, then it is considered week 1.
// Otherwise, it is the last week of the previous year, and the next week is week 1.
// Both January 4th and the first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
var val = Math . floor ( ( date . tm _yday + 7 - ( date . tm _wday + 6 ) % 7 ) / 7 ) ;
// If 1 Jan is just 1-3 days past Monday, the previous week
// is also in this year.
if ( ( date . tm _wday + 371 - date . tm _yday - 2 ) % 7 <= 2 ) {
val ++ ;
}
if ( ! val ) {
val = 52 ;
// If 31 December of prev year a Thursday, or Friday of a
// leap year, then the prev year has 53 weeks.
var dec31 = ( date . tm _wday + 7 - date . tm _yday - 1 ) % 7 ;
if ( dec31 == 4 || ( dec31 == 5 && isLeapYear ( date . tm _year % 400 - 1 ) ) ) {
val ++ ;
}
} else if ( val == 53 ) {
// If 1 January is not a Thursday, and not a Wednesday of a
// leap year, then this year has only 52 weeks.
var jan1 = ( date . tm _wday + 371 - date . tm _yday ) % 7 ;
if ( jan1 != 4 && ( jan1 != 3 || ! isLeapYear ( date . tm _year ) ) )
val = 1 ;
}
return leadingNulls ( val , 2 ) ;
} ,
'%w' : function ( date ) {
return date . tm _wday ;
} ,
'%W' : function ( date ) {
var days = date . tm _yday + 7 - ( ( date . tm _wday + 6 ) % 7 ) ;
return leadingNulls ( Math . floor ( days / 7 ) , 2 ) ;
} ,
'%y' : function ( date ) {
// Replaced by the last two digits of the year as a decimal number [00,99]. [ tm_year]
return ( date . tm _year + 1900 ) . toString ( ) . substring ( 2 ) ;
} ,
'%Y' : function ( date ) {
// Replaced by the year as a decimal number (for example, 1997). [ tm_year]
return date . tm _year + 1900 ;
} ,
'%z' : function ( date ) {
// Replaced by the offset from UTC in the ISO 8601:2000 standard format ( +hhmm or -hhmm ).
// For example, "-0430" means 4 hours 30 minutes behind UTC (west of Greenwich).
var off = date . tm _gmtoff ;
var ahead = off >= 0 ;
off = Math . abs ( off ) / 60 ;
// convert from minutes into hhmm format (which means 60 minutes = 100 units)
off = ( off / 60 ) * 100 + ( off % 60 ) ;
return ( ahead ? '+' : '-' ) + String ( "0000" + off ) . slice ( - 4 ) ;
} ,
'%Z' : function ( date ) {
return date . tm _zone ;
} ,
'%%' : function ( ) {
return '%' ;
}
} ;
// Replace %% with a pair of NULLs (which cannot occur in a C string), then
// re-inject them after processing.
pattern = pattern . replace ( /%%/g , '\0\0' )
for ( var rule in EXPANSION _RULES _2 ) {
if ( pattern . includes ( rule ) ) {
pattern = pattern . replace ( new RegExp ( rule , 'g' ) , EXPANSION _RULES _2 [ rule ] ( date ) ) ;
}
}
pattern = pattern . replace ( /\0\0/g , '%' )
var bytes = intArrayFromString ( pattern , false ) ;
if ( bytes . length > maxsize ) {
return 0 ;
}
writeArrayToMemory ( bytes , s ) ;
return bytes . length - 1 ;
}
function _strftime _l ( s , maxsize , format , tm , loc ) {
return _strftime ( s , maxsize , format , tm ) ; // no locale support yet
}
var FSNode = /** @constructor */ function ( parent , name , mode , rdev ) {
if ( ! parent ) {
parent = this ; // root node sets parent to itself
}
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 /*292*/ | 73 /*73*/ ;
var writeMode = 146 /*146*/ ;
Object . defineProperties ( FSNode . prototype , {
read : {
get : /** @this{FSNode} */ function ( ) {
return ( this . mode & readMode ) === readMode ;
} ,
set : /** @this{FSNode} */ function ( val ) {
val ? this . mode |= readMode : this . mode &= ~ readMode ;
}
} ,
write : {
get : /** @this{FSNode} */ function ( ) {
return ( this . mode & writeMode ) === writeMode ;
} ,
set : /** @this{FSNode} */ function ( val ) {
val ? this . mode |= writeMode : this . mode &= ~ writeMode ;
}
} ,
isFolder : {
get : /** @this{FSNode} */ function ( ) {
return FS . isDir ( this . mode ) ;
}
} ,
isDevice : {
get : /** @this{FSNode} */ function ( ) {
return FS . isChrdev ( this . mode ) ;
}
}
} ) ;
FS . FSNode = FSNode ;
FS . createPreloadedFile = FS _createPreloadedFile ;
FS . staticInit ( ) ; Module [ "FS_createPath" ] = FS . createPath ; Module [ "FS_createDataFile" ] = FS . createDataFile ; Module [ "FS_createPreloadedFile" ] = FS . createPreloadedFile ; Module [ "FS_unlink" ] = FS . unlink ; Module [ "FS_createLazyFile" ] = FS . createLazyFile ; Module [ "FS_createDevice" ] = FS . createDevice ; ;
ERRNO _CODES = {
'EPERM' : 63 ,
'ENOENT' : 44 ,
'ESRCH' : 71 ,
'EINTR' : 27 ,
'EIO' : 29 ,
'ENXIO' : 60 ,
'E2BIG' : 1 ,
'ENOEXEC' : 45 ,
'EBADF' : 8 ,
'ECHILD' : 12 ,
'EAGAIN' : 6 ,
'EWOULDBLOCK' : 6 ,
'ENOMEM' : 48 ,
'EACCES' : 2 ,
'EFAULT' : 21 ,
'ENOTBLK' : 105 ,
'EBUSY' : 10 ,
'EEXIST' : 20 ,
'EXDEV' : 75 ,
'ENODEV' : 43 ,
'ENOTDIR' : 54 ,
'EISDIR' : 31 ,
'EINVAL' : 28 ,
'ENFILE' : 41 ,
'EMFILE' : 33 ,
'ENOTTY' : 59 ,
'ETXTBSY' : 74 ,
'EFBIG' : 22 ,
'ENOSPC' : 51 ,
'ESPIPE' : 70 ,
'EROFS' : 69 ,
'EMLINK' : 34 ,
'EPIPE' : 64 ,
'EDOM' : 18 ,
'ERANGE' : 68 ,
'ENOMSG' : 49 ,
'EIDRM' : 24 ,
'ECHRNG' : 106 ,
'EL2NSYNC' : 156 ,
'EL3HLT' : 107 ,
'EL3RST' : 108 ,
'ELNRNG' : 109 ,
'EUNATCH' : 110 ,
'ENOCSI' : 111 ,
'EL2HLT' : 112 ,
'EDEADLK' : 16 ,
'ENOLCK' : 46 ,
'EBADE' : 113 ,
'EBADR' : 114 ,
'EXFULL' : 115 ,
'ENOANO' : 104 ,
'EBADRQC' : 103 ,
'EBADSLT' : 102 ,
'EDEADLOCK' : 16 ,
'EBFONT' : 101 ,
'ENOSTR' : 100 ,
'ENODATA' : 116 ,
'ETIME' : 117 ,
'ENOSR' : 118 ,
'ENONET' : 119 ,
'ENOPKG' : 120 ,
'EREMOTE' : 121 ,
'ENOLINK' : 47 ,
'EADV' : 122 ,
'ESRMNT' : 123 ,
'ECOMM' : 124 ,
'EPROTO' : 65 ,
'EMULTIHOP' : 36 ,
'EDOTDOT' : 125 ,
'EBADMSG' : 9 ,
'ENOTUNIQ' : 126 ,
'EBADFD' : 127 ,
'EREMCHG' : 128 ,
'ELIBACC' : 129 ,
'ELIBBAD' : 130 ,
'ELIBSCN' : 131 ,
'ELIBMAX' : 132 ,
'ELIBEXEC' : 133 ,
'ENOSYS' : 52 ,
'ENOTEMPTY' : 55 ,
'ENAMETOOLONG' : 37 ,
'ELOOP' : 32 ,
'EOPNOTSUPP' : 138 ,
'EPFNOSUPPORT' : 139 ,
'ECONNRESET' : 15 ,
'ENOBUFS' : 42 ,
'EAFNOSUPPORT' : 5 ,
'EPROTOTYPE' : 67 ,
'ENOTSOCK' : 57 ,
'ENOPROTOOPT' : 50 ,
'ESHUTDOWN' : 140 ,
'ECONNREFUSED' : 14 ,
'EADDRINUSE' : 3 ,
'ECONNABORTED' : 13 ,
'ENETUNREACH' : 40 ,
'ENETDOWN' : 38 ,
'ETIMEDOUT' : 73 ,
'EHOSTDOWN' : 142 ,
'EHOSTUNREACH' : 23 ,
'EINPROGRESS' : 26 ,
'EALREADY' : 7 ,
'EDESTADDRREQ' : 17 ,
'EMSGSIZE' : 35 ,
'EPROTONOSUPPORT' : 66 ,
'ESOCKTNOSUPPORT' : 137 ,
'EADDRNOTAVAIL' : 4 ,
'ENETRESET' : 39 ,
'EISCONN' : 30 ,
'ENOTCONN' : 53 ,
'ETOOMANYREFS' : 141 ,
'EUSERS' : 136 ,
'EDQUOT' : 19 ,
'ESTALE' : 72 ,
'ENOTSUP' : 138 ,
'ENOMEDIUM' : 148 ,
'EILSEQ' : 25 ,
'EOVERFLOW' : 61 ,
'ECANCELED' : 11 ,
'ENOTRECOVERABLE' : 56 ,
'EOWNERDEAD' : 62 ,
'ESTRPIPE' : 135 ,
} ; ;
// exports
Module [ "requestFullscreen" ] = function Module _requestFullscreen ( lockPointer , resizeCanvas ) { Browser . requestFullscreen ( lockPointer , resizeCanvas ) } ;
Module [ "requestFullScreen" ] = function Module _requestFullScreen ( ) { Browser . requestFullScreen ( ) } ;
Module [ "requestAnimationFrame" ] = function Module _requestAnimationFrame ( func ) { Browser . requestAnimationFrame ( func ) } ;
Module [ "setCanvasSize" ] = function Module _setCanvasSize ( width , height , noUpdates ) { Browser . setCanvasSize ( width , height , noUpdates ) } ;
Module [ "pauseMainLoop" ] = function Module _pauseMainLoop ( ) { Browser . mainLoop . pause ( ) } ;
Module [ "resumeMainLoop" ] = function Module _resumeMainLoop ( ) { Browser . mainLoop . resume ( ) } ;
Module [ "getUserMedia" ] = function Module _getUserMedia ( ) { Browser . getUserMedia ( ) } ;
Module [ "createContext" ] = function Module _createContext ( canvas , useWebGL , setInModule , webGLContextAttributes ) { return Browser . createContext ( canvas , useWebGL , setInModule , webGLContextAttributes ) } ;
var preloadedImages = { } ;
var preloadedAudios = { } ; ;
var GLctx ; ;
for ( var i = 0 ; i < 32 ; ++ i ) tempFixedLengthArray . push ( new Array ( i ) ) ; ;
// include: base64Utils.js
// Copied from https://github.com/strophe/strophejs/blob/e06d027/src/polyfills.js#L149
// This code was written by Tyler Akins and has been placed in the
// public domain. It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
/ * *
* Decodes a base64 string .
* @ param { string } input The string to decode .
* /
var decodeBase64 = typeof atob == 'function' ? atob : function ( input ) {
var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' ;
var output = '' ;
var chr1 , chr2 , chr3 ;
var enc1 , enc2 , enc3 , enc4 ;
var i = 0 ;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input = input . replace ( /[^A-Za-z0-9\+\/\=]/g , '' ) ;
do {
enc1 = keyStr . indexOf ( input . charAt ( i ++ ) ) ;
enc2 = keyStr . indexOf ( input . charAt ( i ++ ) ) ;
enc3 = keyStr . indexOf ( input . charAt ( i ++ ) ) ;
enc4 = keyStr . indexOf ( input . charAt ( i ++ ) ) ;
chr1 = ( enc1 << 2 ) | ( enc2 >> 4 ) ;
chr2 = ( ( enc2 & 15 ) << 4 ) | ( enc3 >> 2 ) ;
chr3 = ( ( enc3 & 3 ) << 6 ) | enc4 ;
output = output + String . fromCharCode ( chr1 ) ;
if ( enc3 !== 64 ) {
output = output + String . fromCharCode ( chr2 ) ;
}
if ( enc4 !== 64 ) {
output = output + String . fromCharCode ( chr3 ) ;
}
} while ( i < input . length ) ;
return output ;
} ;
// Converts a string of base64 into a byte array.
// Throws error on invalid input.
function intArrayFromBase64 ( s ) {
if ( typeof ENVIRONMENT _IS _NODE == 'boolean' && ENVIRONMENT _IS _NODE ) {
var buf = Buffer . from ( s , 'base64' ) ;
return new Uint8Array ( buf [ 'buffer' ] , buf [ 'byteOffset' ] , buf [ 'byteLength' ] ) ;
}
try {
var decoded = decodeBase64 ( s ) ;
var bytes = new Uint8Array ( decoded . length ) ;
for ( var i = 0 ; i < decoded . length ; ++ i ) {
bytes [ i ] = decoded . charCodeAt ( i ) ;
}
return bytes ;
} catch ( _ ) {
throw new Error ( 'Converting base64 string to bytes failed.' ) ;
}
}
// If filename is a base64 data URI, parses and returns data (Buffer on node,
// Uint8Array otherwise). If filename is not a base64 data URI, returns undefined.
function tryParseAsDataURI ( filename ) {
if ( ! isDataURI ( filename ) ) {
return ;
}
return intArrayFromBase64 ( filename . slice ( dataURIPrefix . length ) ) ;
}
// end include: base64Utils.js
function checkIncomingModuleAPI ( ) {
ignoredModuleProp ( 'fetchSettings' ) ;
}
var wasmImports = {
"__assert_fail" : _ _ _assert _fail ,
"__cxa_throw" : _ _ _cxa _throw ,
"__syscall_fcntl64" : _ _ _syscall _fcntl64 ,
"__syscall_ioctl" : _ _ _syscall _ioctl ,
"__syscall_openat" : _ _ _syscall _openat ,
"_emscripten_get_now_is_monotonic" : _ _emscripten _get _now _is _monotonic ,
"_emscripten_throw_longjmp" : _ _emscripten _throw _longjmp ,
"abort" : _abort ,
"eglBindAPI" : _eglBindAPI ,
"eglChooseConfig" : _eglChooseConfig ,
"eglCreateContext" : _eglCreateContext ,
"eglCreateWindowSurface" : _eglCreateWindowSurface ,
"eglDestroyContext" : _eglDestroyContext ,
"eglDestroySurface" : _eglDestroySurface ,
"eglGetConfigAttrib" : _eglGetConfigAttrib ,
"eglGetDisplay" : _eglGetDisplay ,
"eglGetError" : _eglGetError ,
"eglInitialize" : _eglInitialize ,
"eglMakeCurrent" : _eglMakeCurrent ,
"eglQueryString" : _eglQueryString ,
"eglSwapBuffers" : _eglSwapBuffers ,
"eglSwapInterval" : _eglSwapInterval ,
"eglTerminate" : _eglTerminate ,
"eglWaitGL" : _eglWaitGL ,
"eglWaitNative" : _eglWaitNative ,
"emscripten_asm_const_int" : _emscripten _asm _const _int ,
"emscripten_asm_const_int_sync_on_main_thread" : _emscripten _asm _const _int _sync _on _main _thread ,
"emscripten_cancel_main_loop" : _emscripten _cancel _main _loop ,
"emscripten_date_now" : _emscripten _date _now ,
"emscripten_exit_fullscreen" : _emscripten _exit _fullscreen ,
"emscripten_exit_pointerlock" : _emscripten _exit _pointerlock ,
"emscripten_get_device_pixel_ratio" : _emscripten _get _device _pixel _ratio ,
"emscripten_get_element_css_size" : _emscripten _get _element _css _size ,
"emscripten_get_gamepad_status" : _emscripten _get _gamepad _status ,
"emscripten_get_now" : _emscripten _get _now ,
"emscripten_get_num_gamepads" : _emscripten _get _num _gamepads ,
"emscripten_get_screen_size" : _emscripten _get _screen _size ,
"emscripten_glActiveTexture" : _emscripten _glActiveTexture ,
"emscripten_glAttachShader" : _emscripten _glAttachShader ,
"emscripten_glBeginQuery" : _emscripten _glBeginQuery ,
"emscripten_glBeginQueryEXT" : _emscripten _glBeginQueryEXT ,
"emscripten_glBeginTransformFeedback" : _emscripten _glBeginTransformFeedback ,
"emscripten_glBindAttribLocation" : _emscripten _glBindAttribLocation ,
"emscripten_glBindBuffer" : _emscripten _glBindBuffer ,
"emscripten_glBindBufferBase" : _emscripten _glBindBufferBase ,
"emscripten_glBindBufferRange" : _emscripten _glBindBufferRange ,
"emscripten_glBindFramebuffer" : _emscripten _glBindFramebuffer ,
"emscripten_glBindRenderbuffer" : _emscripten _glBindRenderbuffer ,
"emscripten_glBindSampler" : _emscripten _glBindSampler ,
"emscripten_glBindTexture" : _emscripten _glBindTexture ,
"emscripten_glBindTransformFeedback" : _emscripten _glBindTransformFeedback ,
"emscripten_glBindVertexArray" : _emscripten _glBindVertexArray ,
"emscripten_glBindVertexArrayOES" : _emscripten _glBindVertexArrayOES ,
"emscripten_glBlendColor" : _emscripten _glBlendColor ,
"emscripten_glBlendEquation" : _emscripten _glBlendEquation ,
"emscripten_glBlendEquationSeparate" : _emscripten _glBlendEquationSeparate ,
"emscripten_glBlendFunc" : _emscripten _glBlendFunc ,
"emscripten_glBlendFuncSeparate" : _emscripten _glBlendFuncSeparate ,
"emscripten_glBlitFramebuffer" : _emscripten _glBlitFramebuffer ,
"emscripten_glBufferData" : _emscripten _glBufferData ,
"emscripten_glBufferSubData" : _emscripten _glBufferSubData ,
"emscripten_glCheckFramebufferStatus" : _emscripten _glCheckFramebufferStatus ,
"emscripten_glClear" : _emscripten _glClear ,
"emscripten_glClearBufferfi" : _emscripten _glClearBufferfi ,
"emscripten_glClearBufferfv" : _emscripten _glClearBufferfv ,
"emscripten_glClearBufferiv" : _emscripten _glClearBufferiv ,
"emscripten_glClearBufferuiv" : _emscripten _glClearBufferuiv ,
"emscripten_glClearColor" : _emscripten _glClearColor ,
"emscripten_glClearDepthf" : _emscripten _glClearDepthf ,
"emscripten_glClearStencil" : _emscripten _glClearStencil ,
"emscripten_glClientWaitSync" : _emscripten _glClientWaitSync ,
"emscripten_glColorMask" : _emscripten _glColorMask ,
"emscripten_glCompileShader" : _emscripten _glCompileShader ,
"emscripten_glCompressedTexImage2D" : _emscripten _glCompressedTexImage2D ,
"emscripten_glCompressedTexImage3D" : _emscripten _glCompressedTexImage3D ,
"emscripten_glCompressedTexSubImage2D" : _emscripten _glCompressedTexSubImage2D ,
"emscripten_glCompressedTexSubImage3D" : _emscripten _glCompressedTexSubImage3D ,
"emscripten_glCopyBufferSubData" : _emscripten _glCopyBufferSubData ,
"emscripten_glCopyTexImage2D" : _emscripten _glCopyTexImage2D ,
"emscripten_glCopyTexSubImage2D" : _emscripten _glCopyTexSubImage2D ,
"emscripten_glCopyTexSubImage3D" : _emscripten _glCopyTexSubImage3D ,
"emscripten_glCreateProgram" : _emscripten _glCreateProgram ,
"emscripten_glCreateShader" : _emscripten _glCreateShader ,
"emscripten_glCullFace" : _emscripten _glCullFace ,
"emscripten_glDeleteBuffers" : _emscripten _glDeleteBuffers ,
"emscripten_glDeleteFramebuffers" : _emscripten _glDeleteFramebuffers ,
"emscripten_glDeleteProgram" : _emscripten _glDeleteProgram ,
"emscripten_glDeleteQueries" : _emscripten _glDeleteQueries ,
"emscripten_glDeleteQueriesEXT" : _emscripten _glDeleteQueriesEXT ,
"emscripten_glDeleteRenderbuffers" : _emscripten _glDeleteRenderbuffers ,
"emscripten_glDeleteSamplers" : _emscripten _glDeleteSamplers ,
"emscripten_glDeleteShader" : _emscripten _glDeleteShader ,
"emscripten_glDeleteSync" : _emscripten _glDeleteSync ,
"emscripten_glDeleteTextures" : _emscripten _glDeleteTextures ,
"emscripten_glDeleteTransformFeedbacks" : _emscripten _glDeleteTransformFeedbacks ,
"emscripten_glDeleteVertexArrays" : _emscripten _glDeleteVertexArrays ,
"emscripten_glDeleteVertexArraysOES" : _emscripten _glDeleteVertexArraysOES ,
"emscripten_glDepthFunc" : _emscripten _glDepthFunc ,
"emscripten_glDepthMask" : _emscripten _glDepthMask ,
"emscripten_glDepthRangef" : _emscripten _glDepthRangef ,
"emscripten_glDetachShader" : _emscripten _glDetachShader ,
"emscripten_glDisable" : _emscripten _glDisable ,
"emscripten_glDisableVertexAttribArray" : _emscripten _glDisableVertexAttribArray ,
"emscripten_glDrawArrays" : _emscripten _glDrawArrays ,
"emscripten_glDrawArraysInstanced" : _emscripten _glDrawArraysInstanced ,
"emscripten_glDrawArraysInstancedANGLE" : _emscripten _glDrawArraysInstancedANGLE ,
"emscripten_glDrawArraysInstancedARB" : _emscripten _glDrawArraysInstancedARB ,
"emscripten_glDrawArraysInstancedEXT" : _emscripten _glDrawArraysInstancedEXT ,
"emscripten_glDrawArraysInstancedNV" : _emscripten _glDrawArraysInstancedNV ,
"emscripten_glDrawBuffers" : _emscripten _glDrawBuffers ,
"emscripten_glDrawBuffersEXT" : _emscripten _glDrawBuffersEXT ,
"emscripten_glDrawBuffersWEBGL" : _emscripten _glDrawBuffersWEBGL ,
"emscripten_glDrawElements" : _emscripten _glDrawElements ,
"emscripten_glDrawElementsInstanced" : _emscripten _glDrawElementsInstanced ,
"emscripten_glDrawElementsInstancedANGLE" : _emscripten _glDrawElementsInstancedANGLE ,
"emscripten_glDrawElementsInstancedARB" : _emscripten _glDrawElementsInstancedARB ,
"emscripten_glDrawElementsInstancedEXT" : _emscripten _glDrawElementsInstancedEXT ,
"emscripten_glDrawElementsInstancedNV" : _emscripten _glDrawElementsInstancedNV ,
"emscripten_glDrawRangeElements" : _emscripten _glDrawRangeElements ,
"emscripten_glEnable" : _emscripten _glEnable ,
"emscripten_glEnableVertexAttribArray" : _emscripten _glEnableVertexAttribArray ,
"emscripten_glEndQuery" : _emscripten _glEndQuery ,
"emscripten_glEndQueryEXT" : _emscripten _glEndQueryEXT ,
"emscripten_glEndTransformFeedback" : _emscripten _glEndTransformFeedback ,
"emscripten_glFenceSync" : _emscripten _glFenceSync ,
"emscripten_glFinish" : _emscripten _glFinish ,
"emscripten_glFlush" : _emscripten _glFlush ,
"emscripten_glFramebufferRenderbuffer" : _emscripten _glFramebufferRenderbuffer ,
"emscripten_glFramebufferTexture2D" : _emscripten _glFramebufferTexture2D ,
"emscripten_glFramebufferTextureLayer" : _emscripten _glFramebufferTextureLayer ,
"emscripten_glFrontFace" : _emscripten _glFrontFace ,
"emscripten_glGenBuffers" : _emscripten _glGenBuffers ,
"emscripten_glGenFramebuffers" : _emscripten _glGenFramebuffers ,
"emscripten_glGenQueries" : _emscripten _glGenQueries ,
"emscripten_glGenQueriesEXT" : _emscripten _glGenQueriesEXT ,
"emscripten_glGenRenderbuffers" : _emscripten _glGenRenderbuffers ,
"emscripten_glGenSamplers" : _emscripten _glGenSamplers ,
"emscripten_glGenTextures" : _emscripten _glGenTextures ,
"emscripten_glGenTransformFeedbacks" : _emscripten _glGenTransformFeedbacks ,
"emscripten_glGenVertexArrays" : _emscripten _glGenVertexArrays ,
"emscripten_glGenVertexArraysOES" : _emscripten _glGenVertexArraysOES ,
"emscripten_glGenerateMipmap" : _emscripten _glGenerateMipmap ,
"emscripten_glGetActiveAttrib" : _emscripten _glGetActiveAttrib ,
"emscripten_glGetActiveUniform" : _emscripten _glGetActiveUniform ,
"emscripten_glGetActiveUniformBlockName" : _emscripten _glGetActiveUniformBlockName ,
"emscripten_glGetActiveUniformBlockiv" : _emscripten _glGetActiveUniformBlockiv ,
"emscripten_glGetActiveUniformsiv" : _emscripten _glGetActiveUniformsiv ,
"emscripten_glGetAttachedShaders" : _emscripten _glGetAttachedShaders ,
"emscripten_glGetAttribLocation" : _emscripten _glGetAttribLocation ,
"emscripten_glGetBooleanv" : _emscripten _glGetBooleanv ,
"emscripten_glGetBufferParameteri64v" : _emscripten _glGetBufferParameteri64v ,
"emscripten_glGetBufferParameteriv" : _emscripten _glGetBufferParameteriv ,
"emscripten_glGetError" : _emscripten _glGetError ,
"emscripten_glGetFloatv" : _emscripten _glGetFloatv ,
"emscripten_glGetFragDataLocation" : _emscripten _glGetFragDataLocation ,
"emscripten_glGetFramebufferAttachmentParameteriv" : _emscripten _glGetFramebufferAttachmentParameteriv ,
"emscripten_glGetInteger64i_v" : _emscripten _glGetInteger64i _v ,
"emscripten_glGetInteger64v" : _emscripten _glGetInteger64v ,
"emscripten_glGetIntegeri_v" : _emscripten _glGetIntegeri _v ,
"emscripten_glGetIntegerv" : _emscripten _glGetIntegerv ,
"emscripten_glGetInternalformativ" : _emscripten _glGetInternalformativ ,
"emscripten_glGetProgramBinary" : _emscripten _glGetProgramBinary ,
"emscripten_glGetProgramInfoLog" : _emscripten _glGetProgramInfoLog ,
"emscripten_glGetProgramiv" : _emscripten _glGetProgramiv ,
"emscripten_glGetQueryObjecti64vEXT" : _emscripten _glGetQueryObjecti64vEXT ,
"emscripten_glGetQueryObjectivEXT" : _emscripten _glGetQueryObjectivEXT ,
"emscripten_glGetQueryObjectui64vEXT" : _emscripten _glGetQueryObjectui64vEXT ,
"emscripten_glGetQueryObjectuiv" : _emscripten _glGetQueryObjectuiv ,
"emscripten_glGetQueryObjectuivEXT" : _emscripten _glGetQueryObjectuivEXT ,
"emscripten_glGetQueryiv" : _emscripten _glGetQueryiv ,
"emscripten_glGetQueryivEXT" : _emscripten _glGetQueryivEXT ,
"emscripten_glGetRenderbufferParameteriv" : _emscripten _glGetRenderbufferParameteriv ,
"emscripten_glGetSamplerParameterfv" : _emscripten _glGetSamplerParameterfv ,
"emscripten_glGetSamplerParameteriv" : _emscripten _glGetSamplerParameteriv ,
"emscripten_glGetShaderInfoLog" : _emscripten _glGetShaderInfoLog ,
"emscripten_glGetShaderPrecisionFormat" : _emscripten _glGetShaderPrecisionFormat ,
"emscripten_glGetShaderSource" : _emscripten _glGetShaderSource ,
"emscripten_glGetShaderiv" : _emscripten _glGetShaderiv ,
"emscripten_glGetString" : _emscripten _glGetString ,
"emscripten_glGetStringi" : _emscripten _glGetStringi ,
"emscripten_glGetSynciv" : _emscripten _glGetSynciv ,
"emscripten_glGetTexParameterfv" : _emscripten _glGetTexParameterfv ,
"emscripten_glGetTexParameteriv" : _emscripten _glGetTexParameteriv ,
"emscripten_glGetTransformFeedbackVarying" : _emscripten _glGetTransformFeedbackVarying ,
"emscripten_glGetUniformBlockIndex" : _emscripten _glGetUniformBlockIndex ,
"emscripten_glGetUniformIndices" : _emscripten _glGetUniformIndices ,
"emscripten_glGetUniformLocation" : _emscripten _glGetUniformLocation ,
"emscripten_glGetUniformfv" : _emscripten _glGetUniformfv ,
"emscripten_glGetUniformiv" : _emscripten _glGetUniformiv ,
"emscripten_glGetUniformuiv" : _emscripten _glGetUniformuiv ,
"emscripten_glGetVertexAttribIiv" : _emscripten _glGetVertexAttribIiv ,
"emscripten_glGetVertexAttribIuiv" : _emscripten _glGetVertexAttribIuiv ,
"emscripten_glGetVertexAttribPointerv" : _emscripten _glGetVertexAttribPointerv ,
"emscripten_glGetVertexAttribfv" : _emscripten _glGetVertexAttribfv ,
"emscripten_glGetVertexAttribiv" : _emscripten _glGetVertexAttribiv ,
"emscripten_glHint" : _emscripten _glHint ,
"emscripten_glInvalidateFramebuffer" : _emscripten _glInvalidateFramebuffer ,
"emscripten_glInvalidateSubFramebuffer" : _emscripten _glInvalidateSubFramebuffer ,
"emscripten_glIsBuffer" : _emscripten _glIsBuffer ,
"emscripten_glIsEnabled" : _emscripten _glIsEnabled ,
"emscripten_glIsFramebuffer" : _emscripten _glIsFramebuffer ,
"emscripten_glIsProgram" : _emscripten _glIsProgram ,
"emscripten_glIsQuery" : _emscripten _glIsQuery ,
"emscripten_glIsQueryEXT" : _emscripten _glIsQueryEXT ,
"emscripten_glIsRenderbuffer" : _emscripten _glIsRenderbuffer ,
"emscripten_glIsSampler" : _emscripten _glIsSampler ,
"emscripten_glIsShader" : _emscripten _glIsShader ,
"emscripten_glIsSync" : _emscripten _glIsSync ,
"emscripten_glIsTexture" : _emscripten _glIsTexture ,
"emscripten_glIsTransformFeedback" : _emscripten _glIsTransformFeedback ,
"emscripten_glIsVertexArray" : _emscripten _glIsVertexArray ,
"emscripten_glIsVertexArrayOES" : _emscripten _glIsVertexArrayOES ,
"emscripten_glLineWidth" : _emscripten _glLineWidth ,
"emscripten_glLinkProgram" : _emscripten _glLinkProgram ,
"emscripten_glPauseTransformFeedback" : _emscripten _glPauseTransformFeedback ,
"emscripten_glPixelStorei" : _emscripten _glPixelStorei ,
"emscripten_glPolygonOffset" : _emscripten _glPolygonOffset ,
"emscripten_glProgramBinary" : _emscripten _glProgramBinary ,
"emscripten_glProgramParameteri" : _emscripten _glProgramParameteri ,
"emscripten_glQueryCounterEXT" : _emscripten _glQueryCounterEXT ,
"emscripten_glReadBuffer" : _emscripten _glReadBuffer ,
"emscripten_glReadPixels" : _emscripten _glReadPixels ,
"emscripten_glReleaseShaderCompiler" : _emscripten _glReleaseShaderCompiler ,
"emscripten_glRenderbufferStorage" : _emscripten _glRenderbufferStorage ,
"emscripten_glRenderbufferStorageMultisample" : _emscripten _glRenderbufferStorageMultisample ,
"emscripten_glResumeTransformFeedback" : _emscripten _glResumeTransformFeedback ,
"emscripten_glSampleCoverage" : _emscripten _glSampleCoverage ,
"emscripten_glSamplerParameterf" : _emscripten _glSamplerParameterf ,
"emscripten_glSamplerParameterfv" : _emscripten _glSamplerParameterfv ,
"emscripten_glSamplerParameteri" : _emscripten _glSamplerParameteri ,
"emscripten_glSamplerParameteriv" : _emscripten _glSamplerParameteriv ,
"emscripten_glScissor" : _emscripten _glScissor ,
"emscripten_glShaderBinary" : _emscripten _glShaderBinary ,
"emscripten_glShaderSource" : _emscripten _glShaderSource ,
"emscripten_glStencilFunc" : _emscripten _glStencilFunc ,
"emscripten_glStencilFuncSeparate" : _emscripten _glStencilFuncSeparate ,
"emscripten_glStencilMask" : _emscripten _glStencilMask ,
"emscripten_glStencilMaskSeparate" : _emscripten _glStencilMaskSeparate ,
"emscripten_glStencilOp" : _emscripten _glStencilOp ,
"emscripten_glStencilOpSeparate" : _emscripten _glStencilOpSeparate ,
"emscripten_glTexImage2D" : _emscripten _glTexImage2D ,
"emscripten_glTexImage3D" : _emscripten _glTexImage3D ,
"emscripten_glTexParameterf" : _emscripten _glTexParameterf ,
"emscripten_glTexParameterfv" : _emscripten _glTexParameterfv ,
"emscripten_glTexParameteri" : _emscripten _glTexParameteri ,
"emscripten_glTexParameteriv" : _emscripten _glTexParameteriv ,
"emscripten_glTexStorage2D" : _emscripten _glTexStorage2D ,
"emscripten_glTexStorage3D" : _emscripten _glTexStorage3D ,
"emscripten_glTexSubImage2D" : _emscripten _glTexSubImage2D ,
"emscripten_glTexSubImage3D" : _emscripten _glTexSubImage3D ,
"emscripten_glTransformFeedbackVaryings" : _emscripten _glTransformFeedbackVaryings ,
"emscripten_glUniform1f" : _emscripten _glUniform1f ,
"emscripten_glUniform1fv" : _emscripten _glUniform1fv ,
"emscripten_glUniform1i" : _emscripten _glUniform1i ,
"emscripten_glUniform1iv" : _emscripten _glUniform1iv ,
"emscripten_glUniform1ui" : _emscripten _glUniform1ui ,
"emscripten_glUniform1uiv" : _emscripten _glUniform1uiv ,
"emscripten_glUniform2f" : _emscripten _glUniform2f ,
"emscripten_glUniform2fv" : _emscripten _glUniform2fv ,
"emscripten_glUniform2i" : _emscripten _glUniform2i ,
"emscripten_glUniform2iv" : _emscripten _glUniform2iv ,
"emscripten_glUniform2ui" : _emscripten _glUniform2ui ,
"emscripten_glUniform2uiv" : _emscripten _glUniform2uiv ,
"emscripten_glUniform3f" : _emscripten _glUniform3f ,
"emscripten_glUniform3fv" : _emscripten _glUniform3fv ,
"emscripten_glUniform3i" : _emscripten _glUniform3i ,
"emscripten_glUniform3iv" : _emscripten _glUniform3iv ,
"emscripten_glUniform3ui" : _emscripten _glUniform3ui ,
"emscripten_glUniform3uiv" : _emscripten _glUniform3uiv ,
"emscripten_glUniform4f" : _emscripten _glUniform4f ,
"emscripten_glUniform4fv" : _emscripten _glUniform4fv ,
"emscripten_glUniform4i" : _emscripten _glUniform4i ,
"emscripten_glUniform4iv" : _emscripten _glUniform4iv ,
"emscripten_glUniform4ui" : _emscripten _glUniform4ui ,
"emscripten_glUniform4uiv" : _emscripten _glUniform4uiv ,
"emscripten_glUniformBlockBinding" : _emscripten _glUniformBlockBinding ,
"emscripten_glUniformMatrix2fv" : _emscripten _glUniformMatrix2fv ,
"emscripten_glUniformMatrix2x3fv" : _emscripten _glUniformMatrix2x3fv ,
"emscripten_glUniformMatrix2x4fv" : _emscripten _glUniformMatrix2x4fv ,
"emscripten_glUniformMatrix3fv" : _emscripten _glUniformMatrix3fv ,
"emscripten_glUniformMatrix3x2fv" : _emscripten _glUniformMatrix3x2fv ,
"emscripten_glUniformMatrix3x4fv" : _emscripten _glUniformMatrix3x4fv ,
"emscripten_glUniformMatrix4fv" : _emscripten _glUniformMatrix4fv ,
"emscripten_glUniformMatrix4x2fv" : _emscripten _glUniformMatrix4x2fv ,
"emscripten_glUniformMatrix4x3fv" : _emscripten _glUniformMatrix4x3fv ,
"emscripten_glUseProgram" : _emscripten _glUseProgram ,
"emscripten_glValidateProgram" : _emscripten _glValidateProgram ,
"emscripten_glVertexAttrib1f" : _emscripten _glVertexAttrib1f ,
"emscripten_glVertexAttrib1fv" : _emscripten _glVertexAttrib1fv ,
"emscripten_glVertexAttrib2f" : _emscripten _glVertexAttrib2f ,
"emscripten_glVertexAttrib2fv" : _emscripten _glVertexAttrib2fv ,
"emscripten_glVertexAttrib3f" : _emscripten _glVertexAttrib3f ,
"emscripten_glVertexAttrib3fv" : _emscripten _glVertexAttrib3fv ,
"emscripten_glVertexAttrib4f" : _emscripten _glVertexAttrib4f ,
"emscripten_glVertexAttrib4fv" : _emscripten _glVertexAttrib4fv ,
"emscripten_glVertexAttribDivisor" : _emscripten _glVertexAttribDivisor ,
"emscripten_glVertexAttribDivisorANGLE" : _emscripten _glVertexAttribDivisorANGLE ,
"emscripten_glVertexAttribDivisorARB" : _emscripten _glVertexAttribDivisorARB ,
"emscripten_glVertexAttribDivisorEXT" : _emscripten _glVertexAttribDivisorEXT ,
"emscripten_glVertexAttribDivisorNV" : _emscripten _glVertexAttribDivisorNV ,
"emscripten_glVertexAttribI4i" : _emscripten _glVertexAttribI4i ,
"emscripten_glVertexAttribI4iv" : _emscripten _glVertexAttribI4iv ,
"emscripten_glVertexAttribI4ui" : _emscripten _glVertexAttribI4ui ,
"emscripten_glVertexAttribI4uiv" : _emscripten _glVertexAttribI4uiv ,
"emscripten_glVertexAttribIPointer" : _emscripten _glVertexAttribIPointer ,
"emscripten_glVertexAttribPointer" : _emscripten _glVertexAttribPointer ,
"emscripten_glViewport" : _emscripten _glViewport ,
"emscripten_glWaitSync" : _emscripten _glWaitSync ,
"emscripten_has_asyncify" : _emscripten _has _asyncify ,
"emscripten_memcpy_big" : _emscripten _memcpy _big ,
"emscripten_request_fullscreen_strategy" : _emscripten _request _fullscreen _strategy ,
"emscripten_request_pointerlock" : _emscripten _request _pointerlock ,
"emscripten_resize_heap" : _emscripten _resize _heap ,
"emscripten_sample_gamepad_data" : _emscripten _sample _gamepad _data ,
"emscripten_set_beforeunload_callback_on_thread" : _emscripten _set _beforeunload _callback _on _thread ,
"emscripten_set_blur_callback_on_thread" : _emscripten _set _blur _callback _on _thread ,
"emscripten_set_canvas_element_size" : _emscripten _set _canvas _element _size ,
"emscripten_set_element_css_size" : _emscripten _set _element _css _size ,
"emscripten_set_focus_callback_on_thread" : _emscripten _set _focus _callback _on _thread ,
"emscripten_set_fullscreenchange_callback_on_thread" : _emscripten _set _fullscreenchange _callback _on _thread ,
"emscripten_set_gamepadconnected_callback_on_thread" : _emscripten _set _gamepadconnected _callback _on _thread ,
"emscripten_set_gamepaddisconnected_callback_on_thread" : _emscripten _set _gamepaddisconnected _callback _on _thread ,
"emscripten_set_keydown_callback_on_thread" : _emscripten _set _keydown _callback _on _thread ,
"emscripten_set_keypress_callback_on_thread" : _emscripten _set _keypress _callback _on _thread ,
"emscripten_set_keyup_callback_on_thread" : _emscripten _set _keyup _callback _on _thread ,
"emscripten_set_main_loop" : _emscripten _set _main _loop ,
"emscripten_set_mousedown_callback_on_thread" : _emscripten _set _mousedown _callback _on _thread ,
"emscripten_set_mouseenter_callback_on_thread" : _emscripten _set _mouseenter _callback _on _thread ,
"emscripten_set_mouseleave_callback_on_thread" : _emscripten _set _mouseleave _callback _on _thread ,
"emscripten_set_mousemove_callback_on_thread" : _emscripten _set _mousemove _callback _on _thread ,
"emscripten_set_mouseup_callback_on_thread" : _emscripten _set _mouseup _callback _on _thread ,
"emscripten_set_pointerlockchange_callback_on_thread" : _emscripten _set _pointerlockchange _callback _on _thread ,
"emscripten_set_resize_callback_on_thread" : _emscripten _set _resize _callback _on _thread ,
"emscripten_set_touchcancel_callback_on_thread" : _emscripten _set _touchcancel _callback _on _thread ,
"emscripten_set_touchend_callback_on_thread" : _emscripten _set _touchend _callback _on _thread ,
"emscripten_set_touchmove_callback_on_thread" : _emscripten _set _touchmove _callback _on _thread ,
"emscripten_set_touchstart_callback_on_thread" : _emscripten _set _touchstart _callback _on _thread ,
"emscripten_set_visibilitychange_callback_on_thread" : _emscripten _set _visibilitychange _callback _on _thread ,
"emscripten_set_wheel_callback_on_thread" : _emscripten _set _wheel _callback _on _thread ,
"emscripten_set_window_title" : _emscripten _set _window _title ,
"emscripten_sleep" : _emscripten _sleep ,
"environ_get" : _environ _get ,
"environ_sizes_get" : _environ _sizes _get ,
"fd_close" : _fd _close ,
"fd_read" : _fd _read ,
"fd_seek" : _fd _seek ,
"fd_write" : _fd _write ,
"glAttachShader" : _glAttachShader ,
"glBindBuffer" : _glBindBuffer ,
"glBindTexture" : _glBindTexture ,
"glBindVertexArrayOES" : _glBindVertexArrayOES ,
"glBlendFunc" : _glBlendFunc ,
"glBufferData" : _glBufferData ,
"glClear" : _glClear ,
"glClearColor" : _glClearColor ,
"glCompileShader" : _glCompileShader ,
"glCreateProgram" : _glCreateProgram ,
"glCreateShader" : _glCreateShader ,
"glDeleteProgram" : _glDeleteProgram ,
"glDeleteShader" : _glDeleteShader ,
"glDeleteTextures" : _glDeleteTextures ,
"glDrawArrays" : _glDrawArrays ,
"glEnable" : _glEnable ,
"glEnableVertexAttribArray" : _glEnableVertexAttribArray ,
"glGenBuffers" : _glGenBuffers ,
"glGenTextures" : _glGenTextures ,
"glGenVertexArraysOES" : _glGenVertexArraysOES ,
"glGetShaderInfoLog" : _glGetShaderInfoLog ,
"glLinkProgram" : _glLinkProgram ,
"glReadPixels" : _glReadPixels ,
"glShaderSource" : _glShaderSource ,
"glTexImage2D" : _glTexImage2D ,
"glTexParameteri" : _glTexParameteri ,
"glUseProgram" : _glUseProgram ,
"glVertexAttribPointer" : _glVertexAttribPointer ,
"glViewport" : _glViewport ,
"invoke_ii" : invoke _ii ,
"invoke_iii" : invoke _iii ,
"invoke_iiii" : invoke _iiii ,
"invoke_iiiii" : invoke _iiiii ,
"invoke_vi" : invoke _vi ,
"invoke_vii" : invoke _vii ,
"invoke_viii" : invoke _viii ,
"invoke_viiii" : invoke _viiii ,
"strftime_l" : _strftime _l
} ;
var asm = createWasm ( ) ;
/** @type {function(...*):?} */
var _ _ _wasm _call _ctors = createExportWrapper ( "__wasm_call_ctors" ) ;
/** @type {function(...*):?} */
var _olc _OnPageUnload = Module [ "_olc_OnPageUnload" ] = createExportWrapper ( "olc_OnPageUnload" ) ;
/** @type {function(...*):?} */
var _olc _PGE _UpdateWindowSize = Module [ "_olc_PGE_UpdateWindowSize" ] = createExportWrapper ( "olc_PGE_UpdateWindowSize" ) ;
/** @type {function(...*):?} */
var _malloc = createExportWrapper ( "malloc" ) ;
/** @type {function(...*):?} */
var _free = createExportWrapper ( "free" ) ;
/** @type {function(...*):?} */
var _main = Module [ "_main" ] = createExportWrapper ( "main" ) ;
/** @type {function(...*):?} */
var _ _ _errno _location = createExportWrapper ( "__errno_location" ) ;
/** @type {function(...*):?} */
var _fflush = Module [ "_fflush" ] = createExportWrapper ( "fflush" ) ;
/** @type {function(...*):?} */
var _setThrew = createExportWrapper ( "setThrew" ) ;
/** @type {function(...*):?} */
var _emscripten _stack _init = function ( ) {
return ( _emscripten _stack _init = Module [ "asm" ] [ "emscripten_stack_init" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _emscripten _stack _get _free = function ( ) {
return ( _emscripten _stack _get _free = Module [ "asm" ] [ "emscripten_stack_get_free" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _emscripten _stack _get _base = function ( ) {
return ( _emscripten _stack _get _base = Module [ "asm" ] [ "emscripten_stack_get_base" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _emscripten _stack _get _end = function ( ) {
return ( _emscripten _stack _get _end = Module [ "asm" ] [ "emscripten_stack_get_end" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var stackSave = createExportWrapper ( "stackSave" ) ;
/** @type {function(...*):?} */
var stackRestore = createExportWrapper ( "stackRestore" ) ;
/** @type {function(...*):?} */
var stackAlloc = createExportWrapper ( "stackAlloc" ) ;
/** @type {function(...*):?} */
var _emscripten _stack _get _current = function ( ) {
return ( _emscripten _stack _get _current = Module [ "asm" ] [ "emscripten_stack_get_current" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _ _ _cxa _is _pointer _type = createExportWrapper ( "__cxa_is_pointer_type" ) ;
/** @type {function(...*):?} */
var dynCall _viijii = Module [ "dynCall_viijii" ] = createExportWrapper ( "dynCall_viijii" ) ;
/** @type {function(...*):?} */
var dynCall _jijii = Module [ "dynCall_jijii" ] = createExportWrapper ( "dynCall_jijii" ) ;
/** @type {function(...*):?} */
var dynCall _jiji = Module [ "dynCall_jiji" ] = createExportWrapper ( "dynCall_jiji" ) ;
/** @type {function(...*):?} */
var dynCall _ji = Module [ "dynCall_ji" ] = createExportWrapper ( "dynCall_ji" ) ;
/** @type {function(...*):?} */
var dynCall _iiiiij = Module [ "dynCall_iiiiij" ] = createExportWrapper ( "dynCall_iiiiij" ) ;
/** @type {function(...*):?} */
var dynCall _iiiiijj = Module [ "dynCall_iiiiijj" ] = createExportWrapper ( "dynCall_iiiiijj" ) ;
/** @type {function(...*):?} */
var dynCall _iiiiiijj = Module [ "dynCall_iiiiiijj" ] = createExportWrapper ( "dynCall_iiiiiijj" ) ;
function invoke _vi ( index , a1 ) {
var sp = stackSave ( ) ;
try {
getWasmTableEntry ( index ) ( a1 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiii ( index , a1 , a2 , a3 , a4 ) {
var sp = stackSave ( ) ;
try {
return getWasmTableEntry ( index ) ( a1 , a2 , a3 , a4 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _ii ( index , a1 ) {
var sp = stackSave ( ) ;
try {
return getWasmTableEntry ( index ) ( a1 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiii ( index , a1 , a2 , a3 ) {
var sp = stackSave ( ) ;
try {
return getWasmTableEntry ( index ) ( a1 , a2 , a3 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viii ( index , a1 , a2 , a3 ) {
var sp = stackSave ( ) ;
try {
getWasmTableEntry ( index ) ( a1 , a2 , a3 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iii ( index , a1 , a2 ) {
var sp = stackSave ( ) ;
try {
return getWasmTableEntry ( index ) ( a1 , a2 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _vii ( index , a1 , a2 ) {
var sp = stackSave ( ) ;
try {
getWasmTableEntry ( index ) ( a1 , a2 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiii ( index , a1 , a2 , a3 , a4 ) {
var sp = stackSave ( ) ;
try {
getWasmTableEntry ( index ) ( a1 , a2 , a3 , a4 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
// include: postamble.js
// === Auto-generated postamble setup entry stuff ===
Module [ "addRunDependency" ] = addRunDependency ;
Module [ "removeRunDependency" ] = removeRunDependency ;
Module [ "FS_createPath" ] = FS . createPath ;
Module [ "FS_createDataFile" ] = FS . createDataFile ;
Module [ "FS_createLazyFile" ] = FS . createLazyFile ;
Module [ "FS_createDevice" ] = FS . createDevice ;
Module [ "FS_unlink" ] = FS . unlink ;
Module [ "FS_createPreloadedFile" ] = FS . createPreloadedFile ;
var missingLibrarySymbols = [
'ydayFromDate' ,
'inetPton4' ,
'inetNtop4' ,
'inetPton6' ,
'inetNtop6' ,
'readSockaddr' ,
'writeSockaddr' ,
'getHostByName' ,
'traverseStack' ,
'getCallstack' ,
'emscriptenLog' ,
'convertPCtoSourceLocation' ,
'jstoi_s' ,
'getDynCaller' ,
'runtimeKeepalivePush' ,
'runtimeKeepalivePop' ,
'asmjsMangle' ,
'HandleAllocator' ,
'getNativeTypeSize' ,
'STACK_SIZE' ,
'STACK_ALIGN' ,
'POINTER_SIZE' ,
'ASSERTIONS' ,
'writeI53ToI64Clamped' ,
'writeI53ToI64Signaling' ,
'writeI53ToU64Clamped' ,
'writeI53ToU64Signaling' ,
'convertU32PairToI53' ,
'getCFunc' ,
'ccall' ,
'cwrap' ,
'uleb128Encode' ,
'sigToWasmTypes' ,
'generateFuncType' ,
'convertJsFunctionToWasm' ,
'getEmptyTableSlot' ,
'updateTableMap' ,
'getFunctionAddress' ,
'addFunction' ,
'removeFunction' ,
'reallyNegative' ,
'unSign' ,
'strLen' ,
'reSign' ,
'formatString' ,
'intArrayToString' ,
'AsciiToString' ,
'UTF16ToString' ,
'stringToUTF16' ,
'lengthBytesUTF16' ,
'UTF32ToString' ,
'stringToUTF32' ,
'lengthBytesUTF32' ,
'fillDeviceOrientationEventData' ,
'registerDeviceOrientationEventCallback' ,
'fillDeviceMotionEventData' ,
'registerDeviceMotionEventCallback' ,
'screenOrientation' ,
'fillOrientationChangeEventData' ,
'registerOrientationChangeEventCallback' ,
'hideEverythingExceptGivenElement' ,
'restoreHiddenElements' ,
'softFullscreenResizeWebGLRenderTarget' ,
'registerPointerlockErrorEventCallback' ,
'fillBatteryEventData' ,
'battery' ,
'registerBatteryEventCallback' ,
'jsStackTrace' ,
'stackTrace' ,
'checkWasiClock' ,
'wasiRightsToMuslOFlags' ,
'wasiOFlagsToMuslOFlags' ,
'createDyncallWrapper' ,
'setImmediateWrapped' ,
'clearImmediateWrapped' ,
'polyfillSetImmediate' ,
'getPromise' ,
'makePromise' ,
'idsToPromises' ,
'makePromiseCallback' ,
'getSocketFromFD' ,
'getSocketAddress' ,
'_setNetworkCallback' ,
'writeGLArray' ,
'registerWebGlEventCallback' ,
'runAndAbortIfError' ,
'GLFW_Window' ,
'ALLOC_NORMAL' ,
'ALLOC_STACK' ,
'allocate' ,
'writeStringToMemory' ,
'writeAsciiToMemory' ,
] ;
missingLibrarySymbols . forEach ( missingLibrarySymbol )
var unexportedSymbols = [
'run' ,
'addOnPreRun' ,
'addOnInit' ,
'addOnPreMain' ,
'addOnExit' ,
'addOnPostRun' ,
'FS_createFolder' ,
'FS_createLink' ,
'out' ,
'err' ,
'callMain' ,
'abort' ,
'keepRuntimeAlive' ,
'wasmMemory' ,
'stackAlloc' ,
'stackSave' ,
'stackRestore' ,
'getTempRet0' ,
'setTempRet0' ,
'writeStackCookie' ,
'checkStackCookie' ,
'ptrToString' ,
'zeroMemory' ,
'exitJS' ,
'getHeapMax' ,
'emscripten_realloc_buffer' ,
'ENV' ,
'MONTH_DAYS_REGULAR' ,
'MONTH_DAYS_LEAP' ,
'MONTH_DAYS_REGULAR_CUMULATIVE' ,
'MONTH_DAYS_LEAP_CUMULATIVE' ,
'isLeapYear' ,
'arraySum' ,
'addDays' ,
'ERRNO_CODES' ,
'ERRNO_MESSAGES' ,
'setErrNo' ,
'DNS' ,
'Protocols' ,
'Sockets' ,
'initRandomFill' ,
'randomFill' ,
'timers' ,
'warnOnce' ,
'UNWIND_CACHE' ,
'readEmAsmArgsArray' ,
'readEmAsmArgs' ,
'runEmAsmFunction' ,
'runMainThreadEmAsm' ,
'jstoi_q' ,
'getExecutableName' ,
'listenOnce' ,
'autoResumeAudioContext' ,
'dynCallLegacy' ,
'dynCall' ,
'handleException' ,
'callUserCallback' ,
'maybeExit' ,
'safeSetTimeout' ,
'asyncLoad' ,
'alignMemory' ,
'mmapAlloc' ,
'writeI53ToI64' ,
'readI53FromI64' ,
'readI53FromU64' ,
'convertI32PairToI53' ,
'convertI32PairToI53Checked' ,
'freeTableIndexes' ,
'functionsInTableMap' ,
'setValue' ,
'getValue' ,
'PATH' ,
'PATH_FS' ,
'UTF8Decoder' ,
'UTF8ArrayToString' ,
'UTF8ToString' ,
'stringToUTF8Array' ,
'stringToUTF8' ,
'lengthBytesUTF8' ,
'intArrayFromString' ,
'stringToAscii' ,
'UTF16Decoder' ,
'stringToNewUTF8' ,
'stringToUTF8OnStack' ,
'writeArrayToMemory' ,
'JSEvents' ,
'registerKeyEventCallback' ,
'specialHTMLTargets' ,
'maybeCStringToJsString' ,
'findEventTarget' ,
'findCanvasEventTarget' ,
'getBoundingClientRect' ,
'fillMouseEventData' ,
'registerMouseEventCallback' ,
'registerWheelEventCallback' ,
'registerUiEventCallback' ,
'registerFocusEventCallback' ,
'fillFullscreenChangeEventData' ,
'registerFullscreenChangeEventCallback' ,
'JSEvents_requestFullscreen' ,
'JSEvents_resizeCanvasForFullscreen' ,
'registerRestoreOldStyle' ,
'setLetterbox' ,
'currentFullscreenStrategy' ,
'restoreOldWindowedStyle' ,
'doRequestFullscreen' ,
'fillPointerlockChangeEventData' ,
'registerPointerlockChangeEventCallback' ,
'requestPointerLock' ,
'fillVisibilityChangeEventData' ,
'registerVisibilityChangeEventCallback' ,
'registerTouchEventCallback' ,
'fillGamepadEventData' ,
'registerGamepadEventCallback' ,
'registerBeforeUnloadEventCallback' ,
'setCanvasElementSize' ,
'getCanvasElementSize' ,
'demangle' ,
'demangleAll' ,
'ExitStatus' ,
'getEnvStrings' ,
'doReadv' ,
'doWritev' ,
'dlopenMissingError' ,
'promiseMap' ,
'uncaughtExceptionCount' ,
'exceptionLast' ,
'exceptionCaught' ,
'ExceptionInfo' ,
'Browser' ,
'setMainLoop' ,
'wget' ,
'SYSCALLS' ,
'preloadPlugins' ,
'FS_modeStringToFlags' ,
'FS_getMode' ,
'FS' ,
'MEMFS' ,
'TTY' ,
'PIPEFS' ,
'SOCKFS' ,
'tempFixedLengthArray' ,
'miniTempWebGLFloatBuffers' ,
'miniTempWebGLIntBuffers' ,
'heapObjectForWebGLType' ,
'heapAccessShiftForWebGLHeap' ,
'webgl_enable_WEBGL_multi_draw' ,
'GL' ,
'emscriptenWebGLGet' ,
'computeUnpackAlignedImageSize' ,
'colorChannelsInGlTextureFormat' ,
'emscriptenWebGLGetTexPixelData' ,
'__glGenObject' ,
'emscriptenWebGLGetUniform' ,
'webglGetUniformLocation' ,
'webglPrepareUniformLocationsBeforeFirstUse' ,
'webglGetLeftBracePos' ,
'emscriptenWebGLGetVertexAttrib' ,
'__glGetActiveAttribOrUniform' ,
'emscripten_webgl_power_preferences' ,
'AL' ,
'GLUT' ,
'EGL' ,
'GLEW' ,
'IDBStore' ,
'GLFW' ,
'emscriptenWebGLGetIndexed' ,
'webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance' ,
'webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance' ,
'allocateUTF8' ,
'allocateUTF8OnStack' ,
] ;
unexportedSymbols . forEach ( unexportedRuntimeSymbol ) ;
var calledRun ;
dependenciesFulfilled = function runCaller ( ) {
// If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
if ( ! calledRun ) run ( ) ;
if ( ! calledRun ) dependenciesFulfilled = runCaller ; // try this again later, after new deps are fulfilled
} ;
function callMain ( ) {
assert ( runDependencies == 0 , 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])' ) ;
assert ( _ _ATPRERUN _ _ . length == 0 , 'cannot call main when preRun functions remain to be called' ) ;
var entryFunction = _main ;
var argc = 0 ;
var argv = 0 ;
try {
var ret = entryFunction ( argc , argv ) ;
// if we're not running an evented main loop, it's time to exit
exitJS ( ret , /* implicit = */ true ) ;
return ret ;
}
catch ( e ) {
return handleException ( e ) ;
}
}
function stackCheckInit ( ) {
// This is normally called automatically during __wasm_call_ctors but need to
// get these values before even running any of the ctors so we call it redundantly
// here.
_emscripten _stack _init ( ) ;
// TODO(sbc): Move writeStackCookie to native to to avoid this.
writeStackCookie ( ) ;
}
function run ( ) {
if ( runDependencies > 0 ) {
return ;
}
stackCheckInit ( ) ;
preRun ( ) ;
// a preRun added a dependency, run will be called later
if ( runDependencies > 0 ) {
return ;
}
function doRun ( ) {
// run may have just been called through dependencies being fulfilled just in this very frame,
// or while the async setStatus time below was happening
if ( calledRun ) return ;
calledRun = true ;
Module [ 'calledRun' ] = true ;
if ( ABORT ) return ;
initRuntime ( ) ;
preMain ( ) ;
if ( Module [ 'onRuntimeInitialized' ] ) Module [ 'onRuntimeInitialized' ] ( ) ;
if ( shouldRunNow ) callMain ( ) ;
postRun ( ) ;
}
if ( Module [ 'setStatus' ] ) {
Module [ 'setStatus' ] ( 'Running...' ) ;
setTimeout ( function ( ) {
setTimeout ( function ( ) {
Module [ 'setStatus' ] ( '' ) ;
} , 1 ) ;
doRun ( ) ;
} , 1 ) ;
} else
{
doRun ( ) ;
}
checkStackCookie ( ) ;
}
function checkUnflushedContent ( ) {
// Compiler settings do not allow exiting the runtime, so flushing
// the streams is not possible. but in ASSERTIONS mode we check
// if there was something to flush, and if so tell the user they
// should request that the runtime be exitable.
// Normally we would not even include flush() at all, but in ASSERTIONS
// builds we do so just for this check, and here we see if there is any
// content to flush, that is, we check if there would have been
// something a non-ASSERTIONS build would have not seen.
// How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
// mode (which has its own special function for this; otherwise, all
// the code is inside libc)
var oldOut = out ;
var oldErr = err ;
var has = false ;
out = err = ( x ) => {
has = true ;
}
try { // it doesn't matter if it fails
_fflush ( 0 ) ;
// also flush in the JS FS layer
[ 'stdout' , 'stderr' ] . forEach ( function ( name ) {
var info = FS . analyzePath ( '/dev/' + name ) ;
if ( ! info ) return ;
var stream = info . object ;
var rdev = stream . rdev ;
var tty = TTY . ttys [ rdev ] ;
if ( tty && tty . output && tty . output . length ) {
has = true ;
}
} ) ;
} catch ( e ) { }
out = oldOut ;
err = oldErr ;
if ( has ) {
warnOnce ( 'stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.' ) ;
}
}
if ( Module [ 'preInit' ] ) {
if ( typeof Module [ 'preInit' ] == 'function' ) Module [ 'preInit' ] = [ Module [ 'preInit' ] ] ;
while ( Module [ 'preInit' ] . length > 0 ) {
Module [ 'preInit' ] . pop ( ) ( ) ;
}
}
// shouldRunNow refers to calling main(), not run().
var shouldRunNow = true ;
if ( Module [ 'noInitialRun' ] ) shouldRunNow = false ;
run ( ) ;
// end include: postamble.js