benz-amr-wb-recorder
Version:
amr 音频录制与播放,支持amr-wb,需要用到这个fork了一份
1,140 lines (1,086 loc) • 368 kB
JavaScript
module.exports = function() {
var Module = typeof Module !== "undefined" ? Module : {};
var AMRWB = (function() {
var AMRWB = {
toWAV: (function (amr) {
var decoded = this._decode(amr);
if (!decoded) {
return null
}
var raw = new Uint8Array(decoded.buffer, decoded.byteOffset, decoded.byteLength);
var out = new Uint8Array(raw.length + this.WAV_HEADER_SIZE);
var offset = 0;
var write_int16 = (function (value) {
var a = new Uint8Array(2);
(new Int16Array(a.buffer))[0] = value;
out.set(a, offset);
offset += 2
});
var write_int32 = (function (value) {
var a = new Uint8Array(4);
(new Int32Array(a.buffer))[0] = value;
out.set(a, offset);
offset += 4
});
var write_string = (function (value) {
var d = (new TextEncoder("utf-8")).encode(value);
out.set(d, offset);
offset += d.length
});
write_string("RIFF");
write_int32(4 + 8 + 16 + 8 + raw.length);
write_string("WAVEfmt ");
write_int32(16);
var bits_per_sample = 16;
var sample_rate = 16e3;
var channels = 1;
var bytes_per_frame = bits_per_sample / 8 * channels;
var bytes_per_sec = bytes_per_frame * sample_rate;
write_int16(1);
write_int16(1);
write_int32(sample_rate);
write_int32(bytes_per_sec);
write_int16(bytes_per_frame);
write_int16(bits_per_sample);
write_string("data");
write_int32(raw.length);
out.set(raw, offset);
return out
}),
/**
* Decode AMR file to the PCM data with sample rate 8000.
* @param {Uint8Array} amr The raw amr file data.
* @returns {Float32Array} PCM data if succeeded. Otherwise null.
*/
decode: function(amr) {
var raw = this._decode(amr);
if (!raw) {
return null;
}
var out = new Float32Array(raw.length);
for (var i = 0; i < out.length; i++) {
out[i] = raw[i] / 0x8000;
}
return out;
},
encode: (function (pcm, pcmSampleRate, mode) {
if (pcmSampleRate < 8e3) {
console.error("pcmSampleRate should not be less than 8000.");
return null
}
if (typeof mode === "undefined") {
mode = this.Mode.MR795
}
var encoder = this.Encoder_Interface_init();
if (!encoder) {
return null
}
var buf = Module._malloc(this.PCM_BUFFER_COUNT * 2);
var encodeInBuffer = new Int16Array(Module.HEAPU8.buffer, buf, this.PCM_BUFFER_COUNT);
buf = Module._malloc(this.AMR_BUFFER_COUNT);
var encodeOutBuffer = new Uint8Array(Module.HEAPU8.buffer, buf, this.AMR_BUFFER_COUNT);
var ratio = pcmSampleRate / 8e3;
var inLength = Math.floor(pcm.length / ratio);
var inData = new Int16Array(inLength);
for (var i = 0; i < inLength; i++) {
inData[i] = pcm[Math.floor(i * ratio)] * (32768 - 1)
}
var blockSize = this.SIZES[mode] + 1;
var out = new Uint8Array(Math.ceil(inLength / this.PCM_BUFFER_COUNT * blockSize) + this.AMR_HEADER.length);
out.set((new TextEncoder("utf-8")).encode(this.AMR_HEADER));
var inOffset = 0;
var outOffset = this.AMR_HEADER.length;
while (inOffset + this.PCM_BUFFER_COUNT < inData.length && outOffset + blockSize < out.length) {
encodeInBuffer.set(inData.subarray(inOffset, inOffset + this.PCM_BUFFER_COUNT));
var n = this.Encoder_Interface_Encode(encoder, mode, encodeInBuffer.byteOffset, encodeOutBuffer.byteOffset, 0);
if (n != blockSize) {
console.error([n, blockSize]);
break
}
out.set(encodeOutBuffer.subarray(0, n), outOffset);
inOffset += this.PCM_BUFFER_COUNT;
outOffset += n
}
Module._free(encodeInBuffer.byteOffset);
Module._free(encodeOutBuffer.byteOffset);
this.Encoder_Interface_exit(encoder);
return out.subarray(0, outOffset)
}),
/**
* Decode RTP AMR file to the PCM data with sample rate 8000.
* @param {Uint8Array} amr The raw amr file data.
* @returns {Float32Array} PCM data if succeeded. Otherwise null.
*/
decodeRtp: function(rtp) {
var raw = this._decodeRtp(rtp);
if (!raw) {
return null;
}
//Oversample as we go
var out = new Float32Array(raw.length * 2);
for (var i = 0; i < out.length; i++) {
out[i * 2] = raw[i] / 0x8000;
out[(i * 2) + 1] = out[i * 2];
}
return out;
},
/**
* Initialise the decoder
*/
decodeInit: function() {
if (!this.decoder) {
this.decoder = this.D_IF_init();
}
return this.decoder;
},
/**
* Exit the decoder
*/
decodeExit: function() {
if (this.decoder) {
this.D_IF_exit(this.decoder);
delete this.decoder;
}
},
/**
* Decode AMR file to raw PCM data with sample rate 16000.
* @param {Uint8Array} amr The raw amr file data.
* @returns {Int16Array} PCM data if succeeded. Otherwise null.
*/
_decode: function(amr) {
// Check file header.
if (String.fromCharCode.apply(null, amr.subarray(0, this.AMR_HEADER.length)) !== this.AMR_HEADER) {
return null;
}
this.decodeInit();
if (!this.decoder) {
return null;
}
var out = new Int16Array(Math.floor(amr.length / 6 * this.PCM_BUFFER_COUNT));
var buf = AMRWB._malloc(this.AMR_BUFFER_COUNT);
var decodeInBuffer = new Uint8Array(AMRWB._HEAPU8.buffer, buf, this.AMR_BUFFER_COUNT);
buf = AMRWB._malloc(this.PCM_BUFFER_COUNT * 2);
var decodeOutBuffer = new Int16Array(AMRWB._HEAPU8.buffer, buf, this.PCM_BUFFER_COUNT);
var inOffset = this.AMR_HEADER.length;
var outOffset = 0;
while (inOffset + 1 < amr.length && outOffset + 1 < out.length) {
// Find the package size
var size = this.SIZES[(amr[inOffset] >> 3) & 0x0F];
if (inOffset + size + 1 > amr.length) {
break;
}
decodeInBuffer.set(amr.subarray(inOffset, inOffset + size + 1));
this.D_IF_decode(this.decoder, decodeInBuffer.byteOffset, decodeOutBuffer.byteOffset, 0);
if (outOffset + this.PCM_BUFFER_COUNT > out.length) {
var newOut = new Int16Array(out.length * 2);
newOut.set(out.subarray(0, outOffset));
out = newOut;
}
out.set(decodeOutBuffer, outOffset);
outOffset += this.PCM_BUFFER_COUNT;
inOffset += size + 1;
}
AMRWB._free(decodeInBuffer.byteOffset);
AMRWB._free(decodeOutBuffer.byteOffset);
return out.subarray(0, outOffset);
},
/**
* Decode RTP packet to raw PCM data with sample rate 16000.
* @param {Uint8Array} rtp The RTP encapsulated amr file data.
* @returns {Int16Array} PCM data if succeeded. Otherwise null.
*/
_decodeRtp: (function(rtp) {
var tocPtr = this.RTP_HEADER_SIZE + 1;
var payloadLengthCheck = 0;
var payLoadptr;
for (payLoadptr = this.RTP_HEADER_SIZE + 1;
((rtp[payLoadptr] & 0x80) == 0x80) && (payLoadptr < rtp.length);
payLoadptr++) {
//Calculate AMR frame size to check packet matches calculated length from TOC
payloadLengthCheck += this._rtpFrameSize(rtp[payLoadptr]) + 1; //The +1 is for the byte in the TOC
}
//Add header and TOC size to AMR data size to yield calculated packet size and advance payload pointer past final TOC entry
payloadLengthCheck += this._rtpFrameSize(rtp[payLoadptr]) + this.RTP_HEADER_SIZE + 2;
payLoadptr++;
if (payloadLengthCheck != rtp.length) {
console.log("RTP calculated vs actual length error: Calc " + payloadLengthCheck + ", actual: " + rtp.length);
return null;
}
if (!this.decoder) {
return null;
}
var out = new Int16Array(Math.floor(rtp.length / 6 * this.PCM_BUFFER_COUNT));
var buf = AMRWB._malloc(this.AMR_BUFFER_COUNT);
var decodeInBuffer = new Uint8Array(AMRWB._HEAPU8.buffer, buf, this.AMR_BUFFER_COUNT);
buf = AMRWB._malloc(this.PCM_BUFFER_COUNT * 2);
var decodeOutBuffer = new Int16Array(AMRWB._HEAPU8.buffer, buf, this.PCM_BUFFER_COUNT);
var outPcmPtr = 0;
while ((((tocPtr == this.RTP_HEADER_SIZE + 1) && (rtp[tocPtr - 1] == this.RTP_TOC_HEADER)) || ((rtp[tocPtr - 1] & 0x80) == 0x80)) && (payLoadptr < rtp.length)) {
var frameSize = this._rtpFrameSize(rtp[tocPtr]);
if (payLoadptr + frameSize > rtp.length) {
break;
}
decodeInBuffer.set([rtp[tocPtr] & 0x7F]); // Start code
decodeInBuffer.set(rtp.subarray(payLoadptr, payLoadptr + frameSize), 1);
this.D_IF_decode(this.decoder, decodeInBuffer.byteOffset, decodeOutBuffer.byteOffset, 0);
if (outPcmPtr + this.PCM_BUFFER_COUNT > out.length) {
var newOut = new Int16Array(out.length * 2);
newOut.set(out.subarray(0, outPcmPtr));
out = newOut;
}
out.set(decodeOutBuffer, outPcmPtr);
outPcmPtr += this.PCM_BUFFER_COUNT;
payLoadptr += frameSize;
}
AMRWB._free(decodeInBuffer.byteOffset);
AMRWB._free(decodeOutBuffer.byteOffset);
return out.subarray(0, outPcmPtr);
}),
_rtpFrameSize: (function(key) {
var frameSizeIndex = (key >> 3) & 0x0F;
var frameSize = this.SIZES[frameSizeIndex];
return frameSize;
}),
// Decoder_Interface_init: (function () {
// console.warn("Decoder_Interface_init not initialized.");
// return 0
// }),
// Decoder_Interface_exit: (function (state) {
// console.warn("Decoder_Interface_exit not initialized.")
// }),
// Decoder_Interface_Decode: (function (state, inBuffer, outBuffer, bfi) {
// console.warn("Decoder_Interface_Decode not initialized.")
// }),
// Encoder_Interface_init: (function (dtx) {
// console.warn("Encoder_Interface_init not initialized.");
// return 0
// }),
// Encoder_Interface_exit: (function (state) {
// console.warn("Encoder_Interface_exit not initialized.")
// }),
// Encoder_Interface_Encode: (function (state, mode, speech, out, forceSpeech) {
// console.warn("Encoder_Interface_Encode not initialized.")
// }),
// Decoding modes and its frame sizes (bytes), respectively
Mode: {MR475: 0, MR515: 1, MR59: 2, MR67: 3, MR74: 4, MR795: 5, MR102: 6, MR122: 7, MRDTX: 8},
SIZES: [17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, -1, 0],
AMR_BUFFER_COUNT: 61,
PCM_BUFFER_COUNT: 320,
AMR_HEADER: "#!AMR-WB\n",
WAV_HEADER_SIZE: 44,
RTP_HEADER_SIZE: 12,
RTP_PAYLOAD_ID: 97,
RTP_TOC_HEADER: 0xF0
};
var Module = {
canvas: {},
print: (function(text) {
console.log(text)
}),
// AMRWB.Encoder_Interface_init = Module._Encoder_Interface_init;
// AMRWB.Encoder_Interface_exit = Module._Encoder_Interface_exit;
// AMRWB.Encoder_Interface_Encode = Module._Encoder_Interface_Encode;
onRuntimeInitialized: (function() {
AMRWB.D_IF_init = Module._D_IF_init;
AMRWB.D_IF_exit = Module._D_IF_exit;
AMRWB.D_IF_decode = Module._D_IF_decode;
AMRWB._free = Module._free;
AMRWB._HEAPU8 = Module.HEAPU8;
AMRWB._malloc = Module._malloc;
return 0
})
};
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;
ret = tryParseAsDataURI(filename);
if (!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) {
Module["printErr"]("node.js exiting due to unhandled promise rejection");
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) {
var data = tryParseAsDataURI(f);
if (data) {
return intArrayToString(data)
}
return read(f)
}
}
Module["readBinary"] = function readBinary(f) {
var data;
data = tryParseAsDataURI(f);
if (data) {
return 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) {
try {
var xhr = new XMLHttpRequest;
xhr.open("GET", url, false);
xhr.send(null);
return xhr.responseText
} catch (err) {
var data = tryParseAsDataURI(url);
if (data) {
return intArrayToString(data)
}
throw err
}
};
if (ENVIRONMENT_IS_WORKER) {
Module["readBinary"] = function readBinary(url) {
try {
var xhr = new XMLHttpRequest;
xhr.open("GET", url, false);
xhr.responseType = "arraybuffer";
xhr.send(null);
return new Uint8Array(xhr.response)
} catch (err) {
var data = tryParseAsDataURI(url);
if (data) {
return data
}
throw err
}
}
}
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
}
var data = tryParseAsDataURI(url);
if (data) {
onload(data.buffer);
return
}
onerror()
};
xhr.onerror = onerror;
xhr.send(null)
};
if (typeof arguments != "undefined") {
Module["arguments"] = arguments
}
Module["setWindowTitle"] = (function(title) {
document.title = title
})
} else {
throw new Error("unknown runtime environment")
}
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;
stackSave = stackRestore = stackAlloc = setTempRet0 = getTempRet0 = (function() {
abort("cannot use the stack before compiled code is ready to run, and has provided stack access")
});
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) {
assert(args.length == sig.length - 1);
assert("dynCall_" + sig in Module, "bad function pointer type - no table for sig '" + sig + "'");
return Module["dynCall_" + sig].apply(null, [ptr].concat(args))
} else {
assert(sig.length == 1);
assert("dynCall_" + sig in Module, "bad function pointer type - no table for sig '" + sig + "'");
return Module["dynCall_" + sig].call(null, ptr)
}
}
var GLOBAL_BASE = 8;
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;
assert(returnType !== "array", 'Return type should not be "array".');
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);
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) {
assert(ptr + i < TOTAL_MEMORY);
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) {
assert(typeof maxBytesToWrite == "number", "stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");
return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite)
}
function 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 demangle(func) {
warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");
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()
}
function stackTrace() {
var js = jsStackTrace();
if (Module["extraStackTrace"]) js += "\n" + Module["extraStackTrace"]();
return demangleAll(js)
}
var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
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 writeStackCookie() {
assert((STACK_MAX & 3) == 0);
HEAPU32[(STACK_MAX >> 2) - 1] = 34821223;
HEAPU32[(STACK_MAX >> 2) - 2] = 2310721022
}
function checkStackCookie() {
if (HEAPU32[(STACK_MAX >> 2) - 1] != 34821223 || HEAPU32[(STACK_MAX >> 2) - 2] != 2310721022) {
abort("Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x02135467, but received 0x" + HEAPU32[(STACK_MAX >> 2) - 2].toString(16) + " " + HEAPU32[(STACK_MAX >> 2) - 1].toString(16))
}
if (HEAP32[0] !== 1668509029) throw "Runtime error: The application has corrupted its heap memory area (address zero)!"
}
function abortStackOverflow(allocSize) {
abort("Stack overflow! Attempted to allocate " + allocSize + " bytes on the stack, but stack has only " + (STACK_MAX - stackSave() + allocSize) + " bytes available!")
}
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 but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) 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"] || 65536;
var TOTAL_MEMORY = Module["TOTAL_MEMORY"] || 16777216;
if (TOTAL_MEMORY < TOTAL_STACK) Module.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was " + TOTAL_MEMORY + "! (TOTAL_STACK=" + TOTAL_STACK + ")");
assert(typeof Int32Array !== "undefined" && typeof Float64Array !== "undefined" && Int32Array.prototype.subarray !== undefined && Int32Array.prototype.set !== undefined, "JS engine does not provide full typed array support");
if (Module["buffer"]) {
buffer = Module["buffer"];
assert(buffer.byteLength === TOTAL_MEMORY, "provided buffer should be " + TOTAL_MEMORY + " bytes, but it is " + buffer.byteLength)
} else {
{
buffer = new ArrayBuffer(TOTAL_MEMORY)
}
assert(buffer.byteLength === 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() {
checkStackCookie();
if (runtimeInitialized) return;
runtimeInitialized = true;
callRuntimeCallbacks(__ATINIT__)
}
function preMain() {
checkStackCookie();
callRuntimeCallbacks(__ATMAIN__)
}
function exitRuntime() {
checkStackCookie();
callRuntimeCallbacks(__ATEXIT__);
runtimeExited = true
}
function postRun() {
checkStackCookie();
if (Module["postRun"]) {
if (typeof Module["postRun"] == "function") Module["postRun"] = [Module["postRun"]];
while (Module["postRun"].length) {
addOnPostRun(Module["postRun"].shift())
}
}
callRuntimeCallbacks(__ATPOSTRUN__)
}
function addOnPreRun(cb) {
__ATPRERUN__.unshift(cb)
}
function addOnPostRun(cb) {
__ATPOSTRUN__.unshift(cb)
}
function writeArrayToMemory(array, buffer) {
assert(array.length >= 0, "writeArrayToMemory array must have a length (should be an array or typed array)");
HEAP8.set(array, buffer)
}
function writeAsciiToMemory(str, buffer, dontAddNull) {
for (var i = 0; i < str.length; ++i) {
assert(str.charCodeAt(i) === str.charCodeAt(i) & 255);
HEAP8[buffer++ >> 0] = str.charCodeAt(i)
}
if (!dontAddNull) HEAP8[buffer >> 0] = 0
}
assert(Math["imul"] && Math["fround"] && Math["clz32"] && Math["trunc"], "this is a legacy browser, build with LEGACY_VM_SUPPORT");
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;
var runDependencyTracking = {};
function addRunDependency(id) {
runDependencies++;
if (Module["monitorRunDependencies"]) {
Module["monitorRunDependencies"](runDependencies)
}
if (id) {
assert(!runDependencyTracking[id]);
runDependencyTracking[id] = 1;
if (runDependencyWatcher === null && typeof setInterval !== "undefined") {
runDependencyWatcher = setInterval((function() {
if (ABORT) {
clearInterval(runDependencyWatcher);
runDependencyWatcher = null;
return
}
var shown = false;
for (var dep in runDependencyTracking) {
if (!shown) {
shown = true;
Module.printErr("still waiting on run dependencies:")
}
Module.printErr("dependency: " + dep)
}
if (shown) {
Module.printErr("(end of list)")
}
}), 1e4)
}
} else {
Module.printErr("warning: run dependency added without ID")
}
}
function removeRunDependency(id) {
runDependencies--;
if (Module["monitorRunDependencies"]) {
Module["monitorRunDependencies"](runDependencies)
}
if (id) {
assert(runDependencyTracking[id]);
delete runDependencyTracking[id]
} else {
Module.printErr("warning: run dependency removed without ID")
}
if (runDependencies == 0) {
if (runDependencyWatcher !== null) {
clearInterval(runDependencyWatcher);
runDependencyWatcher = null
}
if (dependenciesFulfilled) {
var callback = dependenciesFulfilled;
dependenciesFulfilled = null;
callback()
}
}
}
Module["preloadedImages"] = {};
Module["preloadedAudios"] = {};
var memoryInitializer = null;
var FS = {
error: (function() {
abort("Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -s FORCE_FILESYSTEM=1")
}),
init: (function() {
FS.error()
}),
createDataFile: (function() {
FS.error()
}),
createPreloadedFile: (function() {
FS.error()
}),
createLazyFile: (function() {
FS.error()
}),
open: (function() {
FS.error()
}),
mkdev: (function() {
FS.error()
}),
registerDevice: (function() {
FS.error()
}),
analyzePath: (function() {
FS.error()
}),
loadFilesFromDB: (function() {
FS.error()
}),
ErrnoError: function ErrnoError() {
FS.error()
}
};
Module["FS_createDataFile"] = FS.createDataFile;
Module["FS_createPreloadedFile"] = FS.createPreloadedFile;
var dataURIPrefix = "data:application/octet-stream;base64,";
function isDataURI(filename) {
return String.prototype.startsWith ? filename.startsWith(dataURIPrefix) : filename.indexOf(dataURIPrefix) === 0
}
STATIC_BASE = GLOBAL_BASE;
STATICTOP = STATIC_BASE + 25648;
__ATINIT__.push();
memoryInitializer = "data:application/octet-stream;base64,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ywBiAJQAyQD7AF8AkQDGAPgANAACAAEAZQDMAJsAEwAVAAwAEQASABQAEAAZAA0ACgAOABgAFwAWABoACAAPADUAnAAfAGYAzQAJACEACwBnAM4ANgCdABwAGwBoAM8AIgAjAB0ALgAgAB4ANwCeACUAJAAnACYAKABpANAAKQAqACsALAAtADgAagCfANEAOQBCAEsAVABrAHQAfQCGAKAAqQCyALsA0gDbAOQA7QA6AGwAoQDTAD4AcAClANcAQwB1AKoA3ABHAHkArgDgAEwAfgCzAOUAUACCALcA6QBVAIcAvADuAFkAiwDAAPIAOwBtAKIA1AA/AHEApgDYAEQAdgCrAN0ASAB6AK8A4QBNAH8AtADmAFEAgwC4AOoAVgCIAL0A7wBaAIwAwQDzADwAbgCjANUAQAByAKcA2QBFAHcArADeAEkAewCwAOIATgCAALUA5wBSAIQAuQDrAFcAiQC+APAAWwCNAMIA9AA9AG8ApADWAEEAcwCoANoARgB4AK0A3wBKAHwAsQDjAE8AgQC2AOgAUwCFALoA7ABYAIoAvwDxAFwAjgDDAPUAAAAEAAYAZQCfANwAFgEHAAUAAwAvADAAMQAyADMApgCnAKgAqQCqAGYAoADdABcBawClAOIAHAFoAKIA3wAZAWkAowDgABoBbADjAGoApADhABsBZwChAN4AGAE0AAIAAQBtAOQAqwATABUADAARABIAFAAQABkADQAKAA4AGAAXABYAGgAIAA8ANQCsAB8AbgDlAAkAIQALAG8A5gA2AK0AHAAbAHAA5wAiACMAHQAuACAAHgA3AK4AJQAkACcAJgAoAHEA6AApACoAKwAsAC0AOAByAK8A6QA+AHgAtQDvAEsAhQDCAPwAOQBzALAA6gA/AHkAtgDwAEYAgAC9APcATACGAMMA/QBTAI0AygAEAVwAlgDTAA0BVACOAMsABQFdAJcA1AAOAVUAjwDMAAYBXgCYANUADwFWAJAAzQAHAV8AmQDWABABQAB6ALcA8QBNAIcAxAD+AEEAewC4APIATgCIAMUA/wBXAJEAzgAIAWAAmgDXABEBOgB0ALEA6wBCAHwAuQDzAEcAgQC+APgATwCJAMYAAAFYAJIAzwAJAWEAmwDYABIBOwB1ALIA7ABDAH0AugD0AEgAggC/APkAUACKAMcAAQFZAJMA0AAKAWIAnADZABMBPAB2ALMA7QBEAH4AuwD1AEkAgwDAAPoAUQCLAMgAAgFaAJQA0QALAWMAnQDaABQBPQB3ALQA7gBFAH8AvAD2AEoAhADBAPsAUgCMAMkAAwFbAJUA0gAMAWQAngDbABUBAAAEAAYAbQCvAPQANgEHAAUAAwAvADAAMQAyADMAtgC3ALgAuQC6AG4AsAD1ADcBcwC1APoAPAFwALIA9wA5AXEAswD4ADoBdAD7AHIAtAD5ADsBbwCxAPYAOAE0AAIAAQB1APwAuwATABUADAARABIAFAAQABkADQAKAA4AGAAXABYAGgAIAA8ANQC8AB8AdgD9AAkAIQALAHcA/gA2AL0AHAAbAHgA/wAiACMAHQAuACAAHgA3AL4AJQAkACcAJgAoAHkAAAEpACoAKwAsAC0AOAB6AL8AAQE/AIEAxgAIAUwAjgDTABUBWQCbAOAAIgFmAKgA7QAvATkAewDAAAIBRgCIAM0ADwFTAJUA2gAcAWAAogDnACkBPgCAAMUABwFLAI0A0gAUAVgAmgDfACEBZQCnAOwALgE6AHwAwQADAUcAiQDOABABVACWANsAHQFhAKMA6AAqATsAfQDCAAQBQACCAMcACQFDAIUAygAMAUgAigDPABEBTQCPANQAFgFQAJIA1wAZAVUAlwDcAB4BWgCcAOEAIwFdAJ8A5AAmAWIApADpACsBZwCpAO4AMAFqAKwA8QAzATwAfgDDAAUBQQCDAMgACgFEAIYAywANAUkAiwDQABIBTgCQANUAFwFRAJMA2AAaAVYAmADdAB8BWwCdAOIAJAFeAKAA5QAnAWMApQDqACwBaACqAO8AMQFrAK0A8gA0AT0AfwDEAAYBQgCEAMkACwFFAIcAzAAOAUoAjADRABMBTwCRANYAGAFSAJQA2QAbAVcAmQDeACABXACeAOMAJQFfAKEA5gAoAWQApgDrAC0BaQCrAPAAMgFsAK4A8wA1AQAABAAGAHkAxwAYAWYBBwAFAAMALwAwADEAMgAzAM4AzwDQANEA0gB6AMgAGQFnAX8AzQAeAWwBfADKABsBaQF9AMsAHAFqAYAAHwF+AMwAHQFrAXsAyQAaAWgBNAACAAEAgQAgAdMAEwAVAAwAEQASABQAEAAZAA0ACgAOABgAFwAWABoACAAPADUA1AAfAIIAIQEJACEACwCDACIBNgDVABwAGwCEACMBIgAjAB0ALgAgAB4ANwDWACUAJAAnACYAKACFACQBKQAqACsALAAtADgAhgDXACUBxgArAYgAeACKADwAFwE6AD4AZQGLAIwAJwGcADkA2wApAT8A2QCJAKoALAHeAEAAagA9AE4AJgFcAI4AjQCHAN0AKAEtAVcBOwAqAbgASQE7AdwA2AAJAfsA2gDtAGAB3wCdAFYAqwBXAKQAXwFvAC4BQQCyAHMAQwFIAMAAZQCzAF0ASQDBAJcAUQE1AY8AEgFFAEQBpQCWAGEAUgFuADYBSgERAUQAawCvAPUAcgBPAHEAvQD2AAMBrgBHALkAYABYAWQAQgFTAE4BPAFNAfwAoQBcAZMAUgANAegABAE0AWEBWwGjAOcAMgFAAbwADgGSALEACgFeAQABVQCVAHQAvwCgAO4AAgFQATEB/wBYAOAAYwBTAeYA5ADjABAB8gDxAD8B6QA3AWYASgC0ABMBQgDCAJgARQGsAPcA9AAFAXUAngCmAGIBSwCQAGwAOAFeALoALwFQAOoAWQDDAHAAVAG1AFkBPQFGARQB7wCnAHYAOQFGAGMBRwH9AL4AsAAPAWgAYgCZAGcAWgBMAAsBFQH4AOEABgG2AFQAmgDrAE8BqABLAcQAVQH5AKIAMwGUAF0BBwFBAQEB8wDlAGQBnwB3AEMAuwCtAJEA8ABNADABTAE6AVYBbQD+AFEAFgFpAFsAWgE+AbcA+gDFAEgBXwCbAKkADAHiAOwACAEAAAQABgCBANcAMAGGAQcABQADAC8AMAAxADIAMwDeAN8A4ADhAOIAggDYADEBhwGHAN0ANgGMAYQA2gAzAYkBhQDbADQBigGIADcBhgDcADUBiwGDANkAMgGIATQAAgABAIkAOAHjABMAFQAMABEAEgAUABAAGQANAAoADgAYABcAFgAaAAgADwA1AOQAHwCKADkBCQAhAAsAiwA6ATYA5QAcABsAjAA7ASIAIwAdAC4AIAAeADcA5gAlACQAJwAmACgAjQA8ASkAKgArACwALQA4AI4A5wA9AT8ASQBcAFQBUgBEAZUAYQGfAE4BpQBSAbIAowD+AE0AqAABAZkAVwE5APgA7gBPAPwApgBDAFAAyQBlAAsBjwCkAFUB/wBTAbsAeAE+AU4ASAFqAXMA6ADyAP0AIgEUAT4AOgCeAEQAXQCzAD8BlACpAJoASACBAUkBTQFYAWYAUwCQAOkAQwF8APMAwABiAe0AQAD3AMoA0QCWAHQATwEMAe8AKwG8AMQAKgFeAMMAAgF7AGsBgAFtAEUBcwGqAHIBVABuACcBtABKANIAvwBqACMBzQBvAX0BeQHOAGMBegB3AHgAfwGgAGkAbAAVAXwBJgEcAR0BWQHQAA0B+QBuAYIBLAEpAQMBfQBxAcUAYQDCAB4B0wAZARgBtwB0AVcAmwAbATsAXAFHAbgATABvAEoBywBdAUUAYgCYAJEAvQBCAEABUQGtAGYB+wDGAK4ABwEGAX4A8QDBAFgAhAF1AF8AgwFwAGcBHwH0AGcAEAEtAasAogDqABEBfwB1AbUAJAFVAHoBLgF5AGsAbAFaAWQB1AAWAdUAQQB+ASABzwBxAK8AYwAoAXYBcAHHAAQBuQBQAUsBoQAOAQgB+gDwAEsAXgGXADwAWQBBAZwAEgFoAUYBRgAaAacAkgBgAVEAWwCFAQoB9QCxAOsAvgAAAcwAVgGAAHYALwFoAHsBtgByAHcByABgACUBrADWAG0BFwFWACEBXwFbAWUBBQG6ALAADwFaAGQAkwBCARMBaQFHAEwBPQAJAZ0A9gDsAAAABAAGAJEA9wBgAcYBBwAFAAMALwAwADEAMgAzAP4A/wAAAQEBAgGSAPgAYQHHAZcA/QBmAcwBlAD6AGMByQGVAPsAZAHKAZgAZwGWAPwAZQHLAZMA+QBiAcgBNAACAAEAmQBoAQMBEwAVAAwAEQASABQAEAAZAA0ACgAOABgAFwAWABoACAAPADUABAEfAJoAaQEJACEACwCbAGoBNgAFARwAGwCcAGsBIgAjAB0ALgAgAB4ANwAGASUAJAAnACYAKACdAGwBKQAqACsALAAtADgAngAHAW0BtQDAAKoATwA5AI8BWgCfACkBeQFuARMBRAC3AIQBHgHCACsBXABGALYAkQGsADsAWwA6AJABcAGhAFEAoAAIAasAUACFAYYBegF7AcEAKgFFAAoBCQFvARUBIAEUAR8BuAA8AMMAUgBdAEcAcQGSAa0AogC8ASwBhwFiAEwAFgE9AAsBdgGHAJsBpwBmAHwByABXALIAQQBeAMwAfABIAFYBvQAxAX0BjAGxAS0B4gCXASEB7QBxANcAuQCAADUBkwF0AEABxABLAXIBpgGuAEAAiAFTAKkB2wCGALwAsAFwAKsBiwAXAaMAtAHQAL8B2gDsAOUAYQAmAYEB5gCmAAwBsQC7AeEAqgFlABABigB/ACIBdQBbAccAngFfAIwA8ACaAYsB0QCBABsBWgFpAPEAtQFWADQBwAHLAFkBugBrANwAnwFOAT8BagA5AXYAewBJAM8ApQHWAIABdQG2AT4AcwFVAUsAwQGoAEMBpADyAKABRAEwAcUATwGUAQ8BPwC/AEUBYACpAOcAGAE4AbsAlgFUAMkAZABDAH4BrwBQAcoASgENAYkBeAF/ASUBMwGZAbMAHQE6AS4BdAGOAb4AtABZAGMAZwDoAE4AWABNAIgAgwGlAMYAigF9ALAArAFKAHcB7gDjAEIAEQEaAY0AMgGcAXIAVQCCAFwBdwAjASgBggHpAI0BLwGVARwBvQGnAd0A0gDNAMIBbAASAbIB2ABXAVEBjgDzAEEBmAHDATYBJAF4AG0AGQG3AQ4BrQFMAScBogHTADsB3gBGAYMArgH0AEcBXQGhATwBjwBSAbgB6gBuANQAxAH1AHkAowFeAd8AhAC5AUgBnQE9AVMBfgBoAIkAvgFYAe8AswFzAE0BzgBCAdkA5ACoAcUBNwFfAW8AugHgANUAegCvAVQB6wD2AIUAkACkAUkBPgEAAAQABgCRAPsAaAHSAQcABQADAC8AMAAxADIAMwAGAQcBCAEJAQoBkgD8AGkB0wGXAAEBbgHYAZQA/gBrAdUBlQD/AGwB1gGcAHMBlgAAAW0B1wGTAP0AagHUATQAAgABAJ0AdAELARMAFQAMABEAEgAUABAAGQANAAoADgAYABcAFgAaAAgADwA1AAwBHwCYAJkAmgCbAAIBAwEEAQUBbwFwAXEBcgHZAdoB2wHcAZ4AdQEJACEACwCfAHYBNgANARwAGwCgAHcBIgAjAB0ALgAgAB4ANwAOASUAJAAnACYAKAChAHgBKQAqACsALAAtADgAogAPAXkBuQDEAK4ATwA5AJsBWgCjADEBhQF6ARsBRAC7AJABJgHGADMBXABGALoAnQGwADsAWwA6AJwBfAGlAFEApAAQAa8AUACRAZIBhgGHAcUAMgFFABIBEQF7AR0BKAEcAScBvAA8AMcAUgBdAEcAfQGeAbEApgDIATQBkwFiAEwAHgE9ABMBggGHAKcBqwBmAIgBzABXALYAQQBeANAAfABIAF4BwQA5AYkB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