UNPKG

@loaders.gl/potree

Version:

potree loaders for large point clouds.

1,083 lines (1,066 loc) 633 kB
(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if (typeof define === 'function' && define.amd) define([], factory); else if (typeof exports === 'object') exports['loaders'] = factory(); else root['loaders'] = factory();})(globalThis, function () { "use strict"; var __exports__ = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // external-global-plugin:@loaders.gl/core var require_core = __commonJS({ "external-global-plugin:@loaders.gl/core"(exports, module2) { module2.exports = globalThis.loaders; } }); // (disabled):../../node_modules/path/path.js var require_path = __commonJS({ "(disabled):../../node_modules/path/path.js"() { } }); // (disabled):fs var require_fs = __commonJS({ "(disabled):fs"() { } }); // bundle.ts var bundle_exports = {}; __export(bundle_exports, { PotreeBinLoader: () => PotreeBinLoader, PotreeHierarchyChunkLoader: () => PotreeHierarchyChunkLoader, PotreeLoader: () => PotreeLoader, PotreeSource: () => PotreeSource }); __reExport(bundle_exports, __toESM(require_core(), 1)); // src/potree-loader.ts var VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest"; var PotreeLoader = { dataType: null, batchType: null, name: "potree metadata", id: "potree", module: "potree", version: VERSION, extensions: ["js"], mimeTypes: ["application/json"], testText: (text) => text.indexOf("octreeDir") >= 0, parse: (data) => JSON.parse(new TextDecoder().decode(data)), parseTextSync: (text) => JSON.parse(text), options: { potree: {} } }; // src/parsers/parse-potree-hierarchy-chunk.ts function parsePotreeHierarchyChunk(arrayBuffer) { const tileHeaders = parseBinaryChunk(arrayBuffer); return buildHierarchy(tileHeaders); } function parseBinaryChunk(arrayBuffer, byteOffset = 0) { const dataView = new DataView(arrayBuffer); const stack = []; const topTileHeader = {}; byteOffset = decodeRow(dataView, byteOffset, topTileHeader); stack.push(topTileHeader); const tileHeaders = [topTileHeader]; while (stack.length > 0) { const snode = stack.shift(); let mask = 1; for (let i = 0; i < 8; i++) { if (snode && (snode.header.childMask & mask) !== 0) { const tileHeader = {}; byteOffset = decodeRow(dataView, byteOffset, tileHeader); tileHeader.name = snode.name + i; stack.push(tileHeader); tileHeaders.push(tileHeader); snode.header.childCount++; } mask = mask * 2; } if (byteOffset === dataView.byteLength) { break; } } return tileHeaders; } function decodeRow(dataView, byteOffset, tileHeader) { tileHeader.header = tileHeader.header || {}; tileHeader.header.childMask = dataView.getUint8(byteOffset); tileHeader.header.childCount = 0; tileHeader.pointCount = dataView.getUint32(byteOffset + 1, true); tileHeader.name = ""; byteOffset += 5; return byteOffset; } function buildHierarchy(flatNodes, options = {}) { const DEFAULT_OPTIONS = { spacing: 100 }; options = { ...DEFAULT_OPTIONS, ...options }; const topNode = flatNodes[0]; const nodes = {}; for (const node of flatNodes) { const { name } = node; const index = parseInt(name.charAt(name.length - 1), 10); const parentName = name.substring(0, name.length - 1); const parentNode = nodes[parentName]; const level = name.length - 1; node.level = level; node.hasChildren = Boolean(node.header.childCount); node.children = []; node.childrenByIndex = new Array(8).fill(null); node.spacing = (options?.spacing || 0) / Math.pow(2, level); if (parentNode) { parentNode.children.push(node); parentNode.childrenByIndex[index] = node; } nodes[name] = node; } return topNode; } // src/potree-hierarchy-chunk-loader.ts var VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest"; var PotreeHierarchyChunkLoader = { dataType: null, batchType: null, name: "potree Hierarchy Chunk", id: "potree-hrc", module: "potree", version: VERSION2, extensions: ["hrc"], mimeTypes: ["application/octet-stream"], // binary potree files have no header bytes, no content test function possible // test: ['...'], parse: async (arrayBuffer, options) => parsePotreeHierarchyChunk(arrayBuffer), parseSync: (arrayBuffer, options) => parsePotreeHierarchyChunk(arrayBuffer), options: { potree: {} }, binary: true }; // src/parsers/parse-potree-bin.ts function parsePotreeBin(arrayBuffer, byteOffset, options, index) { return null; } // src/potree-bin-loader.ts var PotreeBinLoader = { dataType: null, batchType: null, name: "potree Binary Point Attributes", id: "potree", extensions: ["bin"], mimeTypes: ["application/octet-stream"], // Unfortunately binary potree files have no header bytes, no test possible // test: ['...'], parseSync, binary: true, options: {} // @ts-ignore }; function parseSync(arrayBuffer, options) { const index = {}; const byteOffset = 0; parsePotreeBin(arrayBuffer, byteOffset, options, index); return index; } // src/lib/potree-node-source.ts var import_core = __toESM(require_core(), 1); // ../loader-utils/src/lib/path-utils/file-aliases.ts var pathPrefix = ""; var fileAliases = {}; function resolvePath(filename) { for (const alias in fileAliases) { if (filename.startsWith(alias)) { const replacement = fileAliases[alias]; filename = filename.replace(alias, replacement); } } if (!filename.startsWith("http://") && !filename.startsWith("https://")) { filename = `${pathPrefix}${filename}`; } return filename; } // ../loader-utils/src/lib/sources/data-source.ts var DataSource = class { /** A resolved fetch function extracted from loadOptions prop */ fetch; /** The actual load options, if calling a loaders.gl loader */ loadOptions; _needsRefresh = true; props; constructor(props) { this.props = { ...props }; this.loadOptions = { ...props.loadOptions }; this.fetch = getFetchFunction(this.loadOptions); } setProps(props) { this.props = Object.assign(this.props, props); this.setNeedsRefresh(); } /** Mark this data source as needing a refresh (redraw) */ setNeedsRefresh() { this._needsRefresh = true; } /** * Does this data source need refreshing? * @note The specifics of the refresh mechanism depends on type of data source */ getNeedsRefresh(clear = true) { const needsRefresh = this._needsRefresh; if (clear) { this._needsRefresh = false; } return needsRefresh; } }; function getFetchFunction(options) { const fetchFunction = options?.fetch; if (fetchFunction && typeof fetchFunction === "function") { return (url, fetchOptions2) => fetchFunction(url, fetchOptions2); } const fetchOptions = options?.fetch; if (fetchOptions && typeof fetchOptions !== "function") { return (url) => fetch(url, fetchOptions); } return (url) => fetch(url); } // ../las/src/las-loader.ts var VERSION3 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest"; var LASLoader = { dataType: null, batchType: null, name: "LAS", id: "las", module: "las", version: VERSION3, worker: true, extensions: ["las", "laz"], // LAZ is the "compressed" flavor of LAS, mimeTypes: ["application/octet-stream"], // TODO - text version? text: true, binary: true, tests: ["LAS"], options: { las: { shape: "mesh", fp64: false, skip: 1, colorDepth: 8 } } }; // ../schema/src/lib/table/simple-table/data-type.ts function getDataTypeFromTypedArray(array) { switch (array.constructor) { case Int8Array: return "int8"; case Uint8Array: case Uint8ClampedArray: return "uint8"; case Int16Array: return "int16"; case Uint16Array: return "uint16"; case Int32Array: return "int32"; case Uint32Array: return "uint32"; case Float32Array: return "float32"; case Float64Array: return "float64"; default: return "null"; } } // ../schema/src/lib/mesh/mesh-utils.ts function getMeshBoundingBox(attributes) { let minX = Infinity; let minY = Infinity; let minZ = Infinity; let maxX = -Infinity; let maxY = -Infinity; let maxZ = -Infinity; const positions = attributes.POSITION ? attributes.POSITION.value : []; const len = positions && positions.length; for (let i = 0; i < len; i += 3) { const x = positions[i]; const y = positions[i + 1]; const z = positions[i + 2]; minX = x < minX ? x : minX; minY = y < minY ? y : minY; minZ = z < minZ ? z : minZ; maxX = x > maxX ? x : maxX; maxY = y > maxY ? y : maxY; maxZ = z > maxZ ? z : maxZ; } return [ [minX, minY, minZ], [maxX, maxY, maxZ] ]; } // ../schema/src/lib/mesh/deduce-mesh-schema.ts function deduceMeshSchema(attributes, metadata = {}) { const fields = deduceMeshFields(attributes); return { fields, metadata }; } function deduceMeshField(name, attribute, optionalMetadata) { const type = getDataTypeFromTypedArray(attribute.value); const metadata = optionalMetadata ? optionalMetadata : makeMeshAttributeMetadata(attribute); return { name, type: { type: "fixed-size-list", listSize: attribute.size, children: [{ name: "value", type }] }, nullable: false, metadata }; } function deduceMeshFields(attributes) { const fields = []; for (const attributeName in attributes) { const attribute = attributes[attributeName]; fields.push(deduceMeshField(attributeName, attribute)); } return fields; } function makeMeshAttributeMetadata(attribute) { const result = {}; if ("byteOffset" in attribute) { result.byteOffset = attribute.byteOffset.toString(10); } if ("byteStride" in attribute) { result.byteStride = attribute.byteStride.toString(10); } if ("normalized" in attribute) { result.normalized = attribute.normalized.toString(); } return result; } // ../las/src/lib/libs/laz-perf.ts function getModule() { var Module2 = typeof Module2 !== "undefined" ? Module2 : {}; var moduleOverrides = {}; var key; for (key in Module2) { if (Module2.hasOwnProperty(key)) { moduleOverrides[key] = Module2[key]; } } var arguments_ = []; var thisProgram = "./this.program"; var quit_ = function(status, toThrow) { throw toThrow; }; var ENVIRONMENT_IS_WEB = false; var ENVIRONMENT_IS_WORKER = false; var ENVIRONMENT_IS_NODE = false; var ENVIRONMENT_IS_SHELL = false; ENVIRONMENT_IS_WEB = typeof window === "object"; ENVIRONMENT_IS_WORKER = typeof importScripts === "function"; ENVIRONMENT_IS_NODE = typeof process === "object" && typeof process.versions === "object" && typeof process.versions.node === "string"; ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; var scriptDirectory = ""; function locateFile(path) { if (Module2["locateFile"]) { return Module2["locateFile"](path, scriptDirectory); } return scriptDirectory + path; } var read_, readAsync, readBinary, setWindowTitle; var nodeFS; var nodePath; if (ENVIRONMENT_IS_NODE) { if (ENVIRONMENT_IS_WORKER) { scriptDirectory = require_path().dirname(scriptDirectory) + "/"; } else { const dirname = typeof __dirname !== "undefined" ? __dirname : ""; scriptDirectory = dirname + "/"; } read_ = function shell_read(filename, binary) { var ret = tryParseAsDataURI(filename); if (ret) { return binary ? ret : ret.toString(); } if (!nodeFS) nodeFS = require_fs(); if (!nodePath) nodePath = require_path(); filename = nodePath["normalize"](filename); return nodeFS["readFileSync"](filename, binary ? null : "utf8"); }; readBinary = function readBinary2(filename) { var ret = read_(filename, true); if (!ret.buffer) { ret = new Uint8Array(ret); } assert(ret.buffer); return ret; }; if (process["argv"].length > 1) { thisProgram = process["argv"][1].replace(/\\/g, "/"); } arguments_ = process["argv"].slice(2); if (typeof module !== "undefined") { module["exports"] = Module2; } process["on"]("uncaughtException", function(ex) { if (!(ex instanceof ExitStatus)) { throw ex; } }); process["on"]("unhandledRejection", abort); quit_ = function(status) { process["exit"](status); }; Module2["inspect"] = function() { return "[Emscripten Module object]"; }; } else if (ENVIRONMENT_IS_SHELL) { if (typeof read != "undefined") { read_ = function shell_read(f) { var data2 = tryParseAsDataURI(f); if (data2) { return intArrayToString(data2); } return read(f); }; } readBinary = function readBinary2(f) { var data2; data2 = tryParseAsDataURI(f); if (data2) { return data2; } if (typeof readbuffer === "function") { return new Uint8Array(readbuffer(f)); } data2 = read(f, "binary"); assert(typeof data2 === "object"); return data2; }; if (typeof scriptArgs != "undefined") { arguments_ = scriptArgs; } else if (typeof arguments != "undefined") { arguments_ = arguments; } if (typeof quit === "function") { quit_ = function(status) { quit(status); }; } if (typeof print !== "undefined") { if (typeof console === "undefined") console = {}; console.log = print; console.warn = console.error = typeof printErr !== "undefined" ? printErr : print; } } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { if (ENVIRONMENT_IS_WORKER) { scriptDirectory = self.location.href; } else if (document.currentScript) { scriptDirectory = document.currentScript.src; } if (scriptDirectory.indexOf("blob:") !== 0) { scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf("/") + 1); } else { scriptDirectory = ""; } { read_ = function shell_read(url) { try { var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.send(null); return xhr.responseText; } catch (err2) { var data2 = tryParseAsDataURI(url); if (data2) { return intArrayToString(data2); } throw err2; } }; if (ENVIRONMENT_IS_WORKER) { readBinary = function readBinary2(url) { try { var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.responseType = "arraybuffer"; xhr.send(null); return new Uint8Array(xhr.response); } catch (err2) { var data2 = tryParseAsDataURI(url); if (data2) { return data2; } throw err2; } }; } readAsync = function readAsync2(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 data2 = tryParseAsDataURI(url); if (data2) { onload(data2.buffer); return; } onerror(); }; xhr.onerror = onerror; xhr.send(null); }; } setWindowTitle = function(title) { document.title = title; }; } else { } var out = Module2["print"] || console.log.bind(console); var err = Module2["printErr"] || console.warn.bind(console); for (key in moduleOverrides) { if (moduleOverrides.hasOwnProperty(key)) { Module2[key] = moduleOverrides[key]; } } moduleOverrides = null; if (Module2["arguments"]) arguments_ = Module2["arguments"]; if (Module2["thisProgram"]) thisProgram = Module2["thisProgram"]; if (Module2["quit"]) quit_ = Module2["quit"]; var STACK_ALIGN = 16; function dynamicAlloc(size) { var ret = HEAP32[DYNAMICTOP_PTR >> 2]; var end = ret + size + 15 & -16; HEAP32[DYNAMICTOP_PTR >> 2] = end; return ret; } function 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 = Number(type.substr(1)); assert(bits % 8 === 0, "getNativeTypeSize invalid bits " + bits + ", type " + type); return bits / 8; } else { return 0; } } } } function warnOnce(text) { if (!warnOnce.shown) warnOnce.shown = {}; if (!warnOnce.shown[text]) { warnOnce.shown[text] = 1; err(text); } } var jsCallStartIndex = 1; var functionPointers = new Array(0); var funcWrappers = {}; function dynCall(sig, ptr, args) { if (args && args.length) { return Module2["dynCall_" + sig].apply(null, [ptr].concat(args)); } else { return Module2["dynCall_" + sig].call(null, ptr); } } var tempRet0 = 0; var setTempRet0 = function(value) { tempRet0 = value; }; var getTempRet0 = function() { return tempRet0; }; var GLOBAL_BASE = 8; var wasmBinary; if (Module2["wasmBinary"]) wasmBinary = Module2["wasmBinary"]; var noExitRuntime; if (Module2["noExitRuntime"]) noExitRuntime = Module2["noExitRuntime"]; 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 ABORT = false; var EXITSTATUS = 0; function assert(condition, text) { if (!condition) { abort("Assertion failed: " + text); } } function getCFunc(ident) { var func = Module2["_" + ident]; assert(func, "Cannot call unknown function " + ident + ", make sure it is exported"); return func; } function ccall(ident, returnType, argTypes, args, opts) { var toC = { string: function(str) { var ret2 = 0; if (str !== null && str !== void 0 && str !== 0) { var len = (str.length << 2) + 1; ret2 = stackAlloc(len); stringToUTF8(str, ret2, len); } return ret2; }, array: function(arr) { var ret2 = stackAlloc(arr.length); writeArrayToMemory(arr, ret2); return ret2; } }; function convertReturnValue(ret2) { if (returnType === "string") return UTF8ToString(ret2); if (returnType === "boolean") return Boolean(ret2); return ret2; } var func = getCFunc(ident); var cArgs = []; var stack = 0; if (args) { for (var i = 0; i < args.length; i++) { var converter = toC[argTypes[i]]; if (converter) { if (stack === 0) stack = stackSave(); cArgs[i] = converter(args[i]); } else { cArgs[i] = args[i]; } } } var ret = func.apply(null, cArgs); ret = convertReturnValue(ret); if (stack !== 0) stackRestore(stack); return ret; } var ALLOC_NONE = 3; var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : void 0; function UTF8ArrayToString(heap, idx, maxBytesToRead) { var endIdx = idx + maxBytesToRead; var endPtr = idx; while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { return UTF8Decoder.decode(heap.subarray(idx, endPtr)); } else { var str = ""; while (idx < endPtr) { var u0 = heap[idx++]; if (!(u0 & 128)) { str += String.fromCharCode(u0); continue; } var u1 = heap[idx++] & 63; if ((u0 & 224) == 192) { str += String.fromCharCode((u0 & 31) << 6 | u1); continue; } var u2 = heap[idx++] & 63; if ((u0 & 240) == 224) { u0 = (u0 & 15) << 12 | u1 << 6 | u2; } else { u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[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; } function UTF8ToString(ptr, maxBytesToRead) { return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""; } function stringToUTF8Array(str, heap, 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) { var u1 = str.charCodeAt(++i); u = 65536 + ((u & 1023) << 10) | u1 & 1023; } if (u <= 127) { if (outIdx >= endIdx) break; heap[outIdx++] = u; } else if (u <= 2047) { if (outIdx + 1 >= endIdx) break; heap[outIdx++] = 192 | u >> 6; heap[outIdx++] = 128 | u & 63; } else if (u <= 65535) { if (outIdx + 2 >= endIdx) break; heap[outIdx++] = 224 | u >> 12; heap[outIdx++] = 128 | u >> 6 & 63; heap[outIdx++] = 128 | u & 63; } else { if (outIdx + 3 >= endIdx) break; heap[outIdx++] = 240 | u >> 18; heap[outIdx++] = 128 | u >> 12 & 63; heap[outIdx++] = 128 | u >> 6 & 63; heap[outIdx++] = 128 | u & 63; } } heap[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 len += 4; } return len; } var UTF16Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-16le") : void 0; function UTF16ToString(ptr, maxBytesToRead) { var endPtr = ptr; var idx = endPtr >> 1; var maxIdx = idx + maxBytesToRead / 2; while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; endPtr = idx << 1; if (endPtr - ptr > 32 && UTF16Decoder) { return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); } else { var i = 0; var str = ""; while (1) { var codeUnit = HEAP16[ptr + i * 2 >> 1]; if (codeUnit == 0 || i == maxBytesToRead / 2) return str; ++i; str += String.fromCharCode(codeUnit); } } } function stringToUTF16(str, outPtr, maxBytesToWrite) { if (maxBytesToWrite === void 0) { maxBytesToWrite = 2147483647; } if (maxBytesToWrite < 2) return 0; maxBytesToWrite -= 2; var startPtr = outPtr; var numCharsToWrite = maxBytesToWrite < str.length * 2 ? maxBytesToWrite / 2 : str.length; for (var i = 0; i < numCharsToWrite; ++i) { var codeUnit = str.charCodeAt(i); HEAP16[outPtr >> 1] = codeUnit; outPtr += 2; } HEAP16[outPtr >> 1] = 0; return outPtr - startPtr; } function lengthBytesUTF16(str) { return str.length * 2; } function UTF32ToString(ptr, maxBytesToRead) { var i = 0; var str = ""; while (!(i >= maxBytesToRead / 4)) { var utf32 = HEAP32[ptr + i * 4 >> 2]; if (utf32 == 0) break; ++i; if (utf32 >= 65536) { var ch = utf32 - 65536; str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023); } else { str += String.fromCharCode(utf32); } } return str; } function stringToUTF32(str, outPtr, maxBytesToWrite) { if (maxBytesToWrite === void 0) { maxBytesToWrite = 2147483647; } if (maxBytesToWrite < 4) return 0; var startPtr = outPtr; var endPtr = startPtr + maxBytesToWrite - 4; for (var i = 0; i < str.length; ++i) { var codeUnit = str.charCodeAt(i); if (codeUnit >= 55296 && codeUnit <= 57343) { var trailSurrogate = str.charCodeAt(++i); codeUnit = 65536 + ((codeUnit & 1023) << 10) | trailSurrogate & 1023; } HEAP32[outPtr >> 2] = codeUnit; outPtr += 4; if (outPtr + 4 > endPtr) break; } HEAP32[outPtr >> 2] = 0; return outPtr - startPtr; } function lengthBytesUTF32(str) { var len = 0; for (var i = 0; i < str.length; ++i) { var codeUnit = str.charCodeAt(i); if (codeUnit >= 55296 && codeUnit <= 57343) ++i; len += 4; } return len; } function writeArrayToMemory(array, buffer2) { HEAP8.set(array, buffer2); } function writeAsciiToMemory(str, buffer2, dontAddNull) { for (var i = 0; i < str.length; ++i) { HEAP8[buffer2++ >> 0] = str.charCodeAt(i); } if (!dontAddNull) HEAP8[buffer2 >> 0] = 0; } var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; function updateGlobalBufferAndViews(buf) { buffer = buf; Module2["HEAP8"] = HEAP8 = new Int8Array(buf); Module2["HEAP16"] = HEAP16 = new Int16Array(buf); Module2["HEAP32"] = HEAP32 = new Int32Array(buf); Module2["HEAPU8"] = HEAPU8 = new Uint8Array(buf); Module2["HEAPU16"] = HEAPU16 = new Uint16Array(buf); Module2["HEAPU32"] = HEAPU32 = new Uint32Array(buf); Module2["HEAPF32"] = HEAPF32 = new Float32Array(buf); Module2["HEAPF64"] = HEAPF64 = new Float64Array(buf); } var STACK_BASE = 22384, DYNAMIC_BASE = 5265264, DYNAMICTOP_PTR = 22176; var INITIAL_INITIAL_MEMORY = Module2["INITIAL_MEMORY"] || 167772160; if (Module2["buffer"]) { buffer = Module2["buffer"]; } else { buffer = new ArrayBuffer(INITIAL_INITIAL_MEMORY); } INITIAL_INITIAL_MEMORY = buffer.byteLength; updateGlobalBufferAndViews(buffer); HEAP32[DYNAMICTOP_PTR >> 2] = DYNAMIC_BASE; function callRuntimeCallbacks(callbacks) { while (callbacks.length > 0) { var callback = callbacks.shift(); if (typeof callback == "function") { callback(Module2); continue; } var func = callback.func; if (typeof func === "number") { if (callback.arg === void 0) { Module2["dynCall_v"](func); } else { Module2["dynCall_vi"](func, callback.arg); } } else { func(callback.arg === void 0 ? null : callback.arg); } } } var __ATPRERUN__ = []; var __ATINIT__ = []; var __ATMAIN__ = []; var __ATPOSTRUN__ = []; var runtimeInitialized = false; var runtimeExited = false; function preRun() { if (Module2["preRun"]) { if (typeof Module2["preRun"] == "function") Module2["preRun"] = [Module2["preRun"]]; while (Module2["preRun"].length) { addOnPreRun(Module2["preRun"].shift()); } } callRuntimeCallbacks(__ATPRERUN__); } function initRuntime() { runtimeInitialized = true; callRuntimeCallbacks(__ATINIT__); } function preMain() { callRuntimeCallbacks(__ATMAIN__); } function exitRuntime() { runtimeExited = true; } function postRun() { if (Module2["postRun"]) { if (typeof Module2["postRun"] == "function") Module2["postRun"] = [Module2["postRun"]]; while (Module2["postRun"].length) { addOnPostRun(Module2["postRun"].shift()); } } callRuntimeCallbacks(__ATPOSTRUN__); } function addOnPreRun(cb) { __ATPRERUN__.unshift(cb); } function addOnPostRun(cb) { __ATPOSTRUN__.unshift(cb); } var Math_abs = Math.abs; var Math_ceil = Math.ceil; var Math_floor = Math.floor; var Math_min = Math.min; var runDependencies = 0; var runDependencyWatcher = null; var dependenciesFulfilled = null; function addRunDependency(id) { runDependencies++; if (Module2["monitorRunDependencies"]) { Module2["monitorRunDependencies"](runDependencies); } } function removeRunDependency(id) { runDependencies--; if (Module2["monitorRunDependencies"]) { Module2["monitorRunDependencies"](runDependencies); } if (runDependencies == 0) { if (runDependencyWatcher !== null) { clearInterval(runDependencyWatcher); runDependencyWatcher = null; } if (dependenciesFulfilled) { var callback = dependenciesFulfilled; dependenciesFulfilled = null; callback(); } } } Module2["preloadedImages"] = {}; Module2["preloadedAudios"] = {}; function abort(what) { if (Module2["onAbort"]) { Module2["onAbort"](what); } what += ""; out(what); err(what); ABORT = true; EXITSTATUS = 1; what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info."; throw what; } var memoryInitializer = null; function hasPrefix(str, prefix) { return String.prototype.startsWith ? str.startsWith(prefix) : str.indexOf(prefix) === 0; } var dataURIPrefix = "data:application/octet-stream;base64,"; function isDataURI(filename) { return hasPrefix(filename, dataURIPrefix); } var fileURIPrefix = "file://"; var tempDouble; var tempI64; __ATINIT__.push({ func: function() { globalCtors(); } }); memoryInitializer = "data:application/octet-stream;base64,AAAAAAAAAAAPDg0MCwoJCA4AAQMGCgoJDQECBAcLCwoMAwQFCAwMCwsGBwgJDQ0MCgoLDA0ODg0JCgsMDQ4PDggJCgsMDQ4PAAECAwQFBgcBAAECAwQFBgIBAAECAwQFAwIBAAECAwQEAwIBAAECAwUEAwIBAAECBgUEAwIBAAEHBgUEAwIBAMgPAAAoDQAAEBAAACAQAADIDwAAUA0AABAQAAAgEAAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAEACQsLAAAJBgsAAAsABhEAAAAREREAAAAAAAAAAAAAAAAAAAAACwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAADAAAAAAJDAAAAAAADAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAANAAAABA0AAAAACQ4AAAAAAA4AAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAADwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAASEhIAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAAAAAAAAAAAKAAAAAAoAAAAACQsAAAAAAAsAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGGRJEOwI/LEcUPTMwChsGRktFNw9JDo4XA0AdPGkrNh9KLRwBICUpIQgMFRYiLhA4Pgs0MRhkdHV2L0EJfzkRI0MyQomKiwUEJignDSoeNYwHGkiTE5SVAAAAAAAAAAAASWxsZWdhbCBieXRlIHNlcXVlbmNlAERvbWFpbiBlcnJvcgBSZXN1bHQgbm90IHJlcHJlc2VudGFibGUATm90IGEgdHR5AFBlcm1pc3Npb24gZGVuaWVkAE9wZXJhdGlvbiBub3QgcGVybWl0dGVkAE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkATm8gc3VjaCBwcm9jZXNzAEZpbGUgZXhpc3RzAFZhbHVlIHRvbyBsYXJnZSBmb3IgZGF0YSB0eXBlAE5vIHNwYWNlIGxlZnQgb24gZGV2aWNlAE91dCBvZiBtZW1vcnkAUmVzb3VyY2UgYnVzeQBJbnRlcnJ1cHRlZCBzeXN0ZW0gY2FsbABSZXNvdXJjZSB0ZW1wb3JhcmlseSB1bmF2YWlsYWJsZQBJbnZhbGlkIHNlZWsAQ3Jvc3MtZGV2aWNlIGxpbmsAUmVhZC1vbmx5IGZpbGUgc3lzdGVtAERpcmVjdG9yeSBub3QgZW1wdHkAQ29ubmVjdGlvbiByZXNldCBieSBwZWVyAE9wZXJhdGlvbiB0aW1lZCBvdXQAQ29ubmVjdGlvbiByZWZ1c2VkAEhvc3QgaXMgZG93bgBIb3N0IGlzIHVucmVhY2hhYmxlAEFkZHJlc3MgaW4gdXNlAEJyb2tlbiBwaXBlAEkvTyBlcnJvcgBObyBzdWNoIGRldmljZSBvciBhZGRyZXNzAEJsb2NrIGRldmljZSByZXF1aXJlZABObyBzdWNoIGRldmljZQBOb3QgYSBkaXJlY3RvcnkASXMgYSBkaXJlY3RvcnkAVGV4dCBmaWxlIGJ1c3kARXhlYyBmb3JtYXQgZXJyb3IASW52YWxpZCBhcmd1bWVudABBcmd1bWVudCBsaXN0IHRvbyBsb25nAFN5bWJvbGljIGxpbmsgbG9vcABGaWxlbmFtZSB0b28gbG9uZwBUb28gbWFueSBvcGVuIGZpbGVzIGluIHN5c3RlbQBObyBmaWxlIGRlc2NyaXB0b3JzIGF2YWlsYWJsZQBCYWQgZmlsZSBkZXNjcmlwdG9yAE5vIGNoaWxkIHByb2Nlc3MAQmFkIGFkZHJlc3MARmlsZSB0b28gbGFyZ2UAVG9vIG1hbnkgbGlua3MATm8gbG9ja3MgYXZhaWxhYmxlAFJlc291cmNlIGRlYWRsb2NrIHdvdWxkIG9jY3VyAFN0YXRlIG5vdCByZWNvdmVyYWJsZQBQcmV2aW91cyBvd25lciBkaWVkAE9wZXJhdGlvbiBjYW5jZWxlZABGdW5jdGlvbiBub3QgaW1wbGVtZW50ZWQATm8gbWVzc2FnZSBvZiBkZXNpcmVkIHR5cGUASWRlbnRpZmllciByZW1vdmVkAERldmljZSBub3QgYSBzdHJlYW0ATm8gZGF0YSBhdmFpbGFibGUARGV2aWNlIHRpbWVvdXQAT3V0IG9mIHN0cmVhbXMgcmVzb3VyY2VzAExpbmsgaGFzIGJlZW4gc2V2ZXJlZABQcm90b2NvbCBlcnJvcgBCYWQgbWVzc2FnZQBGaWxlIGRlc2NyaXB0b3IgaW4gYmFkIHN0YXRlAE5vdCBhIHNvY2tldABEZXN0aW5hdGlvbiBhZGRyZXNzIHJlcXVpcmVkAE1lc3NhZ2UgdG9vIGxhcmdlAFByb3RvY29sIHdyb25nIHR5cGUgZm9yIHNvY2tldABQcm90b2NvbCBub3QgYXZhaWxhYmxlAFByb3RvY29sIG5vdCBzdXBwb3J0ZWQAU29ja2V0IHR5cGUgbm90IHN1cHBvcnRlZABOb3Qgc3VwcG9ydGVkAFByb3RvY29sIGZhbWlseSBub3Qgc3VwcG9ydGVkAEFkZHJlc3MgZmFtaWx5IG5vdCBzdXBwb3J0ZWQgYnkgcHJvdG9jb2wAQWRkcmVzcyBub3QgYXZhaWxhYmxlAE5ldHdvcmsgaXMgZG93bgBOZXR3b3JrIHVucmVhY2hhYmxlAENvbm5lY3Rpb24gcmVzZXQgYnkgbmV0d29yawBDb25uZWN0aW9uIGFib3J0ZWQATm8gYnVmZmVyIHNwYWNlIGF2YWlsYWJsZQBTb2NrZXQgaXMgY29ubmVjdGVkAFNvY2tldCBub3QgY29ubmVjdGVkAENhbm5vdCBzZW5kIGFmdGVyIHNvY2tldCBzaHV0ZG93bgBPcGVyYXRpb24gYWxyZWFkeSBpbiBwcm9ncmVzcwBPcGVyYXRpb24gaW4gcHJvZ3Jlc3MAU3RhbGUgZmlsZSBoYW5kbGUAUmVtb3RlIEkvTyBlcnJvcgBRdW90YSBleGNlZWRlZABObyBtZWRpdW0gZm91bmQAV3JvbmcgbWVkaXVtIHR5cGUATm8gZXJyb3IgaW5mb3JtYXRpb24AAAAAAADgFgAAmRgAAGAQAAAAAAAA4BYAAEIZAABgEAAAAAAAAOAWAAAqGgAASA8AAAAAAAC4FgAANBsAAOAWAACfGgAAMAoAAAAAAADgFgAAaRsAAEgPAAAAAAAA4BYAAIobAABIDwAAAAAAALgWAAAPHAAA4BYAAHwcAABIDwAAAAAAAOAWAACVHAAASA8AAAAAAADgFgAA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c2hhcmVkX3B0cl9wb2ludGVySVBONmxhc3ppcDdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRU5TXzE0ZGVmYXVsdF9kZWxldGVJUzNfRUVOU185YWxsb2NhdG9ySVMzX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXA3c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRQBOU3QzX18yMjBfX3NoYXJlZF9wdHJfcG9pbnRlcklQTjZsYXN6aXAyaW82cmVhZGVyMTBiYXNpY19maWxlSU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRU5TXzE0ZGVmYXVsdF9kZWxldGVJUzdfRUVOU185YWxsb2NhdG9ySVM3X0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXAyaW82cmVhZGVyMTBiYXNpY19maWxlSU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFAExBU0YATjZsYXN6aXAxM2ludmFsaWRfbWFnaWNFAGFsbG9jYXRvcjxUPjo6YWxsb2NhdGUoc2l6ZV90IG4pICduJyBleGNlZWRzIG1heGltdW0gc3VwcG9ydGVkIHNpemUARmlsZSBtYWdpYyBpcyBub3QgdmFsaWQATlN0M19fMjEwX19mdW5jdGlvbjZfX2Z1bmNJWk42bGFzemlwMmlvNnJlYWRlcjEwYmFzaWNfZmlsZUlOUzJfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRTExX3ZhbGlkYXRvcnNFdkVVbFJOUzNfNmhlYWRlckVFX05TXzlhbGxvY2F0b3JJU0JfRUVGdlNBX0VFRQBOU3QzX18yMTBfX2Z1bmN0aW9uNl9fYmFzZUlGdlJONmxhc3ppcDJpbzZoZWFkZXJFRUVFAE42bGFzemlwMjFvbGRfc3R5bGVfY29tcHJlc3Npb25FAE42bGFzemlwMTRub3RfY29tcHJlc3NlZEUAVGhlIGZpbGUgc2VlbXMgdG8gaGF2ZSBvbGQgc3R5bGUgY29tcHJlc3Npb24gd2hpY2ggaXMgbm90IHN1cHBvcnRlZABUaGUgZmlsZSBkb2Vzbid0IHNlZW0gdG8gYmUgY29tcHJlc3NlZABaTjZsYXN6aXAyaW82cmVhZGVyMTBiYXNpY19maWxlSU5TXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUUxMV92YWxpZGF0b3JzRXZFVWxSTlMwXzZoZWFkZXJFRV8AbGFzemlwIGVuY29kZWQATjZsYXN6aXAxM25vX2xhc3ppcF92bHJFAE42bGFzemlwMjVsYXN6aXBfZm9ybWF0X3Vuc3VwcG9ydGVkRQBPbmx5IExBU3ppcCBQT0lOVFdJU0UgQ0hVTktFRCBkZWNvbXByZXNzb3IgaXMgc3VwcG9ydGVkAE5vIExBU3ppcCBWTFIgd2FzIGZvdW5kIGluIHRoZSBWTFJzIHNlY3Rpb24ATjZsYXN6aXAyMmNodW5rX3RhYmxlX3JlYWRfZXJyb3JFAENodW5rIHRhYmxlIG9mZnNldCA9PSAtMSBpcyBub3Qgc3VwcG9ydGVkIGF0IHRoaXMgdGltZQBONmxhc3ppcDEzbm90X3N1cHBvcnRlZEUATjZsYXN6aXAyNnVua25vd25fY2h1bmtfdGFibGVfZm9ybWF0RQBjaHVua19zaXplID09IHVpbnQubWF4IGlzIG5vdCBzdXBwb3J0ZWQgYXQgdGhpcyB0aW1lLgBUaGVyZSB3YXMgYSBwcm9ibGVtIHJlYWRpbmcgdGhlIGNodW5rIHRhYmxlAFRoZSBjaHVuayB0YWJsZSB2ZXJzaW9uIG51bWJlciBpcyB1bmtub3duAE42bGFzemlwMTFlbmRfb2ZfZmlsZUUAUmVhY2hlZCBFbmQgb2YgZmlsZQBJbnZhbGlkIG51bWJlciBvZiBzeW1ib2xzAE5TdDNfXzIyMF9fc2hhcmVkX3B0cl9wb2ludGVySVBONmxhc3ppcDhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOU18xNGRlZmF1bHRfZGVsZXRlSVM5X0VFTlNfOWFsbG9jYXRvcklTOV9FRUVFAE5TdDNfXzIxNGRlZmF1bHRfZGVsZXRlSU42bGFzemlwOGRlY29kZXJzMTBhcml0aG1ldGljSU5TMV8yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOUzFfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRUVFAE42bGFzemlwMTl1bmtub3duX3NjaGVtYV90eXBlRQBUaGUgTEFaIHNjaGVtYSBpcyBub3QgcmVjb2duaXplZABONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2ZpZWxkX2RlY29tcHJlc3NvcklOU184ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlNfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlNfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyMGR5bmFtaWNfZGVjb21wcmVzc29yRQBOU3QzX18yMjBfX3NoYXJlZF9wdHJfcG9pbnRlcklQTjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19maWVsZF9kZWNvbXByZXNzb3JJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVFRU5TXzE0ZGVmYXVsdF9kZWxldGVJU0NfRUVOU185YWxsb2NhdG9ySVNDX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19maWVsZF9kZWNvbXByZXNzb3JJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOU18yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOU183c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMwXzVmaWVsZElOUzBfM2xhczdwb2ludDEwRU5TMF8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNDX0VFRUVFRQBONmxhc3ppcDdmb3JtYXRzMTBiYXNlX2ZpZWxkRQBOU3QzX18yMjBfX3NoYXJlZF9wdHJfcG9pbnRlcklQTjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19kZWNvbXByZXNzb3JfZmllbGRJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzJfNWZpZWxkSU5TMl8zbGFzN3BvaW50MTBFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0VfRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTSV9FRU5TXzlhbGxvY2F0b3JJU0lfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TMV8yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOUzFfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRU5TMl81ZmllbGRJTlMyXzNsYXM3cG9pbnQxMEVOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTRV9FRUVFRUVFRQBONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOU184ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlNfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlNfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRU5TMF81ZmllbGRJTlMwXzNsYXM3Z3BzdGltZUVOUzBfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTQ19FRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzVmaWVsZElOUzJfM2xhczdncHN0aW1lRU5TMl8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNFX0VFRUVFRU5TXzE0ZGVmYXVsdF9kZWxldGVJU0lfRUVOU185YWxsb2NhdG9ySVNJX0VFRUUATlN0M19fMjE0ZGVmYXVsdF9kZWxldGVJTjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19kZWNvbXByZXNzb3JfZmllbGRJTlMxXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOUzFfMmlvMThfX2lmc3RyZWFtX3dyYXBwZXJJTlMxXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzJfNWZpZWxkSU5TMl8zbGFzN2dwc3RpbWVFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0VfRUVFRUVFRUUATjZsYXN6aXA3Zm9ybWF0czI2ZHluYW1pY19kZWNvbXByZXNzb3JfZmllbGRJTlNfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TXzdzdHJlYW1zMTNtZW1vcnlfc3RyZWFtRUVFRUVOUzBfNWZpZWxkSU5TMF8zbGFzM3JnYkVOUzBfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTQ19FRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzVmaWVsZElOUzJfM2xhczNyZ2JFTlMyXzIwc3RhbmRhcmRfZGlmZl9tZXRob2RJU0VfRUVFRUVFTlNfMTRkZWZhdWx0X2RlbGV0ZUlTSV9FRU5TXzlhbGxvY2F0b3JJU0lfRUVFRQBOU3QzX18yMTRkZWZhdWx0X2RlbGV0ZUlONmxhc3ppcDdmb3JtYXRzMjZkeW5hbWljX2RlY29tcHJlc3Nvcl9maWVsZElOUzFfOGRlY29kZXJzMTBhcml0aG1ldGljSU5TMV8yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOUzFfN3N0cmVhbXMxM21lbW9yeV9zdHJlYW1FRUVFRU5TMl81ZmllbGRJTlMyXzNsYXMzcmdiRU5TMl8yMHN0YW5kYXJkX2RpZmZfbWV0aG9kSVNFX0VFRUVFRUVFAE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TXzhkZWNvZGVyczEwYXJpdGhtZXRpY0lOU18yaW8xOF9faWZzdHJlYW1fd3JhcHBlcklOU183c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMwXzVmaWVsZElOUzBfM2xhczEwZXh0cmFieXRlc0VOUzBfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTQ19FRUVFRUUATlN0M19fMjIwX19zaGFyZWRfcHRyX3BvaW50ZXJJUE42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzVmaWVsZElOUzJfM2xhczEwZXh0cmFieXRlc0VOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTRV9FRUVFRUVOU18xNGRlZmF1bHRfZGVsZXRlSVNJX0VFTlNfOWFsbG9jYXRvcklTSV9FRUVFAE5TdDNfXzIxNGRlZmF1bHRfZGVsZXRlSU42bGFzemlwN2Zvcm1hdHMyNmR5bmFtaWNfZGVjb21wcmVzc29yX2ZpZWxkSU5TMV84ZGVjb2RlcnMxMGFyaXRobWV0aWNJTlMxXzJpbzE4X19pZnN0cmVhbV93cmFwcGVySU5TMV83c3RyZWFtczEzbWVtb3J5X3N0cmVhbUVFRUVFTlMyXzVmaWVsZElOUzJfM2xhczEwZXh0cmFieXRlc0VOUzJfMjBzdGFuZGFyZF9kaWZmX21ldGhvZElTRV9FRUVFRUVFRQBONmxhc3ppcDdmb3JtYXRzMjFkeW5h