Diff of /example/c2iec.js [000000] .. [853a2a]  Maximize  Restore

Switch to unified view

a b/example/c2iec.js
1
2
3
// The Module object: Our interface to the outside world. We import
4
// and export values on it. There are various ways Module can be used:
5
// 1. Not defined. We create it here
6
// 2. A function parameter, function(Module) { ..generated code.. }
7
// 3. pre-run appended it, var Module = {}; ..generated code..
8
// 4. External script tag defines var Module.
9
// We need to check if Module already exists (e.g. case 3 above).
10
// Substitution will be replaced with actual code on later stage of the build,
11
// this way Closure Compiler will not mangle it (e.g. case 4. above).
12
// Note that if you want to run closure, and also to use Module
13
// after the generated code, you will need to define   var Module = {};
14
// before the code. Then that object will be used in the code, and you
15
// can continue to use Module afterwards as well.
16
var Module = typeof Module !== 'undefined' ? Module : {};
17
18
19
20
// --pre-jses are emitted after the Module integration code, so that they can
21
// refer to Module (if they choose; they can also define Module)
22
// {{PRE_JSES}}
23
24
// Sometimes an existing Module object exists with properties
25
// meant to overwrite the default module functionality. Here
26
// we collect those properties and reapply _after_ we configure
27
// the current environment's defaults to avoid having to be so
28
// defensive during initialization.
29
var moduleOverrides = {};
30
var key;
31
for (key in Module) {
32
  if (Module.hasOwnProperty(key)) {
33
    moduleOverrides[key] = Module[key];
34
  }
35
}
36
37
var arguments_ = [];
38
var thisProgram = './this.program';
39
var quit_ = function(status, toThrow) {
40
  throw toThrow;
41
};
42
43
// Determine the runtime environment we are in. You can customize this by
44
// setting the ENVIRONMENT setting at compile time (see settings.js).
45
46
var ENVIRONMENT_IS_WEB = false;
47
var ENVIRONMENT_IS_WORKER = false;
48
var ENVIRONMENT_IS_NODE = false;
49
var ENVIRONMENT_IS_SHELL = false;
50
ENVIRONMENT_IS_WEB = typeof window === 'object';
51
ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
52
// N.b. Electron.js environment is simultaneously a NODE-environment, but
53
// also a web environment.
54
ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';
55
ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
56
57
if (Module['ENVIRONMENT']) {
58
  throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)');
59
}
60
61
62
63
// `/` should be present at the end if `scriptDirectory` is not empty
64
var scriptDirectory = '';
65
function locateFile(path) {
66
  if (Module['locateFile']) {
67
    return Module['locateFile'](path, scriptDirectory);
68
  }
69
  return scriptDirectory + path;
70
}
71
72
// Hooks that are implemented differently in different runtime environments.
73
var read_,
74
    readAsync,
75
    readBinary,
76
    setWindowTitle;
77
78
var nodeFS;
79
var nodePath;
80
81
if (ENVIRONMENT_IS_NODE) {
82
  if (ENVIRONMENT_IS_WORKER) {
83
    scriptDirectory = require('path').dirname(scriptDirectory) + '/';
84
  } else {
85
    scriptDirectory = __dirname + '/';
86
  }
87
88
89
90
91
  read_ = function shell_read(filename, binary) {
92
    if (!nodeFS) nodeFS = require('fs');
93
    if (!nodePath) nodePath = require('path');
94
    filename = nodePath['normalize'](filename);
95
    return nodeFS['readFileSync'](filename, binary ? null : 'utf8');
96
  };
97
98
  readBinary = function readBinary(filename) {
99
    var ret = read_(filename, true);
100
    if (!ret.buffer) {
101
      ret = new Uint8Array(ret);
102
    }
103
    assert(ret.buffer);
104
    return ret;
105
  };
106
107
108
109
110
  if (process['argv'].length > 1) {
111
    thisProgram = process['argv'][1].replace(/\\/g, '/');
112
  }
113
114
  arguments_ = process['argv'].slice(2);
115
116
  if (typeof module !== 'undefined') {
117
    module['exports'] = Module;
118
  }
119
120
  process['on']('uncaughtException', function(ex) {
121
    // suppress ExitStatus exceptions from showing an error
122
    if (!(ex instanceof ExitStatus)) {
123
      throw ex;
124
    }
125
  });
126
127
  process['on']('unhandledRejection', abort);
128
129
  quit_ = function(status) {
130
    process['exit'](status);
131
  };
132
133
  Module['inspect'] = function () { return '[Emscripten Module object]'; };
134
135
136
137
} else
138
if (ENVIRONMENT_IS_SHELL) {
139
140
141
  if (typeof read != 'undefined') {
142
    read_ = function shell_read(f) {
143
      return read(f);
144
    };
145
  }
146
147
  readBinary = function readBinary(f) {
148
    var data;
149
    if (typeof readbuffer === 'function') {
150
      return new Uint8Array(readbuffer(f));
151
    }
152
    data = read(f, 'binary');
153
    assert(typeof data === 'object');
154
    return data;
155
  };
156
157
  if (typeof scriptArgs != 'undefined') {
158
    arguments_ = scriptArgs;
159
  } else if (typeof arguments != 'undefined') {
160
    arguments_ = arguments;
161
  }
162
163
  if (typeof quit === 'function') {
164
    quit_ = function(status) {
165
      quit(status);
166
    };
167
  }
168
169
  if (typeof print !== 'undefined') {
170
    // Prefer to use print/printErr where they exist, as they usually work better.
171
    if (typeof console === 'undefined') console = /** @type{!Console} */({});
172
    console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
173
    console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print);
174
  }
175
176
177
} else
178
179
// Note that this includes Node.js workers when relevant (pthreads is enabled).
180
// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
181
// ENVIRONMENT_IS_NODE.
182
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
183
  if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
184
    scriptDirectory = self.location.href;
185
  } else if (document.currentScript) { // web
186
    scriptDirectory = document.currentScript.src;
187
  }
188
  // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
189
  // otherwise, slice off the final part of the url to find the script directory.
190
  // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
191
  // and scriptDirectory will correctly be replaced with an empty string.
192
  if (scriptDirectory.indexOf('blob:') !== 0) {
193
    scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1);
194
  } else {
195
    scriptDirectory = '';
196
  }
197
198
199
  // Differentiate the Web Worker from the Node Worker case, as reading must
200
  // be done differently.
201
  {
202
203
204
205
206
  read_ = function shell_read(url) {
207
      var xhr = new XMLHttpRequest();
208
      xhr.open('GET', url, false);
209
      xhr.send(null);
210
      return xhr.responseText;
211
  };
212
213
  if (ENVIRONMENT_IS_WORKER) {
214
    readBinary = function readBinary(url) {
215
        var xhr = new XMLHttpRequest();
216
        xhr.open('GET', url, false);
217
        xhr.responseType = 'arraybuffer';
218
        xhr.send(null);
219
        return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
220
    };
221
  }
222
223
  readAsync = function readAsync(url, onload, onerror) {
224
    var xhr = new XMLHttpRequest();
225
    xhr.open('GET', url, true);
226
    xhr.responseType = 'arraybuffer';
227
    xhr.onload = function xhr_onload() {
228
      if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
229
        onload(xhr.response);
230
        return;
231
      }
232
      onerror();
233
    };
234
    xhr.onerror = onerror;
235
    xhr.send(null);
236
  };
237
238
239
240
241
  }
242
243
  setWindowTitle = function(title) { document.title = title };
244
} else
245
{
246
  throw new Error('environment detection error');
247
}
248
249
250
// Set up the out() and err() hooks, which are how we can print to stdout or
251
// stderr, respectively.
252
var out = Module['print'] || console.log.bind(console);
253
var err = Module['printErr'] || console.warn.bind(console);
254
255
// Merge back in the overrides
256
for (key in moduleOverrides) {
257
  if (moduleOverrides.hasOwnProperty(key)) {
258
    Module[key] = moduleOverrides[key];
259
  }
260
}
261
// Free the object hierarchy contained in the overrides, this lets the GC
262
// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
263
moduleOverrides = null;
264
265
// Emit code to handle expected values on the Module object. This applies Module.x
266
// to the proper local x. This has two benefits: first, we only emit it if it is
267
// expected to arrive, and second, by using a local everywhere else that can be
268
// minified.
269
if (Module['arguments']) arguments_ = Module['arguments'];if (!Object.getOwnPropertyDescriptor(Module, 'arguments')) Object.defineProperty(Module, 'arguments', { configurable: true, get: function() { abort('Module.arguments has been replaced with plain arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
270
if (Module['thisProgram']) thisProgram = Module['thisProgram'];if (!Object.getOwnPropertyDescriptor(Module, 'thisProgram')) Object.defineProperty(Module, 'thisProgram', { configurable: true, get: function() { abort('Module.thisProgram has been replaced with plain thisProgram (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
271
if (Module['quit']) quit_ = Module['quit'];if (!Object.getOwnPropertyDescriptor(Module, 'quit')) Object.defineProperty(Module, 'quit', { configurable: true, get: function() { abort('Module.quit has been replaced with plain quit_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
272
273
// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
274
// Assertions on removed incoming Module JS APIs.
275
assert(typeof Module['memoryInitializerPrefixURL'] === 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
276
assert(typeof Module['pthreadMainPrefixURL'] === 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
277
assert(typeof Module['cdInitializerPrefixURL'] === 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
278
assert(typeof Module['filePackagePrefixURL'] === 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
279
assert(typeof Module['read'] === 'undefined', 'Module.read option was removed (modify read_ in JS)');
280
assert(typeof Module['readAsync'] === 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
281
assert(typeof Module['readBinary'] === 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
282
assert(typeof Module['setWindowTitle'] === 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)');
283
assert(typeof Module['TOTAL_MEMORY'] === 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
284
if (!Object.getOwnPropertyDescriptor(Module, 'read')) Object.defineProperty(Module, 'read', { configurable: true, get: function() { abort('Module.read has been replaced with plain read_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
285
if (!Object.getOwnPropertyDescriptor(Module, 'readAsync')) Object.defineProperty(Module, 'readAsync', { configurable: true, get: function() { abort('Module.readAsync has been replaced with plain readAsync (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
286
if (!Object.getOwnPropertyDescriptor(Module, 'readBinary')) Object.defineProperty(Module, 'readBinary', { configurable: true, get: function() { abort('Module.readBinary has been replaced with plain readBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
287
if (!Object.getOwnPropertyDescriptor(Module, 'setWindowTitle')) Object.defineProperty(Module, 'setWindowTitle', { configurable: true, get: function() { abort('Module.setWindowTitle has been replaced with plain setWindowTitle (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
288
var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
289
var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
290
var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
291
var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
292
293
294
295
296
297
298
// {{PREAMBLE_ADDITIONS}}
299
300
var STACK_ALIGN = 16;
301
302
function dynamicAlloc(size) {
303
  assert(DYNAMICTOP_PTR);
304
  var ret = HEAP32[DYNAMICTOP_PTR>>2];
305
  var end = (ret + size + 15) & -16;
306
  assert(end <= HEAP8.length, 'failure to dynamicAlloc - memory growth etc. is not supported there, call malloc/sbrk directly');
307
  HEAP32[DYNAMICTOP_PTR>>2] = end;
308
  return ret;
309
}
310
311
function alignMemory(size, factor) {
312
  if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default
313
  return Math.ceil(size / factor) * factor;
314
}
315
316
function getNativeTypeSize(type) {
317
  switch (type) {
318
    case 'i1': case 'i8': return 1;
319
    case 'i16': return 2;
320
    case 'i32': return 4;
321
    case 'i64': return 8;
322
    case 'float': return 4;
323
    case 'double': return 8;
324
    default: {
325
      if (type[type.length-1] === '*') {
326
        return 4; // A pointer
327
      } else if (type[0] === 'i') {
328
        var bits = Number(type.substr(1));
329
        assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
330
        return bits / 8;
331
      } else {
332
        return 0;
333
      }
334
    }
335
  }
336
}
337
338
function warnOnce(text) {
339
  if (!warnOnce.shown) warnOnce.shown = {};
340
  if (!warnOnce.shown[text]) {
341
    warnOnce.shown[text] = 1;
342
    err(text);
343
  }
344
}
345
346
347
348
349
350
351
352
353
// Wraps a JS function as a wasm function with a given signature.
354
function convertJsFunctionToWasm(func, sig) {
355
356
  // If the type reflection proposal is available, use the new
357
  // "WebAssembly.Function" constructor.
358
  // Otherwise, construct a minimal wasm module importing the JS function and
359
  // re-exporting it.
360
  if (typeof WebAssembly.Function === "function") {
361
    var typeNames = {
362
      'i': 'i32',
363
      'j': 'i64',
364
      'f': 'f32',
365
      'd': 'f64'
366
    };
367
    var type = {
368
      parameters: [],
369
      results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
370
    };
371
    for (var i = 1; i < sig.length; ++i) {
372
      type.parameters.push(typeNames[sig[i]]);
373
    }
374
    return new WebAssembly.Function(type, func);
375
  }
376
377
  // The module is static, with the exception of the type section, which is
378
  // generated based on the signature passed in.
379
  var typeSection = [
380
    0x01, // id: section,
381
    0x00, // length: 0 (placeholder)
382
    0x01, // count: 1
383
    0x60, // form: func
384
  ];
385
  var sigRet = sig.slice(0, 1);
386
  var sigParam = sig.slice(1);
387
  var typeCodes = {
388
    'i': 0x7f, // i32
389
    'j': 0x7e, // i64
390
    'f': 0x7d, // f32
391
    'd': 0x7c, // f64
392
  };
393
394
  // Parameters, length + signatures
395
  typeSection.push(sigParam.length);
396
  for (var i = 0; i < sigParam.length; ++i) {
397
    typeSection.push(typeCodes[sigParam[i]]);
398
  }
399
400
  // Return values, length + signatures
401
  // With no multi-return in MVP, either 0 (void) or 1 (anything else)
402
  if (sigRet == 'v') {
403
    typeSection.push(0x00);
404
  } else {
405
    typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);
406
  }
407
408
  // Write the overall length of the type section back into the section header
409
  // (excepting the 2 bytes for the section id and length)
410
  typeSection[1] = typeSection.length - 2;
411
412
  // Rest of the module is static
413
  var bytes = new Uint8Array([
414
    0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
415
    0x01, 0x00, 0x00, 0x00, // version: 1
416
  ].concat(typeSection, [
417
    0x02, 0x07, // import section
418
      // (import "e" "f" (func 0 (type 0)))
419
      0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,
420
    0x07, 0x05, // export section
421
      // (export "f" (func 0 (type 0)))
422
      0x01, 0x01, 0x66, 0x00, 0x00,
423
  ]));
424
425
   // We can compile this wasm module synchronously because it is very small.
426
  // This accepts an import (at "e.f"), that it reroutes to an export (at "f")
427
  var module = new WebAssembly.Module(bytes);
428
  var instance = new WebAssembly.Instance(module, {
429
    'e': {
430
      'f': func
431
    }
432
  });
433
  var wrappedFunc = instance.exports['f'];
434
  return wrappedFunc;
435
}
436
437
var freeTableIndexes = [];
438
439
// Weak map of functions in the table to their indexes, created on first use.
440
var functionsInTableMap;
441
442
// Add a wasm function to the table.
443
function addFunctionWasm(func, sig) {
444
  var table = wasmTable;
445
446
  // Check if the function is already in the table, to ensure each function
447
  // gets a unique index. First, create the map if this is the first use.
448
  if (!functionsInTableMap) {
449
    functionsInTableMap = new WeakMap();
450
    for (var i = 0; i < table.length; i++) {
451
      var item = table.get(i);
452
      // Ignore null values.
453
      if (item) {
454
        functionsInTableMap.set(item, i);
455
      }
456
    }
457
  }
458
  if (functionsInTableMap.has(func)) {
459
    return functionsInTableMap.get(func);
460
  }
461
462
  // It's not in the table, add it now.
463
464
465
  var ret;
466
  // Reuse a free index if there is one, otherwise grow.
467
  if (freeTableIndexes.length) {
468
    ret = freeTableIndexes.pop();
469
  } else {
470
    ret = table.length;
471
    // Grow the table
472
    try {
473
      table.grow(1);
474
    } catch (err) {
475
      if (!(err instanceof RangeError)) {
476
        throw err;
477
      }
478
      throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';
479
    }
480
  }
481
482
  // Set the new value.
483
  try {
484
    // Attempting to call this with JS function will cause of table.set() to fail
485
    table.set(ret, func);
486
  } catch (err) {
487
    if (!(err instanceof TypeError)) {
488
      throw err;
489
    }
490
    assert(typeof sig !== 'undefined', 'Missing signature argument to addFunction');
491
    var wrapped = convertJsFunctionToWasm(func, sig);
492
    table.set(ret, wrapped);
493
  }
494
495
  functionsInTableMap.set(func, ret);
496
497
  return ret;
498
}
499
500
function removeFunctionWasm(index) {
501
  functionsInTableMap.delete(wasmTable.get(index));
502
  freeTableIndexes.push(index);
503
}
504
505
// 'sig' parameter is required for the llvm backend but only when func is not
506
// already a WebAssembly function.
507
function addFunction(func, sig) {
508
  assert(typeof func !== 'undefined');
509
510
  return addFunctionWasm(func, sig);
511
}
512
513
function removeFunction(index) {
514
  removeFunctionWasm(index);
515
}
516
517
518
519
var funcWrappers = {};
520
521
function getFuncWrapper(func, sig) {
522
  if (!func) return; // on null pointer, return undefined
523
  assert(sig);
524
  if (!funcWrappers[sig]) {
525
    funcWrappers[sig] = {};
526
  }
527
  var sigCache = funcWrappers[sig];
528
  if (!sigCache[func]) {
529
    // optimize away arguments usage in common cases
530
    if (sig.length === 1) {
531
      sigCache[func] = function dynCall_wrapper() {
532
        return dynCall(sig, func);
533
      };
534
    } else if (sig.length === 2) {
535
      sigCache[func] = function dynCall_wrapper(arg) {
536
        return dynCall(sig, func, [arg]);
537
      };
538
    } else {
539
      // general case
540
      sigCache[func] = function dynCall_wrapper() {
541
        return dynCall(sig, func, Array.prototype.slice.call(arguments));
542
      };
543
    }
544
  }
545
  return sigCache[func];
546
}
547
548
549
550
551
552
553
554
function makeBigInt(low, high, unsigned) {
555
  return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0));
556
}
557
558
/** @param {Array=} args */
559
function dynCall(sig, ptr, args) {
560
  if (args && args.length) {
561
    // j (64-bit integer) must be passed in as two numbers [low 32, high 32].
562
    assert(args.length === sig.substring(1).replace(/j/g, '--').length);
563
    assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\'');
564
    return Module['dynCall_' + sig].apply(null, [ptr].concat(args));
565
  } else {
566
    assert(sig.length == 1);
567
    assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\'');
568
    return Module['dynCall_' + sig].call(null, ptr);
569
  }
570
}
571
572
var tempRet0 = 0;
573
574
var setTempRet0 = function(value) {
575
  tempRet0 = value;
576
};
577
578
var getTempRet0 = function() {
579
  return tempRet0;
580
};
581
582
function getCompilerSetting(name) {
583
  throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work';
584
}
585
586
// The address globals begin at. Very low in memory, for code size and optimization opportunities.
587
// Above 0 is static memory, starting with globals.
588
// Then the stack.
589
// Then 'dynamic' memory for sbrk.
590
var GLOBAL_BASE = 1024;
591
592
593
594
595
596
// === Preamble library stuff ===
597
598
// Documentation for the public APIs defined in this file must be updated in:
599
//    site/source/docs/api_reference/preamble.js.rst
600
// A prebuilt local version of the documentation is available at:
601
//    site/build/text/docs/api_reference/preamble.js.txt
602
// You can also build docs locally as HTML or other formats in site/
603
// An online HTML version (which may be of a different version of Emscripten)
604
//    is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
605
606
607
var wasmBinary;if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];if (!Object.getOwnPropertyDescriptor(Module, 'wasmBinary')) Object.defineProperty(Module, 'wasmBinary', { configurable: true, get: function() { abort('Module.wasmBinary has been replaced with plain wasmBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
608
var noExitRuntime;if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];if (!Object.getOwnPropertyDescriptor(Module, 'noExitRuntime')) Object.defineProperty(Module, 'noExitRuntime', { configurable: true, get: function() { abort('Module.noExitRuntime has been replaced with plain noExitRuntime (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
609
610
611
if (typeof WebAssembly !== 'object') {
612
  abort('No WebAssembly support found. Build with -s WASM=0 to target JavaScript instead.');
613
}
614
615
616
617
618
// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking.
619
// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties)
620
621
/** @param {number} ptr
622
    @param {number} value
623
    @param {string} type
624
    @param {number|boolean=} noSafe */
625
function setValue(ptr, value, type, noSafe) {
626
  type = type || 'i8';
627
  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
628
    switch(type) {
629
      case 'i1': HEAP8[((ptr)>>0)]=value; break;
630
      case 'i8': HEAP8[((ptr)>>0)]=value; break;
631
      case 'i16': HEAP16[((ptr)>>1)]=value; break;
632
      case 'i32': HEAP32[((ptr)>>2)]=value; break;
633
      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
634
      case 'float': HEAPF32[((ptr)>>2)]=value; break;
635
      case 'double': HEAPF64[((ptr)>>3)]=value; break;
636
      default: abort('invalid type for setValue: ' + type);
637
    }
638
}
639
640
/** @param {number} ptr
641
    @param {string} type
642
    @param {number|boolean=} noSafe */
643
function getValue(ptr, type, noSafe) {
644
  type = type || 'i8';
645
  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
646
    switch(type) {
647
      case 'i1': return HEAP8[((ptr)>>0)];
648
      case 'i8': return HEAP8[((ptr)>>0)];
649
      case 'i16': return HEAP16[((ptr)>>1)];
650
      case 'i32': return HEAP32[((ptr)>>2)];
651
      case 'i64': return HEAP32[((ptr)>>2)];
652
      case 'float': return HEAPF32[((ptr)>>2)];
653
      case 'double': return HEAPF64[((ptr)>>3)];
654
      default: abort('invalid type for getValue: ' + type);
655
    }
656
  return null;
657
}
658
659
660
661
662
663
664
// Wasm globals
665
666
var wasmMemory;
667
668
// In fastcomp asm.js, we don't need a wasm Table at all.
669
// In the wasm backend, we polyfill the WebAssembly object,
670
// so this creates a (non-native-wasm) table for us.
671
var wasmTable = new WebAssembly.Table({
672
  'initial': 10,
673
  'maximum': 10 + 0,
674
  'element': 'anyfunc'
675
});
676
677
678
//========================================
679
// Runtime essentials
680
//========================================
681
682
// whether we are quitting the application. no code should run after this.
683
// set in exit() and abort()
684
var ABORT = false;
685
686
// set by exit() and abort().  Passed to 'onExit' handler.
687
// NOTE: This is also used as the process return code code in shell environments
688
// but only when noExitRuntime is false.
689
var EXITSTATUS = 0;
690
691
/** @type {function(*, string=)} */
692
function assert(condition, text) {
693
  if (!condition) {
694
    abort('Assertion failed: ' + text);
695
  }
696
}
697
698
// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
699
function getCFunc(ident) {
700
  var func = Module['_' + ident]; // closure exported function
701
  assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
702
  return func;
703
}
704
705
// C calling interface.
706
/** @param {string|null=} returnType
707
    @param {Array=} argTypes
708
    @param {Arguments|Array=} args
709
    @param {Object=} opts */
710
function ccall(ident, returnType, argTypes, args, opts) {
711
  // For fast lookup of conversion functions
712
  var toC = {
713
    'string': function(str) {
714
      var ret = 0;
715
      if (str !== null && str !== undefined && str !== 0) { // null string
716
        // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
717
        var len = (str.length << 2) + 1;
718
        ret = stackAlloc(len);
719
        stringToUTF8(str, ret, len);
720
      }
721
      return ret;
722
    },
723
    'array': function(arr) {
724
      var ret = stackAlloc(arr.length);
725
      writeArrayToMemory(arr, ret);
726
      return ret;
727
    }
728
  };
729
730
  function convertReturnValue(ret) {
731
    if (returnType === 'string') return UTF8ToString(ret);
732
    if (returnType === 'boolean') return Boolean(ret);
733
    return ret;
734
  }
735
736
  var func = getCFunc(ident);
737
  var cArgs = [];
738
  var stack = 0;
739
  assert(returnType !== 'array', 'Return type should not be "array".');
740
  if (args) {
741
    for (var i = 0; i < args.length; i++) {
742
      var converter = toC[argTypes[i]];
743
      if (converter) {
744
        if (stack === 0) stack = stackSave();
745
        cArgs[i] = converter(args[i]);
746
      } else {
747
        cArgs[i] = args[i];
748
      }
749
    }
750
  }
751
  var ret = func.apply(null, cArgs);
752
753
  ret = convertReturnValue(ret);
754
  if (stack !== 0) stackRestore(stack);
755
  return ret;
756
}
757
758
/** @param {string=} returnType
759
    @param {Array=} argTypes
760
    @param {Object=} opts */
761
function cwrap(ident, returnType, argTypes, opts) {
762
  return function() {
763
    return ccall(ident, returnType, argTypes, arguments, opts);
764
  }
765
}
766
767
var ALLOC_NORMAL = 0; // Tries to use _malloc()
768
var ALLOC_STACK = 1; // Lives for the duration of the current function call
769
var ALLOC_DYNAMIC = 2; // Cannot be freed except through sbrk
770
var ALLOC_NONE = 3; // Do not allocate
771
772
// allocate(): This is for internal use. You can use it yourself as well, but the interface
773
//             is a little tricky (see docs right below). The reason is that it is optimized
774
//             for multiple syntaxes to save space in generated code. So you should
775
//             normally not use allocate(), and instead allocate memory using _malloc(),
776
//             initialize it with setValue(), and so forth.
777
// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
778
//        in *bytes* (note that this is sometimes confusing: the next parameter does not
779
//        affect this!)
780
// @types: Either an array of types, one for each byte (or 0 if no type at that position),
781
//         or a single type which is used for the entire block. This only matters if there
782
//         is initial data - if @slab is a number, then this does not matter at all and is
783
//         ignored.
784
// @allocator: How to allocate memory, see ALLOC_*
785
/** @type {function((TypedArray|Array<number>|number), string, number, number=)} */
786
function allocate(slab, types, allocator, ptr) {
787
  var zeroinit, size;
788
  if (typeof slab === 'number') {
789
    zeroinit = true;
790
    size = slab;
791
  } else {
792
    zeroinit = false;
793
    size = slab.length;
794
  }
795
796
  var singleType = typeof types === 'string' ? types : null;
797
798
  var ret;
799
  if (allocator == ALLOC_NONE) {
800
    ret = ptr;
801
  } else {
802
    ret = [_malloc,
803
    stackAlloc,
804
    dynamicAlloc][allocator](Math.max(size, singleType ? 1 : types.length));
805
  }
806
807
  if (zeroinit) {
808
    var stop;
809
    ptr = ret;
810
    assert((ret & 3) == 0);
811
    stop = ret + (size & ~3);
812
    for (; ptr < stop; ptr += 4) {
813
      HEAP32[((ptr)>>2)]=0;
814
    }
815
    stop = ret + size;
816
    while (ptr < stop) {
817
      HEAP8[((ptr++)>>0)]=0;
818
    }
819
    return ret;
820
  }
821
822
  if (singleType === 'i8') {
823
    if (slab.subarray || slab.slice) {
824
      HEAPU8.set(/** @type {!Uint8Array} */ (slab), ret);
825
    } else {
826
      HEAPU8.set(new Uint8Array(slab), ret);
827
    }
828
    return ret;
829
  }
830
831
  var i = 0, type, typeSize, previousType;
832
  while (i < size) {
833
    var curr = slab[i];
834
835
    type = singleType || types[i];
836
    if (type === 0) {
837
      i++;
838
      continue;
839
    }
840
    assert(type, 'Must know what type to store in allocate!');
841
842
    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
843
844
    setValue(ret+i, curr, type);
845
846
    // no need to look up size unless type changes, so cache it
847
    if (previousType !== type) {
848
      typeSize = getNativeTypeSize(type);
849
      previousType = type;
850
    }
851
    i += typeSize;
852
  }
853
854
  return ret;
855
}
856
857
// Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready
858
function getMemory(size) {
859
  if (!runtimeInitialized) return dynamicAlloc(size);
860
  return _malloc(size);
861
}
862
863
864
865
866
// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime.
867
868
// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns
869
// a copy of that string as a Javascript String object.
870
871
var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;
872
873
/**
874
 * @param {number} idx
875
 * @param {number=} maxBytesToRead
876
 * @return {string}
877
 */
878
function UTF8ArrayToString(heap, idx, maxBytesToRead) {
879
  var endIdx = idx + maxBytesToRead;
880
  var endPtr = idx;
881
  // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
882
  // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
883
  // (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity)
884
  while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
885
886
  if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
887
    return UTF8Decoder.decode(heap.subarray(idx, endPtr));
888
  } else {
889
    var str = '';
890
    // If building with TextDecoder, we have already computed the string length above, so test loop end condition against that
891
    while (idx < endPtr) {
892
      // For UTF8 byte structure, see:
893
      // http://en.wikipedia.org/wiki/UTF-8#Description
894
      // https://www.ietf.org/rfc/rfc2279.txt
895
      // https://tools.ietf.org/html/rfc3629
896
      var u0 = heap[idx++];
897
      if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
898
      var u1 = heap[idx++] & 63;
899
      if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
900
      var u2 = heap[idx++] & 63;
901
      if ((u0 & 0xF0) == 0xE0) {
902
        u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
903
      } else {
904
        if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string on the asm.js/wasm heap to a JS string!');
905
        u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63);
906
      }
907
908
      if (u0 < 0x10000) {
909
        str += String.fromCharCode(u0);
910
      } else {
911
        var ch = u0 - 0x10000;
912
        str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
913
      }
914
    }
915
  }
916
  return str;
917
}
918
919
// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a
920
// copy of that string as a Javascript String object.
921
// maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit
922
//                 this parameter to scan the string until the first \0 byte. If maxBytesToRead is
923
//                 passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the
924
//                 middle, then the string will cut short at that byte index (i.e. maxBytesToRead will
925
//                 not produce a string of exact length [ptr, ptr+maxBytesToRead[)
926
//                 N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may
927
//                 throw JS JIT optimizations off, so it is worth to consider consistently using one
928
//                 style or the other.
929
/**
930
 * @param {number} ptr
931
 * @param {number=} maxBytesToRead
932
 * @return {string}
933
 */
934
function UTF8ToString(ptr, maxBytesToRead) {
935
  return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
936
}
937
938
// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',
939
// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.
940
// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
941
// Parameters:
942
//   str: the Javascript string to copy.
943
//   heap: the array to copy to. Each index in this array is assumed to be one 8-byte element.
944
//   outIdx: The starting offset in the array to begin the copying.
945
//   maxBytesToWrite: The maximum number of bytes this function can write to the array.
946
//                    This count should include the null terminator,
947
//                    i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.
948
//                    maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.
949
// Returns the number of bytes written, EXCLUDING the null terminator.
950
951
function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
952
  if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
953
    return 0;
954
955
  var startIdx = outIdx;
956
  var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
957
  for (var i = 0; i < str.length; ++i) {
958
    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
959
    // See http://unicode.org/faq/utf_bom.html#utf16-3
960
    // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
961
    var u = str.charCodeAt(i); // possibly a lead surrogate
962
    if (u >= 0xD800 && u <= 0xDFFF) {
963
      var u1 = str.charCodeAt(++i);
964
      u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
965
    }
966
    if (u <= 0x7F) {
967
      if (outIdx >= endIdx) break;
968
      heap[outIdx++] = u;
969
    } else if (u <= 0x7FF) {
970
      if (outIdx + 1 >= endIdx) break;
971
      heap[outIdx++] = 0xC0 | (u >> 6);
972
      heap[outIdx++] = 0x80 | (u & 63);
973
    } else if (u <= 0xFFFF) {
974
      if (outIdx + 2 >= endIdx) break;
975
      heap[outIdx++] = 0xE0 | (u >> 12);
976
      heap[outIdx++] = 0x80 | ((u >> 6) & 63);
977
      heap[outIdx++] = 0x80 | (u & 63);
978
    } else {
979
      if (outIdx + 3 >= endIdx) break;
980
      if (u >= 0x200000) warnOnce('Invalid Unicode code point 0x' + u.toString(16) + ' encountered when serializing a JS string to an UTF-8 string on the asm.js/wasm heap! (Valid unicode code points should be in range 0-0x1FFFFF).');
981
      heap[outIdx++] = 0xF0 | (u >> 18);
982
      heap[outIdx++] = 0x80 | ((u >> 12) & 63);
983
      heap[outIdx++] = 0x80 | ((u >> 6) & 63);
984
      heap[outIdx++] = 0x80 | (u & 63);
985
    }
986
  }
987
  // Null-terminate the pointer to the buffer.
988
  heap[outIdx] = 0;
989
  return outIdx - startIdx;
990
}
991
992
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
993
// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.
994
// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
995
// Returns the number of bytes written, EXCLUDING the null terminator.
996
997
function stringToUTF8(str, outPtr, maxBytesToWrite) {
998
  assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
999
  return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);
1000
}
1001
1002
// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.
1003
function lengthBytesUTF8(str) {
1004
  var len = 0;
1005
  for (var i = 0; i < str.length; ++i) {
1006
    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
1007
    // See http://unicode.org/faq/utf_bom.html#utf16-3
1008
    var u = str.charCodeAt(i); // possibly a lead surrogate
1009
    if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
1010
    if (u <= 0x7F) ++len;
1011
    else if (u <= 0x7FF) len += 2;
1012
    else if (u <= 0xFFFF) len += 3;
1013
    else len += 4;
1014
  }
1015
  return len;
1016
}
1017
1018
1019
1020
1021
1022
// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime.
1023
1024
// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns
1025
// a copy of that string as a Javascript String object.
1026
1027
function AsciiToString(ptr) {
1028
  var str = '';
1029
  while (1) {
1030
    var ch = HEAPU8[((ptr++)>>0)];
1031
    if (!ch) return str;
1032
    str += String.fromCharCode(ch);
1033
  }
1034
}
1035
1036
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
1037
// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.
1038
1039
function stringToAscii(str, outPtr) {
1040
  return writeAsciiToMemory(str, outPtr, false);
1041
}
1042
1043
// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
1044
// a copy of that string as a Javascript String object.
1045
1046
var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined;
1047
1048
function UTF16ToString(ptr, maxBytesToRead) {
1049
  assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!');
1050
  var endPtr = ptr;
1051
  // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
1052
  // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
1053
  var idx = endPtr >> 1;
1054
  var maxIdx = idx + maxBytesToRead / 2;
1055
  // If maxBytesToRead is not passed explicitly, it will be undefined, and this
1056
  // will always evaluate to true. This saves on code size.
1057
  while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx;
1058
  endPtr = idx << 1;
1059
1060
  if (endPtr - ptr > 32 && UTF16Decoder) {
1061
    return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
1062
  } else {
1063
    var i = 0;
1064
1065
    var str = '';
1066
    while (1) {
1067
      var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
1068
      if (codeUnit == 0 || i == maxBytesToRead / 2) return str;
1069
      ++i;
1070
      // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
1071
      str += String.fromCharCode(codeUnit);
1072
    }
1073
  }
1074
}
1075
1076
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
1077
// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.
1078
// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.
1079
// Parameters:
1080
//   str: the Javascript string to copy.
1081
//   outPtr: Byte address in Emscripten HEAP where to write the string to.
1082
//   maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
1083
//                    terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.
1084
//                    maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.
1085
// Returns the number of bytes written, EXCLUDING the null terminator.
1086
1087
function stringToUTF16(str, outPtr, maxBytesToWrite) {
1088
  assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!');
1089
  assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
1090
  // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
1091
  if (maxBytesToWrite === undefined) {
1092
    maxBytesToWrite = 0x7FFFFFFF;
1093
  }
1094
  if (maxBytesToWrite < 2) return 0;
1095
  maxBytesToWrite -= 2; // Null terminator.
1096
  var startPtr = outPtr;
1097
  var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length;
1098
  for (var i = 0; i < numCharsToWrite; ++i) {
1099
    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
1100
    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
1101
    HEAP16[((outPtr)>>1)]=codeUnit;
1102
    outPtr += 2;
1103
  }
1104
  // Null-terminate the pointer to the HEAP.
1105
  HEAP16[((outPtr)>>1)]=0;
1106
  return outPtr - startPtr;
1107
}
1108
1109
// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
1110
1111
function lengthBytesUTF16(str) {
1112
  return str.length*2;
1113
}
1114
1115
function UTF32ToString(ptr, maxBytesToRead) {
1116
  assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!');
1117
  var i = 0;
1118
1119
  var str = '';
1120
  // If maxBytesToRead is not passed explicitly, it will be undefined, and this
1121
  // will always evaluate to true. This saves on code size.
1122
  while (!(i >= maxBytesToRead / 4)) {
1123
    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
1124
    if (utf32 == 0) break;
1125
    ++i;
1126
    // 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.
1127
    // See http://unicode.org/faq/utf_bom.html#utf16-3
1128
    if (utf32 >= 0x10000) {
1129
      var ch = utf32 - 0x10000;
1130
      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
1131
    } else {
1132
      str += String.fromCharCode(utf32);
1133
    }
1134
  }
1135
  return str;
1136
}
1137
1138
// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
1139
// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.
1140
// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.
1141
// Parameters:
1142
//   str: the Javascript string to copy.
1143
//   outPtr: Byte address in Emscripten HEAP where to write the string to.
1144
//   maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
1145
//                    terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.
1146
//                    maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.
1147
// Returns the number of bytes written, EXCLUDING the null terminator.
1148
1149
function stringToUTF32(str, outPtr, maxBytesToWrite) {
1150
  assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!');
1151
  assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
1152
  // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
1153
  if (maxBytesToWrite === undefined) {
1154
    maxBytesToWrite = 0x7FFFFFFF;
1155
  }
1156
  if (maxBytesToWrite < 4) return 0;
1157
  var startPtr = outPtr;
1158
  var endPtr = startPtr + maxBytesToWrite - 4;
1159
  for (var i = 0; i < str.length; ++i) {
1160
    // 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.
1161
    // See http://unicode.org/faq/utf_bom.html#utf16-3
1162
    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
1163
    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
1164
      var trailSurrogate = str.charCodeAt(++i);
1165
      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
1166
    }
1167
    HEAP32[((outPtr)>>2)]=codeUnit;
1168
    outPtr += 4;
1169
    if (outPtr + 4 > endPtr) break;
1170
  }
1171
  // Null-terminate the pointer to the HEAP.
1172
  HEAP32[((outPtr)>>2)]=0;
1173
  return outPtr - startPtr;
1174
}
1175
1176
// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
1177
1178
function lengthBytesUTF32(str) {
1179
  var len = 0;
1180
  for (var i = 0; i < str.length; ++i) {
1181
    // 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.
1182
    // See http://unicode.org/faq/utf_bom.html#utf16-3
1183
    var codeUnit = str.charCodeAt(i);
1184
    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate.
1185
    len += 4;
1186
  }
1187
1188
  return len;
1189
}
1190
1191
// Allocate heap space for a JS string, and write it there.
1192
// It is the responsibility of the caller to free() that memory.
1193
function allocateUTF8(str) {
1194
  var size = lengthBytesUTF8(str) + 1;
1195
  var ret = _malloc(size);
1196
  if (ret) stringToUTF8Array(str, HEAP8, ret, size);
1197
  return ret;
1198
}
1199
1200
// Allocate stack space for a JS string, and write it there.
1201
function allocateUTF8OnStack(str) {
1202
  var size = lengthBytesUTF8(str) + 1;
1203
  var ret = stackAlloc(size);
1204
  stringToUTF8Array(str, HEAP8, ret, size);
1205
  return ret;
1206
}
1207
1208
// Deprecated: This function should not be called because it is unsafe and does not provide
1209
// a maximum length limit of how many bytes it is allowed to write. Prefer calling the
1210
// function stringToUTF8Array() instead, which takes in a maximum length that can be used
1211
// to be secure from out of bounds writes.
1212
/** @deprecated
1213
    @param {boolean=} dontAddNull */
1214
function writeStringToMemory(string, buffer, dontAddNull) {
1215
  warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!');
1216
1217
  var /** @type {number} */ lastChar, /** @type {number} */ end;
1218
  if (dontAddNull) {
1219
    // stringToUTF8Array always appends null. If we don't want to do that, remember the
1220
    // character that existed at the location where the null will be placed, and restore
1221
    // that after the write (below).
1222
    end = buffer + lengthBytesUTF8(string);
1223
    lastChar = HEAP8[end];
1224
  }
1225
  stringToUTF8(string, buffer, Infinity);
1226
  if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character.
1227
}
1228
1229
function writeArrayToMemory(array, buffer) {
1230
  assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
1231
  HEAP8.set(array, buffer);
1232
}
1233
1234
/** @param {boolean=} dontAddNull */
1235
function writeAsciiToMemory(str, buffer, dontAddNull) {
1236
  for (var i = 0; i < str.length; ++i) {
1237
    assert(str.charCodeAt(i) === str.charCodeAt(i)&0xff);
1238
    HEAP8[((buffer++)>>0)]=str.charCodeAt(i);
1239
  }
1240
  // Null-terminate the pointer to the HEAP.
1241
  if (!dontAddNull) HEAP8[((buffer)>>0)]=0;
1242
}
1243
1244
1245
1246
// Memory management
1247
1248
var PAGE_SIZE = 16384;
1249
var WASM_PAGE_SIZE = 65536;
1250
var ASMJS_PAGE_SIZE = 16777216;
1251
1252
function alignUp(x, multiple) {
1253
  if (x % multiple > 0) {
1254
    x += multiple - (x % multiple);
1255
  }
1256
  return x;
1257
}
1258
1259
var HEAP,
1260
/** @type {ArrayBuffer} */
1261
  buffer,
1262
/** @type {Int8Array} */
1263
  HEAP8,
1264
/** @type {Uint8Array} */
1265
  HEAPU8,
1266
/** @type {Int16Array} */
1267
  HEAP16,
1268
/** @type {Uint16Array} */
1269
  HEAPU16,
1270
/** @type {Int32Array} */
1271
  HEAP32,
1272
/** @type {Uint32Array} */
1273
  HEAPU32,
1274
/** @type {Float32Array} */
1275
  HEAPF32,
1276
/** @type {Float64Array} */
1277
  HEAPF64;
1278
1279
function updateGlobalBufferAndViews(buf) {
1280
  buffer = buf;
1281
  Module['HEAP8'] = HEAP8 = new Int8Array(buf);
1282
  Module['HEAP16'] = HEAP16 = new Int16Array(buf);
1283
  Module['HEAP32'] = HEAP32 = new Int32Array(buf);
1284
  Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf);
1285
  Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf);
1286
  Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf);
1287
  Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);
1288
  Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);
1289
}
1290
1291
var STATIC_BASE = 1024,
1292
    STACK_BASE = 6013600,
1293
    STACKTOP = STACK_BASE,
1294
    STACK_MAX = 770720,
1295
    DYNAMIC_BASE = 6013600,
1296
    DYNAMICTOP_PTR = 770560;
1297
1298
assert(STACK_BASE % 16 === 0, 'stack must start aligned');
1299
assert(DYNAMIC_BASE % 16 === 0, 'heap must start aligned');
1300
1301
1302
var TOTAL_STACK = 5242880;
1303
if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime')
1304
1305
var INITIAL_INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;if (!Object.getOwnPropertyDescriptor(Module, 'INITIAL_MEMORY')) Object.defineProperty(Module, 'INITIAL_MEMORY', { configurable: true, get: function() { abort('Module.INITIAL_MEMORY has been replaced with plain INITIAL_INITIAL_MEMORY (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') } });
1306
1307
assert(INITIAL_INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')');
1308
1309
// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
1310
assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray !== undefined && Int32Array.prototype.set !== undefined,
1311
       'JS engine does not provide full typed array support');
1312
1313
1314
1315
1316
1317
1318
1319
1320
// In non-standalone/normal mode, we create the memory here.
1321
1322
1323
1324
// Create the main memory. (Note: this isn't used in STANDALONE_WASM mode since the wasm
1325
// memory is created in the wasm, not in JS.)
1326
1327
  if (Module['wasmMemory']) {
1328
    wasmMemory = Module['wasmMemory'];
1329
  } else
1330
  {
1331
    wasmMemory = new WebAssembly.Memory({
1332
      'initial': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE
1333
      ,
1334
      'maximum': INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE
1335
    });
1336
  }
1337
1338
1339
if (wasmMemory) {
1340
  buffer = wasmMemory.buffer;
1341
}
1342
1343
// If the user provides an incorrect length, just use that length instead rather than providing the user to
1344
// specifically provide the memory length with Module['INITIAL_MEMORY'].
1345
INITIAL_INITIAL_MEMORY = buffer.byteLength;
1346
assert(INITIAL_INITIAL_MEMORY % WASM_PAGE_SIZE === 0);
1347
updateGlobalBufferAndViews(buffer);
1348
1349
HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE;
1350
1351
1352
1353
1354
1355
1356
// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
1357
function writeStackCookie() {
1358
  assert((STACK_MAX & 3) == 0);
1359
  // The stack grows downwards
1360
  HEAPU32[(STACK_MAX >> 2)+1] = 0x2135467;
1361
  HEAPU32[(STACK_MAX >> 2)+2] = 0x89BACDFE;
1362
  // Also test the global address 0 for integrity.
1363
  // We don't do this with ASan because ASan does its own checks for this.
1364
  HEAP32[0] = 0x63736d65; /* 'emsc' */
1365
}
1366
1367
function checkStackCookie() {
1368
  var cookie1 = HEAPU32[(STACK_MAX >> 2)+1];
1369
  var cookie2 = HEAPU32[(STACK_MAX >> 2)+2];
1370
  if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) {
1371
    abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' ' + cookie1.toString(16));
1372
  }
1373
  // Also test the global address 0 for integrity.
1374
  // We don't do this with ASan because ASan does its own checks for this.
1375
  if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
1376
}
1377
1378
1379
1380
1381
1382
// Endianness check (note: assumes compiler arch was little-endian)
1383
(function() {
1384
  var h16 = new Int16Array(1);
1385
  var h8 = new Int8Array(h16.buffer);
1386
  h16[0] = 0x6373;
1387
  if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian!';
1388
})();
1389
1390
function abortFnPtrError(ptr, sig) {
1391
    abort("Invalid function pointer " + ptr + " called with signature '" + sig + "'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this). Build with ASSERTIONS=2 for more info.");
1392
}
1393
1394
1395
1396
function callRuntimeCallbacks(callbacks) {
1397
  while(callbacks.length > 0) {
1398
    var callback = callbacks.shift();
1399
    if (typeof callback == 'function') {
1400
      callback(Module); // Pass the module as the first argument.
1401
      continue;
1402
    }
1403
    var func = callback.func;
1404
    if (typeof func === 'number') {
1405
      if (callback.arg === undefined) {
1406
        Module['dynCall_v'](func);
1407
      } else {
1408
        Module['dynCall_vi'](func, callback.arg);
1409
      }
1410
    } else {
1411
      func(callback.arg === undefined ? null : callback.arg);
1412
    }
1413
  }
1414
}
1415
1416
var __ATPRERUN__  = []; // functions called before the runtime is initialized
1417
var __ATINIT__    = []; // functions called during startup
1418
var __ATMAIN__    = []; // functions called when main() is to be run
1419
var __ATEXIT__    = []; // functions called during shutdown
1420
var __ATPOSTRUN__ = []; // functions called after the main() is called
1421
1422
var runtimeInitialized = false;
1423
var runtimeExited = false;
1424
1425
1426
function preRun() {
1427
1428
  if (Module['preRun']) {
1429
    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
1430
    while (Module['preRun'].length) {
1431
      addOnPreRun(Module['preRun'].shift());
1432
    }
1433
  }
1434
1435
  callRuntimeCallbacks(__ATPRERUN__);
1436
}
1437
1438
function initRuntime() {
1439
  checkStackCookie();
1440
  assert(!runtimeInitialized);
1441
  runtimeInitialized = true;
1442
  if (!Module["noFSInit"] && !FS.init.initialized) FS.init();
1443
TTY.init();
1444
  callRuntimeCallbacks(__ATINIT__);
1445
}
1446
1447
function preMain() {
1448
  checkStackCookie();
1449
  FS.ignorePermissions = false;
1450
  callRuntimeCallbacks(__ATMAIN__);
1451
}
1452
1453
function exitRuntime() {
1454
  checkStackCookie();
1455
  runtimeExited = true;
1456
}
1457
1458
function postRun() {
1459
  checkStackCookie();
1460
1461
  if (Module['postRun']) {
1462
    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
1463
    while (Module['postRun'].length) {
1464
      addOnPostRun(Module['postRun'].shift());
1465
    }
1466
  }
1467
1468
  callRuntimeCallbacks(__ATPOSTRUN__);
1469
}
1470
1471
function addOnPreRun(cb) {
1472
  __ATPRERUN__.unshift(cb);
1473
}
1474
1475
function addOnInit(cb) {
1476
  __ATINIT__.unshift(cb);
1477
}
1478
1479
function addOnPreMain(cb) {
1480
  __ATMAIN__.unshift(cb);
1481
}
1482
1483
function addOnExit(cb) {
1484
}
1485
1486
function addOnPostRun(cb) {
1487
  __ATPOSTRUN__.unshift(cb);
1488
}
1489
1490
/** @param {number|boolean=} ignore */
1491
function unSign(value, bits, ignore) {
1492
  if (value >= 0) {
1493
    return value;
1494
  }
1495
  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
1496
                    : Math.pow(2, bits)         + value;
1497
}
1498
/** @param {number|boolean=} ignore */
1499
function reSign(value, bits, ignore) {
1500
  if (value <= 0) {
1501
    return value;
1502
  }
1503
  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
1504
                        : Math.pow(2, bits-1);
1505
  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
1506
                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
1507
                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
1508
    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
1509
  }
1510
  return value;
1511
}
1512
1513
1514
1515
1516
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
1517
1518
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
1519
1520
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
1521
1522
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
1523
1524
assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
1525
assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
1526
assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
1527
assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
1528
1529
var Math_abs = Math.abs;
1530
var Math_cos = Math.cos;
1531
var Math_sin = Math.sin;
1532
var Math_tan = Math.tan;
1533
var Math_acos = Math.acos;
1534
var Math_asin = Math.asin;
1535
var Math_atan = Math.atan;
1536
var Math_atan2 = Math.atan2;
1537
var Math_exp = Math.exp;
1538
var Math_log = Math.log;
1539
var Math_sqrt = Math.sqrt;
1540
var Math_ceil = Math.ceil;
1541
var Math_floor = Math.floor;
1542
var Math_pow = Math.pow;
1543
var Math_imul = Math.imul;
1544
var Math_fround = Math.fround;
1545
var Math_round = Math.round;
1546
var Math_min = Math.min;
1547
var Math_max = Math.max;
1548
var Math_clz32 = Math.clz32;
1549
var Math_trunc = Math.trunc;
1550
1551
1552
1553
// A counter of dependencies for calling run(). If we need to
1554
// do asynchronous work before running, increment this and
1555
// decrement it. Incrementing must happen in a place like
1556
// Module.preRun (used by emcc to add file preloading).
1557
// Note that you can add dependencies in preRun, even though
1558
// it happens right before run - run will be postponed until
1559
// the dependencies are met.
1560
var runDependencies = 0;
1561
var runDependencyWatcher = null;
1562
var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
1563
var runDependencyTracking = {};
1564
1565
function getUniqueRunDependency(id) {
1566
  var orig = id;
1567
  while (1) {
1568
    if (!runDependencyTracking[id]) return id;
1569
    id = orig + Math.random();
1570
  }
1571
}
1572
1573
function addRunDependency(id) {
1574
  runDependencies++;
1575
1576
  if (Module['monitorRunDependencies']) {
1577
    Module['monitorRunDependencies'](runDependencies);
1578
  }
1579
1580
  if (id) {
1581
    assert(!runDependencyTracking[id]);
1582
    runDependencyTracking[id] = 1;
1583
    if (runDependencyWatcher === null && typeof setInterval !== 'undefined') {
1584
      // Check for missing dependencies every few seconds
1585
      runDependencyWatcher = setInterval(function() {
1586
        if (ABORT) {
1587
          clearInterval(runDependencyWatcher);
1588
          runDependencyWatcher = null;
1589
          return;
1590
        }
1591
        var shown = false;
1592
        for (var dep in runDependencyTracking) {
1593
          if (!shown) {
1594
            shown = true;
1595
            err('still waiting on run dependencies:');
1596
          }
1597
          err('dependency: ' + dep);
1598
        }
1599
        if (shown) {
1600
          err('(end of list)');
1601
        }
1602
      }, 10000);
1603
    }
1604
  } else {
1605
    err('warning: run dependency added without ID');
1606
  }
1607
}
1608
1609
function removeRunDependency(id) {
1610
  runDependencies--;
1611
1612
  if (Module['monitorRunDependencies']) {
1613
    Module['monitorRunDependencies'](runDependencies);
1614
  }
1615
1616
  if (id) {
1617
    assert(runDependencyTracking[id]);
1618
    delete runDependencyTracking[id];
1619
  } else {
1620
    err('warning: run dependency removed without ID');
1621
  }
1622
  if (runDependencies == 0) {
1623
    if (runDependencyWatcher !== null) {
1624
      clearInterval(runDependencyWatcher);
1625
      runDependencyWatcher = null;
1626
    }
1627
    if (dependenciesFulfilled) {
1628
      var callback = dependenciesFulfilled;
1629
      dependenciesFulfilled = null;
1630
      callback(); // can add another dependenciesFulfilled
1631
    }
1632
  }
1633
}
1634
1635
Module["preloadedImages"] = {}; // maps url to image data
1636
Module["preloadedAudios"] = {}; // maps url to audio data
1637
1638
/** @param {string|number=} what */
1639
function abort(what) {
1640
  if (Module['onAbort']) {
1641
    Module['onAbort'](what);
1642
  }
1643
1644
  what += '';
1645
  out(what);
1646
  err(what);
1647
1648
  ABORT = true;
1649
  EXITSTATUS = 1;
1650
1651
  var output = 'abort(' + what + ') at ' + stackTrace();
1652
  what = output;
1653
1654
  // Throw a wasm runtime error, because a JS error might be seen as a foreign
1655
  // exception, which means we'd run destructors on it. We need the error to
1656
  // simply make the program stop.
1657
  throw new WebAssembly.RuntimeError(what);
1658
}
1659
1660
1661
var memoryInitializer = null;
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
function hasPrefix(str, prefix) {
1675
  return String.prototype.startsWith ?
1676
      str.startsWith(prefix) :
1677
      str.indexOf(prefix) === 0;
1678
}
1679
1680
// Prefix of data URIs emitted by SINGLE_FILE and related options.
1681
var dataURIPrefix = 'data:application/octet-stream;base64,';
1682
1683
// Indicates whether filename is a base64 data URI.
1684
function isDataURI(filename) {
1685
  return hasPrefix(filename, dataURIPrefix);
1686
}
1687
1688
var fileURIPrefix = "file://";
1689
1690
// Indicates whether filename is delivered via file protocol (as opposed to http/https)
1691
function isFileURI(filename) {
1692
  return hasPrefix(filename, fileURIPrefix);
1693
}
1694
1695
1696
1697
function createExportWrapper(name, fixedasm) {
1698
  return function() {
1699
    var displayName = name;
1700
    var asm = fixedasm;
1701
    if (!fixedasm) {
1702
      asm = Module['asm'];
1703
    }
1704
    assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization');
1705
    assert(!runtimeExited, 'native function `' + displayName + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)');
1706
    if (!asm[name]) {
1707
      assert(asm[name], 'exported native function `' + displayName + '` not found');
1708
    }
1709
    return asm[name].apply(null, arguments);
1710
  };
1711
}
1712
1713
var wasmBinaryFile = 'c2iec.wasm';
1714
if (!isDataURI(wasmBinaryFile)) {
1715
  wasmBinaryFile = locateFile(wasmBinaryFile);
1716
}
1717
1718
function getBinary() {
1719
  try {
1720
    if (wasmBinary) {
1721
      return new Uint8Array(wasmBinary);
1722
    }
1723
1724
    if (readBinary) {
1725
      return readBinary(wasmBinaryFile);
1726
    } else {
1727
      throw "both async and sync fetching of the wasm failed";
1728
    }
1729
  }
1730
  catch (err) {
1731
    abort(err);
1732
  }
1733
}
1734
1735
function getBinaryPromise() {
1736
  // If we don't have the binary yet, and have the Fetch api, use that;
1737
  // in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web
1738
  if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === 'function'
1739
      // Let's not use fetch to get objects over file:// as it's most likely Cordova which doesn't support fetch for file://
1740
      && !isFileURI(wasmBinaryFile)
1741
      ) {
1742
    return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
1743
      if (!response['ok']) {
1744
        throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
1745
      }
1746
      return response['arrayBuffer']();
1747
    }).catch(function () {
1748
      return getBinary();
1749
    });
1750
  }
1751
  // Otherwise, getBinary should be able to get it synchronously
1752
  return new Promise(function(resolve, reject) {
1753
    resolve(getBinary());
1754
  });
1755
}
1756
1757
1758
1759
// Create the wasm instance.
1760
// Receives the wasm imports, returns the exports.
1761
function createWasm() {
1762
  // prepare imports
1763
  var info = {
1764
    'env': asmLibraryArg,
1765
    'wasi_snapshot_preview1': asmLibraryArg
1766
  };
1767
  // Load the wasm module and create an instance of using native support in the JS engine.
1768
  // handle a generated wasm instance, receiving its exports and
1769
  // performing other necessary setup
1770
  /** @param {WebAssembly.Module=} module*/
1771
  function receiveInstance(instance, module) {
1772
    var exports = instance.exports;
1773
    Module['asm'] = exports;
1774
    removeRunDependency('wasm-instantiate');
1775
  }
1776
  // we can't run yet (except in a pthread, where we have a custom sync instantiator)
1777
  addRunDependency('wasm-instantiate');
1778
1779
1780
  // Async compilation can be confusing when an error on the page overwrites Module
1781
  // (for example, if the order of elements is wrong, and the one defining Module is
1782
  // later), so we save Module and check it later.
1783
  var trueModule = Module;
1784
  function receiveInstantiatedSource(output) {
1785
    // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
1786
    // receiveInstance() will swap in the exports (to Module.asm) so they can be called
1787
    assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
1788
    trueModule = null;
1789
    // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
1790
    // When the regression is fixed, can restore the above USE_PTHREADS-enabled path.
1791
    receiveInstance(output['instance']);
1792
  }
1793
1794
1795
  function instantiateArrayBuffer(receiver) {
1796
    return getBinaryPromise().then(function(binary) {
1797
      return WebAssembly.instantiate(binary, info);
1798
    }).then(receiver, function(reason) {
1799
      err('failed to asynchronously prepare wasm: ' + reason);
1800
      abort(reason);
1801
    });
1802
  }
1803
1804
  // Prefer streaming instantiation if available.
1805
  function instantiateAsync() {
1806
    if (!wasmBinary &&
1807
        typeof WebAssembly.instantiateStreaming === 'function' &&
1808
        !isDataURI(wasmBinaryFile) &&
1809
        // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
1810
        !isFileURI(wasmBinaryFile) &&
1811
        typeof fetch === 'function') {
1812
      fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) {
1813
        var result = WebAssembly.instantiateStreaming(response, info);
1814
        return result.then(receiveInstantiatedSource, function(reason) {
1815
            // We expect the most common failure cause to be a bad MIME type for the binary,
1816
            // in which case falling back to ArrayBuffer instantiation should work.
1817
            err('wasm streaming compile failed: ' + reason);
1818
            err('falling back to ArrayBuffer instantiation');
1819
            return instantiateArrayBuffer(receiveInstantiatedSource);
1820
          });
1821
      });
1822
    } else {
1823
      return instantiateArrayBuffer(receiveInstantiatedSource);
1824
    }
1825
  }
1826
  // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
1827
  // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
1828
  // to any other async startup actions they are performing.
1829
  if (Module['instantiateWasm']) {
1830
    try {
1831
      var exports = Module['instantiateWasm'](info, receiveInstance);
1832
      return exports;
1833
    } catch(e) {
1834
      err('Module.instantiateWasm callback failed with error: ' + e);
1835
      return false;
1836
    }
1837
  }
1838
1839
  instantiateAsync();
1840
  return {}; // no exports yet; we'll fill them in later
1841
}
1842
1843
1844
// Globals used by JS i64 conversions
1845
var tempDouble;
1846
var tempI64;
1847
1848
// === Body ===
1849
1850
var ASM_CONSTS = {
1851
  
1852
};
1853
1854
1855
1856
1857
// STATICTOP = STATIC_BASE + 769696;
1858
/* global initializers */  __ATINIT__.push({ func: function() { ___wasm_call_ctors() } });
1859
1860
1861
1862
1863
/* no memory initializer */
1864
// {{PRE_LIBRARY}}
1865
1866
1867
  function abortStackOverflow(allocSize) {
1868
      abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (STACK_MAX - stackSave() + allocSize) + ' bytes available!');
1869
    }
1870
1871
  function demangle(func) {
1872
      warnOnce('warning: build with  -s DEMANGLE_SUPPORT=1  to link in libcxxabi demangling');
1873
      return func;
1874
    }
1875
1876
  function demangleAll(text) {
1877
      var regex =
1878
        /\b_Z[\w\d_]+/g;
1879
      return text.replace(regex,
1880
        function(x) {
1881
          var y = demangle(x);
1882
          return x === y ? x : (y + ' [' + x + ']');
1883
        });
1884
    }
1885
1886
  function jsStackTrace() {
1887
      var err = new Error();
1888
      if (!err.stack) {
1889
        // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
1890
        // so try that as a special-case.
1891
        try {
1892
          throw new Error();
1893
        } catch(e) {
1894
          err = e;
1895
        }
1896
        if (!err.stack) {
1897
          return '(no stack trace available)';
1898
        }
1899
      }
1900
      return err.stack.toString();
1901
    }
1902
1903
  function stackTrace() {
1904
      var js = jsStackTrace();
1905
      if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace']();
1906
      return demangleAll(js);
1907
    }
1908
1909
  function ___handle_stack_overflow() {
1910
      abort('stack overflow')
1911
    }
1912
1913
  function _emscripten_get_sbrk_ptr() {
1914
      return 770560;
1915
    }
1916
1917
  function _emscripten_memcpy_big(dest, src, num) {
1918
      HEAPU8.copyWithin(dest, src, src + num);
1919
    }
1920
1921
  
1922
  function _emscripten_get_heap_size() {
1923
      return HEAPU8.length;
1924
    }
1925
  
1926
  function abortOnCannotGrowMemory(requestedSize) {
1927
      abort('Cannot enlarge memory arrays to size ' + requestedSize + ' bytes (OOM). Either (1) compile with  -s INITIAL_MEMORY=X  with X higher than the current value ' + HEAP8.length + ', (2) compile with  -s ALLOW_MEMORY_GROWTH=1  which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with  -s ABORTING_MALLOC=0 ');
1928
    }function _emscripten_resize_heap(requestedSize) {
1929
      requestedSize = requestedSize >>> 0;
1930
      abortOnCannotGrowMemory(requestedSize);
1931
    }
1932
1933
  function _exit(status) {
1934
      // void _exit(int status);
1935
      // http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
1936
      exit(status);
1937
    }
1938
1939
  
1940
  
1941
  var PATH={splitPath:function(filename) {
1942
        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
1943
        return splitPathRe.exec(filename).slice(1);
1944
      },normalizeArray:function(parts, allowAboveRoot) {
1945
        // if the path tries to go above the root, `up` ends up > 0
1946
        var up = 0;
1947
        for (var i = parts.length - 1; i >= 0; i--) {
1948
          var last = parts[i];
1949
          if (last === '.') {
1950
            parts.splice(i, 1);
1951
          } else if (last === '..') {
1952
            parts.splice(i, 1);
1953
            up++;
1954
          } else if (up) {
1955
            parts.splice(i, 1);
1956
            up--;
1957
          }
1958
        }
1959
        // if the path is allowed to go above the root, restore leading ..s
1960
        if (allowAboveRoot) {
1961
          for (; up; up--) {
1962
            parts.unshift('..');
1963
          }
1964
        }
1965
        return parts;
1966
      },normalize:function(path) {
1967
        var isAbsolute = path.charAt(0) === '/',
1968
            trailingSlash = path.substr(-1) === '/';
1969
        // Normalize the path
1970
        path = PATH.normalizeArray(path.split('/').filter(function(p) {
1971
          return !!p;
1972
        }), !isAbsolute).join('/');
1973
        if (!path && !isAbsolute) {
1974
          path = '.';
1975
        }
1976
        if (path && trailingSlash) {
1977
          path += '/';
1978
        }
1979
        return (isAbsolute ? '/' : '') + path;
1980
      },dirname:function(path) {
1981
        var result = PATH.splitPath(path),
1982
            root = result[0],
1983
            dir = result[1];
1984
        if (!root && !dir) {
1985
          // No dirname whatsoever
1986
          return '.';
1987
        }
1988
        if (dir) {
1989
          // It has a dirname, strip trailing slash
1990
          dir = dir.substr(0, dir.length - 1);
1991
        }
1992
        return root + dir;
1993
      },basename:function(path) {
1994
        // EMSCRIPTEN return '/'' for '/', not an empty string
1995
        if (path === '/') return '/';
1996
        var lastSlash = path.lastIndexOf('/');
1997
        if (lastSlash === -1) return path;
1998
        return path.substr(lastSlash+1);
1999
      },extname:function(path) {
2000
        return PATH.splitPath(path)[3];
2001
      },join:function() {
2002
        var paths = Array.prototype.slice.call(arguments, 0);
2003
        return PATH.normalize(paths.join('/'));
2004
      },join2:function(l, r) {
2005
        return PATH.normalize(l + '/' + r);
2006
      }};
2007
  
2008
  
2009
  function setErrNo(value) {
2010
      HEAP32[((___errno_location())>>2)]=value;
2011
      return value;
2012
    }
2013
  
2014
  var PATH_FS={resolve:function() {
2015
        var resolvedPath = '',
2016
          resolvedAbsolute = false;
2017
        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
2018
          var path = (i >= 0) ? arguments[i] : FS.cwd();
2019
          // Skip empty and invalid entries
2020
          if (typeof path !== 'string') {
2021
            throw new TypeError('Arguments to path.resolve must be strings');
2022
          } else if (!path) {
2023
            return ''; // an invalid portion invalidates the whole thing
2024
          }
2025
          resolvedPath = path + '/' + resolvedPath;
2026
          resolvedAbsolute = path.charAt(0) === '/';
2027
        }
2028
        // At this point the path should be resolved to a full absolute path, but
2029
        // handle relative paths to be safe (might happen when process.cwd() fails)
2030
        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
2031
          return !!p;
2032
        }), !resolvedAbsolute).join('/');
2033
        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
2034
      },relative:function(from, to) {
2035
        from = PATH_FS.resolve(from).substr(1);
2036
        to = PATH_FS.resolve(to).substr(1);
2037
        function trim(arr) {
2038
          var start = 0;
2039
          for (; start < arr.length; start++) {
2040
            if (arr[start] !== '') break;
2041
          }
2042
          var end = arr.length - 1;
2043
          for (; end >= 0; end--) {
2044
            if (arr[end] !== '') break;
2045
          }
2046
          if (start > end) return [];
2047
          return arr.slice(start, end - start + 1);
2048
        }
2049
        var fromParts = trim(from.split('/'));
2050
        var toParts = trim(to.split('/'));
2051
        var length = Math.min(fromParts.length, toParts.length);
2052
        var samePartsLength = length;
2053
        for (var i = 0; i < length; i++) {
2054
          if (fromParts[i] !== toParts[i]) {
2055
            samePartsLength = i;
2056
            break;
2057
          }
2058
        }
2059
        var outputParts = [];
2060
        for (var i = samePartsLength; i < fromParts.length; i++) {
2061
          outputParts.push('..');
2062
        }
2063
        outputParts = outputParts.concat(toParts.slice(samePartsLength));
2064
        return outputParts.join('/');
2065
      }};
2066
  
2067
  var TTY={ttys:[],init:function () {
2068
        // https://github.com/emscripten-core/emscripten/pull/1555
2069
        // if (ENVIRONMENT_IS_NODE) {
2070
        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
2071
        //   // device, it always assumes it's a TTY device. because of this, we're forcing
2072
        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
2073
        //   // with text files until FS.init can be refactored.
2074
        //   process['stdin']['setEncoding']('utf8');
2075
        // }
2076
      },shutdown:function() {
2077
        // https://github.com/emscripten-core/emscripten/pull/1555
2078
        // if (ENVIRONMENT_IS_NODE) {
2079
        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
2080
        //   // 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
2081
        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
2082
        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
2083
        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
2084
        //   process['stdin']['pause']();
2085
        // }
2086
      },register:function(dev, ops) {
2087
        TTY.ttys[dev] = { input: [], output: [], ops: ops };
2088
        FS.registerDevice(dev, TTY.stream_ops);
2089
      },stream_ops:{open:function(stream) {
2090
          var tty = TTY.ttys[stream.node.rdev];
2091
          if (!tty) {
2092
            throw new FS.ErrnoError(43);
2093
          }
2094
          stream.tty = tty;
2095
          stream.seekable = false;
2096
        },close:function(stream) {
2097
          // flush any pending line data
2098
          stream.tty.ops.flush(stream.tty);
2099
        },flush:function(stream) {
2100
          stream.tty.ops.flush(stream.tty);
2101
        },read:function(stream, buffer, offset, length, pos /* ignored */) {
2102
          if (!stream.tty || !stream.tty.ops.get_char) {
2103
            throw new FS.ErrnoError(60);
2104
          }
2105
          var bytesRead = 0;
2106
          for (var i = 0; i < length; i++) {
2107
            var result;
2108
            try {
2109
              result = stream.tty.ops.get_char(stream.tty);
2110
            } catch (e) {
2111
              throw new FS.ErrnoError(29);
2112
            }
2113
            if (result === undefined && bytesRead === 0) {
2114
              throw new FS.ErrnoError(6);
2115
            }
2116
            if (result === null || result === undefined) break;
2117
            bytesRead++;
2118
            buffer[offset+i] = result;
2119
          }
2120
          if (bytesRead) {
2121
            stream.node.timestamp = Date.now();
2122
          }
2123
          return bytesRead;
2124
        },write:function(stream, buffer, offset, length, pos) {
2125
          if (!stream.tty || !stream.tty.ops.put_char) {
2126
            throw new FS.ErrnoError(60);
2127
          }
2128
          try {
2129
            for (var i = 0; i < length; i++) {
2130
              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
2131
            }
2132
          } catch (e) {
2133
            throw new FS.ErrnoError(29);
2134
          }
2135
          if (length) {
2136
            stream.node.timestamp = Date.now();
2137
          }
2138
          return i;
2139
        }},default_tty_ops:{get_char:function(tty) {
2140
          if (!tty.input.length) {
2141
            var result = null;
2142
            if (ENVIRONMENT_IS_NODE) {
2143
              // we will read data by chunks of BUFSIZE
2144
              var BUFSIZE = 256;
2145
              var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE);
2146
              var bytesRead = 0;
2147
  
2148
              try {
2149
                bytesRead = nodeFS.readSync(process.stdin.fd, buf, 0, BUFSIZE, null);
2150
              } catch(e) {
2151
                // Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,
2152
                // reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.
2153
                if (e.toString().indexOf('EOF') != -1) bytesRead = 0;
2154
                else throw e;
2155
              }
2156
  
2157
              if (bytesRead > 0) {
2158
                result = buf.slice(0, bytesRead).toString('utf-8');
2159
              } else {
2160
                result = null;
2161
              }
2162
            } else
2163
            if (typeof window != 'undefined' &&
2164
              typeof window.prompt == 'function') {
2165
              // Browser.
2166
              result = window.prompt('Input: ');  // returns null on cancel
2167
              if (result !== null) {
2168
                result += '\n';
2169
              }
2170
            } else if (typeof readline == 'function') {
2171
              // Command line.
2172
              result = readline();
2173
              if (result !== null) {
2174
                result += '\n';
2175
              }
2176
            }
2177
            if (!result) {
2178
              return null;
2179
            }
2180
            tty.input = intArrayFromString(result, true);
2181
          }
2182
          return tty.input.shift();
2183
        },put_char:function(tty, val) {
2184
          if (val === null || val === 10) {
2185
            out(UTF8ArrayToString(tty.output, 0));
2186
            tty.output = [];
2187
          } else {
2188
            if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
2189
          }
2190
        },flush:function(tty) {
2191
          if (tty.output && tty.output.length > 0) {
2192
            out(UTF8ArrayToString(tty.output, 0));
2193
            tty.output = [];
2194
          }
2195
        }},default_tty1_ops:{put_char:function(tty, val) {
2196
          if (val === null || val === 10) {
2197
            err(UTF8ArrayToString(tty.output, 0));
2198
            tty.output = [];
2199
          } else {
2200
            if (val != 0) tty.output.push(val);
2201
          }
2202
        },flush:function(tty) {
2203
          if (tty.output && tty.output.length > 0) {
2204
            err(UTF8ArrayToString(tty.output, 0));
2205
            tty.output = [];
2206
          }
2207
        }}};
2208
  
2209
  var MEMFS={ops_table:null,mount:function(mount) {
2210
        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
2211
      },createNode:function(parent, name, mode, dev) {
2212
        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
2213
          // no supported
2214
          throw new FS.ErrnoError(63);
2215
        }
2216
        if (!MEMFS.ops_table) {
2217
          MEMFS.ops_table = {
2218
            dir: {
2219
              node: {
2220
                getattr: MEMFS.node_ops.getattr,
2221
                setattr: MEMFS.node_ops.setattr,
2222
                lookup: MEMFS.node_ops.lookup,
2223
                mknod: MEMFS.node_ops.mknod,
2224
                rename: MEMFS.node_ops.rename,
2225
                unlink: MEMFS.node_ops.unlink,
2226
                rmdir: MEMFS.node_ops.rmdir,
2227
                readdir: MEMFS.node_ops.readdir,
2228
                symlink: MEMFS.node_ops.symlink
2229
              },
2230
              stream: {
2231
                llseek: MEMFS.stream_ops.llseek
2232
              }
2233
            },
2234
            file: {
2235
              node: {
2236
                getattr: MEMFS.node_ops.getattr,
2237
                setattr: MEMFS.node_ops.setattr
2238
              },
2239
              stream: {
2240
                llseek: MEMFS.stream_ops.llseek,
2241
                read: MEMFS.stream_ops.read,
2242
                write: MEMFS.stream_ops.write,
2243
                allocate: MEMFS.stream_ops.allocate,
2244
                mmap: MEMFS.stream_ops.mmap,
2245
                msync: MEMFS.stream_ops.msync
2246
              }
2247
            },
2248
            link: {
2249
              node: {
2250
                getattr: MEMFS.node_ops.getattr,
2251
                setattr: MEMFS.node_ops.setattr,
2252
                readlink: MEMFS.node_ops.readlink
2253
              },
2254
              stream: {}
2255
            },
2256
            chrdev: {
2257
              node: {
2258
                getattr: MEMFS.node_ops.getattr,
2259
                setattr: MEMFS.node_ops.setattr
2260
              },
2261
              stream: FS.chrdev_stream_ops
2262
            }
2263
          };
2264
        }
2265
        var node = FS.createNode(parent, name, mode, dev);
2266
        if (FS.isDir(node.mode)) {
2267
          node.node_ops = MEMFS.ops_table.dir.node;
2268
          node.stream_ops = MEMFS.ops_table.dir.stream;
2269
          node.contents = {};
2270
        } else if (FS.isFile(node.mode)) {
2271
          node.node_ops = MEMFS.ops_table.file.node;
2272
          node.stream_ops = MEMFS.ops_table.file.stream;
2273
          node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
2274
          // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
2275
          // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
2276
          // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
2277
          node.contents = null; 
2278
        } else if (FS.isLink(node.mode)) {
2279
          node.node_ops = MEMFS.ops_table.link.node;
2280
          node.stream_ops = MEMFS.ops_table.link.stream;
2281
        } else if (FS.isChrdev(node.mode)) {
2282
          node.node_ops = MEMFS.ops_table.chrdev.node;
2283
          node.stream_ops = MEMFS.ops_table.chrdev.stream;
2284
        }
2285
        node.timestamp = Date.now();
2286
        // add the new node to the parent
2287
        if (parent) {
2288
          parent.contents[name] = node;
2289
        }
2290
        return node;
2291
      },getFileDataAsRegularArray:function(node) {
2292
        if (node.contents && node.contents.subarray) {
2293
          var arr = [];
2294
          for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]);
2295
          return arr; // Returns a copy of the original data.
2296
        }
2297
        return node.contents; // No-op, the file contents are already in a JS array. Return as-is.
2298
      },getFileDataAsTypedArray:function(node) {
2299
        if (!node.contents) return new Uint8Array(0);
2300
        if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
2301
        return new Uint8Array(node.contents);
2302
      },expandFileStorage:function(node, newCapacity) {
2303
        var prevCapacity = node.contents ? node.contents.length : 0;
2304
        if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
2305
        // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
2306
        // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
2307
        // avoid overshooting the allocation cap by a very large margin.
2308
        var CAPACITY_DOUBLING_MAX = 1024 * 1024;
2309
        newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
2310
        if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
2311
        var oldContents = node.contents;
2312
        node.contents = new Uint8Array(newCapacity); // Allocate new storage.
2313
        if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
2314
        return;
2315
      },resizeFileStorage:function(node, newSize) {
2316
        if (node.usedBytes == newSize) return;
2317
        if (newSize == 0) {
2318
          node.contents = null; // Fully decommit when requesting a resize to zero.
2319
          node.usedBytes = 0;
2320
          return;
2321
        }
2322
        if (!node.contents || node.contents.subarray) { // Resize a typed array if that is being used as the backing store.
2323
          var oldContents = node.contents;
2324
          node.contents = new Uint8Array(newSize); // Allocate new storage.
2325
          if (oldContents) {
2326
            node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
2327
          }
2328
          node.usedBytes = newSize;
2329
          return;
2330
        }
2331
        // Backing with a JS array.
2332
        if (!node.contents) node.contents = [];
2333
        if (node.contents.length > newSize) node.contents.length = newSize;
2334
        else while (node.contents.length < newSize) node.contents.push(0);
2335
        node.usedBytes = newSize;
2336
      },node_ops:{getattr:function(node) {
2337
          var attr = {};
2338
          // device numbers reuse inode numbers.
2339
          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
2340
          attr.ino = node.id;
2341
          attr.mode = node.mode;
2342
          attr.nlink = 1;
2343
          attr.uid = 0;
2344
          attr.gid = 0;
2345
          attr.rdev = node.rdev;
2346
          if (FS.isDir(node.mode)) {
2347
            attr.size = 4096;
2348
          } else if (FS.isFile(node.mode)) {
2349
            attr.size = node.usedBytes;
2350
          } else if (FS.isLink(node.mode)) {
2351
            attr.size = node.link.length;
2352
          } else {
2353
            attr.size = 0;
2354
          }
2355
          attr.atime = new Date(node.timestamp);
2356
          attr.mtime = new Date(node.timestamp);
2357
          attr.ctime = new Date(node.timestamp);
2358
          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
2359
          //       but this is not required by the standard.
2360
          attr.blksize = 4096;
2361
          attr.blocks = Math.ceil(attr.size / attr.blksize);
2362
          return attr;
2363
        },setattr:function(node, attr) {
2364
          if (attr.mode !== undefined) {
2365
            node.mode = attr.mode;
2366
          }
2367
          if (attr.timestamp !== undefined) {
2368
            node.timestamp = attr.timestamp;
2369
          }
2370
          if (attr.size !== undefined) {
2371
            MEMFS.resizeFileStorage(node, attr.size);
2372
          }
2373
        },lookup:function(parent, name) {
2374
          throw FS.genericErrors[44];
2375
        },mknod:function(parent, name, mode, dev) {
2376
          return MEMFS.createNode(parent, name, mode, dev);
2377
        },rename:function(old_node, new_dir, new_name) {
2378
          // if we're overwriting a directory at new_name, make sure it's empty.
2379
          if (FS.isDir(old_node.mode)) {
2380
            var new_node;
2381
            try {
2382
              new_node = FS.lookupNode(new_dir, new_name);
2383
            } catch (e) {
2384
            }
2385
            if (new_node) {
2386
              for (var i in new_node.contents) {
2387
                throw new FS.ErrnoError(55);
2388
              }
2389
            }
2390
          }
2391
          // do the internal rewiring
2392
          delete old_node.parent.contents[old_node.name];
2393
          old_node.name = new_name;
2394
          new_dir.contents[new_name] = old_node;
2395
          old_node.parent = new_dir;
2396
        },unlink:function(parent, name) {
2397
          delete parent.contents[name];
2398
        },rmdir:function(parent, name) {
2399
          var node = FS.lookupNode(parent, name);
2400
          for (var i in node.contents) {
2401
            throw new FS.ErrnoError(55);
2402
          }
2403
          delete parent.contents[name];
2404
        },readdir:function(node) {
2405
          var entries = ['.', '..'];
2406
          for (var key in node.contents) {
2407
            if (!node.contents.hasOwnProperty(key)) {
2408
              continue;
2409
            }
2410
            entries.push(key);
2411
          }
2412
          return entries;
2413
        },symlink:function(parent, newname, oldpath) {
2414
          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
2415
          node.link = oldpath;
2416
          return node;
2417
        },readlink:function(node) {
2418
          if (!FS.isLink(node.mode)) {
2419
            throw new FS.ErrnoError(28);
2420
          }
2421
          return node.link;
2422
        }},stream_ops:{read:function(stream, buffer, offset, length, position) {
2423
          var contents = stream.node.contents;
2424
          if (position >= stream.node.usedBytes) return 0;
2425
          var size = Math.min(stream.node.usedBytes - position, length);
2426
          assert(size >= 0);
2427
          if (size > 8 && contents.subarray) { // non-trivial, and typed array
2428
            buffer.set(contents.subarray(position, position + size), offset);
2429
          } else {
2430
            for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
2431
          }
2432
          return size;
2433
        },write:function(stream, buffer, offset, length, position, canOwn) {
2434
          // The data buffer should be a typed array view
2435
          assert(!(buffer instanceof ArrayBuffer));
2436
  
2437
          if (!length) return 0;
2438
          var node = stream.node;
2439
          node.timestamp = Date.now();
2440
  
2441
          if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
2442
            if (canOwn) {
2443
              assert(position === 0, 'canOwn must imply no weird position inside the file');
2444
              node.contents = buffer.subarray(offset, offset + length);
2445
              node.usedBytes = length;
2446
              return length;
2447
            } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
2448
              node.contents = buffer.slice(offset, offset + length);
2449
              node.usedBytes = length;
2450
              return length;
2451
            } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
2452
              node.contents.set(buffer.subarray(offset, offset + length), position);
2453
              return length;
2454
            }
2455
          }
2456
  
2457
          // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
2458
          MEMFS.expandFileStorage(node, position+length);
2459
          if (node.contents.subarray && buffer.subarray) node.contents.set(buffer.subarray(offset, offset + length), position); // Use typed array write if available.
2460
          else {
2461
            for (var i = 0; i < length; i++) {
2462
             node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
2463
            }
2464
          }
2465
          node.usedBytes = Math.max(node.usedBytes, position + length);
2466
          return length;
2467
        },llseek:function(stream, offset, whence) {
2468
          var position = offset;
2469
          if (whence === 1) {
2470
            position += stream.position;
2471
          } else if (whence === 2) {
2472
            if (FS.isFile(stream.node.mode)) {
2473
              position += stream.node.usedBytes;
2474
            }
2475
          }
2476
          if (position < 0) {
2477
            throw new FS.ErrnoError(28);
2478
          }
2479
          return position;
2480
        },allocate:function(stream, offset, length) {
2481
          MEMFS.expandFileStorage(stream.node, offset + length);
2482
          stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length);
2483
        },mmap:function(stream, address, length, position, prot, flags) {
2484
          // We don't currently support location hints for the address of the mapping
2485
          assert(address === 0);
2486
  
2487
          if (!FS.isFile(stream.node.mode)) {
2488
            throw new FS.ErrnoError(43);
2489
          }
2490
          var ptr;
2491
          var allocated;
2492
          var contents = stream.node.contents;
2493
          // Only make a new copy when MAP_PRIVATE is specified.
2494
          if (!(flags & 2) && contents.buffer === buffer) {
2495
            // We can't emulate MAP_SHARED when the file is not backed by the buffer
2496
            // we're mapping to (e.g. the HEAP buffer).
2497
            allocated = false;
2498
            ptr = contents.byteOffset;
2499
          } else {
2500
            // Try to avoid unnecessary slices.
2501
            if (position > 0 || position + length < contents.length) {
2502
              if (contents.subarray) {
2503
                contents = contents.subarray(position, position + length);
2504
              } else {
2505
                contents = Array.prototype.slice.call(contents, position, position + length);
2506
              }
2507
            }
2508
            allocated = true;
2509
            ptr = _malloc(length);
2510
            if (!ptr) {
2511
              throw new FS.ErrnoError(48);
2512
            }
2513
            HEAP8.set(contents, ptr);
2514
          }
2515
          return { ptr: ptr, allocated: allocated };
2516
        },msync:function(stream, buffer, offset, length, mmapFlags) {
2517
          if (!FS.isFile(stream.node.mode)) {
2518
            throw new FS.ErrnoError(43);
2519
          }
2520
          if (mmapFlags & 2) {
2521
            // MAP_PRIVATE calls need not to be synced back to underlying fs
2522
            return 0;
2523
          }
2524
  
2525
          var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
2526
          // should we check if bytesWritten and length are the same?
2527
          return 0;
2528
        }}};
2529
  
2530
  var ERRNO_MESSAGES={0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can   access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"};
2531
  
2532
  var ERRNO_CODES={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6,EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118,ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23,EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,handleFSError:function(e) {
2533
        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
2534
        return setErrNo(e.errno);
2535
      },lookupPath:function(path, opts) {
2536
        path = PATH_FS.resolve(FS.cwd(), path);
2537
        opts = opts || {};
2538
  
2539
        if (!path) return { path: '', node: null };
2540
  
2541
        var defaults = {
2542
          follow_mount: true,
2543
          recurse_count: 0
2544
        };
2545
        for (var key in defaults) {
2546
          if (opts[key] === undefined) {
2547
            opts[key] = defaults[key];
2548
          }
2549
        }
2550
  
2551
        if (opts.recurse_count > 8) {  // max recursive lookup of 8
2552
          throw new FS.ErrnoError(32);
2553
        }
2554
  
2555
        // split the path
2556
        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
2557
          return !!p;
2558
        }), false);
2559
  
2560
        // start at the root
2561
        var current = FS.root;
2562
        var current_path = '/';
2563
  
2564
        for (var i = 0; i < parts.length; i++) {
2565
          var islast = (i === parts.length-1);
2566
          if (islast && opts.parent) {
2567
            // stop resolving
2568
            break;
2569
          }
2570
  
2571
          current = FS.lookupNode(current, parts[i]);
2572
          current_path = PATH.join2(current_path, parts[i]);
2573
  
2574
          // jump to the mount's root node if this is a mountpoint
2575
          if (FS.isMountpoint(current)) {
2576
            if (!islast || (islast && opts.follow_mount)) {
2577
              current = current.mounted.root;
2578
            }
2579
          }
2580
  
2581
          // by default, lookupPath will not follow a symlink if it is the final path component.
2582
          // setting opts.follow = true will override this behavior.
2583
          if (!islast || opts.follow) {
2584
            var count = 0;
2585
            while (FS.isLink(current.mode)) {
2586
              var link = FS.readlink(current_path);
2587
              current_path = PATH_FS.resolve(PATH.dirname(current_path), link);
2588
  
2589
              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
2590
              current = lookup.node;
2591
  
2592
              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
2593
                throw new FS.ErrnoError(32);
2594
              }
2595
            }
2596
          }
2597
        }
2598
  
2599
        return { path: current_path, node: current };
2600
      },getPath:function(node) {
2601
        var path;
2602
        while (true) {
2603
          if (FS.isRoot(node)) {
2604
            var mount = node.mount.mountpoint;
2605
            if (!path) return mount;
2606
            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
2607
          }
2608
          path = path ? node.name + '/' + path : node.name;
2609
          node = node.parent;
2610
        }
2611
      },hashName:function(parentid, name) {
2612
        var hash = 0;
2613
  
2614
  
2615
        for (var i = 0; i < name.length; i++) {
2616
          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
2617
        }
2618
        return ((parentid + hash) >>> 0) % FS.nameTable.length;
2619
      },hashAddNode:function(node) {
2620
        var hash = FS.hashName(node.parent.id, node.name);
2621
        node.name_next = FS.nameTable[hash];
2622
        FS.nameTable[hash] = node;
2623
      },hashRemoveNode:function(node) {
2624
        var hash = FS.hashName(node.parent.id, node.name);
2625
        if (FS.nameTable[hash] === node) {
2626
          FS.nameTable[hash] = node.name_next;
2627
        } else {
2628
          var current = FS.nameTable[hash];
2629
          while (current) {
2630
            if (current.name_next === node) {
2631
              current.name_next = node.name_next;
2632
              break;
2633
            }
2634
            current = current.name_next;
2635
          }
2636
        }
2637
      },lookupNode:function(parent, name) {
2638
        var errCode = FS.mayLookup(parent);
2639
        if (errCode) {
2640
          throw new FS.ErrnoError(errCode, parent);
2641
        }
2642
        var hash = FS.hashName(parent.id, name);
2643
        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
2644
          var nodeName = node.name;
2645
          if (node.parent.id === parent.id && nodeName === name) {
2646
            return node;
2647
          }
2648
        }
2649
        // if we failed to find it in the cache, call into the VFS
2650
        return FS.lookup(parent, name);
2651
      },createNode:function(parent, name, mode, rdev) {
2652
        var node = new FS.FSNode(parent, name, mode, rdev);
2653
  
2654
        FS.hashAddNode(node);
2655
  
2656
        return node;
2657
      },destroyNode:function(node) {
2658
        FS.hashRemoveNode(node);
2659
      },isRoot:function(node) {
2660
        return node === node.parent;
2661
      },isMountpoint:function(node) {
2662
        return !!node.mounted;
2663
      },isFile:function(mode) {
2664
        return (mode & 61440) === 32768;
2665
      },isDir:function(mode) {
2666
        return (mode & 61440) === 16384;
2667
      },isLink:function(mode) {
2668
        return (mode & 61440) === 40960;
2669
      },isChrdev:function(mode) {
2670
        return (mode & 61440) === 8192;
2671
      },isBlkdev:function(mode) {
2672
        return (mode & 61440) === 24576;
2673
      },isFIFO:function(mode) {
2674
        return (mode & 61440) === 4096;
2675
      },isSocket:function(mode) {
2676
        return (mode & 49152) === 49152;
2677
      },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) {
2678
        var flags = FS.flagModes[str];
2679
        if (typeof flags === 'undefined') {
2680
          throw new Error('Unknown file open mode: ' + str);
2681
        }
2682
        return flags;
2683
      },flagsToPermissionString:function(flag) {
2684
        var perms = ['r', 'w', 'rw'][flag & 3];
2685
        if ((flag & 512)) {
2686
          perms += 'w';
2687
        }
2688
        return perms;
2689
      },nodePermissions:function(node, perms) {
2690
        if (FS.ignorePermissions) {
2691
          return 0;
2692
        }
2693
        // return 0 if any user, group or owner bits are set.
2694
        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
2695
          return 2;
2696
        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
2697
          return 2;
2698
        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
2699
          return 2;
2700
        }
2701
        return 0;
2702
      },mayLookup:function(dir) {
2703
        var errCode = FS.nodePermissions(dir, 'x');
2704
        if (errCode) return errCode;
2705
        if (!dir.node_ops.lookup) return 2;
2706
        return 0;
2707
      },mayCreate:function(dir, name) {
2708
        try {
2709
          var node = FS.lookupNode(dir, name);
2710
          return 20;
2711
        } catch (e) {
2712
        }
2713
        return FS.nodePermissions(dir, 'wx');
2714
      },mayDelete:function(dir, name, isdir) {
2715
        var node;
2716
        try {
2717
          node = FS.lookupNode(dir, name);
2718
        } catch (e) {
2719
          return e.errno;
2720
        }
2721
        var errCode = FS.nodePermissions(dir, 'wx');
2722
        if (errCode) {
2723
          return errCode;
2724
        }
2725
        if (isdir) {
2726
          if (!FS.isDir(node.mode)) {
2727
            return 54;
2728
          }
2729
          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
2730
            return 10;
2731
          }
2732
        } else {
2733
          if (FS.isDir(node.mode)) {
2734
            return 31;
2735
          }
2736
        }
2737
        return 0;
2738
      },mayOpen:function(node, flags) {
2739
        if (!node) {
2740
          return 44;
2741
        }
2742
        if (FS.isLink(node.mode)) {
2743
          return 32;
2744
        } else if (FS.isDir(node.mode)) {
2745
          if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write
2746
              (flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only)
2747
            return 31;
2748
          }
2749
        }
2750
        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
2751
      },MAX_OPEN_FDS:4096,nextfd:function(fd_start, fd_end) {
2752
        fd_start = fd_start || 0;
2753
        fd_end = fd_end || FS.MAX_OPEN_FDS;
2754
        for (var fd = fd_start; fd <= fd_end; fd++) {
2755
          if (!FS.streams[fd]) {
2756
            return fd;
2757
          }
2758
        }
2759
        throw new FS.ErrnoError(33);
2760
      },getStream:function(fd) {
2761
        return FS.streams[fd];
2762
      },createStream:function(stream, fd_start, fd_end) {
2763
        if (!FS.FSStream) {
2764
          FS.FSStream = /** @constructor */ function(){};
2765
          FS.FSStream.prototype = {
2766
            object: {
2767
              get: function() { return this.node; },
2768
              set: function(val) { this.node = val; }
2769
            },
2770
            isRead: {
2771
              get: function() { return (this.flags & 2097155) !== 1; }
2772
            },
2773
            isWrite: {
2774
              get: function() { return (this.flags & 2097155) !== 0; }
2775
            },
2776
            isAppend: {
2777
              get: function() { return (this.flags & 1024); }
2778
            }
2779
          };
2780
        }
2781
        // clone it, so we can return an instance of FSStream
2782
        var newStream = new FS.FSStream();
2783
        for (var p in stream) {
2784
          newStream[p] = stream[p];
2785
        }
2786
        stream = newStream;
2787
        var fd = FS.nextfd(fd_start, fd_end);
2788
        stream.fd = fd;
2789
        FS.streams[fd] = stream;
2790
        return stream;
2791
      },closeStream:function(fd) {
2792
        FS.streams[fd] = null;
2793
      },chrdev_stream_ops:{open:function(stream) {
2794
          var device = FS.getDevice(stream.node.rdev);
2795
          // override node's stream ops with the device's
2796
          stream.stream_ops = device.stream_ops;
2797
          // forward the open call
2798
          if (stream.stream_ops.open) {
2799
            stream.stream_ops.open(stream);
2800
          }
2801
        },llseek:function() {
2802
          throw new FS.ErrnoError(70);
2803
        }},major:function(dev) {
2804
        return ((dev) >> 8);
2805
      },minor:function(dev) {
2806
        return ((dev) & 0xff);
2807
      },makedev:function(ma, mi) {
2808
        return ((ma) << 8 | (mi));
2809
      },registerDevice:function(dev, ops) {
2810
        FS.devices[dev] = { stream_ops: ops };
2811
      },getDevice:function(dev) {
2812
        return FS.devices[dev];
2813
      },getMounts:function(mount) {
2814
        var mounts = [];
2815
        var check = [mount];
2816
  
2817
        while (check.length) {
2818
          var m = check.pop();
2819
  
2820
          mounts.push(m);
2821
  
2822
          check.push.apply(check, m.mounts);
2823
        }
2824
  
2825
        return mounts;
2826
      },syncfs:function(populate, callback) {
2827
        if (typeof(populate) === 'function') {
2828
          callback = populate;
2829
          populate = false;
2830
        }
2831
  
2832
        FS.syncFSRequests++;
2833
  
2834
        if (FS.syncFSRequests > 1) {
2835
          err('warning: ' + FS.syncFSRequests + ' FS.syncfs operations in flight at once, probably just doing extra work');
2836
        }
2837
  
2838
        var mounts = FS.getMounts(FS.root.mount);
2839
        var completed = 0;
2840
  
2841
        function doCallback(errCode) {
2842
          assert(FS.syncFSRequests > 0);
2843
          FS.syncFSRequests--;
2844
          return callback(errCode);
2845
        }
2846
  
2847
        function done(errCode) {
2848
          if (errCode) {
2849
            if (!done.errored) {
2850
              done.errored = true;
2851
              return doCallback(errCode);
2852
            }
2853
            return;
2854
          }
2855
          if (++completed >= mounts.length) {
2856
            doCallback(null);
2857
          }
2858
        };
2859
  
2860
        // sync all mounts
2861
        mounts.forEach(function (mount) {
2862
          if (!mount.type.syncfs) {
2863
            return done(null);
2864
          }
2865
          mount.type.syncfs(mount, populate, done);
2866
        });
2867
      },mount:function(type, opts, mountpoint) {
2868
        if (typeof type === 'string') {
2869
          // The filesystem was not included, and instead we have an error
2870
          // message stored in the variable.
2871
          throw type;
2872
        }
2873
        var root = mountpoint === '/';
2874
        var pseudo = !mountpoint;
2875
        var node;
2876
  
2877
        if (root && FS.root) {
2878
          throw new FS.ErrnoError(10);
2879
        } else if (!root && !pseudo) {
2880
          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
2881
  
2882
          mountpoint = lookup.path;  // use the absolute path
2883
          node = lookup.node;
2884
  
2885
          if (FS.isMountpoint(node)) {
2886
            throw new FS.ErrnoError(10);
2887
          }
2888
  
2889
          if (!FS.isDir(node.mode)) {
2890
            throw new FS.ErrnoError(54);
2891
          }
2892
        }
2893
  
2894
        var mount = {
2895
          type: type,
2896
          opts: opts,
2897
          mountpoint: mountpoint,
2898
          mounts: []
2899
        };
2900
  
2901
        // create a root node for the fs
2902
        var mountRoot = type.mount(mount);
2903
        mountRoot.mount = mount;
2904
        mount.root = mountRoot;
2905
  
2906
        if (root) {
2907
          FS.root = mountRoot;
2908
        } else if (node) {
2909
          // set as a mountpoint
2910
          node.mounted = mount;
2911
  
2912
          // add the new mount to the current mount's children
2913
          if (node.mount) {
2914
            node.mount.mounts.push(mount);
2915
          }
2916
        }
2917
  
2918
        return mountRoot;
2919
      },unmount:function (mountpoint) {
2920
        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
2921
  
2922
        if (!FS.isMountpoint(lookup.node)) {
2923
          throw new FS.ErrnoError(28);
2924
        }
2925
  
2926
        // destroy the nodes for this mount, and all its child mounts
2927
        var node = lookup.node;
2928
        var mount = node.mounted;
2929
        var mounts = FS.getMounts(mount);
2930
  
2931
        Object.keys(FS.nameTable).forEach(function (hash) {
2932
          var current = FS.nameTable[hash];
2933
  
2934
          while (current) {
2935
            var next = current.name_next;
2936
  
2937
            if (mounts.indexOf(current.mount) !== -1) {
2938
              FS.destroyNode(current);
2939
            }
2940
  
2941
            current = next;
2942
          }
2943
        });
2944
  
2945
        // no longer a mountpoint
2946
        node.mounted = null;
2947
  
2948
        // remove this mount from the child mounts
2949
        var idx = node.mount.mounts.indexOf(mount);
2950
        assert(idx !== -1);
2951
        node.mount.mounts.splice(idx, 1);
2952
      },lookup:function(parent, name) {
2953
        return parent.node_ops.lookup(parent, name);
2954
      },mknod:function(path, mode, dev) {
2955
        var lookup = FS.lookupPath(path, { parent: true });
2956
        var parent = lookup.node;
2957
        var name = PATH.basename(path);
2958
        if (!name || name === '.' || name === '..') {
2959
          throw new FS.ErrnoError(28);
2960
        }
2961
        var errCode = FS.mayCreate(parent, name);
2962
        if (errCode) {
2963
          throw new FS.ErrnoError(errCode);
2964
        }
2965
        if (!parent.node_ops.mknod) {
2966
          throw new FS.ErrnoError(63);
2967
        }
2968
        return parent.node_ops.mknod(parent, name, mode, dev);
2969
      },create:function(path, mode) {
2970
        mode = mode !== undefined ? mode : 438 /* 0666 */;
2971
        mode &= 4095;
2972
        mode |= 32768;
2973
        return FS.mknod(path, mode, 0);
2974
      },mkdir:function(path, mode) {
2975
        mode = mode !== undefined ? mode : 511 /* 0777 */;
2976
        mode &= 511 | 512;
2977
        mode |= 16384;
2978
        return FS.mknod(path, mode, 0);
2979
      },mkdirTree:function(path, mode) {
2980
        var dirs = path.split('/');
2981
        var d = '';
2982
        for (var i = 0; i < dirs.length; ++i) {
2983
          if (!dirs[i]) continue;
2984
          d += '/' + dirs[i];
2985
          try {
2986
            FS.mkdir(d, mode);
2987
          } catch(e) {
2988
            if (e.errno != 20) throw e;
2989
          }
2990
        }
2991
      },mkdev:function(path, mode, dev) {
2992
        if (typeof(dev) === 'undefined') {
2993
          dev = mode;
2994
          mode = 438 /* 0666 */;
2995
        }
2996
        mode |= 8192;
2997
        return FS.mknod(path, mode, dev);
2998
      },symlink:function(oldpath, newpath) {
2999
        if (!PATH_FS.resolve(oldpath)) {
3000
          throw new FS.ErrnoError(44);
3001
        }
3002
        var lookup = FS.lookupPath(newpath, { parent: true });
3003
        var parent = lookup.node;
3004
        if (!parent) {
3005
          throw new FS.ErrnoError(44);
3006
        }
3007
        var newname = PATH.basename(newpath);
3008
        var errCode = FS.mayCreate(parent, newname);
3009
        if (errCode) {
3010
          throw new FS.ErrnoError(errCode);
3011
        }
3012
        if (!parent.node_ops.symlink) {
3013
          throw new FS.ErrnoError(63);
3014
        }
3015
        return parent.node_ops.symlink(parent, newname, oldpath);
3016
      },rename:function(old_path, new_path) {
3017
        var old_dirname = PATH.dirname(old_path);
3018
        var new_dirname = PATH.dirname(new_path);
3019
        var old_name = PATH.basename(old_path);
3020
        var new_name = PATH.basename(new_path);
3021
        // parents must exist
3022
        var lookup, old_dir, new_dir;
3023
        try {
3024
          lookup = FS.lookupPath(old_path, { parent: true });
3025
          old_dir = lookup.node;
3026
          lookup = FS.lookupPath(new_path, { parent: true });
3027
          new_dir = lookup.node;
3028
        } catch (e) {
3029
          throw new FS.ErrnoError(10);
3030
        }
3031
        if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
3032
        // need to be part of the same mount
3033
        if (old_dir.mount !== new_dir.mount) {
3034
          throw new FS.ErrnoError(75);
3035
        }
3036
        // source must exist
3037
        var old_node = FS.lookupNode(old_dir, old_name);
3038
        // old path should not be an ancestor of the new path
3039
        var relative = PATH_FS.relative(old_path, new_dirname);
3040
        if (relative.charAt(0) !== '.') {
3041
          throw new FS.ErrnoError(28);
3042
        }
3043
        // new path should not be an ancestor of the old path
3044
        relative = PATH_FS.relative(new_path, old_dirname);
3045
        if (relative.charAt(0) !== '.') {
3046
          throw new FS.ErrnoError(55);
3047
        }
3048
        // see if the new path already exists
3049
        var new_node;
3050
        try {
3051
          new_node = FS.lookupNode(new_dir, new_name);
3052
        } catch (e) {
3053
          // not fatal
3054
        }
3055
        // early out if nothing needs to change
3056
        if (old_node === new_node) {
3057
          return;
3058
        }
3059
        // we'll need to delete the old entry
3060
        var isdir = FS.isDir(old_node.mode);
3061
        var errCode = FS.mayDelete(old_dir, old_name, isdir);
3062
        if (errCode) {
3063
          throw new FS.ErrnoError(errCode);
3064
        }
3065
        // need delete permissions if we'll be overwriting.
3066
        // need create permissions if new doesn't already exist.
3067
        errCode = new_node ?
3068
          FS.mayDelete(new_dir, new_name, isdir) :
3069
          FS.mayCreate(new_dir, new_name);
3070
        if (errCode) {
3071
          throw new FS.ErrnoError(errCode);
3072
        }
3073
        if (!old_dir.node_ops.rename) {
3074
          throw new FS.ErrnoError(63);
3075
        }
3076
        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
3077
          throw new FS.ErrnoError(10);
3078
        }
3079
        // if we are going to change the parent, check write permissions
3080
        if (new_dir !== old_dir) {
3081
          errCode = FS.nodePermissions(old_dir, 'w');
3082
          if (errCode) {
3083
            throw new FS.ErrnoError(errCode);
3084
          }
3085
        }
3086
        try {
3087
          if (FS.trackingDelegate['willMovePath']) {
3088
            FS.trackingDelegate['willMovePath'](old_path, new_path);
3089
          }
3090
        } catch(e) {
3091
          err("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message);
3092
        }
3093
        // remove the node from the lookup hash
3094
        FS.hashRemoveNode(old_node);
3095
        // do the underlying fs rename
3096
        try {
3097
          old_dir.node_ops.rename(old_node, new_dir, new_name);
3098
        } catch (e) {
3099
          throw e;
3100
        } finally {
3101
          // add the node back to the hash (in case node_ops.rename
3102
          // changed its name)
3103
          FS.hashAddNode(old_node);
3104
        }
3105
        try {
3106
          if (FS.trackingDelegate['onMovePath']) FS.trackingDelegate['onMovePath'](old_path, new_path);
3107
        } catch(e) {
3108
          err("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message);
3109
        }
3110
      },rmdir:function(path) {
3111
        var lookup = FS.lookupPath(path, { parent: true });
3112
        var parent = lookup.node;
3113
        var name = PATH.basename(path);
3114
        var node = FS.lookupNode(parent, name);
3115
        var errCode = FS.mayDelete(parent, name, true);
3116
        if (errCode) {
3117
          throw new FS.ErrnoError(errCode);
3118
        }
3119
        if (!parent.node_ops.rmdir) {
3120
          throw new FS.ErrnoError(63);
3121
        }
3122
        if (FS.isMountpoint(node)) {
3123
          throw new FS.ErrnoError(10);
3124
        }
3125
        try {
3126
          if (FS.trackingDelegate['willDeletePath']) {
3127
            FS.trackingDelegate['willDeletePath'](path);
3128
          }
3129
        } catch(e) {
3130
          err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message);
3131
        }
3132
        parent.node_ops.rmdir(parent, name);
3133
        FS.destroyNode(node);
3134
        try {
3135
          if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path);
3136
        } catch(e) {
3137
          err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message);
3138
        }
3139
      },readdir:function(path) {
3140
        var lookup = FS.lookupPath(path, { follow: true });
3141
        var node = lookup.node;
3142
        if (!node.node_ops.readdir) {
3143
          throw new FS.ErrnoError(54);
3144
        }
3145
        return node.node_ops.readdir(node);
3146
      },unlink:function(path) {
3147
        var lookup = FS.lookupPath(path, { parent: true });
3148
        var parent = lookup.node;
3149
        var name = PATH.basename(path);
3150
        var node = FS.lookupNode(parent, name);
3151
        var errCode = FS.mayDelete(parent, name, false);
3152
        if (errCode) {
3153
          // According to POSIX, we should map EISDIR to EPERM, but
3154
          // we instead do what Linux does (and we must, as we use
3155
          // the musl linux libc).
3156
          throw new FS.ErrnoError(errCode);
3157
        }
3158
        if (!parent.node_ops.unlink) {
3159
          throw new FS.ErrnoError(63);
3160
        }
3161
        if (FS.isMountpoint(node)) {
3162
          throw new FS.ErrnoError(10);
3163
        }
3164
        try {
3165
          if (FS.trackingDelegate['willDeletePath']) {
3166
            FS.trackingDelegate['willDeletePath'](path);
3167
          }
3168
        } catch(e) {
3169
          err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message);
3170
        }
3171
        parent.node_ops.unlink(parent, name);
3172
        FS.destroyNode(node);
3173
        try {
3174
          if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path);
3175
        } catch(e) {
3176
          err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message);
3177
        }
3178
      },readlink:function(path) {
3179
        var lookup = FS.lookupPath(path);
3180
        var link = lookup.node;
3181
        if (!link) {
3182
          throw new FS.ErrnoError(44);
3183
        }
3184
        if (!link.node_ops.readlink) {
3185
          throw new FS.ErrnoError(28);
3186
        }
3187
        return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
3188
      },stat:function(path, dontFollow) {
3189
        var lookup = FS.lookupPath(path, { follow: !dontFollow });
3190
        var node = lookup.node;
3191
        if (!node) {
3192
          throw new FS.ErrnoError(44);
3193
        }
3194
        if (!node.node_ops.getattr) {
3195
          throw new FS.ErrnoError(63);
3196
        }
3197
        return node.node_ops.getattr(node);
3198
      },lstat:function(path) {
3199
        return FS.stat(path, true);
3200
      },chmod:function(path, mode, dontFollow) {
3201
        var node;
3202
        if (typeof path === 'string') {
3203
          var lookup = FS.lookupPath(path, { follow: !dontFollow });
3204
          node = lookup.node;
3205
        } else {
3206
          node = path;
3207
        }
3208
        if (!node.node_ops.setattr) {
3209
          throw new FS.ErrnoError(63);
3210
        }
3211
        node.node_ops.setattr(node, {
3212
          mode: (mode & 4095) | (node.mode & ~4095),
3213
          timestamp: Date.now()
3214
        });
3215
      },lchmod:function(path, mode) {
3216
        FS.chmod(path, mode, true);
3217
      },fchmod:function(fd, mode) {
3218
        var stream = FS.getStream(fd);
3219
        if (!stream) {
3220
          throw new FS.ErrnoError(8);
3221
        }
3222
        FS.chmod(stream.node, mode);
3223
      },chown:function(path, uid, gid, dontFollow) {
3224
        var node;
3225
        if (typeof path === 'string') {
3226
          var lookup = FS.lookupPath(path, { follow: !dontFollow });
3227
          node = lookup.node;
3228
        } else {
3229
          node = path;
3230
        }
3231
        if (!node.node_ops.setattr) {
3232
          throw new FS.ErrnoError(63);
3233
        }
3234
        node.node_ops.setattr(node, {
3235
          timestamp: Date.now()
3236
          // we ignore the uid / gid for now
3237
        });
3238
      },lchown:function(path, uid, gid) {
3239
        FS.chown(path, uid, gid, true);
3240
      },fchown:function(fd, uid, gid) {
3241
        var stream = FS.getStream(fd);
3242
        if (!stream) {
3243
          throw new FS.ErrnoError(8);
3244
        }
3245
        FS.chown(stream.node, uid, gid);
3246
      },truncate:function(path, len) {
3247
        if (len < 0) {
3248
          throw new FS.ErrnoError(28);
3249
        }
3250
        var node;
3251
        if (typeof path === 'string') {
3252
          var lookup = FS.lookupPath(path, { follow: true });
3253
          node = lookup.node;
3254
        } else {
3255
          node = path;
3256
        }
3257
        if (!node.node_ops.setattr) {
3258
          throw new FS.ErrnoError(63);
3259
        }
3260
        if (FS.isDir(node.mode)) {
3261
          throw new FS.ErrnoError(31);
3262
        }
3263
        if (!FS.isFile(node.mode)) {
3264
          throw new FS.ErrnoError(28);
3265
        }
3266
        var errCode = FS.nodePermissions(node, 'w');
3267
        if (errCode) {
3268
          throw new FS.ErrnoError(errCode);
3269
        }
3270
        node.node_ops.setattr(node, {
3271
          size: len,
3272
          timestamp: Date.now()
3273
        });
3274
      },ftruncate:function(fd, len) {
3275
        var stream = FS.getStream(fd);
3276
        if (!stream) {
3277
          throw new FS.ErrnoError(8);
3278
        }
3279
        if ((stream.flags & 2097155) === 0) {
3280
          throw new FS.ErrnoError(28);
3281
        }
3282
        FS.truncate(stream.node, len);
3283
      },utime:function(path, atime, mtime) {
3284
        var lookup = FS.lookupPath(path, { follow: true });
3285
        var node = lookup.node;
3286
        node.node_ops.setattr(node, {
3287
          timestamp: Math.max(atime, mtime)
3288
        });
3289
      },open:function(path, flags, mode, fd_start, fd_end) {
3290
        if (path === "") {
3291
          throw new FS.ErrnoError(44);
3292
        }
3293
        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
3294
        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
3295
        if ((flags & 64)) {
3296
          mode = (mode & 4095) | 32768;
3297
        } else {
3298
          mode = 0;
3299
        }
3300
        var node;
3301
        if (typeof path === 'object') {
3302
          node = path;
3303
        } else {
3304
          path = PATH.normalize(path);
3305
          try {
3306
            var lookup = FS.lookupPath(path, {
3307
              follow: !(flags & 131072)
3308
            });
3309
            node = lookup.node;
3310
          } catch (e) {
3311
            // ignore
3312
          }
3313
        }
3314
        // perhaps we need to create the node
3315
        var created = false;
3316
        if ((flags & 64)) {
3317
          if (node) {
3318
            // if O_CREAT and O_EXCL are set, error out if the node already exists
3319
            if ((flags & 128)) {
3320
              throw new FS.ErrnoError(20);
3321
            }
3322
          } else {
3323
            // node doesn't exist, try to create it
3324
            node = FS.mknod(path, mode, 0);
3325
            created = true;
3326
          }
3327
        }
3328
        if (!node) {
3329
          throw new FS.ErrnoError(44);
3330
        }
3331
        // can't truncate a device
3332
        if (FS.isChrdev(node.mode)) {
3333
          flags &= ~512;
3334
        }
3335
        // if asked only for a directory, then this must be one
3336
        if ((flags & 65536) && !FS.isDir(node.mode)) {
3337
          throw new FS.ErrnoError(54);
3338
        }
3339
        // check permissions, if this is not a file we just created now (it is ok to
3340
        // create and write to a file with read-only permissions; it is read-only
3341
        // for later use)
3342
        if (!created) {
3343
          var errCode = FS.mayOpen(node, flags);
3344
          if (errCode) {
3345
            throw new FS.ErrnoError(errCode);
3346
          }
3347
        }
3348
        // do truncation if necessary
3349
        if ((flags & 512)) {
3350
          FS.truncate(node, 0);
3351
        }
3352
        // we've already handled these, don't pass down to the underlying vfs
3353
        flags &= ~(128 | 512 | 131072);
3354
  
3355
        // register the stream with the filesystem
3356
        var stream = FS.createStream({
3357
          node: node,
3358
          path: FS.getPath(node),  // we want the absolute path to the node
3359
          flags: flags,
3360
          seekable: true,
3361
          position: 0,
3362
          stream_ops: node.stream_ops,
3363
          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
3364
          ungotten: [],
3365
          error: false
3366
        }, fd_start, fd_end);
3367
        // call the new stream's open function
3368
        if (stream.stream_ops.open) {
3369
          stream.stream_ops.open(stream);
3370
        }
3371
        if (Module['logReadFiles'] && !(flags & 1)) {
3372
          if (!FS.readFiles) FS.readFiles = {};
3373
          if (!(path in FS.readFiles)) {
3374
            FS.readFiles[path] = 1;
3375
            err("FS.trackingDelegate error on read file: " + path);
3376
          }
3377
        }
3378
        try {
3379
          if (FS.trackingDelegate['onOpenFile']) {
3380
            var trackingFlags = 0;
3381
            if ((flags & 2097155) !== 1) {
3382
              trackingFlags |= FS.tracking.openFlags.READ;
3383
            }
3384
            if ((flags & 2097155) !== 0) {
3385
              trackingFlags |= FS.tracking.openFlags.WRITE;
3386
            }
3387
            FS.trackingDelegate['onOpenFile'](path, trackingFlags);
3388
          }
3389
        } catch(e) {
3390
          err("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: " + e.message);
3391
        }
3392
        return stream;
3393
      },close:function(stream) {
3394
        if (FS.isClosed(stream)) {
3395
          throw new FS.ErrnoError(8);
3396
        }
3397
        if (stream.getdents) stream.getdents = null; // free readdir state
3398
        try {
3399
          if (stream.stream_ops.close) {
3400
            stream.stream_ops.close(stream);
3401
          }
3402
        } catch (e) {
3403
          throw e;
3404
        } finally {
3405
          FS.closeStream(stream.fd);
3406
        }
3407
        stream.fd = null;
3408
      },isClosed:function(stream) {
3409
        return stream.fd === null;
3410
      },llseek:function(stream, offset, whence) {
3411
        if (FS.isClosed(stream)) {
3412
          throw new FS.ErrnoError(8);
3413
        }
3414
        if (!stream.seekable || !stream.stream_ops.llseek) {
3415
          throw new FS.ErrnoError(70);
3416
        }
3417
        if (whence != 0 && whence != 1 && whence != 2) {
3418
          throw new FS.ErrnoError(28);
3419
        }
3420
        stream.position = stream.stream_ops.llseek(stream, offset, whence);
3421
        stream.ungotten = [];
3422
        return stream.position;
3423
      },read:function(stream, buffer, offset, length, position) {
3424
        if (length < 0 || position < 0) {
3425
          throw new FS.ErrnoError(28);
3426
        }
3427
        if (FS.isClosed(stream)) {
3428
          throw new FS.ErrnoError(8);
3429
        }
3430
        if ((stream.flags & 2097155) === 1) {
3431
          throw new FS.ErrnoError(8);
3432
        }
3433
        if (FS.isDir(stream.node.mode)) {
3434
          throw new FS.ErrnoError(31);
3435
        }
3436
        if (!stream.stream_ops.read) {
3437
          throw new FS.ErrnoError(28);
3438
        }
3439
        var seeking = typeof position !== 'undefined';
3440
        if (!seeking) {
3441
          position = stream.position;
3442
        } else if (!stream.seekable) {
3443
          throw new FS.ErrnoError(70);
3444
        }
3445
        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
3446
        if (!seeking) stream.position += bytesRead;
3447
        return bytesRead;
3448
      },write:function(stream, buffer, offset, length, position, canOwn) {
3449
        if (length < 0 || position < 0) {
3450
          throw new FS.ErrnoError(28);
3451
        }
3452
        if (FS.isClosed(stream)) {
3453
          throw new FS.ErrnoError(8);
3454
        }
3455
        if ((stream.flags & 2097155) === 0) {
3456
          throw new FS.ErrnoError(8);
3457
        }
3458
        if (FS.isDir(stream.node.mode)) {
3459
          throw new FS.ErrnoError(31);
3460
        }
3461
        if (!stream.stream_ops.write) {
3462
          throw new FS.ErrnoError(28);
3463
        }
3464
        if (stream.seekable && stream.flags & 1024) {
3465
          // seek to the end before writing in append mode
3466
          FS.llseek(stream, 0, 2);
3467
        }
3468
        var seeking = typeof position !== 'undefined';
3469
        if (!seeking) {
3470
          position = stream.position;
3471
        } else if (!stream.seekable) {
3472
          throw new FS.ErrnoError(70);
3473
        }
3474
        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
3475
        if (!seeking) stream.position += bytesWritten;
3476
        try {
3477
          if (stream.path && FS.trackingDelegate['onWriteToFile']) FS.trackingDelegate['onWriteToFile'](stream.path);
3478
        } catch(e) {
3479
          err("FS.trackingDelegate['onWriteToFile']('"+stream.path+"') threw an exception: " + e.message);
3480
        }
3481
        return bytesWritten;
3482
      },allocate:function(stream, offset, length) {
3483
        if (FS.isClosed(stream)) {
3484
          throw new FS.ErrnoError(8);
3485
        }
3486
        if (offset < 0 || length <= 0) {
3487
          throw new FS.ErrnoError(28);
3488
        }
3489
        if ((stream.flags & 2097155) === 0) {
3490
          throw new FS.ErrnoError(8);
3491
        }
3492
        if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
3493
          throw new FS.ErrnoError(43);
3494
        }
3495
        if (!stream.stream_ops.allocate) {
3496
          throw new FS.ErrnoError(138);
3497
        }
3498
        stream.stream_ops.allocate(stream, offset, length);
3499
      },mmap:function(stream, address, length, position, prot, flags) {
3500
        // User requests writing to file (prot & PROT_WRITE != 0).
3501
        // Checking if we have permissions to write to the file unless
3502
        // MAP_PRIVATE flag is set. According to POSIX spec it is possible
3503
        // to write to file opened in read-only mode with MAP_PRIVATE flag,
3504
        // as all modifications will be visible only in the memory of
3505
        // the current process.
3506
        if ((prot & 2) !== 0
3507
            && (flags & 2) === 0
3508
            && (stream.flags & 2097155) !== 2) {
3509
          throw new FS.ErrnoError(2);
3510
        }
3511
        if ((stream.flags & 2097155) === 1) {
3512
          throw new FS.ErrnoError(2);
3513
        }
3514
        if (!stream.stream_ops.mmap) {
3515
          throw new FS.ErrnoError(43);
3516
        }
3517
        return stream.stream_ops.mmap(stream, address, length, position, prot, flags);
3518
      },msync:function(stream, buffer, offset, length, mmapFlags) {
3519
        if (!stream || !stream.stream_ops.msync) {
3520
          return 0;
3521
        }
3522
        return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
3523
      },munmap:function(stream) {
3524
        return 0;
3525
      },ioctl:function(stream, cmd, arg) {
3526
        if (!stream.stream_ops.ioctl) {
3527
          throw new FS.ErrnoError(59);
3528
        }
3529
        return stream.stream_ops.ioctl(stream, cmd, arg);
3530
      },readFile:function(path, opts) {
3531
        opts = opts || {};
3532
        opts.flags = opts.flags || 'r';
3533
        opts.encoding = opts.encoding || 'binary';
3534
        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
3535
          throw new Error('Invalid encoding type "' + opts.encoding + '"');
3536
        }
3537
        var ret;
3538
        var stream = FS.open(path, opts.flags);
3539
        var stat = FS.stat(path);
3540
        var length = stat.size;
3541
        var buf = new Uint8Array(length);
3542
        FS.read(stream, buf, 0, length, 0);
3543
        if (opts.encoding === 'utf8') {
3544
          ret = UTF8ArrayToString(buf, 0);
3545
        } else if (opts.encoding === 'binary') {
3546
          ret = buf;
3547
        }
3548
        FS.close(stream);
3549
        return ret;
3550
      },writeFile:function(path, data, opts) {
3551
        opts = opts || {};
3552
        opts.flags = opts.flags || 'w';
3553
        var stream = FS.open(path, opts.flags, opts.mode);
3554
        if (typeof data === 'string') {
3555
          var buf = new Uint8Array(lengthBytesUTF8(data)+1);
3556
          var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
3557
          FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
3558
        } else if (ArrayBuffer.isView(data)) {
3559
          FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
3560
        } else {
3561
          throw new Error('Unsupported data type');
3562
        }
3563
        FS.close(stream);
3564
      },cwd:function() {
3565
        return FS.currentPath;
3566
      },chdir:function(path) {
3567
        var lookup = FS.lookupPath(path, { follow: true });
3568
        if (lookup.node === null) {
3569
          throw new FS.ErrnoError(44);
3570
        }
3571
        if (!FS.isDir(lookup.node.mode)) {
3572
          throw new FS.ErrnoError(54);
3573
        }
3574
        var errCode = FS.nodePermissions(lookup.node, 'x');
3575
        if (errCode) {
3576
          throw new FS.ErrnoError(errCode);
3577
        }
3578
        FS.currentPath = lookup.path;
3579
      },createDefaultDirectories:function() {
3580
        FS.mkdir('/tmp');
3581
        FS.mkdir('/home');
3582
        FS.mkdir('/home/web_user');
3583
      },createDefaultDevices:function() {
3584
        // create /dev
3585
        FS.mkdir('/dev');
3586
        // setup /dev/null
3587
        FS.registerDevice(FS.makedev(1, 3), {
3588
          read: function() { return 0; },
3589
          write: function(stream, buffer, offset, length, pos) { return length; }
3590
        });
3591
        FS.mkdev('/dev/null', FS.makedev(1, 3));
3592
        // setup /dev/tty and /dev/tty1
3593
        // stderr needs to print output using Module['printErr']
3594
        // so we register a second tty just for it.
3595
        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
3596
        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
3597
        FS.mkdev('/dev/tty', FS.makedev(5, 0));
3598
        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
3599
        // setup /dev/[u]random
3600
        var random_device;
3601
        if (typeof crypto === 'object' && typeof crypto['getRandomValues'] === 'function') {
3602
          // for modern web browsers
3603
          var randomBuffer = new Uint8Array(1);
3604
          random_device = function() { crypto.getRandomValues(randomBuffer); return randomBuffer[0]; };
3605
        } else
3606
        if (ENVIRONMENT_IS_NODE) {
3607
          // for nodejs with or without crypto support included
3608
          try {
3609
            var crypto_module = require('crypto');
3610
            // nodejs has crypto support
3611
            random_device = function() { return crypto_module['randomBytes'](1)[0]; };
3612
          } catch (e) {
3613
            // nodejs doesn't have crypto support
3614
          }
3615
        } else
3616
        {}
3617
        if (!random_device) {
3618
          // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096
3619
          random_device = function() { abort("no cryptographic support found for random_device. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); };
3620
        }
3621
        FS.createDevice('/dev', 'random', random_device);
3622
        FS.createDevice('/dev', 'urandom', random_device);
3623
        // we're not going to emulate the actual shm device,
3624
        // just create the tmp dirs that reside in it commonly
3625
        FS.mkdir('/dev/shm');
3626
        FS.mkdir('/dev/shm/tmp');
3627
      },createSpecialDirectories:function() {
3628
        // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the name of the stream for fd 6 (see test_unistd_ttyname)
3629
        FS.mkdir('/proc');
3630
        FS.mkdir('/proc/self');
3631
        FS.mkdir('/proc/self/fd');
3632
        FS.mount({
3633
          mount: function() {
3634
            var node = FS.createNode('/proc/self', 'fd', 16384 | 511 /* 0777 */, 73);
3635
            node.node_ops = {
3636
              lookup: function(parent, name) {
3637
                var fd = +name;
3638
                var stream = FS.getStream(fd);
3639
                if (!stream) throw new FS.ErrnoError(8);
3640
                var ret = {
3641
                  parent: null,
3642
                  mount: { mountpoint: 'fake' },
3643
                  node_ops: { readlink: function() { return stream.path } }
3644
                };
3645
                ret.parent = ret; // make it look like a simple root node
3646
                return ret;
3647
              }
3648
            };
3649
            return node;
3650
          }
3651
        }, {}, '/proc/self/fd');
3652
      },createStandardStreams:function() {
3653
        // TODO deprecate the old functionality of a single
3654
        // input / output callback and that utilizes FS.createDevice
3655
        // and instead require a unique set of stream ops
3656
  
3657
        // by default, we symlink the standard streams to the
3658
        // default tty devices. however, if the standard streams
3659
        // have been overwritten we create a unique device for
3660
        // them instead.
3661
        if (Module['stdin']) {
3662
          FS.createDevice('/dev', 'stdin', Module['stdin']);
3663
        } else {
3664
          FS.symlink('/dev/tty', '/dev/stdin');
3665
        }
3666
        if (Module['stdout']) {
3667
          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
3668
        } else {
3669
          FS.symlink('/dev/tty', '/dev/stdout');
3670
        }
3671
        if (Module['stderr']) {
3672
          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
3673
        } else {
3674
          FS.symlink('/dev/tty1', '/dev/stderr');
3675
        }
3676
  
3677
        // open default streams for the stdin, stdout and stderr devices
3678
        var stdin = FS.open('/dev/stdin', 'r');
3679
        var stdout = FS.open('/dev/stdout', 'w');
3680
        var stderr = FS.open('/dev/stderr', 'w');
3681
        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
3682
        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
3683
        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
3684
      },ensureErrnoError:function() {
3685
        if (FS.ErrnoError) return;
3686
        FS.ErrnoError = /** @this{Object} */ function ErrnoError(errno, node) {
3687
          this.node = node;
3688
          this.setErrno = /** @this{Object} */ function(errno) {
3689
            this.errno = errno;
3690
            for (var key in ERRNO_CODES) {
3691
              if (ERRNO_CODES[key] === errno) {
3692
                this.code = key;
3693
                break;
3694
              }
3695
            }
3696
          };
3697
          this.setErrno(errno);
3698
          this.message = ERRNO_MESSAGES[errno];
3699
  
3700
          // Try to get a maximally helpful stack trace. On Node.js, getting Error.stack
3701
          // now ensures it shows what we want.
3702
          if (this.stack) {
3703
            // Define the stack property for Node.js 4, which otherwise errors on the next line.
3704
            Object.defineProperty(this, "stack", { value: (new Error).stack, writable: true });
3705
            this.stack = demangleAll(this.stack);
3706
          }
3707
        };
3708
        FS.ErrnoError.prototype = new Error();
3709
        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
3710
        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
3711
        [44].forEach(function(code) {
3712
          FS.genericErrors[code] = new FS.ErrnoError(code);
3713
          FS.genericErrors[code].stack = '<generic error, no stack>';
3714
        });
3715
      },staticInit:function() {
3716
        FS.ensureErrnoError();
3717
  
3718
        FS.nameTable = new Array(4096);
3719
  
3720
        FS.mount(MEMFS, {}, '/');
3721
  
3722
        FS.createDefaultDirectories();
3723
        FS.createDefaultDevices();
3724
        FS.createSpecialDirectories();
3725
  
3726
        FS.filesystems = {
3727
          'MEMFS': MEMFS,
3728
        };
3729
      },init:function(input, output, error) {
3730
        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)');
3731
        FS.init.initialized = true;
3732
  
3733
        FS.ensureErrnoError();
3734
  
3735
        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
3736
        Module['stdin'] = input || Module['stdin'];
3737
        Module['stdout'] = output || Module['stdout'];
3738
        Module['stderr'] = error || Module['stderr'];
3739
  
3740
        FS.createStandardStreams();
3741
      },quit:function() {
3742
        FS.init.initialized = false;
3743
        // force-flush all streams, so we get musl std streams printed out
3744
        var fflush = Module['_fflush'];
3745
        if (fflush) fflush(0);
3746
        // close all of our streams
3747
        for (var i = 0; i < FS.streams.length; i++) {
3748
          var stream = FS.streams[i];
3749
          if (!stream) {
3750
            continue;
3751
          }
3752
          FS.close(stream);
3753
        }
3754
      },getMode:function(canRead, canWrite) {
3755
        var mode = 0;
3756
        if (canRead) mode |= 292 | 73;
3757
        if (canWrite) mode |= 146;
3758
        return mode;
3759
      },joinPath:function(parts, forceRelative) {
3760
        var path = PATH.join.apply(null, parts);
3761
        if (forceRelative && path[0] == '/') path = path.substr(1);
3762
        return path;
3763
      },absolutePath:function(relative, base) {
3764
        return PATH_FS.resolve(base, relative);
3765
      },standardizePath:function(path) {
3766
        return PATH.normalize(path);
3767
      },findObject:function(path, dontResolveLastLink) {
3768
        var ret = FS.analyzePath(path, dontResolveLastLink);
3769
        if (ret.exists) {
3770
          return ret.object;
3771
        } else {
3772
          setErrNo(ret.error);
3773
          return null;
3774
        }
3775
      },analyzePath:function(path, dontResolveLastLink) {
3776
        // operate from within the context of the symlink's target
3777
        try {
3778
          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
3779
          path = lookup.path;
3780
        } catch (e) {
3781
        }
3782
        var ret = {
3783
          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
3784
          parentExists: false, parentPath: null, parentObject: null
3785
        };
3786
        try {
3787
          var lookup = FS.lookupPath(path, { parent: true });
3788
          ret.parentExists = true;
3789
          ret.parentPath = lookup.path;
3790
          ret.parentObject = lookup.node;
3791
          ret.name = PATH.basename(path);
3792
          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
3793
          ret.exists = true;
3794
          ret.path = lookup.path;
3795
          ret.object = lookup.node;
3796
          ret.name = lookup.node.name;
3797
          ret.isRoot = lookup.path === '/';
3798
        } catch (e) {
3799
          ret.error = e.errno;
3800
        };
3801
        return ret;
3802
      },createFolder:function(parent, name, canRead, canWrite) {
3803
        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
3804
        var mode = FS.getMode(canRead, canWrite);
3805
        return FS.mkdir(path, mode);
3806
      },createPath:function(parent, path, canRead, canWrite) {
3807
        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
3808
        var parts = path.split('/').reverse();
3809
        while (parts.length) {
3810
          var part = parts.pop();
3811
          if (!part) continue;
3812
          var current = PATH.join2(parent, part);
3813
          try {
3814
            FS.mkdir(current);
3815
          } catch (e) {
3816
            // ignore EEXIST
3817
          }
3818
          parent = current;
3819
        }
3820
        return current;
3821
      },createFile:function(parent, name, properties, canRead, canWrite) {
3822
        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
3823
        var mode = FS.getMode(canRead, canWrite);
3824
        return FS.create(path, mode);
3825
      },createDataFile:function(parent, name, data, canRead, canWrite, canOwn) {
3826
        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
3827
        var mode = FS.getMode(canRead, canWrite);
3828
        var node = FS.create(path, mode);
3829
        if (data) {
3830
          if (typeof data === 'string') {
3831
            var arr = new Array(data.length);
3832
            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
3833
            data = arr;
3834
          }
3835
          // make sure we can write to the file
3836
          FS.chmod(node, mode | 146);
3837
          var stream = FS.open(node, 'w');
3838
          FS.write(stream, data, 0, data.length, 0, canOwn);
3839
          FS.close(stream);
3840
          FS.chmod(node, mode);
3841
        }
3842
        return node;
3843
      },createDevice:function(parent, name, input, output) {
3844
        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
3845
        var mode = FS.getMode(!!input, !!output);
3846
        if (!FS.createDevice.major) FS.createDevice.major = 64;
3847
        var dev = FS.makedev(FS.createDevice.major++, 0);
3848
        // Create a fake device that a set of stream ops to emulate
3849
        // the old behavior.
3850
        FS.registerDevice(dev, {
3851
          open: function(stream) {
3852
            stream.seekable = false;
3853
          },
3854
          close: function(stream) {
3855
            // flush any pending line data
3856
            if (output && output.buffer && output.buffer.length) {
3857
              output(10);
3858
            }
3859
          },
3860
          read: function(stream, buffer, offset, length, pos /* ignored */) {
3861
            var bytesRead = 0;
3862
            for (var i = 0; i < length; i++) {
3863
              var result;
3864
              try {
3865
                result = input();
3866
              } catch (e) {
3867
                throw new FS.ErrnoError(29);
3868
              }
3869
              if (result === undefined && bytesRead === 0) {
3870
                throw new FS.ErrnoError(6);
3871
              }
3872
              if (result === null || result === undefined) break;
3873
              bytesRead++;
3874
              buffer[offset+i] = result;
3875
            }
3876
            if (bytesRead) {
3877
              stream.node.timestamp = Date.now();
3878
            }
3879
            return bytesRead;
3880
          },
3881
          write: function(stream, buffer, offset, length, pos) {
3882
            for (var i = 0; i < length; i++) {
3883
              try {
3884
                output(buffer[offset+i]);
3885
              } catch (e) {
3886
                throw new FS.ErrnoError(29);
3887
              }
3888
            }
3889
            if (length) {
3890
              stream.node.timestamp = Date.now();
3891
            }
3892
            return i;
3893
          }
3894
        });
3895
        return FS.mkdev(path, mode, dev);
3896
      },createLink:function(parent, name, target, canRead, canWrite) {
3897
        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
3898
        return FS.symlink(target, path);
3899
      },forceLoadFile:function(obj) {
3900
        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
3901
        var success = true;
3902
        if (typeof XMLHttpRequest !== 'undefined') {
3903
          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.");
3904
        } else if (read_) {
3905
          // Command-line.
3906
          try {
3907
            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
3908
            //          read() will try to parse UTF8.
3909
            obj.contents = intArrayFromString(read_(obj.url), true);
3910
            obj.usedBytes = obj.contents.length;
3911
          } catch (e) {
3912
            success = false;
3913
          }
3914
        } else {
3915
          throw new Error('Cannot load without read() or XMLHttpRequest.');
3916
        }
3917
        if (!success) setErrNo(29);
3918
        return success;
3919
      },createLazyFile:function(parent, name, url, canRead, canWrite) {
3920
        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
3921
        /** @constructor */
3922
        function LazyUint8Array() {
3923
          this.lengthKnown = false;
3924
          this.chunks = []; // Loaded chunks. Index is the chunk number
3925
        }
3926
        LazyUint8Array.prototype.get = /** @this{Object} */ function LazyUint8Array_get(idx) {
3927
          if (idx > this.length-1 || idx < 0) {
3928
            return undefined;
3929
          }
3930
          var chunkOffset = idx % this.chunkSize;
3931
          var chunkNum = (idx / this.chunkSize)|0;
3932
          return this.getter(chunkNum)[chunkOffset];
3933
        };
3934
        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
3935
          this.getter = getter;
3936
        };
3937
        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
3938
          // Find length
3939
          var xhr = new XMLHttpRequest();
3940
          xhr.open('HEAD', url, false);
3941
          xhr.send(null);
3942
          if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
3943
          var datalength = Number(xhr.getResponseHeader("Content-length"));
3944
          var header;
3945
          var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
3946
          var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
3947
  
3948
          var chunkSize = 1024*1024; // Chunk size in bytes
3949
  
3950
          if (!hasByteServing) chunkSize = datalength;
3951
  
3952
          // Function to get a range from the remote URL.
3953
          var doXHR = (function(from, to) {
3954
            if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
3955
            if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
3956
  
3957
            // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
3958
            var xhr = new XMLHttpRequest();
3959
            xhr.open('GET', url, false);
3960
            if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
3961
  
3962
            // Some hints to the browser that we want binary data.
3963
            if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
3964
            if (xhr.overrideMimeType) {
3965
              xhr.overrideMimeType('text/plain; charset=x-user-defined');
3966
            }
3967
  
3968
            xhr.send(null);
3969
            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
3970
            if (xhr.response !== undefined) {
3971
              return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
3972
            } else {
3973
              return intArrayFromString(xhr.responseText || '', true);
3974
            }
3975
          });
3976
          var lazyArray = this;
3977
          lazyArray.setDataGetter(function(chunkNum) {
3978
            var start = chunkNum * chunkSize;
3979
            var end = (chunkNum+1) * chunkSize - 1; // including this byte
3980
            end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
3981
            if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
3982
              lazyArray.chunks[chunkNum] = doXHR(start, end);
3983
            }
3984
            if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
3985
            return lazyArray.chunks[chunkNum];
3986
          });
3987
  
3988
          if (usesGzip || !datalength) {
3989
            // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
3990
            chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
3991
            datalength = this.getter(0).length;
3992
            chunkSize = datalength;
3993
            out("LazyFiles on gzip forces download of the whole file when length is accessed");
3994
          }
3995
  
3996
          this._length = datalength;
3997
          this._chunkSize = chunkSize;
3998
          this.lengthKnown = true;
3999
        };
4000
        if (typeof XMLHttpRequest !== 'undefined') {
4001
          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
4002
          var lazyArray = new LazyUint8Array();
4003
          Object.defineProperties(lazyArray, {
4004
            length: {
4005
              get: /** @this{Object} */ function() {
4006
                if(!this.lengthKnown) {
4007
                  this.cacheLength();
4008
                }
4009
                return this._length;
4010
              }
4011
            },
4012
            chunkSize: {
4013
              get: /** @this{Object} */ function() {
4014
                if(!this.lengthKnown) {
4015
                  this.cacheLength();
4016
                }
4017
                return this._chunkSize;
4018
              }
4019
            }
4020
          });
4021
  
4022
          var properties = { isDevice: false, contents: lazyArray };
4023
        } else {
4024
          var properties = { isDevice: false, url: url };
4025
        }
4026
  
4027
        var node = FS.createFile(parent, name, properties, canRead, canWrite);
4028
        // This is a total hack, but I want to get this lazy file code out of the
4029
        // core of MEMFS. If we want to keep this lazy file concept I feel it should
4030
        // be its own thin LAZYFS proxying calls to MEMFS.
4031
        if (properties.contents) {
4032
          node.contents = properties.contents;
4033
        } else if (properties.url) {
4034
          node.contents = null;
4035
          node.url = properties.url;
4036
        }
4037
        // Add a function that defers querying the file size until it is asked the first time.
4038
        Object.defineProperties(node, {
4039
          usedBytes: {
4040
            get: /** @this {FSNode} */ function() { return this.contents.length; }
4041
          }
4042
        });
4043
        // override each stream op with one that tries to force load the lazy file first
4044
        var stream_ops = {};
4045
        var keys = Object.keys(node.stream_ops);
4046
        keys.forEach(function(key) {
4047
          var fn = node.stream_ops[key];
4048
          stream_ops[key] = function forceLoadLazyFile() {
4049
            if (!FS.forceLoadFile(node)) {
4050
              throw new FS.ErrnoError(29);
4051
            }
4052
            return fn.apply(null, arguments);
4053
          };
4054
        });
4055
        // use a custom read function
4056
        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
4057
          if (!FS.forceLoadFile(node)) {
4058
            throw new FS.ErrnoError(29);
4059
          }
4060
          var contents = stream.node.contents;
4061
          if (position >= contents.length)
4062
            return 0;
4063
          var size = Math.min(contents.length - position, length);
4064
          assert(size >= 0);
4065
          if (contents.slice) { // normal array
4066
            for (var i = 0; i < size; i++) {
4067
              buffer[offset + i] = contents[position + i];
4068
            }
4069
          } else {
4070
            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
4071
              buffer[offset + i] = contents.get(position + i);
4072
            }
4073
          }
4074
          return size;
4075
        };
4076
        node.stream_ops = stream_ops;
4077
        return node;
4078
      },createPreloadedFile:function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) {
4079
        Browser.init(); // XXX perhaps this method should move onto Browser?
4080
        // TODO we should allow people to just pass in a complete filename instead
4081
        // of parent and name being that we just join them anyways
4082
        var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
4083
        var dep = getUniqueRunDependency('cp ' + fullname); // might have several active requests for the same fullname
4084
        function processData(byteArray) {
4085
          function finish(byteArray) {
4086
            if (preFinish) preFinish();
4087
            if (!dontCreateFile) {
4088
              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
4089
            }
4090
            if (onload) onload();
4091
            removeRunDependency(dep);
4092
          }
4093
          var handled = false;
4094
          Module['preloadPlugins'].forEach(function(plugin) {
4095
            if (handled) return;
4096
            if (plugin['canHandle'](fullname)) {
4097
              plugin['handle'](byteArray, fullname, finish, function() {
4098
                if (onerror) onerror();
4099
                removeRunDependency(dep);
4100
              });
4101
              handled = true;
4102
            }
4103
          });
4104
          if (!handled) finish(byteArray);
4105
        }
4106
        addRunDependency(dep);
4107
        if (typeof url == 'string') {
4108
          Browser.asyncLoad(url, function(byteArray) {
4109
            processData(byteArray);
4110
          }, onerror);
4111
        } else {
4112
          processData(url);
4113
        }
4114
      },indexedDB:function() {
4115
        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
4116
      },DB_NAME:function() {
4117
        return 'EM_FS_' + window.location.pathname;
4118
      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(paths, onload, onerror) {
4119
        onload = onload || function(){};
4120
        onerror = onerror || function(){};
4121
        var indexedDB = FS.indexedDB();
4122
        try {
4123
          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
4124
        } catch (e) {
4125
          return onerror(e);
4126
        }
4127
        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
4128
          out('creating db');
4129
          var db = openRequest.result;
4130
          db.createObjectStore(FS.DB_STORE_NAME);
4131
        };
4132
        openRequest.onsuccess = function openRequest_onsuccess() {
4133
          var db = openRequest.result;
4134
          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
4135
          var files = transaction.objectStore(FS.DB_STORE_NAME);
4136
          var ok = 0, fail = 0, total = paths.length;
4137
          function finish() {
4138
            if (fail == 0) onload(); else onerror();
4139
          }
4140
          paths.forEach(function(path) {
4141
            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
4142
            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
4143
            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
4144
          });
4145
          transaction.onerror = onerror;
4146
        };
4147
        openRequest.onerror = onerror;
4148
      },loadFilesFromDB:function(paths, onload, onerror) {
4149
        onload = onload || function(){};
4150
        onerror = onerror || function(){};
4151
        var indexedDB = FS.indexedDB();
4152
        try {
4153
          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
4154
        } catch (e) {
4155
          return onerror(e);
4156
        }
4157
        openRequest.onupgradeneeded = onerror; // no database to load from
4158
        openRequest.onsuccess = function openRequest_onsuccess() {
4159
          var db = openRequest.result;
4160
          try {
4161
            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
4162
          } catch(e) {
4163
            onerror(e);
4164
            return;
4165
          }
4166
          var files = transaction.objectStore(FS.DB_STORE_NAME);
4167
          var ok = 0, fail = 0, total = paths.length;
4168
          function finish() {
4169
            if (fail == 0) onload(); else onerror();
4170
          }
4171
          paths.forEach(function(path) {
4172
            var getRequest = files.get(path);
4173
            getRequest.onsuccess = function getRequest_onsuccess() {
4174
              if (FS.analyzePath(path).exists) {
4175
                FS.unlink(path);
4176
              }
4177
              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
4178
              ok++;
4179
              if (ok + fail == total) finish();
4180
            };
4181
            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
4182
          });
4183
          transaction.onerror = onerror;
4184
        };
4185
        openRequest.onerror = onerror;
4186
      }};var SYSCALLS={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(dirfd, path) {
4187
        if (path[0] !== '/') {
4188
          // relative path
4189
          var dir;
4190
          if (dirfd === -100) {
4191
            dir = FS.cwd();
4192
          } else {
4193
            var dirstream = FS.getStream(dirfd);
4194
            if (!dirstream) throw new FS.ErrnoError(8);
4195
            dir = dirstream.path;
4196
          }
4197
          path = PATH.join2(dir, path);
4198
        }
4199
        return path;
4200
      },doStat:function(func, path, buf) {
4201
        try {
4202
          var stat = func(path);
4203
        } catch (e) {
4204
          if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) {
4205
            // an error occurred while trying to look up the path; we should just report ENOTDIR
4206
            return -54;
4207
          }
4208
          throw e;
4209
        }
4210
        HEAP32[((buf)>>2)]=stat.dev;
4211
        HEAP32[(((buf)+(4))>>2)]=0;
4212
        HEAP32[(((buf)+(8))>>2)]=stat.ino;
4213
        HEAP32[(((buf)+(12))>>2)]=stat.mode;
4214
        HEAP32[(((buf)+(16))>>2)]=stat.nlink;
4215
        HEAP32[(((buf)+(20))>>2)]=stat.uid;
4216
        HEAP32[(((buf)+(24))>>2)]=stat.gid;
4217
        HEAP32[(((buf)+(28))>>2)]=stat.rdev;
4218
        HEAP32[(((buf)+(32))>>2)]=0;
4219
        (tempI64 = [stat.size>>>0,(tempDouble=stat.size,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(40))>>2)]=tempI64[0],HEAP32[(((buf)+(44))>>2)]=tempI64[1]);
4220
        HEAP32[(((buf)+(48))>>2)]=4096;
4221
        HEAP32[(((buf)+(52))>>2)]=stat.blocks;
4222
        HEAP32[(((buf)+(56))>>2)]=(stat.atime.getTime() / 1000)|0;
4223
        HEAP32[(((buf)+(60))>>2)]=0;
4224
        HEAP32[(((buf)+(64))>>2)]=(stat.mtime.getTime() / 1000)|0;
4225
        HEAP32[(((buf)+(68))>>2)]=0;
4226
        HEAP32[(((buf)+(72))>>2)]=(stat.ctime.getTime() / 1000)|0;
4227
        HEAP32[(((buf)+(76))>>2)]=0;
4228
        (tempI64 = [stat.ino>>>0,(tempDouble=stat.ino,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(80))>>2)]=tempI64[0],HEAP32[(((buf)+(84))>>2)]=tempI64[1]);
4229
        return 0;
4230
      },doMsync:function(addr, stream, len, flags, offset) {
4231
        var buffer = HEAPU8.slice(addr, addr + len);
4232
        FS.msync(stream, buffer, offset, len, flags);
4233
      },doMkdir:function(path, mode) {
4234
        // remove a trailing slash, if one - /a/b/ has basename of '', but
4235
        // we want to create b in the context of this function
4236
        path = PATH.normalize(path);
4237
        if (path[path.length-1] === '/') path = path.substr(0, path.length-1);
4238
        FS.mkdir(path, mode, 0);
4239
        return 0;
4240
      },doMknod:function(path, mode, dev) {
4241
        // we don't want this in the JS API as it uses mknod to create all nodes.
4242
        switch (mode & 61440) {
4243
          case 32768:
4244
          case 8192:
4245
          case 24576:
4246
          case 4096:
4247
          case 49152:
4248
            break;
4249
          default: return -28;
4250
        }
4251
        FS.mknod(path, mode, dev);
4252
        return 0;
4253
      },doReadlink:function(path, buf, bufsize) {
4254
        if (bufsize <= 0) return -28;
4255
        var ret = FS.readlink(path);
4256
  
4257
        var len = Math.min(bufsize, lengthBytesUTF8(ret));
4258
        var endChar = HEAP8[buf+len];
4259
        stringToUTF8(ret, buf, bufsize+1);
4260
        // readlink is one of the rare functions that write out a C string, but does never append a null to the output buffer(!)
4261
        // stringToUTF8() always appends a null byte, so restore the character under the null byte after the write.
4262
        HEAP8[buf+len] = endChar;
4263
  
4264
        return len;
4265
      },doAccess:function(path, amode) {
4266
        if (amode & ~7) {
4267
          // need a valid mode
4268
          return -28;
4269
        }
4270
        var node;
4271
        var lookup = FS.lookupPath(path, { follow: true });
4272
        node = lookup.node;
4273
        if (!node) {
4274
          return -44;
4275
        }
4276
        var perms = '';
4277
        if (amode & 4) perms += 'r';
4278
        if (amode & 2) perms += 'w';
4279
        if (amode & 1) perms += 'x';
4280
        if (perms /* otherwise, they've just passed F_OK */ && FS.nodePermissions(node, perms)) {
4281
          return -2;
4282
        }
4283
        return 0;
4284
      },doDup:function(path, flags, suggestFD) {
4285
        var suggest = FS.getStream(suggestFD);
4286
        if (suggest) FS.close(suggest);
4287
        return FS.open(path, flags, 0, suggestFD, suggestFD).fd;
4288
      },doReadv:function(stream, iov, iovcnt, offset) {
4289
        var ret = 0;
4290
        for (var i = 0; i < iovcnt; i++) {
4291
          var ptr = HEAP32[(((iov)+(i*8))>>2)];
4292
          var len = HEAP32[(((iov)+(i*8 + 4))>>2)];
4293
          var curr = FS.read(stream, HEAP8,ptr, len, offset);
4294
          if (curr < 0) return -1;
4295
          ret += curr;
4296
          if (curr < len) break; // nothing more to read
4297
        }
4298
        return ret;
4299
      },doWritev:function(stream, iov, iovcnt, offset) {
4300
        var ret = 0;
4301
        for (var i = 0; i < iovcnt; i++) {
4302
          var ptr = HEAP32[(((iov)+(i*8))>>2)];
4303
          var len = HEAP32[(((iov)+(i*8 + 4))>>2)];
4304
          var curr = FS.write(stream, HEAP8,ptr, len, offset);
4305
          if (curr < 0) return -1;
4306
          ret += curr;
4307
        }
4308
        return ret;
4309
      },varargs:undefined,get:function() {
4310
        assert(SYSCALLS.varargs != undefined);
4311
        SYSCALLS.varargs += 4;
4312
        var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];
4313
        return ret;
4314
      },getStr:function(ptr) {
4315
        var ret = UTF8ToString(ptr);
4316
        return ret;
4317
      },getStreamFromFD:function(fd) {
4318
        var stream = FS.getStream(fd);
4319
        if (!stream) throw new FS.ErrnoError(8);
4320
        return stream;
4321
      },get64:function(low, high) {
4322
        if (low >= 0) assert(high === 0);
4323
        else assert(high === -1);
4324
        return low;
4325
      }};function _fd_close(fd) {try {
4326
  
4327
      var stream = SYSCALLS.getStreamFromFD(fd);
4328
      FS.close(stream);
4329
      return 0;
4330
    } catch (e) {
4331
    if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
4332
    return e.errno;
4333
  }
4334
  }
4335
4336
  function _fd_fdstat_get(fd, pbuf) {try {
4337
  
4338
      var stream = SYSCALLS.getStreamFromFD(fd);
4339
      // All character devices are terminals (other things a Linux system would
4340
      // assume is a character device, like the mouse, we have special APIs for).
4341
      var type = stream.tty ? 2 :
4342
                 FS.isDir(stream.mode) ? 3 :
4343
                 FS.isLink(stream.mode) ? 7 :
4344
                 4;
4345
      HEAP8[((pbuf)>>0)]=type;
4346
      // TODO HEAP16[(((pbuf)+(2))>>1)]=?;
4347
      // TODO (tempI64 = [?>>>0,(tempDouble=?,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((pbuf)+(8))>>2)]=tempI64[0],HEAP32[(((pbuf)+(12))>>2)]=tempI64[1]);
4348
      // TODO (tempI64 = [?>>>0,(tempDouble=?,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((pbuf)+(16))>>2)]=tempI64[0],HEAP32[(((pbuf)+(20))>>2)]=tempI64[1]);
4349
      return 0;
4350
    } catch (e) {
4351
    if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
4352
    return e.errno;
4353
  }
4354
  }
4355
4356
  function _fd_read(fd, iov, iovcnt, pnum) {try {
4357
  
4358
      var stream = SYSCALLS.getStreamFromFD(fd);
4359
      var num = SYSCALLS.doReadv(stream, iov, iovcnt);
4360
      HEAP32[((pnum)>>2)]=num
4361
      return 0;
4362
    } catch (e) {
4363
    if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
4364
    return e.errno;
4365
  }
4366
  }
4367
4368
  function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {try {
4369
  
4370
      
4371
      var stream = SYSCALLS.getStreamFromFD(fd);
4372
      var HIGH_OFFSET = 0x100000000; // 2^32
4373
      // use an unsigned operator on low and shift high by 32-bits
4374
      var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0);
4375
  
4376
      var DOUBLE_LIMIT = 0x20000000000000; // 2^53
4377
      // we also check for equality since DOUBLE_LIMIT + 1 == DOUBLE_LIMIT
4378
      if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) {
4379
        return -61;
4380
      }
4381
  
4382
      FS.llseek(stream, offset, whence);
4383
      (tempI64 = [stream.position>>>0,(tempDouble=stream.position,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((newOffset)>>2)]=tempI64[0],HEAP32[(((newOffset)+(4))>>2)]=tempI64[1]);
4384
      if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
4385
      return 0;
4386
    } catch (e) {
4387
    if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
4388
    return e.errno;
4389
  }
4390
  }
4391
4392
  function _fd_write(fd, iov, iovcnt, pnum) {try {
4393
  
4394
      var stream = SYSCALLS.getStreamFromFD(fd);
4395
      var num = SYSCALLS.doWritev(stream, iov, iovcnt);
4396
      HEAP32[((pnum)>>2)]=num
4397
      return 0;
4398
    } catch (e) {
4399
    if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e);
4400
    return e.errno;
4401
  }
4402
  }
4403
4404
  function _setTempRet0($i) {
4405
      setTempRet0(($i) | 0);
4406
    }
4407
var FSNode = /** @constructor */ function(parent, name, mode, rdev) {
4408
    if (!parent) {
4409
      parent = this;  // root node sets parent to itself
4410
    }
4411
    this.parent = parent;
4412
    this.mount = parent.mount;
4413
    this.mounted = null;
4414
    this.id = FS.nextInode++;
4415
    this.name = name;
4416
    this.mode = mode;
4417
    this.node_ops = {};
4418
    this.stream_ops = {};
4419
    this.rdev = rdev;
4420
  };
4421
  var readMode = 292/*292*/ | 73/*73*/;
4422
  var writeMode = 146/*146*/;
4423
  Object.defineProperties(FSNode.prototype, {
4424
   read: {
4425
    get: /** @this{FSNode} */function() {
4426
     return (this.mode & readMode) === readMode;
4427
    },
4428
    set: /** @this{FSNode} */function(val) {
4429
     val ? this.mode |= readMode : this.mode &= ~readMode;
4430
    }
4431
   },
4432
   write: {
4433
    get: /** @this{FSNode} */function() {
4434
     return (this.mode & writeMode) === writeMode;
4435
    },
4436
    set: /** @this{FSNode} */function(val) {
4437
     val ? this.mode |= writeMode : this.mode &= ~writeMode;
4438
    }
4439
   },
4440
   isFolder: {
4441
    get: /** @this{FSNode} */function() {
4442
     return FS.isDir(this.mode);
4443
    }
4444
   },
4445
   isDevice: {
4446
    get: /** @this{FSNode} */function() {
4447
     return FS.isChrdev(this.mode);
4448
    }
4449
   }
4450
  });
4451
  FS.FSNode = FSNode;
4452
  FS.staticInit();;
4453
var ASSERTIONS = true;
4454
4455
4456
4457
/** @type {function(string, boolean=, number=)} */
4458
function intArrayFromString(stringy, dontAddNull, length) {
4459
  var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
4460
  var u8array = new Array(len);
4461
  var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
4462
  if (dontAddNull) u8array.length = numBytesWritten;
4463
  return u8array;
4464
}
4465
4466
function intArrayToString(array) {
4467
  var ret = [];
4468
  for (var i = 0; i < array.length; i++) {
4469
    var chr = array[i];
4470
    if (chr > 0xFF) {
4471
      if (ASSERTIONS) {
4472
        assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ')  at offset ' + i + ' not in 0x00-0xFF.');
4473
      }
4474
      chr &= 0xFF;
4475
    }
4476
    ret.push(String.fromCharCode(chr));
4477
  }
4478
  return ret.join('');
4479
}
4480
4481
4482
var asmGlobalArg = {};
4483
var asmLibraryArg = { "__handle_stack_overflow": ___handle_stack_overflow, "emscripten_get_sbrk_ptr": _emscripten_get_sbrk_ptr, "emscripten_memcpy_big": _emscripten_memcpy_big, "emscripten_resize_heap": _emscripten_resize_heap, "exit": _exit, "fd_close": _fd_close, "fd_fdstat_get": _fd_fdstat_get, "fd_read": _fd_read, "fd_seek": _fd_seek, "fd_write": _fd_write, "memory": wasmMemory, "setTempRet0": _setTempRet0, "table": wasmTable };
4484
var asm = createWasm();
4485
/** @type {function(...*):?} */
4486
var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors");
4487
4488
/** @type {function(...*):?} */
4489
var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location");
4490
4491
/** @type {function(...*):?} */
4492
var _malloc = Module["_malloc"] = createExportWrapper("malloc");
4493
4494
/** @type {function(...*):?} */
4495
var _free = Module["_free"] = createExportWrapper("free");
4496
4497
/** @type {function(...*):?} */
4498
var _fflush = Module["_fflush"] = createExportWrapper("fflush");
4499
4500
/** @type {function(...*):?} */
4501
var _main = Module["_main"] = createExportWrapper("main");
4502
4503
/** @type {function(...*):?} */
4504
var stackSave = Module["stackSave"] = createExportWrapper("stackSave");
4505
4506
/** @type {function(...*):?} */
4507
var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore");
4508
4509
/** @type {function(...*):?} */
4510
var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc");
4511
4512
/** @type {function(...*):?} */
4513
var ___set_stack_limit = Module["___set_stack_limit"] = createExportWrapper("__set_stack_limit");
4514
4515
/** @type {function(...*):?} */
4516
var __growWasmMemory = Module["__growWasmMemory"] = createExportWrapper("__growWasmMemory");
4517
4518
/** @type {function(...*):?} */
4519
var dynCall_iiii = Module["dynCall_iiii"] = createExportWrapper("dynCall_iiii");
4520
4521
/** @type {function(...*):?} */
4522
var dynCall_iidiiii = Module["dynCall_iidiiii"] = createExportWrapper("dynCall_iidiiii");
4523
4524
/** @type {function(...*):?} */
4525
var dynCall_vii = Module["dynCall_vii"] = createExportWrapper("dynCall_vii");
4526
4527
/** @type {function(...*):?} */
4528
var dynCall_ii = Module["dynCall_ii"] = createExportWrapper("dynCall_ii");
4529
4530
/** @type {function(...*):?} */
4531
var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji");
4532
4533
4534
4535
4536
4537
// === Auto-generated postamble setup entry stuff ===
4538
4539
4540
if (!Object.getOwnPropertyDescriptor(Module, "intArrayFromString")) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4541
if (!Object.getOwnPropertyDescriptor(Module, "intArrayToString")) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4542
if (!Object.getOwnPropertyDescriptor(Module, "ccall")) Module["ccall"] = function() { abort("'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4543
if (!Object.getOwnPropertyDescriptor(Module, "cwrap")) Module["cwrap"] = function() { abort("'cwrap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4544
if (!Object.getOwnPropertyDescriptor(Module, "setValue")) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4545
if (!Object.getOwnPropertyDescriptor(Module, "getValue")) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4546
if (!Object.getOwnPropertyDescriptor(Module, "allocate")) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4547
if (!Object.getOwnPropertyDescriptor(Module, "getMemory")) Module["getMemory"] = function() { abort("'getMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4548
if (!Object.getOwnPropertyDescriptor(Module, "UTF8ArrayToString")) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4549
if (!Object.getOwnPropertyDescriptor(Module, "UTF8ToString")) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4550
if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8Array")) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4551
if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8")) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4552
if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF8")) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4553
if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4554
if (!Object.getOwnPropertyDescriptor(Module, "addOnPreRun")) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4555
if (!Object.getOwnPropertyDescriptor(Module, "addOnInit")) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4556
if (!Object.getOwnPropertyDescriptor(Module, "addOnPreMain")) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4557
if (!Object.getOwnPropertyDescriptor(Module, "addOnExit")) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4558
if (!Object.getOwnPropertyDescriptor(Module, "addOnPostRun")) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4559
if (!Object.getOwnPropertyDescriptor(Module, "writeStringToMemory")) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4560
if (!Object.getOwnPropertyDescriptor(Module, "writeArrayToMemory")) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4561
if (!Object.getOwnPropertyDescriptor(Module, "writeAsciiToMemory")) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4562
if (!Object.getOwnPropertyDescriptor(Module, "addRunDependency")) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4563
if (!Object.getOwnPropertyDescriptor(Module, "removeRunDependency")) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4564
if (!Object.getOwnPropertyDescriptor(Module, "FS_createFolder")) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4565
if (!Object.getOwnPropertyDescriptor(Module, "FS_createPath")) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4566
if (!Object.getOwnPropertyDescriptor(Module, "FS_createDataFile")) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4567
if (!Object.getOwnPropertyDescriptor(Module, "FS_createPreloadedFile")) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4568
if (!Object.getOwnPropertyDescriptor(Module, "FS_createLazyFile")) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4569
if (!Object.getOwnPropertyDescriptor(Module, "FS_createLink")) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4570
if (!Object.getOwnPropertyDescriptor(Module, "FS_createDevice")) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4571
if (!Object.getOwnPropertyDescriptor(Module, "FS_unlink")) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") };
4572
if (!Object.getOwnPropertyDescriptor(Module, "dynamicAlloc")) Module["dynamicAlloc"] = function() { abort("'dynamicAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4573
if (!Object.getOwnPropertyDescriptor(Module, "loadDynamicLibrary")) Module["loadDynamicLibrary"] = function() { abort("'loadDynamicLibrary' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4574
if (!Object.getOwnPropertyDescriptor(Module, "loadWebAssemblyModule")) Module["loadWebAssemblyModule"] = function() { abort("'loadWebAssemblyModule' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4575
if (!Object.getOwnPropertyDescriptor(Module, "getLEB")) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4576
if (!Object.getOwnPropertyDescriptor(Module, "getFunctionTables")) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4577
if (!Object.getOwnPropertyDescriptor(Module, "alignFunctionTables")) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4578
if (!Object.getOwnPropertyDescriptor(Module, "registerFunctions")) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4579
if (!Object.getOwnPropertyDescriptor(Module, "addFunction")) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4580
if (!Object.getOwnPropertyDescriptor(Module, "removeFunction")) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4581
if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4582
if (!Object.getOwnPropertyDescriptor(Module, "prettyPrint")) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4583
if (!Object.getOwnPropertyDescriptor(Module, "makeBigInt")) Module["makeBigInt"] = function() { abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4584
if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4585
if (!Object.getOwnPropertyDescriptor(Module, "getCompilerSetting")) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4586
if (!Object.getOwnPropertyDescriptor(Module, "print")) Module["print"] = function() { abort("'print' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4587
if (!Object.getOwnPropertyDescriptor(Module, "printErr")) Module["printErr"] = function() { abort("'printErr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4588
if (!Object.getOwnPropertyDescriptor(Module, "getTempRet0")) Module["getTempRet0"] = function() { abort("'getTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4589
if (!Object.getOwnPropertyDescriptor(Module, "setTempRet0")) Module["setTempRet0"] = function() { abort("'setTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4590
if (!Object.getOwnPropertyDescriptor(Module, "callMain")) Module["callMain"] = function() { abort("'callMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4591
if (!Object.getOwnPropertyDescriptor(Module, "abort")) Module["abort"] = function() { abort("'abort' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4592
if (!Object.getOwnPropertyDescriptor(Module, "stringToNewUTF8")) Module["stringToNewUTF8"] = function() { abort("'stringToNewUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4593
if (!Object.getOwnPropertyDescriptor(Module, "abortOnCannotGrowMemory")) Module["abortOnCannotGrowMemory"] = function() { abort("'abortOnCannotGrowMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4594
if (!Object.getOwnPropertyDescriptor(Module, "emscripten_realloc_buffer")) Module["emscripten_realloc_buffer"] = function() { abort("'emscripten_realloc_buffer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4595
if (!Object.getOwnPropertyDescriptor(Module, "ENV")) Module["ENV"] = function() { abort("'ENV' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4596
if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_CODES")) Module["ERRNO_CODES"] = function() { abort("'ERRNO_CODES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4597
if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_MESSAGES")) Module["ERRNO_MESSAGES"] = function() { abort("'ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4598
if (!Object.getOwnPropertyDescriptor(Module, "setErrNo")) Module["setErrNo"] = function() { abort("'setErrNo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4599
if (!Object.getOwnPropertyDescriptor(Module, "DNS")) Module["DNS"] = function() { abort("'DNS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4600
if (!Object.getOwnPropertyDescriptor(Module, "GAI_ERRNO_MESSAGES")) Module["GAI_ERRNO_MESSAGES"] = function() { abort("'GAI_ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4601
if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] = function() { abort("'Protocols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4602
if (!Object.getOwnPropertyDescriptor(Module, "Sockets")) Module["Sockets"] = function() { abort("'Sockets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4603
if (!Object.getOwnPropertyDescriptor(Module, "UNWIND_CACHE")) Module["UNWIND_CACHE"] = function() { abort("'UNWIND_CACHE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4604
if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgs")) Module["readAsmConstArgs"] = function() { abort("'readAsmConstArgs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4605
if (!Object.getOwnPropertyDescriptor(Module, "jstoi_q")) Module["jstoi_q"] = function() { abort("'jstoi_q' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4606
if (!Object.getOwnPropertyDescriptor(Module, "jstoi_s")) Module["jstoi_s"] = function() { abort("'jstoi_s' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4607
if (!Object.getOwnPropertyDescriptor(Module, "abortStackOverflow")) Module["abortStackOverflow"] = function() { abort("'abortStackOverflow' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4608
if (!Object.getOwnPropertyDescriptor(Module, "reallyNegative")) Module["reallyNegative"] = function() { abort("'reallyNegative' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4609
if (!Object.getOwnPropertyDescriptor(Module, "formatString")) Module["formatString"] = function() { abort("'formatString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4610
if (!Object.getOwnPropertyDescriptor(Module, "PATH")) Module["PATH"] = function() { abort("'PATH' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4611
if (!Object.getOwnPropertyDescriptor(Module, "PATH_FS")) Module["PATH_FS"] = function() { abort("'PATH_FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4612
if (!Object.getOwnPropertyDescriptor(Module, "SYSCALLS")) Module["SYSCALLS"] = function() { abort("'SYSCALLS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4613
if (!Object.getOwnPropertyDescriptor(Module, "syscallMmap2")) Module["syscallMmap2"] = function() { abort("'syscallMmap2' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4614
if (!Object.getOwnPropertyDescriptor(Module, "syscallMunmap")) Module["syscallMunmap"] = function() { abort("'syscallMunmap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4615
if (!Object.getOwnPropertyDescriptor(Module, "JSEvents")) Module["JSEvents"] = function() { abort("'JSEvents' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4616
if (!Object.getOwnPropertyDescriptor(Module, "specialHTMLTargets")) Module["specialHTMLTargets"] = function() { abort("'specialHTMLTargets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4617
if (!Object.getOwnPropertyDescriptor(Module, "demangle")) Module["demangle"] = function() { abort("'demangle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4618
if (!Object.getOwnPropertyDescriptor(Module, "demangleAll")) Module["demangleAll"] = function() { abort("'demangleAll' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4619
if (!Object.getOwnPropertyDescriptor(Module, "jsStackTrace")) Module["jsStackTrace"] = function() { abort("'jsStackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4620
if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4621
if (!Object.getOwnPropertyDescriptor(Module, "getEnvStrings")) Module["getEnvStrings"] = function() { abort("'getEnvStrings' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4622
if (!Object.getOwnPropertyDescriptor(Module, "checkWasiClock")) Module["checkWasiClock"] = function() { abort("'checkWasiClock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4623
if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64")) Module["writeI53ToI64"] = function() { abort("'writeI53ToI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4624
if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Clamped")) Module["writeI53ToI64Clamped"] = function() { abort("'writeI53ToI64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4625
if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Signaling")) Module["writeI53ToI64Signaling"] = function() { abort("'writeI53ToI64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4626
if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Clamped")) Module["writeI53ToU64Clamped"] = function() { abort("'writeI53ToU64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4627
if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Signaling")) Module["writeI53ToU64Signaling"] = function() { abort("'writeI53ToU64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4628
if (!Object.getOwnPropertyDescriptor(Module, "readI53FromI64")) Module["readI53FromI64"] = function() { abort("'readI53FromI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4629
if (!Object.getOwnPropertyDescriptor(Module, "readI53FromU64")) Module["readI53FromU64"] = function() { abort("'readI53FromU64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4630
if (!Object.getOwnPropertyDescriptor(Module, "convertI32PairToI53")) Module["convertI32PairToI53"] = function() { abort("'convertI32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4631
if (!Object.getOwnPropertyDescriptor(Module, "convertU32PairToI53")) Module["convertU32PairToI53"] = function() { abort("'convertU32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4632
if (!Object.getOwnPropertyDescriptor(Module, "Browser")) Module["Browser"] = function() { abort("'Browser' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4633
if (!Object.getOwnPropertyDescriptor(Module, "FS")) Module["FS"] = function() { abort("'FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4634
if (!Object.getOwnPropertyDescriptor(Module, "MEMFS")) Module["MEMFS"] = function() { abort("'MEMFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4635
if (!Object.getOwnPropertyDescriptor(Module, "TTY")) Module["TTY"] = function() { abort("'TTY' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4636
if (!Object.getOwnPropertyDescriptor(Module, "PIPEFS")) Module["PIPEFS"] = function() { abort("'PIPEFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4637
if (!Object.getOwnPropertyDescriptor(Module, "SOCKFS")) Module["SOCKFS"] = function() { abort("'SOCKFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4638
if (!Object.getOwnPropertyDescriptor(Module, "GL")) Module["GL"] = function() { abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4639
if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGet")) Module["emscriptenWebGLGet"] = function() { abort("'emscriptenWebGLGet' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4640
if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetTexPixelData")) Module["emscriptenWebGLGetTexPixelData"] = function() { abort("'emscriptenWebGLGetTexPixelData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4641
if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetUniform")) Module["emscriptenWebGLGetUniform"] = function() { abort("'emscriptenWebGLGetUniform' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4642
if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetVertexAttrib")) Module["emscriptenWebGLGetVertexAttrib"] = function() { abort("'emscriptenWebGLGetVertexAttrib' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4643
if (!Object.getOwnPropertyDescriptor(Module, "AL")) Module["AL"] = function() { abort("'AL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4644
if (!Object.getOwnPropertyDescriptor(Module, "SDL_unicode")) Module["SDL_unicode"] = function() { abort("'SDL_unicode' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4645
if (!Object.getOwnPropertyDescriptor(Module, "SDL_ttfContext")) Module["SDL_ttfContext"] = function() { abort("'SDL_ttfContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4646
if (!Object.getOwnPropertyDescriptor(Module, "SDL_audio")) Module["SDL_audio"] = function() { abort("'SDL_audio' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4647
if (!Object.getOwnPropertyDescriptor(Module, "SDL")) Module["SDL"] = function() { abort("'SDL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4648
if (!Object.getOwnPropertyDescriptor(Module, "SDL_gfx")) Module["SDL_gfx"] = function() { abort("'SDL_gfx' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4649
if (!Object.getOwnPropertyDescriptor(Module, "GLUT")) Module["GLUT"] = function() { abort("'GLUT' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4650
if (!Object.getOwnPropertyDescriptor(Module, "EGL")) Module["EGL"] = function() { abort("'EGL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4651
if (!Object.getOwnPropertyDescriptor(Module, "GLFW_Window")) Module["GLFW_Window"] = function() { abort("'GLFW_Window' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4652
if (!Object.getOwnPropertyDescriptor(Module, "GLFW")) Module["GLFW"] = function() { abort("'GLFW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4653
if (!Object.getOwnPropertyDescriptor(Module, "GLEW")) Module["GLEW"] = function() { abort("'GLEW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4654
if (!Object.getOwnPropertyDescriptor(Module, "IDBStore")) Module["IDBStore"] = function() { abort("'IDBStore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4655
if (!Object.getOwnPropertyDescriptor(Module, "runAndAbortIfError")) Module["runAndAbortIfError"] = function() { abort("'runAndAbortIfError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4656
if (!Object.getOwnPropertyDescriptor(Module, "warnOnce")) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4657
if (!Object.getOwnPropertyDescriptor(Module, "stackSave")) Module["stackSave"] = function() { abort("'stackSave' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4658
if (!Object.getOwnPropertyDescriptor(Module, "stackRestore")) Module["stackRestore"] = function() { abort("'stackRestore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4659
if (!Object.getOwnPropertyDescriptor(Module, "stackAlloc")) Module["stackAlloc"] = function() { abort("'stackAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4660
if (!Object.getOwnPropertyDescriptor(Module, "AsciiToString")) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4661
if (!Object.getOwnPropertyDescriptor(Module, "stringToAscii")) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4662
if (!Object.getOwnPropertyDescriptor(Module, "UTF16ToString")) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4663
if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF16")) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4664
if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF16")) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4665
if (!Object.getOwnPropertyDescriptor(Module, "UTF32ToString")) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4666
if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF32")) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4667
if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF32")) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4668
if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8")) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4669
if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8OnStack")) Module["allocateUTF8OnStack"] = function() { abort("'allocateUTF8OnStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };
4670
Module["writeStackCookie"] = writeStackCookie;
4671
Module["checkStackCookie"] = checkStackCookie;if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NORMAL")) Object.defineProperty(Module, "ALLOC_NORMAL", { configurable: true, get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } });
4672
if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_STACK")) Object.defineProperty(Module, "ALLOC_STACK", { configurable: true, get: function() { abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } });
4673
if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_DYNAMIC")) Object.defineProperty(Module, "ALLOC_DYNAMIC", { configurable: true, get: function() { abort("'ALLOC_DYNAMIC' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } });
4674
if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NONE")) Object.defineProperty(Module, "ALLOC_NONE", { configurable: true, get: function() { abort("'ALLOC_NONE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } });
4675
4676
4677
4678
var calledRun;
4679
4680
/**
4681
 * @constructor
4682
 * @this {ExitStatus}
4683
 */
4684
function ExitStatus(status) {
4685
  this.name = "ExitStatus";
4686
  this.message = "Program terminated with exit(" + status + ")";
4687
  this.status = status;
4688
}
4689
4690
var calledMain = false;
4691
4692
4693
dependenciesFulfilled = function runCaller() {
4694
  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
4695
  if (!calledRun) run();
4696
  if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
4697
};
4698
4699
function callMain(args) {
4700
  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
4701
  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
4702
4703
  var entryFunction = Module['_main'];
4704
4705
4706
  args = args || [];
4707
4708
  var argc = args.length+1;
4709
  var argv = stackAlloc((argc + 1) * 4);
4710
  HEAP32[argv >> 2] = allocateUTF8OnStack(thisProgram);
4711
  for (var i = 1; i < argc; i++) {
4712
    HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i - 1]);
4713
  }
4714
  HEAP32[(argv >> 2) + argc] = 0;
4715
4716
  try {
4717
4718
    Module['___set_stack_limit'](STACK_MAX);
4719
4720
    var ret = entryFunction(argc, argv);
4721
4722
4723
    // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as execution is asynchronously handed
4724
    // off to a pthread.
4725
    // if we're not running an evented main loop, it's time to exit
4726
      exit(ret, /* implicit = */ true);
4727
  }
4728
  catch(e) {
4729
    if (e instanceof ExitStatus) {
4730
      // exit() throws this once it's done to make sure execution
4731
      // has been stopped completely
4732
      return;
4733
    } else if (e == 'unwind') {
4734
      // running an evented main loop, don't immediately exit
4735
      noExitRuntime = true;
4736
      return;
4737
    } else {
4738
      var toLog = e;
4739
      if (e && typeof e === 'object' && e.stack) {
4740
        toLog = [e, e.stack];
4741
      }
4742
      err('exception thrown: ' + toLog);
4743
      quit_(1, e);
4744
    }
4745
  } finally {
4746
    calledMain = true;
4747
  }
4748
}
4749
4750
4751
4752
4753
/** @type {function(Array=)} */
4754
function run(args) {
4755
  args = args || arguments_;
4756
4757
  if (runDependencies > 0) {
4758
    return;
4759
  }
4760
4761
  writeStackCookie();
4762
4763
  preRun();
4764
4765
  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
4766
4767
  function doRun() {
4768
    // run may have just been called through dependencies being fulfilled just in this very frame,
4769
    // or while the async setStatus time below was happening
4770
    if (calledRun) return;
4771
    calledRun = true;
4772
    Module['calledRun'] = true;
4773
4774
    if (ABORT) return;
4775
4776
    initRuntime();
4777
4778
    preMain();
4779
4780
    if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
4781
4782
    if (shouldRunNow) callMain(args);
4783
4784
    postRun();
4785
  }
4786
4787
  if (Module['setStatus']) {
4788
    Module['setStatus']('Running...');
4789
    setTimeout(function() {
4790
      setTimeout(function() {
4791
        Module['setStatus']('');
4792
      }, 1);
4793
      doRun();
4794
    }, 1);
4795
  } else
4796
  {
4797
    doRun();
4798
  }
4799
  checkStackCookie();
4800
}
4801
Module['run'] = run;
4802
4803
function checkUnflushedContent() {
4804
  // Compiler settings do not allow exiting the runtime, so flushing
4805
  // the streams is not possible. but in ASSERTIONS mode we check
4806
  // if there was something to flush, and if so tell the user they
4807
  // should request that the runtime be exitable.
4808
  // Normally we would not even include flush() at all, but in ASSERTIONS
4809
  // builds we do so just for this check, and here we see if there is any
4810
  // content to flush, that is, we check if there would have been
4811
  // something a non-ASSERTIONS build would have not seen.
4812
  // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
4813
  // mode (which has its own special function for this; otherwise, all
4814
  // the code is inside libc)
4815
  var print = out;
4816
  var printErr = err;
4817
  var has = false;
4818
  out = err = function(x) {
4819
    has = true;
4820
  }
4821
  try { // it doesn't matter if it fails
4822
    var flush = Module['_fflush'];
4823
    if (flush) flush(0);
4824
    // also flush in the JS FS layer
4825
    ['stdout', 'stderr'].forEach(function(name) {
4826
      var info = FS.analyzePath('/dev/' + name);
4827
      if (!info) return;
4828
      var stream = info.object;
4829
      var rdev = stream.rdev;
4830
      var tty = TTY.ttys[rdev];
4831
      if (tty && tty.output && tty.output.length) {
4832
        has = true;
4833
      }
4834
    });
4835
  } catch(e) {}
4836
  out = print;
4837
  err = printErr;
4838
  if (has) {
4839
    warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.');
4840
  }
4841
}
4842
4843
/** @param {boolean|number=} implicit */
4844
function exit(status, implicit) {
4845
  checkUnflushedContent();
4846
4847
  // if this is just main exit-ing implicitly, and the status is 0, then we
4848
  // don't need to do anything here and can just leave. if the status is
4849
  // non-zero, though, then we need to report it.
4850
  // (we may have warned about this earlier, if a situation justifies doing so)
4851
  if (implicit && noExitRuntime && status === 0) {
4852
    return;
4853
  }
4854
4855
  if (noExitRuntime) {
4856
    // if exit() was called, we may warn the user if the runtime isn't actually being shut down
4857
    if (!implicit) {
4858
      var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)';
4859
      err(msg);
4860
    }
4861
  } else {
4862
4863
    ABORT = true;
4864
    EXITSTATUS = status;
4865
4866
    exitRuntime();
4867
4868
    if (Module['onExit']) Module['onExit'](status);
4869
  }
4870
4871
  quit_(status, new ExitStatus(status));
4872
}
4873
4874
if (Module['preInit']) {
4875
  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
4876
  while (Module['preInit'].length > 0) {
4877
    Module['preInit'].pop()();
4878
  }
4879
}
4880
4881
// shouldRunNow refers to calling main(), not run().
4882
var shouldRunNow = true;
4883
4884
if (Module['noInitialRun']) shouldRunNow = false;
4885
4886
4887
  noExitRuntime = true;
4888
4889
run();
4890
4891
4892
4893
4894
4895
4896
// {{MODULE_ADDITIONS}}
4897
4898
4899