2019-12-07 23:20:01 +00:00
var cmoc = ( function ( ) {
var _scriptDir = typeof document !== 'undefined' && document . currentScript ? document . currentScript . src : undefined ;
if ( typeof _ _filename !== 'undefined' ) _scriptDir = _scriptDir || _ _filename ;
return (
function ( cmoc ) {
cmoc = cmoc || { } ;
2020-06-08 21:36:33 +00:00
// 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 cmoc !== 'undefined' ? cmoc : { } ;
// Set up the promise that indicates the Module is initialized
var readyPromiseResolve , readyPromiseReject ;
Module [ 'ready' ] = new Promise ( function ( resolve , reject ) {
readyPromiseResolve = resolve ;
readyPromiseReject = reject ;
} ) ;
// --pre-jses are emitted after the Module integration code, so that they can
// refer to Module (if they choose; they can also define Module)
// {{PRE_JSES}}
// 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 = { } ;
var key ;
for ( key in Module ) {
if ( Module . hasOwnProperty ( key ) ) {
moduleOverrides [ key ] = Module [ key ] ;
}
}
var arguments _ = [ ] ;
var thisProgram = './this.program' ;
var quit _ = function ( status , toThrow ) {
throw toThrow ;
} ;
// Determine the runtime environment we are in. You can customize this by
// setting the ENVIRONMENT setting at compile time (see settings.js).
var ENVIRONMENT _IS _WEB = false ;
var ENVIRONMENT _IS _WORKER = false ;
var ENVIRONMENT _IS _NODE = false ;
var ENVIRONMENT _IS _SHELL = false ;
ENVIRONMENT _IS _WEB = typeof window === 'object' ;
ENVIRONMENT _IS _WORKER = typeof importScripts === 'function' ;
// N.b. Electron.js environment is simultaneously a NODE-environment, but
// also a web environment.
ENVIRONMENT _IS _NODE = typeof process === 'object' && typeof process . versions === 'object' && typeof process . versions . node === 'string' ;
ENVIRONMENT _IS _SHELL = ! ENVIRONMENT _IS _WEB && ! ENVIRONMENT _IS _NODE && ! ENVIRONMENT _IS _WORKER ;
// `/` 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 ;
var nodeFS ;
var nodePath ;
if ( ENVIRONMENT _IS _NODE ) {
if ( ENVIRONMENT _IS _WORKER ) {
scriptDirectory = require ( 'path' ) . dirname ( scriptDirectory ) + '/' ;
} else {
scriptDirectory = _ _dirname + '/' ;
}
read _ = function shell _read ( filename , binary ) {
if ( ! nodeFS ) nodeFS = require ( 'fs' ) ;
if ( ! nodePath ) nodePath = require ( 'path' ) ;
filename = nodePath [ 'normalize' ] ( filename ) ;
return nodeFS [ 'readFileSync' ] ( filename , binary ? null : 'utf8' ) ;
} ;
readBinary = function readBinary ( filename ) {
var ret = read _ ( filename , true ) ;
if ( ! ret . buffer ) {
ret = new Uint8Array ( ret ) ;
}
assert ( ret . buffer ) ;
return ret ;
} ;
if ( process [ 'argv' ] . length > 1 ) {
thisProgram = process [ 'argv' ] [ 1 ] . replace ( /\\/g , '/' ) ;
}
arguments _ = process [ 'argv' ] . slice ( 2 ) ;
// MODULARIZE will export the module in the proper place outside, we don't need to export here
process [ 'on' ] ( 'uncaughtException' , function ( ex ) {
// suppress ExitStatus exceptions from showing an error
if ( ! ( ex instanceof ExitStatus ) ) {
throw ex ;
}
} ) ;
process [ 'on' ] ( 'unhandledRejection' , abort ) ;
quit _ = function ( status ) {
process [ 'exit' ] ( status ) ;
} ;
Module [ 'inspect' ] = function ( ) { return '[Emscripten Module object]' ; } ;
} else
if ( ENVIRONMENT _IS _SHELL ) {
if ( typeof read != 'undefined' ) {
read _ = function shell _read ( f ) {
return read ( f ) ;
} ;
}
readBinary = function readBinary ( f ) {
var data ;
if ( typeof readbuffer === 'function' ) {
return new Uint8Array ( readbuffer ( f ) ) ;
}
data = read ( f , 'binary' ) ;
assert ( typeof data === 'object' ) ;
return data ;
} ;
if ( typeof scriptArgs != 'undefined' ) {
arguments _ = scriptArgs ;
} else if ( typeof arguments != 'undefined' ) {
arguments _ = arguments ;
}
if ( typeof quit === 'function' ) {
quit _ = function ( status ) {
quit ( status ) ;
} ;
}
if ( typeof print !== 'undefined' ) {
// 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 ( document . currentScript ) { // web
scriptDirectory = document . currentScript . src ;
}
// When MODULARIZE, this JS may be executed later, after document.currentScript
// is gone, so we saved it, and we use it here instead of any other info.
if ( _scriptDir ) {
scriptDirectory = _scriptDir ;
}
// 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 . indexOf ( 'blob:' ) !== 0 ) {
scriptDirectory = scriptDirectory . substr ( 0 , scriptDirectory . lastIndexOf ( '/' ) + 1 ) ;
} else {
scriptDirectory = '' ;
}
// Differentiate the Web Worker from the Node Worker case, as reading must
// be done differently.
{
read _ = function shell _read ( url ) {
var xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , url , false ) ;
xhr . send ( null ) ;
return xhr . responseText ;
} ;
if ( ENVIRONMENT _IS _WORKER ) {
readBinary = function readBinary ( url ) {
var xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , url , false ) ;
xhr . responseType = 'arraybuffer' ;
xhr . send ( null ) ;
return new Uint8Array ( /** @type{!ArrayBuffer} */ ( xhr . response ) ) ;
} ;
}
readAsync = function readAsync ( url , onload , onerror ) {
var xhr = new XMLHttpRequest ( ) ;
xhr . open ( 'GET' , url , true ) ;
xhr . responseType = 'arraybuffer' ;
xhr . onload = function xhr _onload ( ) {
if ( xhr . status == 200 || ( xhr . status == 0 && xhr . response ) ) { // file URLs can return 0
onload ( xhr . response ) ;
return ;
}
onerror ( ) ;
} ;
xhr . onerror = onerror ;
xhr . send ( null ) ;
} ;
}
setWindowTitle = function ( title ) { document . title = title } ;
} else
{
}
// Set up the out() and err() hooks, which are how we can print to stdout or
// stderr, respectively.
var out = Module [ 'print' ] || console . log . bind ( console ) ;
var err = Module [ 'printErr' ] || console . warn . bind ( console ) ;
// Merge back in the overrides
for ( key in moduleOverrides ) {
if ( moduleOverrides . hasOwnProperty ( key ) ) {
Module [ key ] = moduleOverrides [ key ] ;
}
}
// 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 ;
// 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' ] ;
if ( Module [ 'thisProgram' ] ) thisProgram = Module [ 'thisProgram' ] ;
if ( Module [ 'quit' ] ) quit _ = Module [ 'quit' ] ;
// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
// {{PREAMBLE_ADDITIONS}}
var STACK _ALIGN = 16 ;
function dynamicAlloc ( size ) {
var ret = HEAP32 [ DYNAMICTOP _PTR >> 2 ] ;
var end = ( ret + size + 15 ) & - 16 ;
HEAP32 [ DYNAMICTOP _PTR >> 2 ] = end ;
return ret ;
}
function alignMemory ( size , factor ) {
if ( ! factor ) factor = STACK _ALIGN ; // stack alignment (16-byte) by default
return Math . ceil ( size / factor ) * factor ;
}
function getNativeTypeSize ( type ) {
switch ( type ) {
case 'i1' : case 'i8' : return 1 ;
case 'i16' : return 2 ;
case 'i32' : return 4 ;
case 'i64' : return 8 ;
case 'float' : return 4 ;
case 'double' : return 8 ;
default : {
if ( type [ type . length - 1 ] === '*' ) {
return 4 ; // A pointer
} else if ( type [ 0 ] === 'i' ) {
var bits = Number ( type . substr ( 1 ) ) ;
assert ( bits % 8 === 0 , 'getNativeTypeSize invalid bits ' + bits + ', type ' + type ) ;
return bits / 8 ;
} else {
return 0 ;
}
}
}
}
function warnOnce ( text ) {
if ( ! warnOnce . shown ) warnOnce . shown = { } ;
if ( ! warnOnce . shown [ text ] ) {
warnOnce . shown [ text ] = 1 ;
err ( text ) ;
}
}
// Wraps a JS function as a wasm function with a given signature.
function convertJsFunctionToWasm ( func , sig ) {
// If the type reflection proposal is available, use the new
// "WebAssembly.Function" constructor.
// Otherwise, construct a minimal wasm module importing the JS function and
// re-exporting it.
if ( typeof WebAssembly . Function === "function" ) {
var typeNames = {
'i' : 'i32' ,
'j' : 'i64' ,
'f' : 'f32' ,
'd' : 'f64'
} ;
var type = {
parameters : [ ] ,
results : sig [ 0 ] == 'v' ? [ ] : [ typeNames [ sig [ 0 ] ] ]
} ;
for ( var i = 1 ; i < sig . length ; ++ i ) {
type . parameters . push ( typeNames [ sig [ i ] ] ) ;
}
return new WebAssembly . Function ( type , func ) ;
}
// The module is static, with the exception of the type section, which is
// generated based on the signature passed in.
var typeSection = [
0x01 , // id: section,
0x00 , // length: 0 (placeholder)
0x01 , // count: 1
0x60 , // form: func
] ;
var sigRet = sig . slice ( 0 , 1 ) ;
var sigParam = sig . slice ( 1 ) ;
var typeCodes = {
'i' : 0x7f , // i32
'j' : 0x7e , // i64
'f' : 0x7d , // f32
'd' : 0x7c , // f64
} ;
// Parameters, length + signatures
typeSection . push ( sigParam . length ) ;
for ( var i = 0 ; i < sigParam . length ; ++ i ) {
typeSection . push ( typeCodes [ sigParam [ i ] ] ) ;
}
// Return values, length + signatures
// With no multi-return in MVP, either 0 (void) or 1 (anything else)
if ( sigRet == 'v' ) {
typeSection . push ( 0x00 ) ;
} else {
typeSection = typeSection . concat ( [ 0x01 , typeCodes [ sigRet ] ] ) ;
}
// Write the overall length of the type section back into the section header
// (excepting the 2 bytes for the section id and length)
typeSection [ 1 ] = typeSection . length - 2 ;
// Rest of the module is static
var bytes = new Uint8Array ( [
0x00 , 0x61 , 0x73 , 0x6d , // magic ("\0asm")
0x01 , 0x00 , 0x00 , 0x00 , // version: 1
] . concat ( typeSection , [
0x02 , 0x07 , // import section
// (import "e" "f" (func 0 (type 0)))
0x01 , 0x01 , 0x65 , 0x01 , 0x66 , 0x00 , 0x00 ,
0x07 , 0x05 , // export section
// (export "f" (func 0 (type 0)))
0x01 , 0x01 , 0x66 , 0x00 , 0x00 ,
] ) ) ;
// We can compile this wasm module synchronously because it is very small.
// This accepts an import (at "e.f"), that it reroutes to an export (at "f")
var module = new WebAssembly . Module ( bytes ) ;
var instance = new WebAssembly . Instance ( module , {
'e' : {
'f' : func
}
} ) ;
var wrappedFunc = instance . exports [ 'f' ] ;
return wrappedFunc ;
}
var freeTableIndexes = [ ] ;
// Weak map of functions in the table to their indexes, created on first use.
var functionsInTableMap ;
// Add a wasm function to the table.
function addFunctionWasm ( func , sig ) {
var table = wasmTable ;
// Check if the function is already in the table, to ensure each function
// gets a unique index. First, create the map if this is the first use.
if ( ! functionsInTableMap ) {
functionsInTableMap = new WeakMap ( ) ;
for ( var i = 0 ; i < table . length ; i ++ ) {
var item = table . get ( i ) ;
// Ignore null values.
if ( item ) {
functionsInTableMap . set ( item , i ) ;
}
}
}
if ( functionsInTableMap . has ( func ) ) {
return functionsInTableMap . get ( func ) ;
}
// It's not in the table, add it now.
var ret ;
// Reuse a free index if there is one, otherwise grow.
if ( freeTableIndexes . length ) {
ret = freeTableIndexes . pop ( ) ;
} else {
ret = table . length ;
// Grow the table
try {
table . grow ( 1 ) ;
} catch ( err ) {
if ( ! ( err instanceof RangeError ) ) {
throw err ;
}
throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.' ;
}
}
// Set the new value.
try {
// Attempting to call this with JS function will cause of table.set() to fail
table . set ( ret , func ) ;
} catch ( err ) {
if ( ! ( err instanceof TypeError ) ) {
throw err ;
}
var wrapped = convertJsFunctionToWasm ( func , sig ) ;
table . set ( ret , wrapped ) ;
}
functionsInTableMap . set ( func , ret ) ;
return ret ;
}
function removeFunctionWasm ( index ) {
functionsInTableMap . delete ( wasmTable . get ( index ) ) ;
freeTableIndexes . push ( index ) ;
}
// 'sig' parameter is required for the llvm backend but only when func is not
// already a WebAssembly function.
function addFunction ( func , sig ) {
return addFunctionWasm ( func , sig ) ;
}
function removeFunction ( index ) {
removeFunctionWasm ( index ) ;
}
var funcWrappers = { } ;
function getFuncWrapper ( func , sig ) {
if ( ! func ) return ; // on null pointer, return undefined
assert ( sig ) ;
if ( ! funcWrappers [ sig ] ) {
funcWrappers [ sig ] = { } ;
}
var sigCache = funcWrappers [ sig ] ;
if ( ! sigCache [ func ] ) {
// optimize away arguments usage in common cases
if ( sig . length === 1 ) {
sigCache [ func ] = function dynCall _wrapper ( ) {
return dynCall ( sig , func ) ;
} ;
} else if ( sig . length === 2 ) {
sigCache [ func ] = function dynCall _wrapper ( arg ) {
return dynCall ( sig , func , [ arg ] ) ;
} ;
} else {
// general case
sigCache [ func ] = function dynCall _wrapper ( ) {
return dynCall ( sig , func , Array . prototype . slice . call ( arguments ) ) ;
} ;
}
}
return sigCache [ func ] ;
}
function makeBigInt ( low , high , unsigned ) {
return unsigned ? ( ( + ( ( low >>> 0 ) ) ) + ( ( + ( ( high >>> 0 ) ) ) * 4294967296.0 ) ) : ( ( + ( ( low >>> 0 ) ) ) + ( ( + ( ( high | 0 ) ) ) * 4294967296.0 ) ) ;
}
/** @param {Array=} args */
function dynCall ( sig , ptr , args ) {
if ( args && args . length ) {
return Module [ 'dynCall_' + sig ] . apply ( null , [ ptr ] . concat ( args ) ) ;
} else {
return Module [ 'dynCall_' + sig ] . call ( null , ptr ) ;
}
}
var tempRet0 = 0 ;
var setTempRet0 = function ( value ) {
tempRet0 = value ;
} ;
var getTempRet0 = function ( ) {
return tempRet0 ;
} ;
// The address globals begin at. Very low in memory, for code size and optimization opportunities.
// Above 0 is static memory, starting with globals.
// Then the stack.
// Then 'dynamic' memory for sbrk.
var GLOBAL _BASE = 1024 ;
// === 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' ] ;
var noExitRuntime ; if ( Module [ 'noExitRuntime' ] ) noExitRuntime = Module [ 'noExitRuntime' ] ;
if ( typeof WebAssembly !== 'object' ) {
err ( 'no native wasm support detected' ) ;
}
// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking.
// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties)
/ * * @ p a r a m { n u m b e r } p t r
@ param { number } value
@ param { string } type
@ param { number | boolean = } noSafe * /
function setValue ( ptr , value , type , noSafe ) {
type = type || 'i8' ;
if ( type . charAt ( type . length - 1 ) === '*' ) type = 'i32' ; // pointers are 32-bit
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 _min ( ( + ( Math _floor ( ( tempDouble ) / 4294967296.0 ) ) ) , 4294967295.0 ) ) | 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 ;
default : abort ( 'invalid type for setValue: ' + type ) ;
}
}
/ * * @ p a r a m { n u m b e r } p t r
@ param { string } type
@ param { number | boolean = } noSafe * /
function getValue ( ptr , type , noSafe ) {
type = type || 'i8' ;
if ( type . charAt ( type . length - 1 ) === '*' ) type = 'i32' ; // pointers are 32-bit
switch ( type ) {
case 'i1' : return HEAP8 [ ( ( ptr ) >> 0 ) ] ;
case 'i8' : return HEAP8 [ ( ( ptr ) >> 0 ) ] ;
case 'i16' : return HEAP16 [ ( ( ptr ) >> 1 ) ] ;
case 'i32' : return HEAP32 [ ( ( ptr ) >> 2 ) ] ;
case 'i64' : return HEAP32 [ ( ( ptr ) >> 2 ) ] ;
case 'float' : return HEAPF32 [ ( ( ptr ) >> 2 ) ] ;
case 'double' : return HEAPF64 [ ( ( ptr ) >> 3 ) ] ;
default : abort ( 'invalid type for getValue: ' + type ) ;
}
return null ;
}
// Wasm globals
var wasmMemory ;
// In fastcomp asm.js, we don't need a wasm Table at all.
// In the wasm backend, we polyfill the WebAssembly object,
// so this creates a (non-native-wasm) table for us.
var wasmTable = new WebAssembly . Table ( {
'initial' : 1272 ,
'maximum' : 1272 + 0 ,
'element' : 'anyfunc'
} ) ;
//========================================
// 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 = 0 ;
/** @type {function(*, string=)} */
function assert ( condition , text ) {
if ( ! condition ) {
abort ( 'Assertion failed: ' + text ) ;
}
}
// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
function getCFunc ( ident ) {
var func = Module [ '_' + ident ] ; // closure exported function
assert ( func , 'Cannot call unknown function ' + ident + ', make sure it is exported' ) ;
return func ;
}
// C calling interface.
/ * * @ p a r a m { s t r i n g | n u l l = } r e t u r n T y p e
@ param { Array = } argTypes
@ param { Arguments | Array = } args
@ param { Object = } opts * /
function ccall ( ident , returnType , argTypes , args , opts ) {
// For fast lookup of conversion functions
var toC = {
'string' : function ( str ) {
var ret = 0 ;
if ( str !== null && str !== undefined && str !== 0 ) { // null string
// at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
var len = ( str . length << 2 ) + 1 ;
ret = stackAlloc ( len ) ;
stringToUTF8 ( str , ret , len ) ;
}
return ret ;
} ,
'array' : function ( arr ) {
var ret = stackAlloc ( arr . length ) ;
writeArrayToMemory ( arr , ret ) ;
return ret ;
}
} ;
function convertReturnValue ( ret ) {
if ( returnType === 'string' ) return UTF8ToString ( ret ) ;
if ( returnType === 'boolean' ) return Boolean ( ret ) ;
return ret ;
}
var func = getCFunc ( ident ) ;
var cArgs = [ ] ;
var stack = 0 ;
if ( args ) {
for ( var i = 0 ; i < args . length ; i ++ ) {
var converter = toC [ argTypes [ i ] ] ;
if ( converter ) {
if ( stack === 0 ) stack = stackSave ( ) ;
cArgs [ i ] = converter ( args [ i ] ) ;
} else {
cArgs [ i ] = args [ i ] ;
}
}
}
var ret = func . apply ( null , cArgs ) ;
ret = convertReturnValue ( ret ) ;
if ( stack !== 0 ) stackRestore ( stack ) ;
return ret ;
}
/ * * @ p a r a m { s t r i n g = } r e t u r n T y p e
@ param { Array = } argTypes
@ param { Object = } opts * /
function cwrap ( ident , returnType , argTypes , opts ) {
argTypes = argTypes || [ ] ;
// When the function takes numbers and returns a number, we can just return
// the original function
var numericArgs = argTypes . every ( function ( type ) { return type === 'number' } ) ;
var numericRet = returnType !== 'string' ;
if ( numericRet && numericArgs && ! opts ) {
return getCFunc ( ident ) ;
}
return function ( ) {
return ccall ( ident , returnType , argTypes , arguments , opts ) ;
}
}
var ALLOC _NORMAL = 0 ; // Tries to use _malloc()
var ALLOC _STACK = 1 ; // Lives for the duration of the current function call
var ALLOC _DYNAMIC = 2 ; // Cannot be freed except through sbrk
var ALLOC _NONE = 3 ; // Do not allocate
// allocate(): This is for internal use. You can use it yourself as well, but the interface
// is a little tricky (see docs right below). The reason is that it is optimized
// for multiple syntaxes to save space in generated code. So you should
// normally not use allocate(), and instead allocate memory using _malloc(),
// initialize it with setValue(), and so forth.
// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
// in *bytes* (note that this is sometimes confusing: the next parameter does not
// affect this!)
// @types: Either an array of types, one for each byte (or 0 if no type at that position),
// or a single type which is used for the entire block. This only matters if there
// is initial data - if @slab is a number, then this does not matter at all and is
// ignored.
// @allocator: How to allocate memory, see ALLOC_*
/** @type {function((TypedArray|Array<number>|number), string, number, number=)} */
function allocate ( slab , types , allocator , ptr ) {
var zeroinit , size ;
if ( typeof slab === 'number' ) {
zeroinit = true ;
size = slab ;
} else {
zeroinit = false ;
size = slab . length ;
}
var singleType = typeof types === 'string' ? types : null ;
var ret ;
if ( allocator == ALLOC _NONE ) {
ret = ptr ;
} else {
ret = [ _malloc ,
stackAlloc ,
dynamicAlloc ] [ allocator ] ( Math . max ( size , singleType ? 1 : types . length ) ) ;
}
if ( zeroinit ) {
var stop ;
ptr = ret ;
assert ( ( ret & 3 ) == 0 ) ;
stop = ret + ( size & ~ 3 ) ;
for ( ; ptr < stop ; ptr += 4 ) {
HEAP32 [ ( ( ptr ) >> 2 ) ] = 0 ;
}
stop = ret + size ;
while ( ptr < stop ) {
HEAP8 [ ( ( ptr ++ ) >> 0 ) ] = 0 ;
}
return ret ;
}
if ( singleType === 'i8' ) {
if ( slab . subarray || slab . slice ) {
HEAPU8 . set ( /** @type {!Uint8Array} */ ( slab ) , ret ) ;
} else {
HEAPU8 . set ( new Uint8Array ( slab ) , ret ) ;
}
return ret ;
}
var i = 0 , type , typeSize , previousType ;
while ( i < size ) {
var curr = slab [ i ] ;
type = singleType || types [ i ] ;
if ( type === 0 ) {
i ++ ;
continue ;
}
if ( type == 'i64' ) type = 'i32' ; // special case: we have one i32 here, and one i32 later
setValue ( ret + i , curr , type ) ;
// no need to look up size unless type changes, so cache it
if ( previousType !== type ) {
typeSize = getNativeTypeSize ( type ) ;
previousType = type ;
}
i += typeSize ;
}
return ret ;
}
// Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready
function getMemory ( size ) {
if ( ! runtimeInitialized ) return dynamicAlloc ( size ) ;
return _malloc ( size ) ;
}
// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime.
// Given a pointer 'ptr' 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.
var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder ( 'utf8' ) : undefined ;
/ * *
* @ param { number } idx
* @ param { number = } maxBytesToRead
* @ return { string }
* /
function UTF8ArrayToString ( heap , 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 ( heap [ endPtr ] && ! ( endPtr >= endIdx ) ) ++ endPtr ;
if ( endPtr - idx > 16 && heap . subarray && UTF8Decoder ) {
return UTF8Decoder . decode ( heap . subarray ( idx , endPtr ) ) ;
} else {
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 = heap [ idx ++ ] ;
if ( ! ( u0 & 0x80 ) ) { str += String . fromCharCode ( u0 ) ; continue ; }
var u1 = heap [ idx ++ ] & 63 ;
if ( ( u0 & 0xE0 ) == 0xC0 ) { str += String . fromCharCode ( ( ( u0 & 31 ) << 6 ) | u1 ) ; continue ; }
var u2 = heap [ idx ++ ] & 63 ;
if ( ( u0 & 0xF0 ) == 0xE0 ) {
u0 = ( ( u0 & 15 ) << 12 ) | ( u1 << 6 ) | u2 ;
} else {
u0 = ( ( u0 & 7 ) << 18 ) | ( u1 << 12 ) | ( u2 << 6 ) | ( heap [ 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.
// 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
// style or the other.
/ * *
* @ param { number } ptr
* @ param { number = } maxBytesToRead
* @ return { string }
* /
function UTF8ToString ( ptr , maxBytesToRead ) {
return ptr ? UTF8ArrayToString ( HEAPU8 , ptr , maxBytesToRead ) : '' ;
}
// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',
// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.
// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
// Parameters:
// str: the Javascript string to copy.
// heap: the array to copy to. Each index in this array is assumed to be one 8-byte element.
// outIdx: The starting offset in the array to begin the copying.
// maxBytesToWrite: The maximum number of bytes this function can write to the array.
// This count should include the null terminator,
// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.
// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.
// Returns the number of bytes written, EXCLUDING the null terminator.
function stringToUTF8Array ( str , heap , outIdx , maxBytesToWrite ) {
if ( ! ( maxBytesToWrite > 0 ) ) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
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 ;
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 ;
}
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.
// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
// Returns the number of bytes written, EXCLUDING the null terminator.
function stringToUTF8 ( str , outPtr , maxBytesToWrite ) {
return stringToUTF8Array ( str , HEAPU8 , outPtr , maxBytesToWrite ) ;
}
// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.
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 u = str . charCodeAt ( i ) ; // possibly a lead surrogate
if ( u >= 0xD800 && u <= 0xDFFF ) u = 0x10000 + ( ( u & 0x3FF ) << 10 ) | ( str . charCodeAt ( ++ i ) & 0x3FF ) ;
if ( u <= 0x7F ) ++ len ;
else if ( u <= 0x7FF ) len += 2 ;
else if ( u <= 0xFFFF ) len += 3 ;
else len += 4 ;
}
return len ;
}
// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime.
// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns
// a copy of that string as a Javascript String object.
function AsciiToString ( ptr ) {
var str = '' ;
while ( 1 ) {
var ch = HEAPU8 [ ( ( ptr ++ ) >> 0 ) ] ;
if ( ! ch ) return str ;
str += String . fromCharCode ( ch ) ;
}
}
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.
function stringToAscii ( str , outPtr ) {
return writeAsciiToMemory ( str , outPtr , false ) ;
}
// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
// a copy of that string as a Javascript String object.
var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder ( 'utf-16le' ) : undefined ;
function UTF16ToString ( ptr , maxBytesToRead ) {
var endPtr = ptr ;
// 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.
var idx = endPtr >> 1 ;
var maxIdx = idx + maxBytesToRead / 2 ;
// If maxBytesToRead is not passed explicitly, it will be undefined, and this
// will always evaluate to true. This saves on code size.
while ( ! ( idx >= maxIdx ) && HEAPU16 [ idx ] ) ++ idx ;
endPtr = idx << 1 ;
if ( endPtr - ptr > 32 && UTF16Decoder ) {
return UTF16Decoder . decode ( HEAPU8 . subarray ( ptr , endPtr ) ) ;
} else {
var i = 0 ;
var str = '' ;
while ( 1 ) {
var codeUnit = HEAP16 [ ( ( ( ptr ) + ( i * 2 ) ) >> 1 ) ] ;
if ( codeUnit == 0 || i == maxBytesToRead / 2 ) return str ;
++ i ;
// fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
str += String . fromCharCode ( codeUnit ) ;
}
}
}
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.
// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.
// Parameters:
// str: the Javascript string to copy.
// outPtr: Byte address in Emscripten HEAP where to write the string to.
// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.
// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.
// Returns the number of bytes written, EXCLUDING the null terminator.
function stringToUTF16 ( str , outPtr , maxBytesToWrite ) {
// Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
if ( maxBytesToWrite === undefined ) {
maxBytesToWrite = 0x7FFFFFFF ;
}
if ( maxBytesToWrite < 2 ) return 0 ;
maxBytesToWrite -= 2 ; // Null terminator.
var startPtr = outPtr ;
var numCharsToWrite = ( maxBytesToWrite < str . length * 2 ) ? ( maxBytesToWrite / 2 ) : str . length ;
for ( var i = 0 ; i < numCharsToWrite ; ++ i ) {
// charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
var codeUnit = str . charCodeAt ( i ) ; // possibly a lead surrogate
HEAP16 [ ( ( outPtr ) >> 1 ) ] = codeUnit ;
outPtr += 2 ;
}
// Null-terminate the pointer to the HEAP.
HEAP16 [ ( ( outPtr ) >> 1 ) ] = 0 ;
return outPtr - startPtr ;
}
// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
function lengthBytesUTF16 ( str ) {
return str . length * 2 ;
}
function UTF32ToString ( ptr , maxBytesToRead ) {
var i = 0 ;
var str = '' ;
// If maxBytesToRead is not passed explicitly, it will be undefined, and this
// will always evaluate to true. This saves on code size.
while ( ! ( i >= maxBytesToRead / 4 ) ) {
var utf32 = HEAP32 [ ( ( ( ptr ) + ( i * 4 ) ) >> 2 ) ] ;
if ( utf32 == 0 ) break ;
++ i ;
// Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
// See http://unicode.org/faq/utf_bom.html#utf16-3
if ( utf32 >= 0x10000 ) {
var ch = utf32 - 0x10000 ;
str += String . fromCharCode ( 0xD800 | ( ch >> 10 ) , 0xDC00 | ( ch & 0x3FF ) ) ;
} else {
str += String . fromCharCode ( utf32 ) ;
}
}
return str ;
}
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.
// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.
// Parameters:
// str: the Javascript string to copy.
// outPtr: Byte address in Emscripten HEAP where to write the string to.
// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.
// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.
// Returns the number of bytes written, EXCLUDING the null terminator.
function stringToUTF32 ( str , outPtr , maxBytesToWrite ) {
// Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
if ( maxBytesToWrite === undefined ) {
maxBytesToWrite = 0x7FFFFFFF ;
}
if ( maxBytesToWrite < 4 ) return 0 ;
var startPtr = outPtr ;
var endPtr = startPtr + maxBytesToWrite - 4 ;
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! We must decode the string to UTF-32 to the heap.
// See http://unicode.org/faq/utf_bom.html#utf16-3
var codeUnit = str . charCodeAt ( i ) ; // possibly a lead surrogate
if ( codeUnit >= 0xD800 && codeUnit <= 0xDFFF ) {
var trailSurrogate = str . charCodeAt ( ++ i ) ;
codeUnit = 0x10000 + ( ( codeUnit & 0x3FF ) << 10 ) | ( trailSurrogate & 0x3FF ) ;
}
HEAP32 [ ( ( outPtr ) >> 2 ) ] = codeUnit ;
outPtr += 4 ;
if ( outPtr + 4 > endPtr ) break ;
}
// Null-terminate the pointer to the HEAP.
HEAP32 [ ( ( outPtr ) >> 2 ) ] = 0 ;
return outPtr - startPtr ;
}
// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
function lengthBytesUTF32 ( 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! We must decode the string to UTF-32 to the heap.
// See http://unicode.org/faq/utf_bom.html#utf16-3
var codeUnit = str . charCodeAt ( i ) ;
if ( codeUnit >= 0xD800 && codeUnit <= 0xDFFF ) ++ i ; // possibly a lead surrogate, so skip over the tail surrogate.
len += 4 ;
}
return len ;
}
// Allocate heap space for a JS string, and write it there.
// It is the responsibility of the caller to free() that memory.
function allocateUTF8 ( str ) {
var size = lengthBytesUTF8 ( str ) + 1 ;
var ret = _malloc ( size ) ;
if ( ret ) stringToUTF8Array ( str , HEAP8 , ret , size ) ;
return ret ;
}
// Allocate stack space for a JS string, and write it there.
function allocateUTF8OnStack ( str ) {
var size = lengthBytesUTF8 ( str ) + 1 ;
var ret = stackAlloc ( size ) ;
stringToUTF8Array ( str , HEAP8 , ret , size ) ;
return ret ;
}
// Deprecated: This function should not be called because it is unsafe and does not provide
// a maximum length limit of how many bytes it is allowed to write. Prefer calling the
// function stringToUTF8Array() instead, which takes in a maximum length that can be used
// to be secure from out of bounds writes.
/ * * @ d e p r e c a t e d
@ param { boolean = } dontAddNull * /
function writeStringToMemory ( string , buffer , dontAddNull ) {
warnOnce ( 'writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!' ) ;
var /** @type {number} */ lastChar , /** @type {number} */ end ;
if ( dontAddNull ) {
// stringToUTF8Array always appends null. If we don't want to do that, remember the
// character that existed at the location where the null will be placed, and restore
// that after the write (below).
end = buffer + lengthBytesUTF8 ( string ) ;
lastChar = HEAP8 [ end ] ;
}
stringToUTF8 ( string , buffer , Infinity ) ;
if ( dontAddNull ) HEAP8 [ end ] = lastChar ; // Restore the value under the null character.
}
function writeArrayToMemory ( array , buffer ) {
HEAP8 . set ( array , buffer ) ;
}
/** @param {boolean=} dontAddNull */
function writeAsciiToMemory ( str , buffer , dontAddNull ) {
for ( var i = 0 ; i < str . length ; ++ i ) {
HEAP8 [ ( ( buffer ++ ) >> 0 ) ] = str . charCodeAt ( i ) ;
}
// Null-terminate the pointer to the HEAP.
if ( ! dontAddNull ) HEAP8 [ ( ( buffer ) >> 0 ) ] = 0 ;
}
// Memory management
var PAGE _SIZE = 16384 ;
var WASM _PAGE _SIZE = 65536 ;
var ASMJS _PAGE _SIZE = 16777216 ;
function alignUp ( x , multiple ) {
if ( x % multiple > 0 ) {
x += multiple - ( x % multiple ) ;
}
return x ;
}
var HEAP ,
/** @type {ArrayBuffer} */
buffer ,
/** @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 updateGlobalBufferAndViews ( buf ) {
buffer = buf ;
Module [ 'HEAP8' ] = HEAP8 = new Int8Array ( buf ) ;
Module [ 'HEAP16' ] = HEAP16 = new Int16Array ( buf ) ;
Module [ 'HEAP32' ] = HEAP32 = new Int32Array ( buf ) ;
Module [ 'HEAPU8' ] = HEAPU8 = new Uint8Array ( buf ) ;
Module [ 'HEAPU16' ] = HEAPU16 = new Uint16Array ( buf ) ;
Module [ 'HEAPU32' ] = HEAPU32 = new Uint32Array ( buf ) ;
Module [ 'HEAPF32' ] = HEAPF32 = new Float32Array ( buf ) ;
Module [ 'HEAPF64' ] = HEAPF64 = new Float64Array ( buf ) ;
}
var STATIC _BASE = 1024 ,
STACK _BASE = 5331232 ,
STACKTOP = STACK _BASE ,
STACK _MAX = 88352 ,
DYNAMIC _BASE = 5331232 ,
DYNAMICTOP _PTR = 88176 ;
var TOTAL _STACK = 5242880 ;
var INITIAL _INITIAL _MEMORY = Module [ 'INITIAL_MEMORY' ] || 16777216 ;
// In non-standalone/normal mode, we create the memory here.
// Create the main memory. (Note: this isn't used in STANDALONE_WASM mode since the wasm
// memory is created in the wasm, not in JS.)
if ( Module [ 'wasmMemory' ] ) {
wasmMemory = Module [ 'wasmMemory' ] ;
} else
{
wasmMemory = new WebAssembly . Memory ( {
'initial' : INITIAL _INITIAL _MEMORY / WASM _PAGE _SIZE
,
'maximum' : 2147483648 / WASM _PAGE _SIZE
} ) ;
}
if ( wasmMemory ) {
buffer = wasmMemory . buffer ;
}
// If the user provides an incorrect length, just use that length instead rather than providing the user to
// specifically provide the memory length with Module['INITIAL_MEMORY'].
INITIAL _INITIAL _MEMORY = buffer . byteLength ;
updateGlobalBufferAndViews ( buffer ) ;
HEAP32 [ DYNAMICTOP _PTR >> 2 ] = DYNAMIC _BASE ;
function callRuntimeCallbacks ( callbacks ) {
while ( callbacks . length > 0 ) {
var callback = callbacks . shift ( ) ;
if ( typeof callback == 'function' ) {
callback ( Module ) ; // Pass the module as the first argument.
continue ;
}
var func = callback . func ;
if ( typeof func === 'number' ) {
if ( callback . arg === undefined ) {
Module [ 'dynCall_v' ] ( func ) ;
} else {
Module [ 'dynCall_vi' ] ( func , callback . arg ) ;
}
} else {
func ( callback . arg === undefined ? null : callback . arg ) ;
}
}
}
var _ _ATPRERUN _ _ = [ ] ; // 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 runtimeExited = false ;
function preRun ( ) {
if ( Module [ 'preRun' ] ) {
if ( typeof Module [ 'preRun' ] == 'function' ) Module [ 'preRun' ] = [ Module [ 'preRun' ] ] ;
while ( Module [ 'preRun' ] . length ) {
addOnPreRun ( Module [ 'preRun' ] . shift ( ) ) ;
}
}
callRuntimeCallbacks ( _ _ATPRERUN _ _ ) ;
}
function initRuntime ( ) {
runtimeInitialized = true ;
if ( ! Module [ "noFSInit" ] && ! FS . init . initialized ) FS . init ( ) ;
TTY . init ( ) ;
callRuntimeCallbacks ( _ _ATINIT _ _ ) ;
}
function preMain ( ) {
FS . ignorePermissions = false ;
callRuntimeCallbacks ( _ _ATMAIN _ _ ) ;
}
function exitRuntime ( ) {
runtimeExited = true ;
}
function postRun ( ) {
if ( Module [ 'postRun' ] ) {
if ( typeof Module [ 'postRun' ] == 'function' ) Module [ 'postRun' ] = [ Module [ 'postRun' ] ] ;
while ( Module [ 'postRun' ] . length ) {
addOnPostRun ( Module [ 'postRun' ] . shift ( ) ) ;
}
}
callRuntimeCallbacks ( _ _ATPOSTRUN _ _ ) ;
}
function addOnPreRun ( cb ) {
_ _ATPRERUN _ _ . unshift ( cb ) ;
}
function addOnInit ( cb ) {
_ _ATINIT _ _ . unshift ( cb ) ;
}
function addOnPreMain ( cb ) {
_ _ATMAIN _ _ . unshift ( cb ) ;
}
function addOnExit ( cb ) {
}
function addOnPostRun ( cb ) {
_ _ATPOSTRUN _ _ . unshift ( cb ) ;
}
/** @param {number|boolean=} ignore */
function unSign ( value , bits , ignore ) {
if ( value >= 0 ) {
return value ;
}
return bits <= 32 ? 2 * Math . abs ( 1 << ( bits - 1 ) ) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
: Math . pow ( 2 , bits ) + value ;
}
/** @param {number|boolean=} ignore */
function reSign ( value , bits , ignore ) {
if ( value <= 0 ) {
return value ;
}
var half = bits <= 32 ? Math . abs ( 1 << ( bits - 1 ) ) // abs is needed if bits == 32
: Math . pow ( 2 , bits - 1 ) ;
if ( value >= half && ( bits <= 32 || value > half ) ) { // for huge values, we can hit the precision limit and always get true here. so don't do that
// but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
// TODO: In i64 mode 1, resign the two parts separately and safely
value = - 2 * half + value ; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
}
return value ;
}
// 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
var Math _abs = Math . abs ;
var Math _cos = Math . cos ;
var Math _sin = Math . sin ;
var Math _tan = Math . tan ;
var Math _acos = Math . acos ;
var Math _asin = Math . asin ;
var Math _atan = Math . atan ;
var Math _atan2 = Math . atan2 ;
var Math _exp = Math . exp ;
var Math _log = Math . log ;
var Math _sqrt = Math . sqrt ;
var Math _ceil = Math . ceil ;
var Math _floor = Math . floor ;
var Math _pow = Math . pow ;
var Math _imul = Math . imul ;
var Math _fround = Math . fround ;
var Math _round = Math . round ;
var Math _min = Math . min ;
var Math _max = Math . max ;
var Math _clz32 = Math . clz32 ;
var Math _trunc = Math . trunc ;
// 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
function getUniqueRunDependency ( id ) {
return id ;
}
function addRunDependency ( id ) {
runDependencies ++ ;
if ( Module [ 'monitorRunDependencies' ] ) {
Module [ 'monitorRunDependencies' ] ( runDependencies ) ;
}
}
function removeRunDependency ( id ) {
runDependencies -- ;
if ( Module [ 'monitorRunDependencies' ] ) {
Module [ 'monitorRunDependencies' ] ( runDependencies ) ;
}
if ( runDependencies == 0 ) {
if ( runDependencyWatcher !== null ) {
clearInterval ( runDependencyWatcher ) ;
runDependencyWatcher = null ;
}
if ( dependenciesFulfilled ) {
var callback = dependenciesFulfilled ;
dependenciesFulfilled = null ;
callback ( ) ; // can add another dependenciesFulfilled
}
}
}
Module [ "preloadedImages" ] = { } ; // maps url to image data
Module [ "preloadedAudios" ] = { } ; // maps url to audio data
/** @param {string|number=} what */
function abort ( what ) {
if ( Module [ 'onAbort' ] ) {
Module [ 'onAbort' ] ( what ) ;
}
what += '' ;
out ( what ) ;
err ( what ) ;
ABORT = true ;
EXITSTATUS = 1 ;
what = 'abort(' + what + '). Build with -s ASSERTIONS=1 for more info.' ;
// Throw 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.
throw new WebAssembly . RuntimeError ( what ) ;
}
var memoryInitializer = null ;
function hasPrefix ( str , prefix ) {
return String . prototype . startsWith ?
str . startsWith ( prefix ) :
str . indexOf ( prefix ) === 0 ;
}
// 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 ) {
return hasPrefix ( filename , dataURIPrefix ) ;
}
var fileURIPrefix = "file://" ;
// Indicates whether filename is delivered via file protocol (as opposed to http/https)
function isFileURI ( filename ) {
return hasPrefix ( filename , fileURIPrefix ) ;
}
var wasmBinaryFile = 'cmoc.wasm' ;
if ( ! isDataURI ( wasmBinaryFile ) ) {
wasmBinaryFile = locateFile ( wasmBinaryFile ) ;
}
function getBinary ( ) {
try {
if ( wasmBinary ) {
return new Uint8Array ( wasmBinary ) ;
}
if ( readBinary ) {
return readBinary ( wasmBinaryFile ) ;
} else {
throw "both async and sync fetching of the wasm failed" ;
}
}
catch ( err ) {
abort ( err ) ;
}
}
function getBinaryPromise ( ) {
// If we don't have the binary yet, and have the Fetch api, use that;
// in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web
if ( ! wasmBinary && ( ENVIRONMENT _IS _WEB || ENVIRONMENT _IS _WORKER ) && typeof fetch === 'function'
// Let's not use fetch to get objects over file:// as it's most likely Cordova which doesn't support fetch for file://
&& ! isFileURI ( wasmBinaryFile )
) {
return fetch ( wasmBinaryFile , { credentials : 'same-origin' } ) . then ( function ( response ) {
if ( ! response [ 'ok' ] ) {
throw "failed to load wasm binary file at '" + wasmBinaryFile + "'" ;
}
return response [ 'arrayBuffer' ] ( ) ;
} ) . catch ( function ( ) {
return getBinary ( ) ;
} ) ;
}
// Otherwise, getBinary should be able to get it synchronously
return new Promise ( function ( resolve , reject ) {
resolve ( getBinary ( ) ) ;
} ) ;
}
// Create the wasm instance.
// Receives the wasm imports, returns the exports.
function createWasm ( ) {
// prepare imports
var info = {
'env' : asmLibraryArg ,
'wasi_snapshot_preview1' : asmLibraryArg
} ;
// 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 ;
removeRunDependency ( 'wasm-instantiate' ) ;
}
// we can't run yet (except in a pthread, where we have a custom sync instantiator)
addRunDependency ( 'wasm-instantiate' ) ;
function receiveInstantiatedSource ( output ) {
// 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
// receiveInstance() will swap in the exports (to Module.asm) so they can be called
// 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 USE_PTHREADS-enabled path.
receiveInstance ( output [ 'instance' ] ) ;
}
function instantiateArrayBuffer ( receiver ) {
return getBinaryPromise ( ) . then ( function ( binary ) {
return WebAssembly . instantiate ( binary , info ) ;
} ) . then ( receiver , function ( reason ) {
err ( 'failed to asynchronously prepare wasm: ' + reason ) ;
abort ( reason ) ;
} ) ;
}
// Prefer streaming instantiation if available.
function instantiateAsync ( ) {
if ( ! wasmBinary &&
typeof WebAssembly . instantiateStreaming === 'function' &&
! isDataURI ( wasmBinaryFile ) &&
// Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
! isFileURI ( wasmBinaryFile ) &&
typeof fetch === 'function' ) {
fetch ( wasmBinaryFile , { credentials : 'same-origin' } ) . then ( function ( response ) {
var result = WebAssembly . instantiateStreaming ( response , info ) ;
return result . then ( receiveInstantiatedSource , 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 ( receiveInstantiatedSource ) ;
} ) ;
} ) ;
} else {
return instantiateArrayBuffer ( receiveInstantiatedSource ) ;
}
}
// 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.
if ( Module [ 'instantiateWasm' ] ) {
try {
var exports = Module [ 'instantiateWasm' ] ( info , receiveInstance ) ;
return exports ;
} catch ( e ) {
err ( 'Module.instantiateWasm callback failed with error: ' + e ) ;
return false ;
}
}
instantiateAsync ( ) ;
return { } ; // no exports yet; we'll fill them in later
}
// Globals used by JS i64 conversions
var tempDouble ;
var tempI64 ;
// === Body ===
var ASM _CONSTS = {
} ;
// STATICTOP = STATIC_BASE + 87328;
/* global initializers */ _ _ATINIT _ _ . push ( { func : function ( ) { _ _ _wasm _call _ctors ( ) } } ) ;
/* no memory initializer */
// {{PRE_LIBRARY}}
function demangle ( func ) {
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 + ']' ) ;
} ) ;
}
function jsStackTrace ( ) {
var err = new Error ( ) ;
if ( ! err . stack ) {
// IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
// so try that as a special-case.
try {
throw new Error ( ) ;
} catch ( e ) {
err = e ;
}
if ( ! err . stack ) {
return '(no stack trace available)' ;
}
}
return err . stack . toString ( ) ;
}
function stackTrace ( ) {
var js = jsStackTrace ( ) ;
if ( Module [ 'extraStackTrace' ] ) js += '\n' + Module [ 'extraStackTrace' ] ( ) ;
return demangleAll ( js ) ;
}
function _ _ _assert _fail ( condition , filename , line , func ) {
abort ( 'Assertion failed: ' + UTF8ToString ( condition ) + ', at: ' + [ filename ? UTF8ToString ( filename ) : 'unknown filename' , line , func ? UTF8ToString ( func ) : 'unknown function' ] ) ;
}
function _ _ _cxa _allocate _exception ( size ) {
return _malloc ( size ) ;
}
function _atexit ( func , arg ) {
_ _ATEXIT _ _ . unshift ( { func : func , arg : arg } ) ;
} function _ _ _cxa _atexit ( a0 , a1
) {
return _atexit ( a0 , a1 ) ;
}
var _ _ _exception _infos = { } ;
var _ _ _exception _caught = [ ] ;
function _ _ _exception _addRef ( ptr ) {
if ( ! ptr ) return ;
var info = _ _ _exception _infos [ ptr ] ;
info . refcount ++ ;
}
function _ _ _exception _deAdjust ( adjusted ) {
if ( ! adjusted || _ _ _exception _infos [ adjusted ] ) return adjusted ;
for ( var key in _ _ _exception _infos ) {
var ptr = + key ; // the iteration key is a string, and if we throw this, it must be an integer as that is what we look for
var adj = _ _ _exception _infos [ ptr ] . adjusted ;
var len = adj . length ;
for ( var i = 0 ; i < len ; i ++ ) {
if ( adj [ i ] === adjusted ) {
return ptr ;
}
}
}
return adjusted ;
} function _ _ _cxa _begin _catch ( ptr ) {
var info = _ _ _exception _infos [ ptr ] ;
if ( info && ! info . caught ) {
info . caught = true ;
_ _ZSt18uncaught _exceptionv . uncaught _exceptions -- ;
}
if ( info ) info . rethrown = false ;
_ _ _exception _caught . push ( ptr ) ;
_ _ _exception _addRef ( _ _ _exception _deAdjust ( ptr ) ) ;
return ptr ;
}
var _ _ _exception _last = 0 ;
function _ _ _cxa _free _exception ( ptr ) {
return _free ( ptr ) ;
} function _ _ _exception _decRef ( ptr ) {
if ( ! ptr ) return ;
var info = _ _ _exception _infos [ ptr ] ;
info . refcount -- ;
// A rethrown exception can reach refcount 0; it must not be discarded
// Its next handler will clear the rethrown flag and addRef it, prior to
// final decRef and destruction here
if ( info . refcount === 0 && ! info . rethrown ) {
if ( info . destructor ) {
// In Wasm, destructors return 'this' as in ARM
Module [ 'dynCall_ii' ] ( info . destructor , ptr ) ;
}
delete _ _ _exception _infos [ ptr ] ;
_ _ _cxa _free _exception ( ptr ) ;
}
} function _ _ _cxa _end _catch ( ) {
// Clear state flag.
_setThrew ( 0 ) ;
// Call destructor if one is registered then clear it.
var ptr = _ _ _exception _caught . pop ( ) ;
if ( ptr ) {
_ _ _exception _decRef ( _ _ _exception _deAdjust ( ptr ) ) ;
_ _ _exception _last = 0 ; // XXX in decRef?
}
}
function _ _ _cxa _find _matching _catch _2 ( ) {
var thrown = _ _ _exception _last ;
if ( ! thrown ) {
// just pass through the null ptr
return ( ( setTempRet0 ( 0 ) , 0 ) | 0 ) ;
}
var info = _ _ _exception _infos [ thrown ] ;
var throwntype = info . type ;
if ( ! throwntype ) {
// just pass through the thrown ptr
return ( ( setTempRet0 ( 0 ) , thrown ) | 0 ) ;
}
var typeArray = Array . prototype . slice . call ( arguments ) ;
var pointer = _ _ _cxa _is _pointer _type ( throwntype ) ;
// can_catch receives a **, add indirection
var buffer = 88336 ;
HEAP32 [ ( ( buffer ) >> 2 ) ] = thrown ;
thrown = buffer ;
// The different catch blocks are denoted by different types.
// Due to inheritance, those types may not precisely match the
// type of the thrown object. Find one which matches, and
// return the type of the catch block which should be called.
for ( var i = 0 ; i < typeArray . length ; i ++ ) {
if ( typeArray [ i ] && _ _ _cxa _can _catch ( typeArray [ i ] , throwntype , thrown ) ) {
thrown = HEAP32 [ ( ( thrown ) >> 2 ) ] ; // undo indirection
info . adjusted . push ( thrown ) ;
return ( ( setTempRet0 ( typeArray [ i ] ) , thrown ) | 0 ) ;
}
}
// Shouldn't happen unless we have bogus data in typeArray
// or encounter a type for which emscripten doesn't have suitable
// typeinfo defined. Best-efforts match just in case.
thrown = HEAP32 [ ( ( thrown ) >> 2 ) ] ; // undo indirection
return ( ( setTempRet0 ( throwntype ) , thrown ) | 0 ) ;
}
function _ _ _cxa _find _matching _catch _3 ( ) {
var thrown = _ _ _exception _last ;
if ( ! thrown ) {
// just pass through the null ptr
return ( ( setTempRet0 ( 0 ) , 0 ) | 0 ) ;
}
var info = _ _ _exception _infos [ thrown ] ;
var throwntype = info . type ;
if ( ! throwntype ) {
// just pass through the thrown ptr
return ( ( setTempRet0 ( 0 ) , thrown ) | 0 ) ;
}
var typeArray = Array . prototype . slice . call ( arguments ) ;
var pointer = _ _ _cxa _is _pointer _type ( throwntype ) ;
// can_catch receives a **, add indirection
var buffer = 88336 ;
HEAP32 [ ( ( buffer ) >> 2 ) ] = thrown ;
thrown = buffer ;
// The different catch blocks are denoted by different types.
// Due to inheritance, those types may not precisely match the
// type of the thrown object. Find one which matches, and
// return the type of the catch block which should be called.
for ( var i = 0 ; i < typeArray . length ; i ++ ) {
if ( typeArray [ i ] && _ _ _cxa _can _catch ( typeArray [ i ] , throwntype , thrown ) ) {
thrown = HEAP32 [ ( ( thrown ) >> 2 ) ] ; // undo indirection
info . adjusted . push ( thrown ) ;
return ( ( setTempRet0 ( typeArray [ i ] ) , thrown ) | 0 ) ;
}
}
// Shouldn't happen unless we have bogus data in typeArray
// or encounter a type for which emscripten doesn't have suitable
// typeinfo defined. Best-efforts match just in case.
thrown = HEAP32 [ ( ( thrown ) >> 2 ) ] ; // undo indirection
return ( ( setTempRet0 ( throwntype ) , thrown ) | 0 ) ;
}
function _ _ _cxa _rethrow ( ) {
var ptr = _ _ _exception _caught . pop ( ) ;
ptr = _ _ _exception _deAdjust ( ptr ) ;
if ( ! _ _ _exception _infos [ ptr ] . rethrown ) {
// Only pop if the corresponding push was through rethrow_primary_exception
_ _ _exception _caught . push ( ptr ) ;
_ _ _exception _infos [ ptr ] . rethrown = true ;
}
_ _ _exception _last = ptr ;
throw ptr ;
}
function _ _ _cxa _throw ( ptr , type , destructor ) {
_ _ _exception _infos [ ptr ] = {
ptr : ptr ,
adjusted : [ ptr ] ,
type : type ,
destructor : destructor ,
refcount : 0 ,
caught : false ,
rethrown : false
} ;
_ _ _exception _last = ptr ;
if ( ! ( "uncaught_exception" in _ _ZSt18uncaught _exceptionv ) ) {
_ _ZSt18uncaught _exceptionv . uncaught _exceptions = 1 ;
} else {
_ _ZSt18uncaught _exceptionv . uncaught _exceptions ++ ;
}
throw ptr ;
}
function _ _ _cxa _uncaught _exceptions ( ) {
return _ _ZSt18uncaught _exceptionv . uncaught _exceptions ;
}
function setErrNo ( value ) {
HEAP32 [ ( ( _ _ _errno _location ( ) ) >> 2 ) ] = value ;
return value ;
} function _ _ _map _file ( pathname , size ) {
setErrNo ( 63 ) ;
return - 1 ;
}
function _ _ _resumeException ( ptr ) {
if ( ! _ _ _exception _last ) { _ _ _exception _last = ptr ; }
throw ptr ;
}
var PATH = { splitPath : function ( filename ) {
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/ ;
return splitPathRe . exec ( filename ) . slice ( 1 ) ;
} , normalizeArray : function ( 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 : function ( path ) {
var isAbsolute = path . charAt ( 0 ) === '/' ,
trailingSlash = path . substr ( - 1 ) === '/' ;
// Normalize the path
path = PATH . normalizeArray ( path . split ( '/' ) . filter ( function ( p ) {
return ! ! p ;
} ) , ! isAbsolute ) . join ( '/' ) ;
if ( ! path && ! isAbsolute ) {
path = '.' ;
}
if ( path && trailingSlash ) {
path += '/' ;
}
return ( isAbsolute ? '/' : '' ) + path ;
} , dirname : function ( path ) {
var result = PATH . splitPath ( path ) ,
root = result [ 0 ] ,
dir = result [ 1 ] ;
if ( ! root && ! dir ) {
// No dirname whatsoever
return '.' ;
}
if ( dir ) {
// It has a dirname, strip trailing slash
dir = dir . substr ( 0 , dir . length - 1 ) ;
}
return root + dir ;
} , basename : function ( path ) {
// EMSCRIPTEN return '/'' for '/', not an empty string
if ( path === '/' ) return '/' ;
var lastSlash = path . lastIndexOf ( '/' ) ;
if ( lastSlash === - 1 ) return path ;
return path . substr ( lastSlash + 1 ) ;
} , extname : function ( path ) {
return PATH . splitPath ( path ) [ 3 ] ;
} , join : function ( ) {
var paths = Array . prototype . slice . call ( arguments , 0 ) ;
return PATH . normalize ( paths . join ( '/' ) ) ;
} , join2 : function ( l , r ) {
return PATH . normalize ( l + '/' + r ) ;
} } ;
var 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 . charAt ( 0 ) === '/' ;
}
// 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 ( function ( p ) {
return ! ! p ;
} ) , ! resolvedAbsolute ) . join ( '/' ) ;
return ( ( resolvedAbsolute ? '/' : '' ) + resolvedPath ) || '.' ;
} , relative : function ( from , to ) {
from = PATH _FS . resolve ( from ) . substr ( 1 ) ;
to = PATH _FS . resolve ( to ) . substr ( 1 ) ;
function trim ( arr ) {
var start = 0 ;
for ( ; start < arr . length ; start ++ ) {
if ( arr [ start ] !== '' ) break ;
}
var end = arr . length - 1 ;
for ( ; end >= 0 ; end -- ) {
if ( arr [ end ] !== '' ) break ;
}
if ( start > end ) return [ ] ;
return arr . slice ( start , end - start + 1 ) ;
}
var fromParts = trim ( from . split ( '/' ) ) ;
var toParts = trim ( to . split ( '/' ) ) ;
var length = Math . min ( fromParts . length , toParts . length ) ;
var samePartsLength = length ;
for ( var i = 0 ; i < length ; i ++ ) {
if ( fromParts [ i ] !== toParts [ i ] ) {
samePartsLength = i ;
break ;
}
}
var outputParts = [ ] ;
for ( var i = samePartsLength ; i < fromParts . length ; i ++ ) {
outputParts . push ( '..' ) ;
}
outputParts = outputParts . concat ( toParts . slice ( samePartsLength ) ) ;
return outputParts . join ( '/' ) ;
} } ;
var TTY = { ttys : [ ] , init : function ( ) {
// 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 . flush ( stream . tty ) ;
} , flush : function ( stream ) {
stream . tty . ops . flush ( 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 ? Buffer . alloc ( BUFSIZE ) : new Buffer ( BUFSIZE ) ;
var bytesRead = 0 ;
try {
bytesRead = nodeFS . readSync ( process . stdin . fd , buf , 0 , BUFSIZE , null ) ;
} 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 ( ) . indexOf ( 'EOF' ) != - 1 ) bytesRead = 0 ;
else throw e ;
}
if ( bytesRead > 0 ) {
result = buf . slice ( 0 , bytesRead ) . toString ( 'utf-8' ) ;
} else {
result = null ;
}
} else
if ( typeof window != 'undefined' &&
typeof window . prompt == 'function' ) {
// 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.
}
} , flush : function ( tty ) {
if ( tty . output && tty . output . length > 0 ) {
out ( UTF8ArrayToString ( tty . output , 0 ) ) ;
tty . output = [ ] ;
}
} } , default _tty1 _ops : { put _char : function ( tty , val ) {
if ( val === null || val === 10 ) {
err ( UTF8ArrayToString ( tty . output , 0 ) ) ;
tty . output = [ ] ;
} else {
if ( val != 0 ) tty . output . push ( val ) ;
}
} , flush : function ( tty ) {
if ( tty . output && tty . output . length > 0 ) {
err ( UTF8ArrayToString ( tty . output , 0 ) ) ;
tty . output = [ ] ;
}
} } } ;
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 ;
}
return node ;
} , getFileDataAsRegularArray : function ( node ) {
if ( node . contents && node . contents . subarray ) {
var arr = [ ] ;
for ( var i = 0 ; i < node . usedBytes ; ++ i ) arr . push ( node . contents [ i ] ) ;
return arr ; // Returns a copy of the original data.
}
return node . contents ; // No-op, the file contents are already in a JS array. Return as-is.
} , 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.
return ;
} , 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 ;
return ;
}
if ( ! node . contents || node . contents . subarray ) { // Resize a typed array if that is being used as the backing store.
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 ;
return ;
}
// Backing with a JS array.
if ( ! node . contents ) node . contents = [ ] ;
if ( node . contents . length > newSize ) node . contents . length = newSize ;
else while ( node . contents . length < newSize ) node . contents . push ( 0 ) ;
node . usedBytes = newSize ;
} , node _ops : { getattr : function ( node ) {
var attr = { } ;
// 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 . name = new _name ;
new _dir . contents [ new _name ] = old _node ;
old _node . parent = new _dir ;
} , unlink : function ( parent , name ) {
delete parent . contents [ name ] ;
} , rmdir : function ( parent , name ) {
var node = FS . lookupNode ( parent , name ) ;
for ( var i in node . contents ) {
throw new FS . ErrnoError ( 55 ) ;
}
delete parent . contents [ name ] ;
} , readdir : function ( node ) {
var entries = [ '.' , '..' ] ;
for ( var key in node . contents ) {
if ( ! node . contents . hasOwnProperty ( key ) ) {
continue ;
}
entries . push ( key ) ;
}
return entries ;
} , symlink : function ( parent , newname , oldpath ) {
var node = MEMFS . createNode ( parent , newname , 511 /* 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 ) ;
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 ) {
// 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 ) {
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 ) node . contents . set ( buffer . subarray ( offset , offset + length ) , position ) ; // Use typed array write if available.
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 , address , length , position , prot , flags ) {
// We don't currently support location hints for the address of the mapping
assert ( address === 0 ) ;
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 === 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 = _malloc ( length ) ;
if ( ! ptr ) {
throw new FS . ErrnoError ( 48 ) ;
}
HEAP8 . set ( contents , ptr ) ;
}
return { ptr : ptr , allocated : allocated } ;
} , msync : function ( stream , buffer , offset , length , mmapFlags ) {
if ( ! FS . isFile ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 43 ) ;
}
if ( mmapFlags & 2 ) {
// MAP_PRIVATE calls need not to be synced back to underlying fs
return 0 ;
}
var bytesWritten = MEMFS . stream _ops . write ( stream , buffer , 0 , length , offset , false ) ;
// should we check if bytesWritten and length are the same?
return 0 ;
} } } ; var FS = { root : null , mounts : [ ] , devices : { } , streams : [ ] , nextInode : 1 , nameTable : null , currentPath : "/" , initialized : false , ignorePermissions : true , trackingDelegate : { } , tracking : { openFlags : { READ : 1 , WRITE : 2 } } , ErrnoError : null , genericErrors : { } , filesystems : null , syncFSRequests : 0 , handleFSError : function ( e ) {
if ( ! ( e instanceof FS . ErrnoError ) ) throw e + ' : ' + stackTrace ( ) ;
return setErrNo ( e . errno ) ;
} , lookupPath : function ( path , opts ) {
path = PATH _FS . resolve ( FS . cwd ( ) , path ) ;
opts = opts || { } ;
if ( ! path ) return { path : '' , node : null } ;
var defaults = {
follow _mount : true ,
recurse _count : 0
} ;
for ( var key in defaults ) {
if ( opts [ key ] === undefined ) {
opts [ key ] = defaults [ key ] ;
}
}
if ( opts . recurse _count > 8 ) { // max recursive lookup of 8
throw new FS . ErrnoError ( 32 ) ;
}
// split the path
var parts = PATH . normalizeArray ( path . split ( '/' ) . filter ( function ( p ) {
return ! ! p ;
} ) , false ) ;
// 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 } ) ;
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 : function ( node ) {
var path ;
while ( true ) {
if ( FS . isRoot ( node ) ) {
var mount = node . mount . mountpoint ;
if ( ! path ) return mount ;
return mount [ mount . length - 1 ] !== '/' ? mount + '/' + path : mount + path ;
}
path = path ? node . name + '/' + path : node . name ;
node = node . parent ;
}
} , hashName : function ( parentid , name ) {
var hash = 0 ;
for ( var i = 0 ; i < name . length ; i ++ ) {
hash = ( ( hash << 5 ) - hash + name . charCodeAt ( i ) ) | 0 ;
}
return ( ( parentid + hash ) >>> 0 ) % FS . nameTable . length ;
} , hashAddNode : function ( node ) {
var hash = FS . hashName ( node . parent . id , node . name ) ;
node . name _next = FS . nameTable [ hash ] ;
FS . nameTable [ hash ] = node ;
} , hashRemoveNode : function ( node ) {
var hash = FS . hashName ( node . parent . id , node . name ) ;
if ( FS . nameTable [ hash ] === node ) {
FS . nameTable [ hash ] = node . name _next ;
} else {
var current = FS . nameTable [ hash ] ;
while ( current ) {
if ( current . name _next === node ) {
current . name _next = node . name _next ;
break ;
}
current = current . name _next ;
}
}
} , lookupNode : function ( parent , name ) {
var errCode = FS . mayLookup ( parent ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode , parent ) ;
}
var hash = FS . hashName ( parent . id , name ) ;
for ( var node = FS . nameTable [ hash ] ; node ; node = node . name _next ) {
var nodeName = node . name ;
if ( node . parent . id === parent . id && nodeName === name ) {
return node ;
}
}
// if we failed to find it in the cache, call into the VFS
return FS . lookup ( parent , name ) ;
} , createNode : function ( parent , name , mode , rdev ) {
var node = new FS . FSNode ( parent , name , mode , rdev ) ;
FS . hashAddNode ( node ) ;
return node ;
} , destroyNode : function ( node ) {
FS . hashRemoveNode ( node ) ;
} , isRoot : function ( node ) {
return node === node . parent ;
} , isMountpoint : function ( node ) {
return ! ! node . mounted ;
} , isFile : function ( mode ) {
return ( mode & 61440 ) === 32768 ;
} , isDir : function ( mode ) {
return ( mode & 61440 ) === 16384 ;
} , isLink : function ( mode ) {
return ( mode & 61440 ) === 40960 ;
} , isChrdev : function ( mode ) {
return ( mode & 61440 ) === 8192 ;
} , isBlkdev : function ( mode ) {
return ( mode & 61440 ) === 24576 ;
} , isFIFO : function ( mode ) {
return ( mode & 61440 ) === 4096 ;
} , isSocket : function ( mode ) {
return ( mode & 49152 ) === 49152 ;
} , flagModes : { "r" : 0 , "rs" : 1052672 , "r+" : 2 , "w" : 577 , "wx" : 705 , "xw" : 705 , "w+" : 578 , "wx+" : 706 , "xw+" : 706 , "a" : 1089 , "ax" : 1217 , "xa" : 1217 , "a+" : 1090 , "ax+" : 1218 , "xa+" : 1218 } , modeStringToFlags : function ( str ) {
var flags = FS . flagModes [ str ] ;
if ( typeof flags === 'undefined' ) {
throw new Error ( 'Unknown file open mode: ' + str ) ;
}
return flags ;
} , flagsToPermissionString : function ( flag ) {
var perms = [ 'r' , 'w' , 'rw' ] [ flag & 3 ] ;
if ( ( flag & 512 ) ) {
perms += 'w' ;
}
return perms ;
} , nodePermissions : function ( node , perms ) {
if ( FS . ignorePermissions ) {
return 0 ;
}
// return 0 if any user, group or owner bits are set.
if ( perms . indexOf ( 'r' ) !== - 1 && ! ( node . mode & 292 ) ) {
return 2 ;
} else if ( perms . indexOf ( 'w' ) !== - 1 && ! ( node . mode & 146 ) ) {
return 2 ;
} else if ( perms . indexOf ( 'x' ) !== - 1 && ! ( node . mode & 73 ) ) {
return 2 ;
}
return 0 ;
} , mayLookup : function ( dir ) {
var errCode = FS . nodePermissions ( dir , 'x' ) ;
if ( errCode ) return errCode ;
if ( ! dir . node _ops . lookup ) return 2 ;
return 0 ;
} , mayCreate : function ( dir , name ) {
try {
var node = FS . lookupNode ( dir , name ) ;
return 20 ;
} catch ( e ) {
}
return FS . nodePermissions ( dir , 'wx' ) ;
} , mayDelete : function ( dir , name , isdir ) {
var node ;
try {
node = FS . lookupNode ( dir , name ) ;
} catch ( e ) {
return e . errno ;
}
var errCode = FS . nodePermissions ( dir , 'wx' ) ;
if ( errCode ) {
return errCode ;
}
if ( isdir ) {
if ( ! FS . isDir ( node . mode ) ) {
return 54 ;
}
if ( FS . isRoot ( node ) || FS . getPath ( node ) === FS . cwd ( ) ) {
return 10 ;
}
} else {
if ( FS . isDir ( node . mode ) ) {
return 31 ;
}
}
return 0 ;
} , mayOpen : function ( node , flags ) {
if ( ! node ) {
return 44 ;
}
if ( FS . isLink ( node . mode ) ) {
return 32 ;
} else if ( FS . isDir ( node . mode ) ) {
if ( FS . flagsToPermissionString ( flags ) !== 'r' || // 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 : function ( fd _start , fd _end ) {
fd _start = fd _start || 0 ;
fd _end = fd _end || FS . MAX _OPEN _FDS ;
for ( var fd = fd _start ; fd <= fd _end ; fd ++ ) {
if ( ! FS . streams [ fd ] ) {
return fd ;
}
}
throw new FS . ErrnoError ( 33 ) ;
} , getStream : function ( fd ) {
return FS . streams [ fd ] ;
} , createStream : function ( stream , fd _start , fd _end ) {
if ( ! FS . FSStream ) {
FS . FSStream = /** @constructor */ function ( ) { } ;
FS . FSStream . prototype = {
object : {
get : function ( ) { return this . node ; } ,
set : function ( val ) { this . node = val ; }
} ,
isRead : {
get : function ( ) { return ( this . flags & 2097155 ) !== 1 ; }
} ,
isWrite : {
get : function ( ) { return ( this . flags & 2097155 ) !== 0 ; }
} ,
isAppend : {
get : function ( ) { return ( this . flags & 1024 ) ; }
}
} ;
}
// clone it, so we can return an instance of FSStream
var newStream = new FS . FSStream ( ) ;
for ( var p in stream ) {
newStream [ p ] = stream [ p ] ;
}
stream = newStream ;
var fd = FS . nextfd ( fd _start , fd _end ) ;
stream . fd = fd ;
FS . streams [ fd ] = stream ;
return stream ;
} , closeStream : function ( fd ) {
FS . streams [ fd ] = null ;
} , chrdev _stream _ops : { open : function ( stream ) {
var device = FS . getDevice ( stream . node . rdev ) ;
// 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 : function ( ) {
throw new FS . ErrnoError ( 70 ) ;
} } , major : function ( dev ) {
return ( ( dev ) >> 8 ) ;
} , minor : function ( dev ) {
return ( ( dev ) & 0xff ) ;
} , makedev : function ( ma , mi ) {
return ( ( ma ) << 8 | ( mi ) ) ;
} , registerDevice : function ( dev , ops ) {
FS . devices [ dev ] = { stream _ops : ops } ;
} , getDevice : function ( dev ) {
return FS . devices [ dev ] ;
} , getMounts : function ( mount ) {
var mounts = [ ] ;
var check = [ mount ] ;
while ( check . length ) {
var m = check . pop ( ) ;
mounts . push ( m ) ;
check . push . apply ( check , m . mounts ) ;
}
return mounts ;
} , syncfs : function ( populate , callback ) {
if ( typeof ( populate ) === 'function' ) {
callback = populate ;
populate = false ;
}
FS . syncFSRequests ++ ;
if ( FS . syncFSRequests > 1 ) {
err ( 'warning: ' + FS . syncFSRequests + ' FS.syncfs operations in flight at once, probably just doing extra work' ) ;
}
var mounts = FS . getMounts ( FS . root . mount ) ;
var completed = 0 ;
function doCallback ( errCode ) {
FS . syncFSRequests -- ;
return callback ( errCode ) ;
}
function done ( errCode ) {
if ( errCode ) {
if ( ! done . errored ) {
done . errored = true ;
return doCallback ( errCode ) ;
}
return ;
}
if ( ++ completed >= mounts . length ) {
doCallback ( null ) ;
}
} ;
// sync all mounts
mounts . forEach ( function ( mount ) {
if ( ! mount . type . syncfs ) {
return done ( null ) ;
}
mount . type . syncfs ( mount , populate , done ) ;
} ) ;
} , mount : function ( type , opts , mountpoint ) {
var root = mountpoint === '/' ;
var pseudo = ! mountpoint ;
var node ;
if ( root && FS . root ) {
throw new FS . ErrnoError ( 10 ) ;
} else if ( ! root && ! pseudo ) {
var lookup = FS . lookupPath ( mountpoint , { follow _mount : false } ) ;
mountpoint = lookup . path ; // 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 : function ( 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 ( function ( hash ) {
var current = FS . nameTable [ hash ] ;
while ( current ) {
var next = current . name _next ;
if ( mounts . indexOf ( current . mount ) !== - 1 ) {
FS . destroyNode ( current ) ;
}
current = next ;
}
} ) ;
// no longer a mountpoint
node . mounted = null ;
// remove this mount from the child mounts
var idx = node . mount . mounts . indexOf ( mount ) ;
node . mount . mounts . splice ( idx , 1 ) ;
} , lookup : function ( parent , name ) {
return parent . node _ops . lookup ( parent , name ) ;
} , mknod : function ( path , mode , dev ) {
var lookup = FS . lookupPath ( path , { parent : true } ) ;
var parent = lookup . node ;
var name = PATH . basename ( path ) ;
if ( ! name || name === '.' || name === '..' ) {
throw new FS . ErrnoError ( 28 ) ;
}
var errCode = FS . mayCreate ( parent , name ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
if ( ! parent . node _ops . mknod ) {
throw new FS . ErrnoError ( 63 ) ;
}
return parent . node _ops . mknod ( parent , name , mode , dev ) ;
} , create : function ( path , mode ) {
mode = mode !== undefined ? mode : 438 /* 0666 */ ;
mode &= 4095 ;
mode |= 32768 ;
return FS . mknod ( path , mode , 0 ) ;
} , mkdir : function ( path , mode ) {
mode = mode !== undefined ? mode : 511 /* 0777 */ ;
mode &= 511 | 512 ;
mode |= 16384 ;
return FS . mknod ( path , mode , 0 ) ;
} , mkdirTree : function ( path , mode ) {
var dirs = path . split ( '/' ) ;
var d = '' ;
for ( var i = 0 ; i < dirs . length ; ++ i ) {
if ( ! dirs [ i ] ) continue ;
d += '/' + dirs [ i ] ;
try {
FS . mkdir ( d , mode ) ;
} catch ( e ) {
if ( e . errno != 20 ) throw e ;
}
}
} , mkdev : function ( path , mode , dev ) {
if ( typeof ( dev ) === 'undefined' ) {
dev = mode ;
mode = 438 /* 0666 */ ;
}
mode |= 8192 ;
return FS . mknod ( path , mode , dev ) ;
} , symlink : function ( oldpath , newpath ) {
if ( ! PATH _FS . resolve ( oldpath ) ) {
throw new FS . ErrnoError ( 44 ) ;
}
var lookup = FS . lookupPath ( newpath , { parent : true } ) ;
var parent = lookup . node ;
if ( ! parent ) {
throw new FS . ErrnoError ( 44 ) ;
}
var newname = PATH . basename ( newpath ) ;
var errCode = FS . mayCreate ( parent , newname ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
if ( ! parent . node _ops . symlink ) {
throw new FS . ErrnoError ( 63 ) ;
}
return parent . node _ops . symlink ( parent , newname , oldpath ) ;
} , rename : function ( old _path , new _path ) {
var old _dirname = PATH . dirname ( old _path ) ;
var new _dirname = PATH . dirname ( new _path ) ;
var old _name = PATH . basename ( old _path ) ;
var new _name = PATH . basename ( new _path ) ;
// parents must exist
var lookup , old _dir , new _dir ;
try {
lookup = FS . lookupPath ( old _path , { parent : true } ) ;
old _dir = lookup . node ;
lookup = FS . lookupPath ( new _path , { parent : true } ) ;
new _dir = lookup . node ;
} catch ( e ) {
throw new FS . ErrnoError ( 10 ) ;
}
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 ) ;
}
}
try {
if ( FS . trackingDelegate [ 'willMovePath' ] ) {
FS . trackingDelegate [ 'willMovePath' ] ( old _path , new _path ) ;
}
} catch ( e ) {
err ( "FS.trackingDelegate['willMovePath']('" + old _path + "', '" + new _path + "') threw an exception: " + e . message ) ;
}
// 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 ) ;
}
try {
if ( FS . trackingDelegate [ 'onMovePath' ] ) FS . trackingDelegate [ 'onMovePath' ] ( old _path , new _path ) ;
} catch ( e ) {
err ( "FS.trackingDelegate['onMovePath']('" + old _path + "', '" + new _path + "') threw an exception: " + e . message ) ;
}
} , rmdir : function ( path ) {
var lookup = FS . lookupPath ( path , { parent : true } ) ;
var parent = lookup . node ;
var name = PATH . basename ( path ) ;
var node = FS . lookupNode ( parent , name ) ;
var errCode = FS . mayDelete ( parent , name , true ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
if ( ! parent . node _ops . rmdir ) {
throw new FS . ErrnoError ( 63 ) ;
}
if ( FS . isMountpoint ( node ) ) {
throw new FS . ErrnoError ( 10 ) ;
}
try {
if ( FS . trackingDelegate [ 'willDeletePath' ] ) {
FS . trackingDelegate [ 'willDeletePath' ] ( path ) ;
}
} catch ( e ) {
err ( "FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e . message ) ;
}
parent . node _ops . rmdir ( parent , name ) ;
FS . destroyNode ( node ) ;
try {
if ( FS . trackingDelegate [ 'onDeletePath' ] ) FS . trackingDelegate [ 'onDeletePath' ] ( path ) ;
} catch ( e ) {
err ( "FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e . message ) ;
}
} , readdir : function ( path ) {
var lookup = FS . lookupPath ( path , { follow : true } ) ;
var node = lookup . node ;
if ( ! node . node _ops . readdir ) {
throw new FS . ErrnoError ( 54 ) ;
}
return node . node _ops . readdir ( node ) ;
} , unlink : function ( path ) {
var lookup = FS . lookupPath ( path , { parent : true } ) ;
var parent = lookup . node ;
var name = PATH . basename ( path ) ;
var node = FS . lookupNode ( parent , name ) ;
var errCode = FS . mayDelete ( parent , name , false ) ;
if ( errCode ) {
// 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 ) ;
}
try {
if ( FS . trackingDelegate [ 'willDeletePath' ] ) {
FS . trackingDelegate [ 'willDeletePath' ] ( path ) ;
}
} catch ( e ) {
err ( "FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e . message ) ;
}
parent . node _ops . unlink ( parent , name ) ;
FS . destroyNode ( node ) ;
try {
if ( FS . trackingDelegate [ 'onDeletePath' ] ) FS . trackingDelegate [ 'onDeletePath' ] ( path ) ;
} catch ( e ) {
err ( "FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e . message ) ;
}
} , readlink : function ( path ) {
var lookup = FS . lookupPath ( path ) ;
var link = lookup . node ;
if ( ! link ) {
throw new FS . ErrnoError ( 44 ) ;
}
if ( ! link . node _ops . readlink ) {
throw new FS . ErrnoError ( 28 ) ;
}
return PATH _FS . resolve ( FS . getPath ( link . parent ) , link . node _ops . readlink ( link ) ) ;
} , stat : function ( path , dontFollow ) {
var lookup = FS . lookupPath ( path , { follow : ! dontFollow } ) ;
var node = lookup . node ;
if ( ! node ) {
throw new FS . ErrnoError ( 44 ) ;
}
if ( ! node . node _ops . getattr ) {
throw new FS . ErrnoError ( 63 ) ;
}
return node . node _ops . getattr ( node ) ;
} , lstat : function ( path ) {
return FS . stat ( path , true ) ;
} , chmod : function ( path , mode , dontFollow ) {
var node ;
if ( typeof path === 'string' ) {
var lookup = FS . lookupPath ( path , { follow : ! dontFollow } ) ;
node = lookup . node ;
} else {
node = path ;
}
if ( ! node . node _ops . setattr ) {
throw new FS . ErrnoError ( 63 ) ;
}
node . node _ops . setattr ( node , {
mode : ( mode & 4095 ) | ( node . mode & ~ 4095 ) ,
timestamp : Date . now ( )
} ) ;
} , lchmod : function ( path , mode ) {
FS . chmod ( path , mode , true ) ;
} , fchmod : function ( fd , mode ) {
var stream = FS . getStream ( fd ) ;
if ( ! stream ) {
throw new FS . ErrnoError ( 8 ) ;
}
FS . chmod ( stream . node , mode ) ;
} , chown : function ( path , uid , gid , dontFollow ) {
var node ;
if ( typeof path === 'string' ) {
var lookup = FS . lookupPath ( path , { follow : ! dontFollow } ) ;
node = lookup . node ;
} else {
node = path ;
}
if ( ! node . node _ops . setattr ) {
throw new FS . ErrnoError ( 63 ) ;
}
node . node _ops . setattr ( node , {
timestamp : Date . now ( )
// we ignore the uid / gid for now
} ) ;
} , lchown : function ( path , uid , gid ) {
FS . chown ( path , uid , gid , true ) ;
} , fchown : function ( fd , uid , gid ) {
var stream = FS . getStream ( fd ) ;
if ( ! stream ) {
throw new FS . ErrnoError ( 8 ) ;
}
FS . chown ( stream . node , uid , gid ) ;
} , truncate : function ( path , len ) {
if ( len < 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
var node ;
if ( typeof path === 'string' ) {
var lookup = FS . lookupPath ( path , { follow : true } ) ;
node = lookup . node ;
} else {
node = path ;
}
if ( ! node . node _ops . setattr ) {
throw new FS . ErrnoError ( 63 ) ;
}
if ( FS . isDir ( node . mode ) ) {
throw new FS . ErrnoError ( 31 ) ;
}
if ( ! FS . isFile ( node . mode ) ) {
throw new FS . ErrnoError ( 28 ) ;
}
var errCode = FS . nodePermissions ( node , 'w' ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
node . node _ops . setattr ( node , {
size : len ,
timestamp : Date . now ( )
} ) ;
} , ftruncate : function ( fd , len ) {
var stream = FS . getStream ( fd ) ;
if ( ! stream ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ( stream . flags & 2097155 ) === 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
FS . truncate ( stream . node , len ) ;
} , utime : function ( path , atime , mtime ) {
var lookup = FS . lookupPath ( path , { follow : true } ) ;
var node = lookup . node ;
node . node _ops . setattr ( node , {
timestamp : Math . max ( atime , mtime )
} ) ;
} , open : function ( path , flags , mode , fd _start , fd _end ) {
if ( path === "" ) {
throw new FS . ErrnoError ( 44 ) ;
}
flags = typeof flags === 'string' ? FS . modeStringToFlags ( flags ) : flags ;
mode = typeof mode === 'undefined' ? 438 /* 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 ) ) {
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
} , fd _start , fd _end ) ;
// 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 ;
err ( "FS.trackingDelegate error on read file: " + path ) ;
}
}
try {
if ( FS . trackingDelegate [ 'onOpenFile' ] ) {
var trackingFlags = 0 ;
if ( ( flags & 2097155 ) !== 1 ) {
trackingFlags |= FS . tracking . openFlags . READ ;
}
if ( ( flags & 2097155 ) !== 0 ) {
trackingFlags |= FS . tracking . openFlags . WRITE ;
}
FS . trackingDelegate [ 'onOpenFile' ] ( path , trackingFlags ) ;
}
} catch ( e ) {
err ( "FS.trackingDelegate['onOpenFile']('" + path + "', flags) threw an exception: " + e . message ) ;
}
return stream ;
} , close : function ( stream ) {
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( stream . getdents ) stream . getdents = null ; // 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 : function ( stream ) {
return stream . fd === null ;
} , llseek : function ( stream , offset , whence ) {
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ! stream . seekable || ! stream . stream _ops . llseek ) {
throw new FS . ErrnoError ( 70 ) ;
}
if ( whence != 0 && whence != 1 && whence != 2 ) {
throw new FS . ErrnoError ( 28 ) ;
}
stream . position = stream . stream _ops . llseek ( stream , offset , whence ) ;
stream . ungotten = [ ] ;
return stream . position ;
} , read : function ( stream , buffer , offset , length , position ) {
if ( length < 0 || position < 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ( stream . flags & 2097155 ) === 1 ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( FS . isDir ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 31 ) ;
}
if ( ! stream . stream _ops . read ) {
throw new FS . ErrnoError ( 28 ) ;
}
var seeking = typeof position !== 'undefined' ;
if ( ! seeking ) {
position = stream . position ;
} else if ( ! stream . seekable ) {
throw new FS . ErrnoError ( 70 ) ;
}
var bytesRead = stream . stream _ops . read ( stream , buffer , offset , length , position ) ;
if ( ! seeking ) stream . position += bytesRead ;
return bytesRead ;
} , write : function ( stream , buffer , offset , length , position , canOwn ) {
if ( length < 0 || position < 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ( stream . flags & 2097155 ) === 0 ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( FS . isDir ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 31 ) ;
}
if ( ! stream . stream _ops . write ) {
throw new FS . ErrnoError ( 28 ) ;
}
if ( stream . seekable && stream . flags & 1024 ) {
// 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 ;
try {
if ( stream . path && FS . trackingDelegate [ 'onWriteToFile' ] ) FS . trackingDelegate [ 'onWriteToFile' ] ( stream . path ) ;
} catch ( e ) {
err ( "FS.trackingDelegate['onWriteToFile']('" + stream . path + "') threw an exception: " + e . message ) ;
}
return bytesWritten ;
} , allocate : function ( stream , offset , length ) {
if ( FS . isClosed ( stream ) ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( offset < 0 || length <= 0 ) {
throw new FS . ErrnoError ( 28 ) ;
}
if ( ( stream . flags & 2097155 ) === 0 ) {
throw new FS . ErrnoError ( 8 ) ;
}
if ( ! FS . isFile ( stream . node . mode ) && ! FS . isDir ( stream . node . mode ) ) {
throw new FS . ErrnoError ( 43 ) ;
}
if ( ! stream . stream _ops . allocate ) {
throw new FS . ErrnoError ( 138 ) ;
}
stream . stream _ops . allocate ( stream , offset , length ) ;
} , mmap : function ( stream , address , length , position , prot , flags ) {
// 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 , address , length , position , prot , flags ) ;
} , msync : function ( stream , buffer , offset , length , mmapFlags ) {
if ( ! stream || ! stream . stream _ops . msync ) {
return 0 ;
}
return stream . stream _ops . msync ( stream , buffer , offset , length , mmapFlags ) ;
} , munmap : function ( stream ) {
return 0 ;
} , ioctl : function ( stream , cmd , arg ) {
if ( ! stream . stream _ops . ioctl ) {
throw new FS . ErrnoError ( 59 ) ;
}
return stream . stream _ops . ioctl ( stream , cmd , arg ) ;
} , readFile : function ( path , opts ) {
opts = opts || { } ;
opts . flags = opts . flags || 'r' ;
opts . encoding = opts . encoding || 'binary' ;
if ( opts . encoding !== 'utf8' && opts . encoding !== 'binary' ) {
throw new Error ( 'Invalid encoding type "' + opts . encoding + '"' ) ;
}
var ret ;
var stream = FS . open ( path , opts . flags ) ;
var stat = FS . stat ( path ) ;
var length = stat . size ;
var buf = new Uint8Array ( length ) ;
FS . read ( stream , buf , 0 , length , 0 ) ;
if ( opts . encoding === 'utf8' ) {
ret = UTF8ArrayToString ( buf , 0 ) ;
} else if ( opts . encoding === 'binary' ) {
ret = buf ;
}
FS . close ( stream ) ;
return ret ;
} , writeFile : function ( path , data , opts ) {
opts = opts || { } ;
opts . flags = opts . flags || 'w' ;
var stream = FS . open ( path , opts . flags , opts . mode ) ;
if ( typeof data === 'string' ) {
var buf = new Uint8Array ( lengthBytesUTF8 ( data ) + 1 ) ;
var actualNumBytes = stringToUTF8Array ( data , buf , 0 , buf . length ) ;
FS . write ( stream , buf , 0 , actualNumBytes , undefined , opts . canOwn ) ;
} else if ( ArrayBuffer . isView ( data ) ) {
FS . write ( stream , data , 0 , data . byteLength , undefined , opts . canOwn ) ;
} else {
throw new Error ( 'Unsupported data type' ) ;
}
FS . close ( stream ) ;
} , cwd : function ( ) {
return FS . currentPath ;
} , chdir : function ( path ) {
var lookup = FS . lookupPath ( path , { follow : true } ) ;
if ( lookup . node === null ) {
throw new FS . ErrnoError ( 44 ) ;
}
if ( ! FS . isDir ( lookup . node . mode ) ) {
throw new FS . ErrnoError ( 54 ) ;
}
var errCode = FS . nodePermissions ( lookup . node , 'x' ) ;
if ( errCode ) {
throw new FS . ErrnoError ( errCode ) ;
}
FS . currentPath = lookup . path ;
} , createDefaultDirectories : function ( ) {
FS . mkdir ( '/tmp' ) ;
FS . mkdir ( '/home' ) ;
FS . mkdir ( '/home/web_user' ) ;
} , createDefaultDevices : function ( ) {
// create /dev
FS . mkdir ( '/dev' ) ;
// setup /dev/null
FS . registerDevice ( FS . makedev ( 1 , 3 ) , {
read : function ( ) { return 0 ; } ,
write : function ( stream , buffer , offset , length , pos ) { return length ; }
} ) ;
FS . mkdev ( '/dev/null' , FS . makedev ( 1 , 3 ) ) ;
// setup /dev/tty and /dev/tty1
// stderr needs to print output using Module['printErr']
// 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
var random _device ;
if ( typeof crypto === 'object' && typeof crypto [ 'getRandomValues' ] === 'function' ) {
// for modern web browsers
var randomBuffer = new Uint8Array ( 1 ) ;
random _device = function ( ) { crypto . getRandomValues ( randomBuffer ) ; return randomBuffer [ 0 ] ; } ;
} else
if ( ENVIRONMENT _IS _NODE ) {
// for nodejs with or without crypto support included
try {
var crypto _module = require ( 'crypto' ) ;
// nodejs has crypto support
random _device = function ( ) { return crypto _module [ 'randomBytes' ] ( 1 ) [ 0 ] ; } ;
} catch ( e ) {
// nodejs doesn't have crypto support
}
} else
{ }
if ( ! random _device ) {
// we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
random _device = function ( ) { abort ( "random_device" ) ; } ;
}
FS . createDevice ( '/dev' , 'random' , random _device ) ;
FS . createDevice ( '/dev' , 'urandom' , random _device ) ;
// 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 : function ( ) {
// 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' ) ;
FS . mkdir ( '/proc/self' ) ;
FS . mkdir ( '/proc/self/fd' ) ;
FS . mount ( {
mount : function ( ) {
var node = FS . createNode ( '/proc/self' , 'fd' , 16384 | 511 /* 0777 */ , 73 ) ;
node . node _ops = {
lookup : function ( parent , name ) {
var fd = + name ;
var stream = FS . getStream ( fd ) ;
if ( ! stream ) throw new FS . ErrnoError ( 8 ) ;
var ret = {
parent : null ,
mount : { mountpoint : 'fake' } ,
node _ops : { readlink : function ( ) { return stream . path } }
} ;
ret . parent = ret ; // make it look like a simple root node
return ret ;
}
} ;
return node ;
}
} , { } , '/proc/self/fd' ) ;
} , createStandardStreams : function ( ) {
// 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' , 'r' ) ;
var stdout = FS . open ( '/dev/stdout' , 'w' ) ;
var stderr = FS . open ( '/dev/stderr' , 'w' ) ;
} , ensureErrnoError : function ( ) {
if ( FS . ErrnoError ) return ;
FS . ErrnoError = /** @this{Object} */ function ErrnoError ( errno , node ) {
this . node = node ;
this . setErrno = /** @this{Object} */ function ( errno ) {
this . errno = errno ;
} ;
this . setErrno ( errno ) ;
this . message = 'FS error' ;
} ;
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 ( function ( code ) {
FS . genericErrors [ code ] = new FS . ErrnoError ( code ) ;
FS . genericErrors [ code ] . stack = '<generic error, no stack>' ;
} ) ;
} , staticInit : function ( ) {
FS . ensureErrnoError ( ) ;
FS . nameTable = new Array ( 4096 ) ;
FS . mount ( MEMFS , { } , '/' ) ;
FS . createDefaultDirectories ( ) ;
FS . createDefaultDevices ( ) ;
FS . createSpecialDirectories ( ) ;
FS . filesystems = {
'MEMFS' : MEMFS ,
} ;
} , init : function ( input , output , error ) {
FS . init . initialized = true ;
FS . ensureErrnoError ( ) ;
// 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 : function ( ) {
FS . init . initialized = false ;
// force-flush all streams, so we get musl std streams printed out
var fflush = Module [ '_fflush' ] ;
if ( fflush ) 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 ) ;
}
} , getMode : function ( canRead , canWrite ) {
var mode = 0 ;
if ( canRead ) mode |= 292 | 73 ;
if ( canWrite ) mode |= 146 ;
return mode ;
} , joinPath : function ( parts , forceRelative ) {
var path = PATH . join . apply ( null , parts ) ;
if ( forceRelative && path [ 0 ] == '/' ) path = path . substr ( 1 ) ;
return path ;
} , absolutePath : function ( relative , base ) {
return PATH _FS . resolve ( base , relative ) ;
} , standardizePath : function ( path ) {
return PATH . normalize ( path ) ;
} , findObject : function ( path , dontResolveLastLink ) {
var ret = FS . analyzePath ( path , dontResolveLastLink ) ;
if ( ret . exists ) {
return ret . object ;
} else {
setErrNo ( ret . error ) ;
return null ;
}
} , analyzePath : function ( path , dontResolveLastLink ) {
// 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 ;
} , createFolder : function ( parent , name , canRead , canWrite ) {
var path = PATH . join2 ( typeof parent === 'string' ? parent : FS . getPath ( parent ) , name ) ;
var mode = FS . getMode ( canRead , canWrite ) ;
return FS . mkdir ( path , mode ) ;
} , createPath : function ( parent , path , canRead , canWrite ) {
parent = typeof parent === 'string' ? parent : FS . getPath ( parent ) ;
var parts = path . split ( '/' ) . reverse ( ) ;
while ( parts . length ) {
var part = parts . pop ( ) ;
if ( ! part ) continue ;
var current = PATH . join2 ( parent , part ) ;
try {
FS . mkdir ( current ) ;
} catch ( e ) {
// ignore EEXIST
}
parent = current ;
}
return current ;
} , createFile : function ( parent , name , properties , canRead , canWrite ) {
var path = PATH . join2 ( typeof parent === 'string' ? parent : FS . getPath ( parent ) , name ) ;
var mode = FS . getMode ( canRead , canWrite ) ;
return FS . create ( path , mode ) ;
} , createDataFile : function ( parent , name , data , canRead , canWrite , canOwn ) {
var path = name ? PATH . join2 ( typeof parent === 'string' ? parent : FS . getPath ( parent ) , name ) : parent ;
var mode = FS . getMode ( canRead , canWrite ) ;
var node = FS . create ( path , mode ) ;
if ( data ) {
if ( typeof data === 'string' ) {
var arr = new Array ( data . length ) ;
for ( var i = 0 , len = data . length ; i < len ; ++ i ) arr [ i ] = data . charCodeAt ( i ) ;
data = arr ;
}
// make sure we can write to the file
FS . chmod ( node , mode | 146 ) ;
var stream = FS . open ( node , 'w' ) ;
FS . write ( stream , data , 0 , data . length , 0 , canOwn ) ;
FS . close ( stream ) ;
FS . chmod ( node , mode ) ;
}
return node ;
} , createDevice : function ( parent , name , input , output ) {
var path = PATH . join2 ( typeof parent === 'string' ? parent : FS . getPath ( parent ) , name ) ;
var mode = FS . getMode ( ! ! input , ! ! output ) ;
if ( ! FS . createDevice . major ) FS . createDevice . major = 64 ;
var dev = FS . makedev ( FS . createDevice . major ++ , 0 ) ;
// Create a fake device that a set of stream ops to emulate
// the old behavior.
FS . registerDevice ( dev , {
open : function ( stream ) {
stream . seekable = false ;
} ,
close : function ( stream ) {
// flush any pending line data
if ( output && output . buffer && output . buffer . length ) {
output ( 10 ) ;
}
} ,
read : function ( 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 : function ( stream , buffer , offset , length , pos ) {
for ( var i = 0 ; i < length ; i ++ ) {
try {
output ( buffer [ offset + i ] ) ;
} catch ( e ) {
throw new FS . ErrnoError ( 29 ) ;
}
}
if ( length ) {
stream . node . timestamp = Date . now ( ) ;
}
return i ;
}
} ) ;
return FS . mkdev ( path , mode , dev ) ;
} , createLink : function ( parent , name , target , canRead , canWrite ) {
var path = PATH . join2 ( typeof parent === 'string' ? parent : FS . getPath ( parent ) , name ) ;
return FS . symlink ( target , path ) ;
} , forceLoadFile : function ( obj ) {
if ( obj . isDevice || obj . isFolder || obj . link || obj . contents ) return true ;
var success = true ;
if ( typeof XMLHttpRequest !== 'undefined' ) {
throw new Error ( "Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread." ) ;
} else if ( 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 ) {
success = false ;
}
} else {
throw new Error ( 'Cannot load without read() or XMLHttpRequest.' ) ;
}
if ( ! success ) setErrNo ( 29 ) ;
return success ;
} , createLazyFile : function ( 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 = ( function ( from , to ) {
if ( from > to ) throw new Error ( "invalid range (" + from + ", " + to + ") or no bytes requested!" ) ;
if ( to > datalength - 1 ) throw new Error ( "only " + datalength + " bytes available! programmer error!" ) ;
// 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.
if ( typeof Uint8Array != 'undefined' ) xhr . responseType = 'arraybuffer' ;
if ( xhr . overrideMimeType ) {
xhr . overrideMimeType ( 'text/plain; charset=x-user-defined' ) ;
}
xhr . send ( null ) ;
if ( ! ( xhr . status >= 200 && xhr . status < 300 || xhr . status === 304 ) ) throw new Error ( "Couldn't load " + url + ". Status: " + xhr . status ) ;
if ( xhr . response !== undefined ) {
return new Uint8Array ( /** @type{Array<number>} */ ( xhr . response || [ ] ) ) ;
} else {
return intArrayFromString ( xhr . responseText || '' , true ) ;
}
} ) ;
var lazyArray = this ;
lazyArray . setDataGetter ( function ( chunkNum ) {
var start = chunkNum * chunkSize ;
var end = ( chunkNum + 1 ) * chunkSize - 1 ; // 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 ( function ( key ) {
var fn = node . stream _ops [ key ] ;
stream _ops [ key ] = function forceLoadLazyFile ( ) {
if ( ! FS . forceLoadFile ( node ) ) {
throw new FS . ErrnoError ( 29 ) ;
}
return fn . apply ( null , arguments ) ;
} ;
} ) ;
// use a custom read function
stream _ops . read = function stream _ops _read ( stream , buffer , offset , length , position ) {
if ( ! FS . forceLoadFile ( node ) ) {
throw new FS . ErrnoError ( 29 ) ;
}
var contents = stream . node . contents ;
if ( position >= contents . length )
return 0 ;
var size = Math . min ( contents . length - position , length ) ;
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 ;
} ;
node . stream _ops = stream _ops ;
return node ;
} , createPreloadedFile : function ( parent , name , url , canRead , canWrite , onload , onerror , dontCreateFile , canOwn , preFinish ) {
Browser . init ( ) ; // XXX perhaps this method should move onto Browser?
// 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 ) ;
}
var handled = false ;
Module [ 'preloadPlugins' ] . forEach ( function ( plugin ) {
if ( handled ) return ;
if ( plugin [ 'canHandle' ] ( fullname ) ) {
plugin [ 'handle' ] ( byteArray , fullname , finish , function ( ) {
if ( onerror ) onerror ( ) ;
removeRunDependency ( dep ) ;
} ) ;
handled = true ;
}
} ) ;
if ( ! handled ) finish ( byteArray ) ;
}
addRunDependency ( dep ) ;
if ( typeof url == 'string' ) {
Browser . asyncLoad ( url , function ( byteArray ) {
processData ( byteArray ) ;
} , onerror ) ;
} else {
processData ( url ) ;
}
} , indexedDB : function ( ) {
return window . indexedDB || window . mozIndexedDB || window . webkitIndexedDB || window . msIndexedDB ;
} , DB _NAME : function ( ) {
return 'EM_FS_' + window . location . pathname ;
} , DB _VERSION : 20 , DB _STORE _NAME : "FILE_DATA" , saveFilesToDB : function ( paths , onload , onerror ) {
onload = onload || function ( ) { } ;
onerror = onerror || function ( ) { } ;
var indexedDB = FS . indexedDB ( ) ;
try {
var openRequest = indexedDB . open ( FS . DB _NAME ( ) , FS . DB _VERSION ) ;
} catch ( e ) {
return onerror ( e ) ;
}
openRequest . onupgradeneeded = function openRequest _onupgradeneeded ( ) {
out ( 'creating db' ) ;
var db = openRequest . result ;
db . createObjectStore ( FS . DB _STORE _NAME ) ;
} ;
openRequest . onsuccess = function openRequest _onsuccess ( ) {
var db = openRequest . result ;
var transaction = db . transaction ( [ FS . DB _STORE _NAME ] , 'readwrite' ) ;
var files = transaction . objectStore ( FS . DB _STORE _NAME ) ;
var ok = 0 , fail = 0 , total = paths . length ;
function finish ( ) {
if ( fail == 0 ) onload ( ) ; else onerror ( ) ;
}
paths . forEach ( function ( path ) {
var putRequest = files . put ( FS . analyzePath ( path ) . object . contents , path ) ;
putRequest . onsuccess = function putRequest _onsuccess ( ) { ok ++ ; if ( ok + fail == total ) finish ( ) } ;
putRequest . onerror = function putRequest _onerror ( ) { fail ++ ; if ( ok + fail == total ) finish ( ) } ;
} ) ;
transaction . onerror = onerror ;
} ;
openRequest . onerror = onerror ;
} , loadFilesFromDB : function ( paths , onload , onerror ) {
onload = onload || function ( ) { } ;
onerror = onerror || function ( ) { } ;
var indexedDB = FS . indexedDB ( ) ;
try {
var openRequest = indexedDB . open ( FS . DB _NAME ( ) , FS . DB _VERSION ) ;
} catch ( e ) {
return onerror ( e ) ;
}
openRequest . onupgradeneeded = onerror ; // no database to load from
openRequest . onsuccess = function openRequest _onsuccess ( ) {
var db = openRequest . result ;
try {
var transaction = db . transaction ( [ FS . DB _STORE _NAME ] , 'readonly' ) ;
} catch ( e ) {
onerror ( e ) ;
return ;
}
var files = transaction . objectStore ( FS . DB _STORE _NAME ) ;
var ok = 0 , fail = 0 , total = paths . length ;
function finish ( ) {
if ( fail == 0 ) onload ( ) ; else onerror ( ) ;
}
paths . forEach ( function ( path ) {
var getRequest = files . get ( path ) ;
getRequest . onsuccess = function getRequest _onsuccess ( ) {
if ( FS . analyzePath ( path ) . exists ) {
FS . unlink ( path ) ;
}
FS . createDataFile ( PATH . dirname ( path ) , PATH . basename ( path ) , getRequest . result , true , true , true ) ;
ok ++ ;
if ( ok + fail == total ) finish ( ) ;
} ;
getRequest . onerror = function getRequest _onerror ( ) { fail ++ ; if ( ok + fail == total ) finish ( ) } ;
} ) ;
transaction . onerror = onerror ;
} ;
openRequest . onerror = onerror ;
} } ; var SYSCALLS = { mappings : { } , DEFAULT _POLLMASK : 5 , umask : 511 , calculateAt : function ( dirfd , path ) {
if ( path [ 0 ] !== '/' ) {
// relative path
var dir ;
if ( dirfd === - 100 ) {
dir = FS . cwd ( ) ;
} else {
var dirstream = FS . getStream ( dirfd ) ;
if ( ! dirstream ) throw new FS . ErrnoError ( 8 ) ;
dir = dirstream . path ;
}
path = PATH . join2 ( dir , path ) ;
}
return path ;
} , doStat : function ( func , path , buf ) {
try {
var stat = func ( path ) ;
} catch ( e ) {
if ( e && e . node && PATH . normalize ( path ) !== PATH . normalize ( FS . getPath ( e . node ) ) ) {
// 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 ) + ( 4 ) ) >> 2 ) ] = 0 ;
HEAP32 [ ( ( ( buf ) + ( 8 ) ) >> 2 ) ] = stat . ino ;
HEAP32 [ ( ( ( buf ) + ( 12 ) ) >> 2 ) ] = stat . mode ;
HEAP32 [ ( ( ( buf ) + ( 16 ) ) >> 2 ) ] = stat . nlink ;
HEAP32 [ ( ( ( buf ) + ( 20 ) ) >> 2 ) ] = stat . uid ;
HEAP32 [ ( ( ( buf ) + ( 24 ) ) >> 2 ) ] = stat . gid ;
HEAP32 [ ( ( ( buf ) + ( 28 ) ) >> 2 ) ] = stat . rdev ;
HEAP32 [ ( ( ( buf ) + ( 32 ) ) >> 2 ) ] = 0 ;
( tempI64 = [ stat . size >>> 0 , ( tempDouble = stat . size , ( + ( Math _abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( ( Math _min ( ( + ( Math _floor ( ( tempDouble ) / 4294967296.0 ) ) ) , 4294967295.0 ) ) | 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 ;
HEAP32 [ ( ( ( buf ) + ( 56 ) ) >> 2 ) ] = ( stat . atime . getTime ( ) / 1000 ) | 0 ;
HEAP32 [ ( ( ( buf ) + ( 60 ) ) >> 2 ) ] = 0 ;
HEAP32 [ ( ( ( buf ) + ( 64 ) ) >> 2 ) ] = ( stat . mtime . getTime ( ) / 1000 ) | 0 ;
HEAP32 [ ( ( ( buf ) + ( 68 ) ) >> 2 ) ] = 0 ;
HEAP32 [ ( ( ( buf ) + ( 72 ) ) >> 2 ) ] = ( stat . ctime . getTime ( ) / 1000 ) | 0 ;
HEAP32 [ ( ( ( buf ) + ( 76 ) ) >> 2 ) ] = 0 ;
( tempI64 = [ stat . ino >>> 0 , ( tempDouble = stat . ino , ( + ( Math _abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( ( Math _min ( ( + ( Math _floor ( ( tempDouble ) / 4294967296.0 ) ) ) , 4294967295.0 ) ) | 0 ) >>> 0 : ( ~ ~ ( ( + ( Math _ceil ( ( tempDouble - + ( ( ( ~ ~ ( tempDouble ) ) ) >>> 0 ) ) / 4294967296.0 ) ) ) ) ) >>> 0 ) : 0 ) ] , HEAP32 [ ( ( ( buf ) + ( 80 ) ) >> 2 ) ] = tempI64 [ 0 ] , HEAP32 [ ( ( ( buf ) + ( 84 ) ) >> 2 ) ] = tempI64 [ 1 ] ) ;
return 0 ;
} , doMsync : function ( addr , stream , len , flags , offset ) {
var buffer = HEAPU8 . slice ( addr , addr + len ) ;
FS . msync ( stream , buffer , offset , len , flags ) ;
} , doMkdir : function ( path , mode ) {
// remove a trailing slash, if one - /a/b/ has basename of '', but
// we want to create b in the context of this function
path = PATH . normalize ( path ) ;
if ( path [ path . length - 1 ] === '/' ) path = path . substr ( 0 , path . length - 1 ) ;
FS . mkdir ( path , mode , 0 ) ;
return 0 ;
} , doMknod : function ( path , mode , dev ) {
// we don't want this in the JS API as it uses mknod to create all nodes.
switch ( mode & 61440 ) {
case 32768 :
case 8192 :
case 24576 :
case 4096 :
case 49152 :
break ;
default : return - 28 ;
}
FS . mknod ( path , mode , dev ) ;
return 0 ;
} , doReadlink : function ( path , buf , bufsize ) {
if ( bufsize <= 0 ) return - 28 ;
var ret = FS . readlink ( path ) ;
var len = Math . min ( bufsize , lengthBytesUTF8 ( ret ) ) ;
var endChar = HEAP8 [ buf + len ] ;
stringToUTF8 ( ret , buf , bufsize + 1 ) ;
// readlink is one of the rare functions that write out a C string, but does never append a null to the output buffer(!)
// stringToUTF8() always appends a null byte, so restore the character under the null byte after the write.
HEAP8 [ buf + len ] = endChar ;
return len ;
} , doAccess : function ( path , amode ) {
if ( amode & ~ 7 ) {
// need a valid mode
return - 28 ;
}
var node ;
var lookup = FS . lookupPath ( path , { follow : true } ) ;
node = lookup . node ;
if ( ! node ) {
return - 44 ;
}
var perms = '' ;
if ( amode & 4 ) perms += 'r' ;
if ( amode & 2 ) perms += 'w' ;
if ( amode & 1 ) perms += 'x' ;
if ( perms /* otherwise, they've just passed F_OK */ && FS . nodePermissions ( node , perms ) ) {
return - 2 ;
}
return 0 ;
} , doDup : function ( path , flags , suggestFD ) {
var suggest = FS . getStream ( suggestFD ) ;
if ( suggest ) FS . close ( suggest ) ;
return FS . open ( path , flags , 0 , suggestFD , suggestFD ) . fd ;
} , doReadv : function ( stream , iov , iovcnt , offset ) {
var ret = 0 ;
for ( var i = 0 ; i < iovcnt ; i ++ ) {
var ptr = HEAP32 [ ( ( ( iov ) + ( i * 8 ) ) >> 2 ) ] ;
var len = HEAP32 [ ( ( ( iov ) + ( i * 8 + 4 ) ) >> 2 ) ] ;
var curr = FS . read ( stream , HEAP8 , ptr , len , offset ) ;
if ( curr < 0 ) return - 1 ;
ret += curr ;
if ( curr < len ) break ; // nothing more to read
}
return ret ;
} , doWritev : function ( stream , iov , iovcnt , offset ) {
var ret = 0 ;
for ( var i = 0 ; i < iovcnt ; i ++ ) {
var ptr = HEAP32 [ ( ( ( iov ) + ( i * 8 ) ) >> 2 ) ] ;
var len = HEAP32 [ ( ( ( iov ) + ( i * 8 + 4 ) ) >> 2 ) ] ;
var curr = FS . write ( stream , HEAP8 , ptr , len , offset ) ;
if ( curr < 0 ) return - 1 ;
ret += curr ;
}
return ret ;
} , varargs : undefined , get : function ( ) {
SYSCALLS . varargs += 4 ;
var ret = HEAP32 [ ( ( ( SYSCALLS . varargs ) - ( 4 ) ) >> 2 ) ] ;
return ret ;
} , getStr : function ( ptr ) {
var ret = UTF8ToString ( ptr ) ;
return ret ;
} , getStreamFromFD : function ( fd ) {
var stream = FS . getStream ( fd ) ;
if ( ! stream ) throw new FS . ErrnoError ( 8 ) ;
return stream ;
} , get64 : function ( low , high ) {
return low ;
} } ; function _ _ _sys _fcntl64 ( fd , cmd , varargs ) { SYSCALLS . varargs = varargs ;
try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
switch ( cmd ) {
case 0 : {
var arg = SYSCALLS . get ( ) ;
if ( arg < 0 ) {
return - 28 ;
}
var newStream ;
newStream = FS . open ( stream . path , stream . flags , 0 , arg ) ;
return newStream . fd ;
}
case 1 :
case 2 :
return 0 ; // 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 12 :
/* case 12: 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 13 :
case 14 :
/* case 13: Currently in musl F_SETLK64 has same value as F_SETLK, so omitted to avoid duplicate case blocks. If that changes, uncomment this */
/* case 14: 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 fnctl() returns that, and we set errno ourselves.
setErrNo ( 28 ) ;
return - 1 ;
default : {
return - 28 ;
}
}
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return - e . errno ;
}
}
function _ _ _sys _ioctl ( fd , op , varargs ) { SYSCALLS . varargs = varargs ;
try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
switch ( op ) {
case 21509 :
case 21505 : {
if ( ! stream . tty ) return - 59 ;
return 0 ;
}
case 21510 :
case 21511 :
case 21512 :
case 21506 :
case 21507 :
case 21508 : {
if ( ! stream . tty ) return - 59 ;
return 0 ; // 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 : abort ( 'bad ioctl syscall ' + op ) ;
}
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return - e . errno ;
}
}
function syscallMunmap ( addr , len ) {
if ( ( addr | 0 ) === - 1 || len === 0 ) {
return - 28 ;
}
// TODO: support unmmap'ing parts of allocations
var info = SYSCALLS . mappings [ addr ] ;
if ( ! info ) return 0 ;
if ( len === info . len ) {
var stream = FS . getStream ( info . fd ) ;
if ( info . prot & 2 ) {
SYSCALLS . doMsync ( addr , stream , len , info . flags , info . offset ) ;
}
FS . munmap ( stream ) ;
SYSCALLS . mappings [ addr ] = null ;
if ( info . allocated ) {
_free ( info . malloc ) ;
}
}
return 0 ;
} function _ _ _sys _munmap ( addr , len ) { try {
return syscallMunmap ( addr , len ) ;
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return - e . errno ;
}
}
function _ _ _sys _open ( path , flags , varargs ) { SYSCALLS . varargs = varargs ;
try {
var pathname = SYSCALLS . getStr ( path ) ;
var mode = SYSCALLS . get ( ) ;
var stream = FS . open ( pathname , flags , mode ) ;
return stream . fd ;
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return - e . errno ;
}
}
function _ _ _sys _stat64 ( path , buf ) { try {
path = SYSCALLS . getStr ( path ) ;
return SYSCALLS . doStat ( FS . stat , path , buf ) ;
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return - e . errno ;
}
}
function _ _ _sys _unlink ( path ) { try {
path = SYSCALLS . getStr ( path ) ;
FS . unlink ( path ) ;
return 0 ;
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return - e . errno ;
}
}
function _abort ( ) {
abort ( ) ;
}
function _emscripten _get _sbrk _ptr ( ) {
return 88176 ;
}
function _emscripten _memcpy _big ( dest , src , num ) {
HEAPU8 . copyWithin ( dest , src , src + num ) ;
}
function _emscripten _get _heap _size ( ) {
return HEAPU8 . length ;
}
function emscripten _realloc _buffer ( size ) {
try {
// round size grow request up to wasm page size (fixed 64KB per spec)
wasmMemory . grow ( ( size - buffer . byteLength + 65535 ) >>> 16 ) ; // .grow() takes a delta compared to the previous size
updateGlobalBufferAndViews ( wasmMemory . buffer ) ;
return 1 /*success*/ ;
} catch ( e ) {
}
} function _emscripten _resize _heap ( requestedSize ) {
requestedSize = requestedSize >>> 0 ;
var oldSize = _emscripten _get _heap _size ( ) ;
// With pthreads, races can happen (another thread might increase the size in between), so return a failure, and let the caller retry.
var PAGE _MULTIPLE = 65536 ;
// Memory resize rules:
// 1. When resizing, always produce a resized heap that is at least 16MB (to avoid tiny heap sizes receiving lots of repeated resizes at startup)
// 2. Always increase heap size to at least the requested size, rounded up to next page multiple.
// 3a. 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).
// 3b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap linearly: increase the heap size by at least MEMORY_GROWTH_LINEAR_STEP bytes.
// 4. Max size for the heap is capped at 2048MB-PAGE_MULTIPLE, or by MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
// 5. 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 was 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 = 2147483648 ;
if ( requestedSize > maxHeapSize ) {
return false ;
}
var minHeapSize = 16777216 ;
// 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 ( minHeapSize , requestedSize , overGrownHeapSize ) , PAGE _MULTIPLE ) ) ;
var replacement = emscripten _realloc _buffer ( newSize ) ;
if ( replacement ) {
return true ;
}
}
return false ;
}
var ENV = { } ;
function _ _getExecutableName ( ) {
return thisProgram || './this.program' ;
} function getEnvStrings ( ) {
if ( ! getEnvStrings . strings ) {
// Default values.
var env = {
'USER' : 'web_user' ,
'LOGNAME' : 'web_user' ,
'PATH' : '/' ,
'PWD' : '/' ,
'HOME' : '/home/web_user' ,
// Browser language detection #8751
'LANG' : ( ( typeof navigator === 'object' && navigator . languages && navigator . languages [ 0 ] ) || 'C' ) . replace ( '-' , '_' ) + '.UTF-8' ,
'_' : _ _getExecutableName ( )
} ;
// Apply the user-provided values, if any.
for ( var x in ENV ) {
env [ x ] = ENV [ x ] ;
}
var strings = [ ] ;
for ( var x in env ) {
strings . push ( x + '=' + env [ x ] ) ;
}
getEnvStrings . strings = strings ;
}
return getEnvStrings . strings ;
} function _environ _get ( _ _environ , environ _buf ) {
var bufSize = 0 ;
getEnvStrings ( ) . forEach ( function ( string , i ) {
var ptr = environ _buf + bufSize ;
HEAP32 [ ( ( ( _ _environ ) + ( i * 4 ) ) >> 2 ) ] = ptr ;
writeAsciiToMemory ( string , ptr ) ;
bufSize += string . length + 1 ;
} ) ;
return 0 ;
}
function _environ _sizes _get ( penviron _count , penviron _buf _size ) {
var strings = getEnvStrings ( ) ;
HEAP32 [ ( ( penviron _count ) >> 2 ) ] = strings . length ;
var bufSize = 0 ;
strings . forEach ( function ( string ) {
bufSize += string . length + 1 ;
} ) ;
HEAP32 [ ( ( penviron _buf _size ) >> 2 ) ] = bufSize ;
return 0 ;
}
function _exit ( status ) {
// void _exit(int status);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
exit ( status ) ;
}
function _fd _close ( fd ) { try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
FS . close ( stream ) ;
return 0 ;
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return e . errno ;
}
}
function _fd _fdstat _get ( fd , pbuf ) { try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
// All character devices are terminals (other things a Linux system would
// assume is a character device, like the mouse, we have special APIs for).
var type = stream . tty ? 2 :
FS . isDir ( stream . mode ) ? 3 :
FS . isLink ( stream . mode ) ? 7 :
4 ;
HEAP8 [ ( ( pbuf ) >> 0 ) ] = type ;
// TODO HEAP16[(((pbuf)+(2))>>1)]=?;
// TODO (tempI64 = [?>>>0,(tempDouble=?,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((pbuf)+(8))>>2)]=tempI64[0],HEAP32[(((pbuf)+(12))>>2)]=tempI64[1]);
// TODO (tempI64 = [?>>>0,(tempDouble=?,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((pbuf)+(16))>>2)]=tempI64[0],HEAP32[(((pbuf)+(20))>>2)]=tempI64[1]);
return 0 ;
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return e . errno ;
}
}
function _fd _read ( fd , iov , iovcnt , pnum ) { try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
var num = SYSCALLS . doReadv ( stream , iov , iovcnt ) ;
HEAP32 [ ( ( pnum ) >> 2 ) ] = num
return 0 ;
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return e . errno ;
}
}
function _fd _seek ( fd , offset _low , offset _high , whence , newOffset ) { try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
var HIGH _OFFSET = 0x100000000 ; // 2^32
// use an unsigned operator on low and shift high by 32-bits
var offset = offset _high * HIGH _OFFSET + ( offset _low >>> 0 ) ;
var DOUBLE _LIMIT = 0x20000000000000 ; // 2^53
// we also check for equality since DOUBLE_LIMIT + 1 == DOUBLE_LIMIT
if ( offset <= - DOUBLE _LIMIT || offset >= DOUBLE _LIMIT ) {
return - 61 ;
}
FS . llseek ( stream , offset , whence ) ;
( tempI64 = [ stream . position >>> 0 , ( tempDouble = stream . position , ( + ( Math _abs ( tempDouble ) ) ) >= 1.0 ? ( tempDouble > 0.0 ? ( ( Math _min ( ( + ( Math _floor ( ( tempDouble ) / 4294967296.0 ) ) ) , 4294967295.0 ) ) | 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 instanceof FS . ErrnoError ) ) abort ( e ) ;
return e . errno ;
}
}
function _fd _write ( fd , iov , iovcnt , pnum ) { try {
var stream = SYSCALLS . getStreamFromFD ( fd ) ;
var num = SYSCALLS . doWritev ( stream , iov , iovcnt ) ;
HEAP32 [ ( ( pnum ) >> 2 ) ] = num
return 0 ;
} catch ( e ) {
if ( typeof FS === 'undefined' || ! ( e instanceof FS . ErrnoError ) ) abort ( e ) ;
return e . errno ;
}
}
function _getTempRet0 ( ) {
return ( getTempRet0 ( ) | 0 ) ;
}
function _llvm _eh _typeid _for ( type ) {
return type ;
}
function _setTempRet0 ( $i ) {
setTempRet0 ( ( $i ) | 0 ) ;
}
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 _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 ;
} else {
return thisDate . getFullYear ( ) ;
}
} else {
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' ;
} else {
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 ) {
// Replaced by the week number of the year as a decimal number [00,53].
// The first Sunday of January is the first day of week 1;
// days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
var janFirst = new Date ( date . tm _year + 1900 , 0 , 1 ) ;
var firstSunday = janFirst . getDay ( ) === 0 ? janFirst : _ _addDays ( janFirst , 7 - janFirst . getDay ( ) ) ;
var endDate = new Date ( date . tm _year + 1900 , date . tm _mon , date . tm _mday ) ;
// is target date after the first Sunday?
if ( compareByDay ( firstSunday , endDate ) < 0 ) {
// calculate difference in days between first Sunday and endDate
var februaryFirstUntilEndMonth = _ _arraySum ( _ _isLeapYear ( endDate . getFullYear ( ) ) ? _ _MONTH _DAYS _LEAP : _ _MONTH _DAYS _REGULAR , endDate . getMonth ( ) - 1 ) - 31 ;
var firstSundayUntilEndJanuary = 31 - firstSunday . getDate ( ) ;
var days = firstSundayUntilEndJanuary + februaryFirstUntilEndMonth + endDate . getDate ( ) ;
return leadingNulls ( Math . ceil ( days / 7 ) , 2 ) ;
}
return compareByDay ( firstSunday , janFirst ) === 0 ? '01' : '00' ;
} ,
'%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 janFourthThisYear = new Date ( date . tm _year + 1900 , 0 , 4 ) ;
var janFourthNextYear = new Date ( date . tm _year + 1901 , 0 , 4 ) ;
var firstWeekStartThisYear = getFirstWeekStartDate ( janFourthThisYear ) ;
var firstWeekStartNextYear = getFirstWeekStartDate ( janFourthNextYear ) ;
var endDate = _ _addDays ( new Date ( date . tm _year + 1900 , 0 , 1 ) , date . tm _yday ) ;
if ( compareByDay ( endDate , firstWeekStartThisYear ) < 0 ) {
// if given date is before this years first week, then it belongs to the 53rd week of last year
return '53' ;
}
if ( compareByDay ( firstWeekStartNextYear , endDate ) <= 0 ) {
// if given date is after next years first week, then it belongs to the 01th week of next year
return '01' ;
}
// given date is in between CW 01..53 of this calendar year
var daysDifference ;
if ( firstWeekStartThisYear . getFullYear ( ) < date . tm _year + 1900 ) {
// first CW of this year starts last year
daysDifference = date . tm _yday + 32 - firstWeekStartThisYear . getDate ( )
} else {
// first CW of this year starts this year
daysDifference = date . tm _yday + 1 - firstWeekStartThisYear . getDate ( ) ;
}
return leadingNulls ( Math . ceil ( daysDifference / 7 ) , 2 ) ;
} ,
'%w' : function ( date ) {
return date . tm _wday ;
} ,
'%W' : function ( date ) {
// Replaced by the week number of the year as a decimal number [00,53].
// The first Monday of January is the first day of week 1;
// days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
var janFirst = new Date ( date . tm _year , 0 , 1 ) ;
var firstMonday = janFirst . getDay ( ) === 1 ? janFirst : _ _addDays ( janFirst , janFirst . getDay ( ) === 0 ? 1 : 7 - janFirst . getDay ( ) + 1 ) ;
var endDate = new Date ( date . tm _year + 1900 , date . tm _mon , date . tm _mday ) ;
// is target date after the first Monday?
if ( compareByDay ( firstMonday , endDate ) < 0 ) {
var februaryFirstUntilEndMonth = _ _arraySum ( _ _isLeapYear ( endDate . getFullYear ( ) ) ? _ _MONTH _DAYS _LEAP : _ _MONTH _DAYS _REGULAR , endDate . getMonth ( ) - 1 ) - 31 ;
var firstMondayUntilEndJanuary = 31 - firstMonday . getDate ( ) ;
var days = firstMondayUntilEndJanuary + februaryFirstUntilEndMonth + endDate . getDate ( ) ;
return leadingNulls ( Math . ceil ( days / 7 ) , 2 ) ;
}
return compareByDay ( firstMonday , janFirst ) === 0 ? '01' : '00' ;
} ,
'%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 '%' ;
}
} ;
for ( var rule in EXPANSION _RULES _2 ) {
if ( pattern . indexOf ( rule ) >= 0 ) {
pattern = pattern . replace ( new RegExp ( rule , 'g' ) , EXPANSION _RULES _2 [ rule ] ( date ) ) ;
}
}
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 ) {
return _strftime ( s , maxsize , format , tm ) ; // no locale support yet
}
function _system ( command ) {
if ( ENVIRONMENT _IS _NODE ) {
if ( ! command ) return 1 ; // shell is available
var cmdstr = UTF8ToString ( command ) ;
if ( ! cmdstr . length ) return 0 ; // this is what glibc seems to do (shell works test?)
var cp = require ( 'child_process' ) ;
var ret = cp . spawnSync ( cmdstr , [ ] , { shell : true , stdio : 'inherit' } ) ;
var _W _EXITCODE = function ( ret , sig ) {
return ( ( ret ) << 8 | ( sig ) ) ;
}
// this really only can happen if process is killed by signal
if ( ret . status === null ) {
// sadly node doesn't expose such function
var signalToNumber = function ( sig ) {
// implement only the most common ones, and fallback to SIGINT
switch ( sig ) {
case 'SIGHUP' : return 1 ;
case 'SIGINT' : return 2 ;
case 'SIGQUIT' : return 3 ;
case 'SIGFPE' : return 8 ;
case 'SIGKILL' : return 9 ;
case 'SIGALRM' : return 14 ;
case 'SIGTERM' : return 15 ;
}
return 2 ; // SIGINT
}
return _W _EXITCODE ( 0 , signalToNumber ( ret . signal ) ) ;
}
return _W _EXITCODE ( ret . status , 0 ) ;
}
// int system(const char *command);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/system.html
// Can't call external programs.
if ( ! command ) return 0 ; // no shell available
setErrNo ( 6 ) ;
return - 1 ;
}
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 . staticInit ( ) ; Module [ "FS_createFolder" ] = FS . createFolder ; Module [ "FS_createPath" ] = FS . createPath ; Module [ "FS_createDataFile" ] = FS . createDataFile ; Module [ "FS_createPreloadedFile" ] = FS . createPreloadedFile ; Module [ "FS_createLazyFile" ] = FS . createLazyFile ; Module [ "FS_createLink" ] = FS . createLink ; Module [ "FS_createDevice" ] = FS . createDevice ; Module [ "FS_unlink" ] = FS . unlink ; ;
var ASSERTIONS = false ;
/** @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 ;
}
function intArrayToString ( array ) {
var ret = [ ] ;
for ( var i = 0 ; i < array . length ; i ++ ) {
var chr = array [ i ] ;
if ( chr > 0xFF ) {
if ( ASSERTIONS ) {
assert ( false , 'Character code ' + chr + ' (' + String . fromCharCode ( chr ) + ') at offset ' + i + ' not in 0x00-0xFF.' ) ;
}
chr &= 0xFF ;
}
ret . push ( String . fromCharCode ( chr ) ) ;
}
return ret . join ( '' ) ;
}
var asmGlobalArg = { } ;
var asmLibraryArg = { "__assert_fail" : _ _ _assert _fail , "__cxa_allocate_exception" : _ _ _cxa _allocate _exception , "__cxa_atexit" : _ _ _cxa _atexit , "__cxa_begin_catch" : _ _ _cxa _begin _catch , "__cxa_end_catch" : _ _ _cxa _end _catch , "__cxa_find_matching_catch_2" : _ _ _cxa _find _matching _catch _2 , "__cxa_find_matching_catch_3" : _ _ _cxa _find _matching _catch _3 , "__cxa_free_exception" : _ _ _cxa _free _exception , "__cxa_rethrow" : _ _ _cxa _rethrow , "__cxa_throw" : _ _ _cxa _throw , "__cxa_uncaught_exceptions" : _ _ _cxa _uncaught _exceptions , "__map_file" : _ _ _map _file , "__resumeException" : _ _ _resumeException , "__sys_fcntl64" : _ _ _sys _fcntl64 , "__sys_ioctl" : _ _ _sys _ioctl , "__sys_munmap" : _ _ _sys _munmap , "__sys_open" : _ _ _sys _open , "__sys_stat64" : _ _ _sys _stat64 , "__sys_unlink" : _ _ _sys _unlink , "abort" : _abort , "emscripten_get_sbrk_ptr" : _emscripten _get _sbrk _ptr , "emscripten_memcpy_big" : _emscripten _memcpy _big , "emscripten_resize_heap" : _emscripten _resize _heap , "environ_get" : _environ _get , "environ_sizes_get" : _environ _sizes _get , "exit" : _exit , "fd_close" : _fd _close , "fd_fdstat_get" : _fd _fdstat _get , "fd_read" : _fd _read , "fd_seek" : _fd _seek , "fd_write" : _fd _write , "getTempRet0" : _getTempRet0 , "invoke_diii" : invoke _diii , "invoke_fiii" : invoke _fiii , "invoke_i" : invoke _i , "invoke_ii" : invoke _ii , "invoke_iidi" : invoke _iidi , "invoke_iidii" : invoke _iidii , "invoke_iii" : invoke _iii , "invoke_iiii" : invoke _iiii , "invoke_iiiii" : invoke _iiiii , "invoke_iiiiii" : invoke _iiiiii , "invoke_iiiiiii" : invoke _iiiiiii , "invoke_iiiiiiii" : invoke _iiiiiiii , "invoke_iiiiiiiiii" : invoke _iiiiiiiiii , "invoke_iiiiiiiiiii" : invoke _iiiiiiiiiii , "invoke_iiiiiiiiiiii" : invoke _iiiiiiiiiiii , "invoke_iiiiiiiiiiiii" : invoke _iiiiiiiiiiiii , "invoke_jiiii" : invoke _jiiii , "invoke_v" : invoke _v , "invoke_vi" : invoke _vi , "invoke_vid" : invoke _vid , "invoke_vii" : invoke _vii , "invoke_viii" : invoke _viii , "invoke_viiii" : invoke _viiii , "invoke_viiiii" : invoke _viiiii , "invoke_viiiiii" : invoke _viiiiii , "invoke_viiiiiii" : invoke _viiiiiii , "invoke_viiiiiiii" : invoke _viiiiiiii , "invoke_viiiiiiiii" : invoke _viiiiiiiii , "invoke_viiiiiiiiii" : invoke _viiiiiiiiii , "invoke_viiiiiiiiiiiiiii" : invoke _viiiiiiiiiiiiiii , "llvm_eh_typeid_for" : _llvm _eh _typeid _for , "memory" : wasmMemory , "setTempRet0" : _setTempRet0 , "strftime_l" : _strftime _l , "system" : _system , "table" : wasmTable } ;
var asm = createWasm ( ) ;
/** @type {function(...*):?} */
var _ _ _wasm _call _ctors = Module [ "___wasm_call_ctors" ] = function ( ) {
return ( _ _ _wasm _call _ctors = Module [ "___wasm_call_ctors" ] = Module [ "asm" ] [ "__wasm_call_ctors" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _malloc = Module [ "_malloc" ] = function ( ) {
return ( _malloc = Module [ "_malloc" ] = Module [ "asm" ] [ "malloc" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _free = Module [ "_free" ] = function ( ) {
return ( _free = Module [ "_free" ] = Module [ "asm" ] [ "free" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _ _ _errno _location = Module [ "___errno_location" ] = function ( ) {
return ( _ _ _errno _location = Module [ "___errno_location" ] = Module [ "asm" ] [ "__errno_location" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _main = Module [ "_main" ] = function ( ) {
return ( _main = Module [ "_main" ] = Module [ "asm" ] [ "main" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _setThrew = Module [ "_setThrew" ] = function ( ) {
return ( _setThrew = Module [ "_setThrew" ] = Module [ "asm" ] [ "setThrew" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var stackSave = Module [ "stackSave" ] = function ( ) {
return ( stackSave = Module [ "stackSave" ] = Module [ "asm" ] [ "stackSave" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var stackRestore = Module [ "stackRestore" ] = function ( ) {
return ( stackRestore = Module [ "stackRestore" ] = Module [ "asm" ] [ "stackRestore" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var stackAlloc = Module [ "stackAlloc" ] = function ( ) {
return ( stackAlloc = Module [ "stackAlloc" ] = Module [ "asm" ] [ "stackAlloc" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _ _ZSt18uncaught _exceptionv = Module [ "__ZSt18uncaught_exceptionv" ] = function ( ) {
return ( _ _ZSt18uncaught _exceptionv = Module [ "__ZSt18uncaught_exceptionv" ] = Module [ "asm" ] [ "_ZSt18uncaught_exceptionv" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _ _ _cxa _can _catch = Module [ "___cxa_can_catch" ] = function ( ) {
return ( _ _ _cxa _can _catch = Module [ "___cxa_can_catch" ] = Module [ "asm" ] [ "__cxa_can_catch" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _ _ _cxa _is _pointer _type = Module [ "___cxa_is_pointer_type" ] = function ( ) {
return ( _ _ _cxa _is _pointer _type = Module [ "___cxa_is_pointer_type" ] = Module [ "asm" ] [ "__cxa_is_pointer_type" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _v = Module [ "dynCall_v" ] = function ( ) {
return ( dynCall _v = Module [ "dynCall_v" ] = Module [ "asm" ] [ "dynCall_v" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _vi = Module [ "dynCall_vi" ] = function ( ) {
return ( dynCall _vi = Module [ "dynCall_vi" ] = Module [ "asm" ] [ "dynCall_vi" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _vii = Module [ "dynCall_vii" ] = function ( ) {
return ( dynCall _vii = Module [ "dynCall_vii" ] = Module [ "asm" ] [ "dynCall_vii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viii = Module [ "dynCall_viii" ] = function ( ) {
return ( dynCall _viii = Module [ "dynCall_viii" ] = Module [ "asm" ] [ "dynCall_viii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viiii = Module [ "dynCall_viiii" ] = function ( ) {
return ( dynCall _viiii = Module [ "dynCall_viiii" ] = Module [ "asm" ] [ "dynCall_viiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viiiii = Module [ "dynCall_viiiii" ] = function ( ) {
return ( dynCall _viiiii = Module [ "dynCall_viiiii" ] = Module [ "asm" ] [ "dynCall_viiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viiiiii = Module [ "dynCall_viiiiii" ] = function ( ) {
return ( dynCall _viiiiii = Module [ "dynCall_viiiiii" ] = Module [ "asm" ] [ "dynCall_viiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viiiiiii = Module [ "dynCall_viiiiiii" ] = function ( ) {
return ( dynCall _viiiiiii = Module [ "dynCall_viiiiiii" ] = Module [ "asm" ] [ "dynCall_viiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viiiiiiii = Module [ "dynCall_viiiiiiii" ] = function ( ) {
return ( dynCall _viiiiiiii = Module [ "dynCall_viiiiiiii" ] = Module [ "asm" ] [ "dynCall_viiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viiiiiiiii = Module [ "dynCall_viiiiiiiii" ] = function ( ) {
return ( dynCall _viiiiiiiii = Module [ "dynCall_viiiiiiiii" ] = Module [ "asm" ] [ "dynCall_viiiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viiiiiiiiii = Module [ "dynCall_viiiiiiiiii" ] = function ( ) {
return ( dynCall _viiiiiiiiii = Module [ "dynCall_viiiiiiiiii" ] = Module [ "asm" ] [ "dynCall_viiiiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viiiiiiiiiiiiiii = Module [ "dynCall_viiiiiiiiiiiiiii" ] = function ( ) {
return ( dynCall _viiiiiiiiiiiiiii = Module [ "dynCall_viiiiiiiiiiiiiii" ] = Module [ "asm" ] [ "dynCall_viiiiiiiiiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _vid = Module [ "dynCall_vid" ] = function ( ) {
return ( dynCall _vid = Module [ "dynCall_vid" ] = Module [ "asm" ] [ "dynCall_vid" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _i = Module [ "dynCall_i" ] = function ( ) {
return ( dynCall _i = Module [ "dynCall_i" ] = Module [ "asm" ] [ "dynCall_i" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _ii = Module [ "dynCall_ii" ] = function ( ) {
return ( dynCall _ii = Module [ "dynCall_ii" ] = Module [ "asm" ] [ "dynCall_ii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iii = Module [ "dynCall_iii" ] = function ( ) {
return ( dynCall _iii = Module [ "dynCall_iii" ] = Module [ "asm" ] [ "dynCall_iii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiii = Module [ "dynCall_iiii" ] = function ( ) {
return ( dynCall _iiii = Module [ "dynCall_iiii" ] = Module [ "asm" ] [ "dynCall_iiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiii = Module [ "dynCall_iiiii" ] = function ( ) {
return ( dynCall _iiiii = Module [ "dynCall_iiiii" ] = Module [ "asm" ] [ "dynCall_iiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiii = Module [ "dynCall_iiiiii" ] = function ( ) {
return ( dynCall _iiiiii = Module [ "dynCall_iiiiii" ] = Module [ "asm" ] [ "dynCall_iiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiiii = Module [ "dynCall_iiiiiii" ] = function ( ) {
return ( dynCall _iiiiiii = Module [ "dynCall_iiiiiii" ] = Module [ "asm" ] [ "dynCall_iiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiiiii = Module [ "dynCall_iiiiiiii" ] = function ( ) {
return ( dynCall _iiiiiiii = Module [ "dynCall_iiiiiiii" ] = Module [ "asm" ] [ "dynCall_iiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiiiiiii = Module [ "dynCall_iiiiiiiiii" ] = function ( ) {
return ( dynCall _iiiiiiiiii = Module [ "dynCall_iiiiiiiiii" ] = Module [ "asm" ] [ "dynCall_iiiiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiiiiiiii = Module [ "dynCall_iiiiiiiiiii" ] = function ( ) {
return ( dynCall _iiiiiiiiiii = Module [ "dynCall_iiiiiiiiiii" ] = Module [ "asm" ] [ "dynCall_iiiiiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiiiiiiiii = Module [ "dynCall_iiiiiiiiiiii" ] = function ( ) {
return ( dynCall _iiiiiiiiiiii = Module [ "dynCall_iiiiiiiiiiii" ] = Module [ "asm" ] [ "dynCall_iiiiiiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiiiiiiiiii = Module [ "dynCall_iiiiiiiiiiiii" ] = function ( ) {
return ( dynCall _iiiiiiiiiiiii = Module [ "dynCall_iiiiiiiiiiiii" ] = Module [ "asm" ] [ "dynCall_iiiiiiiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iidi = Module [ "dynCall_iidi" ] = function ( ) {
return ( dynCall _iidi = Module [ "dynCall_iidi" ] = Module [ "asm" ] [ "dynCall_iidi" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iidii = Module [ "dynCall_iidii" ] = function ( ) {
return ( dynCall _iidii = Module [ "dynCall_iidii" ] = Module [ "asm" ] [ "dynCall_iidii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _jiiii = Module [ "dynCall_jiiii" ] = function ( ) {
return ( dynCall _jiiii = Module [ "dynCall_jiiii" ] = Module [ "asm" ] [ "dynCall_jiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _fiii = Module [ "dynCall_fiii" ] = function ( ) {
return ( dynCall _fiii = Module [ "dynCall_fiii" ] = Module [ "asm" ] [ "dynCall_fiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _diii = Module [ "dynCall_diii" ] = function ( ) {
return ( dynCall _diii = Module [ "dynCall_diii" ] = Module [ "asm" ] [ "dynCall_diii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var _ _growWasmMemory = Module [ "__growWasmMemory" ] = function ( ) {
return ( _ _growWasmMemory = Module [ "__growWasmMemory" ] = Module [ "asm" ] [ "__growWasmMemory" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _viijii = Module [ "dynCall_viijii" ] = function ( ) {
return ( dynCall _viijii = Module [ "dynCall_viijii" ] = Module [ "asm" ] [ "dynCall_viijii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _jiji = Module [ "dynCall_jiji" ] = function ( ) {
return ( dynCall _jiji = Module [ "dynCall_jiji" ] = Module [ "asm" ] [ "dynCall_jiji" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iidiiii = Module [ "dynCall_iidiiii" ] = function ( ) {
return ( dynCall _iidiiii = Module [ "dynCall_iidiiii" ] = Module [ "asm" ] [ "dynCall_iidiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiiiiii = Module [ "dynCall_iiiiiiiii" ] = function ( ) {
return ( dynCall _iiiiiiiii = Module [ "dynCall_iiiiiiiii" ] = Module [ "asm" ] [ "dynCall_iiiiiiiii" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiij = Module [ "dynCall_iiiiij" ] = function ( ) {
return ( dynCall _iiiiij = Module [ "dynCall_iiiiij" ] = Module [ "asm" ] [ "dynCall_iiiiij" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiid = Module [ "dynCall_iiiiid" ] = function ( ) {
return ( dynCall _iiiiid = Module [ "dynCall_iiiiid" ] = Module [ "asm" ] [ "dynCall_iiiiid" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiijj = Module [ "dynCall_iiiiijj" ] = function ( ) {
return ( dynCall _iiiiijj = Module [ "dynCall_iiiiijj" ] = Module [ "asm" ] [ "dynCall_iiiiijj" ] ) . apply ( null , arguments ) ;
} ;
/** @type {function(...*):?} */
var dynCall _iiiiiijj = Module [ "dynCall_iiiiiijj" ] = function ( ) {
return ( dynCall _iiiiiijj = Module [ "dynCall_iiiiiijj" ] = Module [ "asm" ] [ "dynCall_iiiiiijj" ] ) . apply ( null , arguments ) ;
} ;
function invoke _iii ( index , a1 , a2 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iii ( index , a1 , a2 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiii ( index , a1 , a2 , a3 , a4 ) {
var sp = stackSave ( ) ;
try {
dynCall _viiii ( index , a1 , a2 , a3 , a4 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _vi ( index , a1 ) {
var sp = stackSave ( ) ;
try {
dynCall _vi ( index , a1 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _ii ( index , a1 ) {
var sp = stackSave ( ) ;
try {
return dynCall _ii ( index , a1 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _vii ( index , a1 , a2 ) {
var sp = stackSave ( ) ;
try {
dynCall _vii ( index , a1 , a2 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiii ( index , a1 , a2 , a3 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiii ( index , a1 , a2 , a3 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiiii ( index , a1 , a2 , a3 , a4 , a5 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiiiii ( index , a1 , a2 , a3 , a4 , a5 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viii ( index , a1 , a2 , a3 ) {
var sp = stackSave ( ) ;
try {
dynCall _viii ( index , a1 , a2 , a3 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _v ( index ) {
var sp = stackSave ( ) ;
try {
dynCall _v ( index ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiii ( index , a1 , a2 , a3 , a4 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiiii ( index , a1 , a2 , a3 , a4 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iidii ( index , a1 , a2 , a3 , a4 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iidii ( index , a1 , a2 , a3 , a4 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 ) {
var sp = stackSave ( ) ;
try {
dynCall _viiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiiii ( index , a1 , a2 , a3 , a4 , a5 ) {
var sp = stackSave ( ) ;
try {
dynCall _viiiii ( index , a1 , a2 , a3 , a4 , a5 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iidi ( index , a1 , a2 , a3 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iidi ( index , a1 , a2 , a3 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _vid ( index , a1 , a2 ) {
var sp = stackSave ( ) ;
try {
dynCall _vid ( index , a1 , a2 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 ) {
var sp = stackSave ( ) ;
try {
dynCall _viiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _i ( index ) {
var sp = stackSave ( ) ;
try {
return dynCall _i ( index ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ) {
var sp = stackSave ( ) ;
try {
dynCall _viiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) {
var sp = stackSave ( ) ;
try {
dynCall _viiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiiiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 , a12 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiiiiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 , a12 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _fiii ( index , a1 , a2 , a3 ) {
var sp = stackSave ( ) ;
try {
return dynCall _fiii ( index , a1 , a2 , a3 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _diii ( index , a1 , a2 , a3 ) {
var sp = stackSave ( ) ;
try {
return dynCall _diii ( index , a1 , a2 , a3 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _iiiiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 ) {
var sp = stackSave ( ) ;
try {
return dynCall _iiiiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 ) {
var sp = stackSave ( ) ;
try {
dynCall _viiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _viiiiiiiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 , a12 , a13 , a14 , a15 ) {
var sp = stackSave ( ) ;
try {
dynCall _viiiiiiiiiiiiiii ( index , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , a11 , a12 , a13 , a14 , a15 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
function invoke _jiiii ( index , a1 , a2 , a3 , a4 ) {
var sp = stackSave ( ) ;
try {
return dynCall _jiiii ( index , a1 , a2 , a3 , a4 ) ;
} catch ( e ) {
stackRestore ( sp ) ;
if ( e !== e + 0 && e !== 'longjmp' ) throw e ;
_setThrew ( 1 , 0 ) ;
}
}
// === Auto-generated postamble setup entry stuff ===
Module [ "getMemory" ] = getMemory ;
Module [ "addRunDependency" ] = addRunDependency ;
Module [ "removeRunDependency" ] = removeRunDependency ;
Module [ "FS_createFolder" ] = FS . createFolder ;
Module [ "FS_createPath" ] = FS . createPath ;
Module [ "FS_createDataFile" ] = FS . createDataFile ;
Module [ "FS_createPreloadedFile" ] = FS . createPreloadedFile ;
Module [ "FS_createLazyFile" ] = FS . createLazyFile ;
Module [ "FS_createLink" ] = FS . createLink ;
Module [ "FS_createDevice" ] = FS . createDevice ;
Module [ "FS_unlink" ] = FS . unlink ;
Module [ "callMain" ] = callMain ;
Module [ "FS" ] = FS ;
var calledRun ;
/ * *
* @ constructor
* @ this { ExitStatus }
* /
function ExitStatus ( status ) {
this . name = "ExitStatus" ;
this . message = "Program terminated with exit(" + status + ")" ;
this . status = status ;
}
var calledMain = false ;
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 ( args ) {
var entryFunction = Module [ '_main' ] ;
args = args || [ ] ;
var argc = args . length + 1 ;
var argv = stackAlloc ( ( argc + 1 ) * 4 ) ;
HEAP32 [ argv >> 2 ] = allocateUTF8OnStack ( thisProgram ) ;
for ( var i = 1 ; i < argc ; i ++ ) {
HEAP32 [ ( argv >> 2 ) + i ] = allocateUTF8OnStack ( args [ i - 1 ] ) ;
}
HEAP32 [ ( argv >> 2 ) + argc ] = 0 ;
try {
var ret = entryFunction ( argc , argv ) ;
// In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as execution is asynchronously handed
// off to a pthread.
// if we're not running an evented main loop, it's time to exit
exit ( ret , /* implicit = */ true ) ;
}
catch ( e ) {
if ( e instanceof ExitStatus ) {
// exit() throws this once it's done to make sure execution
// has been stopped completely
return ;
} else if ( e == 'unwind' ) {
// running an evented main loop, don't immediately exit
noExitRuntime = true ;
return ;
} else {
var toLog = e ;
if ( e && typeof e === 'object' && e . stack ) {
toLog = [ e , e . stack ] ;
}
err ( 'exception thrown: ' + toLog ) ;
quit _ ( 1 , e ) ;
}
} finally {
calledMain = true ;
}
}
/** @type {function(Array=)} */
function run ( args ) {
args = args || arguments _ ;
if ( runDependencies > 0 ) {
return ;
}
preRun ( ) ;
if ( runDependencies > 0 ) return ; // a preRun added a dependency, run will be called later
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 ( ) ;
readyPromiseResolve ( Module ) ;
if ( Module [ 'onRuntimeInitialized' ] ) Module [ 'onRuntimeInitialized' ] ( ) ;
if ( shouldRunNow ) callMain ( args ) ;
postRun ( ) ;
}
if ( Module [ 'setStatus' ] ) {
Module [ 'setStatus' ] ( 'Running...' ) ;
setTimeout ( function ( ) {
setTimeout ( function ( ) {
Module [ 'setStatus' ] ( '' ) ;
} , 1 ) ;
doRun ( ) ;
} , 1 ) ;
} else
{
doRun ( ) ;
}
}
Module [ 'run' ] = run ;
/** @param {boolean|number=} implicit */
function exit ( status , implicit ) {
// if this is just main exit-ing implicitly, and the status is 0, then we
// don't need to do anything here and can just leave. if the status is
// non-zero, though, then we need to report it.
// (we may have warned about this earlier, if a situation justifies doing so)
if ( implicit && noExitRuntime && status === 0 ) {
return ;
}
if ( noExitRuntime ) {
} else {
ABORT = true ;
EXITSTATUS = status ;
exitRuntime ( ) ;
if ( Module [ 'onExit' ] ) Module [ 'onExit' ] ( status ) ;
}
quit _ ( status , new ExitStatus ( status ) ) ;
}
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 ;
noExitRuntime = true ;
run ( ) ;
// {{MODULE_ADDITIONS}}
return cmoc /*.ready*/
2019-12-07 23:20:01 +00:00
}
) ;
} ) ( ) ;
if ( typeof exports === 'object' && typeof module === 'object' )
module . exports = cmoc ;
else if ( typeof define === 'function' && define [ 'amd' ] )
define ( [ ] , function ( ) { return cmoc ; } ) ;
else if ( typeof exports === 'object' )
exports [ "cmoc" ] = cmoc ;