Merge pull request #28 from danleh/quicksort-wasm-scoring

Move quicksort-wasm to JS-style scoring
diff --git a/JetStreamDriver.js b/JetStreamDriver.js
index c28a020..e6abc30 100644
--- a/JetStreamDriver.js
+++ b/JetStreamDriver.js
@@ -1964,14 +1964,16 @@
         worstCaseCount: 2,
         testGroup: WasmGroup
     }),
-    new WasmLegacyBenchmark({
+    new WasmEMCCBenchmark({
         name: "quicksort-wasm",
         files: [
-            "./wasm/quicksort.js"
+            "./wasm/quicksort/build/quicksort.js",
+            "./wasm/quicksort/benchmark.js",
         ],
         preload: {
-            wasmBinary: "./wasm/quicksort.wasm"
+            wasmBinary: "./wasm/quicksort/build/quicksort.wasm"
         },
+        iterations: 50,
         testGroup: WasmGroup
     }),
     new WasmEMCCBenchmark({
diff --git a/wasm/quicksort.js b/wasm/quicksort.js
deleted file mode 100644
index 23bbb48..0000000
--- a/wasm/quicksort.js
+++ /dev/null
@@ -1,1198 +0,0 @@
-function doRun() {
-    let __startupStartTime = benchmarkTime();
-var moduleOverrides = {};
-var key;
-for (key in Module) {
- if (Module.hasOwnProperty(key)) {
-  moduleOverrides[key] = Module[key];
- }
-}
-Module["arguments"] = [];
-Module["thisProgram"] = "./this.program";
-Module["quit"] = (function(status, toThrow) {
- throw toThrow;
-});
-Module["preRun"] = [];
-Module["postRun"] = [];
-var ENVIRONMENT_IS_WEB = false;
-var ENVIRONMENT_IS_WORKER = false;
-var ENVIRONMENT_IS_NODE = false;
-var ENVIRONMENT_IS_SHELL = false;
-if (Module["ENVIRONMENT"]) {
- if (Module["ENVIRONMENT"] === "WEB") {
-  ENVIRONMENT_IS_WEB = true;
- } else if (Module["ENVIRONMENT"] === "WORKER") {
-  ENVIRONMENT_IS_WORKER = true;
- } else if (Module["ENVIRONMENT"] === "NODE") {
-  ENVIRONMENT_IS_NODE = true;
- } else if (Module["ENVIRONMENT"] === "SHELL") {
-  ENVIRONMENT_IS_SHELL = true;
- } else {
-  throw new Error("Module['ENVIRONMENT'] value is not valid. must be one of: WEB|WORKER|NODE|SHELL.");
- }
-} else {
- ENVIRONMENT_IS_WEB = typeof window === "object";
- ENVIRONMENT_IS_WORKER = typeof importScripts === "function";
- ENVIRONMENT_IS_NODE = typeof process === "object" && typeof require === "function" && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER;
- ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
-}
-if (ENVIRONMENT_IS_NODE) {
- var nodeFS;
- var nodePath;
- Module["read"] = function shell_read(filename, binary) {
-  var ret;
-  if (!nodeFS) nodeFS = require("fs");
-  if (!nodePath) nodePath = require("path");
-  filename = nodePath["normalize"](filename);
-  ret = nodeFS["readFileSync"](filename);
-  return binary ? ret : ret.toString();
- };
- Module["readBinary"] = function readBinary(filename) {
-  var ret = Module["read"](filename, true);
-  if (!ret.buffer) {
-   ret = new Uint8Array(ret);
-  }
-  assert(ret.buffer);
-  return ret;
- };
- if (process["argv"].length > 1) {
-  Module["thisProgram"] = process["argv"][1].replace(/\\/g, "/");
- }
- Module["arguments"] = process["argv"].slice(2);
- if (typeof module !== "undefined") {
-  module["exports"] = Module;
- }
- process["on"]("uncaughtException", (function(ex) {
-  if (!(ex instanceof ExitStatus)) {
-   throw ex;
-  }
- }));
- process["on"]("unhandledRejection", (function(reason, p) {
-  process["exit"](1);
- }));
- Module["inspect"] = (function() {
-  return "[Emscripten Module object]";
- });
-} else if (ENVIRONMENT_IS_SHELL) {
- if (typeof read != "undefined") {
-  Module["read"] = function shell_read(f) {
-   return read(f);
-  };
- }
- Module["readBinary"] = function readBinary(f) {
-  var data;
-  if (typeof readbuffer === "function") {
-   return new Uint8Array(readbuffer(f));
-  }
-  data = read(f, "binary");
-  assert(typeof data === "object");
-  return data;
- };
- if (typeof scriptArgs != "undefined") {
-  Module["arguments"] = scriptArgs;
- } else if (typeof arguments != "undefined") {
-  Module["arguments"] = arguments;
- }
- if (typeof quit === "function") {
-  Module["quit"] = (function(status, toThrow) {
-   quit(status);
-  });
- }
-} else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
- Module["read"] = function shell_read(url) {
-  var xhr = new XMLHttpRequest;
-  xhr.open("GET", url, false);
-  xhr.send(null);
-  return xhr.responseText;
- };
- if (ENVIRONMENT_IS_WORKER) {
-  Module["readBinary"] = function readBinary(url) {
-   var xhr = new XMLHttpRequest;
-   xhr.open("GET", url, false);
-   xhr.responseType = "arraybuffer";
-   xhr.send(null);
-   return new Uint8Array(xhr.response);
-  };
- }
- Module["readAsync"] = function readAsync(url, onload, onerror) {
-  var xhr = new XMLHttpRequest;
-  xhr.open("GET", url, true);
-  xhr.responseType = "arraybuffer";
-  xhr.onload = function xhr_onload() {
-   if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
-    onload(xhr.response);
-    return;
-   }
-   onerror();
-  };
-  xhr.onerror = onerror;
-  xhr.send(null);
- };
- Module["setWindowTitle"] = (function(title) {
-  document.title = title;
- });
-}
-Module["print"] = typeof console !== "undefined" ? console.log.bind(console) : typeof print !== "undefined" ? print : null;
-Module["printErr"] = typeof printErr !== "undefined" ? printErr : typeof console !== "undefined" && console.warn.bind(console) || Module["print"];
-Module.print = Module["print"];
-Module.printErr = Module["printErr"];
-for (key in moduleOverrides) {
- if (moduleOverrides.hasOwnProperty(key)) {
-  Module[key] = moduleOverrides[key];
- }
-}
-moduleOverrides = undefined;
-var STACK_ALIGN = 16;
-function staticAlloc(size) {
- assert(!staticSealed);
- var ret = STATICTOP;
- STATICTOP = STATICTOP + size + 15 & -16;
- return ret;
-}
-function dynamicAlloc(size) {
- assert(DYNAMICTOP_PTR);
- var ret = HEAP32[DYNAMICTOP_PTR >> 2];
- var end = ret + size + 15 & -16;
- HEAP32[DYNAMICTOP_PTR >> 2] = end;
- if (end >= TOTAL_MEMORY) {
-  var success = enlargeMemory();
-  if (!success) {
-   HEAP32[DYNAMICTOP_PTR >> 2] = ret;
-   return 0;
-  }
- }
- return ret;
-}
-function alignMemory(size, factor) {
- if (!factor) factor = STACK_ALIGN;
- var ret = size = Math.ceil(size / factor) * factor;
- return ret;
-}
-function getNativeTypeSize(type) {
- switch (type) {
- case "i1":
- case "i8":
-  return 1;
- case "i16":
-  return 2;
- case "i32":
-  return 4;
- case "i64":
-  return 8;
- case "float":
-  return 4;
- case "double":
-  return 8;
- default:
-  {
-   if (type[type.length - 1] === "*") {
-    return 4;
-   } else if (type[0] === "i") {
-    var bits = parseInt(type.substr(1));
-    assert(bits % 8 === 0);
-    return bits / 8;
-   } else {
-    return 0;
-   }
-  }
- }
-}
-function warnOnce(text) {
- if (!warnOnce.shown) warnOnce.shown = {};
- if (!warnOnce.shown[text]) {
-  warnOnce.shown[text] = 1;
-  Module.printErr(text);
- }
-}
-var jsCallStartIndex = 1;
-var functionPointers = new Array(0);
-var funcWrappers = {};
-function dynCall(sig, ptr, args) {
- if (args && args.length) {
-  return Module["dynCall_" + sig].apply(null, [ ptr ].concat(args));
- } else {
-  return Module["dynCall_" + sig].call(null, ptr);
- }
-}
-var GLOBAL_BASE = 1024;
-var ABORT = 0;
-var EXITSTATUS = 0;
-function assert(condition, text) {
- if (!condition) {
-  abort("Assertion failed: " + text);
- }
-}
-function getCFunc(ident) {
- var func = Module["_" + ident];
- assert(func, "Cannot call unknown function " + ident + ", make sure it is exported");
- return func;
-}
-var JSfuncs = {
- "stackSave": (function() {
-  stackSave();
- }),
- "stackRestore": (function() {
-  stackRestore();
- }),
- "arrayToC": (function(arr) {
-  var ret = stackAlloc(arr.length);
-  writeArrayToMemory(arr, ret);
-  return ret;
- }),
- "stringToC": (function(str) {
-  var ret = 0;
-  if (str !== null && str !== undefined && str !== 0) {
-   var len = (str.length << 2) + 1;
-   ret = stackAlloc(len);
-   stringToUTF8(str, ret, len);
-  }
-  return ret;
- })
-};
-var toC = {
- "string": JSfuncs["stringToC"],
- "array": JSfuncs["arrayToC"]
-};
-function ccall(ident, returnType, argTypes, args, opts) {
- var func = getCFunc(ident);
- var cArgs = [];
- var stack = 0;
- if (args) {
-  for (var i = 0; i < args.length; i++) {
-   var converter = toC[argTypes[i]];
-   if (converter) {
-    if (stack === 0) stack = stackSave();
-    cArgs[i] = converter(args[i]);
-   } else {
-    cArgs[i] = args[i];
-   }
-  }
- }
- var ret = func.apply(null, cArgs);
- if (returnType === "string") ret = Pointer_stringify(ret); else if (returnType === "boolean") ret = Boolean(ret);
- if (stack !== 0) {
-  stackRestore(stack);
- }
- return ret;
-}
-function setValue(ptr, value, type, noSafe) {
- type = type || "i8";
- if (type.charAt(type.length - 1) === "*") type = "i32";
- switch (type) {
- case "i1":
-  HEAP8[ptr >> 0] = value;
-  break;
- case "i8":
-  HEAP8[ptr >> 0] = value;
-  break;
- case "i16":
-  HEAP16[ptr >> 1] = value;
-  break;
- case "i32":
-  HEAP32[ptr >> 2] = value;
-  break;
- case "i64":
-  tempI64 = [ value >>> 0, (tempDouble = value, +Math_abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math_ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ], HEAP32[ptr >> 2] = tempI64[0], HEAP32[ptr + 4 >> 2] = tempI64[1];
-  break;
- case "float":
-  HEAPF32[ptr >> 2] = value;
-  break;
- case "double":
-  HEAPF64[ptr >> 3] = value;
-  break;
- default:
-  abort("invalid type for setValue: " + type);
- }
-}
-var ALLOC_STATIC = 2;
-var ALLOC_NONE = 4;
-function Pointer_stringify(ptr, length) {
- if (length === 0 || !ptr) return "";
- var hasUtf = 0;
- var t;
- var i = 0;
- while (1) {
-  t = HEAPU8[ptr + i >> 0];
-  hasUtf |= t;
-  if (t == 0 && !length) break;
-  i++;
-  if (length && i == length) break;
- }
- if (!length) length = i;
- var ret = "";
- if (hasUtf < 128) {
-  var MAX_CHUNK = 1024;
-  var curr;
-  while (length > 0) {
-   curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
-   ret = ret ? ret + curr : curr;
-   ptr += MAX_CHUNK;
-   length -= MAX_CHUNK;
-  }
-  return ret;
- }
- return UTF8ToString(ptr);
-}
-var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : undefined;
-function UTF8ArrayToString(u8Array, idx) {
- var endPtr = idx;
- while (u8Array[endPtr]) ++endPtr;
- if (endPtr - idx > 16 && u8Array.subarray && UTF8Decoder) {
-  return UTF8Decoder.decode(u8Array.subarray(idx, endPtr));
- } else {
-  var u0, u1, u2, u3, u4, u5;
-  var str = "";
-  while (1) {
-   u0 = u8Array[idx++];
-   if (!u0) return str;
-   if (!(u0 & 128)) {
-    str += String.fromCharCode(u0);
-    continue;
-   }
-   u1 = u8Array[idx++] & 63;
-   if ((u0 & 224) == 192) {
-    str += String.fromCharCode((u0 & 31) << 6 | u1);
-    continue;
-   }
-   u2 = u8Array[idx++] & 63;
-   if ((u0 & 240) == 224) {
-    u0 = (u0 & 15) << 12 | u1 << 6 | u2;
-   } else {
-    u3 = u8Array[idx++] & 63;
-    if ((u0 & 248) == 240) {
-     u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | u3;
-    } else {
-     u4 = u8Array[idx++] & 63;
-     if ((u0 & 252) == 248) {
-      u0 = (u0 & 3) << 24 | u1 << 18 | u2 << 12 | u3 << 6 | u4;
-     } else {
-      u5 = u8Array[idx++] & 63;
-      u0 = (u0 & 1) << 30 | u1 << 24 | u2 << 18 | u3 << 12 | u4 << 6 | u5;
-     }
-    }
-   }
-   if (u0 < 65536) {
-    str += String.fromCharCode(u0);
-   } else {
-    var ch = u0 - 65536;
-    str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
-   }
-  }
- }
-}
-function UTF8ToString(ptr) {
- return UTF8ArrayToString(HEAPU8, ptr);
-}
-function stringToUTF8Array(str, outU8Array, outIdx, maxBytesToWrite) {
- if (!(maxBytesToWrite > 0)) return 0;
- var startIdx = outIdx;
- var endIdx = outIdx + maxBytesToWrite - 1;
- for (var i = 0; i < str.length; ++i) {
-  var u = str.charCodeAt(i);
-  if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
-  if (u <= 127) {
-   if (outIdx >= endIdx) break;
-   outU8Array[outIdx++] = u;
-  } else if (u <= 2047) {
-   if (outIdx + 1 >= endIdx) break;
-   outU8Array[outIdx++] = 192 | u >> 6;
-   outU8Array[outIdx++] = 128 | u & 63;
-  } else if (u <= 65535) {
-   if (outIdx + 2 >= endIdx) break;
-   outU8Array[outIdx++] = 224 | u >> 12;
-   outU8Array[outIdx++] = 128 | u >> 6 & 63;
-   outU8Array[outIdx++] = 128 | u & 63;
-  } else if (u <= 2097151) {
-   if (outIdx + 3 >= endIdx) break;
-   outU8Array[outIdx++] = 240 | u >> 18;
-   outU8Array[outIdx++] = 128 | u >> 12 & 63;
-   outU8Array[outIdx++] = 128 | u >> 6 & 63;
-   outU8Array[outIdx++] = 128 | u & 63;
-  } else if (u <= 67108863) {
-   if (outIdx + 4 >= endIdx) break;
-   outU8Array[outIdx++] = 248 | u >> 24;
-   outU8Array[outIdx++] = 128 | u >> 18 & 63;
-   outU8Array[outIdx++] = 128 | u >> 12 & 63;
-   outU8Array[outIdx++] = 128 | u >> 6 & 63;
-   outU8Array[outIdx++] = 128 | u & 63;
-  } else {
-   if (outIdx + 5 >= endIdx) break;
-   outU8Array[outIdx++] = 252 | u >> 30;
-   outU8Array[outIdx++] = 128 | u >> 24 & 63;
-   outU8Array[outIdx++] = 128 | u >> 18 & 63;
-   outU8Array[outIdx++] = 128 | u >> 12 & 63;
-   outU8Array[outIdx++] = 128 | u >> 6 & 63;
-   outU8Array[outIdx++] = 128 | u & 63;
-  }
- }
- outU8Array[outIdx] = 0;
- return outIdx - startIdx;
-}
-function stringToUTF8(str, outPtr, maxBytesToWrite) {
- return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
-}
-function lengthBytesUTF8(str) {
- var len = 0;
- for (var i = 0; i < str.length; ++i) {
-  var u = str.charCodeAt(i);
-  if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023;
-  if (u <= 127) {
-   ++len;
-  } else if (u <= 2047) {
-   len += 2;
-  } else if (u <= 65535) {
-   len += 3;
-  } else if (u <= 2097151) {
-   len += 4;
-  } else if (u <= 67108863) {
-   len += 5;
-  } else {
-   len += 6;
-  }
- }
- return len;
-}
-var UTF16Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-16le") : undefined;
-function allocateUTF8OnStack(str) {
- var size = lengthBytesUTF8(str) + 1;
- var ret = stackAlloc(size);
- stringToUTF8Array(str, HEAP8, ret, size);
- return ret;
-}
-function demangle(func) {
- return func;
-}
-function demangleAll(text) {
- var regex = /__Z[\w\d_]+/g;
- return text.replace(regex, (function(x) {
-  var y = demangle(x);
-  return x === y ? x : x + " [" + y + "]";
- }));
-}
-function jsStackTrace() {
- var err = new Error;
- if (!err.stack) {
-  try {
-   throw new Error(0);
-  } catch (e) {
-   err = e;
-  }
-  if (!err.stack) {
-   return "(no stack trace available)";
-  }
- }
- return err.stack.toString();
-}
-var WASM_PAGE_SIZE = 65536;
-var ASMJS_PAGE_SIZE = 16777216;
-function alignUp(x, multiple) {
- if (x % multiple > 0) {
-  x += multiple - x % multiple;
- }
- return x;
-}
-var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
-function updateGlobalBuffer(buf) {
- Module["buffer"] = buffer = buf;
-}
-function updateGlobalBufferViews() {
- Module["HEAP8"] = HEAP8 = new Int8Array(buffer);
- Module["HEAP16"] = HEAP16 = new Int16Array(buffer);
- Module["HEAP32"] = HEAP32 = new Int32Array(buffer);
- Module["HEAPU8"] = HEAPU8 = new Uint8Array(buffer);
- Module["HEAPU16"] = HEAPU16 = new Uint16Array(buffer);
- Module["HEAPU32"] = HEAPU32 = new Uint32Array(buffer);
- Module["HEAPF32"] = HEAPF32 = new Float32Array(buffer);
- Module["HEAPF64"] = HEAPF64 = new Float64Array(buffer);
-}
-var STATIC_BASE, STATICTOP, staticSealed;
-var STACK_BASE, STACKTOP, STACK_MAX;
-var DYNAMIC_BASE, DYNAMICTOP_PTR;
-STATIC_BASE = STATICTOP = STACK_BASE = STACKTOP = STACK_MAX = DYNAMIC_BASE = DYNAMICTOP_PTR = 0;
-staticSealed = false;
-function abortOnCannotGrowMemory() {
- abort("Cannot enlarge memory arrays. Either (1) compile with  -s TOTAL_MEMORY=X  with X higher than the current value " + TOTAL_MEMORY + ", (2) compile with  -s ALLOW_MEMORY_GROWTH=1  which 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 ");
-}
-function enlargeMemory() {
- abortOnCannotGrowMemory();
-}
-var TOTAL_STACK = Module["TOTAL_STACK"] || 5242880;
-var TOTAL_MEMORY = Module["TOTAL_MEMORY"] || 67108864;
-if (TOTAL_MEMORY < TOTAL_STACK) Module.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was " + TOTAL_MEMORY + "! (TOTAL_STACK=" + TOTAL_STACK + ")");
-if (Module["buffer"]) {
- buffer = Module["buffer"];
-} else {
- if (typeof WebAssembly === "object" && typeof WebAssembly.Memory === "function") {
-  Module["wasmMemory"] = new WebAssembly.Memory({
-   "initial": TOTAL_MEMORY / WASM_PAGE_SIZE,
-   "maximum": TOTAL_MEMORY / WASM_PAGE_SIZE
-  });
-  buffer = Module["wasmMemory"].buffer;
- } else {
-  buffer = new ArrayBuffer(TOTAL_MEMORY);
- }
- Module["buffer"] = buffer;
-}
-updateGlobalBufferViews();
-function getTotalMemory() {
- return TOTAL_MEMORY;
-}
-HEAP32[0] = 1668509029;
-HEAP16[1] = 25459;
-if (HEAPU8[2] !== 115 || HEAPU8[3] !== 99) throw "Runtime error: expected the system to be little-endian!";
-function callRuntimeCallbacks(callbacks) {
- while (callbacks.length > 0) {
-  var callback = callbacks.shift();
-  if (typeof callback == "function") {
-   callback();
-   continue;
-  }
-  var func = callback.func;
-  if (typeof func === "number") {
-   if (callback.arg === undefined) {
-    Module["dynCall_v"](func);
-   } else {
-    Module["dynCall_vi"](func, callback.arg);
-   }
-  } else {
-   func(callback.arg === undefined ? null : callback.arg);
-  }
- }
-}
-var __ATPRERUN__ = [];
-var __ATINIT__ = [];
-var __ATMAIN__ = [];
-var __ATEXIT__ = [];
-var __ATPOSTRUN__ = [];
-var runtimeInitialized = false;
-var runtimeExited = false;
-function preRun() {
- if (Module["preRun"]) {
-  if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
-  while (Module["preRun"].length) {
-   addOnPreRun(Module["preRun"].shift());
-  }
- }
- callRuntimeCallbacks(__ATPRERUN__);
-}
-function ensureInitRuntime() {
- if (runtimeInitialized) return;
- runtimeInitialized = true;
- callRuntimeCallbacks(__ATINIT__);
-}
-function preMain() {
- callRuntimeCallbacks(__ATMAIN__);
-}
-function exitRuntime() {
- callRuntimeCallbacks(__ATEXIT__);
- runtimeExited = true;
-}
-function postRun() {
- if (Module["postRun"]) {
-  if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ];
-  while (Module["postRun"].length) {
-   addOnPostRun(Module["postRun"].shift());
-  }
- }
- callRuntimeCallbacks(__ATPOSTRUN__);
-}
-function addOnPreRun(cb) {
- __ATPRERUN__.unshift(cb);
-}
-function addOnPostRun(cb) {
- __ATPOSTRUN__.unshift(cb);
-}
-function writeArrayToMemory(array, buffer) {
- HEAP8.set(array, buffer);
-}
-function writeAsciiToMemory(str, buffer, dontAddNull) {
- for (var i = 0; i < str.length; ++i) {
-  HEAP8[buffer++ >> 0] = str.charCodeAt(i);
- }
- if (!dontAddNull) HEAP8[buffer >> 0] = 0;
-}
-var Math_abs = Math.abs;
-var Math_cos = Math.cos;
-var Math_sin = Math.sin;
-var Math_tan = Math.tan;
-var Math_acos = Math.acos;
-var Math_asin = Math.asin;
-var Math_atan = Math.atan;
-var Math_atan2 = Math.atan2;
-var Math_exp = Math.exp;
-var Math_log = Math.log;
-var Math_sqrt = Math.sqrt;
-var Math_ceil = Math.ceil;
-var Math_floor = Math.floor;
-var Math_pow = Math.pow;
-var Math_imul = Math.imul;
-var Math_fround = Math.fround;
-var Math_round = Math.round;
-var Math_min = Math.min;
-var Math_max = Math.max;
-var Math_clz32 = Math.clz32;
-var Math_trunc = Math.trunc;
-var runDependencies = 0;
-var runDependencyWatcher = null;
-var dependenciesFulfilled = null;
-function addRunDependency(id) {
- runDependencies++;
- if (Module["monitorRunDependencies"]) {
-  Module["monitorRunDependencies"](runDependencies);
- }
-}
-function removeRunDependency(id) {
- runDependencies--;
- if (Module["monitorRunDependencies"]) {
-  Module["monitorRunDependencies"](runDependencies);
- }
- if (runDependencies == 0) {
-  if (runDependencyWatcher !== null) {
-   clearInterval(runDependencyWatcher);
-   runDependencyWatcher = null;
-  }
-  if (dependenciesFulfilled) {
-   var callback = dependenciesFulfilled;
-   dependenciesFulfilled = null;
-   callback();
-  }
- }
-}
-Module["preloadedImages"] = {};
-Module["preloadedAudios"] = {};
-var dataURIPrefix = "data:application/octet-stream;base64,";
-function isDataURI(filename) {
- return String.prototype.startsWith ? filename.startsWith(dataURIPrefix) : filename.indexOf(dataURIPrefix) === 0;
-}
-function integrateWasmJS() {
- var wasmTextFile = "quicksort.wast";
- var wasmBinaryFile = "quicksort.wasm";
- var asmjsCodeFile = "quicksort.temp.asm.js";
- if (typeof Module["locateFile"] === "function") {
-  if (!isDataURI(wasmTextFile)) {
-   wasmTextFile = Module["locateFile"](wasmTextFile);
-  }
-  if (!isDataURI(wasmBinaryFile)) {
-   wasmBinaryFile = Module["locateFile"](wasmBinaryFile);
-  }
-  if (!isDataURI(asmjsCodeFile)) {
-   asmjsCodeFile = Module["locateFile"](asmjsCodeFile);
-  }
- }
- var wasmPageSize = 64 * 1024;
- var info = {
-  "global": null,
-  "env": null,
-  "asm2wasm": {
-   "f64-rem": (function(x, y) {
-    return x % y;
-   }),
-   "debugger": (function() {
-    debugger;
-   })
-  },
-  "parent": Module
- };
- var exports = null;
- function mergeMemory(newBuffer) {
-  var oldBuffer = Module["buffer"];
-  if (newBuffer.byteLength < oldBuffer.byteLength) {
-   Module["printErr"]("the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here");
-  }
-  var oldView = new Int8Array(oldBuffer);
-  var newView = new Int8Array(newBuffer);
-  newView.set(oldView);
-  updateGlobalBuffer(newBuffer);
-  updateGlobalBufferViews();
- }
- function fixImports(imports) {
-  return imports;
- }
- function getBinary() {
-  try {
-   if (Module["wasmBinary"]) {
-    return new Uint8Array(Module["wasmBinary"]);
-   }
-    throw "on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)";
-  } catch (err) {
-   abort(err);
-  }
- }
- function getBinaryPromise() {
-  if (!Module["wasmBinary"] && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === "function") {
-   return fetch(wasmBinaryFile, {
-    credentials: "same-origin"
-   }).then((function(response) {
-    if (!response["ok"]) {
-     throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
-    }
-    return response["arrayBuffer"]();
-   })).catch((function() {
-    return getBinary();
-   }));
-  }
-  return new Promise((function(resolve, reject) {
-   resolve(getBinary());
-  }));
- }
- function doNativeWasm(global, env, providedBuffer) {
-  if (typeof WebAssembly !== "object") {
-   Module["printErr"]("no native wasm support detected");
-   return false;
-  }
-  if (!(Module["wasmMemory"] instanceof WebAssembly.Memory)) {
-   Module["printErr"]("no native wasm Memory in use");
-   return false;
-  }
-  env["memory"] = Module["wasmMemory"];
-  info["global"] = {
-   "NaN": NaN,
-   "Infinity": Infinity
-  };
-  info["global.Math"] = Math;
-  info["env"] = env;
-  function receiveInstance(instance, module) {
-   exports = instance.exports;
-   if (exports.memory) mergeMemory(exports.memory);
-   Module["asm"] = exports;
-   Module["usingWasm"] = true;
-   removeRunDependency("wasm-instantiate");
-  }
-  addRunDependency("wasm-instantiate");
-  if (Module["instantiateWasm"]) {
-   try {
-    return Module["instantiateWasm"](info, receiveInstance);
-   } catch (e) {
-    Module["printErr"]("Module.instantiateWasm callback failed with error: " + e);
-    return false;
-   }
-  }
-  function receiveInstantiatedSource(output) {
-   receiveInstance(output["instance"], output["module"]);
-  }
-  function instantiateArrayBuffer(receiver) {
-   getBinaryPromise().then((function(binary) {
-    return WebAssembly.instantiate(binary, info);
-   })).then((...args) => {
-       reportCompileTime(benchmarkTime() - __startupStartTime);
-       return Promise.resolve(...args);
-   })
-   .then(receiver).catch((function(reason) {
-    Module["printErr"]("failed to asynchronously prepare wasm: " + reason);
-    abort(reason);
-   }));
-  }
-  if (!Module["wasmBinary"] && typeof WebAssembly.instantiateStreaming === "function" && !isDataURI(wasmBinaryFile) && typeof fetch === "function") {
-   WebAssembly.instantiateStreaming(fetch(wasmBinaryFile, {
-    credentials: "same-origin"
-   }), info).then(receiveInstantiatedSource).catch((function(reason) {
-    Module["printErr"]("wasm streaming compile failed: " + reason);
-    Module["printErr"]("falling back to ArrayBuffer instantiation");
-    instantiateArrayBuffer(receiveInstantiatedSource);
-   }));
-  } else {
-   instantiateArrayBuffer(receiveInstantiatedSource);
-  }
-  return {};
- }
- Module["asmPreload"] = Module["asm"];
- var asmjsReallocBuffer = Module["reallocBuffer"];
- var wasmReallocBuffer = (function(size) {
-  var PAGE_MULTIPLE = Module["usingWasm"] ? WASM_PAGE_SIZE : ASMJS_PAGE_SIZE;
-  size = alignUp(size, PAGE_MULTIPLE);
-  var old = Module["buffer"];
-  var oldSize = old.byteLength;
-  if (Module["usingWasm"]) {
-   try {
-    var result = Module["wasmMemory"].grow((size - oldSize) / wasmPageSize);
-    if (result !== (-1 | 0)) {
-     return Module["buffer"] = Module["wasmMemory"].buffer;
-    } else {
-     return null;
-    }
-   } catch (e) {
-    return null;
-   }
-  }
- });
- Module["reallocBuffer"] = (function(size) {
-  if (finalMethod === "asmjs") {
-   return asmjsReallocBuffer(size);
-  } else {
-   return wasmReallocBuffer(size);
-  }
- });
- var finalMethod = "";
- Module["asm"] = (function(global, env, providedBuffer) {
-  env = fixImports(env);
-  if (!env["table"]) {
-   var TABLE_SIZE = Module["wasmTableSize"];
-   if (TABLE_SIZE === undefined) TABLE_SIZE = 1024;
-   var MAX_TABLE_SIZE = Module["wasmMaxTableSize"];
-   if (typeof WebAssembly === "object" && typeof WebAssembly.Table === "function") {
-    if (MAX_TABLE_SIZE !== undefined) {
-     env["table"] = new WebAssembly.Table({
-      "initial": TABLE_SIZE,
-      "maximum": MAX_TABLE_SIZE,
-      "element": "anyfunc"
-     });
-    } else {
-     env["table"] = new WebAssembly.Table({
-      "initial": TABLE_SIZE,
-      element: "anyfunc"
-     });
-    }
-   } else {
-    env["table"] = new Array(TABLE_SIZE);
-   }
-   Module["wasmTable"] = env["table"];
-  }
-  if (!env["memoryBase"]) {
-   env["memoryBase"] = Module["STATIC_BASE"];
-  }
-  if (!env["tableBase"]) {
-   env["tableBase"] = 0;
-  }
-  var exports;
-  exports = doNativeWasm(global, env, providedBuffer);
-  if (!exports) abort("no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods");
-  return exports;
- });
-}
-integrateWasmJS();
-STATIC_BASE = GLOBAL_BASE;
-STATICTOP = STATIC_BASE + 22720;
-__ATINIT__.push();
-var STATIC_BUMP = 22720;
-Module["STATIC_BASE"] = STATIC_BASE;
-Module["STATIC_BUMP"] = STATIC_BUMP;
-var tempDoublePtr = STATICTOP;
-STATICTOP += 16;
-var SYSCALLS = {
- varargs: 0,
- get: (function(varargs) {
-  SYSCALLS.varargs += 4;
-  var ret = HEAP32[SYSCALLS.varargs - 4 >> 2];
-  return ret;
- }),
- getStr: (function() {
-  var ret = Pointer_stringify(SYSCALLS.get());
-  return ret;
- }),
- get64: (function() {
-  var low = SYSCALLS.get(), high = SYSCALLS.get();
-  if (low >= 0) assert(high === 0); else assert(high === -1);
-  return low;
- }),
- getZero: (function() {
-  assert(SYSCALLS.get() === 0);
- })
-};
-function ___syscall140(which, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-  var stream = SYSCALLS.getStreamFromFD(), offset_high = SYSCALLS.get(), offset_low = SYSCALLS.get(), result = SYSCALLS.get(), whence = SYSCALLS.get();
-  var offset = offset_low;
-  FS.llseek(stream, offset, whence);
-  HEAP32[result >> 2] = stream.position;
-  if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null;
-  return 0;
- } catch (e) {
-  if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
-  return -e.errno;
- }
-}
-function flush_NO_FILESYSTEM() {
- var fflush = Module["_fflush"];
- if (fflush) fflush(0);
- var printChar = ___syscall146.printChar;
- if (!printChar) return;
- var buffers = ___syscall146.buffers;
- if (buffers[1].length) printChar(1, 10);
- if (buffers[2].length) printChar(2, 10);
-}
-function ___syscall146(which, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-  var stream = SYSCALLS.get(), iov = SYSCALLS.get(), iovcnt = SYSCALLS.get();
-  var ret = 0;
-  if (!___syscall146.buffers) {
-   ___syscall146.buffers = [ null, [], [] ];
-   ___syscall146.printChar = (function(stream, curr) {
-    var buffer = ___syscall146.buffers[stream];
-    assert(buffer);
-    if (curr === 0 || curr === 10) {
-     (stream === 1 ? Module["print"] : Module["printErr"])(UTF8ArrayToString(buffer, 0));
-     buffer.length = 0;
-    } else {
-     buffer.push(curr);
-    }
-   });
-  }
-  for (var i = 0; i < iovcnt; i++) {
-   var ptr = HEAP32[iov + i * 8 >> 2];
-   var len = HEAP32[iov + (i * 8 + 4) >> 2];
-   for (var j = 0; j < len; j++) {
-    ___syscall146.printChar(stream, HEAPU8[ptr + j]);
-   }
-   ret += len;
-  }
-  return ret;
- } catch (e) {
-  if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
-  return -e.errno;
- }
-}
-function ___syscall54(which, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-  return 0;
- } catch (e) {
-  if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
-  return -e.errno;
- }
-}
-function ___syscall6(which, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-  var stream = SYSCALLS.getStreamFromFD();
-  FS.close(stream);
-  return 0;
- } catch (e) {
-  if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e);
-  return -e.errno;
- }
-}
-function _emscripten_memcpy_big(dest, src, num) {
- HEAPU8.set(HEAPU8.subarray(src, src + num), dest);
- return dest;
-}
-function ___setErrNo(value) {
- if (Module["___errno_location"]) HEAP32[Module["___errno_location"]() >> 2] = value;
- return value;
-}
-DYNAMICTOP_PTR = staticAlloc(4);
-STACK_BASE = STACKTOP = alignMemory(STATICTOP);
-STACK_MAX = STACK_BASE + TOTAL_STACK;
-DYNAMIC_BASE = alignMemory(STACK_MAX);
-HEAP32[DYNAMICTOP_PTR >> 2] = DYNAMIC_BASE;
-staticSealed = true;
-var ASSERTIONS = false;
-Module["wasmTableSize"] = 6;
-Module["wasmMaxTableSize"] = 6;
-function invoke_ii(index, a1) {
- try {
-  return Module["dynCall_ii"](index, a1);
- } catch (e) {
-  if (typeof e !== "number" && e !== "longjmp") throw e;
-  Module["setThrew"](1, 0);
- }
-}
-function invoke_iiii(index, a1, a2, a3) {
- try {
-  return Module["dynCall_iiii"](index, a1, a2, a3);
- } catch (e) {
-  if (typeof e !== "number" && e !== "longjmp") throw e;
-  Module["setThrew"](1, 0);
- }
-}
-Module.asmGlobalArg = {};
-Module.asmLibraryArg = {
- "abort": abort,
- "assert": assert,
- "enlargeMemory": enlargeMemory,
- "getTotalMemory": getTotalMemory,
- "abortOnCannotGrowMemory": abortOnCannotGrowMemory,
- "invoke_ii": invoke_ii,
- "invoke_iiii": invoke_iiii,
- "___setErrNo": ___setErrNo,
- "___syscall140": ___syscall140,
- "___syscall146": ___syscall146,
- "___syscall54": ___syscall54,
- "___syscall6": ___syscall6,
- "_emscripten_memcpy_big": _emscripten_memcpy_big,
- "flush_NO_FILESYSTEM": flush_NO_FILESYSTEM,
- "DYNAMICTOP_PTR": DYNAMICTOP_PTR,
- "tempDoublePtr": tempDoublePtr,
- "ABORT": ABORT,
- "STACKTOP": STACKTOP,
- "STACK_MAX": STACK_MAX
-};
-var asm = Module["asm"](Module.asmGlobalArg, Module.asmLibraryArg, buffer);
-Module["asm"] = asm;
-var ___errno_location = Module["___errno_location"] = (function() {
- return Module["asm"]["___errno_location"].apply(null, arguments);
-});
-var _free = Module["_free"] = (function() {
- return Module["asm"]["_free"].apply(null, arguments);
-});
-var _main = Module["_main"] = (function() {
- let start = benchmarkTime();
- let result = Module["asm"]["_main"].apply(null, arguments);
- reportRunTime(benchmarkTime() - start);
- return result;
-});
-var _malloc = Module["_malloc"] = (function() {
- return Module["asm"]["_malloc"].apply(null, arguments);
-});
-var _memcpy = Module["_memcpy"] = (function() {
- return Module["asm"]["_memcpy"].apply(null, arguments);
-});
-var _memset = Module["_memset"] = (function() {
- return Module["asm"]["_memset"].apply(null, arguments);
-});
-var _sbrk = Module["_sbrk"] = (function() {
- return Module["asm"]["_sbrk"].apply(null, arguments);
-});
-var establishStackSpace = Module["establishStackSpace"] = (function() {
- return Module["asm"]["establishStackSpace"].apply(null, arguments);
-});
-var getTempRet0 = Module["getTempRet0"] = (function() {
- return Module["asm"]["getTempRet0"].apply(null, arguments);
-});
-var runPostSets = Module["runPostSets"] = (function() {
- return Module["asm"]["runPostSets"].apply(null, arguments);
-});
-var setTempRet0 = Module["setTempRet0"] = (function() {
- return Module["asm"]["setTempRet0"].apply(null, arguments);
-});
-var setThrew = Module["setThrew"] = (function() {
- return Module["asm"]["setThrew"].apply(null, arguments);
-});
-var stackAlloc = Module["stackAlloc"] = (function() {
- return Module["asm"]["stackAlloc"].apply(null, arguments);
-});
-var stackRestore = Module["stackRestore"] = (function() {
- return Module["asm"]["stackRestore"].apply(null, arguments);
-});
-var stackSave = Module["stackSave"] = (function() {
- return Module["asm"]["stackSave"].apply(null, arguments);
-});
-var dynCall_ii = Module["dynCall_ii"] = (function() {
- return Module["asm"]["dynCall_ii"].apply(null, arguments);
-});
-var dynCall_iiii = Module["dynCall_iiii"] = (function() {
- return Module["asm"]["dynCall_iiii"].apply(null, arguments);
-});
-Module["asm"] = asm;
-function ExitStatus(status) {
- this.name = "ExitStatus";
- this.message = "Program terminated with exit(" + status + ")";
- this.status = status;
-}
-ExitStatus.prototype = new Error;
-ExitStatus.prototype.constructor = ExitStatus;
-var initialStackTop;
-var calledMain = false;
-dependenciesFulfilled = function runCaller() {
- if (!Module["calledRun"]) run();
- if (!Module["calledRun"]) dependenciesFulfilled = runCaller;
-};
-Module["callMain"] = function callMain(args) {
- args = args || [];
- ensureInitRuntime();
- var argc = args.length + 1;
- var argv = stackAlloc((argc + 1) * 4);
- HEAP32[argv >> 2] = allocateUTF8OnStack(Module["thisProgram"]);
- for (var i = 1; i < argc; i++) {
-  HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i - 1]);
- }
- HEAP32[(argv >> 2) + argc] = 0;
- try {
-  var ret = Module["_main"](argc, argv, 0);
-  exit(ret, true);
- } catch (e) {
-  if (e instanceof ExitStatus) {
-   return;
-  } else if (e == "SimulateInfiniteLoop") {
-   Module["noExitRuntime"] = true;
-   return;
-  } else {
-   var toLog = e;
-   if (e && typeof e === "object" && e.stack) {
-    toLog = [ e, e.stack ];
-   }
-   Module.printErr("exception thrown: " + toLog);
-   Module["quit"](1, e);
-  }
- } finally {
-  calledMain = true;
- }
-};
-function run(args) {
- args = args || Module["arguments"];
- if (runDependencies > 0) {
-  return;
- }
- preRun();
- if (runDependencies > 0) return;
- if (Module["calledRun"]) return;
- function doRun() {
-  if (Module["calledRun"]) return;
-  Module["calledRun"] = true;
-  if (ABORT) return;
-  ensureInitRuntime();
-  preMain();
-  if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"]();
-  if (Module["_main"] && shouldRunNow) Module["callMain"](args);
-  postRun();
- }
- if (Module["setStatus"]) {
-  Module["setStatus"]("Running...");
-  setTimeout((function() {
-   setTimeout((function() {
-    Module["setStatus"]("");
-   }), 1);
-   doRun();
-  }), 1);
- } else {
-  doRun();
- }
-}
-Module["run"] = run;
-function exit(status, implicit) {
- if (implicit && Module["noExitRuntime"] && status === 0) {
-  return;
- }
- if (Module["noExitRuntime"]) {} else {
-  ABORT = true;
-  EXITSTATUS = status;
-  STACKTOP = initialStackTop;
-  exitRuntime();
-  if (Module["onExit"]) Module["onExit"](status);
- }
- if (ENVIRONMENT_IS_NODE) {
-  process["exit"](status);
- }
- Module["quit"](status, new ExitStatus(status));
-}
-Module["exit"] = exit;
-function abort(what) {
- if (Module["onAbort"]) {
-  Module["onAbort"](what);
- }
- if (what !== undefined) {
-  Module.print(what);
-  Module.printErr(what);
-  what = JSON.stringify(what);
- } else {
-  what = "";
- }
- ABORT = true;
- EXITSTATUS = 1;
- throw "abort(" + what + "). Build with -s ASSERTIONS=1 for more info.";
-}
-Module["abort"] = abort;
-if (Module["preInit"]) {
- if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ];
- while (Module["preInit"].length > 0) {
-  Module["preInit"].pop()();
- }
-}
-var shouldRunNow = true;
-if (Module["noInitialRun"]) {
- shouldRunNow = false;
-}
-Module["noExitRuntime"] = true;
-run();
-}
diff --git a/wasm/quicksort.wasm b/wasm/quicksort.wasm
deleted file mode 100644
index 2f3f7b9..0000000
--- a/wasm/quicksort.wasm
+++ /dev/null
Binary files differ
diff --git a/wasm/quicksort/benchmark.js b/wasm/quicksort/benchmark.js
new file mode 100644
index 0000000..f39f218
--- /dev/null
+++ b/wasm/quicksort/benchmark.js
@@ -0,0 +1,12 @@
+// Copyright 2025 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+class Benchmark {
+  async runIteration() {
+    if (!Module._main)
+      await setupModule(Module);
+
+    Module._main();
+  }
+}
diff --git a/wasm/quicksort/build.log b/wasm/quicksort/build.log
new file mode 100644
index 0000000..fd5c866
--- /dev/null
+++ b/wasm/quicksort/build.log
@@ -0,0 +1,5 @@
+Built on 2025-01-21T12:25:46Z
+Toolchain versions
+emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.73 (ac676d5e437525d15df5fd46bc2c208ec6d376a3)
+Building...
+Building done
diff --git a/wasm/quicksort/build.sh b/wasm/quicksort/build.sh
new file mode 100755
index 0000000..d6bfdc3
--- /dev/null
+++ b/wasm/quicksort/build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+set -euo pipefail
+
+touch build.log
+BUILD_LOG="$(realpath build.log)"
+echo "Built on $(date -u '+%Y-%m-%dT%H:%M:%SZ')" | tee "$BUILD_LOG"
+
+echo "Toolchain versions" | tee -a "$BUILD_LOG"
+emcc --version | head -n1 | tee -a "$BUILD_LOG"
+
+echo "Building..." | tee -a "$BUILD_LOG"
+mkdir -p build
+emcc -o build/quicksort.js \
+    -s WASM=1 -O2 \
+    -g1 --emit-symbol-map \
+    -s MODULARIZE=1 \
+    -s EXPORT_NAME=setupModule \
+    quicksort.c | tee -a "$BUILD_LOG"
+
+echo "Building done" | tee -a "$BUILD_LOG"
diff --git a/wasm/quicksort/build/quicksort.js b/wasm/quicksort/build/quicksort.js
new file mode 100644
index 0000000..b8f5311
--- /dev/null
+++ b/wasm/quicksort/build/quicksort.js
@@ -0,0 +1,771 @@
+
+var setupModule = (() => {
+  var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
+  if (typeof __filename != 'undefined') _scriptName = _scriptName || __filename;
+  return (
+function(moduleArg = {}) {
+  var moduleRtn;
+
+// include: shell.js
+// The Module object: Our interface to the outside world. We import
+// and export values on it. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(moduleArg) => Promise<Module>
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to check if Module already exists (e.g. case 3 above).
+// Substitution will be replaced with actual code on later stage of the build,
+// this way Closure Compiler will not mangle it (e.g. case 4. above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module = moduleArg;
+
+// Set up the promise that indicates the Module is initialized
+var readyPromiseResolve, readyPromiseReject;
+
+var readyPromise = new Promise((resolve, reject) => {
+  readyPromiseResolve = resolve;
+  readyPromiseReject = reject;
+});
+
+// Determine the runtime environment we are in. You can customize this by
+// setting the ENVIRONMENT setting at compile time (see settings.js).
+// Attempt to auto-detect the environment
+var ENVIRONMENT_IS_WEB = typeof window == "object";
+
+var ENVIRONMENT_IS_WORKER = typeof WorkerGlobalScope != "undefined";
+
+// N.b. Electron.js environment is simultaneously a NODE-environment, but
+// also a web environment.
+var ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string" && process.type != "renderer";
+
+if (ENVIRONMENT_IS_NODE) {}
+
+// --pre-jses are emitted after the Module integration code, so that they can
+// refer to Module (if they choose; they can also define Module)
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = Object.assign({}, Module);
+
+var arguments_ = [];
+
+var thisProgram = "./this.program";
+
+var quit_ = (status, toThrow) => {
+  throw toThrow;
+};
+
+// `/` should be present at the end if `scriptDirectory` is not empty
+var scriptDirectory = "";
+
+function locateFile(path) {
+  if (Module["locateFile"]) {
+    return Module["locateFile"](path, scriptDirectory);
+  }
+  return scriptDirectory + path;
+}
+
+// Hooks that are implemented differently in different runtime environments.
+var readAsync, readBinary;
+
+if (ENVIRONMENT_IS_NODE) {
+  // These modules will usually be used on Node.js. Load them eagerly to avoid
+  // the complexity of lazy-loading.
+  var fs = require("fs");
+  var nodePath = require("path");
+  scriptDirectory = __dirname + "/";
+  // include: node_shell_read.js
+  readBinary = filename => {
+    // We need to re-wrap `file://` strings to URLs. Normalizing isn't
+    // necessary in that case, the path should already be absolute.
+    filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
+    var ret = fs.readFileSync(filename);
+    return ret;
+  };
+  readAsync = (filename, binary = true) => {
+    // See the comment in the `readBinary` function.
+    filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
+    return new Promise((resolve, reject) => {
+      fs.readFile(filename, binary ? undefined : "utf8", (err, data) => {
+        if (err) reject(err); else resolve(binary ? data.buffer : data);
+      });
+    });
+  };
+  // end include: node_shell_read.js
+  if (!Module["thisProgram"] && process.argv.length > 1) {
+    thisProgram = process.argv[1].replace(/\\/g, "/");
+  }
+  arguments_ = process.argv.slice(2);
+  // MODULARIZE will export the module in the proper place outside, we don't need to export here
+  quit_ = (status, toThrow) => {
+    process.exitCode = status;
+    throw toThrow;
+  };
+} else // Note that this includes Node.js workers when relevant (pthreads is enabled).
+// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
+// ENVIRONMENT_IS_NODE.
+if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  if (ENVIRONMENT_IS_WORKER) {
+    // Check worker, not web, since window could be polyfilled
+    scriptDirectory = self.location.href;
+  } else if (typeof document != "undefined" && document.currentScript) {
+    // web
+    scriptDirectory = document.currentScript.src;
+  }
+  // When MODULARIZE, this JS may be executed later, after document.currentScript
+  // is gone, so we saved it, and we use it here instead of any other info.
+  if (_scriptName) {
+    scriptDirectory = _scriptName;
+  }
+  // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
+  // otherwise, slice off the final part of the url to find the script directory.
+  // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
+  // and scriptDirectory will correctly be replaced with an empty string.
+  // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
+  // they are removed because they could contain a slash.
+  if (scriptDirectory.startsWith("blob:")) {
+    scriptDirectory = "";
+  } else {
+    scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1);
+  }
+  {
+    // include: web_or_worker_shell_read.js
+    if (ENVIRONMENT_IS_WORKER) {
+      readBinary = url => {
+        var xhr = new XMLHttpRequest;
+        xhr.open("GET", url, false);
+        xhr.responseType = "arraybuffer";
+        xhr.send(null);
+        return new Uint8Array(/** @type{!ArrayBuffer} */ (xhr.response));
+      };
+    }
+    readAsync = url => {
+      // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
+      // See https://github.com/github/fetch/pull/92#issuecomment-140665932
+      // Cordova or Electron apps are typically loaded from a file:// url.
+      // So use XHR on webview if URL is a file URL.
+      if (isFileURI(url)) {
+        return new Promise((resolve, reject) => {
+          var xhr = new XMLHttpRequest;
+          xhr.open("GET", url, true);
+          xhr.responseType = "arraybuffer";
+          xhr.onload = () => {
+            if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) {
+              // file URLs can return 0
+              resolve(xhr.response);
+              return;
+            }
+            reject(xhr.status);
+          };
+          xhr.onerror = reject;
+          xhr.send(null);
+        });
+      }
+      return fetch(url, {
+        credentials: "same-origin"
+      }).then(response => {
+        if (response.ok) {
+          return response.arrayBuffer();
+        }
+        return Promise.reject(new Error(response.status + " : " + response.url));
+      });
+    };
+  }
+} else // end include: web_or_worker_shell_read.js
+{}
+
+var out = Module["print"] || console.log.bind(console);
+
+var err = Module["printErr"] || console.error.bind(console);
+
+// Merge back in the overrides
+Object.assign(Module, moduleOverrides);
+
+// Free the object hierarchy contained in the overrides, this lets the GC
+// reclaim data used.
+moduleOverrides = null;
+
+// Emit code to handle expected values on the Module object. This applies Module.x
+// to the proper local x. This has two benefits: first, we only emit it if it is
+// expected to arrive, and second, by using a local everywhere else that can be
+// minified.
+if (Module["arguments"]) arguments_ = Module["arguments"];
+
+if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
+
+// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
+// end include: shell.js
+// include: preamble.js
+// === Preamble library stuff ===
+// Documentation for the public APIs defined in this file must be updated in:
+//    site/source/docs/api_reference/preamble.js.rst
+// A prebuilt local version of the documentation is available at:
+//    site/build/text/docs/api_reference/preamble.js.txt
+// You can also build docs locally as HTML or other formats in site/
+// An online HTML version (which may be of a different version of Emscripten)
+//    is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
+var wasmBinary = Module["wasmBinary"];
+
+// Wasm globals
+var wasmMemory;
+
+//========================================
+// Runtime essentials
+//========================================
+// whether we are quitting the application. no code should run after this.
+// set in exit() and abort()
+var ABORT = false;
+
+// set by exit() and abort().  Passed to 'onExit' handler.
+// NOTE: This is also used as the process return code code in shell environments
+// but only when noExitRuntime is false.
+var EXITSTATUS;
+
+// Memory management
+var /** @type {!Int8Array} */ HEAP8, /** @type {!Uint8Array} */ HEAPU8, /** @type {!Int16Array} */ HEAP16, /** @type {!Uint16Array} */ HEAPU16, /** @type {!Int32Array} */ HEAP32, /** @type {!Uint32Array} */ HEAPU32, /** @type {!Float32Array} */ HEAPF32, /** @type {!Float64Array} */ HEAPF64;
+
+// include: runtime_shared.js
+function updateMemoryViews() {
+  var b = wasmMemory.buffer;
+  Module["HEAP8"] = HEAP8 = new Int8Array(b);
+  Module["HEAP16"] = HEAP16 = new Int16Array(b);
+  Module["HEAPU8"] = HEAPU8 = new Uint8Array(b);
+  Module["HEAPU16"] = HEAPU16 = new Uint16Array(b);
+  Module["HEAP32"] = HEAP32 = new Int32Array(b);
+  Module["HEAPU32"] = HEAPU32 = new Uint32Array(b);
+  Module["HEAPF32"] = HEAPF32 = new Float32Array(b);
+  Module["HEAPF64"] = HEAPF64 = new Float64Array(b);
+}
+
+// end include: runtime_shared.js
+// include: runtime_stack_check.js
+// end include: runtime_stack_check.js
+var __ATPRERUN__ = [];
+
+// functions called before the runtime is initialized
+var __ATINIT__ = [];
+
+// functions called during startup
+var __ATMAIN__ = [];
+
+// functions called during shutdown
+var __ATPOSTRUN__ = [];
+
+// functions called after the main() is called
+var runtimeInitialized = false;
+
+function preRun() {
+  if (Module["preRun"]) {
+    if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
+    while (Module["preRun"].length) {
+      addOnPreRun(Module["preRun"].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function initRuntime() {
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function postRun() {
+  if (Module["postRun"]) {
+    if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ];
+    while (Module["postRun"].length) {
+      addOnPostRun(Module["postRun"].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+
+// include: runtime_math.js
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
+// end include: runtime_math.js
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// Module.preRun (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+
+var runDependencyWatcher = null;
+
+var dependenciesFulfilled = null;
+
+function addRunDependency(id) {
+  runDependencies++;
+  Module["monitorRunDependencies"]?.(runDependencies);
+}
+
+function removeRunDependency(id) {
+  runDependencies--;
+  Module["monitorRunDependencies"]?.(runDependencies);
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback();
+    }
+  }
+}
+
+/** @param {string|number=} what */ function abort(what) {
+  Module["onAbort"]?.(what);
+  what = "Aborted(" + what + ")";
+  // TODO(sbc): Should we remove printing and leave it up to whoever
+  // catches the exception?
+  err(what);
+  ABORT = true;
+  what += ". Build with -sASSERTIONS for more info.";
+  // Use a wasm runtime error, because a JS error might be seen as a foreign
+  // exception, which means we'd run destructors on it. We need the error to
+  // simply make the program stop.
+  // FIXME This approach does not work in Wasm EH because it currently does not assume
+  // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
+  // a trap or not based on a hidden field within the object. So at the moment
+  // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
+  // allows this in the wasm spec.
+  // Suppress closure compiler warning here. Closure compiler's builtin extern
+  // definition for WebAssembly.RuntimeError claims it takes no arguments even
+  // though it can.
+  // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
+  /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what);
+  readyPromiseReject(e);
+  // Throw the error whether or not MODULARIZE is set because abort is used
+  // in code paths apart from instantiation where an exception is expected
+  // to be thrown when abort is called.
+  throw e;
+}
+
+// include: memoryprofiler.js
+// end include: memoryprofiler.js
+// include: URIUtils.js
+// Prefix of data URIs emitted by SINGLE_FILE and related options.
+var dataURIPrefix = "data:application/octet-stream;base64,";
+
+/**
+ * Indicates whether filename is a base64 data URI.
+ * @noinline
+ */ var isDataURI = filename => filename.startsWith(dataURIPrefix);
+
+/**
+ * Indicates whether filename is delivered via file protocol (as opposed to http/https)
+ * @noinline
+ */ var isFileURI = filename => filename.startsWith("file://");
+
+// end include: URIUtils.js
+// include: runtime_exceptions.js
+// end include: runtime_exceptions.js
+function findWasmBinary() {
+  var f = "quicksort.wasm";
+  if (!isDataURI(f)) {
+    return locateFile(f);
+  }
+  return f;
+}
+
+var wasmBinaryFile;
+
+function getBinarySync(file) {
+  if (file == wasmBinaryFile && wasmBinary) {
+    return new Uint8Array(wasmBinary);
+  }
+  if (readBinary) {
+    return readBinary(file);
+  }
+  throw "both async and sync fetching of the wasm failed";
+}
+
+function getBinaryPromise(binaryFile) {
+  // If we don't have the binary yet, load it asynchronously using readAsync.
+  if (!wasmBinary) {
+    // Fetch the binary using readAsync
+    return readAsync(binaryFile).then(response => new Uint8Array(/** @type{!ArrayBuffer} */ (response)), // Fall back to getBinarySync if readAsync fails
+    () => getBinarySync(binaryFile));
+  }
+  // Otherwise, getBinarySync should be able to get it synchronously
+  return Promise.resolve().then(() => getBinarySync(binaryFile));
+}
+
+function instantiateArrayBuffer(binaryFile, imports, receiver) {
+  return getBinaryPromise(binaryFile).then(binary => WebAssembly.instantiate(binary, imports)).then(receiver, reason => {
+    err(`failed to asynchronously prepare wasm: ${reason}`);
+    abort(reason);
+  });
+}
+
+function instantiateAsync(binary, binaryFile, imports, callback) {
+  if (!binary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(binaryFile) && // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously.
+  !isFileURI(binaryFile) && // Avoid instantiateStreaming() on Node.js environment for now, as while
+  // Node.js v18.1.0 implements it, it does not have a full fetch()
+  // implementation yet.
+  // Reference:
+  //   https://github.com/emscripten-core/emscripten/pull/16917
+  !ENVIRONMENT_IS_NODE && typeof fetch == "function") {
+    return fetch(binaryFile, {
+      credentials: "same-origin"
+    }).then(response => {
+      // Suppress closure warning here since the upstream definition for
+      // instantiateStreaming only allows Promise<Repsponse> rather than
+      // an actual Response.
+      // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
+      /** @suppress {checkTypes} */ var result = WebAssembly.instantiateStreaming(response, imports);
+      return result.then(callback, function(reason) {
+        // We expect the most common failure cause to be a bad MIME type for the binary,
+        // in which case falling back to ArrayBuffer instantiation should work.
+        err(`wasm streaming compile failed: ${reason}`);
+        err("falling back to ArrayBuffer instantiation");
+        return instantiateArrayBuffer(binaryFile, imports, callback);
+      });
+    });
+  }
+  return instantiateArrayBuffer(binaryFile, imports, callback);
+}
+
+function getWasmImports() {
+  // prepare imports
+  return {
+    "env": wasmImports,
+    "wasi_snapshot_preview1": wasmImports
+  };
+}
+
+// Create the wasm instance.
+// Receives the wasm imports, returns the exports.
+function createWasm() {
+  // Load the wasm module and create an instance of using native support in the JS engine.
+  // handle a generated wasm instance, receiving its exports and
+  // performing other necessary setup
+  /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) {
+    wasmExports = instance.exports;
+    wasmMemory = wasmExports["memory"];
+    updateMemoryViews();
+    addOnInit(wasmExports["__wasm_call_ctors"]);
+    removeRunDependency("wasm-instantiate");
+    return wasmExports;
+  }
+  // wait for the pthread pool (if any)
+  addRunDependency("wasm-instantiate");
+  // Prefer streaming instantiation if available.
+  function receiveInstantiationResult(result) {
+    // 'result' is a ResultObject object which has both the module and instance.
+    // receiveInstance() will swap in the exports (to Module.asm) so they can be called
+    // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
+    // When the regression is fixed, can restore the above PTHREADS-enabled path.
+    receiveInstance(result["instance"]);
+  }
+  var info = getWasmImports();
+  // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
+  // to manually instantiate the Wasm module themselves. This allows pages to
+  // run the instantiation parallel to any other async startup actions they are
+  // performing.
+  // Also pthreads and wasm workers initialize the wasm instance through this
+  // path.
+  if (Module["instantiateWasm"]) {
+    try {
+      return Module["instantiateWasm"](info, receiveInstance);
+    } catch (e) {
+      err(`Module.instantiateWasm callback failed with error: ${e}`);
+      // If instantiation fails, reject the module ready promise.
+      readyPromiseReject(e);
+    }
+  }
+  wasmBinaryFile ??= findWasmBinary();
+  // If instantiation fails, reject the module ready promise.
+  instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult).catch(readyPromiseReject);
+  return {};
+}
+
+// include: runtime_debug.js
+// end include: runtime_debug.js
+// === Body ===
+// end include: preamble.js
+class ExitStatus {
+  name="ExitStatus";
+  constructor(status) {
+    this.message = `Program terminated with exit(${status})`;
+    this.status = status;
+  }
+}
+
+var callRuntimeCallbacks = callbacks => {
+  while (callbacks.length > 0) {
+    // Pass the module as the first argument.
+    callbacks.shift()(Module);
+  }
+};
+
+var noExitRuntime = Module["noExitRuntime"] || true;
+
+var __emscripten_memcpy_js = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num);
+
+var printCharBuffers = [ null, [], [] ];
+
+var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder : undefined;
+
+/**
+     * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
+     * array that contains uint8 values, returns a copy of that string as a
+     * Javascript String object.
+     * heapOrArray is either a regular array, or a JavaScript typed array view.
+     * @param {number=} idx
+     * @param {number=} maxBytesToRead
+     * @return {string}
+     */ var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => {
+  var endIdx = idx + maxBytesToRead;
+  var endPtr = idx;
+  // TextDecoder needs to know the byte length in advance, it doesn't stop on
+  // null terminator by itself.  Also, use the length info to avoid running tiny
+  // strings through TextDecoder, since .subarray() allocates garbage.
+  // (As a tiny code save trick, compare endPtr against endIdx using a negation,
+  // so that undefined/NaN means Infinity)
+  while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
+  if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
+    return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
+  }
+  var str = "";
+  // If building with TextDecoder, we have already computed the string length
+  // above, so test loop end condition against that
+  while (idx < endPtr) {
+    // For UTF8 byte structure, see:
+    // http://en.wikipedia.org/wiki/UTF-8#Description
+    // https://www.ietf.org/rfc/rfc2279.txt
+    // https://tools.ietf.org/html/rfc3629
+    var u0 = heapOrArray[idx++];
+    if (!(u0 & 128)) {
+      str += String.fromCharCode(u0);
+      continue;
+    }
+    var u1 = heapOrArray[idx++] & 63;
+    if ((u0 & 224) == 192) {
+      str += String.fromCharCode(((u0 & 31) << 6) | u1);
+      continue;
+    }
+    var u2 = heapOrArray[idx++] & 63;
+    if ((u0 & 240) == 224) {
+      u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
+    } else {
+      u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
+    }
+    if (u0 < 65536) {
+      str += String.fromCharCode(u0);
+    } else {
+      var ch = u0 - 65536;
+      str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
+    }
+  }
+  return str;
+};
+
+var printChar = (stream, curr) => {
+  var buffer = printCharBuffers[stream];
+  if (curr === 0 || curr === 10) {
+    (stream === 1 ? out : err)(UTF8ArrayToString(buffer));
+    buffer.length = 0;
+  } else {
+    buffer.push(curr);
+  }
+};
+
+/**
+     * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
+     * emscripten HEAP, returns a copy of that string as a Javascript String object.
+     *
+     * @param {number} ptr
+     * @param {number=} maxBytesToRead - An optional length that specifies the
+     *   maximum number of bytes to read. You can omit this parameter to scan the
+     *   string until the first 0 byte. If maxBytesToRead is passed, and the string
+     *   at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
+     *   string will cut short at that byte index (i.e. maxBytesToRead will not
+     *   produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
+     *   frequent uses of UTF8ToString() with and without maxBytesToRead may throw
+     *   JS JIT optimizations off, so it is worth to consider consistently using one
+     * @return {string}
+     */ var UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
+
+var _fd_write = (fd, iov, iovcnt, pnum) => {
+  // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0
+  var num = 0;
+  for (var i = 0; i < iovcnt; i++) {
+    var ptr = HEAPU32[((iov) >> 2)];
+    var len = HEAPU32[(((iov) + (4)) >> 2)];
+    iov += 8;
+    for (var j = 0; j < len; j++) {
+      printChar(fd, HEAPU8[ptr + j]);
+    }
+    num += len;
+  }
+  HEAPU32[((pnum) >> 2)] = num;
+  return 0;
+};
+
+var runtimeKeepaliveCounter = 0;
+
+var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
+
+var _proc_exit = code => {
+  EXITSTATUS = code;
+  if (!keepRuntimeAlive()) {
+    Module["onExit"]?.(code);
+    ABORT = true;
+  }
+  quit_(code, new ExitStatus(code));
+};
+
+/** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => {
+  EXITSTATUS = status;
+  _proc_exit(status);
+};
+
+var handleException = e => {
+  // Certain exception types we do not treat as errors since they are used for
+  // internal control flow.
+  // 1. ExitStatus, which is thrown by exit()
+  // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
+  //    that wish to return to JS event loop.
+  if (e instanceof ExitStatus || e == "unwind") {
+    return EXITSTATUS;
+  }
+  quit_(1, e);
+};
+
+var wasmImports = {
+  /** @export */ _emscripten_memcpy_js: __emscripten_memcpy_js,
+  /** @export */ fd_write: _fd_write
+};
+
+var wasmExports = createWasm();
+
+var ___wasm_call_ctors = () => (___wasm_call_ctors = wasmExports["__wasm_call_ctors"])();
+
+var _main = Module["_main"] = (a0, a1) => (_main = Module["_main"] = wasmExports["main"])(a0, a1);
+
+var __emscripten_stack_restore = a0 => (__emscripten_stack_restore = wasmExports["_emscripten_stack_restore"])(a0);
+
+var __emscripten_stack_alloc = a0 => (__emscripten_stack_alloc = wasmExports["_emscripten_stack_alloc"])(a0);
+
+var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports["emscripten_stack_get_current"])();
+
+var dynCall_jiji = Module["dynCall_jiji"] = (a0, a1, a2, a3, a4) => (dynCall_jiji = Module["dynCall_jiji"] = wasmExports["dynCall_jiji"])(a0, a1, a2, a3, a4);
+
+// include: postamble.js
+// === Auto-generated postamble setup entry stuff ===
+var calledRun;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!calledRun) run();
+  if (!calledRun) dependenciesFulfilled = runCaller;
+};
+
+// try this again later, after new deps are fulfilled
+function callMain() {
+  var entryFunction = _main;
+  var argc = 0;
+  var argv = 0;
+  try {
+    var ret = entryFunction(argc, argv);
+    // if we're not running an evented main loop, it's time to exit
+    exitJS(ret, /* implicit = */ true);
+    return ret;
+  } catch (e) {
+    return handleException(e);
+  }
+}
+
+function run() {
+  if (runDependencies > 0) {
+    return;
+  }
+  preRun();
+  // a preRun added a dependency, run will be called later
+  if (runDependencies > 0) {
+    return;
+  }
+  function doRun() {
+    // run may have just been called through dependencies being fulfilled just in this very frame,
+    // or while the async setStatus time below was happening
+    if (calledRun) return;
+    calledRun = true;
+    Module["calledRun"] = true;
+    if (ABORT) return;
+    initRuntime();
+    preMain();
+    readyPromiseResolve(Module);
+    Module["onRuntimeInitialized"]?.();
+    if (shouldRunNow) callMain();
+    postRun();
+  }
+  if (Module["setStatus"]) {
+    Module["setStatus"]("Running...");
+    setTimeout(() => {
+      setTimeout(() => Module["setStatus"](""), 1);
+      doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+
+if (Module["preInit"]) {
+  if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ];
+  while (Module["preInit"].length > 0) {
+    Module["preInit"].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+
+if (Module["noInitialRun"]) shouldRunNow = false;
+
+run();
+
+// end include: postamble.js
+// include: postamble_modularize.js
+// In MODULARIZE mode we wrap the generated code in a factory function
+// and return either the Module itself, or a promise of the module.
+// We assign to the `moduleRtn` global here and configure closure to see
+// this as and extern so it won't get minified.
+moduleRtn = readyPromise;
+
+
+  return moduleRtn;
+}
+);
+})();
+if (typeof exports === 'object' && typeof module === 'object')
+  module.exports = setupModule;
+else if (typeof define === 'function' && define['amd'])
+  define([], () => setupModule);
diff --git a/wasm/quicksort/build/quicksort.js.symbols b/wasm/quicksort/build/quicksort.js.symbols
new file mode 100644
index 0000000..bcc944c
--- /dev/null
+++ b/wasm/quicksort/build/quicksort.js.symbols
@@ -0,0 +1,22 @@
+0:_emscripten_memcpy_js
+1:__wasi_fd_write
+2:__wasm_call_ctors
+3:Quicksort
+4:main
+5:__towrite
+6:__fwritex
+7:__stdio_write
+8:__emscripten_stdout_close
+9:__emscripten_stdout_seek
+10:__memset
+11:printf_core
+12:out
+13:getint
+14:pop_arg
+15:pad
+16:__wasi_syscall_ret
+17:wctomb
+18:_emscripten_stack_restore
+19:_emscripten_stack_alloc
+20:emscripten_stack_get_current
+21:legalstub$dynCall_jiji
diff --git a/wasm/quicksort/build/quicksort.wasm b/wasm/quicksort/build/quicksort.wasm
new file mode 100755
index 0000000..af6c419
--- /dev/null
+++ b/wasm/quicksort/build/quicksort.wasm
Binary files differ
diff --git a/wasm/quicksort.c b/wasm/quicksort/quicksort.c
similarity index 100%
rename from wasm/quicksort.c
rename to wasm/quicksort/quicksort.c