Home | History | Annotate | Download | only in embenchen
      1 // Modified embenchen to direct to asm-wasm.
      2 // Flags: --expose-wasm
      3 
      4 var EXPECTED_OUTPUT = 'final: 840.\n';
      5 var Module = {
      6   arguments: [1],
      7   print: function(x) {Module.printBuffer += x + '\n';},
      8   preRun: [function() {Module.printBuffer = ''}],
      9   postRun: [function() {
     10     assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
     11   }],
     12 };
     13 // The Module object: Our interface to the outside world. We import
     14 // and export values on it, and do the work to get that through
     15 // closure compiler if necessary. There are various ways Module can be used:
     16 // 1. Not defined. We create it here
     17 // 2. A function parameter, function(Module) { ..generated code.. }
     18 // 3. pre-run appended it, var Module = {}; ..generated code..
     19 // 4. External script tag defines var Module.
     20 // We need to do an eval in order to handle the closure compiler
     21 // case, where this code here is minified but Module was defined
     22 // elsewhere (e.g. case 4 above). We also need to check if Module
     23 // already exists (e.g. case 3 above).
     24 // Note that if you want to run closure, and also to use Module
     25 // after the generated code, you will need to define   var Module = {};
     26 // before the code. Then that object will be used in the code, and you
     27 // can continue to use Module afterwards as well.
     28 var Module;
     29 if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
     30 
     31 // Sometimes an existing Module object exists with properties
     32 // meant to overwrite the default module functionality. Here
     33 // we collect those properties and reapply _after_ we configure
     34 // the current environment's defaults to avoid having to be so
     35 // defensive during initialization.
     36 var moduleOverrides = {};
     37 for (var key in Module) {
     38   if (Module.hasOwnProperty(key)) {
     39     moduleOverrides[key] = Module[key];
     40   }
     41 }
     42 
     43 // The environment setup code below is customized to use Module.
     44 // *** Environment setup code ***
     45 var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
     46 var ENVIRONMENT_IS_WEB = typeof window === 'object';
     47 var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
     48 var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
     49 
     50 if (ENVIRONMENT_IS_NODE) {
     51   // Expose functionality in the same simple way that the shells work
     52   // Note that we pollute the global namespace here, otherwise we break in node
     53   if (!Module['print']) Module['print'] = function print(x) {
     54     process['stdout'].write(x + '\n');
     55   };
     56   if (!Module['printErr']) Module['printErr'] = function printErr(x) {
     57     process['stderr'].write(x + '\n');
     58   };
     59 
     60   var nodeFS = require('fs');
     61   var nodePath = require('path');
     62 
     63   Module['read'] = function read(filename, binary) {
     64     filename = nodePath['normalize'](filename);
     65     var ret = nodeFS['readFileSync'](filename);
     66     // The path is absolute if the normalized version is the same as the resolved.
     67     if (!ret && filename != nodePath['resolve'](filename)) {
     68       filename = path.join(__dirname, '..', 'src', filename);
     69       ret = nodeFS['readFileSync'](filename);
     70     }
     71     if (ret && !binary) ret = ret.toString();
     72     return ret;
     73   };
     74 
     75   Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
     76 
     77   Module['load'] = function load(f) {
     78     globalEval(read(f));
     79   };
     80 
     81   Module['arguments'] = process['argv'].slice(2);
     82 
     83   module['exports'] = Module;
     84 }
     85 else if (ENVIRONMENT_IS_SHELL) {
     86   if (!Module['print']) Module['print'] = print;
     87   if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
     88 
     89   if (typeof read != 'undefined') {
     90     Module['read'] = read;
     91   } else {
     92     Module['read'] = function read() { throw 'no read() available (jsc?)' };
     93   }
     94 
     95   Module['readBinary'] = function readBinary(f) {
     96     return read(f, 'binary');
     97   };
     98 
     99   if (typeof scriptArgs != 'undefined') {
    100     Module['arguments'] = scriptArgs;
    101   } else if (typeof arguments != 'undefined') {
    102     Module['arguments'] = arguments;
    103   }
    104 
    105   this['Module'] = Module;
    106 
    107   eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
    108 }
    109 else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
    110   Module['read'] = function read(url) {
    111     var xhr = new XMLHttpRequest();
    112     xhr.open('GET', url, false);
    113     xhr.send(null);
    114     return xhr.responseText;
    115   };
    116 
    117   if (typeof arguments != 'undefined') {
    118     Module['arguments'] = arguments;
    119   }
    120 
    121   if (typeof console !== 'undefined') {
    122     if (!Module['print']) Module['print'] = function print(x) {
    123       console.log(x);
    124     };
    125     if (!Module['printErr']) Module['printErr'] = function printErr(x) {
    126       console.log(x);
    127     };
    128   } else {
    129     // Probably a worker, and without console.log. We can do very little here...
    130     var TRY_USE_DUMP = false;
    131     if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
    132       dump(x);
    133     }) : (function(x) {
    134       // self.postMessage(x); // enable this if you want stdout to be sent as messages
    135     }));
    136   }
    137 
    138   if (ENVIRONMENT_IS_WEB) {
    139     window['Module'] = Module;
    140   } else {
    141     Module['load'] = importScripts;
    142   }
    143 }
    144 else {
    145   // Unreachable because SHELL is dependant on the others
    146   throw 'Unknown runtime environment. Where are we?';
    147 }
    148 
    149 function globalEval(x) {
    150   eval.call(null, x);
    151 }
    152 if (!Module['load'] == 'undefined' && Module['read']) {
    153   Module['load'] = function load(f) {
    154     globalEval(Module['read'](f));
    155   };
    156 }
    157 if (!Module['print']) {
    158   Module['print'] = function(){};
    159 }
    160 if (!Module['printErr']) {
    161   Module['printErr'] = Module['print'];
    162 }
    163 if (!Module['arguments']) {
    164   Module['arguments'] = [];
    165 }
    166 // *** Environment setup code ***
    167 
    168 // Closure helpers
    169 Module.print = Module['print'];
    170 Module.printErr = Module['printErr'];
    171 
    172 // Callbacks
    173 Module['preRun'] = [];
    174 Module['postRun'] = [];
    175 
    176 // Merge back in the overrides
    177 for (var key in moduleOverrides) {
    178   if (moduleOverrides.hasOwnProperty(key)) {
    179     Module[key] = moduleOverrides[key];
    180   }
    181 }
    182 
    183 
    184 
    185 // === Auto-generated preamble library stuff ===
    186 
    187 //========================================
    188 // Runtime code shared with compiler
    189 //========================================
    190 
    191 var Runtime = {
    192   stackSave: function () {
    193     return STACKTOP;
    194   },
    195   stackRestore: function (stackTop) {
    196     STACKTOP = stackTop;
    197   },
    198   forceAlign: function (target, quantum) {
    199     quantum = quantum || 4;
    200     if (quantum == 1) return target;
    201     if (isNumber(target) && isNumber(quantum)) {
    202       return Math.ceil(target/quantum)*quantum;
    203     } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
    204       return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
    205     }
    206     return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
    207   },
    208   isNumberType: function (type) {
    209     return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
    210   },
    211   isPointerType: function isPointerType(type) {
    212   return type[type.length-1] == '*';
    213 },
    214   isStructType: function isStructType(type) {
    215   if (isPointerType(type)) return false;
    216   if (isArrayType(type)) return true;
    217   if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
    218   // See comment in isStructPointerType()
    219   return type[0] == '%';
    220 },
    221   INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
    222   FLOAT_TYPES: {"float":0,"double":0},
    223   or64: function (x, y) {
    224     var l = (x | 0) | (y | 0);
    225     var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
    226     return l + h;
    227   },
    228   and64: function (x, y) {
    229     var l = (x | 0) & (y | 0);
    230     var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
    231     return l + h;
    232   },
    233   xor64: function (x, y) {
    234     var l = (x | 0) ^ (y | 0);
    235     var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
    236     return l + h;
    237   },
    238   getNativeTypeSize: function (type) {
    239     switch (type) {
    240       case 'i1': case 'i8': return 1;
    241       case 'i16': return 2;
    242       case 'i32': return 4;
    243       case 'i64': return 8;
    244       case 'float': return 4;
    245       case 'double': return 8;
    246       default: {
    247         if (type[type.length-1] === '*') {
    248           return Runtime.QUANTUM_SIZE; // A pointer
    249         } else if (type[0] === 'i') {
    250           var bits = parseInt(type.substr(1));
    251           assert(bits % 8 === 0);
    252           return bits/8;
    253         } else {
    254           return 0;
    255         }
    256       }
    257     }
    258   },
    259   getNativeFieldSize: function (type) {
    260     return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
    261   },
    262   dedup: function dedup(items, ident) {
    263   var seen = {};
    264   if (ident) {
    265     return items.filter(function(item) {
    266       if (seen[item[ident]]) return false;
    267       seen[item[ident]] = true;
    268       return true;
    269     });
    270   } else {
    271     return items.filter(function(item) {
    272       if (seen[item]) return false;
    273       seen[item] = true;
    274       return true;
    275     });
    276   }
    277 },
    278   set: function set() {
    279   var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
    280   var ret = {};
    281   for (var i = 0; i < args.length; i++) {
    282     ret[args[i]] = 0;
    283   }
    284   return ret;
    285 },
    286   STACK_ALIGN: 8,
    287   getAlignSize: function (type, size, vararg) {
    288     // we align i64s and doubles on 64-bit boundaries, unlike x86
    289     if (!vararg && (type == 'i64' || type == 'double')) return 8;
    290     if (!type) return Math.min(size, 8); // align structures internally to 64 bits
    291     return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
    292   },
    293   calculateStructAlignment: function calculateStructAlignment(type) {
    294     type.flatSize = 0;
    295     type.alignSize = 0;
    296     var diffs = [];
    297     var prev = -1;
    298     var index = 0;
    299     type.flatIndexes = type.fields.map(function(field) {
    300       index++;
    301       var size, alignSize;
    302       if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
    303         size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
    304         alignSize = Runtime.getAlignSize(field, size);
    305       } else if (Runtime.isStructType(field)) {
    306         if (field[1] === '0') {
    307           // this is [0 x something]. When inside another structure like here, it must be at the end,
    308           // and it adds no size
    309           // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
    310           size = 0;
    311           if (Types.types[field]) {
    312             alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
    313           } else {
    314             alignSize = type.alignSize || QUANTUM_SIZE;
    315           }
    316         } else {
    317           size = Types.types[field].flatSize;
    318           alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
    319         }
    320       } else if (field[0] == 'b') {
    321         // bN, large number field, like a [N x i8]
    322         size = field.substr(1)|0;
    323         alignSize = 1;
    324       } else if (field[0] === '<') {
    325         // vector type
    326         size = alignSize = Types.types[field].flatSize; // fully aligned
    327       } else if (field[0] === 'i') {
    328         // illegal integer field, that could not be legalized because it is an internal structure field
    329         // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
    330         size = alignSize = parseInt(field.substr(1))/8;
    331         assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
    332       } else {
    333         assert(false, 'invalid type for calculateStructAlignment');
    334       }
    335       if (type.packed) alignSize = 1;
    336       type.alignSize = Math.max(type.alignSize, alignSize);
    337       var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
    338       type.flatSize = curr + size;
    339       if (prev >= 0) {
    340         diffs.push(curr-prev);
    341       }
    342       prev = curr;
    343       return curr;
    344     });
    345     if (type.name_ && type.name_[0] === '[') {
    346       // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
    347       // allocating a potentially huge array for [999999 x i8] etc.
    348       type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
    349     }
    350     type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
    351     if (diffs.length == 0) {
    352       type.flatFactor = type.flatSize;
    353     } else if (Runtime.dedup(diffs).length == 1) {
    354       type.flatFactor = diffs[0];
    355     }
    356     type.needsFlattening = (type.flatFactor != 1);
    357     return type.flatIndexes;
    358   },
    359   generateStructInfo: function (struct, typeName, offset) {
    360     var type, alignment;
    361     if (typeName) {
    362       offset = offset || 0;
    363       type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
    364       if (!type) return null;
    365       if (type.fields.length != struct.length) {
    366         printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
    367         return null;
    368       }
    369       alignment = type.flatIndexes;
    370     } else {
    371       var type = { fields: struct.map(function(item) { return item[0] }) };
    372       alignment = Runtime.calculateStructAlignment(type);
    373     }
    374     var ret = {
    375       __size__: type.flatSize
    376     };
    377     if (typeName) {
    378       struct.forEach(function(item, i) {
    379         if (typeof item === 'string') {
    380           ret[item] = alignment[i] + offset;
    381         } else {
    382           // embedded struct
    383           var key;
    384           for (var k in item) key = k;
    385           ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
    386         }
    387       });
    388     } else {
    389       struct.forEach(function(item, i) {
    390         ret[item[1]] = alignment[i];
    391       });
    392     }
    393     return ret;
    394   },
    395   dynCall: function (sig, ptr, args) {
    396     if (args && args.length) {
    397       if (!args.splice) args = Array.prototype.slice.call(args);
    398       args.splice(0, 0, ptr);
    399       return Module['dynCall_' + sig].apply(null, args);
    400     } else {
    401       return Module['dynCall_' + sig].call(null, ptr);
    402     }
    403   },
    404   functionPointers: [],
    405   addFunction: function (func) {
    406     for (var i = 0; i < Runtime.functionPointers.length; i++) {
    407       if (!Runtime.functionPointers[i]) {
    408         Runtime.functionPointers[i] = func;
    409         return 2*(1 + i);
    410       }
    411     }
    412     throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
    413   },
    414   removeFunction: function (index) {
    415     Runtime.functionPointers[(index-2)/2] = null;
    416   },
    417   getAsmConst: function (code, numArgs) {
    418     // code is a constant string on the heap, so we can cache these
    419     if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
    420     var func = Runtime.asmConstCache[code];
    421     if (func) return func;
    422     var args = [];
    423     for (var i = 0; i < numArgs; i++) {
    424       args.push(String.fromCharCode(36) + i); // $0, $1 etc
    425     }
    426     var source = Pointer_stringify(code);
    427     if (source[0] === '"') {
    428       // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
    429       if (source.indexOf('"', 1) === source.length-1) {
    430         source = source.substr(1, source.length-2);
    431       } else {
    432         // something invalid happened, e.g. EM_ASM("..code($0)..", input)
    433         abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
    434       }
    435     }
    436     try {
    437       var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
    438     } catch(e) {
    439       Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
    440       throw e;
    441     }
    442     return Runtime.asmConstCache[code] = evalled;
    443   },
    444   warnOnce: function (text) {
    445     if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
    446     if (!Runtime.warnOnce.shown[text]) {
    447       Runtime.warnOnce.shown[text] = 1;
    448       Module.printErr(text);
    449     }
    450   },
    451   funcWrappers: {},
    452   getFuncWrapper: function (func, sig) {
    453     assert(sig);
    454     if (!Runtime.funcWrappers[func]) {
    455       Runtime.funcWrappers[func] = function dynCall_wrapper() {
    456         return Runtime.dynCall(sig, func, arguments);
    457       };
    458     }
    459     return Runtime.funcWrappers[func];
    460   },
    461   UTF8Processor: function () {
    462     var buffer = [];
    463     var needed = 0;
    464     this.processCChar = function (code) {
    465       code = code & 0xFF;
    466 
    467       if (buffer.length == 0) {
    468         if ((code & 0x80) == 0x00) {        // 0xxxxxxx
    469           return String.fromCharCode(code);
    470         }
    471         buffer.push(code);
    472         if ((code & 0xE0) == 0xC0) {        // 110xxxxx
    473           needed = 1;
    474         } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
    475           needed = 2;
    476         } else {                            // 11110xxx
    477           needed = 3;
    478         }
    479         return '';
    480       }
    481 
    482       if (needed) {
    483         buffer.push(code);
    484         needed--;
    485         if (needed > 0) return '';
    486       }
    487 
    488       var c1 = buffer[0];
    489       var c2 = buffer[1];
    490       var c3 = buffer[2];
    491       var c4 = buffer[3];
    492       var ret;
    493       if (buffer.length == 2) {
    494         ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
    495       } else if (buffer.length == 3) {
    496         ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
    497       } else {
    498         // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
    499         var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
    500                         ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
    501         ret = String.fromCharCode(
    502           Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
    503           (codePoint - 0x10000) % 0x400 + 0xDC00);
    504       }
    505       buffer.length = 0;
    506       return ret;
    507     }
    508     this.processJSString = function processJSString(string) {
    509       /* TODO: use TextEncoder when present,
    510         var encoder = new TextEncoder();
    511         encoder['encoding'] = "utf-8";
    512         var utf8Array = encoder['encode'](aMsg.data);
    513       */
    514       string = unescape(encodeURIComponent(string));
    515       var ret = [];
    516       for (var i = 0; i < string.length; i++) {
    517         ret.push(string.charCodeAt(i));
    518       }
    519       return ret;
    520     }
    521   },
    522   getCompilerSetting: function (name) {
    523     throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
    524   },
    525   stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
    526   staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
    527   dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
    528   alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
    529   makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
    530   GLOBAL_BASE: 8,
    531   QUANTUM_SIZE: 4,
    532   __dummy__: 0
    533 }
    534 
    535 
    536 Module['Runtime'] = Runtime;
    537 
    538 
    539 
    540 
    541 
    542 
    543 
    544 
    545 
    546 //========================================
    547 // Runtime essentials
    548 //========================================
    549 
    550 var __THREW__ = 0; // Used in checking for thrown exceptions.
    551 
    552 var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
    553 var EXITSTATUS = 0;
    554 
    555 var undef = 0;
    556 // tempInt is used for 32-bit signed values or smaller. tempBigInt is used
    557 // for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
    558 var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
    559 var tempI64, tempI64b;
    560 var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
    561 
    562 function assert(condition, text) {
    563   if (!condition) {
    564     abort('Assertion failed: ' + text);
    565   }
    566 }
    567 
    568 var globalScope = this;
    569 
    570 // C calling interface. A convenient way to call C functions (in C files, or
    571 // defined with extern "C").
    572 //
    573 // Note: LLVM optimizations can inline and remove functions, after which you will not be
    574 //       able to call them. Closure can also do so. To avoid that, add your function to
    575 //       the exports using something like
    576 //
    577 //         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
    578 //
    579 // @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
    580 // @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
    581 //                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
    582 // @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
    583 //                   except that 'array' is not possible (there is no way for us to know the length of the array)
    584 // @param args       An array of the arguments to the function, as native JS values (as in returnType)
    585 //                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
    586 // @return           The return value, as a native JS value (as in returnType)
    587 function ccall(ident, returnType, argTypes, args) {
    588   return ccallFunc(getCFunc(ident), returnType, argTypes, args);
    589 }
    590 Module["ccall"] = ccall;
    591 
    592 // Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
    593 function getCFunc(ident) {
    594   try {
    595     var func = Module['_' + ident]; // closure exported function
    596     if (!func) func = eval('_' + ident); // explicit lookup
    597   } catch(e) {
    598   }
    599   assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
    600   return func;
    601 }
    602 
    603 // Internal function that does a C call using a function, not an identifier
    604 function ccallFunc(func, returnType, argTypes, args) {
    605   var stack = 0;
    606   function toC(value, type) {
    607     if (type == 'string') {
    608       if (value === null || value === undefined || value === 0) return 0; // null string
    609       value = intArrayFromString(value);
    610       type = 'array';
    611     }
    612     if (type == 'array') {
    613       if (!stack) stack = Runtime.stackSave();
    614       var ret = Runtime.stackAlloc(value.length);
    615       writeArrayToMemory(value, ret);
    616       return ret;
    617     }
    618     return value;
    619   }
    620   function fromC(value, type) {
    621     if (type == 'string') {
    622       return Pointer_stringify(value);
    623     }
    624     assert(type != 'array');
    625     return value;
    626   }
    627   var i = 0;
    628   var cArgs = args ? args.map(function(arg) {
    629     return toC(arg, argTypes[i++]);
    630   }) : [];
    631   var ret = fromC(func.apply(null, cArgs), returnType);
    632   if (stack) Runtime.stackRestore(stack);
    633   return ret;
    634 }
    635 
    636 // Returns a native JS wrapper for a C function. This is similar to ccall, but
    637 // returns a function you can call repeatedly in a normal way. For example:
    638 //
    639 //   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
    640 //   alert(my_function(5, 22));
    641 //   alert(my_function(99, 12));
    642 //
    643 function cwrap(ident, returnType, argTypes) {
    644   var func = getCFunc(ident);
    645   return function() {
    646     return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
    647   }
    648 }
    649 Module["cwrap"] = cwrap;
    650 
    651 // Sets a value in memory in a dynamic way at run-time. Uses the
    652 // type data. This is the same as makeSetValue, except that
    653 // makeSetValue is done at compile-time and generates the needed
    654 // code then, whereas this function picks the right code at
    655 // run-time.
    656 // Note that setValue and getValue only do *aligned* writes and reads!
    657 // Note that ccall uses JS types as for defining types, while setValue and
    658 // getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
    659 function setValue(ptr, value, type, noSafe) {
    660   type = type || 'i8';
    661   if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
    662     switch(type) {
    663       case 'i1': HEAP8[(ptr)]=value; break;
    664       case 'i8': HEAP8[(ptr)]=value; break;
    665       case 'i16': HEAP16[((ptr)>>1)]=value; break;
    666       case 'i32': HEAP32[((ptr)>>2)]=value; break;
    667       case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
    668       case 'float': HEAPF32[((ptr)>>2)]=value; break;
    669       case 'double': HEAPF64[((ptr)>>3)]=value; break;
    670       default: abort('invalid type for setValue: ' + type);
    671     }
    672 }
    673 Module['setValue'] = setValue;
    674 
    675 // Parallel to setValue.
    676 function getValue(ptr, type, noSafe) {
    677   type = type || 'i8';
    678   if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
    679     switch(type) {
    680       case 'i1': return HEAP8[(ptr)];
    681       case 'i8': return HEAP8[(ptr)];
    682       case 'i16': return HEAP16[((ptr)>>1)];
    683       case 'i32': return HEAP32[((ptr)>>2)];
    684       case 'i64': return HEAP32[((ptr)>>2)];
    685       case 'float': return HEAPF32[((ptr)>>2)];
    686       case 'double': return HEAPF64[((ptr)>>3)];
    687       default: abort('invalid type for setValue: ' + type);
    688     }
    689   return null;
    690 }
    691 Module['getValue'] = getValue;
    692 
    693 var ALLOC_NORMAL = 0; // Tries to use _malloc()
    694 var ALLOC_STACK = 1; // Lives for the duration of the current function call
    695 var ALLOC_STATIC = 2; // Cannot be freed
    696 var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
    697 var ALLOC_NONE = 4; // Do not allocate
    698 Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
    699 Module['ALLOC_STACK'] = ALLOC_STACK;
    700 Module['ALLOC_STATIC'] = ALLOC_STATIC;
    701 Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
    702 Module['ALLOC_NONE'] = ALLOC_NONE;
    703 
    704 // allocate(): This is for internal use. You can use it yourself as well, but the interface
    705 //             is a little tricky (see docs right below). The reason is that it is optimized
    706 //             for multiple syntaxes to save space in generated code. So you should
    707 //             normally not use allocate(), and instead allocate memory using _malloc(),
    708 //             initialize it with setValue(), and so forth.
    709 // @slab: An array of data, or a number. If a number, then the size of the block to allocate,
    710 //        in *bytes* (note that this is sometimes confusing: the next parameter does not
    711 //        affect this!)
    712 // @types: Either an array of types, one for each byte (or 0 if no type at that position),
    713 //         or a single type which is used for the entire block. This only matters if there
    714 //         is initial data - if @slab is a number, then this does not matter at all and is
    715 //         ignored.
    716 // @allocator: How to allocate memory, see ALLOC_*
    717 function allocate(slab, types, allocator, ptr) {
    718   var zeroinit, size;
    719   if (typeof slab === 'number') {
    720     zeroinit = true;
    721     size = slab;
    722   } else {
    723     zeroinit = false;
    724     size = slab.length;
    725   }
    726 
    727   var singleType = typeof types === 'string' ? types : null;
    728 
    729   var ret;
    730   if (allocator == ALLOC_NONE) {
    731     ret = ptr;
    732   } else {
    733     ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
    734   }
    735 
    736   if (zeroinit) {
    737     var ptr = ret, stop;
    738     assert((ret & 3) == 0);
    739     stop = ret + (size & ~3);
    740     for (; ptr < stop; ptr += 4) {
    741       HEAP32[((ptr)>>2)]=0;
    742     }
    743     stop = ret + size;
    744     while (ptr < stop) {
    745       HEAP8[((ptr++)|0)]=0;
    746     }
    747     return ret;
    748   }
    749 
    750   if (singleType === 'i8') {
    751     if (slab.subarray || slab.slice) {
    752       HEAPU8.set(slab, ret);
    753     } else {
    754       HEAPU8.set(new Uint8Array(slab), ret);
    755     }
    756     return ret;
    757   }
    758 
    759   var i = 0, type, typeSize, previousType;
    760   while (i < size) {
    761     var curr = slab[i];
    762 
    763     if (typeof curr === 'function') {
    764       curr = Runtime.getFunctionIndex(curr);
    765     }
    766 
    767     type = singleType || types[i];
    768     if (type === 0) {
    769       i++;
    770       continue;
    771     }
    772 
    773     if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
    774 
    775     setValue(ret+i, curr, type);
    776 
    777     // no need to look up size unless type changes, so cache it
    778     if (previousType !== type) {
    779       typeSize = Runtime.getNativeTypeSize(type);
    780       previousType = type;
    781     }
    782     i += typeSize;
    783   }
    784 
    785   return ret;
    786 }
    787 Module['allocate'] = allocate;
    788 
    789 function Pointer_stringify(ptr, /* optional */ length) {
    790   // TODO: use TextDecoder
    791   // Find the length, and check for UTF while doing so
    792   var hasUtf = false;
    793   var t;
    794   var i = 0;
    795   while (1) {
    796     t = HEAPU8[(((ptr)+(i))|0)];
    797     if (t >= 128) hasUtf = true;
    798     else if (t == 0 && !length) break;
    799     i++;
    800     if (length && i == length) break;
    801   }
    802   if (!length) length = i;
    803 
    804   var ret = '';
    805 
    806   if (!hasUtf) {
    807     var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
    808     var curr;
    809     while (length > 0) {
    810       curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
    811       ret = ret ? ret + curr : curr;
    812       ptr += MAX_CHUNK;
    813       length -= MAX_CHUNK;
    814     }
    815     return ret;
    816   }
    817 
    818   var utf8 = new Runtime.UTF8Processor();
    819   for (i = 0; i < length; i++) {
    820     t = HEAPU8[(((ptr)+(i))|0)];
    821     ret += utf8.processCChar(t);
    822   }
    823   return ret;
    824 }
    825 Module['Pointer_stringify'] = Pointer_stringify;
    826 
    827 // Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
    828 // a copy of that string as a Javascript String object.
    829 function UTF16ToString(ptr) {
    830   var i = 0;
    831 
    832   var str = '';
    833   while (1) {
    834     var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
    835     if (codeUnit == 0)
    836       return str;
    837     ++i;
    838     // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
    839     str += String.fromCharCode(codeUnit);
    840   }
    841 }
    842 Module['UTF16ToString'] = UTF16ToString;
    843 
    844 // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
    845 // null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
    846 function stringToUTF16(str, outPtr) {
    847   for(var i = 0; i < str.length; ++i) {
    848     // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
    849     var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
    850     HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
    851   }
    852   // Null-terminate the pointer to the HEAP.
    853   HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
    854 }
    855 Module['stringToUTF16'] = stringToUTF16;
    856 
    857 // Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
    858 // a copy of that string as a Javascript String object.
    859 function UTF32ToString(ptr) {
    860   var i = 0;
    861 
    862   var str = '';
    863   while (1) {
    864     var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
    865     if (utf32 == 0)
    866       return str;
    867     ++i;
    868     // 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.
    869     if (utf32 >= 0x10000) {
    870       var ch = utf32 - 0x10000;
    871       str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
    872     } else {
    873       str += String.fromCharCode(utf32);
    874     }
    875   }
    876 }
    877 Module['UTF32ToString'] = UTF32ToString;
    878 
    879 // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
    880 // null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
    881 // but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
    882 function stringToUTF32(str, outPtr) {
    883   var iChar = 0;
    884   for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
    885     // 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.
    886     var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
    887     if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
    888       var trailSurrogate = str.charCodeAt(++iCodeUnit);
    889       codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
    890     }
    891     HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
    892     ++iChar;
    893   }
    894   // Null-terminate the pointer to the HEAP.
    895   HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
    896 }
    897 Module['stringToUTF32'] = stringToUTF32;
    898 
    899 function demangle(func) {
    900   var i = 3;
    901   // params, etc.
    902   var basicTypes = {
    903     'v': 'void',
    904     'b': 'bool',
    905     'c': 'char',
    906     's': 'short',
    907     'i': 'int',
    908     'l': 'long',
    909     'f': 'float',
    910     'd': 'double',
    911     'w': 'wchar_t',
    912     'a': 'signed char',
    913     'h': 'unsigned char',
    914     't': 'unsigned short',
    915     'j': 'unsigned int',
    916     'm': 'unsigned long',
    917     'x': 'long long',
    918     'y': 'unsigned long long',
    919     'z': '...'
    920   };
    921   var subs = [];
    922   var first = true;
    923   function dump(x) {
    924     //return;
    925     if (x) Module.print(x);
    926     Module.print(func);
    927     var pre = '';
    928     for (var a = 0; a < i; a++) pre += ' ';
    929     Module.print (pre + '^');
    930   }
    931   function parseNested() {
    932     i++;
    933     if (func[i] === 'K') i++; // ignore const
    934     var parts = [];
    935     while (func[i] !== 'E') {
    936       if (func[i] === 'S') { // substitution
    937         i++;
    938         var next = func.indexOf('_', i);
    939         var num = func.substring(i, next) || 0;
    940         parts.push(subs[num] || '?');
    941         i = next+1;
    942         continue;
    943       }
    944       if (func[i] === 'C') { // constructor
    945         parts.push(parts[parts.length-1]);
    946         i += 2;
    947         continue;
    948       }
    949       var size = parseInt(func.substr(i));
    950       var pre = size.toString().length;
    951       if (!size || !pre) { i--; break; } // counter i++ below us
    952       var curr = func.substr(i + pre, size);
    953       parts.push(curr);
    954       subs.push(curr);
    955       i += pre + size;
    956     }
    957     i++; // skip E
    958     return parts;
    959   }
    960   function parse(rawList, limit, allowVoid) { // main parser
    961     limit = limit || Infinity;
    962     var ret = '', list = [];
    963     function flushList() {
    964       return '(' + list.join(', ') + ')';
    965     }
    966     var name;
    967     if (func[i] === 'N') {
    968       // namespaced N-E
    969       name = parseNested().join('::');
    970       limit--;
    971       if (limit === 0) return rawList ? [name] : name;
    972     } else {
    973       // not namespaced
    974       if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
    975       var size = parseInt(func.substr(i));
    976       if (size) {
    977         var pre = size.toString().length;
    978         name = func.substr(i + pre, size);
    979         i += pre + size;
    980       }
    981     }
    982     first = false;
    983     if (func[i] === 'I') {
    984       i++;
    985       var iList = parse(true);
    986       var iRet = parse(true, 1, true);
    987       ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
    988     } else {
    989       ret = name;
    990     }
    991     paramLoop: while (i < func.length && limit-- > 0) {
    992       //dump('paramLoop');
    993       var c = func[i++];
    994       if (c in basicTypes) {
    995         list.push(basicTypes[c]);
    996       } else {
    997         switch (c) {
    998           case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
    999           case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
   1000           case 'L': { // literal
   1001             i++; // skip basic type
   1002             var end = func.indexOf('E', i);
   1003             var size = end - i;
   1004             list.push(func.substr(i, size));
   1005             i += size + 2; // size + 'EE'
   1006             break;
   1007           }
   1008           case 'A': { // array
   1009             var size = parseInt(func.substr(i));
   1010             i += size.toString().length;
   1011             if (func[i] !== '_') throw '?';
   1012             i++; // skip _
   1013             list.push(parse(true, 1, true)[0] + ' [' + size + ']');
   1014             break;
   1015           }
   1016           case 'E': break paramLoop;
   1017           default: ret += '?' + c; break paramLoop;
   1018         }
   1019       }
   1020     }
   1021     if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
   1022     if (rawList) {
   1023       if (ret) {
   1024         list.push(ret + '?');
   1025       }
   1026       return list;
   1027     } else {
   1028       return ret + flushList();
   1029     }
   1030   }
   1031   try {
   1032     // Special-case the entry point, since its name differs from other name mangling.
   1033     if (func == 'Object._main' || func == '_main') {
   1034       return 'main()';
   1035     }
   1036     if (typeof func === 'number') func = Pointer_stringify(func);
   1037     if (func[0] !== '_') return func;
   1038     if (func[1] !== '_') return func; // C function
   1039     if (func[2] !== 'Z') return func;
   1040     switch (func[3]) {
   1041       case 'n': return 'operator new()';
   1042       case 'd': return 'operator delete()';
   1043     }
   1044     return parse();
   1045   } catch(e) {
   1046     return func;
   1047   }
   1048 }
   1049 
   1050 function demangleAll(text) {
   1051   return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
   1052 }
   1053 
   1054 function stackTrace() {
   1055   var stack = new Error().stack;
   1056   return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
   1057 }
   1058 
   1059 // Memory management
   1060 
   1061 var PAGE_SIZE = 4096;
   1062 function alignMemoryPage(x) {
   1063   return (x+4095)&-4096;
   1064 }
   1065 
   1066 var HEAP;
   1067 var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
   1068 
   1069 var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
   1070 var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
   1071 var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
   1072 
   1073 function enlargeMemory() {
   1074   abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
   1075 }
   1076 
   1077 var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
   1078 var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
   1079 var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
   1080 
   1081 var totalMemory = 4096;
   1082 while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
   1083   if (totalMemory < 16*1024*1024) {
   1084     totalMemory *= 2;
   1085   } else {
   1086     totalMemory += 16*1024*1024
   1087   }
   1088 }
   1089 if (totalMemory !== TOTAL_MEMORY) {
   1090   Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
   1091   TOTAL_MEMORY = totalMemory;
   1092 }
   1093 
   1094 // Initialize the runtime's memory
   1095 // check for full engine support (use string 'subarray' to avoid closure compiler confusion)
   1096 assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
   1097        'JS engine does not provide full typed array support');
   1098 
   1099 var buffer = new ArrayBuffer(TOTAL_MEMORY);
   1100 HEAP8 = new Int8Array(buffer);
   1101 HEAP16 = new Int16Array(buffer);
   1102 HEAP32 = new Int32Array(buffer);
   1103 HEAPU8 = new Uint8Array(buffer);
   1104 HEAPU16 = new Uint16Array(buffer);
   1105 HEAPU32 = new Uint32Array(buffer);
   1106 HEAPF32 = new Float32Array(buffer);
   1107 HEAPF64 = new Float64Array(buffer);
   1108 
   1109 // Endianness check (note: assumes compiler arch was little-endian)
   1110 HEAP32[0] = 255;
   1111 assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
   1112 
   1113 Module['HEAP'] = HEAP;
   1114 Module['HEAP8'] = HEAP8;
   1115 Module['HEAP16'] = HEAP16;
   1116 Module['HEAP32'] = HEAP32;
   1117 Module['HEAPU8'] = HEAPU8;
   1118 Module['HEAPU16'] = HEAPU16;
   1119 Module['HEAPU32'] = HEAPU32;
   1120 Module['HEAPF32'] = HEAPF32;
   1121 Module['HEAPF64'] = HEAPF64;
   1122 
   1123 function callRuntimeCallbacks(callbacks) {
   1124   while(callbacks.length > 0) {
   1125     var callback = callbacks.shift();
   1126     if (typeof callback == 'function') {
   1127       callback();
   1128       continue;
   1129     }
   1130     var func = callback.func;
   1131     if (typeof func === 'number') {
   1132       if (callback.arg === undefined) {
   1133         Runtime.dynCall('v', func);
   1134       } else {
   1135         Runtime.dynCall('vi', func, [callback.arg]);
   1136       }
   1137     } else {
   1138       func(callback.arg === undefined ? null : callback.arg);
   1139     }
   1140   }
   1141 }
   1142 
   1143 var __ATPRERUN__  = []; // functions called before the runtime is initialized
   1144 var __ATINIT__    = []; // functions called during startup
   1145 var __ATMAIN__    = []; // functions called when main() is to be run
   1146 var __ATEXIT__    = []; // functions called during shutdown
   1147 var __ATPOSTRUN__ = []; // functions called after the runtime has exited
   1148 
   1149 var runtimeInitialized = false;
   1150 
   1151 function preRun() {
   1152   // compatibility - merge in anything from Module['preRun'] at this time
   1153   if (Module['preRun']) {
   1154     if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
   1155     while (Module['preRun'].length) {
   1156       addOnPreRun(Module['preRun'].shift());
   1157     }
   1158   }
   1159   callRuntimeCallbacks(__ATPRERUN__);
   1160 }
   1161 
   1162 function ensureInitRuntime() {
   1163   if (runtimeInitialized) return;
   1164   runtimeInitialized = true;
   1165   callRuntimeCallbacks(__ATINIT__);
   1166 }
   1167 
   1168 function preMain() {
   1169   callRuntimeCallbacks(__ATMAIN__);
   1170 }
   1171 
   1172 function exitRuntime() {
   1173   callRuntimeCallbacks(__ATEXIT__);
   1174 }
   1175 
   1176 function postRun() {
   1177   // compatibility - merge in anything from Module['postRun'] at this time
   1178   if (Module['postRun']) {
   1179     if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
   1180     while (Module['postRun'].length) {
   1181       addOnPostRun(Module['postRun'].shift());
   1182     }
   1183   }
   1184   callRuntimeCallbacks(__ATPOSTRUN__);
   1185 }
   1186 
   1187 function addOnPreRun(cb) {
   1188   __ATPRERUN__.unshift(cb);
   1189 }
   1190 Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
   1191 
   1192 function addOnInit(cb) {
   1193   __ATINIT__.unshift(cb);
   1194 }
   1195 Module['addOnInit'] = Module.addOnInit = addOnInit;
   1196 
   1197 function addOnPreMain(cb) {
   1198   __ATMAIN__.unshift(cb);
   1199 }
   1200 Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
   1201 
   1202 function addOnExit(cb) {
   1203   __ATEXIT__.unshift(cb);
   1204 }
   1205 Module['addOnExit'] = Module.addOnExit = addOnExit;
   1206 
   1207 function addOnPostRun(cb) {
   1208   __ATPOSTRUN__.unshift(cb);
   1209 }
   1210 Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
   1211 
   1212 // Tools
   1213 
   1214 // This processes a JS string into a C-line array of numbers, 0-terminated.
   1215 // For LLVM-originating strings, see parser.js:parseLLVMString function
   1216 function intArrayFromString(stringy, dontAddNull, length /* optional */) {
   1217   var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
   1218   if (length) {
   1219     ret.length = length;
   1220   }
   1221   if (!dontAddNull) {
   1222     ret.push(0);
   1223   }
   1224   return ret;
   1225 }
   1226 Module['intArrayFromString'] = intArrayFromString;
   1227 
   1228 function intArrayToString(array) {
   1229   var ret = [];
   1230   for (var i = 0; i < array.length; i++) {
   1231     var chr = array[i];
   1232     if (chr > 0xFF) {
   1233       chr &= 0xFF;
   1234     }
   1235     ret.push(String.fromCharCode(chr));
   1236   }
   1237   return ret.join('');
   1238 }
   1239 Module['intArrayToString'] = intArrayToString;
   1240 
   1241 // Write a Javascript array to somewhere in the heap
   1242 function writeStringToMemory(string, buffer, dontAddNull) {
   1243   var array = intArrayFromString(string, dontAddNull);
   1244   var i = 0;
   1245   while (i < array.length) {
   1246     var chr = array[i];
   1247     HEAP8[(((buffer)+(i))|0)]=chr;
   1248     i = i + 1;
   1249   }
   1250 }
   1251 Module['writeStringToMemory'] = writeStringToMemory;
   1252 
   1253 function writeArrayToMemory(array, buffer) {
   1254   for (var i = 0; i < array.length; i++) {
   1255     HEAP8[(((buffer)+(i))|0)]=array[i];
   1256   }
   1257 }
   1258 Module['writeArrayToMemory'] = writeArrayToMemory;
   1259 
   1260 function writeAsciiToMemory(str, buffer, dontAddNull) {
   1261   for (var i = 0; i < str.length; i++) {
   1262     HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
   1263   }
   1264   if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
   1265 }
   1266 Module['writeAsciiToMemory'] = writeAsciiToMemory;
   1267 
   1268 function unSign(value, bits, ignore) {
   1269   if (value >= 0) {
   1270     return value;
   1271   }
   1272   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
   1273                     : Math.pow(2, bits)         + value;
   1274 }
   1275 function reSign(value, bits, ignore) {
   1276   if (value <= 0) {
   1277     return value;
   1278   }
   1279   var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
   1280                         : Math.pow(2, bits-1);
   1281   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
   1282                                                        // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
   1283                                                        // TODO: In i64 mode 1, resign the two parts separately and safely
   1284     value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
   1285   }
   1286   return value;
   1287 }
   1288 
   1289 // check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
   1290 if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
   1291   var ah  = a >>> 16;
   1292   var al = a & 0xffff;
   1293   var bh  = b >>> 16;
   1294   var bl = b & 0xffff;
   1295   return (al*bl + ((ah*bl + al*bh) << 16))|0;
   1296 };
   1297 Math.imul = Math['imul'];
   1298 
   1299 
   1300 var Math_abs = Math.abs;
   1301 var Math_cos = Math.cos;
   1302 var Math_sin = Math.sin;
   1303 var Math_tan = Math.tan;
   1304 var Math_acos = Math.acos;
   1305 var Math_asin = Math.asin;
   1306 var Math_atan = Math.atan;
   1307 var Math_atan2 = Math.atan2;
   1308 var Math_exp = Math.exp;
   1309 var Math_log = Math.log;
   1310 var Math_sqrt = Math.sqrt;
   1311 var Math_ceil = Math.ceil;
   1312 var Math_floor = Math.floor;
   1313 var Math_pow = Math.pow;
   1314 var Math_imul = Math.imul;
   1315 var Math_fround = Math.fround;
   1316 var Math_min = Math.min;
   1317 
   1318 // A counter of dependencies for calling run(). If we need to
   1319 // do asynchronous work before running, increment this and
   1320 // decrement it. Incrementing must happen in a place like
   1321 // PRE_RUN_ADDITIONS (used by emcc to add file preloading).
   1322 // Note that you can add dependencies in preRun, even though
   1323 // it happens right before run - run will be postponed until
   1324 // the dependencies are met.
   1325 var runDependencies = 0;
   1326 var runDependencyWatcher = null;
   1327 var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
   1328 
   1329 function addRunDependency(id) {
   1330   runDependencies++;
   1331   if (Module['monitorRunDependencies']) {
   1332     Module['monitorRunDependencies'](runDependencies);
   1333   }
   1334 }
   1335 Module['addRunDependency'] = addRunDependency;
   1336 function removeRunDependency(id) {
   1337   runDependencies--;
   1338   if (Module['monitorRunDependencies']) {
   1339     Module['monitorRunDependencies'](runDependencies);
   1340   }
   1341   if (runDependencies == 0) {
   1342     if (runDependencyWatcher !== null) {
   1343       clearInterval(runDependencyWatcher);
   1344       runDependencyWatcher = null;
   1345     }
   1346     if (dependenciesFulfilled) {
   1347       var callback = dependenciesFulfilled;
   1348       dependenciesFulfilled = null;
   1349       callback(); // can add another dependenciesFulfilled
   1350     }
   1351   }
   1352 }
   1353 Module['removeRunDependency'] = removeRunDependency;
   1354 
   1355 Module["preloadedImages"] = {}; // maps url to image data
   1356 Module["preloadedAudios"] = {}; // maps url to audio data
   1357 
   1358 
   1359 var memoryInitializer = null;
   1360 
   1361 // === Body ===
   1362 
   1363 
   1364 
   1365 
   1366 
   1367 STATIC_BASE = 8;
   1368 
   1369 STATICTOP = STATIC_BASE + Runtime.alignMemory(531);
   1370 /* global initializers */ __ATINIT__.push();
   1371 
   1372 
   1373 /* memory initializer */ allocate([101,114,114,111,114,58,32,37,100,10,0,0,0,0,0,0,102,105,110,97,108,58,32,37,100,46,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
   1374 
   1375 
   1376 
   1377 
   1378 var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
   1379 
   1380 assert(tempDoublePtr % 8 == 0);
   1381 
   1382 function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
   1383 
   1384   HEAP8[tempDoublePtr] = HEAP8[ptr];
   1385 
   1386   HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
   1387 
   1388   HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
   1389 
   1390   HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
   1391 
   1392 }
   1393 
   1394 function copyTempDouble(ptr) {
   1395 
   1396   HEAP8[tempDoublePtr] = HEAP8[ptr];
   1397 
   1398   HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
   1399 
   1400   HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
   1401 
   1402   HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
   1403 
   1404   HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
   1405 
   1406   HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
   1407 
   1408   HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
   1409 
   1410   HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
   1411 
   1412 }
   1413 
   1414 
   1415 
   1416 
   1417 
   1418 
   1419   var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
   1420 
   1421   var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
   1422 
   1423 
   1424   var ___errno_state=0;function ___setErrNo(value) {
   1425       // For convenient setting and returning of errno.
   1426       HEAP32[((___errno_state)>>2)]=value;
   1427       return value;
   1428     }
   1429 
   1430   var PATH={splitPath:function (filename) {
   1431         var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
   1432         return splitPathRe.exec(filename).slice(1);
   1433       },normalizeArray:function (parts, allowAboveRoot) {
   1434         // if the path tries to go above the root, `up` ends up > 0
   1435         var up = 0;
   1436         for (var i = parts.length - 1; i >= 0; i--) {
   1437           var last = parts[i];
   1438           if (last === '.') {
   1439             parts.splice(i, 1);
   1440           } else if (last === '..') {
   1441             parts.splice(i, 1);
   1442             up++;
   1443           } else if (up) {
   1444             parts.splice(i, 1);
   1445             up--;
   1446           }
   1447         }
   1448         // if the path is allowed to go above the root, restore leading ..s
   1449         if (allowAboveRoot) {
   1450           for (; up--; up) {
   1451             parts.unshift('..');
   1452           }
   1453         }
   1454         return parts;
   1455       },normalize:function (path) {
   1456         var isAbsolute = path.charAt(0) === '/',
   1457             trailingSlash = path.substr(-1) === '/';
   1458         // Normalize the path
   1459         path = PATH.normalizeArray(path.split('/').filter(function(p) {
   1460           return !!p;
   1461         }), !isAbsolute).join('/');
   1462         if (!path && !isAbsolute) {
   1463           path = '.';
   1464         }
   1465         if (path && trailingSlash) {
   1466           path += '/';
   1467         }
   1468         return (isAbsolute ? '/' : '') + path;
   1469       },dirname:function (path) {
   1470         var result = PATH.splitPath(path),
   1471             root = result[0],
   1472             dir = result[1];
   1473         if (!root && !dir) {
   1474           // No dirname whatsoever
   1475           return '.';
   1476         }
   1477         if (dir) {
   1478           // It has a dirname, strip trailing slash
   1479           dir = dir.substr(0, dir.length - 1);
   1480         }
   1481         return root + dir;
   1482       },basename:function (path) {
   1483         // EMSCRIPTEN return '/'' for '/', not an empty string
   1484         if (path === '/') return '/';
   1485         var lastSlash = path.lastIndexOf('/');
   1486         if (lastSlash === -1) return path;
   1487         return path.substr(lastSlash+1);
   1488       },extname:function (path) {
   1489         return PATH.splitPath(path)[3];
   1490       },join:function () {
   1491         var paths = Array.prototype.slice.call(arguments, 0);
   1492         return PATH.normalize(paths.join('/'));
   1493       },join2:function (l, r) {
   1494         return PATH.normalize(l + '/' + r);
   1495       },resolve:function () {
   1496         var resolvedPath = '',
   1497           resolvedAbsolute = false;
   1498         for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
   1499           var path = (i >= 0) ? arguments[i] : FS.cwd();
   1500           // Skip empty and invalid entries
   1501           if (typeof path !== 'string') {
   1502             throw new TypeError('Arguments to path.resolve must be strings');
   1503           } else if (!path) {
   1504             continue;
   1505           }
   1506           resolvedPath = path + '/' + resolvedPath;
   1507           resolvedAbsolute = path.charAt(0) === '/';
   1508         }
   1509         // At this point the path should be resolved to a full absolute path, but
   1510         // handle relative paths to be safe (might happen when process.cwd() fails)
   1511         resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
   1512           return !!p;
   1513         }), !resolvedAbsolute).join('/');
   1514         return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
   1515       },relative:function (from, to) {
   1516         from = PATH.resolve(from).substr(1);
   1517         to = PATH.resolve(to).substr(1);
   1518         function trim(arr) {
   1519           var start = 0;
   1520           for (; start < arr.length; start++) {
   1521             if (arr[start] !== '') break;
   1522           }
   1523           var end = arr.length - 1;
   1524           for (; end >= 0; end--) {
   1525             if (arr[end] !== '') break;
   1526           }
   1527           if (start > end) return [];
   1528           return arr.slice(start, end - start + 1);
   1529         }
   1530         var fromParts = trim(from.split('/'));
   1531         var toParts = trim(to.split('/'));
   1532         var length = Math.min(fromParts.length, toParts.length);
   1533         var samePartsLength = length;
   1534         for (var i = 0; i < length; i++) {
   1535           if (fromParts[i] !== toParts[i]) {
   1536             samePartsLength = i;
   1537             break;
   1538           }
   1539         }
   1540         var outputParts = [];
   1541         for (var i = samePartsLength; i < fromParts.length; i++) {
   1542           outputParts.push('..');
   1543         }
   1544         outputParts = outputParts.concat(toParts.slice(samePartsLength));
   1545         return outputParts.join('/');
   1546       }};
   1547 
   1548   var TTY={ttys:[],init:function () {
   1549         // https://github.com/kripken/emscripten/pull/1555
   1550         // if (ENVIRONMENT_IS_NODE) {
   1551         //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
   1552         //   // device, it always assumes it's a TTY device. because of this, we're forcing
   1553         //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
   1554         //   // with text files until FS.init can be refactored.
   1555         //   process['stdin']['setEncoding']('utf8');
   1556         // }
   1557       },shutdown:function () {
   1558         // https://github.com/kripken/emscripten/pull/1555
   1559         // if (ENVIRONMENT_IS_NODE) {
   1560         //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
   1561         //   // 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
   1562         //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
   1563         //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
   1564         //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
   1565         //   process['stdin']['pause']();
   1566         // }
   1567       },register:function (dev, ops) {
   1568         TTY.ttys[dev] = { input: [], output: [], ops: ops };
   1569         FS.registerDevice(dev, TTY.stream_ops);
   1570       },stream_ops:{open:function (stream) {
   1571           var tty = TTY.ttys[stream.node.rdev];
   1572           if (!tty) {
   1573             throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
   1574           }
   1575           stream.tty = tty;
   1576           stream.seekable = false;
   1577         },close:function (stream) {
   1578           // flush any pending line data
   1579           if (stream.tty.output.length) {
   1580             stream.tty.ops.put_char(stream.tty, 10);
   1581           }
   1582         },read:function (stream, buffer, offset, length, pos /* ignored */) {
   1583           if (!stream.tty || !stream.tty.ops.get_char) {
   1584             throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
   1585           }
   1586           var bytesRead = 0;
   1587           for (var i = 0; i < length; i++) {
   1588             var result;
   1589             try {
   1590               result = stream.tty.ops.get_char(stream.tty);
   1591             } catch (e) {
   1592               throw new FS.ErrnoError(ERRNO_CODES.EIO);
   1593             }
   1594             if (result === undefined && bytesRead === 0) {
   1595               throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
   1596             }
   1597             if (result === null || result === undefined) break;
   1598             bytesRead++;
   1599             buffer[offset+i] = result;
   1600           }
   1601           if (bytesRead) {
   1602             stream.node.timestamp = Date.now();
   1603           }
   1604           return bytesRead;
   1605         },write:function (stream, buffer, offset, length, pos) {
   1606           if (!stream.tty || !stream.tty.ops.put_char) {
   1607             throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
   1608           }
   1609           for (var i = 0; i < length; i++) {
   1610             try {
   1611               stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
   1612             } catch (e) {
   1613               throw new FS.ErrnoError(ERRNO_CODES.EIO);
   1614             }
   1615           }
   1616           if (length) {
   1617             stream.node.timestamp = Date.now();
   1618           }
   1619           return i;
   1620         }},default_tty_ops:{get_char:function (tty) {
   1621           if (!tty.input.length) {
   1622             var result = null;
   1623             if (ENVIRONMENT_IS_NODE) {
   1624               result = process['stdin']['read']();
   1625               if (!result) {
   1626                 if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
   1627                   return null;  // EOF
   1628                 }
   1629                 return undefined;  // no data available
   1630               }
   1631             } else if (typeof window != 'undefined' &&
   1632               typeof window.prompt == 'function') {
   1633               // Browser.
   1634               result = window.prompt('Input: ');  // returns null on cancel
   1635               if (result !== null) {
   1636                 result += '\n';
   1637               }
   1638             } else if (typeof readline == 'function') {
   1639               // Command line.
   1640               result = readline();
   1641               if (result !== null) {
   1642                 result += '\n';
   1643               }
   1644             }
   1645             if (!result) {
   1646               return null;
   1647             }
   1648             tty.input = intArrayFromString(result, true);
   1649           }
   1650           return tty.input.shift();
   1651         },put_char:function (tty, val) {
   1652           if (val === null || val === 10) {
   1653             Module['print'](tty.output.join(''));
   1654             tty.output = [];
   1655           } else {
   1656             tty.output.push(TTY.utf8.processCChar(val));
   1657           }
   1658         }},default_tty1_ops:{put_char:function (tty, val) {
   1659           if (val === null || val === 10) {
   1660             Module['printErr'](tty.output.join(''));
   1661             tty.output = [];
   1662           } else {
   1663             tty.output.push(TTY.utf8.processCChar(val));
   1664           }
   1665         }}};
   1666 
   1667   var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
   1668         return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
   1669       },createNode:function (parent, name, mode, dev) {
   1670         if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
   1671           // no supported
   1672           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   1673         }
   1674         if (!MEMFS.ops_table) {
   1675           MEMFS.ops_table = {
   1676             dir: {
   1677               node: {
   1678                 getattr: MEMFS.node_ops.getattr,
   1679                 setattr: MEMFS.node_ops.setattr,
   1680                 lookup: MEMFS.node_ops.lookup,
   1681                 mknod: MEMFS.node_ops.mknod,
   1682                 rename: MEMFS.node_ops.rename,
   1683                 unlink: MEMFS.node_ops.unlink,
   1684                 rmdir: MEMFS.node_ops.rmdir,
   1685                 readdir: MEMFS.node_ops.readdir,
   1686                 symlink: MEMFS.node_ops.symlink
   1687               },
   1688               stream: {
   1689                 llseek: MEMFS.stream_ops.llseek
   1690               }
   1691             },
   1692             file: {
   1693               node: {
   1694                 getattr: MEMFS.node_ops.getattr,
   1695                 setattr: MEMFS.node_ops.setattr
   1696               },
   1697               stream: {
   1698                 llseek: MEMFS.stream_ops.llseek,
   1699                 read: MEMFS.stream_ops.read,
   1700                 write: MEMFS.stream_ops.write,
   1701                 allocate: MEMFS.stream_ops.allocate,
   1702                 mmap: MEMFS.stream_ops.mmap
   1703               }
   1704             },
   1705             link: {
   1706               node: {
   1707                 getattr: MEMFS.node_ops.getattr,
   1708                 setattr: MEMFS.node_ops.setattr,
   1709                 readlink: MEMFS.node_ops.readlink
   1710               },
   1711               stream: {}
   1712             },
   1713             chrdev: {
   1714               node: {
   1715                 getattr: MEMFS.node_ops.getattr,
   1716                 setattr: MEMFS.node_ops.setattr
   1717               },
   1718               stream: FS.chrdev_stream_ops
   1719             },
   1720           };
   1721         }
   1722         var node = FS.createNode(parent, name, mode, dev);
   1723         if (FS.isDir(node.mode)) {
   1724           node.node_ops = MEMFS.ops_table.dir.node;
   1725           node.stream_ops = MEMFS.ops_table.dir.stream;
   1726           node.contents = {};
   1727         } else if (FS.isFile(node.mode)) {
   1728           node.node_ops = MEMFS.ops_table.file.node;
   1729           node.stream_ops = MEMFS.ops_table.file.stream;
   1730           node.contents = [];
   1731           node.contentMode = MEMFS.CONTENT_FLEXIBLE;
   1732         } else if (FS.isLink(node.mode)) {
   1733           node.node_ops = MEMFS.ops_table.link.node;
   1734           node.stream_ops = MEMFS.ops_table.link.stream;
   1735         } else if (FS.isChrdev(node.mode)) {
   1736           node.node_ops = MEMFS.ops_table.chrdev.node;
   1737           node.stream_ops = MEMFS.ops_table.chrdev.stream;
   1738         }
   1739         node.timestamp = Date.now();
   1740         // add the new node to the parent
   1741         if (parent) {
   1742           parent.contents[name] = node;
   1743         }
   1744         return node;
   1745       },ensureFlexible:function (node) {
   1746         if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
   1747           var contents = node.contents;
   1748           node.contents = Array.prototype.slice.call(contents);
   1749           node.contentMode = MEMFS.CONTENT_FLEXIBLE;
   1750         }
   1751       },node_ops:{getattr:function (node) {
   1752           var attr = {};
   1753           // device numbers reuse inode numbers.
   1754           attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
   1755           attr.ino = node.id;
   1756           attr.mode = node.mode;
   1757           attr.nlink = 1;
   1758           attr.uid = 0;
   1759           attr.gid = 0;
   1760           attr.rdev = node.rdev;
   1761           if (FS.isDir(node.mode)) {
   1762             attr.size = 4096;
   1763           } else if (FS.isFile(node.mode)) {
   1764             attr.size = node.contents.length;
   1765           } else if (FS.isLink(node.mode)) {
   1766             attr.size = node.link.length;
   1767           } else {
   1768             attr.size = 0;
   1769           }
   1770           attr.atime = new Date(node.timestamp);
   1771           attr.mtime = new Date(node.timestamp);
   1772           attr.ctime = new Date(node.timestamp);
   1773           // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
   1774           //       but this is not required by the standard.
   1775           attr.blksize = 4096;
   1776           attr.blocks = Math.ceil(attr.size / attr.blksize);
   1777           return attr;
   1778         },setattr:function (node, attr) {
   1779           if (attr.mode !== undefined) {
   1780             node.mode = attr.mode;
   1781           }
   1782           if (attr.timestamp !== undefined) {
   1783             node.timestamp = attr.timestamp;
   1784           }
   1785           if (attr.size !== undefined) {
   1786             MEMFS.ensureFlexible(node);
   1787             var contents = node.contents;
   1788             if (attr.size < contents.length) contents.length = attr.size;
   1789             else while (attr.size > contents.length) contents.push(0);
   1790           }
   1791         },lookup:function (parent, name) {
   1792           throw FS.genericErrors[ERRNO_CODES.ENOENT];
   1793         },mknod:function (parent, name, mode, dev) {
   1794           return MEMFS.createNode(parent, name, mode, dev);
   1795         },rename:function (old_node, new_dir, new_name) {
   1796           // if we're overwriting a directory at new_name, make sure it's empty.
   1797           if (FS.isDir(old_node.mode)) {
   1798             var new_node;
   1799             try {
   1800               new_node = FS.lookupNode(new_dir, new_name);
   1801             } catch (e) {
   1802             }
   1803             if (new_node) {
   1804               for (var i in new_node.contents) {
   1805                 throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
   1806               }
   1807             }
   1808           }
   1809           // do the internal rewiring
   1810           delete old_node.parent.contents[old_node.name];
   1811           old_node.name = new_name;
   1812           new_dir.contents[new_name] = old_node;
   1813           old_node.parent = new_dir;
   1814         },unlink:function (parent, name) {
   1815           delete parent.contents[name];
   1816         },rmdir:function (parent, name) {
   1817           var node = FS.lookupNode(parent, name);
   1818           for (var i in node.contents) {
   1819             throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
   1820           }
   1821           delete parent.contents[name];
   1822         },readdir:function (node) {
   1823           var entries = ['.', '..']
   1824           for (var key in node.contents) {
   1825             if (!node.contents.hasOwnProperty(key)) {
   1826               continue;
   1827             }
   1828             entries.push(key);
   1829           }
   1830           return entries;
   1831         },symlink:function (parent, newname, oldpath) {
   1832           var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
   1833           node.link = oldpath;
   1834           return node;
   1835         },readlink:function (node) {
   1836           if (!FS.isLink(node.mode)) {
   1837             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   1838           }
   1839           return node.link;
   1840         }},stream_ops:{read:function (stream, buffer, offset, length, position) {
   1841           var contents = stream.node.contents;
   1842           if (position >= contents.length)
   1843             return 0;
   1844           var size = Math.min(contents.length - position, length);
   1845           assert(size >= 0);
   1846           if (size > 8 && contents.subarray) { // non-trivial, and typed array
   1847             buffer.set(contents.subarray(position, position + size), offset);
   1848           } else
   1849           {
   1850             for (var i = 0; i < size; i++) {
   1851               buffer[offset + i] = contents[position + i];
   1852             }
   1853           }
   1854           return size;
   1855         },write:function (stream, buffer, offset, length, position, canOwn) {
   1856           var node = stream.node;
   1857           node.timestamp = Date.now();
   1858           var contents = node.contents;
   1859           if (length && contents.length === 0 && position === 0 && buffer.subarray) {
   1860             // just replace it with the new data
   1861             if (canOwn && offset === 0) {
   1862               node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
   1863               node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
   1864             } else {
   1865               node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
   1866               node.contentMode = MEMFS.CONTENT_FIXED;
   1867             }
   1868             return length;
   1869           }
   1870           MEMFS.ensureFlexible(node);
   1871           var contents = node.contents;
   1872           while (contents.length < position) contents.push(0);
   1873           for (var i = 0; i < length; i++) {
   1874             contents[position + i] = buffer[offset + i];
   1875           }
   1876           return length;
   1877         },llseek:function (stream, offset, whence) {
   1878           var position = offset;
   1879           if (whence === 1) {  // SEEK_CUR.
   1880             position += stream.position;
   1881           } else if (whence === 2) {  // SEEK_END.
   1882             if (FS.isFile(stream.node.mode)) {
   1883               position += stream.node.contents.length;
   1884             }
   1885           }
   1886           if (position < 0) {
   1887             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   1888           }
   1889           stream.ungotten = [];
   1890           stream.position = position;
   1891           return position;
   1892         },allocate:function (stream, offset, length) {
   1893           MEMFS.ensureFlexible(stream.node);
   1894           var contents = stream.node.contents;
   1895           var limit = offset + length;
   1896           while (limit > contents.length) contents.push(0);
   1897         },mmap:function (stream, buffer, offset, length, position, prot, flags) {
   1898           if (!FS.isFile(stream.node.mode)) {
   1899             throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
   1900           }
   1901           var ptr;
   1902           var allocated;
   1903           var contents = stream.node.contents;
   1904           // Only make a new copy when MAP_PRIVATE is specified.
   1905           if ( !(flags & 2) &&
   1906                 (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
   1907             // We can't emulate MAP_SHARED when the file is not backed by the buffer
   1908             // we're mapping to (e.g. the HEAP buffer).
   1909             allocated = false;
   1910             ptr = contents.byteOffset;
   1911           } else {
   1912             // Try to avoid unnecessary slices.
   1913             if (position > 0 || position + length < contents.length) {
   1914               if (contents.subarray) {
   1915                 contents = contents.subarray(position, position + length);
   1916               } else {
   1917                 contents = Array.prototype.slice.call(contents, position, position + length);
   1918               }
   1919             }
   1920             allocated = true;
   1921             ptr = _malloc(length);
   1922             if (!ptr) {
   1923               throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
   1924             }
   1925             buffer.set(contents, ptr);
   1926           }
   1927           return { ptr: ptr, allocated: allocated };
   1928         }}};
   1929 
   1930   var IDBFS={dbs:{},indexedDB:function () {
   1931         return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
   1932       },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
   1933         // reuse all of the core MEMFS functionality
   1934         return MEMFS.mount.apply(null, arguments);
   1935       },syncfs:function (mount, populate, callback) {
   1936         IDBFS.getLocalSet(mount, function(err, local) {
   1937           if (err) return callback(err);
   1938 
   1939           IDBFS.getRemoteSet(mount, function(err, remote) {
   1940             if (err) return callback(err);
   1941 
   1942             var src = populate ? remote : local;
   1943             var dst = populate ? local : remote;
   1944 
   1945             IDBFS.reconcile(src, dst, callback);
   1946           });
   1947         });
   1948       },getDB:function (name, callback) {
   1949         // check the cache first
   1950         var db = IDBFS.dbs[name];
   1951         if (db) {
   1952           return callback(null, db);
   1953         }
   1954 
   1955         var req;
   1956         try {
   1957           req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
   1958         } catch (e) {
   1959           return callback(e);
   1960         }
   1961         req.onupgradeneeded = function(e) {
   1962           var db = e.target.result;
   1963           var transaction = e.target.transaction;
   1964 
   1965           var fileStore;
   1966 
   1967           if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
   1968             fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
   1969           } else {
   1970             fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
   1971           }
   1972 
   1973           fileStore.createIndex('timestamp', 'timestamp', { unique: false });
   1974         };
   1975         req.onsuccess = function() {
   1976           db = req.result;
   1977 
   1978           // add to the cache
   1979           IDBFS.dbs[name] = db;
   1980           callback(null, db);
   1981         };
   1982         req.onerror = function() {
   1983           callback(this.error);
   1984         };
   1985       },getLocalSet:function (mount, callback) {
   1986         var entries = {};
   1987 
   1988         function isRealDir(p) {
   1989           return p !== '.' && p !== '..';
   1990         };
   1991         function toAbsolute(root) {
   1992           return function(p) {
   1993             return PATH.join2(root, p);
   1994           }
   1995         };
   1996 
   1997         var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
   1998 
   1999         while (check.length) {
   2000           var path = check.pop();
   2001           var stat;
   2002 
   2003           try {
   2004             stat = FS.stat(path);
   2005           } catch (e) {
   2006             return callback(e);
   2007           }
   2008 
   2009           if (FS.isDir(stat.mode)) {
   2010             check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
   2011           }
   2012 
   2013           entries[path] = { timestamp: stat.mtime };
   2014         }
   2015 
   2016         return callback(null, { type: 'local', entries: entries });
   2017       },getRemoteSet:function (mount, callback) {
   2018         var entries = {};
   2019 
   2020         IDBFS.getDB(mount.mountpoint, function(err, db) {
   2021           if (err) return callback(err);
   2022 
   2023           var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
   2024           transaction.onerror = function() { callback(this.error); };
   2025 
   2026           var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
   2027           var index = store.index('timestamp');
   2028 
   2029           index.openKeyCursor().onsuccess = function(event) {
   2030             var cursor = event.target.result;
   2031 
   2032             if (!cursor) {
   2033               return callback(null, { type: 'remote', db: db, entries: entries });
   2034             }
   2035 
   2036             entries[cursor.primaryKey] = { timestamp: cursor.key };
   2037 
   2038             cursor.continue();
   2039           };
   2040         });
   2041       },loadLocalEntry:function (path, callback) {
   2042         var stat, node;
   2043 
   2044         try {
   2045           var lookup = FS.lookupPath(path);
   2046           node = lookup.node;
   2047           stat = FS.stat(path);
   2048         } catch (e) {
   2049           return callback(e);
   2050         }
   2051 
   2052         if (FS.isDir(stat.mode)) {
   2053           return callback(null, { timestamp: stat.mtime, mode: stat.mode });
   2054         } else if (FS.isFile(stat.mode)) {
   2055           return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
   2056         } else {
   2057           return callback(new Error('node type not supported'));
   2058         }
   2059       },storeLocalEntry:function (path, entry, callback) {
   2060         try {
   2061           if (FS.isDir(entry.mode)) {
   2062             FS.mkdir(path, entry.mode);
   2063           } else if (FS.isFile(entry.mode)) {
   2064             FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
   2065           } else {
   2066             return callback(new Error('node type not supported'));
   2067           }
   2068 
   2069           FS.utime(path, entry.timestamp, entry.timestamp);
   2070         } catch (e) {
   2071           return callback(e);
   2072         }
   2073 
   2074         callback(null);
   2075       },removeLocalEntry:function (path, callback) {
   2076         try {
   2077           var lookup = FS.lookupPath(path);
   2078           var stat = FS.stat(path);
   2079 
   2080           if (FS.isDir(stat.mode)) {
   2081             FS.rmdir(path);
   2082           } else if (FS.isFile(stat.mode)) {
   2083             FS.unlink(path);
   2084           }
   2085         } catch (e) {
   2086           return callback(e);
   2087         }
   2088 
   2089         callback(null);
   2090       },loadRemoteEntry:function (store, path, callback) {
   2091         var req = store.get(path);
   2092         req.onsuccess = function(event) { callback(null, event.target.result); };
   2093         req.onerror = function() { callback(this.error); };
   2094       },storeRemoteEntry:function (store, path, entry, callback) {
   2095         var req = store.put(entry, path);
   2096         req.onsuccess = function() { callback(null); };
   2097         req.onerror = function() { callback(this.error); };
   2098       },removeRemoteEntry:function (store, path, callback) {
   2099         var req = store.delete(path);
   2100         req.onsuccess = function() { callback(null); };
   2101         req.onerror = function() { callback(this.error); };
   2102       },reconcile:function (src, dst, callback) {
   2103         var total = 0;
   2104 
   2105         var create = [];
   2106         Object.keys(src.entries).forEach(function (key) {
   2107           var e = src.entries[key];
   2108           var e2 = dst.entries[key];
   2109           if (!e2 || e.timestamp > e2.timestamp) {
   2110             create.push(key);
   2111             total++;
   2112           }
   2113         });
   2114 
   2115         var remove = [];
   2116         Object.keys(dst.entries).forEach(function (key) {
   2117           var e = dst.entries[key];
   2118           var e2 = src.entries[key];
   2119           if (!e2) {
   2120             remove.push(key);
   2121             total++;
   2122           }
   2123         });
   2124 
   2125         if (!total) {
   2126           return callback(null);
   2127         }
   2128 
   2129         var errored = false;
   2130         var completed = 0;
   2131         var db = src.type === 'remote' ? src.db : dst.db;
   2132         var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
   2133         var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
   2134 
   2135         function done(err) {
   2136           if (err) {
   2137             if (!done.errored) {
   2138               done.errored = true;
   2139               return callback(err);
   2140             }
   2141             return;
   2142           }
   2143           if (++completed >= total) {
   2144             return callback(null);
   2145           }
   2146         };
   2147 
   2148         transaction.onerror = function() { done(this.error); };
   2149 
   2150         // sort paths in ascending order so directory entries are created
   2151         // before the files inside them
   2152         create.sort().forEach(function (path) {
   2153           if (dst.type === 'local') {
   2154             IDBFS.loadRemoteEntry(store, path, function (err, entry) {
   2155               if (err) return done(err);
   2156               IDBFS.storeLocalEntry(path, entry, done);
   2157             });
   2158           } else {
   2159             IDBFS.loadLocalEntry(path, function (err, entry) {
   2160               if (err) return done(err);
   2161               IDBFS.storeRemoteEntry(store, path, entry, done);
   2162             });
   2163           }
   2164         });
   2165 
   2166         // sort paths in descending order so files are deleted before their
   2167         // parent directories
   2168         remove.sort().reverse().forEach(function(path) {
   2169           if (dst.type === 'local') {
   2170             IDBFS.removeLocalEntry(path, done);
   2171           } else {
   2172             IDBFS.removeRemoteEntry(store, path, done);
   2173           }
   2174         });
   2175       }};
   2176 
   2177   var NODEFS={isWindows:false,staticInit:function () {
   2178         NODEFS.isWindows = !!process.platform.match(/^win/);
   2179       },mount:function (mount) {
   2180         assert(ENVIRONMENT_IS_NODE);
   2181         return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
   2182       },createNode:function (parent, name, mode, dev) {
   2183         if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
   2184           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   2185         }
   2186         var node = FS.createNode(parent, name, mode);
   2187         node.node_ops = NODEFS.node_ops;
   2188         node.stream_ops = NODEFS.stream_ops;
   2189         return node;
   2190       },getMode:function (path) {
   2191         var stat;
   2192         try {
   2193           stat = fs.lstatSync(path);
   2194           if (NODEFS.isWindows) {
   2195             // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
   2196             // propagate write bits to execute bits.
   2197             stat.mode = stat.mode | ((stat.mode & 146) >> 1);
   2198           }
   2199         } catch (e) {
   2200           if (!e.code) throw e;
   2201           throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2202         }
   2203         return stat.mode;
   2204       },realPath:function (node) {
   2205         var parts = [];
   2206         while (node.parent !== node) {
   2207           parts.push(node.name);
   2208           node = node.parent;
   2209         }
   2210         parts.push(node.mount.opts.root);
   2211         parts.reverse();
   2212         return PATH.join.apply(null, parts);
   2213       },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
   2214         if (flags in NODEFS.flagsToPermissionStringMap) {
   2215           return NODEFS.flagsToPermissionStringMap[flags];
   2216         } else {
   2217           return flags;
   2218         }
   2219       },node_ops:{getattr:function (node) {
   2220           var path = NODEFS.realPath(node);
   2221           var stat;
   2222           try {
   2223             stat = fs.lstatSync(path);
   2224           } catch (e) {
   2225             if (!e.code) throw e;
   2226             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2227           }
   2228           // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
   2229           // See http://support.microsoft.com/kb/140365
   2230           if (NODEFS.isWindows && !stat.blksize) {
   2231             stat.blksize = 4096;
   2232           }
   2233           if (NODEFS.isWindows && !stat.blocks) {
   2234             stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
   2235           }
   2236           return {
   2237             dev: stat.dev,
   2238             ino: stat.ino,
   2239             mode: stat.mode,
   2240             nlink: stat.nlink,
   2241             uid: stat.uid,
   2242             gid: stat.gid,
   2243             rdev: stat.rdev,
   2244             size: stat.size,
   2245             atime: stat.atime,
   2246             mtime: stat.mtime,
   2247             ctime: stat.ctime,
   2248             blksize: stat.blksize,
   2249             blocks: stat.blocks
   2250           };
   2251         },setattr:function (node, attr) {
   2252           var path = NODEFS.realPath(node);
   2253           try {
   2254             if (attr.mode !== undefined) {
   2255               fs.chmodSync(path, attr.mode);
   2256               // update the common node structure mode as well
   2257               node.mode = attr.mode;
   2258             }
   2259             if (attr.timestamp !== undefined) {
   2260               var date = new Date(attr.timestamp);
   2261               fs.utimesSync(path, date, date);
   2262             }
   2263             if (attr.size !== undefined) {
   2264               fs.truncateSync(path, attr.size);
   2265             }
   2266           } catch (e) {
   2267             if (!e.code) throw e;
   2268             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2269           }
   2270         },lookup:function (parent, name) {
   2271           var path = PATH.join2(NODEFS.realPath(parent), name);
   2272           var mode = NODEFS.getMode(path);
   2273           return NODEFS.createNode(parent, name, mode);
   2274         },mknod:function (parent, name, mode, dev) {
   2275           var node = NODEFS.createNode(parent, name, mode, dev);
   2276           // create the backing node for this in the fs root as well
   2277           var path = NODEFS.realPath(node);
   2278           try {
   2279             if (FS.isDir(node.mode)) {
   2280               fs.mkdirSync(path, node.mode);
   2281             } else {
   2282               fs.writeFileSync(path, '', { mode: node.mode });
   2283             }
   2284           } catch (e) {
   2285             if (!e.code) throw e;
   2286             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2287           }
   2288           return node;
   2289         },rename:function (oldNode, newDir, newName) {
   2290           var oldPath = NODEFS.realPath(oldNode);
   2291           var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
   2292           try {
   2293             fs.renameSync(oldPath, newPath);
   2294           } catch (e) {
   2295             if (!e.code) throw e;
   2296             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2297           }
   2298         },unlink:function (parent, name) {
   2299           var path = PATH.join2(NODEFS.realPath(parent), name);
   2300           try {
   2301             fs.unlinkSync(path);
   2302           } catch (e) {
   2303             if (!e.code) throw e;
   2304             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2305           }
   2306         },rmdir:function (parent, name) {
   2307           var path = PATH.join2(NODEFS.realPath(parent), name);
   2308           try {
   2309             fs.rmdirSync(path);
   2310           } catch (e) {
   2311             if (!e.code) throw e;
   2312             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2313           }
   2314         },readdir:function (node) {
   2315           var path = NODEFS.realPath(node);
   2316           try {
   2317             return fs.readdirSync(path);
   2318           } catch (e) {
   2319             if (!e.code) throw e;
   2320             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2321           }
   2322         },symlink:function (parent, newName, oldPath) {
   2323           var newPath = PATH.join2(NODEFS.realPath(parent), newName);
   2324           try {
   2325             fs.symlinkSync(oldPath, newPath);
   2326           } catch (e) {
   2327             if (!e.code) throw e;
   2328             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2329           }
   2330         },readlink:function (node) {
   2331           var path = NODEFS.realPath(node);
   2332           try {
   2333             return fs.readlinkSync(path);
   2334           } catch (e) {
   2335             if (!e.code) throw e;
   2336             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2337           }
   2338         }},stream_ops:{open:function (stream) {
   2339           var path = NODEFS.realPath(stream.node);
   2340           try {
   2341             if (FS.isFile(stream.node.mode)) {
   2342               stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
   2343             }
   2344           } catch (e) {
   2345             if (!e.code) throw e;
   2346             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2347           }
   2348         },close:function (stream) {
   2349           try {
   2350             if (FS.isFile(stream.node.mode) && stream.nfd) {
   2351               fs.closeSync(stream.nfd);
   2352             }
   2353           } catch (e) {
   2354             if (!e.code) throw e;
   2355             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2356           }
   2357         },read:function (stream, buffer, offset, length, position) {
   2358           // FIXME this is terrible.
   2359           var nbuffer = new Buffer(length);
   2360           var res;
   2361           try {
   2362             res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
   2363           } catch (e) {
   2364             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2365           }
   2366           if (res > 0) {
   2367             for (var i = 0; i < res; i++) {
   2368               buffer[offset + i] = nbuffer[i];
   2369             }
   2370           }
   2371           return res;
   2372         },write:function (stream, buffer, offset, length, position) {
   2373           // FIXME this is terrible.
   2374           var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
   2375           var res;
   2376           try {
   2377             res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
   2378           } catch (e) {
   2379             throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2380           }
   2381           return res;
   2382         },llseek:function (stream, offset, whence) {
   2383           var position = offset;
   2384           if (whence === 1) {  // SEEK_CUR.
   2385             position += stream.position;
   2386           } else if (whence === 2) {  // SEEK_END.
   2387             if (FS.isFile(stream.node.mode)) {
   2388               try {
   2389                 var stat = fs.fstatSync(stream.nfd);
   2390                 position += stat.size;
   2391               } catch (e) {
   2392                 throw new FS.ErrnoError(ERRNO_CODES[e.code]);
   2393               }
   2394             }
   2395           }
   2396 
   2397           if (position < 0) {
   2398             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   2399           }
   2400 
   2401           stream.position = position;
   2402           return position;
   2403         }}};
   2404 
   2405   var _stdin=allocate(1, "i32*", ALLOC_STATIC);
   2406 
   2407   var _stdout=allocate(1, "i32*", ALLOC_STATIC);
   2408 
   2409   var _stderr=allocate(1, "i32*", ALLOC_STATIC);
   2410 
   2411   function _fflush(stream) {
   2412       // int fflush(FILE *stream);
   2413       // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
   2414       // we don't currently perform any user-space buffering of data
   2415     }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
   2416         if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
   2417         return ___setErrNo(e.errno);
   2418       },lookupPath:function (path, opts) {
   2419         path = PATH.resolve(FS.cwd(), path);
   2420         opts = opts || {};
   2421 
   2422         var defaults = {
   2423           follow_mount: true,
   2424           recurse_count: 0
   2425         };
   2426         for (var key in defaults) {
   2427           if (opts[key] === undefined) {
   2428             opts[key] = defaults[key];
   2429           }
   2430         }
   2431 
   2432         if (opts.recurse_count > 8) {  // max recursive lookup of 8
   2433           throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
   2434         }
   2435 
   2436         // split the path
   2437         var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
   2438           return !!p;
   2439         }), false);
   2440 
   2441         // start at the root
   2442         var current = FS.root;
   2443         var current_path = '/';
   2444 
   2445         for (var i = 0; i < parts.length; i++) {
   2446           var islast = (i === parts.length-1);
   2447           if (islast && opts.parent) {
   2448             // stop resolving
   2449             break;
   2450           }
   2451 
   2452           current = FS.lookupNode(current, parts[i]);
   2453           current_path = PATH.join2(current_path, parts[i]);
   2454 
   2455           // jump to the mount's root node if this is a mountpoint
   2456           if (FS.isMountpoint(current)) {
   2457             if (!islast || (islast && opts.follow_mount)) {
   2458               current = current.mounted.root;
   2459             }
   2460           }
   2461 
   2462           // by default, lookupPath will not follow a symlink if it is the final path component.
   2463           // setting opts.follow = true will override this behavior.
   2464           if (!islast || opts.follow) {
   2465             var count = 0;
   2466             while (FS.isLink(current.mode)) {
   2467               var link = FS.readlink(current_path);
   2468               current_path = PATH.resolve(PATH.dirname(current_path), link);
   2469 
   2470               var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
   2471               current = lookup.node;
   2472 
   2473               if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
   2474                 throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
   2475               }
   2476             }
   2477           }
   2478         }
   2479 
   2480         return { path: current_path, node: current };
   2481       },getPath:function (node) {
   2482         var path;
   2483         while (true) {
   2484           if (FS.isRoot(node)) {
   2485             var mount = node.mount.mountpoint;
   2486             if (!path) return mount;
   2487             return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
   2488           }
   2489           path = path ? node.name + '/' + path : node.name;
   2490           node = node.parent;
   2491         }
   2492       },hashName:function (parentid, name) {
   2493         var hash = 0;
   2494 
   2495 
   2496         for (var i = 0; i < name.length; i++) {
   2497           hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
   2498         }
   2499         return ((parentid + hash) >>> 0) % FS.nameTable.length;
   2500       },hashAddNode:function (node) {
   2501         var hash = FS.hashName(node.parent.id, node.name);
   2502         node.name_next = FS.nameTable[hash];
   2503         FS.nameTable[hash] = node;
   2504       },hashRemoveNode:function (node) {
   2505         var hash = FS.hashName(node.parent.id, node.name);
   2506         if (FS.nameTable[hash] === node) {
   2507           FS.nameTable[hash] = node.name_next;
   2508         } else {
   2509           var current = FS.nameTable[hash];
   2510           while (current) {
   2511             if (current.name_next === node) {
   2512               current.name_next = node.name_next;
   2513               break;
   2514             }
   2515             current = current.name_next;
   2516           }
   2517         }
   2518       },lookupNode:function (parent, name) {
   2519         var err = FS.mayLookup(parent);
   2520         if (err) {
   2521           throw new FS.ErrnoError(err);
   2522         }
   2523         var hash = FS.hashName(parent.id, name);
   2524         for (var node = FS.nameTable[hash]; node; node = node.name_next) {
   2525           var nodeName = node.name;
   2526           if (node.parent.id === parent.id && nodeName === name) {
   2527             return node;
   2528           }
   2529         }
   2530         // if we failed to find it in the cache, call into the VFS
   2531         return FS.lookup(parent, name);
   2532       },createNode:function (parent, name, mode, rdev) {
   2533         if (!FS.FSNode) {
   2534           FS.FSNode = function(parent, name, mode, rdev) {
   2535             if (!parent) {
   2536               parent = this;  // root node sets parent to itself
   2537             }
   2538             this.parent = parent;
   2539             this.mount = parent.mount;
   2540             this.mounted = null;
   2541             this.id = FS.nextInode++;
   2542             this.name = name;
   2543             this.mode = mode;
   2544             this.node_ops = {};
   2545             this.stream_ops = {};
   2546             this.rdev = rdev;
   2547           };
   2548 
   2549           FS.FSNode.prototype = {};
   2550 
   2551           // compatibility
   2552           var readMode = 292 | 73;
   2553           var writeMode = 146;
   2554 
   2555           // NOTE we must use Object.defineProperties instead of individual calls to
   2556           // Object.defineProperty in order to make closure compiler happy
   2557           Object.defineProperties(FS.FSNode.prototype, {
   2558             read: {
   2559               get: function() { return (this.mode & readMode) === readMode; },
   2560               set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
   2561             },
   2562             write: {
   2563               get: function() { return (this.mode & writeMode) === writeMode; },
   2564               set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
   2565             },
   2566             isFolder: {
   2567               get: function() { return FS.isDir(this.mode); },
   2568             },
   2569             isDevice: {
   2570               get: function() { return FS.isChrdev(this.mode); },
   2571             },
   2572           });
   2573         }
   2574 
   2575         var node = new FS.FSNode(parent, name, mode, rdev);
   2576 
   2577         FS.hashAddNode(node);
   2578 
   2579         return node;
   2580       },destroyNode:function (node) {
   2581         FS.hashRemoveNode(node);
   2582       },isRoot:function (node) {
   2583         return node === node.parent;
   2584       },isMountpoint:function (node) {
   2585         return !!node.mounted;
   2586       },isFile:function (mode) {
   2587         return (mode & 61440) === 32768;
   2588       },isDir:function (mode) {
   2589         return (mode & 61440) === 16384;
   2590       },isLink:function (mode) {
   2591         return (mode & 61440) === 40960;
   2592       },isChrdev:function (mode) {
   2593         return (mode & 61440) === 8192;
   2594       },isBlkdev:function (mode) {
   2595         return (mode & 61440) === 24576;
   2596       },isFIFO:function (mode) {
   2597         return (mode & 61440) === 4096;
   2598       },isSocket:function (mode) {
   2599         return (mode & 49152) === 49152;
   2600       },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) {
   2601         var flags = FS.flagModes[str];
   2602         if (typeof flags === 'undefined') {
   2603           throw new Error('Unknown file open mode: ' + str);
   2604         }
   2605         return flags;
   2606       },flagsToPermissionString:function (flag) {
   2607         var accmode = flag & 2097155;
   2608         var perms = ['r', 'w', 'rw'][accmode];
   2609         if ((flag & 512)) {
   2610           perms += 'w';
   2611         }
   2612         return perms;
   2613       },nodePermissions:function (node, perms) {
   2614         if (FS.ignorePermissions) {
   2615           return 0;
   2616         }
   2617         // return 0 if any user, group or owner bits are set.
   2618         if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
   2619           return ERRNO_CODES.EACCES;
   2620         } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
   2621           return ERRNO_CODES.EACCES;
   2622         } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
   2623           return ERRNO_CODES.EACCES;
   2624         }
   2625         return 0;
   2626       },mayLookup:function (dir) {
   2627         return FS.nodePermissions(dir, 'x');
   2628       },mayCreate:function (dir, name) {
   2629         try {
   2630           var node = FS.lookupNode(dir, name);
   2631           return ERRNO_CODES.EEXIST;
   2632         } catch (e) {
   2633         }
   2634         return FS.nodePermissions(dir, 'wx');
   2635       },mayDelete:function (dir, name, isdir) {
   2636         var node;
   2637         try {
   2638           node = FS.lookupNode(dir, name);
   2639         } catch (e) {
   2640           return e.errno;
   2641         }
   2642         var err = FS.nodePermissions(dir, 'wx');
   2643         if (err) {
   2644           return err;
   2645         }
   2646         if (isdir) {
   2647           if (!FS.isDir(node.mode)) {
   2648             return ERRNO_CODES.ENOTDIR;
   2649           }
   2650           if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
   2651             return ERRNO_CODES.EBUSY;
   2652           }
   2653         } else {
   2654           if (FS.isDir(node.mode)) {
   2655             return ERRNO_CODES.EISDIR;
   2656           }
   2657         }
   2658         return 0;
   2659       },mayOpen:function (node, flags) {
   2660         if (!node) {
   2661           return ERRNO_CODES.ENOENT;
   2662         }
   2663         if (FS.isLink(node.mode)) {
   2664           return ERRNO_CODES.ELOOP;
   2665         } else if (FS.isDir(node.mode)) {
   2666           if ((flags & 2097155) !== 0 ||  // opening for write
   2667               (flags & 512)) {
   2668             return ERRNO_CODES.EISDIR;
   2669           }
   2670         }
   2671         return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
   2672       },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
   2673         fd_start = fd_start || 0;
   2674         fd_end = fd_end || FS.MAX_OPEN_FDS;
   2675         for (var fd = fd_start; fd <= fd_end; fd++) {
   2676           if (!FS.streams[fd]) {
   2677             return fd;
   2678           }
   2679         }
   2680         throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
   2681       },getStream:function (fd) {
   2682         return FS.streams[fd];
   2683       },createStream:function (stream, fd_start, fd_end) {
   2684         if (!FS.FSStream) {
   2685           FS.FSStream = function(){};
   2686           FS.FSStream.prototype = {};
   2687           // compatibility
   2688           Object.defineProperties(FS.FSStream.prototype, {
   2689             object: {
   2690               get: function() { return this.node; },
   2691               set: function(val) { this.node = val; }
   2692             },
   2693             isRead: {
   2694               get: function() { return (this.flags & 2097155) !== 1; }
   2695             },
   2696             isWrite: {
   2697               get: function() { return (this.flags & 2097155) !== 0; }
   2698             },
   2699             isAppend: {
   2700               get: function() { return (this.flags & 1024); }
   2701             }
   2702           });
   2703         }
   2704         if (0) {
   2705           // reuse the object
   2706           stream.__proto__ = FS.FSStream.prototype;
   2707         } else {
   2708           var newStream = new FS.FSStream();
   2709           for (var p in stream) {
   2710             newStream[p] = stream[p];
   2711           }
   2712           stream = newStream;
   2713         }
   2714         var fd = FS.nextfd(fd_start, fd_end);
   2715         stream.fd = fd;
   2716         FS.streams[fd] = stream;
   2717         return stream;
   2718       },closeStream:function (fd) {
   2719         FS.streams[fd] = null;
   2720       },getStreamFromPtr:function (ptr) {
   2721         return FS.streams[ptr - 1];
   2722       },getPtrForStream:function (stream) {
   2723         return stream ? stream.fd + 1 : 0;
   2724       },chrdev_stream_ops:{open:function (stream) {
   2725           var device = FS.getDevice(stream.node.rdev);
   2726           // override node's stream ops with the device's
   2727           stream.stream_ops = device.stream_ops;
   2728           // forward the open call
   2729           if (stream.stream_ops.open) {
   2730             stream.stream_ops.open(stream);
   2731           }
   2732         },llseek:function () {
   2733           throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
   2734         }},major:function (dev) {
   2735         return ((dev) >> 8);
   2736       },minor:function (dev) {
   2737         return ((dev) & 0xff);
   2738       },makedev:function (ma, mi) {
   2739         return ((ma) << 8 | (mi));
   2740       },registerDevice:function (dev, ops) {
   2741         FS.devices[dev] = { stream_ops: ops };
   2742       },getDevice:function (dev) {
   2743         return FS.devices[dev];
   2744       },getMounts:function (mount) {
   2745         var mounts = [];
   2746         var check = [mount];
   2747 
   2748         while (check.length) {
   2749           var m = check.pop();
   2750 
   2751           mounts.push(m);
   2752 
   2753           check.push.apply(check, m.mounts);
   2754         }
   2755 
   2756         return mounts;
   2757       },syncfs:function (populate, callback) {
   2758         if (typeof(populate) === 'function') {
   2759           callback = populate;
   2760           populate = false;
   2761         }
   2762 
   2763         var mounts = FS.getMounts(FS.root.mount);
   2764         var completed = 0;
   2765 
   2766         function done(err) {
   2767           if (err) {
   2768             if (!done.errored) {
   2769               done.errored = true;
   2770               return callback(err);
   2771             }
   2772             return;
   2773           }
   2774           if (++completed >= mounts.length) {
   2775             callback(null);
   2776           }
   2777         };
   2778 
   2779         // sync all mounts
   2780         mounts.forEach(function (mount) {
   2781           if (!mount.type.syncfs) {
   2782             return done(null);
   2783           }
   2784           mount.type.syncfs(mount, populate, done);
   2785         });
   2786       },mount:function (type, opts, mountpoint) {
   2787         var root = mountpoint === '/';
   2788         var pseudo = !mountpoint;
   2789         var node;
   2790 
   2791         if (root && FS.root) {
   2792           throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
   2793         } else if (!root && !pseudo) {
   2794           var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
   2795 
   2796           mountpoint = lookup.path;  // use the absolute path
   2797           node = lookup.node;
   2798 
   2799           if (FS.isMountpoint(node)) {
   2800             throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
   2801           }
   2802 
   2803           if (!FS.isDir(node.mode)) {
   2804             throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
   2805           }
   2806         }
   2807 
   2808         var mount = {
   2809           type: type,
   2810           opts: opts,
   2811           mountpoint: mountpoint,
   2812           mounts: []
   2813         };
   2814 
   2815         // create a root node for the fs
   2816         var mountRoot = type.mount(mount);
   2817         mountRoot.mount = mount;
   2818         mount.root = mountRoot;
   2819 
   2820         if (root) {
   2821           FS.root = mountRoot;
   2822         } else if (node) {
   2823           // set as a mountpoint
   2824           node.mounted = mount;
   2825 
   2826           // add the new mount to the current mount's children
   2827           if (node.mount) {
   2828             node.mount.mounts.push(mount);
   2829           }
   2830         }
   2831 
   2832         return mountRoot;
   2833       },unmount:function (mountpoint) {
   2834         var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
   2835 
   2836         if (!FS.isMountpoint(lookup.node)) {
   2837           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   2838         }
   2839 
   2840         // destroy the nodes for this mount, and all its child mounts
   2841         var node = lookup.node;
   2842         var mount = node.mounted;
   2843         var mounts = FS.getMounts(mount);
   2844 
   2845         Object.keys(FS.nameTable).forEach(function (hash) {
   2846           var current = FS.nameTable[hash];
   2847 
   2848           while (current) {
   2849             var next = current.name_next;
   2850 
   2851             if (mounts.indexOf(current.mount) !== -1) {
   2852               FS.destroyNode(current);
   2853             }
   2854 
   2855             current = next;
   2856           }
   2857         });
   2858 
   2859         // no longer a mountpoint
   2860         node.mounted = null;
   2861 
   2862         // remove this mount from the child mounts
   2863         var idx = node.mount.mounts.indexOf(mount);
   2864         assert(idx !== -1);
   2865         node.mount.mounts.splice(idx, 1);
   2866       },lookup:function (parent, name) {
   2867         return parent.node_ops.lookup(parent, name);
   2868       },mknod:function (path, mode, dev) {
   2869         var lookup = FS.lookupPath(path, { parent: true });
   2870         var parent = lookup.node;
   2871         var name = PATH.basename(path);
   2872         var err = FS.mayCreate(parent, name);
   2873         if (err) {
   2874           throw new FS.ErrnoError(err);
   2875         }
   2876         if (!parent.node_ops.mknod) {
   2877           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   2878         }
   2879         return parent.node_ops.mknod(parent, name, mode, dev);
   2880       },create:function (path, mode) {
   2881         mode = mode !== undefined ? mode : 438 /* 0666 */;
   2882         mode &= 4095;
   2883         mode |= 32768;
   2884         return FS.mknod(path, mode, 0);
   2885       },mkdir:function (path, mode) {
   2886         mode = mode !== undefined ? mode : 511 /* 0777 */;
   2887         mode &= 511 | 512;
   2888         mode |= 16384;
   2889         return FS.mknod(path, mode, 0);
   2890       },mkdev:function (path, mode, dev) {
   2891         if (typeof(dev) === 'undefined') {
   2892           dev = mode;
   2893           mode = 438 /* 0666 */;
   2894         }
   2895         mode |= 8192;
   2896         return FS.mknod(path, mode, dev);
   2897       },symlink:function (oldpath, newpath) {
   2898         var lookup = FS.lookupPath(newpath, { parent: true });
   2899         var parent = lookup.node;
   2900         var newname = PATH.basename(newpath);
   2901         var err = FS.mayCreate(parent, newname);
   2902         if (err) {
   2903           throw new FS.ErrnoError(err);
   2904         }
   2905         if (!parent.node_ops.symlink) {
   2906           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   2907         }
   2908         return parent.node_ops.symlink(parent, newname, oldpath);
   2909       },rename:function (old_path, new_path) {
   2910         var old_dirname = PATH.dirname(old_path);
   2911         var new_dirname = PATH.dirname(new_path);
   2912         var old_name = PATH.basename(old_path);
   2913         var new_name = PATH.basename(new_path);
   2914         // parents must exist
   2915         var lookup, old_dir, new_dir;
   2916         try {
   2917           lookup = FS.lookupPath(old_path, { parent: true });
   2918           old_dir = lookup.node;
   2919           lookup = FS.lookupPath(new_path, { parent: true });
   2920           new_dir = lookup.node;
   2921         } catch (e) {
   2922           throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
   2923         }
   2924         // need to be part of the same mount
   2925         if (old_dir.mount !== new_dir.mount) {
   2926           throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
   2927         }
   2928         // source must exist
   2929         var old_node = FS.lookupNode(old_dir, old_name);
   2930         // old path should not be an ancestor of the new path
   2931         var relative = PATH.relative(old_path, new_dirname);
   2932         if (relative.charAt(0) !== '.') {
   2933           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   2934         }
   2935         // new path should not be an ancestor of the old path
   2936         relative = PATH.relative(new_path, old_dirname);
   2937         if (relative.charAt(0) !== '.') {
   2938           throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
   2939         }
   2940         // see if the new path already exists
   2941         var new_node;
   2942         try {
   2943           new_node = FS.lookupNode(new_dir, new_name);
   2944         } catch (e) {
   2945           // not fatal
   2946         }
   2947         // early out if nothing needs to change
   2948         if (old_node === new_node) {
   2949           return;
   2950         }
   2951         // we'll need to delete the old entry
   2952         var isdir = FS.isDir(old_node.mode);
   2953         var err = FS.mayDelete(old_dir, old_name, isdir);
   2954         if (err) {
   2955           throw new FS.ErrnoError(err);
   2956         }
   2957         // need delete permissions if we'll be overwriting.
   2958         // need create permissions if new doesn't already exist.
   2959         err = new_node ?
   2960           FS.mayDelete(new_dir, new_name, isdir) :
   2961           FS.mayCreate(new_dir, new_name);
   2962         if (err) {
   2963           throw new FS.ErrnoError(err);
   2964         }
   2965         if (!old_dir.node_ops.rename) {
   2966           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   2967         }
   2968         if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
   2969           throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
   2970         }
   2971         // if we are going to change the parent, check write permissions
   2972         if (new_dir !== old_dir) {
   2973           err = FS.nodePermissions(old_dir, 'w');
   2974           if (err) {
   2975             throw new FS.ErrnoError(err);
   2976           }
   2977         }
   2978         // remove the node from the lookup hash
   2979         FS.hashRemoveNode(old_node);
   2980         // do the underlying fs rename
   2981         try {
   2982           old_dir.node_ops.rename(old_node, new_dir, new_name);
   2983         } catch (e) {
   2984           throw e;
   2985         } finally {
   2986           // add the node back to the hash (in case node_ops.rename
   2987           // changed its name)
   2988           FS.hashAddNode(old_node);
   2989         }
   2990       },rmdir:function (path) {
   2991         var lookup = FS.lookupPath(path, { parent: true });
   2992         var parent = lookup.node;
   2993         var name = PATH.basename(path);
   2994         var node = FS.lookupNode(parent, name);
   2995         var err = FS.mayDelete(parent, name, true);
   2996         if (err) {
   2997           throw new FS.ErrnoError(err);
   2998         }
   2999         if (!parent.node_ops.rmdir) {
   3000           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   3001         }
   3002         if (FS.isMountpoint(node)) {
   3003           throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
   3004         }
   3005         parent.node_ops.rmdir(parent, name);
   3006         FS.destroyNode(node);
   3007       },readdir:function (path) {
   3008         var lookup = FS.lookupPath(path, { follow: true });
   3009         var node = lookup.node;
   3010         if (!node.node_ops.readdir) {
   3011           throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
   3012         }
   3013         return node.node_ops.readdir(node);
   3014       },unlink:function (path) {
   3015         var lookup = FS.lookupPath(path, { parent: true });
   3016         var parent = lookup.node;
   3017         var name = PATH.basename(path);
   3018         var node = FS.lookupNode(parent, name);
   3019         var err = FS.mayDelete(parent, name, false);
   3020         if (err) {
   3021           // POSIX says unlink should set EPERM, not EISDIR
   3022           if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
   3023           throw new FS.ErrnoError(err);
   3024         }
   3025         if (!parent.node_ops.unlink) {
   3026           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   3027         }
   3028         if (FS.isMountpoint(node)) {
   3029           throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
   3030         }
   3031         parent.node_ops.unlink(parent, name);
   3032         FS.destroyNode(node);
   3033       },readlink:function (path) {
   3034         var lookup = FS.lookupPath(path);
   3035         var link = lookup.node;
   3036         if (!link.node_ops.readlink) {
   3037           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3038         }
   3039         return link.node_ops.readlink(link);
   3040       },stat:function (path, dontFollow) {
   3041         var lookup = FS.lookupPath(path, { follow: !dontFollow });
   3042         var node = lookup.node;
   3043         if (!node.node_ops.getattr) {
   3044           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   3045         }
   3046         return node.node_ops.getattr(node);
   3047       },lstat:function (path) {
   3048         return FS.stat(path, true);
   3049       },chmod:function (path, mode, dontFollow) {
   3050         var node;
   3051         if (typeof path === 'string') {
   3052           var lookup = FS.lookupPath(path, { follow: !dontFollow });
   3053           node = lookup.node;
   3054         } else {
   3055           node = path;
   3056         }
   3057         if (!node.node_ops.setattr) {
   3058           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   3059         }
   3060         node.node_ops.setattr(node, {
   3061           mode: (mode & 4095) | (node.mode & ~4095),
   3062           timestamp: Date.now()
   3063         });
   3064       },lchmod:function (path, mode) {
   3065         FS.chmod(path, mode, true);
   3066       },fchmod:function (fd, mode) {
   3067         var stream = FS.getStream(fd);
   3068         if (!stream) {
   3069           throw new FS.ErrnoError(ERRNO_CODES.EBADF);
   3070         }
   3071         FS.chmod(stream.node, mode);
   3072       },chown:function (path, uid, gid, dontFollow) {
   3073         var node;
   3074         if (typeof path === 'string') {
   3075           var lookup = FS.lookupPath(path, { follow: !dontFollow });
   3076           node = lookup.node;
   3077         } else {
   3078           node = path;
   3079         }
   3080         if (!node.node_ops.setattr) {
   3081           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   3082         }
   3083         node.node_ops.setattr(node, {
   3084           timestamp: Date.now()
   3085           // we ignore the uid / gid for now
   3086         });
   3087       },lchown:function (path, uid, gid) {
   3088         FS.chown(path, uid, gid, true);
   3089       },fchown:function (fd, uid, gid) {
   3090         var stream = FS.getStream(fd);
   3091         if (!stream) {
   3092           throw new FS.ErrnoError(ERRNO_CODES.EBADF);
   3093         }
   3094         FS.chown(stream.node, uid, gid);
   3095       },truncate:function (path, len) {
   3096         if (len < 0) {
   3097           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3098         }
   3099         var node;
   3100         if (typeof path === 'string') {
   3101           var lookup = FS.lookupPath(path, { follow: true });
   3102           node = lookup.node;
   3103         } else {
   3104           node = path;
   3105         }
   3106         if (!node.node_ops.setattr) {
   3107           throw new FS.ErrnoError(ERRNO_CODES.EPERM);
   3108         }
   3109         if (FS.isDir(node.mode)) {
   3110           throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
   3111         }
   3112         if (!FS.isFile(node.mode)) {
   3113           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3114         }
   3115         var err = FS.nodePermissions(node, 'w');
   3116         if (err) {
   3117           throw new FS.ErrnoError(err);
   3118         }
   3119         node.node_ops.setattr(node, {
   3120           size: len,
   3121           timestamp: Date.now()
   3122         });
   3123       },ftruncate:function (fd, len) {
   3124         var stream = FS.getStream(fd);
   3125         if (!stream) {
   3126           throw new FS.ErrnoError(ERRNO_CODES.EBADF);
   3127         }
   3128         if ((stream.flags & 2097155) === 0) {
   3129           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3130         }
   3131         FS.truncate(stream.node, len);
   3132       },utime:function (path, atime, mtime) {
   3133         var lookup = FS.lookupPath(path, { follow: true });
   3134         var node = lookup.node;
   3135         node.node_ops.setattr(node, {
   3136           timestamp: Math.max(atime, mtime)
   3137         });
   3138       },open:function (path, flags, mode, fd_start, fd_end) {
   3139         flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
   3140         mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
   3141         if ((flags & 64)) {
   3142           mode = (mode & 4095) | 32768;
   3143         } else {
   3144           mode = 0;
   3145         }
   3146         var node;
   3147         if (typeof path === 'object') {
   3148           node = path;
   3149         } else {
   3150           path = PATH.normalize(path);
   3151           try {
   3152             var lookup = FS.lookupPath(path, {
   3153               follow: !(flags & 131072)
   3154             });
   3155             node = lookup.node;
   3156           } catch (e) {
   3157             // ignore
   3158           }
   3159         }
   3160         // perhaps we need to create the node
   3161         if ((flags & 64)) {
   3162           if (node) {
   3163             // if O_CREAT and O_EXCL are set, error out if the node already exists
   3164             if ((flags & 128)) {
   3165               throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
   3166             }
   3167           } else {
   3168             // node doesn't exist, try to create it
   3169             node = FS.mknod(path, mode, 0);
   3170           }
   3171         }
   3172         if (!node) {
   3173           throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
   3174         }
   3175         // can't truncate a device
   3176         if (FS.isChrdev(node.mode)) {
   3177           flags &= ~512;
   3178         }
   3179         // check permissions
   3180         var err = FS.mayOpen(node, flags);
   3181         if (err) {
   3182           throw new FS.ErrnoError(err);
   3183         }
   3184         // do truncation if necessary
   3185         if ((flags & 512)) {
   3186           FS.truncate(node, 0);
   3187         }
   3188         // we've already handled these, don't pass down to the underlying vfs
   3189         flags &= ~(128 | 512);
   3190 
   3191         // register the stream with the filesystem
   3192         var stream = FS.createStream({
   3193           node: node,
   3194           path: FS.getPath(node),  // we want the absolute path to the node
   3195           flags: flags,
   3196           seekable: true,
   3197           position: 0,
   3198           stream_ops: node.stream_ops,
   3199           // used by the file family libc calls (fopen, fwrite, ferror, etc.)
   3200           ungotten: [],
   3201           error: false
   3202         }, fd_start, fd_end);
   3203         // call the new stream's open function
   3204         if (stream.stream_ops.open) {
   3205           stream.stream_ops.open(stream);
   3206         }
   3207         if (Module['logReadFiles'] && !(flags & 1)) {
   3208           if (!FS.readFiles) FS.readFiles = {};
   3209           if (!(path in FS.readFiles)) {
   3210             FS.readFiles[path] = 1;
   3211             Module['printErr']('read file: ' + path);
   3212           }
   3213         }
   3214         return stream;
   3215       },close:function (stream) {
   3216         try {
   3217           if (stream.stream_ops.close) {
   3218             stream.stream_ops.close(stream);
   3219           }
   3220         } catch (e) {
   3221           throw e;
   3222         } finally {
   3223           FS.closeStream(stream.fd);
   3224         }
   3225       },llseek:function (stream, offset, whence) {
   3226         if (!stream.seekable || !stream.stream_ops.llseek) {
   3227           throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
   3228         }
   3229         return stream.stream_ops.llseek(stream, offset, whence);
   3230       },read:function (stream, buffer, offset, length, position) {
   3231         if (length < 0 || position < 0) {
   3232           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3233         }
   3234         if ((stream.flags & 2097155) === 1) {
   3235           throw new FS.ErrnoError(ERRNO_CODES.EBADF);
   3236         }
   3237         if (FS.isDir(stream.node.mode)) {
   3238           throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
   3239         }
   3240         if (!stream.stream_ops.read) {
   3241           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3242         }
   3243         var seeking = true;
   3244         if (typeof position === 'undefined') {
   3245           position = stream.position;
   3246           seeking = false;
   3247         } else if (!stream.seekable) {
   3248           throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
   3249         }
   3250         var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
   3251         if (!seeking) stream.position += bytesRead;
   3252         return bytesRead;
   3253       },write:function (stream, buffer, offset, length, position, canOwn) {
   3254         if (length < 0 || position < 0) {
   3255           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3256         }
   3257         if ((stream.flags & 2097155) === 0) {
   3258           throw new FS.ErrnoError(ERRNO_CODES.EBADF);
   3259         }
   3260         if (FS.isDir(stream.node.mode)) {
   3261           throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
   3262         }
   3263         if (!stream.stream_ops.write) {
   3264           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3265         }
   3266         var seeking = true;
   3267         if (typeof position === 'undefined') {
   3268           position = stream.position;
   3269           seeking = false;
   3270         } else if (!stream.seekable) {
   3271           throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
   3272         }
   3273         if (stream.flags & 1024) {
   3274           // seek to the end before writing in append mode
   3275           FS.llseek(stream, 0, 2);
   3276         }
   3277         var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
   3278         if (!seeking) stream.position += bytesWritten;
   3279         return bytesWritten;
   3280       },allocate:function (stream, offset, length) {
   3281         if (offset < 0 || length <= 0) {
   3282           throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   3283         }
   3284         if ((stream.flags & 2097155) === 0) {
   3285           throw new FS.ErrnoError(ERRNO_CODES.EBADF);
   3286         }
   3287         if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
   3288           throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
   3289         }
   3290         if (!stream.stream_ops.allocate) {
   3291           throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
   3292         }
   3293         stream.stream_ops.allocate(stream, offset, length);
   3294       },mmap:function (stream, buffer, offset, length, position, prot, flags) {
   3295         // TODO if PROT is PROT_WRITE, make sure we have write access
   3296         if ((stream.flags & 2097155) === 1) {
   3297           throw new FS.ErrnoError(ERRNO_CODES.EACCES);
   3298         }
   3299         if (!stream.stream_ops.mmap) {
   3300           throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
   3301         }
   3302         return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
   3303       },ioctl:function (stream, cmd, arg) {
   3304         if (!stream.stream_ops.ioctl) {
   3305           throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
   3306         }
   3307         return stream.stream_ops.ioctl(stream, cmd, arg);
   3308       },readFile:function (path, opts) {
   3309         opts = opts || {};
   3310         opts.flags = opts.flags || 'r';
   3311         opts.encoding = opts.encoding || 'binary';
   3312         if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
   3313           throw new Error('Invalid encoding type "' + opts.encoding + '"');
   3314         }
   3315         var ret;
   3316         var stream = FS.open(path, opts.flags);
   3317         var stat = FS.stat(path);
   3318         var length = stat.size;
   3319         var buf = new Uint8Array(length);
   3320         FS.read(stream, buf, 0, length, 0);
   3321         if (opts.encoding === 'utf8') {
   3322           ret = '';
   3323           var utf8 = new Runtime.UTF8Processor();
   3324           for (var i = 0; i < length; i++) {
   3325             ret += utf8.processCChar(buf[i]);
   3326           }
   3327         } else if (opts.encoding === 'binary') {
   3328           ret = buf;
   3329         }
   3330         FS.close(stream);
   3331         return ret;
   3332       },writeFile:function (path, data, opts) {
   3333         opts = opts || {};
   3334         opts.flags = opts.flags || 'w';
   3335         opts.encoding = opts.encoding || 'utf8';
   3336         if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
   3337           throw new Error('Invalid encoding type "' + opts.encoding + '"');
   3338         }
   3339         var stream = FS.open(path, opts.flags, opts.mode);
   3340         if (opts.encoding === 'utf8') {
   3341           var utf8 = new Runtime.UTF8Processor();
   3342           var buf = new Uint8Array(utf8.processJSString(data));
   3343           FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
   3344         } else if (opts.encoding === 'binary') {
   3345           FS.write(stream, data, 0, data.length, 0, opts.canOwn);
   3346         }
   3347         FS.close(stream);
   3348       },cwd:function () {
   3349         return FS.currentPath;
   3350       },chdir:function (path) {
   3351         var lookup = FS.lookupPath(path, { follow: true });
   3352         if (!FS.isDir(lookup.node.mode)) {
   3353           throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
   3354         }
   3355         var err = FS.nodePermissions(lookup.node, 'x');
   3356         if (err) {
   3357           throw new FS.ErrnoError(err);
   3358         }
   3359         FS.currentPath = lookup.path;
   3360       },createDefaultDirectories:function () {
   3361         FS.mkdir('/tmp');
   3362       },createDefaultDevices:function () {
   3363         // create /dev
   3364         FS.mkdir('/dev');
   3365         // setup /dev/null
   3366         FS.registerDevice(FS.makedev(1, 3), {
   3367           read: function() { return 0; },
   3368           write: function() { return 0; }
   3369         });
   3370         FS.mkdev('/dev/null', FS.makedev(1, 3));
   3371         // setup /dev/tty and /dev/tty1
   3372         // stderr needs to print output using Module['printErr']
   3373         // so we register a second tty just for it.
   3374         TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
   3375         TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
   3376         FS.mkdev('/dev/tty', FS.makedev(5, 0));
   3377         FS.mkdev('/dev/tty1', FS.makedev(6, 0));
   3378         // we're not going to emulate the actual shm device,
   3379         // just create the tmp dirs that reside in it commonly
   3380         FS.mkdir('/dev/shm');
   3381         FS.mkdir('/dev/shm/tmp');
   3382       },createStandardStreams:function () {
   3383         // TODO deprecate the old functionality of a single
   3384         // input / output callback and that utilizes FS.createDevice
   3385         // and instead require a unique set of stream ops
   3386 
   3387         // by default, we symlink the standard streams to the
   3388         // default tty devices. however, if the standard streams
   3389         // have been overwritten we create a unique device for
   3390         // them instead.
   3391         if (Module['stdin']) {
   3392           FS.createDevice('/dev', 'stdin', Module['stdin']);
   3393         } else {
   3394           FS.symlink('/dev/tty', '/dev/stdin');
   3395         }
   3396         if (Module['stdout']) {
   3397           FS.createDevice('/dev', 'stdout', null, Module['stdout']);
   3398         } else {
   3399           FS.symlink('/dev/tty', '/dev/stdout');
   3400         }
   3401         if (Module['stderr']) {
   3402           FS.createDevice('/dev', 'stderr', null, Module['stderr']);
   3403         } else {
   3404           FS.symlink('/dev/tty1', '/dev/stderr');
   3405         }
   3406 
   3407         // open default streams for the stdin, stdout and stderr devices
   3408         var stdin = FS.open('/dev/stdin', 'r');
   3409         HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
   3410         assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
   3411 
   3412         var stdout = FS.open('/dev/stdout', 'w');
   3413         HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
   3414         assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
   3415 
   3416         var stderr = FS.open('/dev/stderr', 'w');
   3417         HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
   3418         assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
   3419       },ensureErrnoError:function () {
   3420         if (FS.ErrnoError) return;
   3421         FS.ErrnoError = function ErrnoError(errno) {
   3422           this.errno = errno;
   3423           for (var key in ERRNO_CODES) {
   3424             if (ERRNO_CODES[key] === errno) {
   3425               this.code = key;
   3426               break;
   3427             }
   3428           }
   3429           this.message = ERRNO_MESSAGES[errno];
   3430         };
   3431         FS.ErrnoError.prototype = new Error();
   3432         FS.ErrnoError.prototype.constructor = FS.ErrnoError;
   3433         // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
   3434         [ERRNO_CODES.ENOENT].forEach(function(code) {
   3435           FS.genericErrors[code] = new FS.ErrnoError(code);
   3436           FS.genericErrors[code].stack = '<generic error, no stack>';
   3437         });
   3438       },staticInit:function () {
   3439         FS.ensureErrnoError();
   3440 
   3441         FS.nameTable = new Array(4096);
   3442 
   3443         FS.mount(MEMFS, {}, '/');
   3444 
   3445         FS.createDefaultDirectories();
   3446         FS.createDefaultDevices();
   3447       },init:function (input, output, error) {
   3448         assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
   3449         FS.init.initialized = true;
   3450 
   3451         FS.ensureErrnoError();
   3452 
   3453         // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
   3454         Module['stdin'] = input || Module['stdin'];
   3455         Module['stdout'] = output || Module['stdout'];
   3456         Module['stderr'] = error || Module['stderr'];
   3457 
   3458         FS.createStandardStreams();
   3459       },quit:function () {
   3460         FS.init.initialized = false;
   3461         for (var i = 0; i < FS.streams.length; i++) {
   3462           var stream = FS.streams[i];
   3463           if (!stream) {
   3464             continue;
   3465           }
   3466           FS.close(stream);
   3467         }
   3468       },getMode:function (canRead, canWrite) {
   3469         var mode = 0;
   3470         if (canRead) mode |= 292 | 73;
   3471         if (canWrite) mode |= 146;
   3472         return mode;
   3473       },joinPath:function (parts, forceRelative) {
   3474         var path = PATH.join.apply(null, parts);
   3475         if (forceRelative && path[0] == '/') path = path.substr(1);
   3476         return path;
   3477       },absolutePath:function (relative, base) {
   3478         return PATH.resolve(base, relative);
   3479       },standardizePath:function (path) {
   3480         return PATH.normalize(path);
   3481       },findObject:function (path, dontResolveLastLink) {
   3482         var ret = FS.analyzePath(path, dontResolveLastLink);
   3483         if (ret.exists) {
   3484           return ret.object;
   3485         } else {
   3486           ___setErrNo(ret.error);
   3487           return null;
   3488         }
   3489       },analyzePath:function (path, dontResolveLastLink) {
   3490         // operate from within the context of the symlink's target
   3491         try {
   3492           var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
   3493           path = lookup.path;
   3494         } catch (e) {
   3495         }
   3496         var ret = {
   3497           isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
   3498           parentExists: false, parentPath: null, parentObject: null
   3499         };
   3500         try {
   3501           var lookup = FS.lookupPath(path, { parent: true });
   3502           ret.parentExists = true;
   3503           ret.parentPath = lookup.path;
   3504           ret.parentObject = lookup.node;
   3505           ret.name = PATH.basename(path);
   3506           lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
   3507           ret.exists = true;
   3508           ret.path = lookup.path;
   3509           ret.object = lookup.node;
   3510           ret.name = lookup.node.name;
   3511           ret.isRoot = lookup.path === '/';
   3512         } catch (e) {
   3513           ret.error = e.errno;
   3514         };
   3515         return ret;
   3516       },createFolder:function (parent, name, canRead, canWrite) {
   3517         var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
   3518         var mode = FS.getMode(canRead, canWrite);
   3519         return FS.mkdir(path, mode);
   3520       },createPath:function (parent, path, canRead, canWrite) {
   3521         parent = typeof parent === 'string' ? parent : FS.getPath(parent);
   3522         var parts = path.split('/').reverse();
   3523         while (parts.length) {
   3524           var part = parts.pop();
   3525           if (!part) continue;
   3526           var current = PATH.join2(parent, part);
   3527           try {
   3528             FS.mkdir(current);
   3529           } catch (e) {
   3530             // ignore EEXIST
   3531           }
   3532           parent = current;
   3533         }
   3534         return current;
   3535       },createFile:function (parent, name, properties, canRead, canWrite) {
   3536         var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
   3537         var mode = FS.getMode(canRead, canWrite);
   3538         return FS.create(path, mode);
   3539       },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
   3540         var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
   3541         var mode = FS.getMode(canRead, canWrite);
   3542         var node = FS.create(path, mode);
   3543         if (data) {
   3544           if (typeof data === 'string') {
   3545             var arr = new Array(data.length);
   3546             for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
   3547             data = arr;
   3548           }
   3549           // make sure we can write to the file
   3550           FS.chmod(node, mode | 146);
   3551           var stream = FS.open(node, 'w');
   3552           FS.write(stream, data, 0, data.length, 0, canOwn);
   3553           FS.close(stream);
   3554           FS.chmod(node, mode);
   3555         }
   3556         return node;
   3557       },createDevice:function (parent, name, input, output) {
   3558         var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
   3559         var mode = FS.getMode(!!input, !!output);
   3560         if (!FS.createDevice.major) FS.createDevice.major = 64;
   3561         var dev = FS.makedev(FS.createDevice.major++, 0);
   3562         // Create a fake device that a set of stream ops to emulate
   3563         // the old behavior.
   3564         FS.registerDevice(dev, {
   3565           open: function(stream) {
   3566             stream.seekable = false;
   3567           },
   3568           close: function(stream) {
   3569             // flush any pending line data
   3570             if (output && output.buffer && output.buffer.length) {
   3571               output(10);
   3572             }
   3573           },
   3574           read: function(stream, buffer, offset, length, pos /* ignored */) {
   3575             var bytesRead = 0;
   3576             for (var i = 0; i < length; i++) {
   3577               var result;
   3578               try {
   3579                 result = input();
   3580               } catch (e) {
   3581                 throw new FS.ErrnoError(ERRNO_CODES.EIO);
   3582               }
   3583               if (result === undefined && bytesRead === 0) {
   3584                 throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
   3585               }
   3586               if (result === null || result === undefined) break;
   3587               bytesRead++;
   3588               buffer[offset+i] = result;
   3589             }
   3590             if (bytesRead) {
   3591               stream.node.timestamp = Date.now();
   3592             }
   3593             return bytesRead;
   3594           },
   3595           write: function(stream, buffer, offset, length, pos) {
   3596             for (var i = 0; i < length; i++) {
   3597               try {
   3598                 output(buffer[offset+i]);
   3599               } catch (e) {
   3600                 throw new FS.ErrnoError(ERRNO_CODES.EIO);
   3601               }
   3602             }
   3603             if (length) {
   3604               stream.node.timestamp = Date.now();
   3605             }
   3606             return i;
   3607           }
   3608         });
   3609         return FS.mkdev(path, mode, dev);
   3610       },createLink:function (parent, name, target, canRead, canWrite) {
   3611         var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
   3612         return FS.symlink(target, path);
   3613       },forceLoadFile:function (obj) {
   3614         if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
   3615         var success = true;
   3616         if (typeof XMLHttpRequest !== 'undefined') {
   3617           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.");
   3618         } else if (Module['read']) {
   3619           // Command-line.
   3620           try {
   3621             // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
   3622             //          read() will try to parse UTF8.
   3623             obj.contents = intArrayFromString(Module['read'](obj.url), true);
   3624           } catch (e) {
   3625             success = false;
   3626           }
   3627         } else {
   3628           throw new Error('Cannot load without read() or XMLHttpRequest.');
   3629         }
   3630         if (!success) ___setErrNo(ERRNO_CODES.EIO);
   3631         return success;
   3632       },createLazyFile:function (parent, name, url, canRead, canWrite) {
   3633         // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
   3634         function LazyUint8Array() {
   3635           this.lengthKnown = false;
   3636           this.chunks = []; // Loaded chunks. Index is the chunk number
   3637         }
   3638         LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
   3639           if (idx > this.length-1 || idx < 0) {
   3640             return undefined;
   3641           }
   3642           var chunkOffset = idx % this.chunkSize;
   3643           var chunkNum = Math.floor(idx / this.chunkSize);
   3644           return this.getter(chunkNum)[chunkOffset];
   3645         }
   3646         LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
   3647           this.getter = getter;
   3648         }
   3649         LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
   3650             // Find length
   3651             var xhr = new XMLHttpRequest();
   3652             xhr.open('HEAD', url, false);
   3653             xhr.send(null);
   3654             if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
   3655             var datalength = Number(xhr.getResponseHeader("Content-length"));
   3656             var header;
   3657             var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
   3658             var chunkSize = 1024*1024; // Chunk size in bytes
   3659 
   3660             if (!hasByteServing) chunkSize = datalength;
   3661 
   3662             // Function to get a range from the remote URL.
   3663             var doXHR = (function(from, to) {
   3664               if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
   3665               if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
   3666 
   3667               // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
   3668               var xhr = new XMLHttpRequest();
   3669               xhr.open('GET', url, false);
   3670               if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
   3671 
   3672               // Some hints to the browser that we want binary data.
   3673               if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
   3674               if (xhr.overrideMimeType) {
   3675                 xhr.overrideMimeType('text/plain; charset=x-user-defined');
   3676               }
   3677 
   3678               xhr.send(null);
   3679               if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
   3680               if (xhr.response !== undefined) {
   3681                 return new Uint8Array(xhr.response || []);
   3682               } else {
   3683                 return intArrayFromString(xhr.responseText || '', true);
   3684               }
   3685             });
   3686             var lazyArray = this;
   3687             lazyArray.setDataGetter(function(chunkNum) {
   3688               var start = chunkNum * chunkSize;
   3689               var end = (chunkNum+1) * chunkSize - 1; // including this byte
   3690               end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
   3691               if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
   3692                 lazyArray.chunks[chunkNum] = doXHR(start, end);
   3693               }
   3694               if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
   3695               return lazyArray.chunks[chunkNum];
   3696             });
   3697 
   3698             this._length = datalength;
   3699             this._chunkSize = chunkSize;
   3700             this.lengthKnown = true;
   3701         }
   3702         if (typeof XMLHttpRequest !== 'undefined') {
   3703           if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
   3704           var lazyArray = new LazyUint8Array();
   3705           Object.defineProperty(lazyArray, "length", {
   3706               get: function() {
   3707                   if(!this.lengthKnown) {
   3708                       this.cacheLength();
   3709                   }
   3710                   return this._length;
   3711               }
   3712           });
   3713           Object.defineProperty(lazyArray, "chunkSize", {
   3714               get: function() {
   3715                   if(!this.lengthKnown) {
   3716                       this.cacheLength();
   3717                   }
   3718                   return this._chunkSize;
   3719               }
   3720           });
   3721 
   3722           var properties = { isDevice: false, contents: lazyArray };
   3723         } else {
   3724           var properties = { isDevice: false, url: url };
   3725         }
   3726 
   3727         var node = FS.createFile(parent, name, properties, canRead, canWrite);
   3728         // This is a total hack, but I want to get this lazy file code out of the
   3729         // core of MEMFS. If we want to keep this lazy file concept I feel it should
   3730         // be its own thin LAZYFS proxying calls to MEMFS.
   3731         if (properties.contents) {
   3732           node.contents = properties.contents;
   3733         } else if (properties.url) {
   3734           node.contents = null;
   3735           node.url = properties.url;
   3736         }
   3737         // override each stream op with one that tries to force load the lazy file first
   3738         var stream_ops = {};
   3739         var keys = Object.keys(node.stream_ops);
   3740         keys.forEach(function(key) {
   3741           var fn = node.stream_ops[key];
   3742           stream_ops[key] = function forceLoadLazyFile() {
   3743             if (!FS.forceLoadFile(node)) {
   3744               throw new FS.ErrnoError(ERRNO_CODES.EIO);
   3745             }
   3746             return fn.apply(null, arguments);
   3747           };
   3748         });
   3749         // use a custom read function
   3750         stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
   3751           if (!FS.forceLoadFile(node)) {
   3752             throw new FS.ErrnoError(ERRNO_CODES.EIO);
   3753           }
   3754           var contents = stream.node.contents;
   3755           if (position >= contents.length)
   3756             return 0;
   3757           var size = Math.min(contents.length - position, length);
   3758           assert(size >= 0);
   3759           if (contents.slice) { // normal array
   3760             for (var i = 0; i < size; i++) {
   3761               buffer[offset + i] = contents[position + i];
   3762             }
   3763           } else {
   3764             for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
   3765               buffer[offset + i] = contents.get(position + i);
   3766             }
   3767           }
   3768           return size;
   3769         };
   3770         node.stream_ops = stream_ops;
   3771         return node;
   3772       },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
   3773         Browser.init();
   3774         // TODO we should allow people to just pass in a complete filename instead
   3775         // of parent and name being that we just join them anyways
   3776         var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
   3777         function processData(byteArray) {
   3778           function finish(byteArray) {
   3779             if (!dontCreateFile) {
   3780               FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
   3781             }
   3782             if (onload) onload();
   3783             removeRunDependency('cp ' + fullname);
   3784           }
   3785           var handled = false;
   3786           Module['preloadPlugins'].forEach(function(plugin) {
   3787             if (handled) return;
   3788             if (plugin['canHandle'](fullname)) {
   3789               plugin['handle'](byteArray, fullname, finish, function() {
   3790                 if (onerror) onerror();
   3791                 removeRunDependency('cp ' + fullname);
   3792               });
   3793               handled = true;
   3794             }
   3795           });
   3796           if (!handled) finish(byteArray);
   3797         }
   3798         addRunDependency('cp ' + fullname);
   3799         if (typeof url == 'string') {
   3800           Browser.asyncLoad(url, function(byteArray) {
   3801             processData(byteArray);
   3802           }, onerror);
   3803         } else {
   3804           processData(url);
   3805         }
   3806       },indexedDB:function () {
   3807         return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
   3808       },DB_NAME:function () {
   3809         return 'EM_FS_' + window.location.pathname;
   3810       },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
   3811         onload = onload || function(){};
   3812         onerror = onerror || function(){};
   3813         var indexedDB = FS.indexedDB();
   3814         try {
   3815           var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
   3816         } catch (e) {
   3817           return onerror(e);
   3818         }
   3819         openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
   3820           console.log('creating db');
   3821           var db = openRequest.result;
   3822           db.createObjectStore(FS.DB_STORE_NAME);
   3823         };
   3824         openRequest.onsuccess = function openRequest_onsuccess() {
   3825           var db = openRequest.result;
   3826           var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
   3827           var files = transaction.objectStore(FS.DB_STORE_NAME);
   3828           var ok = 0, fail = 0, total = paths.length;
   3829           function finish() {
   3830             if (fail == 0) onload(); else onerror();
   3831           }
   3832           paths.forEach(function(path) {
   3833             var putRequest = files.put(FS.analyzePath(path).object.contents, path);
   3834             putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
   3835             putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
   3836           });
   3837           transaction.onerror = onerror;
   3838         };
   3839         openRequest.onerror = onerror;
   3840       },loadFilesFromDB:function (paths, onload, onerror) {
   3841         onload = onload || function(){};
   3842         onerror = onerror || function(){};
   3843         var indexedDB = FS.indexedDB();
   3844         try {
   3845           var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
   3846         } catch (e) {
   3847           return onerror(e);
   3848         }
   3849         openRequest.onupgradeneeded = onerror; // no database to load from
   3850         openRequest.onsuccess = function openRequest_onsuccess() {
   3851           var db = openRequest.result;
   3852           try {
   3853             var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
   3854           } catch(e) {
   3855             onerror(e);
   3856             return;
   3857           }
   3858           var files = transaction.objectStore(FS.DB_STORE_NAME);
   3859           var ok = 0, fail = 0, total = paths.length;
   3860           function finish() {
   3861             if (fail == 0) onload(); else onerror();
   3862           }
   3863           paths.forEach(function(path) {
   3864             var getRequest = files.get(path);
   3865             getRequest.onsuccess = function getRequest_onsuccess() {
   3866               if (FS.analyzePath(path).exists) {
   3867                 FS.unlink(path);
   3868               }
   3869               FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
   3870               ok++;
   3871               if (ok + fail == total) finish();
   3872             };
   3873             getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
   3874           });
   3875           transaction.onerror = onerror;
   3876         };
   3877         openRequest.onerror = onerror;
   3878       }};
   3879 
   3880 
   3881 
   3882 
   3883   function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
   3884         return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
   3885       },createSocket:function (family, type, protocol) {
   3886         var streaming = type == 1;
   3887         if (protocol) {
   3888           assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
   3889         }
   3890 
   3891         // create our internal socket structure
   3892         var sock = {
   3893           family: family,
   3894           type: type,
   3895           protocol: protocol,
   3896           server: null,
   3897           peers: {},
   3898           pending: [],
   3899           recv_queue: [],
   3900           sock_ops: SOCKFS.websocket_sock_ops
   3901         };
   3902 
   3903         // create the filesystem node to store the socket structure
   3904         var name = SOCKFS.nextname();
   3905         var node = FS.createNode(SOCKFS.root, name, 49152, 0);
   3906         node.sock = sock;
   3907 
   3908         // and the wrapping stream that enables library functions such
   3909         // as read and write to indirectly interact with the socket
   3910         var stream = FS.createStream({
   3911           path: name,
   3912           node: node,
   3913           flags: FS.modeStringToFlags('r+'),
   3914           seekable: false,
   3915           stream_ops: SOCKFS.stream_ops
   3916         });
   3917 
   3918         // map the new stream to the socket structure (sockets have a 1:1
   3919         // relationship with a stream)
   3920         sock.stream = stream;
   3921 
   3922         return sock;
   3923       },getSocket:function (fd) {
   3924         var stream = FS.getStream(fd);
   3925         if (!stream || !FS.isSocket(stream.node.mode)) {
   3926           return null;
   3927         }
   3928         return stream.node.sock;
   3929       },stream_ops:{poll:function (stream) {
   3930           var sock = stream.node.sock;
   3931           return sock.sock_ops.poll(sock);
   3932         },ioctl:function (stream, request, varargs) {
   3933           var sock = stream.node.sock;
   3934           return sock.sock_ops.ioctl(sock, request, varargs);
   3935         },read:function (stream, buffer, offset, length, position /* ignored */) {
   3936           var sock = stream.node.sock;
   3937           var msg = sock.sock_ops.recvmsg(sock, length);
   3938           if (!msg) {
   3939             // socket is closed
   3940             return 0;
   3941           }
   3942           buffer.set(msg.buffer, offset);
   3943           return msg.buffer.length;
   3944         },write:function (stream, buffer, offset, length, position /* ignored */) {
   3945           var sock = stream.node.sock;
   3946           return sock.sock_ops.sendmsg(sock, buffer, offset, length);
   3947         },close:function (stream) {
   3948           var sock = stream.node.sock;
   3949           sock.sock_ops.close(sock);
   3950         }},nextname:function () {
   3951         if (!SOCKFS.nextname.current) {
   3952           SOCKFS.nextname.current = 0;
   3953         }
   3954         return 'socket[' + (SOCKFS.nextname.current++) + ']';
   3955       },websocket_sock_ops:{createPeer:function (sock, addr, port) {
   3956           var ws;
   3957 
   3958           if (typeof addr === 'object') {
   3959             ws = addr;
   3960             addr = null;
   3961             port = null;
   3962           }
   3963 
   3964           if (ws) {
   3965             // for sockets that've already connected (e.g. we're the server)
   3966             // we can inspect the _socket property for the address
   3967             if (ws._socket) {
   3968               addr = ws._socket.remoteAddress;
   3969               port = ws._socket.remotePort;
   3970             }
   3971             // if we're just now initializing a connection to the remote,
   3972             // inspect the url property
   3973             else {
   3974               var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
   3975               if (!result) {
   3976                 throw new Error('WebSocket URL must be in the format ws(s)://address:port');
   3977               }
   3978               addr = result[1];
   3979               port = parseInt(result[2], 10);
   3980             }
   3981           } else {
   3982             // create the actual websocket object and connect
   3983             try {
   3984               // runtimeConfig gets set to true if WebSocket runtime configuration is available.
   3985               var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
   3986 
   3987               // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
   3988               // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
   3989               var url = 'ws:#'.replace('#', '//');
   3990 
   3991               if (runtimeConfig) {
   3992                 if ('string' === typeof Module['websocket']['url']) {
   3993                   url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
   3994                 }
   3995               }
   3996 
   3997               if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
   3998                 url = url + addr + ':' + port;
   3999               }
   4000 
   4001               // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
   4002               var subProtocols = 'binary'; // The default value is 'binary'
   4003 
   4004               if (runtimeConfig) {
   4005                 if ('string' === typeof Module['websocket']['subprotocol']) {
   4006                   subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
   4007                 }
   4008               }
   4009 
   4010               // The regex trims the string (removes spaces at the beginning and end, then splits the string by
   4011               // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
   4012               subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
   4013 
   4014               // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
   4015               var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
   4016 
   4017               // If node we use the ws library.
   4018               var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
   4019               ws = new WebSocket(url, opts);
   4020               ws.binaryType = 'arraybuffer';
   4021             } catch (e) {
   4022               throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
   4023             }
   4024           }
   4025 
   4026 
   4027           var peer = {
   4028             addr: addr,
   4029             port: port,
   4030             socket: ws,
   4031             dgram_send_queue: []
   4032           };
   4033 
   4034           SOCKFS.websocket_sock_ops.addPeer(sock, peer);
   4035           SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
   4036 
   4037           // if this is a bound dgram socket, send the port number first to allow
   4038           // us to override the ephemeral port reported to us by remotePort on the
   4039           // remote end.
   4040           if (sock.type === 2 && typeof sock.sport !== 'undefined') {
   4041             peer.dgram_send_queue.push(new Uint8Array([
   4042                 255, 255, 255, 255,
   4043                 'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
   4044                 ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
   4045             ]));
   4046           }
   4047 
   4048           return peer;
   4049         },getPeer:function (sock, addr, port) {
   4050           return sock.peers[addr + ':' + port];
   4051         },addPeer:function (sock, peer) {
   4052           sock.peers[peer.addr + ':' + peer.port] = peer;
   4053         },removePeer:function (sock, peer) {
   4054           delete sock.peers[peer.addr + ':' + peer.port];
   4055         },handlePeerEvents:function (sock, peer) {
   4056           var first = true;
   4057 
   4058           var handleOpen = function () {
   4059             try {
   4060               var queued = peer.dgram_send_queue.shift();
   4061               while (queued) {
   4062                 peer.socket.send(queued);
   4063                 queued = peer.dgram_send_queue.shift();
   4064               }
   4065             } catch (e) {
   4066               // not much we can do here in the way of proper error handling as we've already
   4067               // lied and said this data was sent. shut it down.
   4068               peer.socket.close();
   4069             }
   4070           };
   4071 
   4072           function handleMessage(data) {
   4073             assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
   4074             data = new Uint8Array(data);  // make a typed array view on the array buffer
   4075 
   4076 
   4077             // if this is the port message, override the peer's port with it
   4078             var wasfirst = first;
   4079             first = false;
   4080             if (wasfirst &&
   4081                 data.length === 10 &&
   4082                 data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
   4083                 data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
   4084               // update the peer's port and it's key in the peer map
   4085               var newport = ((data[8] << 8) | data[9]);
   4086               SOCKFS.websocket_sock_ops.removePeer(sock, peer);
   4087               peer.port = newport;
   4088               SOCKFS.websocket_sock_ops.addPeer(sock, peer);
   4089               return;
   4090             }
   4091 
   4092             sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
   4093           };
   4094 
   4095           if (ENVIRONMENT_IS_NODE) {
   4096             peer.socket.on('open', handleOpen);
   4097             peer.socket.on('message', function(data, flags) {
   4098               if (!flags.binary) {
   4099                 return;
   4100               }
   4101               handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
   4102             });
   4103             peer.socket.on('error', function() {
   4104               // don't throw
   4105             });
   4106           } else {
   4107             peer.socket.onopen = handleOpen;
   4108             peer.socket.onmessage = function peer_socket_onmessage(event) {
   4109               handleMessage(event.data);
   4110             };
   4111           }
   4112         },poll:function (sock) {
   4113           if (sock.type === 1 && sock.server) {
   4114             // listen sockets should only say they're available for reading
   4115             // if there are pending clients.
   4116             return sock.pending.length ? (64 | 1) : 0;
   4117           }
   4118 
   4119           var mask = 0;
   4120           var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
   4121             SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
   4122             null;
   4123 
   4124           if (sock.recv_queue.length ||
   4125               !dest ||  // connection-less sockets are always ready to read
   4126               (dest && dest.socket.readyState === dest.socket.CLOSING) ||
   4127               (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
   4128             mask |= (64 | 1);
   4129           }
   4130 
   4131           if (!dest ||  // connection-less sockets are always ready to write
   4132               (dest && dest.socket.readyState === dest.socket.OPEN)) {
   4133             mask |= 4;
   4134           }
   4135 
   4136           if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
   4137               (dest && dest.socket.readyState === dest.socket.CLOSED)) {
   4138             mask |= 16;
   4139           }
   4140 
   4141           return mask;
   4142         },ioctl:function (sock, request, arg) {
   4143           switch (request) {
   4144             case 21531:
   4145               var bytes = 0;
   4146               if (sock.recv_queue.length) {
   4147                 bytes = sock.recv_queue[0].data.length;
   4148               }
   4149               HEAP32[((arg)>>2)]=bytes;
   4150               return 0;
   4151             default:
   4152               return ERRNO_CODES.EINVAL;
   4153           }
   4154         },close:function (sock) {
   4155           // if we've spawned a listen server, close it
   4156           if (sock.server) {
   4157             try {
   4158               sock.server.close();
   4159             } catch (e) {
   4160             }
   4161             sock.server = null;
   4162           }
   4163           // close any peer connections
   4164           var peers = Object.keys(sock.peers);
   4165           for (var i = 0; i < peers.length; i++) {
   4166             var peer = sock.peers[peers[i]];
   4167             try {
   4168               peer.socket.close();
   4169             } catch (e) {
   4170             }
   4171             SOCKFS.websocket_sock_ops.removePeer(sock, peer);
   4172           }
   4173           return 0;
   4174         },bind:function (sock, addr, port) {
   4175           if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
   4176             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
   4177           }
   4178           sock.saddr = addr;
   4179           sock.sport = port || _mkport();
   4180           // in order to emulate dgram sockets, we need to launch a listen server when
   4181           // binding on a connection-less socket
   4182           // note: this is only required on the server side
   4183           if (sock.type === 2) {
   4184             // close the existing server if it exists
   4185             if (sock.server) {
   4186               sock.server.close();
   4187               sock.server = null;
   4188             }
   4189             // swallow error operation not supported error that occurs when binding in the
   4190             // browser where this isn't supported
   4191             try {
   4192               sock.sock_ops.listen(sock, 0);
   4193             } catch (e) {
   4194               if (!(e instanceof FS.ErrnoError)) throw e;
   4195               if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
   4196             }
   4197           }
   4198         },connect:function (sock, addr, port) {
   4199           if (sock.server) {
   4200             throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
   4201           }
   4202 
   4203           // TODO autobind
   4204           // if (!sock.addr && sock.type == 2) {
   4205           // }
   4206 
   4207           // early out if we're already connected / in the middle of connecting
   4208           if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
   4209             var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
   4210             if (dest) {
   4211               if (dest.socket.readyState === dest.socket.CONNECTING) {
   4212                 throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
   4213               } else {
   4214                 throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
   4215               }
   4216             }
   4217           }
   4218 
   4219           // add the socket to our peer list and set our
   4220           // destination address / port to match
   4221           var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
   4222           sock.daddr = peer.addr;
   4223           sock.dport = peer.port;
   4224 
   4225           // always "fail" in non-blocking mode
   4226           throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
   4227         },listen:function (sock, backlog) {
   4228           if (!ENVIRONMENT_IS_NODE) {
   4229             throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
   4230           }
   4231           if (sock.server) {
   4232              throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
   4233           }
   4234           var WebSocketServer = require('ws').Server;
   4235           var host = sock.saddr;
   4236           sock.server = new WebSocketServer({
   4237             host: host,
   4238             port: sock.sport
   4239             // TODO support backlog
   4240           });
   4241 
   4242           sock.server.on('connection', function(ws) {
   4243             if (sock.type === 1) {
   4244               var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
   4245 
   4246               // create a peer on the new socket
   4247               var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
   4248               newsock.daddr = peer.addr;
   4249               newsock.dport = peer.port;
   4250 
   4251               // push to queue for accept to pick up
   4252               sock.pending.push(newsock);
   4253             } else {
   4254               // create a peer on the listen socket so calling sendto
   4255               // with the listen socket and an address will resolve
   4256               // to the correct client
   4257               SOCKFS.websocket_sock_ops.createPeer(sock, ws);
   4258             }
   4259           });
   4260           sock.server.on('closed', function() {
   4261             sock.server = null;
   4262           });
   4263           sock.server.on('error', function() {
   4264             // don't throw
   4265           });
   4266         },accept:function (listensock) {
   4267           if (!listensock.server) {
   4268             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   4269           }
   4270           var newsock = listensock.pending.shift();
   4271           newsock.stream.flags = listensock.stream.flags;
   4272           return newsock;
   4273         },getname:function (sock, peer) {
   4274           var addr, port;
   4275           if (peer) {
   4276             if (sock.daddr === undefined || sock.dport === undefined) {
   4277               throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
   4278             }
   4279             addr = sock.daddr;
   4280             port = sock.dport;
   4281           } else {
   4282             // TODO saddr and sport will be set for bind()'d UDP sockets, but what
   4283             // should we be returning for TCP sockets that've been connect()'d?
   4284             addr = sock.saddr || 0;
   4285             port = sock.sport || 0;
   4286           }
   4287           return { addr: addr, port: port };
   4288         },sendmsg:function (sock, buffer, offset, length, addr, port) {
   4289           if (sock.type === 2) {
   4290             // connection-less sockets will honor the message address,
   4291             // and otherwise fall back to the bound destination address
   4292             if (addr === undefined || port === undefined) {
   4293               addr = sock.daddr;
   4294               port = sock.dport;
   4295             }
   4296             // if there was no address to fall back to, error out
   4297             if (addr === undefined || port === undefined) {
   4298               throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
   4299             }
   4300           } else {
   4301             // connection-based sockets will only use the bound
   4302             addr = sock.daddr;
   4303             port = sock.dport;
   4304           }
   4305 
   4306           // find the peer for the destination address
   4307           var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
   4308 
   4309           // early out if not connected with a connection-based socket
   4310           if (sock.type === 1) {
   4311             if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
   4312               throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
   4313             } else if (dest.socket.readyState === dest.socket.CONNECTING) {
   4314               throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
   4315             }
   4316           }
   4317 
   4318           // create a copy of the incoming data to send, as the WebSocket API
   4319           // doesn't work entirely with an ArrayBufferView, it'll just send
   4320           // the entire underlying buffer
   4321           var data;
   4322           if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
   4323             data = buffer.slice(offset, offset + length);
   4324           } else {  // ArrayBufferView
   4325             data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
   4326           }
   4327 
   4328           // if we're emulating a connection-less dgram socket and don't have
   4329           // a cached connection, queue the buffer to send upon connect and
   4330           // lie, saying the data was sent now.
   4331           if (sock.type === 2) {
   4332             if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
   4333               // if we're not connected, open a new connection
   4334               if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
   4335                 dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
   4336               }
   4337               dest.dgram_send_queue.push(data);
   4338               return length;
   4339             }
   4340           }
   4341 
   4342           try {
   4343             // send the actual data
   4344             dest.socket.send(data);
   4345             return length;
   4346           } catch (e) {
   4347             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
   4348           }
   4349         },recvmsg:function (sock, length) {
   4350           // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
   4351           if (sock.type === 1 && sock.server) {
   4352             // tcp servers should not be recv()'ing on the listen socket
   4353             throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
   4354           }
   4355 
   4356           var queued = sock.recv_queue.shift();
   4357           if (!queued) {
   4358             if (sock.type === 1) {
   4359               var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
   4360 
   4361               if (!dest) {
   4362                 // if we have a destination address but are not connected, error out
   4363                 throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
   4364               }
   4365               else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
   4366                 // return null if the socket has closed
   4367                 return null;
   4368               }
   4369               else {
   4370                 // else, our socket is in a valid state but truly has nothing available
   4371                 throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
   4372               }
   4373             } else {
   4374               throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
   4375             }
   4376           }
   4377 
   4378           // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
   4379           // requeued TCP data it'll be an ArrayBufferView
   4380           var queuedLength = queued.data.byteLength || queued.data.length;
   4381           var queuedOffset = queued.data.byteOffset || 0;
   4382           var queuedBuffer = queued.data.buffer || queued.data;
   4383           var bytesRead = Math.min(length, queuedLength);
   4384           var res = {
   4385             buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
   4386             addr: queued.addr,
   4387             port: queued.port
   4388           };
   4389 
   4390 
   4391           // push back any unread data for TCP connections
   4392           if (sock.type === 1 && bytesRead < queuedLength) {
   4393             var bytesRemaining = queuedLength - bytesRead;
   4394             queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
   4395             sock.recv_queue.unshift(queued);
   4396           }
   4397 
   4398           return res;
   4399         }}};function _send(fd, buf, len, flags) {
   4400       var sock = SOCKFS.getSocket(fd);
   4401       if (!sock) {
   4402         ___setErrNo(ERRNO_CODES.EBADF);
   4403         return -1;
   4404       }
   4405       // TODO honor flags
   4406       return _write(fd, buf, len);
   4407     }
   4408 
   4409   function _pwrite(fildes, buf, nbyte, offset) {
   4410       // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
   4411       // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
   4412       var stream = FS.getStream(fildes);
   4413       if (!stream) {
   4414         ___setErrNo(ERRNO_CODES.EBADF);
   4415         return -1;
   4416       }
   4417       try {
   4418         var slab = HEAP8;
   4419         return FS.write(stream, slab, buf, nbyte, offset);
   4420       } catch (e) {
   4421         FS.handleFSError(e);
   4422         return -1;
   4423       }
   4424     }function _write(fildes, buf, nbyte) {
   4425       // ssize_t write(int fildes, const void *buf, size_t nbyte);
   4426       // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
   4427       var stream = FS.getStream(fildes);
   4428       if (!stream) {
   4429         ___setErrNo(ERRNO_CODES.EBADF);
   4430         return -1;
   4431       }
   4432 
   4433 
   4434       try {
   4435         var slab = HEAP8;
   4436         return FS.write(stream, slab, buf, nbyte);
   4437       } catch (e) {
   4438         FS.handleFSError(e);
   4439         return -1;
   4440       }
   4441     }
   4442 
   4443   function _fileno(stream) {
   4444       // int fileno(FILE *stream);
   4445       // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
   4446       stream = FS.getStreamFromPtr(stream);
   4447       if (!stream) return -1;
   4448       return stream.fd;
   4449     }function _fwrite(ptr, size, nitems, stream) {
   4450       // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
   4451       // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
   4452       var bytesToWrite = nitems * size;
   4453       if (bytesToWrite == 0) return 0;
   4454       var fd = _fileno(stream);
   4455       var bytesWritten = _write(fd, ptr, bytesToWrite);
   4456       if (bytesWritten == -1) {
   4457         var streamObj = FS.getStreamFromPtr(stream);
   4458         if (streamObj) streamObj.error = true;
   4459         return 0;
   4460       } else {
   4461         return Math.floor(bytesWritten / size);
   4462       }
   4463     }
   4464 
   4465 
   4466 
   4467   Module["_strlen"] = _strlen;
   4468 
   4469   function __reallyNegative(x) {
   4470       return x < 0 || (x === 0 && (1/x) === -Infinity);
   4471     }function __formatString(format, varargs) {
   4472       var textIndex = format;
   4473       var argIndex = 0;
   4474       function getNextArg(type) {
   4475         // NOTE: Explicitly ignoring type safety. Otherwise this fails:
   4476         //       int x = 4; printf("%c\n", (char)x);
   4477         var ret;
   4478         if (type === 'double') {
   4479           ret = HEAPF64[(((varargs)+(argIndex))>>3)];
   4480         } else if (type == 'i64') {
   4481           ret = [HEAP32[(((varargs)+(argIndex))>>2)],
   4482                  HEAP32[(((varargs)+(argIndex+4))>>2)]];
   4483 
   4484         } else {
   4485           type = 'i32'; // varargs are always i32, i64, or double
   4486           ret = HEAP32[(((varargs)+(argIndex))>>2)];
   4487         }
   4488         argIndex += Runtime.getNativeFieldSize(type);
   4489         return ret;
   4490       }
   4491 
   4492       var ret = [];
   4493       var curr, next, currArg;
   4494       while(1) {
   4495         var startTextIndex = textIndex;
   4496         curr = HEAP8[(textIndex)];
   4497         if (curr === 0) break;
   4498         next = HEAP8[((textIndex+1)|0)];
   4499         if (curr == 37) {
   4500           // Handle flags.
   4501           var flagAlwaysSigned = false;
   4502           var flagLeftAlign = false;
   4503           var flagAlternative = false;
   4504           var flagZeroPad = false;
   4505           var flagPadSign = false;
   4506           flagsLoop: while (1) {
   4507             switch (next) {
   4508               case 43:
   4509                 flagAlwaysSigned = true;
   4510                 break;
   4511               case 45:
   4512                 flagLeftAlign = true;
   4513                 break;
   4514               case 35:
   4515                 flagAlternative = true;
   4516                 break;
   4517               case 48:
   4518                 if (flagZeroPad) {
   4519                   break flagsLoop;
   4520                 } else {
   4521                   flagZeroPad = true;
   4522                   break;
   4523                 }
   4524               case 32:
   4525                 flagPadSign = true;
   4526                 break;
   4527               default:
   4528                 break flagsLoop;
   4529             }
   4530             textIndex++;
   4531             next = HEAP8[((textIndex+1)|0)];
   4532           }
   4533 
   4534           // Handle width.
   4535           var width = 0;
   4536           if (next == 42) {
   4537             width = getNextArg('i32');
   4538             textIndex++;
   4539             next = HEAP8[((textIndex+1)|0)];
   4540           } else {
   4541             while (next >= 48 && next <= 57) {
   4542               width = width * 10 + (next - 48);
   4543               textIndex++;
   4544               next = HEAP8[((textIndex+1)|0)];
   4545             }
   4546           }
   4547 
   4548           // Handle precision.
   4549           var precisionSet = false, precision = -1;
   4550           if (next == 46) {
   4551             precision = 0;
   4552             precisionSet = true;
   4553             textIndex++;
   4554             next = HEAP8[((textIndex+1)|0)];
   4555             if (next == 42) {
   4556               precision = getNextArg('i32');
   4557               textIndex++;
   4558             } else {
   4559               while(1) {
   4560                 var precisionChr = HEAP8[((textIndex+1)|0)];
   4561                 if (precisionChr < 48 ||
   4562                     precisionChr > 57) break;
   4563                 precision = precision * 10 + (precisionChr - 48);
   4564                 textIndex++;
   4565               }
   4566             }
   4567             next = HEAP8[((textIndex+1)|0)];
   4568           }
   4569           if (precision < 0) {
   4570             precision = 6; // Standard default.
   4571             precisionSet = false;
   4572           }
   4573 
   4574           // Handle integer sizes. WARNING: These assume a 32-bit architecture!
   4575           var argSize;
   4576           switch (String.fromCharCode(next)) {
   4577             case 'h':
   4578               var nextNext = HEAP8[((textIndex+2)|0)];
   4579               if (nextNext == 104) {
   4580                 textIndex++;
   4581                 argSize = 1; // char (actually i32 in varargs)
   4582               } else {
   4583                 argSize = 2; // short (actually i32 in varargs)
   4584               }
   4585               break;
   4586             case 'l':
   4587               var nextNext = HEAP8[((textIndex+2)|0)];
   4588               if (nextNext == 108) {
   4589                 textIndex++;
   4590                 argSize = 8; // long long
   4591               } else {
   4592                 argSize = 4; // long
   4593               }
   4594               break;
   4595             case 'L': // long long
   4596             case 'q': // int64_t
   4597             case 'j': // intmax_t
   4598               argSize = 8;
   4599               break;
   4600             case 'z': // size_t
   4601             case 't': // ptrdiff_t
   4602             case 'I': // signed ptrdiff_t or unsigned size_t
   4603               argSize = 4;
   4604               break;
   4605             default:
   4606               argSize = null;
   4607           }
   4608           if (argSize) textIndex++;
   4609           next = HEAP8[((textIndex+1)|0)];
   4610 
   4611           // Handle type specifier.
   4612           switch (String.fromCharCode(next)) {
   4613             case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
   4614               // Integer.
   4615               var signed = next == 100 || next == 105;
   4616               argSize = argSize || 4;
   4617               var currArg = getNextArg('i' + (argSize * 8));
   4618               var argText;
   4619               // Flatten i64-1 [low, high] into a (slightly rounded) double
   4620               if (argSize == 8) {
   4621                 currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
   4622               }
   4623               // Truncate to requested size.
   4624               if (argSize <= 4) {
   4625                 var limit = Math.pow(256, argSize) - 1;
   4626                 currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
   4627               }
   4628               // Format the number.
   4629               var currAbsArg = Math.abs(currArg);
   4630               var prefix = '';
   4631               if (next == 100 || next == 105) {
   4632                 argText = reSign(currArg, 8 * argSize, 1).toString(10);
   4633               } else if (next == 117) {
   4634                 argText = unSign(currArg, 8 * argSize, 1).toString(10);
   4635                 currArg = Math.abs(currArg);
   4636               } else if (next == 111) {
   4637                 argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
   4638               } else if (next == 120 || next == 88) {
   4639                 prefix = (flagAlternative && currArg != 0) ? '0x' : '';
   4640                 if (currArg < 0) {
   4641                   // Represent negative numbers in hex as 2's complement.
   4642                   currArg = -currArg;
   4643                   argText = (currAbsArg - 1).toString(16);
   4644                   var buffer = [];
   4645                   for (var i = 0; i < argText.length; i++) {
   4646                     buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
   4647                   }
   4648                   argText = buffer.join('');
   4649                   while (argText.length < argSize * 2) argText = 'f' + argText;
   4650                 } else {
   4651                   argText = currAbsArg.toString(16);
   4652                 }
   4653                 if (next == 88) {
   4654                   prefix = prefix.toUpperCase();
   4655                   argText = argText.toUpperCase();
   4656                 }
   4657               } else if (next == 112) {
   4658                 if (currAbsArg === 0) {
   4659                   argText = '(nil)';
   4660                 } else {
   4661                   prefix = '0x';
   4662                   argText = currAbsArg.toString(16);
   4663                 }
   4664               }
   4665               if (precisionSet) {
   4666                 while (argText.length < precision) {
   4667                   argText = '0' + argText;
   4668                 }
   4669               }
   4670 
   4671               // Add sign if needed
   4672               if (currArg >= 0) {
   4673                 if (flagAlwaysSigned) {
   4674                   prefix = '+' + prefix;
   4675                 } else if (flagPadSign) {
   4676                   prefix = ' ' + prefix;
   4677                 }
   4678               }
   4679 
   4680               // Move sign to prefix so we zero-pad after the sign
   4681               if (argText.charAt(0) == '-') {
   4682                 prefix = '-' + prefix;
   4683                 argText = argText.substr(1);
   4684               }
   4685 
   4686               // Add padding.
   4687               while (prefix.length + argText.length < width) {
   4688                 if (flagLeftAlign) {
   4689                   argText += ' ';
   4690                 } else {
   4691                   if (flagZeroPad) {
   4692                     argText = '0' + argText;
   4693                   } else {
   4694                     prefix = ' ' + prefix;
   4695                   }
   4696                 }
   4697               }
   4698 
   4699               // Insert the result into the buffer.
   4700               argText = prefix + argText;
   4701               argText.split('').forEach(function(chr) {
   4702                 ret.push(chr.charCodeAt(0));
   4703               });
   4704               break;
   4705             }
   4706             case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
   4707               // Float.
   4708               var currArg = getNextArg('double');
   4709               var argText;
   4710               if (isNaN(currArg)) {
   4711                 argText = 'nan';
   4712                 flagZeroPad = false;
   4713               } else if (!isFinite(currArg)) {
   4714                 argText = (currArg < 0 ? '-' : '') + 'inf';
   4715                 flagZeroPad = false;
   4716               } else {
   4717                 var isGeneral = false;
   4718                 var effectivePrecision = Math.min(precision, 20);
   4719 
   4720                 // Convert g/G to f/F or e/E, as per:
   4721                 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
   4722                 if (next == 103 || next == 71) {
   4723                   isGeneral = true;
   4724                   precision = precision || 1;
   4725                   var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
   4726                   if (precision > exponent && exponent >= -4) {
   4727                     next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
   4728                     precision -= exponent + 1;
   4729                   } else {
   4730                     next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
   4731                     precision--;
   4732                   }
   4733                   effectivePrecision = Math.min(precision, 20);
   4734                 }
   4735 
   4736                 if (next == 101 || next == 69) {
   4737                   argText = currArg.toExponential(effectivePrecision);
   4738                   // Make sure the exponent has at least 2 digits.
   4739                   if (/[eE][-+]\d$/.test(argText)) {
   4740                     argText = argText.slice(0, -1) + '0' + argText.slice(-1);
   4741                   }
   4742                 } else if (next == 102 || next == 70) {
   4743                   argText = currArg.toFixed(effectivePrecision);
   4744                   if (currArg === 0 && __reallyNegative(currArg)) {
   4745                     argText = '-' + argText;
   4746                   }
   4747                 }
   4748 
   4749                 var parts = argText.split('e');
   4750                 if (isGeneral && !flagAlternative) {
   4751                   // Discard trailing zeros and periods.
   4752                   while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
   4753                          (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
   4754                     parts[0] = parts[0].slice(0, -1);
   4755                   }
   4756                 } else {
   4757                   // Make sure we have a period in alternative mode.
   4758                   if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
   4759                   // Zero pad until required precision.
   4760                   while (precision > effectivePrecision++) parts[0] += '0';
   4761                 }
   4762                 argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
   4763 
   4764                 // Capitalize 'E' if needed.
   4765                 if (next == 69) argText = argText.toUpperCase();
   4766 
   4767                 // Add sign.
   4768                 if (currArg >= 0) {
   4769                   if (flagAlwaysSigned) {
   4770                     argText = '+' + argText;
   4771                   } else if (flagPadSign) {
   4772                     argText = ' ' + argText;
   4773                   }
   4774                 }
   4775               }
   4776 
   4777               // Add padding.
   4778               while (argText.length < width) {
   4779                 if (flagLeftAlign) {
   4780                   argText += ' ';
   4781                 } else {
   4782                   if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
   4783                     argText = argText[0] + '0' + argText.slice(1);
   4784                   } else {
   4785                     argText = (flagZeroPad ? '0' : ' ') + argText;
   4786                   }
   4787                 }
   4788               }
   4789 
   4790               // Adjust case.
   4791               if (next < 97) argText = argText.toUpperCase();
   4792 
   4793               // Insert the result into the buffer.
   4794               argText.split('').forEach(function(chr) {
   4795                 ret.push(chr.charCodeAt(0));
   4796               });
   4797               break;
   4798             }
   4799             case 's': {
   4800               // String.
   4801               var arg = getNextArg('i8*');
   4802               var argLength = arg ? _strlen(arg) : '(null)'.length;
   4803               if (precisionSet) argLength = Math.min(argLength, precision);
   4804               if (!flagLeftAlign) {
   4805                 while (argLength < width--) {
   4806                   ret.push(32);
   4807                 }
   4808               }
   4809               if (arg) {
   4810                 for (var i = 0; i < argLength; i++) {
   4811                   ret.push(HEAPU8[((arg++)|0)]);
   4812                 }
   4813               } else {
   4814                 ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
   4815               }
   4816               if (flagLeftAlign) {
   4817                 while (argLength < width--) {
   4818                   ret.push(32);
   4819                 }
   4820               }
   4821               break;
   4822             }
   4823             case 'c': {
   4824               // Character.
   4825               if (flagLeftAlign) ret.push(getNextArg('i8'));
   4826               while (--width > 0) {
   4827                 ret.push(32);
   4828               }
   4829               if (!flagLeftAlign) ret.push(getNextArg('i8'));
   4830               break;
   4831             }
   4832             case 'n': {
   4833               // Write the length written so far to the next parameter.
   4834               var ptr = getNextArg('i32*');
   4835               HEAP32[((ptr)>>2)]=ret.length;
   4836               break;
   4837             }
   4838             case '%': {
   4839               // Literal percent sign.
   4840               ret.push(curr);
   4841               break;
   4842             }
   4843             default: {
   4844               // Unknown specifiers remain untouched.
   4845               for (var i = startTextIndex; i < textIndex + 2; i++) {
   4846                 ret.push(HEAP8[(i)]);
   4847               }
   4848             }
   4849           }
   4850           textIndex += 2;
   4851           // TODO: Support a/A (hex float) and m (last error) specifiers.
   4852           // TODO: Support %1${specifier} for arg selection.
   4853         } else {
   4854           ret.push(curr);
   4855           textIndex += 1;
   4856         }
   4857       }
   4858       return ret;
   4859     }function _fprintf(stream, format, varargs) {
   4860       // int fprintf(FILE *restrict stream, const char *restrict format, ...);
   4861       // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
   4862       var result = __formatString(format, varargs);
   4863       var stack = Runtime.stackSave();
   4864       var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
   4865       Runtime.stackRestore(stack);
   4866       return ret;
   4867     }function _printf(format, varargs) {
   4868       // int printf(const char *restrict format, ...);
   4869       // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
   4870       var stdout = HEAP32[((_stdout)>>2)];
   4871       return _fprintf(stdout, format, varargs);
   4872     }
   4873 
   4874   function _sbrk(bytes) {
   4875       // Implement a Linux-like 'memory area' for our 'process'.
   4876       // Changes the size of the memory area by |bytes|; returns the
   4877       // address of the previous top ('break') of the memory area
   4878       // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
   4879       var self = _sbrk;
   4880       if (!self.called) {
   4881         DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
   4882         self.called = true;
   4883         assert(Runtime.dynamicAlloc);
   4884         self.alloc = Runtime.dynamicAlloc;
   4885         Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
   4886       }
   4887       var ret = DYNAMICTOP;
   4888       if (bytes != 0) self.alloc(bytes);
   4889       return ret;  // Previous break location.
   4890     }
   4891 
   4892   function _sysconf(name) {
   4893       // long sysconf(int name);
   4894       // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
   4895       switch(name) {
   4896         case 30: return PAGE_SIZE;
   4897         case 132:
   4898         case 133:
   4899         case 12:
   4900         case 137:
   4901         case 138:
   4902         case 15:
   4903         case 235:
   4904         case 16:
   4905         case 17:
   4906         case 18:
   4907         case 19:
   4908         case 20:
   4909         case 149:
   4910         case 13:
   4911         case 10:
   4912         case 236:
   4913         case 153:
   4914         case 9:
   4915         case 21:
   4916         case 22:
   4917         case 159:
   4918         case 154:
   4919         case 14:
   4920         case 77:
   4921         case 78:
   4922         case 139:
   4923         case 80:
   4924         case 81:
   4925         case 79:
   4926         case 82:
   4927         case 68:
   4928         case 67:
   4929         case 164:
   4930         case 11:
   4931         case 29:
   4932         case 47:
   4933         case 48:
   4934         case 95:
   4935         case 52:
   4936         case 51:
   4937         case 46:
   4938           return 200809;
   4939         case 27:
   4940         case 246:
   4941         case 127:
   4942         case 128:
   4943         case 23:
   4944         case 24:
   4945         case 160:
   4946         case 161:
   4947         case 181:
   4948         case 182:
   4949         case 242:
   4950         case 183:
   4951         case 184:
   4952         case 243:
   4953         case 244:
   4954         case 245:
   4955         case 165:
   4956         case 178:
   4957         case 179:
   4958         case 49:
   4959         case 50:
   4960         case 168:
   4961         case 169:
   4962         case 175:
   4963         case 170:
   4964         case 171:
   4965         case 172:
   4966         case 97:
   4967         case 76:
   4968         case 32:
   4969         case 173:
   4970         case 35:
   4971           return -1;
   4972         case 176:
   4973         case 177:
   4974         case 7:
   4975         case 155:
   4976         case 8:
   4977         case 157:
   4978         case 125:
   4979         case 126:
   4980         case 92:
   4981         case 93:
   4982         case 129:
   4983         case 130:
   4984         case 131:
   4985         case 94:
   4986         case 91:
   4987           return 1;
   4988         case 74:
   4989         case 60:
   4990         case 69:
   4991         case 70:
   4992         case 4:
   4993           return 1024;
   4994         case 31:
   4995         case 42:
   4996         case 72:
   4997           return 32;
   4998         case 87:
   4999         case 26:
   5000         case 33:
   5001           return 2147483647;
   5002         case 34:
   5003         case 1:
   5004           return 47839;
   5005         case 38:
   5006         case 36:
   5007           return 99;
   5008         case 43:
   5009         case 37:
   5010           return 2048;
   5011         case 0: return 2097152;
   5012         case 3: return 65536;
   5013         case 28: return 32768;
   5014         case 44: return 32767;
   5015         case 75: return 16384;
   5016         case 39: return 1000;
   5017         case 89: return 700;
   5018         case 71: return 256;
   5019         case 40: return 255;
   5020         case 2: return 100;
   5021         case 180: return 64;
   5022         case 25: return 20;
   5023         case 5: return 16;
   5024         case 6: return 6;
   5025         case 73: return 4;
   5026         case 84: return 1;
   5027       }
   5028       ___setErrNo(ERRNO_CODES.EINVAL);
   5029       return -1;
   5030     }
   5031 
   5032 
   5033   Module["_memset"] = _memset;
   5034 
   5035   function ___errno_location() {
   5036       return ___errno_state;
   5037     }
   5038 
   5039   function _abort() {
   5040       Module['abort']();
   5041     }
   5042 
   5043   var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
   5044           Browser.mainLoop.shouldPause = true;
   5045         },resume:function () {
   5046           if (Browser.mainLoop.paused) {
   5047             Browser.mainLoop.paused = false;
   5048             Browser.mainLoop.scheduler();
   5049           }
   5050           Browser.mainLoop.shouldPause = false;
   5051         },updateStatus:function () {
   5052           if (Module['setStatus']) {
   5053             var message = Module['statusMessage'] || 'Please wait...';
   5054             var remaining = Browser.mainLoop.remainingBlockers;
   5055             var expected = Browser.mainLoop.expectedBlockers;
   5056             if (remaining) {
   5057               if (remaining < expected) {
   5058                 Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
   5059               } else {
   5060                 Module['setStatus'](message);
   5061               }
   5062             } else {
   5063               Module['setStatus']('');
   5064             }
   5065           }
   5066         }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
   5067         if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
   5068 
   5069         if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
   5070         Browser.initted = true;
   5071 
   5072         try {
   5073           new Blob();
   5074           Browser.hasBlobConstructor = true;
   5075         } catch(e) {
   5076           Browser.hasBlobConstructor = false;
   5077           console.log("warning: no blob constructor, cannot create blobs with mimetypes");
   5078         }
   5079         Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
   5080         Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
   5081         if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
   5082           console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
   5083           Module.noImageDecoding = true;
   5084         }
   5085 
   5086         // Support for plugins that can process preloaded files. You can add more of these to
   5087         // your app by creating and appending to Module.preloadPlugins.
   5088         //
   5089         // Each plugin is asked if it can handle a file based on the file's name. If it can,
   5090         // it is given the file's raw data. When it is done, it calls a callback with the file's
   5091         // (possibly modified) data. For example, a plugin might decompress a file, or it
   5092         // might create some side data structure for use later (like an Image element, etc.).
   5093 
   5094         var imagePlugin = {};
   5095         imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
   5096           return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
   5097         };
   5098         imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
   5099           var b = null;
   5100           if (Browser.hasBlobConstructor) {
   5101             try {
   5102               b = new Blob([byteArray], { type: Browser.getMimetype(name) });
   5103               if (b.size !== byteArray.length) { // Safari bug #118630
   5104                 // Safari's Blob can only take an ArrayBuffer
   5105                 b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
   5106               }
   5107             } catch(e) {
   5108               Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
   5109             }
   5110           }
   5111           if (!b) {
   5112             var bb = new Browser.BlobBuilder();
   5113             bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
   5114             b = bb.getBlob();
   5115           }
   5116           var url = Browser.URLObject.createObjectURL(b);
   5117           var img = new Image();
   5118           img.onload = function img_onload() {
   5119             assert(img.complete, 'Image ' + name + ' could not be decoded');
   5120             var canvas = document.createElement('canvas');
   5121             canvas.width = img.width;
   5122             canvas.height = img.height;
   5123             var ctx = canvas.getContext('2d');
   5124             ctx.drawImage(img, 0, 0);
   5125             Module["preloadedImages"][name] = canvas;
   5126             Browser.URLObject.revokeObjectURL(url);
   5127             if (onload) onload(byteArray);
   5128           };
   5129           img.onerror = function img_onerror(event) {
   5130             console.log('Image ' + url + ' could not be decoded');
   5131             if (onerror) onerror();
   5132           };
   5133           img.src = url;
   5134         };
   5135         Module['preloadPlugins'].push(imagePlugin);
   5136 
   5137         var audioPlugin = {};
   5138         audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
   5139           return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
   5140         };
   5141         audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
   5142           var done = false;
   5143           function finish(audio) {
   5144             if (done) return;
   5145             done = true;
   5146             Module["preloadedAudios"][name] = audio;
   5147             if (onload) onload(byteArray);
   5148           }
   5149           function fail() {
   5150             if (done) return;
   5151             done = true;
   5152             Module["preloadedAudios"][name] = new Audio(); // empty shim
   5153             if (onerror) onerror();
   5154           }
   5155           if (Browser.hasBlobConstructor) {
   5156             try {
   5157               var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
   5158             } catch(e) {
   5159               return fail();
   5160             }
   5161             var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
   5162             var audio = new Audio();
   5163             audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
   5164             audio.onerror = function audio_onerror(event) {
   5165               if (done) return;
   5166               console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
   5167               function encode64(data) {
   5168                 var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
   5169                 var PAD = '=';
   5170                 var ret = '';
   5171                 var leftchar = 0;
   5172                 var leftbits = 0;
   5173                 for (var i = 0; i < data.length; i++) {
   5174                   leftchar = (leftchar << 8) | data[i];
   5175                   leftbits += 8;
   5176                   while (leftbits >= 6) {
   5177                     var curr = (leftchar >> (leftbits-6)) & 0x3f;
   5178                     leftbits -= 6;
   5179                     ret += BASE[curr];
   5180                   }
   5181                 }
   5182                 if (leftbits == 2) {
   5183                   ret += BASE[(leftchar&3) << 4];
   5184                   ret += PAD + PAD;
   5185                 } else if (leftbits == 4) {
   5186                   ret += BASE[(leftchar&0xf) << 2];
   5187                   ret += PAD;
   5188                 }
   5189                 return ret;
   5190               }
   5191               audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
   5192               finish(audio); // we don't wait for confirmation this worked - but it's worth trying
   5193             };
   5194             audio.src = url;
   5195             // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
   5196             Browser.safeSetTimeout(function() {
   5197               finish(audio); // try to use it even though it is not necessarily ready to play
   5198             }, 10000);
   5199           } else {
   5200             return fail();
   5201           }
   5202         };
   5203         Module['preloadPlugins'].push(audioPlugin);
   5204 
   5205         // Canvas event setup
   5206 
   5207         var canvas = Module['canvas'];
   5208 
   5209         // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
   5210         // Module['forcedAspectRatio'] = 4 / 3;
   5211 
   5212         canvas.requestPointerLock = canvas['requestPointerLock'] ||
   5213                                     canvas['mozRequestPointerLock'] ||
   5214                                     canvas['webkitRequestPointerLock'] ||
   5215                                     canvas['msRequestPointerLock'] ||
   5216                                     function(){};
   5217         canvas.exitPointerLock = document['exitPointerLock'] ||
   5218                                  document['mozExitPointerLock'] ||
   5219                                  document['webkitExitPointerLock'] ||
   5220                                  document['msExitPointerLock'] ||
   5221                                  function(){}; // no-op if function does not exist
   5222         canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
   5223 
   5224         function pointerLockChange() {
   5225           Browser.pointerLock = document['pointerLockElement'] === canvas ||
   5226                                 document['mozPointerLockElement'] === canvas ||
   5227                                 document['webkitPointerLockElement'] === canvas ||
   5228                                 document['msPointerLockElement'] === canvas;
   5229         }
   5230 
   5231         document.addEventListener('pointerlockchange', pointerLockChange, false);
   5232         document.addEventListener('mozpointerlockchange', pointerLockChange, false);
   5233         document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
   5234         document.addEventListener('mspointerlockchange', pointerLockChange, false);
   5235 
   5236         if (Module['elementPointerLock']) {
   5237           canvas.addEventListener("click", function(ev) {
   5238             if (!Browser.pointerLock && canvas.requestPointerLock) {
   5239               canvas.requestPointerLock();
   5240               ev.preventDefault();
   5241             }
   5242           }, false);
   5243         }
   5244       },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
   5245         var ctx;
   5246         var errorInfo = '?';
   5247         function onContextCreationError(event) {
   5248           errorInfo = event.statusMessage || errorInfo;
   5249         }
   5250         try {
   5251           if (useWebGL) {
   5252             var contextAttributes = {
   5253               antialias: false,
   5254               alpha: false
   5255             };
   5256 
   5257             if (webGLContextAttributes) {
   5258               for (var attribute in webGLContextAttributes) {
   5259                 contextAttributes[attribute] = webGLContextAttributes[attribute];
   5260               }
   5261             }
   5262 
   5263 
   5264             canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
   5265             try {
   5266               ['experimental-webgl', 'webgl'].some(function(webglId) {
   5267                 return ctx = canvas.getContext(webglId, contextAttributes);
   5268               });
   5269             } finally {
   5270               canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
   5271             }
   5272           } else {
   5273             ctx = canvas.getContext('2d');
   5274           }
   5275           if (!ctx) throw ':(';
   5276         } catch (e) {
   5277           Module.print('Could not create canvas: ' + [errorInfo, e]);
   5278           return null;
   5279         }
   5280         if (useWebGL) {
   5281           // Set the background of the WebGL canvas to black
   5282           canvas.style.backgroundColor = "black";
   5283 
   5284           // Warn on context loss
   5285           canvas.addEventListener('webglcontextlost', function(event) {
   5286             alert('WebGL context lost. You will need to reload the page.');
   5287           }, false);
   5288         }
   5289         if (setInModule) {
   5290           GLctx = Module.ctx = ctx;
   5291           Module.useWebGL = useWebGL;
   5292           Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
   5293           Browser.init();
   5294         }
   5295         return ctx;
   5296       },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
   5297         Browser.lockPointer = lockPointer;
   5298         Browser.resizeCanvas = resizeCanvas;
   5299         if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
   5300         if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
   5301 
   5302         var canvas = Module['canvas'];
   5303         function fullScreenChange() {
   5304           Browser.isFullScreen = false;
   5305           var canvasContainer = canvas.parentNode;
   5306           if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
   5307                document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
   5308                document['fullScreenElement'] || document['fullscreenElement'] ||
   5309                document['msFullScreenElement'] || document['msFullscreenElement'] ||
   5310                document['webkitCurrentFullScreenElement']) === canvasContainer) {
   5311             canvas.cancelFullScreen = document['cancelFullScreen'] ||
   5312                                       document['mozCancelFullScreen'] ||
   5313                                       document['webkitCancelFullScreen'] ||
   5314                                       document['msExitFullscreen'] ||
   5315                                       document['exitFullscreen'] ||
   5316                                       function() {};
   5317             canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
   5318             if (Browser.lockPointer) canvas.requestPointerLock();
   5319             Browser.isFullScreen = true;
   5320             if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
   5321           } else {
   5322 
   5323             // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
   5324             canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
   5325             canvasContainer.parentNode.removeChild(canvasContainer);
   5326 
   5327             if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
   5328           }
   5329           if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
   5330           Browser.updateCanvasDimensions(canvas);
   5331         }
   5332 
   5333         if (!Browser.fullScreenHandlersInstalled) {
   5334           Browser.fullScreenHandlersInstalled = true;
   5335           document.addEventListener('fullscreenchange', fullScreenChange, false);
   5336           document.addEventListener('mozfullscreenchange', fullScreenChange, false);
   5337           document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
   5338           document.addEventListener('MSFullscreenChange', fullScreenChange, false);
   5339         }
   5340 
   5341         // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
   5342         var canvasContainer = document.createElement("div");
   5343         canvas.parentNode.insertBefore(canvasContainer, canvas);
   5344         canvasContainer.appendChild(canvas);
   5345 
   5346         // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
   5347         canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
   5348                                             canvasContainer['mozRequestFullScreen'] ||
   5349                                             canvasContainer['msRequestFullscreen'] ||
   5350                                            (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
   5351         canvasContainer.requestFullScreen();
   5352       },requestAnimationFrame:function requestAnimationFrame(func) {
   5353         if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
   5354           setTimeout(func, 1000/60);
   5355         } else {
   5356           if (!window.requestAnimationFrame) {
   5357             window.requestAnimationFrame = window['requestAnimationFrame'] ||
   5358                                            window['mozRequestAnimationFrame'] ||
   5359                                            window['webkitRequestAnimationFrame'] ||
   5360                                            window['msRequestAnimationFrame'] ||
   5361                                            window['oRequestAnimationFrame'] ||
   5362                                            window['setTimeout'];
   5363           }
   5364           window.requestAnimationFrame(func);
   5365         }
   5366       },safeCallback:function (func) {
   5367         return function() {
   5368           if (!ABORT) return func.apply(null, arguments);
   5369         };
   5370       },safeRequestAnimationFrame:function (func) {
   5371         return Browser.requestAnimationFrame(function() {
   5372           if (!ABORT) func();
   5373         });
   5374       },safeSetTimeout:function (func, timeout) {
   5375         return setTimeout(function() {
   5376           if (!ABORT) func();
   5377         }, timeout);
   5378       },safeSetInterval:function (func, timeout) {
   5379         return setInterval(function() {
   5380           if (!ABORT) func();
   5381         }, timeout);
   5382       },getMimetype:function (name) {
   5383         return {
   5384           'jpg': 'image/jpeg',
   5385           'jpeg': 'image/jpeg',
   5386           'png': 'image/png',
   5387           'bmp': 'image/bmp',
   5388           'ogg': 'audio/ogg',
   5389           'wav': 'audio/wav',
   5390           'mp3': 'audio/mpeg'
   5391         }[name.substr(name.lastIndexOf('.')+1)];
   5392       },getUserMedia:function (func) {
   5393         if(!window.getUserMedia) {
   5394           window.getUserMedia = navigator['getUserMedia'] ||
   5395                                 navigator['mozGetUserMedia'];
   5396         }
   5397         window.getUserMedia(func);
   5398       },getMovementX:function (event) {
   5399         return event['movementX'] ||
   5400                event['mozMovementX'] ||
   5401                event['webkitMovementX'] ||
   5402                0;
   5403       },getMovementY:function (event) {
   5404         return event['movementY'] ||
   5405                event['mozMovementY'] ||
   5406                event['webkitMovementY'] ||
   5407                0;
   5408       },getMouseWheelDelta:function (event) {
   5409         return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
   5410       },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
   5411         if (Browser.pointerLock) {
   5412           // When the pointer is locked, calculate the coordinates
   5413           // based on the movement of the mouse.
   5414           // Workaround for Firefox bug 764498
   5415           if (event.type != 'mousemove' &&
   5416               ('mozMovementX' in event)) {
   5417             Browser.mouseMovementX = Browser.mouseMovementY = 0;
   5418           } else {
   5419             Browser.mouseMovementX = Browser.getMovementX(event);
   5420             Browser.mouseMovementY = Browser.getMovementY(event);
   5421           }
   5422 
   5423           // check if SDL is available
   5424           if (typeof SDL != "undefined") {
   5425     Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
   5426     Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
   5427           } else {
   5428     // just add the mouse delta to the current absolut mouse position
   5429     // FIXME: ideally this should be clamped against the canvas size and zero
   5430     Browser.mouseX += Browser.mouseMovementX;
   5431     Browser.mouseY += Browser.mouseMovementY;
   5432           }
   5433         } else {
   5434           // Otherwise, calculate the movement based on the changes
   5435           // in the coordinates.
   5436           var rect = Module["canvas"].getBoundingClientRect();
   5437           var x, y;
   5438 
   5439           // Neither .scrollX or .pageXOffset are defined in a spec, but
   5440           // we prefer .scrollX because it is currently in a spec draft.
   5441           // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
   5442           var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
   5443           var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
   5444           if (event.type == 'touchstart' ||
   5445               event.type == 'touchend' ||
   5446               event.type == 'touchmove') {
   5447             var t = event.touches.item(0);
   5448             if (t) {
   5449               x = t.pageX - (scrollX + rect.left);
   5450               y = t.pageY - (scrollY + rect.top);
   5451             } else {
   5452               return;
   5453             }
   5454           } else {
   5455             x = event.pageX - (scrollX + rect.left);
   5456             y = event.pageY - (scrollY + rect.top);
   5457           }
   5458 
   5459           // the canvas might be CSS-scaled compared to its backbuffer;
   5460           // SDL-using content will want mouse coordinates in terms
   5461           // of backbuffer units.
   5462           var cw = Module["canvas"].width;
   5463           var ch = Module["canvas"].height;
   5464           x = x * (cw / rect.width);
   5465           y = y * (ch / rect.height);
   5466 
   5467           Browser.mouseMovementX = x - Browser.mouseX;
   5468           Browser.mouseMovementY = y - Browser.mouseY;
   5469           Browser.mouseX = x;
   5470           Browser.mouseY = y;
   5471         }
   5472       },xhrLoad:function (url, onload, onerror) {
   5473         var xhr = new XMLHttpRequest();
   5474         xhr.open('GET', url, true);
   5475         xhr.responseType = 'arraybuffer';
   5476         xhr.onload = function xhr_onload() {
   5477           if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
   5478             onload(xhr.response);
   5479           } else {
   5480             onerror();
   5481           }
   5482         };
   5483         xhr.onerror = onerror;
   5484         xhr.send(null);
   5485       },asyncLoad:function (url, onload, onerror, noRunDep) {
   5486         Browser.xhrLoad(url, function(arrayBuffer) {
   5487           assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
   5488           onload(new Uint8Array(arrayBuffer));
   5489           if (!noRunDep) removeRunDependency('al ' + url);
   5490         }, function(event) {
   5491           if (onerror) {
   5492             onerror();
   5493           } else {
   5494             throw 'Loading data file "' + url + '" failed.';
   5495           }
   5496         });
   5497         if (!noRunDep) addRunDependency('al ' + url);
   5498       },resizeListeners:[],updateResizeListeners:function () {
   5499         var canvas = Module['canvas'];
   5500         Browser.resizeListeners.forEach(function(listener) {
   5501           listener(canvas.width, canvas.height);
   5502         });
   5503       },setCanvasSize:function (width, height, noUpdates) {
   5504         var canvas = Module['canvas'];
   5505         Browser.updateCanvasDimensions(canvas, width, height);
   5506         if (!noUpdates) Browser.updateResizeListeners();
   5507       },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
   5508         // check if SDL is available
   5509         if (typeof SDL != "undefined") {
   5510     var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
   5511     flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
   5512     HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
   5513         }
   5514         Browser.updateResizeListeners();
   5515       },setWindowedCanvasSize:function () {
   5516         // check if SDL is available
   5517         if (typeof SDL != "undefined") {
   5518     var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
   5519     flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
   5520     HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
   5521         }
   5522         Browser.updateResizeListeners();
   5523       },updateCanvasDimensions:function (canvas, wNative, hNative) {
   5524         if (wNative && hNative) {
   5525           canvas.widthNative = wNative;
   5526           canvas.heightNative = hNative;
   5527         } else {
   5528           wNative = canvas.widthNative;
   5529           hNative = canvas.heightNative;
   5530         }
   5531         var w = wNative;
   5532         var h = hNative;
   5533         if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
   5534           if (w/h < Module['forcedAspectRatio']) {
   5535             w = Math.round(h * Module['forcedAspectRatio']);
   5536           } else {
   5537             h = Math.round(w / Module['forcedAspectRatio']);
   5538           }
   5539         }
   5540         if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
   5541              document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
   5542              document['fullScreenElement'] || document['fullscreenElement'] ||
   5543              document['msFullScreenElement'] || document['msFullscreenElement'] ||
   5544              document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
   5545            var factor = Math.min(screen.width / w, screen.height / h);
   5546            w = Math.round(w * factor);
   5547            h = Math.round(h * factor);
   5548         }
   5549         if (Browser.resizeCanvas) {
   5550           if (canvas.width  != w) canvas.width  = w;
   5551           if (canvas.height != h) canvas.height = h;
   5552           if (typeof canvas.style != 'undefined') {
   5553             canvas.style.removeProperty( "width");
   5554             canvas.style.removeProperty("height");
   5555           }
   5556         } else {
   5557           if (canvas.width  != wNative) canvas.width  = wNative;
   5558           if (canvas.height != hNative) canvas.height = hNative;
   5559           if (typeof canvas.style != 'undefined') {
   5560             if (w != wNative || h != hNative) {
   5561               canvas.style.setProperty( "width", w + "px", "important");
   5562               canvas.style.setProperty("height", h + "px", "important");
   5563             } else {
   5564               canvas.style.removeProperty( "width");
   5565               canvas.style.removeProperty("height");
   5566             }
   5567           }
   5568         }
   5569       }};
   5570 
   5571   function _time(ptr) {
   5572       var ret = Math.floor(Date.now()/1000);
   5573       if (ptr) {
   5574         HEAP32[((ptr)>>2)]=ret;
   5575       }
   5576       return ret;
   5577     }
   5578 
   5579 
   5580 
   5581   function _emscripten_memcpy_big(dest, src, num) {
   5582       HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
   5583       return dest;
   5584     }
   5585   Module["_memcpy"] = _memcpy;
   5586 FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
   5587 ___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
   5588 __ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
   5589 if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
   5590 __ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
   5591 Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
   5592   Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
   5593   Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
   5594   Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
   5595   Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
   5596   Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
   5597 STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
   5598 
   5599 staticSealed = true; // seal the static portion of memory
   5600 
   5601 STACK_MAX = STACK_BASE + 5242880;
   5602 
   5603 DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
   5604 
   5605 assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
   5606 
   5607 
   5608 var Math_min = Math.min;
   5609 function asmPrintInt(x, y) {
   5610   Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
   5611 }
   5612 function asmPrintFloat(x, y) {
   5613   Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
   5614 }
   5615 // EMSCRIPTEN_START_ASM
   5616 var asm = Wasm.instantiateModuleFromAsm((function Module(global, env, buffer) {
   5617   'use asm';
   5618   var HEAP8 = new global.Int8Array(buffer);
   5619   var HEAP16 = new global.Int16Array(buffer);
   5620   var HEAP32 = new global.Int32Array(buffer);
   5621   var HEAPU8 = new global.Uint8Array(buffer);
   5622   var HEAPU16 = new global.Uint16Array(buffer);
   5623   var HEAPU32 = new global.Uint32Array(buffer);
   5624   var HEAPF32 = new global.Float32Array(buffer);
   5625   var HEAPF64 = new global.Float64Array(buffer);
   5626 
   5627   var STACKTOP=env.STACKTOP|0;
   5628   var STACK_MAX=env.STACK_MAX|0;
   5629   var tempDoublePtr=env.tempDoublePtr|0;
   5630   var ABORT=env.ABORT|0;
   5631 
   5632   var __THREW__ = 0;
   5633   var threwValue = 0;
   5634   var setjmpId = 0;
   5635   var undef = 0;
   5636   var nan = +env.NaN, inf = +env.Infinity;
   5637   var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
   5638 
   5639   var tempRet0 = 0;
   5640   var tempRet1 = 0;
   5641   var tempRet2 = 0;
   5642   var tempRet3 = 0;
   5643   var tempRet4 = 0;
   5644   var tempRet5 = 0;
   5645   var tempRet6 = 0;
   5646   var tempRet7 = 0;
   5647   var tempRet8 = 0;
   5648   var tempRet9 = 0;
   5649   var Math_floor=global.Math.floor;
   5650   var Math_abs=global.Math.abs;
   5651   var Math_sqrt=global.Math.sqrt;
   5652   var Math_pow=global.Math.pow;
   5653   var Math_cos=global.Math.cos;
   5654   var Math_sin=global.Math.sin;
   5655   var Math_tan=global.Math.tan;
   5656   var Math_acos=global.Math.acos;
   5657   var Math_asin=global.Math.asin;
   5658   var Math_atan=global.Math.atan;
   5659   var Math_atan2=global.Math.atan2;
   5660   var Math_exp=global.Math.exp;
   5661   var Math_log=global.Math.log;
   5662   var Math_ceil=global.Math.ceil;
   5663   var Math_imul=global.Math.imul;
   5664   var abort=env.abort;
   5665   var assert=env.assert;
   5666   var asmPrintInt=env.asmPrintInt;
   5667   var asmPrintFloat=env.asmPrintFloat;
   5668   var Math_min=env.min;
   5669   var _fflush=env._fflush;
   5670   var _emscripten_memcpy_big=env._emscripten_memcpy_big;
   5671   var _printf=env._printf;
   5672   var _send=env._send;
   5673   var _pwrite=env._pwrite;
   5674   var _abort=env._abort;
   5675   var ___setErrNo=env.___setErrNo;
   5676   var _fwrite=env._fwrite;
   5677   var _sbrk=env._sbrk;
   5678   var _time=env._time;
   5679   var _mkport=env._mkport;
   5680   var __reallyNegative=env.__reallyNegative;
   5681   var __formatString=env.__formatString;
   5682   var _fileno=env._fileno;
   5683   var _write=env._write;
   5684   var _fprintf=env._fprintf;
   5685   var _sysconf=env._sysconf;
   5686   var ___errno_location=env.___errno_location;
   5687   var tempFloat = 0.0;
   5688 
   5689 // EMSCRIPTEN_START_FUNCS
   5690 function _malloc(i12) {
   5691  i12 = i12 | 0;
   5692  var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
   5693  i1 = STACKTOP;
   5694  do {
   5695   if (i12 >>> 0 < 245) {
   5696    if (i12 >>> 0 < 11) {
   5697     i12 = 16;
   5698    } else {
   5699     i12 = i12 + 11 & -8;
   5700    }
   5701    i20 = i12 >>> 3;
   5702    i18 = HEAP32[10] | 0;
   5703    i21 = i18 >>> i20;
   5704    if ((i21 & 3 | 0) != 0) {
   5705     i6 = (i21 & 1 ^ 1) + i20 | 0;
   5706     i5 = i6 << 1;
   5707     i3 = 80 + (i5 << 2) | 0;
   5708     i5 = 80 + (i5 + 2 << 2) | 0;
   5709     i7 = HEAP32[i5 >> 2] | 0;
   5710     i2 = i7 + 8 | 0;
   5711     i4 = HEAP32[i2 >> 2] | 0;
   5712     do {
   5713      if ((i3 | 0) != (i4 | 0)) {
   5714       if (i4 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   5715        _abort();
   5716       }
   5717       i8 = i4 + 12 | 0;
   5718       if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) {
   5719        HEAP32[i8 >> 2] = i3;
   5720        HEAP32[i5 >> 2] = i4;
   5721        break;
   5722       } else {
   5723        _abort();
   5724       }
   5725      } else {
   5726       HEAP32[10] = i18 & ~(1 << i6);
   5727      }
   5728     } while (0);
   5729     i32 = i6 << 3;
   5730     HEAP32[i7 + 4 >> 2] = i32 | 3;
   5731     i32 = i7 + (i32 | 4) | 0;
   5732     HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
   5733     i32 = i2;
   5734     STACKTOP = i1;
   5735     return i32 | 0;
   5736    }
   5737    if (i12 >>> 0 > (HEAP32[48 >> 2] | 0) >>> 0) {
   5738     if ((i21 | 0) != 0) {
   5739      i7 = 2 << i20;
   5740      i7 = i21 << i20 & (i7 | 0 - i7);
   5741      i7 = (i7 & 0 - i7) + -1 | 0;
   5742      i2 = i7 >>> 12 & 16;
   5743      i7 = i7 >>> i2;
   5744      i6 = i7 >>> 5 & 8;
   5745      i7 = i7 >>> i6;
   5746      i5 = i7 >>> 2 & 4;
   5747      i7 = i7 >>> i5;
   5748      i4 = i7 >>> 1 & 2;
   5749      i7 = i7 >>> i4;
   5750      i3 = i7 >>> 1 & 1;
   5751      i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0;
   5752      i7 = i3 << 1;
   5753      i4 = 80 + (i7 << 2) | 0;
   5754      i7 = 80 + (i7 + 2 << 2) | 0;
   5755      i5 = HEAP32[i7 >> 2] | 0;
   5756      i2 = i5 + 8 | 0;
   5757      i6 = HEAP32[i2 >> 2] | 0;
   5758      do {
   5759       if ((i4 | 0) != (i6 | 0)) {
   5760        if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   5761         _abort();
   5762        }
   5763        i8 = i6 + 12 | 0;
   5764        if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) {
   5765         HEAP32[i8 >> 2] = i4;
   5766         HEAP32[i7 >> 2] = i6;
   5767         break;
   5768        } else {
   5769         _abort();
   5770        }
   5771       } else {
   5772        HEAP32[10] = i18 & ~(1 << i3);
   5773       }
   5774      } while (0);
   5775      i6 = i3 << 3;
   5776      i4 = i6 - i12 | 0;
   5777      HEAP32[i5 + 4 >> 2] = i12 | 3;
   5778      i3 = i5 + i12 | 0;
   5779      HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1;
   5780      HEAP32[i5 + i6 >> 2] = i4;
   5781      i6 = HEAP32[48 >> 2] | 0;
   5782      if ((i6 | 0) != 0) {
   5783       i5 = HEAP32[60 >> 2] | 0;
   5784       i8 = i6 >>> 3;
   5785       i9 = i8 << 1;
   5786       i6 = 80 + (i9 << 2) | 0;
   5787       i7 = HEAP32[10] | 0;
   5788       i8 = 1 << i8;
   5789       if ((i7 & i8 | 0) != 0) {
   5790        i7 = 80 + (i9 + 2 << 2) | 0;
   5791        i8 = HEAP32[i7 >> 2] | 0;
   5792        if (i8 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   5793         _abort();
   5794        } else {
   5795         i28 = i7;
   5796         i27 = i8;
   5797        }
   5798       } else {
   5799        HEAP32[10] = i7 | i8;
   5800        i28 = 80 + (i9 + 2 << 2) | 0;
   5801        i27 = i6;
   5802       }
   5803       HEAP32[i28 >> 2] = i5;
   5804       HEAP32[i27 + 12 >> 2] = i5;
   5805       HEAP32[i5 + 8 >> 2] = i27;
   5806       HEAP32[i5 + 12 >> 2] = i6;
   5807      }
   5808      HEAP32[48 >> 2] = i4;
   5809      HEAP32[60 >> 2] = i3;
   5810      i32 = i2;
   5811      STACKTOP = i1;
   5812      return i32 | 0;
   5813     }
   5814     i18 = HEAP32[44 >> 2] | 0;
   5815     if ((i18 | 0) != 0) {
   5816      i2 = (i18 & 0 - i18) + -1 | 0;
   5817      i31 = i2 >>> 12 & 16;
   5818      i2 = i2 >>> i31;
   5819      i30 = i2 >>> 5 & 8;
   5820      i2 = i2 >>> i30;
   5821      i32 = i2 >>> 2 & 4;
   5822      i2 = i2 >>> i32;
   5823      i6 = i2 >>> 1 & 2;
   5824      i2 = i2 >>> i6;
   5825      i3 = i2 >>> 1 & 1;
   5826      i3 = HEAP32[344 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0;
   5827      i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0;
   5828      i6 = i3;
   5829      while (1) {
   5830       i5 = HEAP32[i6 + 16 >> 2] | 0;
   5831       if ((i5 | 0) == 0) {
   5832        i5 = HEAP32[i6 + 20 >> 2] | 0;
   5833        if ((i5 | 0) == 0) {
   5834         break;
   5835        }
   5836       }
   5837       i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0;
   5838       i4 = i6 >>> 0 < i2 >>> 0;
   5839       i2 = i4 ? i6 : i2;
   5840       i6 = i5;
   5841       i3 = i4 ? i5 : i3;
   5842      }
   5843      i6 = HEAP32[56 >> 2] | 0;
   5844      if (i3 >>> 0 < i6 >>> 0) {
   5845       _abort();
   5846      }
   5847      i4 = i3 + i12 | 0;
   5848      if (!(i3 >>> 0 < i4 >>> 0)) {
   5849       _abort();
   5850      }
   5851      i5 = HEAP32[i3 + 24 >> 2] | 0;
   5852      i7 = HEAP32[i3 + 12 >> 2] | 0;
   5853      do {
   5854       if ((i7 | 0) == (i3 | 0)) {
   5855        i8 = i3 + 20 | 0;
   5856        i7 = HEAP32[i8 >> 2] | 0;
   5857        if ((i7 | 0) == 0) {
   5858         i8 = i3 + 16 | 0;
   5859         i7 = HEAP32[i8 >> 2] | 0;
   5860         if ((i7 | 0) == 0) {
   5861          i26 = 0;
   5862          break;
   5863         }
   5864        }
   5865        while (1) {
   5866         i10 = i7 + 20 | 0;
   5867         i9 = HEAP32[i10 >> 2] | 0;
   5868         if ((i9 | 0) != 0) {
   5869          i7 = i9;
   5870          i8 = i10;
   5871          continue;
   5872         }
   5873         i10 = i7 + 16 | 0;
   5874         i9 = HEAP32[i10 >> 2] | 0;
   5875         if ((i9 | 0) == 0) {
   5876          break;
   5877         } else {
   5878          i7 = i9;
   5879          i8 = i10;
   5880         }
   5881        }
   5882        if (i8 >>> 0 < i6 >>> 0) {
   5883         _abort();
   5884        } else {
   5885         HEAP32[i8 >> 2] = 0;
   5886         i26 = i7;
   5887         break;
   5888        }
   5889       } else {
   5890        i8 = HEAP32[i3 + 8 >> 2] | 0;
   5891        if (i8 >>> 0 < i6 >>> 0) {
   5892         _abort();
   5893        }
   5894        i6 = i8 + 12 | 0;
   5895        if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) {
   5896         _abort();
   5897        }
   5898        i9 = i7 + 8 | 0;
   5899        if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) {
   5900         HEAP32[i6 >> 2] = i7;
   5901         HEAP32[i9 >> 2] = i8;
   5902         i26 = i7;
   5903         break;
   5904        } else {
   5905         _abort();
   5906        }
   5907       }
   5908      } while (0);
   5909      do {
   5910       if ((i5 | 0) != 0) {
   5911        i7 = HEAP32[i3 + 28 >> 2] | 0;
   5912        i6 = 344 + (i7 << 2) | 0;
   5913        if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) {
   5914         HEAP32[i6 >> 2] = i26;
   5915         if ((i26 | 0) == 0) {
   5916          HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i7);
   5917          break;
   5918         }
   5919        } else {
   5920         if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   5921          _abort();
   5922         }
   5923         i6 = i5 + 16 | 0;
   5924         if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) {
   5925          HEAP32[i6 >> 2] = i26;
   5926         } else {
   5927          HEAP32[i5 + 20 >> 2] = i26;
   5928         }
   5929         if ((i26 | 0) == 0) {
   5930          break;
   5931         }
   5932        }
   5933        if (i26 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   5934         _abort();
   5935        }
   5936        HEAP32[i26 + 24 >> 2] = i5;
   5937        i5 = HEAP32[i3 + 16 >> 2] | 0;
   5938        do {
   5939         if ((i5 | 0) != 0) {
   5940          if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   5941           _abort();
   5942          } else {
   5943           HEAP32[i26 + 16 >> 2] = i5;
   5944           HEAP32[i5 + 24 >> 2] = i26;
   5945           break;
   5946          }
   5947         }
   5948        } while (0);
   5949        i5 = HEAP32[i3 + 20 >> 2] | 0;
   5950        if ((i5 | 0) != 0) {
   5951         if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   5952          _abort();
   5953         } else {
   5954          HEAP32[i26 + 20 >> 2] = i5;
   5955          HEAP32[i5 + 24 >> 2] = i26;
   5956          break;
   5957         }
   5958        }
   5959       }
   5960      } while (0);
   5961      if (i2 >>> 0 < 16) {
   5962       i32 = i2 + i12 | 0;
   5963       HEAP32[i3 + 4 >> 2] = i32 | 3;
   5964       i32 = i3 + (i32 + 4) | 0;
   5965       HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
   5966      } else {
   5967       HEAP32[i3 + 4 >> 2] = i12 | 3;
   5968       HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1;
   5969       HEAP32[i3 + (i2 + i12) >> 2] = i2;
   5970       i6 = HEAP32[48 >> 2] | 0;
   5971       if ((i6 | 0) != 0) {
   5972        i5 = HEAP32[60 >> 2] | 0;
   5973        i8 = i6 >>> 3;
   5974        i9 = i8 << 1;
   5975        i6 = 80 + (i9 << 2) | 0;
   5976        i7 = HEAP32[10] | 0;
   5977        i8 = 1 << i8;
   5978        if ((i7 & i8 | 0) != 0) {
   5979         i7 = 80 + (i9 + 2 << 2) | 0;
   5980         i8 = HEAP32[i7 >> 2] | 0;
   5981         if (i8 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   5982          _abort();
   5983         } else {
   5984          i25 = i7;
   5985          i24 = i8;
   5986         }
   5987        } else {
   5988         HEAP32[10] = i7 | i8;
   5989         i25 = 80 + (i9 + 2 << 2) | 0;
   5990         i24 = i6;
   5991        }
   5992        HEAP32[i25 >> 2] = i5;
   5993        HEAP32[i24 + 12 >> 2] = i5;
   5994        HEAP32[i5 + 8 >> 2] = i24;
   5995        HEAP32[i5 + 12 >> 2] = i6;
   5996       }
   5997       HEAP32[48 >> 2] = i2;
   5998       HEAP32[60 >> 2] = i4;
   5999      }
   6000      i32 = i3 + 8 | 0;
   6001      STACKTOP = i1;
   6002      return i32 | 0;
   6003     }
   6004    }
   6005   } else {
   6006    if (!(i12 >>> 0 > 4294967231)) {
   6007     i24 = i12 + 11 | 0;
   6008     i12 = i24 & -8;
   6009     i26 = HEAP32[44 >> 2] | 0;
   6010     if ((i26 | 0) != 0) {
   6011      i25 = 0 - i12 | 0;
   6012      i24 = i24 >>> 8;
   6013      if ((i24 | 0) != 0) {
   6014       if (i12 >>> 0 > 16777215) {
   6015        i27 = 31;
   6016       } else {
   6017        i31 = (i24 + 1048320 | 0) >>> 16 & 8;
   6018        i32 = i24 << i31;
   6019        i30 = (i32 + 520192 | 0) >>> 16 & 4;
   6020        i32 = i32 << i30;
   6021        i27 = (i32 + 245760 | 0) >>> 16 & 2;
   6022        i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0;
   6023        i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1;
   6024       }
   6025      } else {
   6026       i27 = 0;
   6027      }
   6028      i30 = HEAP32[344 + (i27 << 2) >> 2] | 0;
   6029      L126 : do {
   6030       if ((i30 | 0) == 0) {
   6031        i29 = 0;
   6032        i24 = 0;
   6033       } else {
   6034        if ((i27 | 0) == 31) {
   6035         i24 = 0;
   6036        } else {
   6037         i24 = 25 - (i27 >>> 1) | 0;
   6038        }
   6039        i29 = 0;
   6040        i28 = i12 << i24;
   6041        i24 = 0;
   6042        while (1) {
   6043         i32 = HEAP32[i30 + 4 >> 2] & -8;
   6044         i31 = i32 - i12 | 0;
   6045         if (i31 >>> 0 < i25 >>> 0) {
   6046          if ((i32 | 0) == (i12 | 0)) {
   6047           i25 = i31;
   6048           i29 = i30;
   6049           i24 = i30;
   6050           break L126;
   6051          } else {
   6052           i25 = i31;
   6053           i24 = i30;
   6054          }
   6055         }
   6056         i31 = HEAP32[i30 + 20 >> 2] | 0;
   6057         i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0;
   6058         i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31;
   6059         if ((i30 | 0) == 0) {
   6060          break;
   6061         } else {
   6062          i28 = i28 << 1;
   6063         }
   6064        }
   6065       }
   6066      } while (0);
   6067      if ((i29 | 0) == 0 & (i24 | 0) == 0) {
   6068       i32 = 2 << i27;
   6069       i26 = i26 & (i32 | 0 - i32);
   6070       if ((i26 | 0) == 0) {
   6071        break;
   6072       }
   6073       i32 = (i26 & 0 - i26) + -1 | 0;
   6074       i28 = i32 >>> 12 & 16;
   6075       i32 = i32 >>> i28;
   6076       i27 = i32 >>> 5 & 8;
   6077       i32 = i32 >>> i27;
   6078       i30 = i32 >>> 2 & 4;
   6079       i32 = i32 >>> i30;
   6080       i31 = i32 >>> 1 & 2;
   6081       i32 = i32 >>> i31;
   6082       i29 = i32 >>> 1 & 1;
   6083       i29 = HEAP32[344 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0;
   6084      }
   6085      if ((i29 | 0) != 0) {
   6086       while (1) {
   6087        i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0;
   6088        i26 = i27 >>> 0 < i25 >>> 0;
   6089        i25 = i26 ? i27 : i25;
   6090        i24 = i26 ? i29 : i24;
   6091        i26 = HEAP32[i29 + 16 >> 2] | 0;
   6092        if ((i26 | 0) != 0) {
   6093         i29 = i26;
   6094         continue;
   6095        }
   6096        i29 = HEAP32[i29 + 20 >> 2] | 0;
   6097        if ((i29 | 0) == 0) {
   6098         break;
   6099        }
   6100       }
   6101      }
   6102      if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[48 >> 2] | 0) - i12 | 0) >>> 0 : 0) {
   6103       i4 = HEAP32[56 >> 2] | 0;
   6104       if (i24 >>> 0 < i4 >>> 0) {
   6105        _abort();
   6106       }
   6107       i2 = i24 + i12 | 0;
   6108       if (!(i24 >>> 0 < i2 >>> 0)) {
   6109        _abort();
   6110       }
   6111       i3 = HEAP32[i24 + 24 >> 2] | 0;
   6112       i6 = HEAP32[i24 + 12 >> 2] | 0;
   6113       do {
   6114        if ((i6 | 0) == (i24 | 0)) {
   6115         i6 = i24 + 20 | 0;
   6116         i5 = HEAP32[i6 >> 2] | 0;
   6117         if ((i5 | 0) == 0) {
   6118          i6 = i24 + 16 | 0;
   6119          i5 = HEAP32[i6 >> 2] | 0;
   6120          if ((i5 | 0) == 0) {
   6121           i22 = 0;
   6122           break;
   6123          }
   6124         }
   6125         while (1) {
   6126          i8 = i5 + 20 | 0;
   6127          i7 = HEAP32[i8 >> 2] | 0;
   6128          if ((i7 | 0) != 0) {
   6129           i5 = i7;
   6130           i6 = i8;
   6131           continue;
   6132          }
   6133          i7 = i5 + 16 | 0;
   6134          i8 = HEAP32[i7 >> 2] | 0;
   6135          if ((i8 | 0) == 0) {
   6136           break;
   6137          } else {
   6138           i5 = i8;
   6139           i6 = i7;
   6140          }
   6141         }
   6142         if (i6 >>> 0 < i4 >>> 0) {
   6143          _abort();
   6144         } else {
   6145          HEAP32[i6 >> 2] = 0;
   6146          i22 = i5;
   6147          break;
   6148         }
   6149        } else {
   6150         i5 = HEAP32[i24 + 8 >> 2] | 0;
   6151         if (i5 >>> 0 < i4 >>> 0) {
   6152          _abort();
   6153         }
   6154         i7 = i5 + 12 | 0;
   6155         if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) {
   6156          _abort();
   6157         }
   6158         i4 = i6 + 8 | 0;
   6159         if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
   6160          HEAP32[i7 >> 2] = i6;
   6161          HEAP32[i4 >> 2] = i5;
   6162          i22 = i6;
   6163          break;
   6164         } else {
   6165          _abort();
   6166         }
   6167        }
   6168       } while (0);
   6169       do {
   6170        if ((i3 | 0) != 0) {
   6171         i4 = HEAP32[i24 + 28 >> 2] | 0;
   6172         i5 = 344 + (i4 << 2) | 0;
   6173         if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) {
   6174          HEAP32[i5 >> 2] = i22;
   6175          if ((i22 | 0) == 0) {
   6176           HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i4);
   6177           break;
   6178          }
   6179         } else {
   6180          if (i3 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6181           _abort();
   6182          }
   6183          i4 = i3 + 16 | 0;
   6184          if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
   6185           HEAP32[i4 >> 2] = i22;
   6186          } else {
   6187           HEAP32[i3 + 20 >> 2] = i22;
   6188          }
   6189          if ((i22 | 0) == 0) {
   6190           break;
   6191          }
   6192         }
   6193         if (i22 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6194          _abort();
   6195         }
   6196         HEAP32[i22 + 24 >> 2] = i3;
   6197         i3 = HEAP32[i24 + 16 >> 2] | 0;
   6198         do {
   6199          if ((i3 | 0) != 0) {
   6200           if (i3 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6201            _abort();
   6202           } else {
   6203            HEAP32[i22 + 16 >> 2] = i3;
   6204            HEAP32[i3 + 24 >> 2] = i22;
   6205            break;
   6206           }
   6207          }
   6208         } while (0);
   6209         i3 = HEAP32[i24 + 20 >> 2] | 0;
   6210         if ((i3 | 0) != 0) {
   6211          if (i3 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6212           _abort();
   6213          } else {
   6214           HEAP32[i22 + 20 >> 2] = i3;
   6215           HEAP32[i3 + 24 >> 2] = i22;
   6216           break;
   6217          }
   6218         }
   6219        }
   6220       } while (0);
   6221       L204 : do {
   6222        if (!(i25 >>> 0 < 16)) {
   6223         HEAP32[i24 + 4 >> 2] = i12 | 3;
   6224         HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1;
   6225         HEAP32[i24 + (i25 + i12) >> 2] = i25;
   6226         i4 = i25 >>> 3;
   6227         if (i25 >>> 0 < 256) {
   6228          i6 = i4 << 1;
   6229          i3 = 80 + (i6 << 2) | 0;
   6230          i5 = HEAP32[10] | 0;
   6231          i4 = 1 << i4;
   6232          if ((i5 & i4 | 0) != 0) {
   6233           i5 = 80 + (i6 + 2 << 2) | 0;
   6234           i4 = HEAP32[i5 >> 2] | 0;
   6235           if (i4 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6236            _abort();
   6237           } else {
   6238            i21 = i5;
   6239            i20 = i4;
   6240           }
   6241          } else {
   6242           HEAP32[10] = i5 | i4;
   6243           i21 = 80 + (i6 + 2 << 2) | 0;
   6244           i20 = i3;
   6245          }
   6246          HEAP32[i21 >> 2] = i2;
   6247          HEAP32[i20 + 12 >> 2] = i2;
   6248          HEAP32[i24 + (i12 + 8) >> 2] = i20;
   6249          HEAP32[i24 + (i12 + 12) >> 2] = i3;
   6250          break;
   6251         }
   6252         i3 = i25 >>> 8;
   6253         if ((i3 | 0) != 0) {
   6254          if (i25 >>> 0 > 16777215) {
   6255           i3 = 31;
   6256          } else {
   6257           i31 = (i3 + 1048320 | 0) >>> 16 & 8;
   6258           i32 = i3 << i31;
   6259           i30 = (i32 + 520192 | 0) >>> 16 & 4;
   6260           i32 = i32 << i30;
   6261           i3 = (i32 + 245760 | 0) >>> 16 & 2;
   6262           i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
   6263           i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1;
   6264          }
   6265         } else {
   6266          i3 = 0;
   6267         }
   6268         i6 = 344 + (i3 << 2) | 0;
   6269         HEAP32[i24 + (i12 + 28) >> 2] = i3;
   6270         HEAP32[i24 + (i12 + 20) >> 2] = 0;
   6271         HEAP32[i24 + (i12 + 16) >> 2] = 0;
   6272         i4 = HEAP32[44 >> 2] | 0;
   6273         i5 = 1 << i3;
   6274         if ((i4 & i5 | 0) == 0) {
   6275          HEAP32[44 >> 2] = i4 | i5;
   6276          HEAP32[i6 >> 2] = i2;
   6277          HEAP32[i24 + (i12 + 24) >> 2] = i6;
   6278          HEAP32[i24 + (i12 + 12) >> 2] = i2;
   6279          HEAP32[i24 + (i12 + 8) >> 2] = i2;
   6280          break;
   6281         }
   6282         i4 = HEAP32[i6 >> 2] | 0;
   6283         if ((i3 | 0) == 31) {
   6284          i3 = 0;
   6285         } else {
   6286          i3 = 25 - (i3 >>> 1) | 0;
   6287         }
   6288         L225 : do {
   6289          if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) {
   6290           i3 = i25 << i3;
   6291           while (1) {
   6292            i6 = i4 + (i3 >>> 31 << 2) + 16 | 0;
   6293            i5 = HEAP32[i6 >> 2] | 0;
   6294            if ((i5 | 0) == 0) {
   6295             break;
   6296            }
   6297            if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) {
   6298             i18 = i5;
   6299             break L225;
   6300            } else {
   6301             i3 = i3 << 1;
   6302             i4 = i5;
   6303            }
   6304           }
   6305           if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6306            _abort();
   6307           } else {
   6308            HEAP32[i6 >> 2] = i2;
   6309            HEAP32[i24 + (i12 + 24) >> 2] = i4;
   6310            HEAP32[i24 + (i12 + 12) >> 2] = i2;
   6311            HEAP32[i24 + (i12 + 8) >> 2] = i2;
   6312            break L204;
   6313           }
   6314          } else {
   6315           i18 = i4;
   6316          }
   6317         } while (0);
   6318         i4 = i18 + 8 | 0;
   6319         i3 = HEAP32[i4 >> 2] | 0;
   6320         i5 = HEAP32[56 >> 2] | 0;
   6321         if (i18 >>> 0 < i5 >>> 0) {
   6322          _abort();
   6323         }
   6324         if (i3 >>> 0 < i5 >>> 0) {
   6325          _abort();
   6326         } else {
   6327          HEAP32[i3 + 12 >> 2] = i2;
   6328          HEAP32[i4 >> 2] = i2;
   6329          HEAP32[i24 + (i12 + 8) >> 2] = i3;
   6330          HEAP32[i24 + (i12 + 12) >> 2] = i18;
   6331          HEAP32[i24 + (i12 + 24) >> 2] = 0;
   6332          break;
   6333         }
   6334        } else {
   6335         i32 = i25 + i12 | 0;
   6336         HEAP32[i24 + 4 >> 2] = i32 | 3;
   6337         i32 = i24 + (i32 + 4) | 0;
   6338         HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
   6339        }
   6340       } while (0);
   6341       i32 = i24 + 8 | 0;
   6342       STACKTOP = i1;
   6343       return i32 | 0;
   6344      }
   6345     }
   6346    } else {
   6347     i12 = -1;
   6348    }
   6349   }
   6350  } while (0);
   6351  i18 = HEAP32[48 >> 2] | 0;
   6352  if (!(i12 >>> 0 > i18 >>> 0)) {
   6353   i3 = i18 - i12 | 0;
   6354   i2 = HEAP32[60 >> 2] | 0;
   6355   if (i3 >>> 0 > 15) {
   6356    HEAP32[60 >> 2] = i2 + i12;
   6357    HEAP32[48 >> 2] = i3;
   6358    HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1;
   6359    HEAP32[i2 + i18 >> 2] = i3;
   6360    HEAP32[i2 + 4 >> 2] = i12 | 3;
   6361   } else {
   6362    HEAP32[48 >> 2] = 0;
   6363    HEAP32[60 >> 2] = 0;
   6364    HEAP32[i2 + 4 >> 2] = i18 | 3;
   6365    i32 = i2 + (i18 + 4) | 0;
   6366    HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
   6367   }
   6368   i32 = i2 + 8 | 0;
   6369   STACKTOP = i1;
   6370   return i32 | 0;
   6371  }
   6372  i18 = HEAP32[52 >> 2] | 0;
   6373  if (i12 >>> 0 < i18 >>> 0) {
   6374   i31 = i18 - i12 | 0;
   6375   HEAP32[52 >> 2] = i31;
   6376   i32 = HEAP32[64 >> 2] | 0;
   6377   HEAP32[64 >> 2] = i32 + i12;
   6378   HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
   6379   HEAP32[i32 + 4 >> 2] = i12 | 3;
   6380   i32 = i32 + 8 | 0;
   6381   STACKTOP = i1;
   6382   return i32 | 0;
   6383  }
   6384  do {
   6385   if ((HEAP32[128] | 0) == 0) {
   6386    i18 = _sysconf(30) | 0;
   6387    if ((i18 + -1 & i18 | 0) == 0) {
   6388     HEAP32[520 >> 2] = i18;
   6389     HEAP32[516 >> 2] = i18;
   6390     HEAP32[524 >> 2] = -1;
   6391     HEAP32[528 >> 2] = -1;
   6392     HEAP32[532 >> 2] = 0;
   6393     HEAP32[484 >> 2] = 0;
   6394     HEAP32[128] = (_time(0) | 0) & -16 ^ 1431655768;
   6395     break;
   6396    } else {
   6397     _abort();
   6398    }
   6399   }
   6400  } while (0);
   6401  i20 = i12 + 48 | 0;
   6402  i25 = HEAP32[520 >> 2] | 0;
   6403  i21 = i12 + 47 | 0;
   6404  i22 = i25 + i21 | 0;
   6405  i25 = 0 - i25 | 0;
   6406  i18 = i22 & i25;
   6407  if (!(i18 >>> 0 > i12 >>> 0)) {
   6408   i32 = 0;
   6409   STACKTOP = i1;
   6410   return i32 | 0;
   6411  }
   6412  i24 = HEAP32[480 >> 2] | 0;
   6413  if ((i24 | 0) != 0 ? (i31 = HEAP32[472 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) {
   6414   i32 = 0;
   6415   STACKTOP = i1;
   6416   return i32 | 0;
   6417  }
   6418  L269 : do {
   6419   if ((HEAP32[484 >> 2] & 4 | 0) == 0) {
   6420    i26 = HEAP32[64 >> 2] | 0;
   6421    L271 : do {
   6422     if ((i26 | 0) != 0) {
   6423      i24 = 488 | 0;
   6424      while (1) {
   6425       i27 = HEAP32[i24 >> 2] | 0;
   6426       if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) {
   6427        break;
   6428       }
   6429       i24 = HEAP32[i24 + 8 >> 2] | 0;
   6430       if ((i24 | 0) == 0) {
   6431        i13 = 182;
   6432        break L271;
   6433       }
   6434      }
   6435      if ((i24 | 0) != 0) {
   6436       i25 = i22 - (HEAP32[52 >> 2] | 0) & i25;
   6437       if (i25 >>> 0 < 2147483647) {
   6438        i13 = _sbrk(i25 | 0) | 0;
   6439        i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0);
   6440        i22 = i13;
   6441        i24 = i25;
   6442        i23 = i26 ? i13 : -1;
   6443        i25 = i26 ? i25 : 0;
   6444        i13 = 191;
   6445       } else {
   6446        i25 = 0;
   6447       }
   6448      } else {
   6449       i13 = 182;
   6450      }
   6451     } else {
   6452      i13 = 182;
   6453     }
   6454    } while (0);
   6455    do {
   6456     if ((i13 | 0) == 182) {
   6457      i23 = _sbrk(0) | 0;
   6458      if ((i23 | 0) != (-1 | 0)) {
   6459       i24 = i23;
   6460       i22 = HEAP32[516 >> 2] | 0;
   6461       i25 = i22 + -1 | 0;
   6462       if ((i25 & i24 | 0) == 0) {
   6463        i25 = i18;
   6464       } else {
   6465        i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0;
   6466       }
   6467       i24 = HEAP32[472 >> 2] | 0;
   6468       i26 = i24 + i25 | 0;
   6469       if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) {
   6470        i22 = HEAP32[480 >> 2] | 0;
   6471        if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) {
   6472         i25 = 0;
   6473         break;
   6474        }
   6475        i22 = _sbrk(i25 | 0) | 0;
   6476        i13 = (i22 | 0) == (i23 | 0);
   6477        i24 = i25;
   6478        i23 = i13 ? i23 : -1;
   6479        i25 = i13 ? i25 : 0;
   6480        i13 = 191;
   6481       } else {
   6482        i25 = 0;
   6483       }
   6484      } else {
   6485       i25 = 0;
   6486      }
   6487     }
   6488    } while (0);
   6489    L291 : do {
   6490     if ((i13 | 0) == 191) {
   6491      i13 = 0 - i24 | 0;
   6492      if ((i23 | 0) != (-1 | 0)) {
   6493       i17 = i23;
   6494       i14 = i25;
   6495       i13 = 202;
   6496       break L269;
   6497      }
   6498      do {
   6499       if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[520 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) {
   6500        if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) {
   6501         _sbrk(i13 | 0) | 0;
   6502         break L291;
   6503        } else {
   6504         i24 = i19 + i24 | 0;
   6505         break;
   6506        }
   6507       }
   6508      } while (0);
   6509      if ((i22 | 0) != (-1 | 0)) {
   6510       i17 = i22;
   6511       i14 = i24;
   6512       i13 = 202;
   6513       break L269;
   6514      }
   6515     }
   6516    } while (0);
   6517    HEAP32[484 >> 2] = HEAP32[484 >> 2] | 4;
   6518    i13 = 199;
   6519   } else {
   6520    i25 = 0;
   6521    i13 = 199;
   6522   }
   6523  } while (0);
   6524  if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) {
   6525   i14 = i14 ? i15 : i25;
   6526   i13 = 202;
   6527  }
   6528  if ((i13 | 0) == 202) {
   6529   i15 = (HEAP32[472 >> 2] | 0) + i14 | 0;
   6530   HEAP32[472 >> 2] = i15;
   6531   if (i15 >>> 0 > (HEAP32[476 >> 2] | 0) >>> 0) {
   6532    HEAP32[476 >> 2] = i15;
   6533   }
   6534   i15 = HEAP32[64 >> 2] | 0;
   6535   L311 : do {
   6536    if ((i15 | 0) != 0) {
   6537     i21 = 488 | 0;
   6538     while (1) {
   6539      i16 = HEAP32[i21 >> 2] | 0;
   6540      i19 = i21 + 4 | 0;
   6541      i20 = HEAP32[i19 >> 2] | 0;
   6542      if ((i17 | 0) == (i16 + i20 | 0)) {
   6543       i13 = 214;
   6544       break;
   6545      }
   6546      i18 = HEAP32[i21 + 8 >> 2] | 0;
   6547      if ((i18 | 0) == 0) {
   6548       break;
   6549      } else {
   6550       i21 = i18;
   6551      }
   6552     }
   6553     if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) {
   6554      HEAP32[i19 >> 2] = i20 + i14;
   6555      i2 = (HEAP32[52 >> 2] | 0) + i14 | 0;
   6556      i3 = i15 + 8 | 0;
   6557      if ((i3 & 7 | 0) == 0) {
   6558       i3 = 0;
   6559      } else {
   6560       i3 = 0 - i3 & 7;
   6561      }
   6562      i32 = i2 - i3 | 0;
   6563      HEAP32[64 >> 2] = i15 + i3;
   6564      HEAP32[52 >> 2] = i32;
   6565      HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1;
   6566      HEAP32[i15 + (i2 + 4) >> 2] = 40;
   6567      HEAP32[68 >> 2] = HEAP32[528 >> 2];
   6568      break;
   6569     }
   6570     if (i17 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6571      HEAP32[56 >> 2] = i17;
   6572     }
   6573     i19 = i17 + i14 | 0;
   6574     i16 = 488 | 0;
   6575     while (1) {
   6576      if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) {
   6577       i13 = 224;
   6578       break;
   6579      }
   6580      i18 = HEAP32[i16 + 8 >> 2] | 0;
   6581      if ((i18 | 0) == 0) {
   6582       break;
   6583      } else {
   6584       i16 = i18;
   6585      }
   6586     }
   6587     if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) {
   6588      HEAP32[i16 >> 2] = i17;
   6589      i6 = i16 + 4 | 0;
   6590      HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14;
   6591      i6 = i17 + 8 | 0;
   6592      if ((i6 & 7 | 0) == 0) {
   6593       i6 = 0;
   6594      } else {
   6595       i6 = 0 - i6 & 7;
   6596      }
   6597      i7 = i17 + (i14 + 8) | 0;
   6598      if ((i7 & 7 | 0) == 0) {
   6599       i13 = 0;
   6600      } else {
   6601       i13 = 0 - i7 & 7;
   6602      }
   6603      i15 = i17 + (i13 + i14) | 0;
   6604      i8 = i6 + i12 | 0;
   6605      i7 = i17 + i8 | 0;
   6606      i10 = i15 - (i17 + i6) - i12 | 0;
   6607      HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3;
   6608      L348 : do {
   6609       if ((i15 | 0) != (HEAP32[64 >> 2] | 0)) {
   6610        if ((i15 | 0) == (HEAP32[60 >> 2] | 0)) {
   6611         i32 = (HEAP32[48 >> 2] | 0) + i10 | 0;
   6612         HEAP32[48 >> 2] = i32;
   6613         HEAP32[60 >> 2] = i7;
   6614         HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
   6615         HEAP32[i17 + (i32 + i8) >> 2] = i32;
   6616         break;
   6617        }
   6618        i12 = i14 + 4 | 0;
   6619        i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0;
   6620        if ((i18 & 3 | 0) == 1) {
   6621         i11 = i18 & -8;
   6622         i16 = i18 >>> 3;
   6623         do {
   6624          if (!(i18 >>> 0 < 256)) {
   6625           i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0;
   6626           i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
   6627           do {
   6628            if ((i19 | 0) == (i15 | 0)) {
   6629             i19 = i13 | 16;
   6630             i18 = i17 + (i12 + i19) | 0;
   6631             i16 = HEAP32[i18 >> 2] | 0;
   6632             if ((i16 | 0) == 0) {
   6633              i18 = i17 + (i19 + i14) | 0;
   6634              i16 = HEAP32[i18 >> 2] | 0;
   6635              if ((i16 | 0) == 0) {
   6636               i5 = 0;
   6637               break;
   6638              }
   6639             }
   6640             while (1) {
   6641              i20 = i16 + 20 | 0;
   6642              i19 = HEAP32[i20 >> 2] | 0;
   6643              if ((i19 | 0) != 0) {
   6644               i16 = i19;
   6645               i18 = i20;
   6646               continue;
   6647              }
   6648              i19 = i16 + 16 | 0;
   6649              i20 = HEAP32[i19 >> 2] | 0;
   6650              if ((i20 | 0) == 0) {
   6651               break;
   6652              } else {
   6653               i16 = i20;
   6654               i18 = i19;
   6655              }
   6656             }
   6657             if (i18 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6658              _abort();
   6659             } else {
   6660              HEAP32[i18 >> 2] = 0;
   6661              i5 = i16;
   6662              break;
   6663             }
   6664            } else {
   6665             i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
   6666             if (i18 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6667              _abort();
   6668             }
   6669             i16 = i18 + 12 | 0;
   6670             if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) {
   6671              _abort();
   6672             }
   6673             i20 = i19 + 8 | 0;
   6674             if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) {
   6675              HEAP32[i16 >> 2] = i19;
   6676              HEAP32[i20 >> 2] = i18;
   6677              i5 = i19;
   6678              break;
   6679             } else {
   6680              _abort();
   6681             }
   6682            }
   6683           } while (0);
   6684           if ((i9 | 0) != 0) {
   6685            i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0;
   6686            i18 = 344 + (i16 << 2) | 0;
   6687            if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) {
   6688             HEAP32[i18 >> 2] = i5;
   6689             if ((i5 | 0) == 0) {
   6690              HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i16);
   6691              break;
   6692             }
   6693            } else {
   6694             if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6695              _abort();
   6696             }
   6697             i16 = i9 + 16 | 0;
   6698             if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
   6699              HEAP32[i16 >> 2] = i5;
   6700             } else {
   6701              HEAP32[i9 + 20 >> 2] = i5;
   6702             }
   6703             if ((i5 | 0) == 0) {
   6704              break;
   6705             }
   6706            }
   6707            if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6708             _abort();
   6709            }
   6710            HEAP32[i5 + 24 >> 2] = i9;
   6711            i15 = i13 | 16;
   6712            i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0;
   6713            do {
   6714             if ((i9 | 0) != 0) {
   6715              if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6716               _abort();
   6717              } else {
   6718               HEAP32[i5 + 16 >> 2] = i9;
   6719               HEAP32[i9 + 24 >> 2] = i5;
   6720               break;
   6721              }
   6722             }
   6723            } while (0);
   6724            i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0;
   6725            if ((i9 | 0) != 0) {
   6726             if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6727              _abort();
   6728             } else {
   6729              HEAP32[i5 + 20 >> 2] = i9;
   6730              HEAP32[i9 + 24 >> 2] = i5;
   6731              break;
   6732             }
   6733            }
   6734           }
   6735          } else {
   6736           i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
   6737           i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
   6738           i18 = 80 + (i16 << 1 << 2) | 0;
   6739           if ((i5 | 0) != (i18 | 0)) {
   6740            if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6741             _abort();
   6742            }
   6743            if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) {
   6744             _abort();
   6745            }
   6746           }
   6747           if ((i12 | 0) == (i5 | 0)) {
   6748            HEAP32[10] = HEAP32[10] & ~(1 << i16);
   6749            break;
   6750           }
   6751           if ((i12 | 0) != (i18 | 0)) {
   6752            if (i12 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6753             _abort();
   6754            }
   6755            i16 = i12 + 8 | 0;
   6756            if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
   6757             i9 = i16;
   6758            } else {
   6759             _abort();
   6760            }
   6761           } else {
   6762            i9 = i12 + 8 | 0;
   6763           }
   6764           HEAP32[i5 + 12 >> 2] = i12;
   6765           HEAP32[i9 >> 2] = i5;
   6766          }
   6767         } while (0);
   6768         i15 = i17 + ((i11 | i13) + i14) | 0;
   6769         i10 = i11 + i10 | 0;
   6770        }
   6771        i5 = i15 + 4 | 0;
   6772        HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2;
   6773        HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1;
   6774        HEAP32[i17 + (i10 + i8) >> 2] = i10;
   6775        i5 = i10 >>> 3;
   6776        if (i10 >>> 0 < 256) {
   6777         i10 = i5 << 1;
   6778         i2 = 80 + (i10 << 2) | 0;
   6779         i9 = HEAP32[10] | 0;
   6780         i5 = 1 << i5;
   6781         if ((i9 & i5 | 0) != 0) {
   6782          i9 = 80 + (i10 + 2 << 2) | 0;
   6783          i5 = HEAP32[i9 >> 2] | 0;
   6784          if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6785           _abort();
   6786          } else {
   6787           i3 = i9;
   6788           i4 = i5;
   6789          }
   6790         } else {
   6791          HEAP32[10] = i9 | i5;
   6792          i3 = 80 + (i10 + 2 << 2) | 0;
   6793          i4 = i2;
   6794         }
   6795         HEAP32[i3 >> 2] = i7;
   6796         HEAP32[i4 + 12 >> 2] = i7;
   6797         HEAP32[i17 + (i8 + 8) >> 2] = i4;
   6798         HEAP32[i17 + (i8 + 12) >> 2] = i2;
   6799         break;
   6800        }
   6801        i3 = i10 >>> 8;
   6802        if ((i3 | 0) != 0) {
   6803         if (i10 >>> 0 > 16777215) {
   6804          i3 = 31;
   6805         } else {
   6806          i31 = (i3 + 1048320 | 0) >>> 16 & 8;
   6807          i32 = i3 << i31;
   6808          i30 = (i32 + 520192 | 0) >>> 16 & 4;
   6809          i32 = i32 << i30;
   6810          i3 = (i32 + 245760 | 0) >>> 16 & 2;
   6811          i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
   6812          i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1;
   6813         }
   6814        } else {
   6815         i3 = 0;
   6816        }
   6817        i4 = 344 + (i3 << 2) | 0;
   6818        HEAP32[i17 + (i8 + 28) >> 2] = i3;
   6819        HEAP32[i17 + (i8 + 20) >> 2] = 0;
   6820        HEAP32[i17 + (i8 + 16) >> 2] = 0;
   6821        i9 = HEAP32[44 >> 2] | 0;
   6822        i5 = 1 << i3;
   6823        if ((i9 & i5 | 0) == 0) {
   6824         HEAP32[44 >> 2] = i9 | i5;
   6825         HEAP32[i4 >> 2] = i7;
   6826         HEAP32[i17 + (i8 + 24) >> 2] = i4;
   6827         HEAP32[i17 + (i8 + 12) >> 2] = i7;
   6828         HEAP32[i17 + (i8 + 8) >> 2] = i7;
   6829         break;
   6830        }
   6831        i4 = HEAP32[i4 >> 2] | 0;
   6832        if ((i3 | 0) == 31) {
   6833         i3 = 0;
   6834        } else {
   6835         i3 = 25 - (i3 >>> 1) | 0;
   6836        }
   6837        L444 : do {
   6838         if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) {
   6839          i3 = i10 << i3;
   6840          while (1) {
   6841           i5 = i4 + (i3 >>> 31 << 2) + 16 | 0;
   6842           i9 = HEAP32[i5 >> 2] | 0;
   6843           if ((i9 | 0) == 0) {
   6844            break;
   6845           }
   6846           if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) {
   6847            i2 = i9;
   6848            break L444;
   6849           } else {
   6850            i3 = i3 << 1;
   6851            i4 = i9;
   6852           }
   6853          }
   6854          if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6855           _abort();
   6856          } else {
   6857           HEAP32[i5 >> 2] = i7;
   6858           HEAP32[i17 + (i8 + 24) >> 2] = i4;
   6859           HEAP32[i17 + (i8 + 12) >> 2] = i7;
   6860           HEAP32[i17 + (i8 + 8) >> 2] = i7;
   6861           break L348;
   6862          }
   6863         } else {
   6864          i2 = i4;
   6865         }
   6866        } while (0);
   6867        i4 = i2 + 8 | 0;
   6868        i3 = HEAP32[i4 >> 2] | 0;
   6869        i5 = HEAP32[56 >> 2] | 0;
   6870        if (i2 >>> 0 < i5 >>> 0) {
   6871         _abort();
   6872        }
   6873        if (i3 >>> 0 < i5 >>> 0) {
   6874         _abort();
   6875        } else {
   6876         HEAP32[i3 + 12 >> 2] = i7;
   6877         HEAP32[i4 >> 2] = i7;
   6878         HEAP32[i17 + (i8 + 8) >> 2] = i3;
   6879         HEAP32[i17 + (i8 + 12) >> 2] = i2;
   6880         HEAP32[i17 + (i8 + 24) >> 2] = 0;
   6881         break;
   6882        }
   6883       } else {
   6884        i32 = (HEAP32[52 >> 2] | 0) + i10 | 0;
   6885        HEAP32[52 >> 2] = i32;
   6886        HEAP32[64 >> 2] = i7;
   6887        HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
   6888       }
   6889      } while (0);
   6890      i32 = i17 + (i6 | 8) | 0;
   6891      STACKTOP = i1;
   6892      return i32 | 0;
   6893     }
   6894     i3 = 488 | 0;
   6895     while (1) {
   6896      i2 = HEAP32[i3 >> 2] | 0;
   6897      if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) {
   6898       break;
   6899      }
   6900      i3 = HEAP32[i3 + 8 >> 2] | 0;
   6901     }
   6902     i3 = i2 + (i11 + -39) | 0;
   6903     if ((i3 & 7 | 0) == 0) {
   6904      i3 = 0;
   6905     } else {
   6906      i3 = 0 - i3 & 7;
   6907     }
   6908     i2 = i2 + (i11 + -47 + i3) | 0;
   6909     i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2;
   6910     i3 = i2 + 8 | 0;
   6911     i4 = i17 + 8 | 0;
   6912     if ((i4 & 7 | 0) == 0) {
   6913      i4 = 0;
   6914     } else {
   6915      i4 = 0 - i4 & 7;
   6916     }
   6917     i32 = i14 + -40 - i4 | 0;
   6918     HEAP32[64 >> 2] = i17 + i4;
   6919     HEAP32[52 >> 2] = i32;
   6920     HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1;
   6921     HEAP32[i17 + (i14 + -36) >> 2] = 40;
   6922     HEAP32[68 >> 2] = HEAP32[528 >> 2];
   6923     HEAP32[i2 + 4 >> 2] = 27;
   6924     HEAP32[i3 + 0 >> 2] = HEAP32[488 >> 2];
   6925     HEAP32[i3 + 4 >> 2] = HEAP32[492 >> 2];
   6926     HEAP32[i3 + 8 >> 2] = HEAP32[496 >> 2];
   6927     HEAP32[i3 + 12 >> 2] = HEAP32[500 >> 2];
   6928     HEAP32[488 >> 2] = i17;
   6929     HEAP32[492 >> 2] = i14;
   6930     HEAP32[500 >> 2] = 0;
   6931     HEAP32[496 >> 2] = i3;
   6932     i4 = i2 + 28 | 0;
   6933     HEAP32[i4 >> 2] = 7;
   6934     if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) {
   6935      while (1) {
   6936       i3 = i4 + 4 | 0;
   6937       HEAP32[i3 >> 2] = 7;
   6938       if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) {
   6939        i4 = i3;
   6940       } else {
   6941        break;
   6942       }
   6943      }
   6944     }
   6945     if ((i2 | 0) != (i15 | 0)) {
   6946      i2 = i2 - i15 | 0;
   6947      i3 = i15 + (i2 + 4) | 0;
   6948      HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2;
   6949      HEAP32[i15 + 4 >> 2] = i2 | 1;
   6950      HEAP32[i15 + i2 >> 2] = i2;
   6951      i3 = i2 >>> 3;
   6952      if (i2 >>> 0 < 256) {
   6953       i4 = i3 << 1;
   6954       i2 = 80 + (i4 << 2) | 0;
   6955       i5 = HEAP32[10] | 0;
   6956       i3 = 1 << i3;
   6957       if ((i5 & i3 | 0) != 0) {
   6958        i4 = 80 + (i4 + 2 << 2) | 0;
   6959        i3 = HEAP32[i4 >> 2] | 0;
   6960        if (i3 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   6961         _abort();
   6962        } else {
   6963         i7 = i4;
   6964         i8 = i3;
   6965        }
   6966       } else {
   6967        HEAP32[10] = i5 | i3;
   6968        i7 = 80 + (i4 + 2 << 2) | 0;
   6969        i8 = i2;
   6970       }
   6971       HEAP32[i7 >> 2] = i15;
   6972       HEAP32[i8 + 12 >> 2] = i15;
   6973       HEAP32[i15 + 8 >> 2] = i8;
   6974       HEAP32[i15 + 12 >> 2] = i2;
   6975       break;
   6976      }
   6977      i3 = i2 >>> 8;
   6978      if ((i3 | 0) != 0) {
   6979       if (i2 >>> 0 > 16777215) {
   6980        i3 = 31;
   6981       } else {
   6982        i31 = (i3 + 1048320 | 0) >>> 16 & 8;
   6983        i32 = i3 << i31;
   6984        i30 = (i32 + 520192 | 0) >>> 16 & 4;
   6985        i32 = i32 << i30;
   6986        i3 = (i32 + 245760 | 0) >>> 16 & 2;
   6987        i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
   6988        i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1;
   6989       }
   6990      } else {
   6991       i3 = 0;
   6992      }
   6993      i7 = 344 + (i3 << 2) | 0;
   6994      HEAP32[i15 + 28 >> 2] = i3;
   6995      HEAP32[i15 + 20 >> 2] = 0;
   6996      HEAP32[i15 + 16 >> 2] = 0;
   6997      i4 = HEAP32[44 >> 2] | 0;
   6998      i5 = 1 << i3;
   6999      if ((i4 & i5 | 0) == 0) {
   7000       HEAP32[44 >> 2] = i4 | i5;
   7001       HEAP32[i7 >> 2] = i15;
   7002       HEAP32[i15 + 24 >> 2] = i7;
   7003       HEAP32[i15 + 12 >> 2] = i15;
   7004       HEAP32[i15 + 8 >> 2] = i15;
   7005       break;
   7006      }
   7007      i4 = HEAP32[i7 >> 2] | 0;
   7008      if ((i3 | 0) == 31) {
   7009       i3 = 0;
   7010      } else {
   7011       i3 = 25 - (i3 >>> 1) | 0;
   7012      }
   7013      L499 : do {
   7014       if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) {
   7015        i3 = i2 << i3;
   7016        while (1) {
   7017         i7 = i4 + (i3 >>> 31 << 2) + 16 | 0;
   7018         i5 = HEAP32[i7 >> 2] | 0;
   7019         if ((i5 | 0) == 0) {
   7020          break;
   7021         }
   7022         if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) {
   7023          i6 = i5;
   7024          break L499;
   7025         } else {
   7026          i3 = i3 << 1;
   7027          i4 = i5;
   7028         }
   7029        }
   7030        if (i7 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7031         _abort();
   7032        } else {
   7033         HEAP32[i7 >> 2] = i15;
   7034         HEAP32[i15 + 24 >> 2] = i4;
   7035         HEAP32[i15 + 12 >> 2] = i15;
   7036         HEAP32[i15 + 8 >> 2] = i15;
   7037         break L311;
   7038        }
   7039       } else {
   7040        i6 = i4;
   7041       }
   7042      } while (0);
   7043      i4 = i6 + 8 | 0;
   7044      i3 = HEAP32[i4 >> 2] | 0;
   7045      i2 = HEAP32[56 >> 2] | 0;
   7046      if (i6 >>> 0 < i2 >>> 0) {
   7047       _abort();
   7048      }
   7049      if (i3 >>> 0 < i2 >>> 0) {
   7050       _abort();
   7051      } else {
   7052       HEAP32[i3 + 12 >> 2] = i15;
   7053       HEAP32[i4 >> 2] = i15;
   7054       HEAP32[i15 + 8 >> 2] = i3;
   7055       HEAP32[i15 + 12 >> 2] = i6;
   7056       HEAP32[i15 + 24 >> 2] = 0;
   7057       break;
   7058      }
   7059     }
   7060    } else {
   7061     i32 = HEAP32[56 >> 2] | 0;
   7062     if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) {
   7063      HEAP32[56 >> 2] = i17;
   7064     }
   7065     HEAP32[488 >> 2] = i17;
   7066     HEAP32[492 >> 2] = i14;
   7067     HEAP32[500 >> 2] = 0;
   7068     HEAP32[76 >> 2] = HEAP32[128];
   7069     HEAP32[72 >> 2] = -1;
   7070     i2 = 0;
   7071     do {
   7072      i32 = i2 << 1;
   7073      i31 = 80 + (i32 << 2) | 0;
   7074      HEAP32[80 + (i32 + 3 << 2) >> 2] = i31;
   7075      HEAP32[80 + (i32 + 2 << 2) >> 2] = i31;
   7076      i2 = i2 + 1 | 0;
   7077     } while ((i2 | 0) != 32);
   7078     i2 = i17 + 8 | 0;
   7079     if ((i2 & 7 | 0) == 0) {
   7080      i2 = 0;
   7081     } else {
   7082      i2 = 0 - i2 & 7;
   7083     }
   7084     i32 = i14 + -40 - i2 | 0;
   7085     HEAP32[64 >> 2] = i17 + i2;
   7086     HEAP32[52 >> 2] = i32;
   7087     HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1;
   7088     HEAP32[i17 + (i14 + -36) >> 2] = 40;
   7089     HEAP32[68 >> 2] = HEAP32[528 >> 2];
   7090    }
   7091   } while (0);
   7092   i2 = HEAP32[52 >> 2] | 0;
   7093   if (i2 >>> 0 > i12 >>> 0) {
   7094    i31 = i2 - i12 | 0;
   7095    HEAP32[52 >> 2] = i31;
   7096    i32 = HEAP32[64 >> 2] | 0;
   7097    HEAP32[64 >> 2] = i32 + i12;
   7098    HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
   7099    HEAP32[i32 + 4 >> 2] = i12 | 3;
   7100    i32 = i32 + 8 | 0;
   7101    STACKTOP = i1;
   7102    return i32 | 0;
   7103   }
   7104  }
   7105  HEAP32[(___errno_location() | 0) >> 2] = 12;
   7106  i32 = 0;
   7107  STACKTOP = i1;
   7108  return i32 | 0;
   7109 }
   7110 function _free(i7) {
   7111  i7 = i7 | 0;
   7112  var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
   7113  i1 = STACKTOP;
   7114  if ((i7 | 0) == 0) {
   7115   STACKTOP = i1;
   7116   return;
   7117  }
   7118  i15 = i7 + -8 | 0;
   7119  i16 = HEAP32[56 >> 2] | 0;
   7120  if (i15 >>> 0 < i16 >>> 0) {
   7121   _abort();
   7122  }
   7123  i13 = HEAP32[i7 + -4 >> 2] | 0;
   7124  i12 = i13 & 3;
   7125  if ((i12 | 0) == 1) {
   7126   _abort();
   7127  }
   7128  i8 = i13 & -8;
   7129  i6 = i7 + (i8 + -8) | 0;
   7130  do {
   7131   if ((i13 & 1 | 0) == 0) {
   7132    i19 = HEAP32[i15 >> 2] | 0;
   7133    if ((i12 | 0) == 0) {
   7134     STACKTOP = i1;
   7135     return;
   7136    }
   7137    i15 = -8 - i19 | 0;
   7138    i13 = i7 + i15 | 0;
   7139    i12 = i19 + i8 | 0;
   7140    if (i13 >>> 0 < i16 >>> 0) {
   7141     _abort();
   7142    }
   7143    if ((i13 | 0) == (HEAP32[60 >> 2] | 0)) {
   7144     i2 = i7 + (i8 + -4) | 0;
   7145     if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
   7146      i2 = i13;
   7147      i11 = i12;
   7148      break;
   7149     }
   7150     HEAP32[48 >> 2] = i12;
   7151     HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
   7152     HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1;
   7153     HEAP32[i6 >> 2] = i12;
   7154     STACKTOP = i1;
   7155     return;
   7156    }
   7157    i18 = i19 >>> 3;
   7158    if (i19 >>> 0 < 256) {
   7159     i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
   7160     i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
   7161     i14 = 80 + (i18 << 1 << 2) | 0;
   7162     if ((i2 | 0) != (i14 | 0)) {
   7163      if (i2 >>> 0 < i16 >>> 0) {
   7164       _abort();
   7165      }
   7166      if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) {
   7167       _abort();
   7168      }
   7169     }
   7170     if ((i11 | 0) == (i2 | 0)) {
   7171      HEAP32[10] = HEAP32[10] & ~(1 << i18);
   7172      i2 = i13;
   7173      i11 = i12;
   7174      break;
   7175     }
   7176     if ((i11 | 0) != (i14 | 0)) {
   7177      if (i11 >>> 0 < i16 >>> 0) {
   7178       _abort();
   7179      }
   7180      i14 = i11 + 8 | 0;
   7181      if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) {
   7182       i17 = i14;
   7183      } else {
   7184       _abort();
   7185      }
   7186     } else {
   7187      i17 = i11 + 8 | 0;
   7188     }
   7189     HEAP32[i2 + 12 >> 2] = i11;
   7190     HEAP32[i17 >> 2] = i2;
   7191     i2 = i13;
   7192     i11 = i12;
   7193     break;
   7194    }
   7195    i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0;
   7196    i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
   7197    do {
   7198     if ((i18 | 0) == (i13 | 0)) {
   7199      i19 = i7 + (i15 + 20) | 0;
   7200      i18 = HEAP32[i19 >> 2] | 0;
   7201      if ((i18 | 0) == 0) {
   7202       i19 = i7 + (i15 + 16) | 0;
   7203       i18 = HEAP32[i19 >> 2] | 0;
   7204       if ((i18 | 0) == 0) {
   7205        i14 = 0;
   7206        break;
   7207       }
   7208      }
   7209      while (1) {
   7210       i21 = i18 + 20 | 0;
   7211       i20 = HEAP32[i21 >> 2] | 0;
   7212       if ((i20 | 0) != 0) {
   7213        i18 = i20;
   7214        i19 = i21;
   7215        continue;
   7216       }
   7217       i20 = i18 + 16 | 0;
   7218       i21 = HEAP32[i20 >> 2] | 0;
   7219       if ((i21 | 0) == 0) {
   7220        break;
   7221       } else {
   7222        i18 = i21;
   7223        i19 = i20;
   7224       }
   7225      }
   7226      if (i19 >>> 0 < i16 >>> 0) {
   7227       _abort();
   7228      } else {
   7229       HEAP32[i19 >> 2] = 0;
   7230       i14 = i18;
   7231       break;
   7232      }
   7233     } else {
   7234      i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
   7235      if (i19 >>> 0 < i16 >>> 0) {
   7236       _abort();
   7237      }
   7238      i16 = i19 + 12 | 0;
   7239      if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) {
   7240       _abort();
   7241      }
   7242      i20 = i18 + 8 | 0;
   7243      if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) {
   7244       HEAP32[i16 >> 2] = i18;
   7245       HEAP32[i20 >> 2] = i19;
   7246       i14 = i18;
   7247       break;
   7248      } else {
   7249       _abort();
   7250      }
   7251     }
   7252    } while (0);
   7253    if ((i17 | 0) != 0) {
   7254     i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0;
   7255     i16 = 344 + (i18 << 2) | 0;
   7256     if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) {
   7257      HEAP32[i16 >> 2] = i14;
   7258      if ((i14 | 0) == 0) {
   7259       HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i18);
   7260       i2 = i13;
   7261       i11 = i12;
   7262       break;
   7263      }
   7264     } else {
   7265      if (i17 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7266       _abort();
   7267      }
   7268      i16 = i17 + 16 | 0;
   7269      if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) {
   7270       HEAP32[i16 >> 2] = i14;
   7271      } else {
   7272       HEAP32[i17 + 20 >> 2] = i14;
   7273      }
   7274      if ((i14 | 0) == 0) {
   7275       i2 = i13;
   7276       i11 = i12;
   7277       break;
   7278      }
   7279     }
   7280     if (i14 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7281      _abort();
   7282     }
   7283     HEAP32[i14 + 24 >> 2] = i17;
   7284     i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0;
   7285     do {
   7286      if ((i16 | 0) != 0) {
   7287       if (i16 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7288        _abort();
   7289       } else {
   7290        HEAP32[i14 + 16 >> 2] = i16;
   7291        HEAP32[i16 + 24 >> 2] = i14;
   7292        break;
   7293       }
   7294      }
   7295     } while (0);
   7296     i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0;
   7297     if ((i15 | 0) != 0) {
   7298      if (i15 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7299       _abort();
   7300      } else {
   7301       HEAP32[i14 + 20 >> 2] = i15;
   7302       HEAP32[i15 + 24 >> 2] = i14;
   7303       i2 = i13;
   7304       i11 = i12;
   7305       break;
   7306      }
   7307     } else {
   7308      i2 = i13;
   7309      i11 = i12;
   7310     }
   7311    } else {
   7312     i2 = i13;
   7313     i11 = i12;
   7314    }
   7315   } else {
   7316    i2 = i15;
   7317    i11 = i8;
   7318   }
   7319  } while (0);
   7320  if (!(i2 >>> 0 < i6 >>> 0)) {
   7321   _abort();
   7322  }
   7323  i12 = i7 + (i8 + -4) | 0;
   7324  i13 = HEAP32[i12 >> 2] | 0;
   7325  if ((i13 & 1 | 0) == 0) {
   7326   _abort();
   7327  }
   7328  if ((i13 & 2 | 0) == 0) {
   7329   if ((i6 | 0) == (HEAP32[64 >> 2] | 0)) {
   7330    i21 = (HEAP32[52 >> 2] | 0) + i11 | 0;
   7331    HEAP32[52 >> 2] = i21;
   7332    HEAP32[64 >> 2] = i2;
   7333    HEAP32[i2 + 4 >> 2] = i21 | 1;
   7334    if ((i2 | 0) != (HEAP32[60 >> 2] | 0)) {
   7335     STACKTOP = i1;
   7336     return;
   7337    }
   7338    HEAP32[60 >> 2] = 0;
   7339    HEAP32[48 >> 2] = 0;
   7340    STACKTOP = i1;
   7341    return;
   7342   }
   7343   if ((i6 | 0) == (HEAP32[60 >> 2] | 0)) {
   7344    i21 = (HEAP32[48 >> 2] | 0) + i11 | 0;
   7345    HEAP32[48 >> 2] = i21;
   7346    HEAP32[60 >> 2] = i2;
   7347    HEAP32[i2 + 4 >> 2] = i21 | 1;
   7348    HEAP32[i2 + i21 >> 2] = i21;
   7349    STACKTOP = i1;
   7350    return;
   7351   }
   7352   i11 = (i13 & -8) + i11 | 0;
   7353   i12 = i13 >>> 3;
   7354   do {
   7355    if (!(i13 >>> 0 < 256)) {
   7356     i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0;
   7357     i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
   7358     do {
   7359      if ((i15 | 0) == (i6 | 0)) {
   7360       i13 = i7 + (i8 + 12) | 0;
   7361       i12 = HEAP32[i13 >> 2] | 0;
   7362       if ((i12 | 0) == 0) {
   7363        i13 = i7 + (i8 + 8) | 0;
   7364        i12 = HEAP32[i13 >> 2] | 0;
   7365        if ((i12 | 0) == 0) {
   7366         i9 = 0;
   7367         break;
   7368        }
   7369       }
   7370       while (1) {
   7371        i14 = i12 + 20 | 0;
   7372        i15 = HEAP32[i14 >> 2] | 0;
   7373        if ((i15 | 0) != 0) {
   7374         i12 = i15;
   7375         i13 = i14;
   7376         continue;
   7377        }
   7378        i14 = i12 + 16 | 0;
   7379        i15 = HEAP32[i14 >> 2] | 0;
   7380        if ((i15 | 0) == 0) {
   7381         break;
   7382        } else {
   7383         i12 = i15;
   7384         i13 = i14;
   7385        }
   7386       }
   7387       if (i13 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7388        _abort();
   7389       } else {
   7390        HEAP32[i13 >> 2] = 0;
   7391        i9 = i12;
   7392        break;
   7393       }
   7394      } else {
   7395       i13 = HEAP32[i7 + i8 >> 2] | 0;
   7396       if (i13 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7397        _abort();
   7398       }
   7399       i14 = i13 + 12 | 0;
   7400       if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) {
   7401        _abort();
   7402       }
   7403       i12 = i15 + 8 | 0;
   7404       if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
   7405        HEAP32[i14 >> 2] = i15;
   7406        HEAP32[i12 >> 2] = i13;
   7407        i9 = i15;
   7408        break;
   7409       } else {
   7410        _abort();
   7411       }
   7412      }
   7413     } while (0);
   7414     if ((i10 | 0) != 0) {
   7415      i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0;
   7416      i13 = 344 + (i12 << 2) | 0;
   7417      if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) {
   7418       HEAP32[i13 >> 2] = i9;
   7419       if ((i9 | 0) == 0) {
   7420        HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i12);
   7421        break;
   7422       }
   7423      } else {
   7424       if (i10 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7425        _abort();
   7426       }
   7427       i12 = i10 + 16 | 0;
   7428       if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
   7429        HEAP32[i12 >> 2] = i9;
   7430       } else {
   7431        HEAP32[i10 + 20 >> 2] = i9;
   7432       }
   7433       if ((i9 | 0) == 0) {
   7434        break;
   7435       }
   7436      }
   7437      if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7438       _abort();
   7439      }
   7440      HEAP32[i9 + 24 >> 2] = i10;
   7441      i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0;
   7442      do {
   7443       if ((i6 | 0) != 0) {
   7444        if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7445         _abort();
   7446        } else {
   7447         HEAP32[i9 + 16 >> 2] = i6;
   7448         HEAP32[i6 + 24 >> 2] = i9;
   7449         break;
   7450        }
   7451       }
   7452      } while (0);
   7453      i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0;
   7454      if ((i6 | 0) != 0) {
   7455       if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7456        _abort();
   7457       } else {
   7458        HEAP32[i9 + 20 >> 2] = i6;
   7459        HEAP32[i6 + 24 >> 2] = i9;
   7460        break;
   7461       }
   7462      }
   7463     }
   7464    } else {
   7465     i9 = HEAP32[i7 + i8 >> 2] | 0;
   7466     i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
   7467     i8 = 80 + (i12 << 1 << 2) | 0;
   7468     if ((i9 | 0) != (i8 | 0)) {
   7469      if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7470       _abort();
   7471      }
   7472      if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) {
   7473       _abort();
   7474      }
   7475     }
   7476     if ((i7 | 0) == (i9 | 0)) {
   7477      HEAP32[10] = HEAP32[10] & ~(1 << i12);
   7478      break;
   7479     }
   7480     if ((i7 | 0) != (i8 | 0)) {
   7481      if (i7 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7482       _abort();
   7483      }
   7484      i8 = i7 + 8 | 0;
   7485      if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) {
   7486       i10 = i8;
   7487      } else {
   7488       _abort();
   7489      }
   7490     } else {
   7491      i10 = i7 + 8 | 0;
   7492     }
   7493     HEAP32[i9 + 12 >> 2] = i7;
   7494     HEAP32[i10 >> 2] = i9;
   7495    }
   7496   } while (0);
   7497   HEAP32[i2 + 4 >> 2] = i11 | 1;
   7498   HEAP32[i2 + i11 >> 2] = i11;
   7499   if ((i2 | 0) == (HEAP32[60 >> 2] | 0)) {
   7500    HEAP32[48 >> 2] = i11;
   7501    STACKTOP = i1;
   7502    return;
   7503   }
   7504  } else {
   7505   HEAP32[i12 >> 2] = i13 & -2;
   7506   HEAP32[i2 + 4 >> 2] = i11 | 1;
   7507   HEAP32[i2 + i11 >> 2] = i11;
   7508  }
   7509  i6 = i11 >>> 3;
   7510  if (i11 >>> 0 < 256) {
   7511   i7 = i6 << 1;
   7512   i3 = 80 + (i7 << 2) | 0;
   7513   i8 = HEAP32[10] | 0;
   7514   i6 = 1 << i6;
   7515   if ((i8 & i6 | 0) != 0) {
   7516    i6 = 80 + (i7 + 2 << 2) | 0;
   7517    i7 = HEAP32[i6 >> 2] | 0;
   7518    if (i7 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7519     _abort();
   7520    } else {
   7521     i4 = i6;
   7522     i5 = i7;
   7523    }
   7524   } else {
   7525    HEAP32[10] = i8 | i6;
   7526    i4 = 80 + (i7 + 2 << 2) | 0;
   7527    i5 = i3;
   7528   }
   7529   HEAP32[i4 >> 2] = i2;
   7530   HEAP32[i5 + 12 >> 2] = i2;
   7531   HEAP32[i2 + 8 >> 2] = i5;
   7532   HEAP32[i2 + 12 >> 2] = i3;
   7533   STACKTOP = i1;
   7534   return;
   7535  }
   7536  i4 = i11 >>> 8;
   7537  if ((i4 | 0) != 0) {
   7538   if (i11 >>> 0 > 16777215) {
   7539    i4 = 31;
   7540   } else {
   7541    i20 = (i4 + 1048320 | 0) >>> 16 & 8;
   7542    i21 = i4 << i20;
   7543    i19 = (i21 + 520192 | 0) >>> 16 & 4;
   7544    i21 = i21 << i19;
   7545    i4 = (i21 + 245760 | 0) >>> 16 & 2;
   7546    i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0;
   7547    i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1;
   7548   }
   7549  } else {
   7550   i4 = 0;
   7551  }
   7552  i5 = 344 + (i4 << 2) | 0;
   7553  HEAP32[i2 + 28 >> 2] = i4;
   7554  HEAP32[i2 + 20 >> 2] = 0;
   7555  HEAP32[i2 + 16 >> 2] = 0;
   7556  i7 = HEAP32[44 >> 2] | 0;
   7557  i6 = 1 << i4;
   7558  L199 : do {
   7559   if ((i7 & i6 | 0) != 0) {
   7560    i5 = HEAP32[i5 >> 2] | 0;
   7561    if ((i4 | 0) == 31) {
   7562     i4 = 0;
   7563    } else {
   7564     i4 = 25 - (i4 >>> 1) | 0;
   7565    }
   7566    L205 : do {
   7567     if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) {
   7568      i4 = i11 << i4;
   7569      i7 = i5;
   7570      while (1) {
   7571       i6 = i7 + (i4 >>> 31 << 2) + 16 | 0;
   7572       i5 = HEAP32[i6 >> 2] | 0;
   7573       if ((i5 | 0) == 0) {
   7574        break;
   7575       }
   7576       if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) {
   7577        i3 = i5;
   7578        break L205;
   7579       } else {
   7580        i4 = i4 << 1;
   7581        i7 = i5;
   7582       }
   7583      }
   7584      if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
   7585       _abort();
   7586      } else {
   7587       HEAP32[i6 >> 2] = i2;
   7588       HEAP32[i2 + 24 >> 2] = i7;
   7589       HEAP32[i2 + 12 >> 2] = i2;
   7590       HEAP32[i2 + 8 >> 2] = i2;
   7591       break L199;
   7592      }
   7593     } else {
   7594      i3 = i5;
   7595     }
   7596    } while (0);
   7597    i5 = i3 + 8 | 0;
   7598    i4 = HEAP32[i5 >> 2] | 0;
   7599    i6 = HEAP32[56 >> 2] | 0;
   7600    if (i3 >>> 0 < i6 >>> 0) {
   7601     _abort();
   7602    }
   7603    if (i4 >>> 0 < i6 >>> 0) {
   7604     _abort();
   7605    } else {
   7606     HEAP32[i4 + 12 >> 2] = i2;
   7607     HEAP32[i5 >> 2] = i2;
   7608     HEAP32[i2 + 8 >> 2] = i4;
   7609     HEAP32[i2 + 12 >> 2] = i3;
   7610     HEAP32[i2 + 24 >> 2] = 0;
   7611     break;
   7612    }
   7613   } else {
   7614    HEAP32[44 >> 2] = i7 | i6;
   7615    HEAP32[i5 >> 2] = i2;
   7616    HEAP32[i2 + 24 >> 2] = i5;
   7617    HEAP32[i2 + 12 >> 2] = i2;
   7618    HEAP32[i2 + 8 >> 2] = i2;
   7619   }
   7620  } while (0);
   7621  i21 = (HEAP32[72 >> 2] | 0) + -1 | 0;
   7622  HEAP32[72 >> 2] = i21;
   7623  if ((i21 | 0) == 0) {
   7624   i2 = 496 | 0;
   7625  } else {
   7626   STACKTOP = i1;
   7627   return;
   7628  }
   7629  while (1) {
   7630   i2 = HEAP32[i2 >> 2] | 0;
   7631   if ((i2 | 0) == 0) {
   7632    break;
   7633   } else {
   7634    i2 = i2 + 8 | 0;
   7635   }
   7636  }
   7637  HEAP32[72 >> 2] = -1;
   7638  STACKTOP = i1;
   7639  return;
   7640 }
   7641 function _main(i3, i5) {
   7642  i3 = i3 | 0;
   7643  i5 = i5 | 0;
   7644  var i1 = 0, i2 = 0, i4 = 0, i6 = 0, i7 = 0;
   7645  i1 = STACKTOP;
   7646  STACKTOP = STACKTOP + 16 | 0;
   7647  i2 = i1;
   7648  L1 : do {
   7649   if ((i3 | 0) > 1) {
   7650    i3 = HEAP8[HEAP32[i5 + 4 >> 2] | 0] | 0;
   7651    switch (i3 | 0) {
   7652    case 50:
   7653     {
   7654      i3 = 400;
   7655      break L1;
   7656     }
   7657    case 51:
   7658     {
   7659      i4 = 4;
   7660      break L1;
   7661     }
   7662    case 52:
   7663     {
   7664      i3 = 4e3;
   7665      break L1;
   7666     }
   7667    case 53:
   7668     {
   7669      i3 = 8e3;
   7670      break L1;
   7671     }
   7672    case 49:
   7673     {
   7674      i3 = 55;
   7675      break L1;
   7676     }
   7677    case 48:
   7678     {
   7679      i7 = 0;
   7680      STACKTOP = i1;
   7681      return i7 | 0;
   7682     }
   7683    default:
   7684     {
   7685      HEAP32[i2 >> 2] = i3 + -48;
   7686      _printf(8, i2 | 0) | 0;
   7687      i7 = -1;
   7688      STACKTOP = i1;
   7689      return i7 | 0;
   7690     }
   7691    }
   7692   } else {
   7693    i4 = 4;
   7694   }
   7695  } while (0);
   7696  if ((i4 | 0) == 4) {
   7697   i3 = 800;
   7698  }
   7699  i5 = _malloc(1048576) | 0;
   7700  i6 = 0;
   7701  i4 = 0;
   7702  do {
   7703   i7 = 0;
   7704   while (1) {
   7705    HEAP8[i5 + i7 | 0] = i7 + i6;
   7706    i7 = i7 + 1 | 0;
   7707    if ((i7 | 0) == 1048576) {
   7708     i7 = 0;
   7709     break;
   7710    }
   7711   }
   7712   do {
   7713    i6 = (HEAP8[i5 + i7 | 0] & 1) + i6 | 0;
   7714    i7 = i7 + 1 | 0;
   7715   } while ((i7 | 0) != 1048576);
   7716   i6 = (i6 | 0) % 1e3 | 0;
   7717   i4 = i4 + 1 | 0;
   7718  } while ((i4 | 0) < (i3 | 0));
   7719  HEAP32[i2 >> 2] = i6;
   7720  _printf(24, i2 | 0) | 0;
   7721  i7 = 0;
   7722  STACKTOP = i1;
   7723  return i7 | 0;
   7724 }
   7725 function _memcpy(i3, i2, i1) {
   7726  i3 = i3 | 0;
   7727  i2 = i2 | 0;
   7728  i1 = i1 | 0;
   7729  var i4 = 0;
   7730  if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
   7731  i4 = i3 | 0;
   7732  if ((i3 & 3) == (i2 & 3)) {
   7733   while (i3 & 3) {
   7734    if ((i1 | 0) == 0) return i4 | 0;
   7735    HEAP8[i3] = HEAP8[i2] | 0;
   7736    i3 = i3 + 1 | 0;
   7737    i2 = i2 + 1 | 0;
   7738    i1 = i1 - 1 | 0;
   7739   }
   7740   while ((i1 | 0) >= 4) {
   7741    HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
   7742    i3 = i3 + 4 | 0;
   7743    i2 = i2 + 4 | 0;
   7744    i1 = i1 - 4 | 0;
   7745   }
   7746  }
   7747  while ((i1 | 0) > 0) {
   7748   HEAP8[i3] = HEAP8[i2] | 0;
   7749   i3 = i3 + 1 | 0;
   7750   i2 = i2 + 1 | 0;
   7751   i1 = i1 - 1 | 0;
   7752  }
   7753  return i4 | 0;
   7754 }
   7755 function _memset(i1, i4, i3) {
   7756  i1 = i1 | 0;
   7757  i4 = i4 | 0;
   7758  i3 = i3 | 0;
   7759  var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
   7760  i2 = i1 + i3 | 0;
   7761  if ((i3 | 0) >= 20) {
   7762   i4 = i4 & 255;
   7763   i7 = i1 & 3;
   7764   i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
   7765   i5 = i2 & ~3;
   7766   if (i7) {
   7767    i7 = i1 + 4 - i7 | 0;
   7768    while ((i1 | 0) < (i7 | 0)) {
   7769     HEAP8[i1] = i4;
   7770     i1 = i1 + 1 | 0;
   7771    }
   7772   }
   7773   while ((i1 | 0) < (i5 | 0)) {
   7774    HEAP32[i1 >> 2] = i6;
   7775    i1 = i1 + 4 | 0;
   7776   }
   7777  }
   7778  while ((i1 | 0) < (i2 | 0)) {
   7779   HEAP8[i1] = i4;
   7780   i1 = i1 + 1 | 0;
   7781  }
   7782  return i1 - i3 | 0;
   7783 }
   7784 function copyTempDouble(i1) {
   7785  i1 = i1 | 0;
   7786  HEAP8[tempDoublePtr] = HEAP8[i1];
   7787  HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
   7788  HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
   7789  HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
   7790  HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
   7791  HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
   7792  HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
   7793  HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
   7794 }
   7795 function copyTempFloat(i1) {
   7796  i1 = i1 | 0;
   7797  HEAP8[tempDoublePtr] = HEAP8[i1];
   7798  HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
   7799  HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
   7800  HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
   7801 }
   7802 function runPostSets() {}
   7803 function _strlen(i1) {
   7804  i1 = i1 | 0;
   7805  var i2 = 0;
   7806  i2 = i1;
   7807  while (HEAP8[i2] | 0) {
   7808   i2 = i2 + 1 | 0;
   7809  }
   7810  return i2 - i1 | 0;
   7811 }
   7812 function stackAlloc(i1) {
   7813  i1 = i1 | 0;
   7814  var i2 = 0;
   7815  i2 = STACKTOP;
   7816  STACKTOP = STACKTOP + i1 | 0;
   7817  STACKTOP = STACKTOP + 7 & -8;
   7818  return i2 | 0;
   7819 }
   7820 function setThrew(i1, i2) {
   7821  i1 = i1 | 0;
   7822  i2 = i2 | 0;
   7823  if ((__THREW__ | 0) == 0) {
   7824   __THREW__ = i1;
   7825   threwValue = i2;
   7826  }
   7827 }
   7828 function stackRestore(i1) {
   7829  i1 = i1 | 0;
   7830  STACKTOP = i1;
   7831 }
   7832 function setTempRet9(i1) {
   7833  i1 = i1 | 0;
   7834  tempRet9 = i1;
   7835 }
   7836 function setTempRet8(i1) {
   7837  i1 = i1 | 0;
   7838  tempRet8 = i1;
   7839 }
   7840 function setTempRet7(i1) {
   7841  i1 = i1 | 0;
   7842  tempRet7 = i1;
   7843 }
   7844 function setTempRet6(i1) {
   7845  i1 = i1 | 0;
   7846  tempRet6 = i1;
   7847 }
   7848 function setTempRet5(i1) {
   7849  i1 = i1 | 0;
   7850  tempRet5 = i1;
   7851 }
   7852 function setTempRet4(i1) {
   7853  i1 = i1 | 0;
   7854  tempRet4 = i1;
   7855 }
   7856 function setTempRet3(i1) {
   7857  i1 = i1 | 0;
   7858  tempRet3 = i1;
   7859 }
   7860 function setTempRet2(i1) {
   7861  i1 = i1 | 0;
   7862  tempRet2 = i1;
   7863 }
   7864 function setTempRet1(i1) {
   7865  i1 = i1 | 0;
   7866  tempRet1 = i1;
   7867 }
   7868 function setTempRet0(i1) {
   7869  i1 = i1 | 0;
   7870  tempRet0 = i1;
   7871 }
   7872 function stackSave() {
   7873  return STACKTOP | 0;
   7874 }
   7875 
   7876 // EMSCRIPTEN_END_FUNCS
   7877 
   7878 
   7879   return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9 };
   7880 }).toString(),
   7881 // EMSCRIPTEN_END_ASM
   7882 { "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array, "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "_fflush": _fflush, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_printf": _printf, "_send": _send, "_pwrite": _pwrite, "_abort": _abort, "___setErrNo": ___setErrNo, "_fwrite": _fwrite, "_sbrk": _sbrk, "_time": _time, "_mkport": _mkport, "__reallyNegative": __reallyNegative, "__formatString": __formatString, "_fileno": _fileno, "_write": _write, "_fprintf": _fprintf, "_sysconf": _sysconf, "___errno_location": ___errno_location, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }, buffer);
   7883 var _strlen = Module["_strlen"] = asm["_strlen"];
   7884 var _free = Module["_free"] = asm["_free"];
   7885 var _main = Module["_main"] = asm["_main"];
   7886 var _memset = Module["_memset"] = asm["_memset"];
   7887 var _malloc = Module["_malloc"] = asm["_malloc"];
   7888 var _memcpy = Module["_memcpy"] = asm["_memcpy"];
   7889 var runPostSets = Module["runPostSets"] = asm["runPostSets"];
   7890 
   7891 Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
   7892 Runtime.stackSave = function() { return asm['stackSave']() };
   7893 Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
   7894 
   7895 
   7896 // Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
   7897 var i64Math = null;
   7898 
   7899 // === Auto-generated postamble setup entry stuff ===
   7900 
   7901 if (memoryInitializer) {
   7902   if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
   7903     var data = Module['readBinary'](memoryInitializer);
   7904     HEAPU8.set(data, STATIC_BASE);
   7905   } else {
   7906     addRunDependency('memory initializer');
   7907     Browser.asyncLoad(memoryInitializer, function(data) {
   7908       HEAPU8.set(data, STATIC_BASE);
   7909       removeRunDependency('memory initializer');
   7910     }, function(data) {
   7911       throw 'could not load memory initializer ' + memoryInitializer;
   7912     });
   7913   }
   7914 }
   7915 
   7916 function ExitStatus(status) {
   7917   this.name = "ExitStatus";
   7918   this.message = "Program terminated with exit(" + status + ")";
   7919   this.status = status;
   7920 };
   7921 ExitStatus.prototype = new Error();
   7922 ExitStatus.prototype.constructor = ExitStatus;
   7923 
   7924 var initialStackTop;
   7925 var preloadStartTime = null;
   7926 var calledMain = false;
   7927 
   7928 dependenciesFulfilled = function runCaller() {
   7929   // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
   7930   if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
   7931   if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
   7932 }
   7933 
   7934 Module['callMain'] = Module.callMain = function callMain(args) {
   7935   assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
   7936   assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
   7937 
   7938   args = args || [];
   7939 
   7940   ensureInitRuntime();
   7941 
   7942   var argc = args.length+1;
   7943   function pad() {
   7944     for (var i = 0; i < 4-1; i++) {
   7945       argv.push(0);
   7946     }
   7947   }
   7948   var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
   7949   pad();
   7950   for (var i = 0; i < argc-1; i = i + 1) {
   7951     argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
   7952     pad();
   7953   }
   7954   argv.push(0);
   7955   argv = allocate(argv, 'i32', ALLOC_NORMAL);
   7956 
   7957   initialStackTop = STACKTOP;
   7958 
   7959   try {
   7960 
   7961     var ret = Module['_main'](argc, argv, 0);
   7962 
   7963 
   7964     // if we're not running an evented main loop, it's time to exit
   7965     if (!Module['noExitRuntime']) {
   7966       exit(ret);
   7967     }
   7968   }
   7969   catch(e) {
   7970     if (e instanceof ExitStatus) {
   7971       // exit() throws this once it's done to make sure execution
   7972       // has been stopped completely
   7973       return;
   7974     } else if (e == 'SimulateInfiniteLoop') {
   7975       // running an evented main loop, don't immediately exit
   7976       Module['noExitRuntime'] = true;
   7977       return;
   7978     } else {
   7979       if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
   7980       throw e;
   7981     }
   7982   } finally {
   7983     calledMain = true;
   7984   }
   7985 }
   7986 
   7987 
   7988 
   7989 
   7990 function run(args) {
   7991   args = args || Module['arguments'];
   7992 
   7993   if (preloadStartTime === null) preloadStartTime = Date.now();
   7994 
   7995   if (runDependencies > 0) {
   7996     Module.printErr('run() called, but dependencies remain, so not running');
   7997     return;
   7998   }
   7999 
   8000   preRun();
   8001 
   8002   if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
   8003   if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
   8004 
   8005   function doRun() {
   8006     if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
   8007     Module['calledRun'] = true;
   8008 
   8009     ensureInitRuntime();
   8010 
   8011     preMain();
   8012 
   8013     if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
   8014       Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
   8015     }
   8016 
   8017     if (Module['_main'] && shouldRunNow) {
   8018       Module['callMain'](args);
   8019     }
   8020 
   8021     postRun();
   8022   }
   8023 
   8024   if (Module['setStatus']) {
   8025     Module['setStatus']('Running...');
   8026     setTimeout(function() {
   8027       setTimeout(function() {
   8028         Module['setStatus']('');
   8029       }, 1);
   8030       if (!ABORT) doRun();
   8031     }, 1);
   8032   } else {
   8033     doRun();
   8034   }
   8035 }
   8036 Module['run'] = Module.run = run;
   8037 
   8038 function exit(status) {
   8039   ABORT = true;
   8040   EXITSTATUS = status;
   8041   STACKTOP = initialStackTop;
   8042 
   8043   // exit the runtime
   8044   exitRuntime();
   8045 
   8046   // TODO We should handle this differently based on environment.
   8047   // In the browser, the best we can do is throw an exception
   8048   // to halt execution, but in node we could process.exit and
   8049   // I'd imagine SM shell would have something equivalent.
   8050   // This would let us set a proper exit status (which
   8051   // would be great for checking test exit statuses).
   8052   // https://github.com/kripken/emscripten/issues/1371
   8053 
   8054   // throw an exception to halt the current execution
   8055   throw new ExitStatus(status);
   8056 }
   8057 Module['exit'] = Module.exit = exit;
   8058 
   8059 function abort(text) {
   8060   if (text) {
   8061     Module.print(text);
   8062     Module.printErr(text);
   8063   }
   8064 
   8065   ABORT = true;
   8066   EXITSTATUS = 1;
   8067 
   8068   var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
   8069 
   8070   throw 'abort() at ' + stackTrace() + extra;
   8071 }
   8072 Module['abort'] = Module.abort = abort;
   8073 
   8074 // {{PRE_RUN_ADDITIONS}}
   8075 
   8076 if (Module['preInit']) {
   8077   if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
   8078   while (Module['preInit'].length > 0) {
   8079     Module['preInit'].pop()();
   8080   }
   8081 }
   8082 
   8083 // shouldRunNow refers to calling main(), not run().
   8084 var shouldRunNow = true;
   8085 if (Module['noInitialRun']) {
   8086   shouldRunNow = false;
   8087 }
   8088 
   8089 
   8090 run([].concat(Module["arguments"]));
   8091