From 5bfa9633d2235fe55f767785817b5b8f34604d9e Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Mon, 29 Mar 2021 14:20:40 -0700 Subject: [PATCH 01/39] Fix, regression with Metal buffers (#3715) --- filament/backend/src/metal/MetalHandles.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filament/backend/src/metal/MetalHandles.mm b/filament/backend/src/metal/MetalHandles.mm index 6b471a24a4..5a2c67961f 100644 --- a/filament/backend/src/metal/MetalHandles.mm +++ b/filament/backend/src/metal/MetalHandles.mm @@ -320,7 +320,7 @@ void MetalRenderPrimitive::setBuffers(MetalVertexBuffer* vertexBuffer, MetalInde uint32_t bufferIndex = 0; for (uint32_t attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++) { const auto& attribute = vertexBuffer->attributes[attributeIndex]; - if (attribute.buffer != Attribute::BUFFER_UNUSED) { + if (attribute.buffer == Attribute::BUFFER_UNUSED) { const uint8_t flags = attribute.flags; const MTLVertexFormat format = (flags & Attribute::FLAG_INTEGER_TARGET) ? MTLVertexFormatUInt4 : MTLVertexFormatFloat4; From a0e7c26a634999f711d6e873da029ef903fe2093 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Mon, 29 Mar 2021 14:49:12 -0700 Subject: [PATCH 02/39] Remote pip lockfile from web docs generator. --- web/docs/Pipfile.lock | 58 ------------------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 web/docs/Pipfile.lock diff --git a/web/docs/Pipfile.lock b/web/docs/Pipfile.lock deleted file mode 100644 index 867304fb60..0000000000 --- a/web/docs/Pipfile.lock +++ /dev/null @@ -1,58 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "64fb040f71095c2ee61210e3b1cab5dfde8866fcc1121829f2106ea38abbd125" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.8" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "editorconfig": { - "hashes": [ - "sha256:1b0ef345f9c3a673e492cfe608ed644b236139f7fceab5c6f513a71bcaf8a56c", - "sha256:60d6f10b87d2572ac1581cb8c9f018163e2b13a9e49588f9fb6dc8c715a1744c" - ], - "version": "==0.12.2" - }, - "jsbeautifier": { - "hashes": [ - "sha256:4f670c6f4f8d4caca9a348271010742f494becb96fe0a9be6ffac8b3d46350ca" - ], - "index": "pypi", - "version": "==1.11.0" - }, - "mistletoe": { - "hashes": [ - "sha256:24d0f18cc5f0381c2cfb8a24ef3de83eb9f7929cb7d0e71ecb164b671d86e6a3", - "sha256:3e2d31b2fa6231ea2ee46981274ebac8d5e5736e3aad2d1cd449e2c053b7023b" - ], - "index": "pypi", - "version": "==0.7.2" - }, - "pygments": { - "hashes": [ - "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44", - "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324" - ], - "index": "pypi", - "version": "==2.6.1" - }, - "six": { - "hashes": [ - "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", - "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" - ], - "version": "==1.14.0" - } - }, - "develop": {} -} From d2bff95c90c8b4a11cc9e023ec34b8ee05ca5606 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Mon, 29 Mar 2021 16:56:33 -0700 Subject: [PATCH 03/39] Easy build: add matdbg option and help message. --- CMakeLists.txt | 10 +++++-- android/filament-android/CMakeLists.txt | 1 + build.sh | 38 ++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09e8aaf1ac..352038ad7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -400,6 +400,13 @@ else() option(FILAMENT_ENABLE_MATDBG "Enable the material debugger" OFF) endif() +# Only optimize materials in Release mode (so error message lines match the source code) +if (CMAKE_BUILD_TYPE MATCHES Release) + option(FILAMENT_DISABLE_MATOPT "Disable material optimizations" OFF) +else() + option(FILAMENT_DISABLE_MATOPT "Disable material optimizations" ON) +endif() + # ================================================================================================== # Material compilation flags # ================================================================================================== @@ -423,8 +430,7 @@ if (FILAMENT_SUPPORTS_METAL) set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal) endif() -# Only optimize materials in Release mode (so error message lines match the source code) -if (NOT CMAKE_BUILD_TYPE MATCHES Release) +if (FILAMENT_DISABLE_MATOPT) set(MATC_OPT_FLAGS -g) endif() diff --git a/android/filament-android/CMakeLists.txt b/android/filament-android/CMakeLists.txt index 3a38131b5a..09cb594a78 100644 --- a/android/filament-android/CMakeLists.txt +++ b/android/filament-android/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.6) option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF) option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF) +option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF) set(FILAMENT_DIR ${FILAMENT_DIST_DIR}) diff --git a/build.sh b/build.sh index 5c89b80042..b953601045 100755 --- a/build.sh +++ b/build.sh @@ -17,6 +17,8 @@ function print_help { echo " Generate .tgz build archives, implies -i." echo " -c" echo " Clean build directories." + echo " -d" + echo " Enable matdbg and disable material optimization." echo " -f" echo " Always invoke CMake before incremental builds." echo " -i" @@ -80,6 +82,27 @@ function print_help { echo "" } +function print_matdbg_help { + echo "matdbg is enabled in the build, but some extra steps are needed." + echo "" + echo "FOR DESKTOP BUILDS:" + echo "" + echo "Please set the port environment variable before launching. e.g., on macOS do:" + echo " export FILAMENT_MATDBG_PORT=8080" + echo "" + echo "FOR ANDROID BUILDS:" + echo "" + echo "1) The most reliable way to enable matdbg is to bypass Gradle and" + echo " directly modify the appropriate two lines in the following file:" + echo " ./android/filament-android/CMakeLists.txt" + echo "" + echo "2) The port number is hardcoded to 8081 so you will need to do:" + echo " adb forward tcp:8081 tcp:8081" + echo "" + echo "3) Be sure to enable INTERNET permission in your app's manifest file." + echo "" +} + # Requirements CMAKE_MAJOR=3 CMAKE_MINOR=10 @@ -122,6 +145,8 @@ VULKAN_ANDROID_GRADLE_OPTION="" SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF" +MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF" + IOS_BUILD_SIMULATOR=false BUILD_UNIVERSAL_LIBRARIES=false @@ -174,6 +199,7 @@ function build_desktop_target { -DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \ -DFILAMENT_ENABLE_JAVA="${FILAMENT_ENABLE_JAVA}" \ ${SWIFTSHADER_OPTION} \ + ${MATDBG_OPTION} \ ${deployment_target} \ ${architectures} \ ../.. @@ -298,6 +324,7 @@ function build_android_target { -DCMAKE_BUILD_TYPE="$1" \ -DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \ -DCMAKE_TOOLCHAIN_FILE="../../build/toolchain-${arch}-linux-android.cmake" \ + ${MATDBG_OPTION} \ ${VULKAN_ANDROID_OPTION} \ ../.. fi @@ -484,6 +511,7 @@ function build_ios_target { -DPLATFORM_NAME="${platform}" \ -DIOS=1 \ -DCMAKE_TOOLCHAIN_FILE=../../third_party/clang/iOS.cmake \ + ${MATDBG_OPTION} \ ../.. fi @@ -654,7 +682,7 @@ function run_tests { pushd "$(dirname "$0")" > /dev/null -while getopts ":hacfijmp:q:uvslwt" opt; do +while getopts ":hacfijmp:q:uvslwtd" opt; do case ${opt} in h) print_help @@ -667,6 +695,10 @@ while getopts ":hacfijmp:q:uvslwt" opt; do c) ISSUE_CLEAN=true ;; + d) + PRINT_MATDBG_HELP=true + MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON" + ;; f) ISSUE_CMAKE_ALWAYS=true ;; @@ -825,3 +857,7 @@ fi if [[ "${RUN_TESTS}" == "true" ]]; then run_tests fi + +if [[ "${PRINT_MATDBG_HELP}" == "true" ]]; then + print_matdbg_help +fi From 3161f6a8f1ab062b8f299554c95d079ef664fa9d Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Mon, 29 Mar 2021 14:34:35 -0700 Subject: [PATCH 04/39] Remote UI now handles keyboard input. --- docs/remote/filament.js | 2 +- docs/remote/filament.wasm | Bin 3835299 -> 3839296 bytes docs/remote/index.html | 20 +++++-- libs/viewer/include/viewer/SimpleViewer.h | 14 ++++- libs/viewer/src/SimpleViewer.cpp | 67 ++++++++++++++++++---- web/filament-js/jsbindings.cpp | 6 +- web/samples/remote.html | 20 +++++-- 7 files changed, 102 insertions(+), 27 deletions(-) diff --git a/docs/remote/filament.js b/docs/remote/filament.js index 013ebbb32a..34411860de 100644 --- a/docs/remote/filament.js +++ b/docs/remote/filament.js @@ -6,7 +6,7 @@ var Filament = (function() { function(Filament) { Filament = Filament || {}; -var Module=typeof Filament!=="undefined"?Filament:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[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(Module["locateFile"]){return Module["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{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(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);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}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"){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(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;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>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=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=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"):undefined;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 str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>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===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=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=55296&&codeUnit<=57343)++i;len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}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 updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;__ATINIT__.push({func:function(){___wasm_call_ctors()}});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;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;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 addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}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"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}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://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="filament.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){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(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["Zg"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["_g"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var tempDouble;var tempI64;var ASM_CONSTS={10126:function(){const handle=GL.registerContext(Filament.glContext,Filament.glOptions);GL.makeContextCurrent(handle)},2419420:function(){GL.currArrayBuffer=GLctx.currentArrayBufferBinding}};function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){var alignedSize=alignMemory(size,16384);var ptr=_malloc(alignedSize);while(size=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){FS.forceLoadFile(node);var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=varargs?SYSCALLS.get():0;var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var tupleRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}return Module["dynCall_"+sig].call(null,ptr)}function dynCall(sig,ptr,args){if(sig.indexOf("j")!=-1){return dynCallLegacy(sig,ptr,args)}return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){assert(sig.indexOf("j")>=0,"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i>2)+i])}return array}function __embind_register_class_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,fn){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.constructor;if(undefined===proto[methodName]){unboundTypesHandler.argCount=argCount-1;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-1]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));var func=craftInvokerFunction(humanName,invokerArgsArray,null,rawInvoker,fn);if(undefined===proto[methodName].overloadTable){func.argCount=argCount-1;proto[methodName]=func}else{proto[methodName].overloadTable[argCount-1]=func}return[]});return[]})}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>1])};case 2:return function(pointer){var heap=signed?HEAP32:HEAPU32;return this["fromWireType"](heap[pointer>>2])};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_enum(rawType,name,size,isSigned){var shift=getShiftFromSize(size);name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":function(destructors,c){return c.value},"argPackAdvance":8,"readValueFromPointer":enumReadValueFromPointer(name,shift,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __embind_register_enum_value(rawEnumType,name,enumValue){var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(enumType.name+"_"+name,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_array(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){tupleRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),elements:[]}}function __embind_register_value_array_element(rawTupleType,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){tupleRegistrations[rawTupleType].elements.push({getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireHandle(handle){if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value}function __emval_as(handle,returnType,destructorsRef){handle=requireHandle(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=__emval_register(destructors);HEAP32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}function __emval_get_property(handle,key){handle=requireHandle(handle);key=requireHandle(key);return __emval_register(handle[key])}function __emval_incref(handle){if(handle>4){emval_handle_array[handle].refcount+=1}}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function __emval_take_value(type,argv){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](argv);return __emval_register(v)}function _abort(){abort()}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else if(typeof dateNow!=="undefined"){_emscripten_get_now=dateNow}else _emscripten_get_now=function(){return performance.now()};var _emscripten_get_now_is_monotonic=true;function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if((clk_id===1||clk_id===4)&&_emscripten_get_now_is_monotonic){now=_emscripten_get_now()}else{setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}function __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(ctx){return!!(ctx.dibvbi=ctx.getExtension("WEBGL_draw_instanced_base_vertex_base_instance"))}function __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(ctx){return!!(ctx.mdibvbi=ctx.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance"))}function __webgl_enable_WEBGL_multi_draw(ctx){return!!(ctx.multiDrawWebgl=ctx.getExtension("WEBGL_multi_draw"))}var GL={counter:1,buffers:[],mappedBuffers:{},programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},timerQueriesEXT:[],queries:[],samplers:[],transformFeedbacks:[],syncs:[],byteSizeByTypeRoot:5120,byteSizeByType:[1,1,2,2,4,4,4,2,3,4,8],programInfos:{},stringCache:{},stringiCache:{},unpackAlignment:4,recordError:function recordError(errorCode){if(!GL.lastError){GL.lastError=errorCode}},getNewId:function(table){var ret=GL.counter++;for(var i=table.length;i>1;var quadIndexes=new Uint16Array(numIndexes);var i=0,v=0;while(1){quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+1;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v+3;if(i>=numIndexes)break;v+=4}context.GLctx.bufferData(34963,quadIndexes,35044);context.GLctx.bindBuffer(34963,null)}},getTempVertexBuffer:function getTempVertexBuffer(sizeBytes){var idx=GL.log2ceilLookup(sizeBytes);var ringbuffer=GL.currentContext.tempVertexBuffers1[idx];var nextFreeBufferIndex=GL.currentContext.tempVertexBufferCounters1[idx];GL.currentContext.tempVertexBufferCounters1[idx]=GL.currentContext.tempVertexBufferCounters1[idx]+1&GL.numTempVertexBuffersPerSize-1;var vbo=ringbuffer[nextFreeBufferIndex];if(vbo){return vbo}var prevVBO=GLctx.getParameter(34964);ringbuffer[nextFreeBufferIndex]=GLctx.createBuffer();GLctx.bindBuffer(34962,ringbuffer[nextFreeBufferIndex]);GLctx.bufferData(34962,1<>2]:-1;source+=UTF8ToString(HEAP32[string+i*4>>2],len<0?undefined:len)}return source},calcBufLength:function calcBufLength(size,type,stride,count){if(stride>0){return count*stride}var typeSize=GL.byteSizeByType[type-GL.byteSizeByTypeRoot];return size*typeSize*count},usedTempBuffers:[],preDrawHandleClientVertexAttribBindings:function preDrawHandleClientVertexAttribBindings(count){GL.resetBufferBinding=false;for(var i=0;i>2)}function _emscripten_glClearBufferiv(buffer,drawbuffer,value){GLctx["clearBufferiv"](buffer,drawbuffer,HEAP32,value>>2)}function _emscripten_glClearBufferuiv(buffer,drawbuffer,value){GLctx["clearBufferuiv"](buffer,drawbuffer,HEAPU32,value>>2)}function _emscripten_glClearColor(x0,x1,x2,x3){GLctx["clearColor"](x0,x1,x2,x3)}function _emscripten_glClearDepthf(x0){GLctx["clearDepth"](x0)}function _emscripten_glClearStencil(x0){GLctx["clearStencil"](x0)}function convertI32PairToI53(lo,hi){return(lo>>>0)+hi*4294967296}function _emscripten_glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _emscripten_glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _emscripten_glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _emscripten_glCompressedTexImage2D(target,level,internalFormat,width,height,border,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,imageSize,data)}else{GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,HEAPU8,data,imageSize)}return}GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexImage3D(target,level,internalFormat,width,height,depth,border,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexImage3D"](target,level,internalFormat,width,height,depth,border,imageSize,data)}else{GLctx["compressedTexImage3D"](target,level,internalFormat,width,height,depth,border,HEAPU8,data,imageSize)}}function _emscripten_glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,imageSize,data)}else{GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,HEAPU8,data,imageSize)}return}GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data)}else{GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,HEAPU8,data,imageSize)}}function _emscripten_glCopyBufferSubData(x0,x1,x2,x3,x4){GLctx["copyBufferSubData"](x0,x1,x2,x3,x4)}function _emscripten_glCopyTexImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexSubImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage3D(x0,x1,x2,x3,x4,x5,x6,x7,x8){GLctx["copyTexSubImage3D"](x0,x1,x2,x3,x4,x5,x6,x7,x8)}function _emscripten_glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _emscripten_glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _emscripten_glCullFace(x0){GLctx["cullFace"](x0)}function _emscripten_glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _emscripten_glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _emscripten_glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _emscripten_glDeleteQueries(n,ids){for(var i=0;i>2];var query=GL.queries[id];if(!query)continue;GLctx["deleteQuery"](query);GL.queries[id]=null}}function _emscripten_glDeleteQueriesEXT(n,ids){for(var i=0;i>2];var query=GL.timerQueriesEXT[id];if(!query)continue;GLctx.disjointTimerQueryExt["deleteQueryEXT"](query);GL.timerQueriesEXT[id]=null}}function _emscripten_glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _emscripten_glDeleteSamplers(n,samplers){for(var i=0;i>2];var sampler=GL.samplers[id];if(!sampler)continue;GLctx["deleteSampler"](sampler);sampler.name=0;GL.samplers[id]=null}}function _emscripten_glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _emscripten_glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _emscripten_glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _emscripten_glDeleteTransformFeedbacks(n,ids){for(var i=0;i>2];var transformFeedback=GL.transformFeedbacks[id];if(!transformFeedback)continue;GLctx["deleteTransformFeedback"](transformFeedback);transformFeedback.name=0;GL.transformFeedbacks[id]=null}}function _emscripten_glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDeleteVertexArraysOES(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDepthFunc(x0){GLctx["depthFunc"](x0)}function _emscripten_glDepthMask(flag){GLctx.depthMask(!!flag)}function _emscripten_glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _emscripten_glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _emscripten_glDisable(x0){GLctx["disable"](x0)}function _emscripten_glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _emscripten_glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _emscripten_glDrawArraysInstanced(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedANGLE(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedARB(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedEXT(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedNV(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}var tempFixedLengthArray=[];function _emscripten_glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawBuffersEXT(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawBuffersWEBGL(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawElements(mode,count,type,indices){var buf;if(!GLctx.currentElementArrayBufferBinding){var size=GL.calcBufLength(1,type,0,count);buf=GL.getTempIndexBuffer(size);GLctx.bindBuffer(34963,buf);GLctx.bufferSubData(34963,0,HEAPU8.subarray(indices,indices+size));indices=0}GL.preDrawHandleClientVertexAttribBindings(count);GLctx.drawElements(mode,count,type,indices);GL.postDrawHandleClientVertexAttribBindings(count);if(!GLctx.currentElementArrayBufferBinding){GLctx.bindBuffer(34963,null)}}function _emscripten_glDrawElementsInstanced(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedANGLE(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedARB(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedEXT(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedNV(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _glDrawElements(mode,count,type,indices){var buf;if(!GLctx.currentElementArrayBufferBinding){var size=GL.calcBufLength(1,type,0,count);buf=GL.getTempIndexBuffer(size);GLctx.bindBuffer(34963,buf);GLctx.bufferSubData(34963,0,HEAPU8.subarray(indices,indices+size));indices=0}GL.preDrawHandleClientVertexAttribBindings(count);GLctx.drawElements(mode,count,type,indices);GL.postDrawHandleClientVertexAttribBindings(count);if(!GLctx.currentElementArrayBufferBinding){GLctx.bindBuffer(34963,null)}}function _emscripten_glDrawRangeElements(mode,start,end,count,type,indices){_glDrawElements(mode,count,type,indices)}function _emscripten_glEnable(x0){GLctx["enable"](x0)}function _emscripten_glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _emscripten_glEndQuery(x0){GLctx["endQuery"](x0)}function _emscripten_glEndQueryEXT(target){GLctx.disjointTimerQueryExt["endQueryEXT"](target)}function _emscripten_glEndTransformFeedback(){GLctx["endTransformFeedback"]()}function _emscripten_glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _emscripten_glFinish(){GLctx["finish"]()}function _emscripten_glFlush(){GLctx["flush"]()}function emscriptenWebGLGetBufferBinding(target){switch(target){case 34962:target=34964;break;case 34963:target=34965;break;case 35051:target=35053;break;case 35052:target=35055;break;case 35982:target=35983;break;case 36662:target=36662;break;case 36663:target=36663;break;case 35345:target=35368;break}var buffer=GLctx.getParameter(target);if(buffer)return buffer.name|0;else return 0}function emscriptenWebGLValidateMapBufferTarget(target){switch(target){case 34962:case 34963:case 36662:case 36663:case 35051:case 35052:case 35882:case 35982:case 35345:return true;default:return false}}function _emscripten_glFlushMappedBufferRange(target,offset,length){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glFlushMappedBufferRange");return}var mapping=GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glFlushMappedBufferRange");return}if(!(mapping.access&16)){GL.recordError(1282);err("buffer was not mapped with GL_MAP_FLUSH_EXPLICIT_BIT in glFlushMappedBufferRange");return}if(offset<0||length<0||offset+length>mapping.length){GL.recordError(1281);err("invalid range in glFlushMappedBufferRange");return}GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem+offset,mapping.mem+offset+length))}function _emscripten_glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _emscripten_glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _emscripten_glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function _emscripten_glFrontFace(x0){GLctx["frontFace"](x0)}function __glGenObject(n,buffers,createFunction,objectTable){for(var i=0;i>2]=id}}function _emscripten_glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _emscripten_glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _emscripten_glGenQueries(n,ids){__glGenObject(n,ids,"createQuery",GL.queries)}function _emscripten_glGenQueriesEXT(n,ids){for(var i=0;i>2]=0;return}var id=GL.getNewId(GL.timerQueriesEXT);query.name=id;GL.timerQueriesEXT[id]=query;HEAP32[ids+i*4>>2]=id}}function _emscripten_glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _emscripten_glGenSamplers(n,samplers){__glGenObject(n,samplers,"createSampler",GL.samplers)}function _emscripten_glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _emscripten_glGenTransformFeedbacks(n,ids){__glGenObject(n,ids,"createTransformFeedback",GL.transformFeedbacks)}function _emscripten_glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenVertexArraysOES(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function __glGetActiveAttribOrUniform(funcName,program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx[funcName](program,index);if(info){var numBytesWrittenExclNull=name&&stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull;if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}}function _emscripten_glGetActiveAttrib(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveAttrib",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniform(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveUniform",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniformBlockName(program,uniformBlockIndex,bufSize,length,uniformBlockName){program=GL.programs[program];var result=GLctx["getActiveUniformBlockName"](program,uniformBlockIndex);if(!result)return;if(uniformBlockName&&bufSize>0){var numBytesWrittenExclNull=stringToUTF8(result,uniformBlockName,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull}else{if(length)HEAP32[length>>2]=0}}function _emscripten_glGetActiveUniformBlockiv(program,uniformBlockIndex,pname,params){if(!params){GL.recordError(1281);return}program=GL.programs[program];switch(pname){case 35393:var name=GLctx["getActiveUniformBlockName"](program,uniformBlockIndex);HEAP32[params>>2]=name.length+1;return;default:var result=GLctx["getActiveUniformBlockParameter"](program,uniformBlockIndex,pname);if(!result)return;if(typeof result=="number"){HEAP32[params>>2]=result}else{for(var i=0;i>2]=result[i]}}}}function _emscripten_glGetActiveUniformsiv(program,uniformCount,uniformIndices,pname,params){if(!params){GL.recordError(1281);return}if(uniformCount>0&&uniformIndices==0){GL.recordError(1281);return}program=GL.programs[program];var ids=[];for(var i=0;i>2])}var result=GLctx["getActiveUniforms"](program,ids,pname);if(!result)return;var len=result.length;for(var i=0;i>2]=result[i]}}function _emscripten_glGetAttachedShaders(program,maxCount,count,shaders){var result=GLctx.getAttachedShaders(GL.programs[program]);var len=result.length;if(len>maxCount){len=maxCount}HEAP32[count>>2]=len;for(var i=0;i>2]=id}}function _emscripten_glGetAttribLocation(program,name){return GLctx.getAttribLocation(GL.programs[program],UTF8ToString(name))}function writeI53ToI64(ptr,num){HEAPU32[ptr>>2]=num;HEAPU32[ptr+4>>2]=(num-HEAPU32[ptr>>2])/4294967296}function emscriptenWebGLGet(name_,p,type){if(!p){GL.recordError(1281);return}var ret=undefined;switch(name_){case 36346:ret=1;break;case 36344:if(type!=0&&type!=1){GL.recordError(1280)}return;case 34814:case 36345:ret=0;break;case 34466:var formats=GLctx.getParameter(34467);ret=formats?formats.length:0;break;case 33309:if(GL.currentContext.version<2){GL.recordError(1282);return}var exts=GLctx.getSupportedExtensions()||[];ret=2*exts.length;break;case 33307:case 33308:if(GL.currentContext.version<2){GL.recordError(1280);return}ret=name_==33307?3:0;break}if(ret===undefined){var result=GLctx.getParameter(name_);switch(typeof result){case"number":ret=result;break;case"boolean":ret=result?1:0;break;case"string":GL.recordError(1280);return;case"object":if(result===null){switch(name_){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:{ret=0;break}default:{GL.recordError(1280);return}}}else if(result instanceof Float32Array||result instanceof Uint32Array||result instanceof Int32Array||result instanceof Array){for(var i=0;i>2]=result[i];break;case 2:HEAPF32[p+i*4>>2]=result[i];break;case 4:HEAP8[p+i>>0]=result[i]?1:0;break}}return}else{try{ret=result.name|0}catch(e){GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Unknown object returned from WebGL getParameter("+name_+")! (error: "+e+")");return}}break;default:GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Native code calling glGet"+type+"v("+name_+") and it returns "+result+" of type "+typeof result+"!");return}}switch(type){case 1:writeI53ToI64(p,ret);break;case 0:HEAP32[p>>2]=ret;break;case 2:HEAPF32[p>>2]=ret;break;case 4:HEAP8[p>>0]=ret?1:0;break}}function _emscripten_glGetBooleanv(name_,p){emscriptenWebGLGet(name_,p,4)}function _emscripten_glGetBufferParameteri64v(target,value,data){if(!data){GL.recordError(1281);return}writeI53ToI64(data,GLctx.getBufferParameter(target,value))}function _emscripten_glGetBufferParameteriv(target,value,data){if(!data){GL.recordError(1281);return}HEAP32[data>>2]=GLctx.getBufferParameter(target,value)}function _emscripten_glGetBufferPointerv(target,pname,params){if(pname==35005){var ptr=0;var mappedBuffer=GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)];if(mappedBuffer){ptr=mappedBuffer.mem}HEAP32[params>>2]=ptr}else{GL.recordError(1280);err("GL_INVALID_ENUM in glGetBufferPointerv")}}function _emscripten_glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _emscripten_glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _emscripten_glGetFragDataLocation(program,name){return GLctx["getFragDataLocation"](GL.programs[program],UTF8ToString(name))}function _emscripten_glGetFramebufferAttachmentParameteriv(target,attachment,pname,params){var result=GLctx.getFramebufferAttachmentParameter(target,attachment,pname);if(result instanceof WebGLRenderbuffer||result instanceof WebGLTexture){result=result.name|0}HEAP32[params>>2]=result}function emscriptenWebGLGetIndexed(target,index,data,type){if(!data){GL.recordError(1281);return}var result=GLctx["getIndexedParameter"](target,index);var ret;switch(typeof result){case"boolean":ret=result?1:0;break;case"number":ret=result;break;case"object":if(result===null){switch(target){case 35983:case 35368:ret=0;break;default:{GL.recordError(1280);return}}}else if(result instanceof WebGLBuffer){ret=result.name|0}else{GL.recordError(1280);return}break;default:GL.recordError(1280);return}switch(type){case 1:writeI53ToI64(data,ret);break;case 0:HEAP32[data>>2]=ret;break;case 2:HEAPF32[data>>2]=ret;break;case 4:HEAP8[data>>0]=ret?1:0;break;default:throw"internal emscriptenWebGLGetIndexed() error, bad type: "+type}}function _emscripten_glGetInteger64i_v(target,index,data){emscriptenWebGLGetIndexed(target,index,data,1)}function _emscripten_glGetInteger64v(name_,p){emscriptenWebGLGet(name_,p,1)}function _emscripten_glGetIntegeri_v(target,index,data){emscriptenWebGLGetIndexed(target,index,data,0)}function _emscripten_glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _emscripten_glGetInternalformativ(target,internalformat,pname,bufSize,params){if(bufSize<0){GL.recordError(1281);return}if(!params){GL.recordError(1281);return}var ret=GLctx["getInternalformatParameter"](target,internalformat,pname);if(ret===null)return;for(var i=0;i>2]=ret[i]}}function _emscripten_glGetProgramBinary(program,bufSize,length,binaryFormat,binary){GL.recordError(1282)}function _emscripten_glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _emscripten_glGetQueryObjecti64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectui64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectuiv(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.queries[id];var param=GLctx["getQueryParameter"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectuivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryiv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx["getQuery"](target,pname)}function _emscripten_glGetQueryivEXT(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.disjointTimerQueryExt["getQueryEXT"](target,pname)}function _emscripten_glGetRenderbufferParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getRenderbufferParameter(target,pname)}function _emscripten_glGetSamplerParameterfv(sampler,pname,params){if(!params){GL.recordError(1281);return}sampler=GL.samplers[sampler];HEAPF32[params>>2]=GLctx["getSamplerParameter"](sampler,pname)}function _emscripten_glGetSamplerParameteriv(sampler,pname,params){if(!params){GL.recordError(1281);return}sampler=GL.samplers[sampler];HEAP32[params>>2]=GLctx["getSamplerParameter"](sampler,pname)}function _emscripten_glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderPrecisionFormat(shaderType,precisionType,range,precision){var result=GLctx.getShaderPrecisionFormat(shaderType,precisionType);HEAP32[range>>2]=result.rangeMin;HEAP32[range+4>>2]=result.rangeMax;HEAP32[precision>>2]=result.precision}function _emscripten_glGetShaderSource(shader,bufSize,length,source){var result=GLctx.getShaderSource(GL.shaders[shader]);if(!result)return;var numBytesWrittenExclNull=bufSize>0&&source?stringToUTF8(result,source,bufSize):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function stringToNewUTF8(jsString){var length=lengthBytesUTF8(jsString)+1;var cString=_malloc(length);stringToUTF8(jsString,cString,length);return cString}function _emscripten_glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(true)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _emscripten_glGetStringi(name,index){if(GL.currentContext.version<2){GL.recordError(1282);return 0}var stringiCache=GL.stringiCache[name];if(stringiCache){if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index]}switch(name){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));exts=exts.map(function(e){return stringToNewUTF8(e)});stringiCache=GL.stringiCache[name]=exts;if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index];default:GL.recordError(1280);return 0}}function _emscripten_glGetSynciv(sync,pname,bufSize,length,values){if(bufSize<0){GL.recordError(1281);return}if(!values){GL.recordError(1281);return}var ret=GLctx.getSyncParameter(GL.syncs[sync],pname);HEAP32[length>>2]=ret;if(ret!==null&&length)HEAP32[length>>2]=1}function _emscripten_glGetTexParameterfv(target,pname,params){if(!params){GL.recordError(1281);return}HEAPF32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTexParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTransformFeedbackVarying(program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx["getTransformFeedbackVarying"](program,index);if(!info)return;if(name&&bufSize>0){var numBytesWrittenExclNull=stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull}else{if(length)HEAP32[length>>2]=0}if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}function _emscripten_glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function _emscripten_glGetUniformIndices(program,uniformCount,uniformNames,uniformIndices){if(!uniformIndices){GL.recordError(1281);return}if(uniformCount>0&&(uniformNames==0||uniformIndices==0)){GL.recordError(1281);return}program=GL.programs[program];var names=[];for(var i=0;i>2]));var result=GLctx["getUniformIndices"](program,names);if(!result)return;var len=result.length;for(var i=0;i>2]=result[i]}}function jstoi_q(str){return parseInt(str)}function _emscripten_glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]=data;break;case 2:HEAPF32[params>>2]=data;break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break}}}}function _emscripten_glGetUniformfv(program,location,params){emscriptenWebGLGetUniform(program,location,params,2)}function _emscripten_glGetUniformiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function _emscripten_glGetUniformuiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function emscriptenWebGLGetVertexAttrib(index,pname,params,type){if(!params){GL.recordError(1281);return}if(GL.currentContext.clientBuffers[index].enabled){err("glGetVertexAttrib*v on client-side array: not supported, bad data returned")}var data=GLctx.getVertexAttrib(index,pname);if(pname==34975){HEAP32[params>>2]=data&&data["name"]}else if(typeof data=="number"||typeof data=="boolean"){switch(type){case 0:HEAP32[params>>2]=data;break;case 2:HEAPF32[params>>2]=data;break;case 5:HEAP32[params>>2]=Math.fround(data);break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break;case 5:HEAP32[params+i*4>>2]=Math.fround(data[i]);break}}}}function _emscripten_glGetVertexAttribIiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,0)}function _emscripten_glGetVertexAttribIuiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,0)}function _emscripten_glGetVertexAttribPointerv(index,pname,pointer){if(!pointer){GL.recordError(1281);return}if(GL.currentContext.clientBuffers[index].enabled){err("glGetVertexAttribPointer on client-side array: not supported, bad data returned")}HEAP32[pointer>>2]=GLctx.getVertexAttribOffset(index,pname)}function _emscripten_glGetVertexAttribfv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,2)}function _emscripten_glGetVertexAttribiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,5)}function _emscripten_glHint(x0,x1){GLctx["hint"](x0,x1)}function _emscripten_glInvalidateFramebuffer(target,numAttachments,attachments){var list=tempFixedLengthArray[numAttachments];for(var i=0;i>2]}GLctx["invalidateFramebuffer"](target,list)}function _emscripten_glInvalidateSubFramebuffer(target,numAttachments,attachments,x,y,width,height){var list=tempFixedLengthArray[numAttachments];for(var i=0;i>2]}GLctx["invalidateSubFramebuffer"](target,list,x,y,width,height)}function _emscripten_glIsBuffer(buffer){var b=GL.buffers[buffer];if(!b)return 0;return GLctx.isBuffer(b)}function _emscripten_glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _emscripten_glIsFramebuffer(framebuffer){var fb=GL.framebuffers[framebuffer];if(!fb)return 0;return GLctx.isFramebuffer(fb)}function _emscripten_glIsProgram(program){program=GL.programs[program];if(!program)return 0;return GLctx.isProgram(program)}function _emscripten_glIsQuery(id){var query=GL.queries[id];if(!query)return 0;return GLctx["isQuery"](query)}function _emscripten_glIsQueryEXT(id){var query=GL.timerQueriesEXT[id];if(!query)return 0;return GLctx.disjointTimerQueryExt["isQueryEXT"](query)}function _emscripten_glIsRenderbuffer(renderbuffer){var rb=GL.renderbuffers[renderbuffer];if(!rb)return 0;return GLctx.isRenderbuffer(rb)}function _emscripten_glIsSampler(id){var sampler=GL.samplers[id];if(!sampler)return 0;return GLctx["isSampler"](sampler)}function _emscripten_glIsShader(shader){var s=GL.shaders[shader];if(!s)return 0;return GLctx.isShader(s)}function _emscripten_glIsSync(sync){return GLctx.isSync(GL.syncs[sync])}function _emscripten_glIsTexture(id){var texture=GL.textures[id];if(!texture)return 0;return GLctx.isTexture(texture)}function _emscripten_glIsTransformFeedback(id){return GLctx["isTransformFeedback"](GL.transformFeedbacks[id])}function _emscripten_glIsVertexArray(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glIsVertexArrayOES(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glLineWidth(x0){GLctx["lineWidth"](x0)}function _emscripten_glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _emscripten_glMapBufferRange(target,offset,length,access){if(access!=26&&access!=10){err("glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER");return 0}if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glMapBufferRange");return 0}var mem=_malloc(length);if(!mem)return 0;GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)]={offset:offset,length:length,mem:mem,access:access};return mem}function _emscripten_glPauseTransformFeedback(){GLctx["pauseTransformFeedback"]()}function _emscripten_glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _emscripten_glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _emscripten_glProgramBinary(program,binaryFormat,binary,length){GL.recordError(1280)}function _emscripten_glProgramParameteri(program,pname,value){GL.recordError(1280)}function _emscripten_glQueryCounterEXT(id,target){GLctx.disjointTimerQueryExt["queryCounterEXT"](GL.timerQueriesEXT[id],target)}function _emscripten_glReadBuffer(x0){GLctx["readBuffer"](x0)}function computeUnpackAlignedImageSize(width,height,sizePerPixel,alignment){function roundedToNextMultipleOf(x,y){return x+y-1&-y}var plainRowSize=width*sizePerPixel;var alignedRowSize=roundedToNextMultipleOf(plainRowSize,alignment);return height*alignedRowSize}function __colorChannelsInGlTextureFormat(format){var colorChannels={5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4};return colorChannels[format-6402]||1}function heapObjectForWebGLType(type){type-=5120;if(type==0)return HEAP8;if(type==1)return HEAPU8;if(type==2)return HEAP16;if(type==4)return HEAP32;if(type==6)return HEAPF32;if(type==5||type==28922||type==28520||type==30779||type==30782)return HEAPU32;return HEAPU16}function heapAccessShiftForWebGLHeap(heap){return 31-Math.clz32(heap.BYTES_PER_ELEMENT)}function emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat){var heap=heapObjectForWebGLType(type);var shift=heapAccessShiftForWebGLHeap(heap);var byteSize=1<>shift,pixels+bytes>>shift)}function _emscripten_glReadPixels(x,y,width,height,format,type,pixels){if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _emscripten_glReleaseShaderCompiler(){}function _emscripten_glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _emscripten_glRenderbufferStorageMultisample(x0,x1,x2,x3,x4){GLctx["renderbufferStorageMultisample"](x0,x1,x2,x3,x4)}function _emscripten_glResumeTransformFeedback(){GLctx["resumeTransformFeedback"]()}function _emscripten_glSampleCoverage(value,invert){GLctx.sampleCoverage(value,!!invert)}function _emscripten_glSamplerParameterf(sampler,pname,param){GLctx["samplerParameterf"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameterfv(sampler,pname,params){var param=HEAPF32[params>>2];GLctx["samplerParameterf"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameteri(sampler,pname,param){GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameteriv(sampler,pname,params){var param=HEAP32[params>>2];GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _emscripten_glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _emscripten_glShaderBinary(){GL.recordError(1280)}function _emscripten_glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _emscripten_glStencilFunc(x0,x1,x2){GLctx["stencilFunc"](x0,x1,x2)}function _emscripten_glStencilFuncSeparate(x0,x1,x2,x3){GLctx["stencilFuncSeparate"](x0,x1,x2,x3)}function _emscripten_glStencilMask(x0){GLctx["stencilMask"](x0)}function _emscripten_glStencilMaskSeparate(x0,x1){GLctx["stencilMaskSeparate"](x0,x1)}function _emscripten_glStencilOp(x0,x1,x2){GLctx["stencilOp"](x0,x1,x2)}function _emscripten_glStencilOpSeparate(x0,x1,x2,x3){GLctx["stencilOpSeparate"](x0,x1,x2,x3)}function _emscripten_glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,null)}return}GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels?emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat):null)}function _emscripten_glTexImage3D(target,level,internalFormat,width,height,depth,border,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,null)}}function _emscripten_glTexParameterf(x0,x1,x2){GLctx["texParameterf"](x0,x1,x2)}function _emscripten_glTexParameterfv(target,pname,params){var param=HEAPF32[params>>2];GLctx.texParameterf(target,pname,param)}function _emscripten_glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _emscripten_glTexParameteriv(target,pname,params){var param=HEAP32[params>>2];GLctx.texParameteri(target,pname,param)}function _emscripten_glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _emscripten_glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _emscripten_glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _emscripten_glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function _emscripten_glTransformFeedbackVaryings(program,count,varyings,bufferMode){program=GL.programs[program];var vars=[];for(var i=0;i>2]));GLctx["transformFeedbackVaryings"](program,vars,bufferMode)}function _emscripten_glUniform1f(location,v0){GLctx.uniform1f(GL.uniforms[location],v0)}function _emscripten_glUniform1fv(location,count,value){GLctx.uniform1fv(GL.uniforms[location],HEAPF32,value>>2,count)}function _emscripten_glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}function _emscripten_glUniform1iv(location,count,value){GLctx.uniform1iv(GL.uniforms[location],HEAP32,value>>2,count)}function _emscripten_glUniform1ui(location,v0){GLctx.uniform1ui(GL.uniforms[location],v0)}function _emscripten_glUniform1uiv(location,count,value){GLctx.uniform1uiv(GL.uniforms[location],HEAPU32,value>>2,count)}function _emscripten_glUniform2f(location,v0,v1){GLctx.uniform2f(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2fv(location,count,value){GLctx.uniform2fv(GL.uniforms[location],HEAPF32,value>>2,count*2)}function _emscripten_glUniform2i(location,v0,v1){GLctx.uniform2i(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2iv(location,count,value){GLctx.uniform2iv(GL.uniforms[location],HEAP32,value>>2,count*2)}function _emscripten_glUniform2ui(location,v0,v1){GLctx.uniform2ui(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2uiv(location,count,value){GLctx.uniform2uiv(GL.uniforms[location],HEAPU32,value>>2,count*2)}function _emscripten_glUniform3f(location,v0,v1,v2){GLctx.uniform3f(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3fv(location,count,value){GLctx.uniform3fv(GL.uniforms[location],HEAPF32,value>>2,count*3)}function _emscripten_glUniform3i(location,v0,v1,v2){GLctx.uniform3i(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3iv(location,count,value){GLctx.uniform3iv(GL.uniforms[location],HEAP32,value>>2,count*3)}function _emscripten_glUniform3ui(location,v0,v1,v2){GLctx.uniform3ui(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3uiv(location,count,value){GLctx.uniform3uiv(GL.uniforms[location],HEAPU32,value>>2,count*3)}function _emscripten_glUniform4f(location,v0,v1,v2,v3){GLctx.uniform4f(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4fv(location,count,value){GLctx.uniform4fv(GL.uniforms[location],HEAPF32,value>>2,count*4)}function _emscripten_glUniform4i(location,v0,v1,v2,v3){GLctx.uniform4i(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4iv(location,count,value){GLctx.uniform4iv(GL.uniforms[location],HEAP32,value>>2,count*4)}function _emscripten_glUniform4ui(location,v0,v1,v2,v3){GLctx.uniform4ui(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4uiv(location,count,value){GLctx.uniform4uiv(GL.uniforms[location],HEAPU32,value>>2,count*4)}function _emscripten_glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _emscripten_glUniformMatrix2fv(location,count,transpose,value){GLctx.uniformMatrix2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*4)}function _emscripten_glUniformMatrix2x3fv(location,count,transpose,value){GLctx.uniformMatrix2x3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*6)}function _emscripten_glUniformMatrix2x4fv(location,count,transpose,value){GLctx.uniformMatrix2x4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*8)}function _emscripten_glUniformMatrix3fv(location,count,transpose,value){GLctx.uniformMatrix3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*9)}function _emscripten_glUniformMatrix3x2fv(location,count,transpose,value){GLctx.uniformMatrix3x2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*6)}function _emscripten_glUniformMatrix3x4fv(location,count,transpose,value){GLctx.uniformMatrix3x4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*12)}function _emscripten_glUniformMatrix4fv(location,count,transpose,value){GLctx.uniformMatrix4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*16)}function _emscripten_glUniformMatrix4x2fv(location,count,transpose,value){GLctx.uniformMatrix4x2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*8)}function _emscripten_glUniformMatrix4x3fv(location,count,transpose,value){GLctx.uniformMatrix4x3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*12)}function _emscripten_glUnmapBuffer(target){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glUnmapBuffer");return 0}var buffer=emscriptenWebGLGetBufferBinding(target);var mapping=GL.mappedBuffers[buffer];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glUnmapBuffer");return 0}GL.mappedBuffers[buffer]=null;if(!(mapping.access&16))if(true){GLctx.bufferSubData(target,mapping.offset,HEAPU8,mapping.mem,mapping.length)}else{GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem,mapping.mem+mapping.length))}_free(mapping.mem);return 1}function _emscripten_glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _emscripten_glValidateProgram(program){GLctx.validateProgram(GL.programs[program])}function _emscripten_glVertexAttrib1f(x0,x1){GLctx["vertexAttrib1f"](x0,x1)}function _emscripten_glVertexAttrib1fv(index,v){GLctx.vertexAttrib1f(index,HEAPF32[v>>2])}function _emscripten_glVertexAttrib2f(x0,x1,x2){GLctx["vertexAttrib2f"](x0,x1,x2)}function _emscripten_glVertexAttrib2fv(index,v){GLctx.vertexAttrib2f(index,HEAPF32[v>>2],HEAPF32[v+4>>2])}function _emscripten_glVertexAttrib3f(x0,x1,x2,x3){GLctx["vertexAttrib3f"](x0,x1,x2,x3)}function _emscripten_glVertexAttrib3fv(index,v){GLctx.vertexAttrib3f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2])}function _emscripten_glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttrib4fv(index,v){GLctx.vertexAttrib4f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2],HEAPF32[v+12>>2])}function _emscripten_glVertexAttribDivisor(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorANGLE(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorARB(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorEXT(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorNV(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribI4i(x0,x1,x2,x3,x4){GLctx["vertexAttribI4i"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttribI4iv(index,v){GLctx.vertexAttribI4i(index,HEAP32[v>>2],HEAP32[v+4>>2],HEAP32[v+8>>2],HEAP32[v+12>>2])}function _emscripten_glVertexAttribI4ui(x0,x1,x2,x3,x4){GLctx["vertexAttribI4ui"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttribI4uiv(index,v){GLctx.vertexAttribI4ui(index,HEAPU32[v>>2],HEAPU32[v+4>>2],HEAPU32[v+8>>2],HEAPU32[v+12>>2])}function _emscripten_glVertexAttribIPointer(index,size,type,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=false;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribIPointer(index,size,type,stride,ptr)};return}cb.clientside=false;GLctx["vertexAttribIPointer"](index,size,type,stride,ptr)}function _emscripten_glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _emscripten_glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _emscripten_glWaitSync(sync,flags,timeoutLo,timeoutHi){GLctx.waitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){try{var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _environ_sizes_get(penviron_count,penviron_buf_size){try{var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];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 _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _getentropy(buffer,size){if(!_getentropy.randomDevice){_getentropy.randomDevice=getRandomDevice()}for(var i=0;i>0]=_getentropy.randomDevice()}return 0}function _glActiveTexture(x0){GLctx["activeTexture"](x0)}function _glAttachShader(program,shader){GLctx.attachShader(GL.programs[program],GL.shaders[shader])}function _glBeginQuery(target,id){GLctx["beginQuery"](target,GL.queries[id])}function _glBindBuffer(target,buffer){if(target==34962){GLctx.currentArrayBufferBinding=buffer}else if(target==34963){GLctx.currentElementArrayBufferBinding=buffer}if(target==35051){GLctx.currentPixelPackBufferBinding=buffer}else if(target==35052){GLctx.currentPixelUnpackBufferBinding=buffer}GLctx.bindBuffer(target,GL.buffers[buffer])}function _glBindBufferRange(target,index,buffer,offset,ptrsize){GLctx["bindBufferRange"](target,index,GL.buffers[buffer],offset,ptrsize)}function _glBindFramebuffer(target,framebuffer){GLctx.bindFramebuffer(target,GL.framebuffers[framebuffer])}function _glBindRenderbuffer(target,renderbuffer){GLctx.bindRenderbuffer(target,GL.renderbuffers[renderbuffer])}function _glBindSampler(unit,sampler){GLctx["bindSampler"](unit,GL.samplers[sampler])}function _glBindTexture(target,texture){GLctx.bindTexture(target,GL.textures[texture])}function _glBindVertexArray(vao){GLctx["bindVertexArray"](GL.vaos[vao]);var ibo=GLctx.getParameter(34965);GLctx.currentElementArrayBufferBinding=ibo?ibo.name|0:0}function _glBlendEquationSeparate(x0,x1){GLctx["blendEquationSeparate"](x0,x1)}function _glBlendFuncSeparate(x0,x1,x2,x3){GLctx["blendFuncSeparate"](x0,x1,x2,x3)}function _glBlitFramebuffer(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9){GLctx["blitFramebuffer"](x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)}function _glBufferData(target,size,data,usage){if(true){if(data){GLctx.bufferData(target,HEAPU8,usage,data,size)}else{GLctx.bufferData(target,size,usage)}}else{GLctx.bufferData(target,data?HEAPU8.subarray(data,data+size):size,usage)}}function _glBufferSubData(target,offset,size,data){if(true){GLctx.bufferSubData(target,offset,HEAPU8,data,size);return}GLctx.bufferSubData(target,offset,HEAPU8.subarray(data,data+size))}function _glClearBufferfi(x0,x1,x2,x3){GLctx["clearBufferfi"](x0,x1,x2,x3)}function _glClearBufferfv(buffer,drawbuffer,value){GLctx["clearBufferfv"](buffer,drawbuffer,HEAPF32,value>>2)}function _glClearBufferiv(buffer,drawbuffer,value){GLctx["clearBufferiv"](buffer,drawbuffer,HEAP32,value>>2)}function _glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,imageSize,data)}else{GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,HEAPU8,data,imageSize)}return}GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _glCompressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data)}else{GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,HEAPU8,data,imageSize)}}function _glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _glCullFace(x0){GLctx["cullFace"](x0)}function _glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _glDeleteQueries(n,ids){for(var i=0;i>2];var query=GL.queries[id];if(!query)continue;GLctx["deleteQuery"](query);GL.queries[id]=null}}function _glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _glDeleteSamplers(n,samplers){for(var i=0;i>2];var sampler=GL.samplers[id];if(!sampler)continue;GLctx["deleteSampler"](sampler);sampler.name=0;GL.samplers[id]=null}}function _glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _glDepthFunc(x0){GLctx["depthFunc"](x0)}function _glDepthMask(flag){GLctx.depthMask(!!flag)}function _glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _glDisable(x0){GLctx["disable"](x0)}function _glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _glDrawRangeElements(mode,start,end,count,type,indices){_glDrawElements(mode,count,type,indices)}function _glEnable(x0){GLctx["enable"](x0)}function _glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _glEndQuery(x0){GLctx["endQuery"](x0)}function _glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _glFinish(){GLctx["finish"]()}function _glFlush(){GLctx["flush"]()}function _glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function _glFrontFace(x0){GLctx["frontFace"](x0)}function _glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _glGenQueries(n,ids){__glGenObject(n,ids,"createQuery",GL.queries)}function _glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _glGenSamplers(n,samplers){__glGenObject(n,samplers,"createSampler",GL.samplers)}function _glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function _glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _glGetQueryObjectuiv(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.queries[id];var param=GLctx["getQueryParameter"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function _glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(true)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _glGetStringi(name,index){if(GL.currentContext.version<2){GL.recordError(1282);return 0}var stringiCache=GL.stringiCache[name];if(stringiCache){if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index]}switch(name){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));exts=exts.map(function(e){return stringToNewUTF8(e)});stringiCache=GL.stringiCache[name]=exts;if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index];default:GL.recordError(1280);return 0}}function _glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function _glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]}GLctx["invalidateFramebuffer"](target,list)}function _glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _glMapBufferRange(target,offset,length,access){if(access!=26&&access!=10){err("glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER");return 0}if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glMapBufferRange");return 0}var mem=_malloc(length);if(!mem)return 0;GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)]={offset:offset,length:length,mem:mem,access:access};return mem}function _glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _glReadPixels(x,y,width,height,format,type,pixels){if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _glRenderbufferStorageMultisample(x0,x1,x2,x3,x4){GLctx["renderbufferStorageMultisample"](x0,x1,x2,x3,x4)}function _glSamplerParameteri(sampler,pname,param){GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function _glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}function _glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _glUnmapBuffer(target){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glUnmapBuffer");return 0}var buffer=emscriptenWebGLGetBufferBinding(target);var mapping=GL.mappedBuffers[buffer];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glUnmapBuffer");return 0}GL.mappedBuffers[buffer]=null;if(!(mapping.access&16))if(true){GLctx.bufferSubData(target,mapping.offset,HEAPU8,mapping.mem,mapping.length)}else{GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem,mapping.mem+mapping.length))}_free(mapping.mem);return 1}function _glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _glVertexAttribI4ui(x0,x1,x2,x3,x4){GLctx["vertexAttribI4ui"](x0,x1,x2,x3,x4)}function _glVertexAttribIPointer(index,size,type,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=false;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribIPointer(index,size,type,stride,ptr)};return}cb.clientside=false;GLctx["vertexAttribIPointer"](index,size,type,stride,ptr)}function _glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _glWaitSync(sync,flags,timeoutLo,timeoutHi){GLctx.waitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _pthread_create(){return 6}function _pthread_join(){return 28}function _setTempRet0($i){setTempRet0($i|0)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.indexOf(rule)>=0){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm){return _strftime(s,maxsize,format,tm)}function _sysconf(name){switch(name){case 30:return 16384;case 85:var maxHeapSize=2147483648;return maxHeapSize/16384;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:case 80:case 81:case 79:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}setErrNo(28);return-1}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){var double=ch<105;if(double&&buf&1)buf++;readAsmConstArgsArray.push(double?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var GLctx;for(var i=0;i<32;++i)tempFixedLengthArray.push(new Array(i));function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var asmLibraryArg={"Ha":___sys_fcntl64,"Dg":___sys_ioctl,"Eg":___sys_open,"v":__embind_finalize_value_array,"z":__embind_finalize_value_object,"Hg":__embind_register_bool,"d":__embind_register_class,"n":__embind_register_class_class_function,"m":__embind_register_class_constructor,"a":__embind_register_class_function,"u":__embind_register_class_property,"Gg":__embind_register_emval,"i":__embind_register_enum,"b":__embind_register_enum_value,"Ja":__embind_register_float,"La":__embind_register_function,"D":__embind_register_integer,"x":__embind_register_memory_view,"Ka":__embind_register_std_string,"ja":__embind_register_std_wstring,"w":__embind_register_value_array,"f":__embind_register_value_array_element,"A":__embind_register_value_object,"e":__embind_register_value_object_field,"Ig":__embind_register_void,"q":__emval_as,"g":__emval_decref,"r":__emval_get_property,"ha":__emval_incref,"G":__emval_new_cstring,"p":__emval_run_destructors,"s":__emval_take_value,"c":_abort,"wg":_clock_gettime,"Ga":_emscripten_asm_const_int,"ag":_emscripten_glActiveTexture,"$f":_emscripten_glAttachShader,"cd":_emscripten_glBeginQuery,"qg":_emscripten_glBeginQueryEXT,"Gc":_emscripten_glBeginTransformFeedback,"_f":_emscripten_glBindAttribLocation,"Zf":_emscripten_glBindBuffer,"Dc":_emscripten_glBindBufferBase,"Ec":_emscripten_glBindBufferRange,"Yf":_emscripten_glBindFramebuffer,"Xf":_emscripten_glBindRenderbuffer,"Kb":_emscripten_glBindSampler,"Wf":_emscripten_glBindTexture,"Cb":_emscripten_glBindTransformFeedback,"Lc":_emscripten_glBindVertexArray,"ig":_emscripten_glBindVertexArrayOES,"Vf":_emscripten_glBlendColor,"Uf":_emscripten_glBlendEquation,"Tf":_emscripten_glBlendEquationSeparate,"Sf":_emscripten_glBlendFunc,"Rf":_emscripten_glBlendFuncSeparate,"Rc":_emscripten_glBlitFramebuffer,"Qf":_emscripten_glBufferData,"Pf":_emscripten_glBufferSubData,"Of":_emscripten_glCheckFramebufferStatus,"Nf":_emscripten_glClear,"gc":_emscripten_glClearBufferfi,"hc":_emscripten_glClearBufferfv,"jc":_emscripten_glClearBufferiv,"ic":_emscripten_glClearBufferuiv,"Mf":_emscripten_glClearColor,"Lf":_emscripten_glClearDepthf,"Kf":_emscripten_glClearStencil,"Ub":_emscripten_glClientWaitSync,"Jf":_emscripten_glColorMask,"If":_emscripten_glCompileShader,"Hf":_emscripten_glCompressedTexImage2D,"hd":_emscripten_glCompressedTexImage3D,"Gf":_emscripten_glCompressedTexSubImage2D,"gd":_emscripten_glCompressedTexSubImage3D,"ec":_emscripten_glCopyBufferSubData,"Ff":_emscripten_glCopyTexImage2D,"Ef":_emscripten_glCopyTexSubImage2D,"jd":_emscripten_glCopyTexSubImage3D,"Df":_emscripten_glCreateProgram,"Cf":_emscripten_glCreateShader,"Bf":_emscripten_glCullFace,"Af":_emscripten_glDeleteBuffers,"zf":_emscripten_glDeleteFramebuffers,"yf":_emscripten_glDeleteProgram,"ed":_emscripten_glDeleteQueries,"sg":_emscripten_glDeleteQueriesEXT,"xf":_emscripten_glDeleteRenderbuffers,"Mb":_emscripten_glDeleteSamplers,"wf":_emscripten_glDeleteShader,"Vb":_emscripten_glDeleteSync,"vf":_emscripten_glDeleteTextures,"Bb":_emscripten_glDeleteTransformFeedbacks,"Kc":_emscripten_glDeleteVertexArrays,"hg":_emscripten_glDeleteVertexArraysOES,"uf":_emscripten_glDepthFunc,"tf":_emscripten_glDepthMask,"sf":_emscripten_glDepthRangef,"rf":_emscripten_glDetachShader,"qf":_emscripten_glDisable,"pf":_emscripten_glDisableVertexAttribArray,"of":_emscripten_glDrawArrays,"Zb":_emscripten_glDrawArraysInstanced,"dg":_emscripten_glDrawArraysInstancedANGLE,"lb":_emscripten_glDrawArraysInstancedARB,"qd":_emscripten_glDrawArraysInstancedEXT,"mb":_emscripten_glDrawArraysInstancedNV,"Yc":_emscripten_glDrawBuffers,"od":_emscripten_glDrawBuffersEXT,"eg":_emscripten_glDrawBuffersWEBGL,"nf":_emscripten_glDrawElements,"Yb":_emscripten_glDrawElementsInstanced,"cg":_emscripten_glDrawElementsInstancedANGLE,"jb":_emscripten_glDrawElementsInstancedARB,"kb":_emscripten_glDrawElementsInstancedEXT,"pd":_emscripten_glDrawElementsInstancedNV,"md":_emscripten_glDrawRangeElements,"mf":_emscripten_glEnable,"lf":_emscripten_glEnableVertexAttribArray,"bd":_emscripten_glEndQuery,"pg":_emscripten_glEndQueryEXT,"Fc":_emscripten_glEndTransformFeedback,"Xb":_emscripten_glFenceSync,"kf":_emscripten_glFinish,"jf":_emscripten_glFlush,"Mc":_emscripten_glFlushMappedBufferRange,"hf":_emscripten_glFramebufferRenderbuffer,"gf":_emscripten_glFramebufferTexture2D,"Oc":_emscripten_glFramebufferTextureLayer,"ff":_emscripten_glFrontFace,"ef":_emscripten_glGenBuffers,"cf":_emscripten_glGenFramebuffers,"fd":_emscripten_glGenQueries,"tg":_emscripten_glGenQueriesEXT,"bf":_emscripten_glGenRenderbuffers,"Nb":_emscripten_glGenSamplers,"af":_emscripten_glGenTextures,"Ab":_emscripten_glGenTransformFeedbacks,"Jc":_emscripten_glGenVertexArrays,"gg":_emscripten_glGenVertexArraysOES,"df":_emscripten_glGenerateMipmap,"$e":_emscripten_glGetActiveAttrib,"_e":_emscripten_glGetActiveUniform,"$b":_emscripten_glGetActiveUniformBlockName,"ac":_emscripten_glGetActiveUniformBlockiv,"cc":_emscripten_glGetActiveUniformsiv,"Ze":_emscripten_glGetAttachedShaders,"Ye":_emscripten_glGetAttribLocation,"Xe":_emscripten_glGetBooleanv,"Ob":_emscripten_glGetBufferParameteri64v,"We":_emscripten_glGetBufferParameteriv,"Zc":_emscripten_glGetBufferPointerv,"Ve":_emscripten_glGetError,"Ue":_emscripten_glGetFloatv,"sc":_emscripten_glGetFragDataLocation,"Te":_emscripten_glGetFramebufferAttachmentParameteriv,"Pb":_emscripten_glGetInteger64i_v,"Rb":_emscripten_glGetInteger64v,"Hc":_emscripten_glGetIntegeri_v,"Se":_emscripten_glGetIntegerv,"pb":_emscripten_glGetInternalformativ,"wb":_emscripten_glGetProgramBinary,"Qe":_emscripten_glGetProgramInfoLog,"Re":_emscripten_glGetProgramiv,"kg":_emscripten_glGetQueryObjecti64vEXT,"mg":_emscripten_glGetQueryObjectivEXT,"jg":_emscripten_glGetQueryObjectui64vEXT,"$c":_emscripten_glGetQueryObjectuiv,"lg":_emscripten_glGetQueryObjectuivEXT,"ad":_emscripten_glGetQueryiv,"ng":_emscripten_glGetQueryivEXT,"Pe":_emscripten_glGetRenderbufferParameteriv,"Eb":_emscripten_glGetSamplerParameterfv,"Fb":_emscripten_glGetSamplerParameteriv,"Ne":_emscripten_glGetShaderInfoLog,"Me":_emscripten_glGetShaderPrecisionFormat,"Le":_emscripten_glGetShaderSource,"Oe":_emscripten_glGetShaderiv,"Ke":_emscripten_glGetString,"fc":_emscripten_glGetStringi,"Qb":_emscripten_glGetSynciv,"Je":_emscripten_glGetTexParameterfv,"Ie":_emscripten_glGetTexParameteriv,"Bc":_emscripten_glGetTransformFeedbackVarying,"bc":_emscripten_glGetUniformBlockIndex,"dc":_emscripten_glGetUniformIndices,"Fe":_emscripten_glGetUniformLocation,"He":_emscripten_glGetUniformfv,"Ge":_emscripten_glGetUniformiv,"tc":_emscripten_glGetUniformuiv,"zc":_emscripten_glGetVertexAttribIiv,"yc":_emscripten_glGetVertexAttribIuiv,"Ce":_emscripten_glGetVertexAttribPointerv,"Ee":_emscripten_glGetVertexAttribfv,"De":_emscripten_glGetVertexAttribiv,"Be":_emscripten_glHint,"tb":_emscripten_glInvalidateFramebuffer,"sb":_emscripten_glInvalidateSubFramebuffer,"Ae":_emscripten_glIsBuffer,"ze":_emscripten_glIsEnabled,"ye":_emscripten_glIsFramebuffer,"xe":_emscripten_glIsProgram,"dd":_emscripten_glIsQuery,"rg":_emscripten_glIsQueryEXT,"we":_emscripten_glIsRenderbuffer,"Lb":_emscripten_glIsSampler,"ve":_emscripten_glIsShader,"Wb":_emscripten_glIsSync,"ue":_emscripten_glIsTexture,"zb":_emscripten_glIsTransformFeedback,"Ic":_emscripten_glIsVertexArray,"fg":_emscripten_glIsVertexArrayOES,"te":_emscripten_glLineWidth,"se":_emscripten_glLinkProgram,"Nc":_emscripten_glMapBufferRange,"yb":_emscripten_glPauseTransformFeedback,"re":_emscripten_glPixelStorei,"qe":_emscripten_glPolygonOffset,"vb":_emscripten_glProgramBinary,"ub":_emscripten_glProgramParameteri,"og":_emscripten_glQueryCounterEXT,"nd":_emscripten_glReadBuffer,"pe":_emscripten_glReadPixels,"oe":_emscripten_glReleaseShaderCompiler,"ne":_emscripten_glRenderbufferStorage,"Qc":_emscripten_glRenderbufferStorageMultisample,"xb":_emscripten_glResumeTransformFeedback,"me":_emscripten_glSampleCoverage,"Hb":_emscripten_glSamplerParameterf,"Gb":_emscripten_glSamplerParameterfv,"Jb":_emscripten_glSamplerParameteri,"Ib":_emscripten_glSamplerParameteriv,"le":_emscripten_glScissor,"ke":_emscripten_glShaderBinary,"je":_emscripten_glShaderSource,"ie":_emscripten_glStencilFunc,"he":_emscripten_glStencilFuncSeparate,"ge":_emscripten_glStencilMask,"fe":_emscripten_glStencilMaskSeparate,"ee":_emscripten_glStencilOp,"de":_emscripten_glStencilOpSeparate,"ce":_emscripten_glTexImage2D,"ld":_emscripten_glTexImage3D,"be":_emscripten_glTexParameterf,"ae":_emscripten_glTexParameterfv,"$d":_emscripten_glTexParameteri,"_d":_emscripten_glTexParameteriv,"rb":_emscripten_glTexStorage2D,"qb":_emscripten_glTexStorage3D,"Zd":_emscripten_glTexSubImage2D,"kd":_emscripten_glTexSubImage3D,"Cc":_emscripten_glTransformFeedbackVaryings,"Yd":_emscripten_glUniform1f,"Xd":_emscripten_glUniform1fv,"Wd":_emscripten_glUniform1i,"Vd":_emscripten_glUniform1iv,"rc":_emscripten_glUniform1ui,"nc":_emscripten_glUniform1uiv,"Ud":_emscripten_glUniform2f,"Td":_emscripten_glUniform2fv,"Sd":_emscripten_glUniform2i,"Rd":_emscripten_glUniform2iv,"qc":_emscripten_glUniform2ui,"mc":_emscripten_glUniform2uiv,"Qd":_emscripten_glUniform3f,"Pd":_emscripten_glUniform3fv,"Nd":_emscripten_glUniform3i,"Md":_emscripten_glUniform3iv,"pc":_emscripten_glUniform3ui,"lc":_emscripten_glUniform3uiv,"Ld":_emscripten_glUniform4f,"Kd":_emscripten_glUniform4fv,"Jd":_emscripten_glUniform4i,"Id":_emscripten_glUniform4iv,"oc":_emscripten_glUniform4ui,"kc":_emscripten_glUniform4uiv,"_b":_emscripten_glUniformBlockBinding,"Hd":_emscripten_glUniformMatrix2fv,"Xc":_emscripten_glUniformMatrix2x3fv,"Vc":_emscripten_glUniformMatrix2x4fv,"Gd":_emscripten_glUniformMatrix3fv,"Wc":_emscripten_glUniformMatrix3x2fv,"Tc":_emscripten_glUniformMatrix3x4fv,"Fd":_emscripten_glUniformMatrix4fv,"Uc":_emscripten_glUniformMatrix4x2fv,"Sc":_emscripten_glUniformMatrix4x3fv,"_c":_emscripten_glUnmapBuffer,"Ed":_emscripten_glUseProgram,"Dd":_emscripten_glValidateProgram,"Cd":_emscripten_glVertexAttrib1f,"Bd":_emscripten_glVertexAttrib1fv,"Ad":_emscripten_glVertexAttrib2f,"zd":_emscripten_glVertexAttrib2fv,"yd":_emscripten_glVertexAttrib3f,"xd":_emscripten_glVertexAttrib3fv,"wd":_emscripten_glVertexAttrib4f,"vd":_emscripten_glVertexAttrib4fv,"Db":_emscripten_glVertexAttribDivisor,"bg":_emscripten_glVertexAttribDivisorANGLE,"nb":_emscripten_glVertexAttribDivisorARB,"rd":_emscripten_glVertexAttribDivisorEXT,"ob":_emscripten_glVertexAttribDivisorNV,"xc":_emscripten_glVertexAttribI4i,"vc":_emscripten_glVertexAttribI4iv,"wc":_emscripten_glVertexAttribI4ui,"uc":_emscripten_glVertexAttribI4uiv,"Ac":_emscripten_glVertexAttribIPointer,"ud":_emscripten_glVertexAttribPointer,"sd":_emscripten_glViewport,"Tb":_emscripten_glWaitSync,"ug":_emscripten_memcpy_big,"vg":_emscripten_resize_heap,"zg":_environ_get,"Ag":_environ_sizes_get,"ia":_fd_close,"Fg":_fd_read,"gb":_fd_seek,"Ia":_fd_write,"xg":_getentropy,"h":_glActiveTexture,"T":_glAttachShader,"Xg":_glBeginQuery,"C":_glBindBuffer,"ra":_glBindBufferRange,"l":_glBindFramebuffer,"H":_glBindRenderbuffer,"U":_glBindSampler,"k":_glBindTexture,"N":_glBindVertexArray,"Tg":_glBlendEquationSeparate,"Sg":_glBlendFuncSeparate,"pa":_glBlitFramebuffer,"M":_glBufferData,"Y":_glBufferSubData,"Mg":_glClearBufferfi,"O":_glClearBufferfv,"Lg":_glClearBufferiv,"hb":_glClientWaitSync,"la":_glColorMask,"ba":_glCompileShader,"Na":_glCompressedTexSubImage2D,"Ma":_glCompressedTexSubImage3D,"Aa":_glCreateProgram,"da":_glCreateShader,"ka":_glCullFace,"Ca":_glDeleteBuffers,"S":_glDeleteFramebuffers,"$":_glDeleteProgram,"$a":_glDeleteQueries,"E":_glDeleteRenderbuffers,"na":_glDeleteSamplers,"L":_glDeleteShader,"F":_glDeleteSync,"J":_glDeleteTextures,"Sb":_glDeleteVertexArrays,"Rg":_glDepthFunc,"Qg":_glDepthMask,"Za":_glDepthRangef,"_":_glDetachShader,"j":_glDisable,"sa":_glDisableVertexAttribArray,"Ra":_glDrawArrays,"Ta":_glDrawBuffers,"Ua":_glDrawRangeElements,"B":_glEnable,"ta":_glEnableVertexAttribArray,"Wg":_glEndQuery,"Z":_glFenceSync,"Da":_glFinish,"Ea":_glFlush,"P":_glFramebufferRenderbuffer,"Q":_glFramebufferTexture2D,"Qa":_glFramebufferTextureLayer,"Ug":_glFrontFace,"W":_glGenBuffers,"R":_glGenFramebuffers,"ab":_glGenQueries,"ga":_glGenRenderbuffers,"oa":_glGenSamplers,"I":_glGenTextures,"fb":_glGenVertexArrays,"_a":_glGenerateMipmap,"Sa":_glGetError,"td":_glGetFloatv,"o":_glGetIntegerv,"cb":_glGetProgramInfoLog,"ya":_glGetProgramiv,"Vg":_glGetQueryObjectuiv,"bb":_glGetShaderInfoLog,"aa":_glGetShaderiv,"V":_glGetString,"Od":_glGetStringi,"eb":_glGetUniformBlockIndex,"xa":_glGetUniformLocation,"Yg":_glGetVertexAttribiv,"id":_glHint,"va":_glInvalidateFramebuffer,"ma":_glIsEnabled,"za":_glLinkProgram,"Kg":_glMapBufferRange,"Pc":_glPixelStorei,"Va":_glPolygonOffset,"qa":_glReadPixels,"ea":_glRenderbufferStorage,"fa":_glRenderbufferStorageMultisample,"t":_glSamplerParameteri,"Ng":_glScissor,"ca":_glShaderSource,"y":_glTexParameteri,"Pg":_glTexStorage2D,"Og":_glTexStorage3D,"Pa":_glTexSubImage2D,"Oa":_glTexSubImage3D,"wa":_glUniform1i,"db":_glUniformBlockBinding,"Jg":_glUnmapBuffer,"K":_glUseProgram,"Wa":_glVertexAttrib4f,"Xa":_glVertexAttribI4ui,"Ya":_glVertexAttribIPointer,"ua":_glVertexAttribPointer,"X":_glViewport,"ib":_glWaitSync,"Fa":_pthread_create,"Cg":_pthread_join,"Ba":_setTempRet0,"yg":_strftime_l,"Bg":_sysconf};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["$g"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["ah"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["bh"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["ch"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["dh"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["eh"]).apply(null,arguments)};var dynCall_viijii=Module["dynCall_viijii"]=function(){return(dynCall_viijii=Module["dynCall_viijii"]=Module["asm"]["fh"]).apply(null,arguments)};var dynCall_jii=Module["dynCall_jii"]=function(){return(dynCall_jii=Module["dynCall_jii"]=Module["asm"]["gh"]).apply(null,arguments)};var dynCall_iiij=Module["dynCall_iiij"]=function(){return(dynCall_iiij=Module["dynCall_iiij"]=Module["asm"]["hh"]).apply(null,arguments)};var dynCall_vij=Module["dynCall_vij"]=function(){return(dynCall_vij=Module["dynCall_vij"]=Module["asm"]["ih"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["jh"]).apply(null,arguments)};var dynCall_iiiiij=Module["dynCall_iiiiij"]=function(){return(dynCall_iiiiij=Module["dynCall_iiiiij"]=Module["asm"]["kh"]).apply(null,arguments)};var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=function(){return(dynCall_iiiiijj=Module["dynCall_iiiiijj"]=Module["asm"]["lh"]).apply(null,arguments)};var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=function(){return(dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=Module["asm"]["mh"]).apply(null,arguments)};var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); +var Module=typeof Filament!=="undefined"?Filament:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[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(Module["locateFile"]){return Module["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{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(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);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}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"){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(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;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>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=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=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"):undefined;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 str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>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===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=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=55296&&codeUnit<=57343)++i;len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}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 updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;__ATINIT__.push({func:function(){___wasm_call_ctors()}});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;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;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 addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}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"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}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://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="filament.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){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(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["Zg"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["_g"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var tempDouble;var tempI64;var ASM_CONSTS={10272:function(){const handle=GL.registerContext(Filament.glContext,Filament.glOptions);GL.makeContextCurrent(handle)}};function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){var alignedSize=alignMemory(size,16384);var ptr=_malloc(alignedSize);while(size=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){FS.forceLoadFile(node);var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=varargs?SYSCALLS.get():0;var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var tupleRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}return Module["dynCall_"+sig].call(null,ptr)}function dynCall(sig,ptr,args){if(sig.indexOf("j")!=-1){return dynCallLegacy(sig,ptr,args)}return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){assert(sig.indexOf("j")>=0,"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i>2)+i])}return array}function __embind_register_class_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,fn){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.constructor;if(undefined===proto[methodName]){unboundTypesHandler.argCount=argCount-1;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-1]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));var func=craftInvokerFunction(humanName,invokerArgsArray,null,rawInvoker,fn);if(undefined===proto[methodName].overloadTable){func.argCount=argCount-1;proto[methodName]=func}else{proto[methodName].overloadTable[argCount-1]=func}return[]});return[]})}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>1])};case 2:return function(pointer){var heap=signed?HEAP32:HEAPU32;return this["fromWireType"](heap[pointer>>2])};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_enum(rawType,name,size,isSigned){var shift=getShiftFromSize(size);name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":function(destructors,c){return c.value},"argPackAdvance":8,"readValueFromPointer":enumReadValueFromPointer(name,shift,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __embind_register_enum_value(rawEnumType,name,enumValue){var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(enumType.name+"_"+name,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_array(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){tupleRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),elements:[]}}function __embind_register_value_array_element(rawTupleType,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){tupleRegistrations[rawTupleType].elements.push({getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireHandle(handle){if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value}function __emval_as(handle,returnType,destructorsRef){handle=requireHandle(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=__emval_register(destructors);HEAP32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}function __emval_get_property(handle,key){handle=requireHandle(handle);key=requireHandle(key);return __emval_register(handle[key])}function __emval_incref(handle){if(handle>4){emval_handle_array[handle].refcount+=1}}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function __emval_take_value(type,argv){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](argv);return __emval_register(v)}function _abort(){abort()}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else if(typeof dateNow!=="undefined"){_emscripten_get_now=dateNow}else _emscripten_get_now=function(){return performance.now()};var _emscripten_get_now_is_monotonic=true;function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if((clk_id===1||clk_id===4)&&_emscripten_get_now_is_monotonic){now=_emscripten_get_now()}else{setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}function __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(ctx){return!!(ctx.dibvbi=ctx.getExtension("WEBGL_draw_instanced_base_vertex_base_instance"))}function __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(ctx){return!!(ctx.mdibvbi=ctx.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance"))}function __webgl_enable_WEBGL_multi_draw(ctx){return!!(ctx.multiDrawWebgl=ctx.getExtension("WEBGL_multi_draw"))}var GL={counter:1,buffers:[],mappedBuffers:{},programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},timerQueriesEXT:[],queries:[],samplers:[],transformFeedbacks:[],syncs:[],byteSizeByTypeRoot:5120,byteSizeByType:[1,1,2,2,4,4,4,2,3,4,8],programInfos:{},stringCache:{},stringiCache:{},unpackAlignment:4,recordError:function recordError(errorCode){if(!GL.lastError){GL.lastError=errorCode}},getNewId:function(table){var ret=GL.counter++;for(var i=table.length;i>1;var quadIndexes=new Uint16Array(numIndexes);var i=0,v=0;while(1){quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+1;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v+3;if(i>=numIndexes)break;v+=4}context.GLctx.bufferData(34963,quadIndexes,35044);context.GLctx.bindBuffer(34963,null)}},getTempVertexBuffer:function getTempVertexBuffer(sizeBytes){var idx=GL.log2ceilLookup(sizeBytes);var ringbuffer=GL.currentContext.tempVertexBuffers1[idx];var nextFreeBufferIndex=GL.currentContext.tempVertexBufferCounters1[idx];GL.currentContext.tempVertexBufferCounters1[idx]=GL.currentContext.tempVertexBufferCounters1[idx]+1&GL.numTempVertexBuffersPerSize-1;var vbo=ringbuffer[nextFreeBufferIndex];if(vbo){return vbo}var prevVBO=GLctx.getParameter(34964);ringbuffer[nextFreeBufferIndex]=GLctx.createBuffer();GLctx.bindBuffer(34962,ringbuffer[nextFreeBufferIndex]);GLctx.bufferData(34962,1<>2]:-1;source+=UTF8ToString(HEAP32[string+i*4>>2],len<0?undefined:len)}return source},calcBufLength:function calcBufLength(size,type,stride,count){if(stride>0){return count*stride}var typeSize=GL.byteSizeByType[type-GL.byteSizeByTypeRoot];return size*typeSize*count},usedTempBuffers:[],preDrawHandleClientVertexAttribBindings:function preDrawHandleClientVertexAttribBindings(count){GL.resetBufferBinding=false;for(var i=0;i>2)}function _emscripten_glClearBufferiv(buffer,drawbuffer,value){GLctx["clearBufferiv"](buffer,drawbuffer,HEAP32,value>>2)}function _emscripten_glClearBufferuiv(buffer,drawbuffer,value){GLctx["clearBufferuiv"](buffer,drawbuffer,HEAPU32,value>>2)}function _emscripten_glClearColor(x0,x1,x2,x3){GLctx["clearColor"](x0,x1,x2,x3)}function _emscripten_glClearDepthf(x0){GLctx["clearDepth"](x0)}function _emscripten_glClearStencil(x0){GLctx["clearStencil"](x0)}function convertI32PairToI53(lo,hi){return(lo>>>0)+hi*4294967296}function _emscripten_glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _emscripten_glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _emscripten_glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _emscripten_glCompressedTexImage2D(target,level,internalFormat,width,height,border,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,imageSize,data)}else{GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,HEAPU8,data,imageSize)}return}GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexImage3D(target,level,internalFormat,width,height,depth,border,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexImage3D"](target,level,internalFormat,width,height,depth,border,imageSize,data)}else{GLctx["compressedTexImage3D"](target,level,internalFormat,width,height,depth,border,HEAPU8,data,imageSize)}}function _emscripten_glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,imageSize,data)}else{GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,HEAPU8,data,imageSize)}return}GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data)}else{GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,HEAPU8,data,imageSize)}}function _emscripten_glCopyBufferSubData(x0,x1,x2,x3,x4){GLctx["copyBufferSubData"](x0,x1,x2,x3,x4)}function _emscripten_glCopyTexImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexSubImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage3D(x0,x1,x2,x3,x4,x5,x6,x7,x8){GLctx["copyTexSubImage3D"](x0,x1,x2,x3,x4,x5,x6,x7,x8)}function _emscripten_glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _emscripten_glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _emscripten_glCullFace(x0){GLctx["cullFace"](x0)}function _emscripten_glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _emscripten_glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _emscripten_glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _emscripten_glDeleteQueries(n,ids){for(var i=0;i>2];var query=GL.queries[id];if(!query)continue;GLctx["deleteQuery"](query);GL.queries[id]=null}}function _emscripten_glDeleteQueriesEXT(n,ids){for(var i=0;i>2];var query=GL.timerQueriesEXT[id];if(!query)continue;GLctx.disjointTimerQueryExt["deleteQueryEXT"](query);GL.timerQueriesEXT[id]=null}}function _emscripten_glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _emscripten_glDeleteSamplers(n,samplers){for(var i=0;i>2];var sampler=GL.samplers[id];if(!sampler)continue;GLctx["deleteSampler"](sampler);sampler.name=0;GL.samplers[id]=null}}function _emscripten_glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _emscripten_glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _emscripten_glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _emscripten_glDeleteTransformFeedbacks(n,ids){for(var i=0;i>2];var transformFeedback=GL.transformFeedbacks[id];if(!transformFeedback)continue;GLctx["deleteTransformFeedback"](transformFeedback);transformFeedback.name=0;GL.transformFeedbacks[id]=null}}function _emscripten_glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDeleteVertexArraysOES(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDepthFunc(x0){GLctx["depthFunc"](x0)}function _emscripten_glDepthMask(flag){GLctx.depthMask(!!flag)}function _emscripten_glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _emscripten_glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _emscripten_glDisable(x0){GLctx["disable"](x0)}function _emscripten_glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _emscripten_glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _emscripten_glDrawArraysInstanced(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedANGLE(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedARB(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedEXT(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedNV(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}var tempFixedLengthArray=[];function _emscripten_glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawBuffersEXT(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawBuffersWEBGL(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawElements(mode,count,type,indices){var buf;if(!GLctx.currentElementArrayBufferBinding){var size=GL.calcBufLength(1,type,0,count);buf=GL.getTempIndexBuffer(size);GLctx.bindBuffer(34963,buf);GLctx.bufferSubData(34963,0,HEAPU8.subarray(indices,indices+size));indices=0}GL.preDrawHandleClientVertexAttribBindings(count);GLctx.drawElements(mode,count,type,indices);GL.postDrawHandleClientVertexAttribBindings(count);if(!GLctx.currentElementArrayBufferBinding){GLctx.bindBuffer(34963,null)}}function _emscripten_glDrawElementsInstanced(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedANGLE(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedARB(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedEXT(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedNV(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _glDrawElements(mode,count,type,indices){var buf;if(!GLctx.currentElementArrayBufferBinding){var size=GL.calcBufLength(1,type,0,count);buf=GL.getTempIndexBuffer(size);GLctx.bindBuffer(34963,buf);GLctx.bufferSubData(34963,0,HEAPU8.subarray(indices,indices+size));indices=0}GL.preDrawHandleClientVertexAttribBindings(count);GLctx.drawElements(mode,count,type,indices);GL.postDrawHandleClientVertexAttribBindings(count);if(!GLctx.currentElementArrayBufferBinding){GLctx.bindBuffer(34963,null)}}function _emscripten_glDrawRangeElements(mode,start,end,count,type,indices){_glDrawElements(mode,count,type,indices)}function _emscripten_glEnable(x0){GLctx["enable"](x0)}function _emscripten_glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _emscripten_glEndQuery(x0){GLctx["endQuery"](x0)}function _emscripten_glEndQueryEXT(target){GLctx.disjointTimerQueryExt["endQueryEXT"](target)}function _emscripten_glEndTransformFeedback(){GLctx["endTransformFeedback"]()}function _emscripten_glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _emscripten_glFinish(){GLctx["finish"]()}function _emscripten_glFlush(){GLctx["flush"]()}function emscriptenWebGLGetBufferBinding(target){switch(target){case 34962:target=34964;break;case 34963:target=34965;break;case 35051:target=35053;break;case 35052:target=35055;break;case 35982:target=35983;break;case 36662:target=36662;break;case 36663:target=36663;break;case 35345:target=35368;break}var buffer=GLctx.getParameter(target);if(buffer)return buffer.name|0;else return 0}function emscriptenWebGLValidateMapBufferTarget(target){switch(target){case 34962:case 34963:case 36662:case 36663:case 35051:case 35052:case 35882:case 35982:case 35345:return true;default:return false}}function _emscripten_glFlushMappedBufferRange(target,offset,length){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glFlushMappedBufferRange");return}var mapping=GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glFlushMappedBufferRange");return}if(!(mapping.access&16)){GL.recordError(1282);err("buffer was not mapped with GL_MAP_FLUSH_EXPLICIT_BIT in glFlushMappedBufferRange");return}if(offset<0||length<0||offset+length>mapping.length){GL.recordError(1281);err("invalid range in glFlushMappedBufferRange");return}GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem+offset,mapping.mem+offset+length))}function _emscripten_glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _emscripten_glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _emscripten_glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function _emscripten_glFrontFace(x0){GLctx["frontFace"](x0)}function __glGenObject(n,buffers,createFunction,objectTable){for(var i=0;i>2]=id}}function _emscripten_glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _emscripten_glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _emscripten_glGenQueries(n,ids){__glGenObject(n,ids,"createQuery",GL.queries)}function _emscripten_glGenQueriesEXT(n,ids){for(var i=0;i>2]=0;return}var id=GL.getNewId(GL.timerQueriesEXT);query.name=id;GL.timerQueriesEXT[id]=query;HEAP32[ids+i*4>>2]=id}}function _emscripten_glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _emscripten_glGenSamplers(n,samplers){__glGenObject(n,samplers,"createSampler",GL.samplers)}function _emscripten_glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _emscripten_glGenTransformFeedbacks(n,ids){__glGenObject(n,ids,"createTransformFeedback",GL.transformFeedbacks)}function _emscripten_glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenVertexArraysOES(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function __glGetActiveAttribOrUniform(funcName,program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx[funcName](program,index);if(info){var numBytesWrittenExclNull=name&&stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull;if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}}function _emscripten_glGetActiveAttrib(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveAttrib",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniform(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveUniform",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniformBlockName(program,uniformBlockIndex,bufSize,length,uniformBlockName){program=GL.programs[program];var result=GLctx["getActiveUniformBlockName"](program,uniformBlockIndex);if(!result)return;if(uniformBlockName&&bufSize>0){var numBytesWrittenExclNull=stringToUTF8(result,uniformBlockName,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull}else{if(length)HEAP32[length>>2]=0}}function _emscripten_glGetActiveUniformBlockiv(program,uniformBlockIndex,pname,params){if(!params){GL.recordError(1281);return}program=GL.programs[program];switch(pname){case 35393:var name=GLctx["getActiveUniformBlockName"](program,uniformBlockIndex);HEAP32[params>>2]=name.length+1;return;default:var result=GLctx["getActiveUniformBlockParameter"](program,uniformBlockIndex,pname);if(!result)return;if(typeof result=="number"){HEAP32[params>>2]=result}else{for(var i=0;i>2]=result[i]}}}}function _emscripten_glGetActiveUniformsiv(program,uniformCount,uniformIndices,pname,params){if(!params){GL.recordError(1281);return}if(uniformCount>0&&uniformIndices==0){GL.recordError(1281);return}program=GL.programs[program];var ids=[];for(var i=0;i>2])}var result=GLctx["getActiveUniforms"](program,ids,pname);if(!result)return;var len=result.length;for(var i=0;i>2]=result[i]}}function _emscripten_glGetAttachedShaders(program,maxCount,count,shaders){var result=GLctx.getAttachedShaders(GL.programs[program]);var len=result.length;if(len>maxCount){len=maxCount}HEAP32[count>>2]=len;for(var i=0;i>2]=id}}function _emscripten_glGetAttribLocation(program,name){return GLctx.getAttribLocation(GL.programs[program],UTF8ToString(name))}function writeI53ToI64(ptr,num){HEAPU32[ptr>>2]=num;HEAPU32[ptr+4>>2]=(num-HEAPU32[ptr>>2])/4294967296}function emscriptenWebGLGet(name_,p,type){if(!p){GL.recordError(1281);return}var ret=undefined;switch(name_){case 36346:ret=1;break;case 36344:if(type!=0&&type!=1){GL.recordError(1280)}return;case 34814:case 36345:ret=0;break;case 34466:var formats=GLctx.getParameter(34467);ret=formats?formats.length:0;break;case 33309:if(GL.currentContext.version<2){GL.recordError(1282);return}var exts=GLctx.getSupportedExtensions()||[];ret=2*exts.length;break;case 33307:case 33308:if(GL.currentContext.version<2){GL.recordError(1280);return}ret=name_==33307?3:0;break}if(ret===undefined){var result=GLctx.getParameter(name_);switch(typeof result){case"number":ret=result;break;case"boolean":ret=result?1:0;break;case"string":GL.recordError(1280);return;case"object":if(result===null){switch(name_){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:{ret=0;break}default:{GL.recordError(1280);return}}}else if(result instanceof Float32Array||result instanceof Uint32Array||result instanceof Int32Array||result instanceof Array){for(var i=0;i>2]=result[i];break;case 2:HEAPF32[p+i*4>>2]=result[i];break;case 4:HEAP8[p+i>>0]=result[i]?1:0;break}}return}else{try{ret=result.name|0}catch(e){GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Unknown object returned from WebGL getParameter("+name_+")! (error: "+e+")");return}}break;default:GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Native code calling glGet"+type+"v("+name_+") and it returns "+result+" of type "+typeof result+"!");return}}switch(type){case 1:writeI53ToI64(p,ret);break;case 0:HEAP32[p>>2]=ret;break;case 2:HEAPF32[p>>2]=ret;break;case 4:HEAP8[p>>0]=ret?1:0;break}}function _emscripten_glGetBooleanv(name_,p){emscriptenWebGLGet(name_,p,4)}function _emscripten_glGetBufferParameteri64v(target,value,data){if(!data){GL.recordError(1281);return}writeI53ToI64(data,GLctx.getBufferParameter(target,value))}function _emscripten_glGetBufferParameteriv(target,value,data){if(!data){GL.recordError(1281);return}HEAP32[data>>2]=GLctx.getBufferParameter(target,value)}function _emscripten_glGetBufferPointerv(target,pname,params){if(pname==35005){var ptr=0;var mappedBuffer=GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)];if(mappedBuffer){ptr=mappedBuffer.mem}HEAP32[params>>2]=ptr}else{GL.recordError(1280);err("GL_INVALID_ENUM in glGetBufferPointerv")}}function _emscripten_glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _emscripten_glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _emscripten_glGetFragDataLocation(program,name){return GLctx["getFragDataLocation"](GL.programs[program],UTF8ToString(name))}function _emscripten_glGetFramebufferAttachmentParameteriv(target,attachment,pname,params){var result=GLctx.getFramebufferAttachmentParameter(target,attachment,pname);if(result instanceof WebGLRenderbuffer||result instanceof WebGLTexture){result=result.name|0}HEAP32[params>>2]=result}function emscriptenWebGLGetIndexed(target,index,data,type){if(!data){GL.recordError(1281);return}var result=GLctx["getIndexedParameter"](target,index);var ret;switch(typeof result){case"boolean":ret=result?1:0;break;case"number":ret=result;break;case"object":if(result===null){switch(target){case 35983:case 35368:ret=0;break;default:{GL.recordError(1280);return}}}else if(result instanceof WebGLBuffer){ret=result.name|0}else{GL.recordError(1280);return}break;default:GL.recordError(1280);return}switch(type){case 1:writeI53ToI64(data,ret);break;case 0:HEAP32[data>>2]=ret;break;case 2:HEAPF32[data>>2]=ret;break;case 4:HEAP8[data>>0]=ret?1:0;break;default:throw"internal emscriptenWebGLGetIndexed() error, bad type: "+type}}function _emscripten_glGetInteger64i_v(target,index,data){emscriptenWebGLGetIndexed(target,index,data,1)}function _emscripten_glGetInteger64v(name_,p){emscriptenWebGLGet(name_,p,1)}function _emscripten_glGetIntegeri_v(target,index,data){emscriptenWebGLGetIndexed(target,index,data,0)}function _emscripten_glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _emscripten_glGetInternalformativ(target,internalformat,pname,bufSize,params){if(bufSize<0){GL.recordError(1281);return}if(!params){GL.recordError(1281);return}var ret=GLctx["getInternalformatParameter"](target,internalformat,pname);if(ret===null)return;for(var i=0;i>2]=ret[i]}}function _emscripten_glGetProgramBinary(program,bufSize,length,binaryFormat,binary){GL.recordError(1282)}function _emscripten_glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _emscripten_glGetQueryObjecti64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectui64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectuiv(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.queries[id];var param=GLctx["getQueryParameter"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectuivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryiv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx["getQuery"](target,pname)}function _emscripten_glGetQueryivEXT(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.disjointTimerQueryExt["getQueryEXT"](target,pname)}function _emscripten_glGetRenderbufferParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getRenderbufferParameter(target,pname)}function _emscripten_glGetSamplerParameterfv(sampler,pname,params){if(!params){GL.recordError(1281);return}sampler=GL.samplers[sampler];HEAPF32[params>>2]=GLctx["getSamplerParameter"](sampler,pname)}function _emscripten_glGetSamplerParameteriv(sampler,pname,params){if(!params){GL.recordError(1281);return}sampler=GL.samplers[sampler];HEAP32[params>>2]=GLctx["getSamplerParameter"](sampler,pname)}function _emscripten_glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderPrecisionFormat(shaderType,precisionType,range,precision){var result=GLctx.getShaderPrecisionFormat(shaderType,precisionType);HEAP32[range>>2]=result.rangeMin;HEAP32[range+4>>2]=result.rangeMax;HEAP32[precision>>2]=result.precision}function _emscripten_glGetShaderSource(shader,bufSize,length,source){var result=GLctx.getShaderSource(GL.shaders[shader]);if(!result)return;var numBytesWrittenExclNull=bufSize>0&&source?stringToUTF8(result,source,bufSize):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function stringToNewUTF8(jsString){var length=lengthBytesUTF8(jsString)+1;var cString=_malloc(length);stringToUTF8(jsString,cString,length);return cString}function _emscripten_glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(true)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _emscripten_glGetStringi(name,index){if(GL.currentContext.version<2){GL.recordError(1282);return 0}var stringiCache=GL.stringiCache[name];if(stringiCache){if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index]}switch(name){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));exts=exts.map(function(e){return stringToNewUTF8(e)});stringiCache=GL.stringiCache[name]=exts;if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index];default:GL.recordError(1280);return 0}}function _emscripten_glGetSynciv(sync,pname,bufSize,length,values){if(bufSize<0){GL.recordError(1281);return}if(!values){GL.recordError(1281);return}var ret=GLctx.getSyncParameter(GL.syncs[sync],pname);HEAP32[length>>2]=ret;if(ret!==null&&length)HEAP32[length>>2]=1}function _emscripten_glGetTexParameterfv(target,pname,params){if(!params){GL.recordError(1281);return}HEAPF32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTexParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTransformFeedbackVarying(program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx["getTransformFeedbackVarying"](program,index);if(!info)return;if(name&&bufSize>0){var numBytesWrittenExclNull=stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull}else{if(length)HEAP32[length>>2]=0}if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}function _emscripten_glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function _emscripten_glGetUniformIndices(program,uniformCount,uniformNames,uniformIndices){if(!uniformIndices){GL.recordError(1281);return}if(uniformCount>0&&(uniformNames==0||uniformIndices==0)){GL.recordError(1281);return}program=GL.programs[program];var names=[];for(var i=0;i>2]));var result=GLctx["getUniformIndices"](program,names);if(!result)return;var len=result.length;for(var i=0;i>2]=result[i]}}function jstoi_q(str){return parseInt(str)}function _emscripten_glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]=data;break;case 2:HEAPF32[params>>2]=data;break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break}}}}function _emscripten_glGetUniformfv(program,location,params){emscriptenWebGLGetUniform(program,location,params,2)}function _emscripten_glGetUniformiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function _emscripten_glGetUniformuiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function emscriptenWebGLGetVertexAttrib(index,pname,params,type){if(!params){GL.recordError(1281);return}if(GL.currentContext.clientBuffers[index].enabled){err("glGetVertexAttrib*v on client-side array: not supported, bad data returned")}var data=GLctx.getVertexAttrib(index,pname);if(pname==34975){HEAP32[params>>2]=data&&data["name"]}else if(typeof data=="number"||typeof data=="boolean"){switch(type){case 0:HEAP32[params>>2]=data;break;case 2:HEAPF32[params>>2]=data;break;case 5:HEAP32[params>>2]=Math.fround(data);break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break;case 5:HEAP32[params+i*4>>2]=Math.fround(data[i]);break}}}}function _emscripten_glGetVertexAttribIiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,0)}function _emscripten_glGetVertexAttribIuiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,0)}function _emscripten_glGetVertexAttribPointerv(index,pname,pointer){if(!pointer){GL.recordError(1281);return}if(GL.currentContext.clientBuffers[index].enabled){err("glGetVertexAttribPointer on client-side array: not supported, bad data returned")}HEAP32[pointer>>2]=GLctx.getVertexAttribOffset(index,pname)}function _emscripten_glGetVertexAttribfv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,2)}function _emscripten_glGetVertexAttribiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,5)}function _emscripten_glHint(x0,x1){GLctx["hint"](x0,x1)}function _emscripten_glInvalidateFramebuffer(target,numAttachments,attachments){var list=tempFixedLengthArray[numAttachments];for(var i=0;i>2]}GLctx["invalidateFramebuffer"](target,list)}function _emscripten_glInvalidateSubFramebuffer(target,numAttachments,attachments,x,y,width,height){var list=tempFixedLengthArray[numAttachments];for(var i=0;i>2]}GLctx["invalidateSubFramebuffer"](target,list,x,y,width,height)}function _emscripten_glIsBuffer(buffer){var b=GL.buffers[buffer];if(!b)return 0;return GLctx.isBuffer(b)}function _emscripten_glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _emscripten_glIsFramebuffer(framebuffer){var fb=GL.framebuffers[framebuffer];if(!fb)return 0;return GLctx.isFramebuffer(fb)}function _emscripten_glIsProgram(program){program=GL.programs[program];if(!program)return 0;return GLctx.isProgram(program)}function _emscripten_glIsQuery(id){var query=GL.queries[id];if(!query)return 0;return GLctx["isQuery"](query)}function _emscripten_glIsQueryEXT(id){var query=GL.timerQueriesEXT[id];if(!query)return 0;return GLctx.disjointTimerQueryExt["isQueryEXT"](query)}function _emscripten_glIsRenderbuffer(renderbuffer){var rb=GL.renderbuffers[renderbuffer];if(!rb)return 0;return GLctx.isRenderbuffer(rb)}function _emscripten_glIsSampler(id){var sampler=GL.samplers[id];if(!sampler)return 0;return GLctx["isSampler"](sampler)}function _emscripten_glIsShader(shader){var s=GL.shaders[shader];if(!s)return 0;return GLctx.isShader(s)}function _emscripten_glIsSync(sync){return GLctx.isSync(GL.syncs[sync])}function _emscripten_glIsTexture(id){var texture=GL.textures[id];if(!texture)return 0;return GLctx.isTexture(texture)}function _emscripten_glIsTransformFeedback(id){return GLctx["isTransformFeedback"](GL.transformFeedbacks[id])}function _emscripten_glIsVertexArray(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glIsVertexArrayOES(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glLineWidth(x0){GLctx["lineWidth"](x0)}function _emscripten_glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _emscripten_glMapBufferRange(target,offset,length,access){if(access!=26&&access!=10){err("glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER");return 0}if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glMapBufferRange");return 0}var mem=_malloc(length);if(!mem)return 0;GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)]={offset:offset,length:length,mem:mem,access:access};return mem}function _emscripten_glPauseTransformFeedback(){GLctx["pauseTransformFeedback"]()}function _emscripten_glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _emscripten_glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _emscripten_glProgramBinary(program,binaryFormat,binary,length){GL.recordError(1280)}function _emscripten_glProgramParameteri(program,pname,value){GL.recordError(1280)}function _emscripten_glQueryCounterEXT(id,target){GLctx.disjointTimerQueryExt["queryCounterEXT"](GL.timerQueriesEXT[id],target)}function _emscripten_glReadBuffer(x0){GLctx["readBuffer"](x0)}function computeUnpackAlignedImageSize(width,height,sizePerPixel,alignment){function roundedToNextMultipleOf(x,y){return x+y-1&-y}var plainRowSize=width*sizePerPixel;var alignedRowSize=roundedToNextMultipleOf(plainRowSize,alignment);return height*alignedRowSize}function __colorChannelsInGlTextureFormat(format){var colorChannels={5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4};return colorChannels[format-6402]||1}function heapObjectForWebGLType(type){type-=5120;if(type==0)return HEAP8;if(type==1)return HEAPU8;if(type==2)return HEAP16;if(type==4)return HEAP32;if(type==6)return HEAPF32;if(type==5||type==28922||type==28520||type==30779||type==30782)return HEAPU32;return HEAPU16}function heapAccessShiftForWebGLHeap(heap){return 31-Math.clz32(heap.BYTES_PER_ELEMENT)}function emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat){var heap=heapObjectForWebGLType(type);var shift=heapAccessShiftForWebGLHeap(heap);var byteSize=1<>shift,pixels+bytes>>shift)}function _emscripten_glReadPixels(x,y,width,height,format,type,pixels){if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _emscripten_glReleaseShaderCompiler(){}function _emscripten_glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _emscripten_glRenderbufferStorageMultisample(x0,x1,x2,x3,x4){GLctx["renderbufferStorageMultisample"](x0,x1,x2,x3,x4)}function _emscripten_glResumeTransformFeedback(){GLctx["resumeTransformFeedback"]()}function _emscripten_glSampleCoverage(value,invert){GLctx.sampleCoverage(value,!!invert)}function _emscripten_glSamplerParameterf(sampler,pname,param){GLctx["samplerParameterf"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameterfv(sampler,pname,params){var param=HEAPF32[params>>2];GLctx["samplerParameterf"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameteri(sampler,pname,param){GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameteriv(sampler,pname,params){var param=HEAP32[params>>2];GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _emscripten_glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _emscripten_glShaderBinary(){GL.recordError(1280)}function _emscripten_glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _emscripten_glStencilFunc(x0,x1,x2){GLctx["stencilFunc"](x0,x1,x2)}function _emscripten_glStencilFuncSeparate(x0,x1,x2,x3){GLctx["stencilFuncSeparate"](x0,x1,x2,x3)}function _emscripten_glStencilMask(x0){GLctx["stencilMask"](x0)}function _emscripten_glStencilMaskSeparate(x0,x1){GLctx["stencilMaskSeparate"](x0,x1)}function _emscripten_glStencilOp(x0,x1,x2){GLctx["stencilOp"](x0,x1,x2)}function _emscripten_glStencilOpSeparate(x0,x1,x2,x3){GLctx["stencilOpSeparate"](x0,x1,x2,x3)}function _emscripten_glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,null)}return}GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels?emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat):null)}function _emscripten_glTexImage3D(target,level,internalFormat,width,height,depth,border,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,null)}}function _emscripten_glTexParameterf(x0,x1,x2){GLctx["texParameterf"](x0,x1,x2)}function _emscripten_glTexParameterfv(target,pname,params){var param=HEAPF32[params>>2];GLctx.texParameterf(target,pname,param)}function _emscripten_glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _emscripten_glTexParameteriv(target,pname,params){var param=HEAP32[params>>2];GLctx.texParameteri(target,pname,param)}function _emscripten_glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _emscripten_glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _emscripten_glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _emscripten_glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function _emscripten_glTransformFeedbackVaryings(program,count,varyings,bufferMode){program=GL.programs[program];var vars=[];for(var i=0;i>2]));GLctx["transformFeedbackVaryings"](program,vars,bufferMode)}function _emscripten_glUniform1f(location,v0){GLctx.uniform1f(GL.uniforms[location],v0)}function _emscripten_glUniform1fv(location,count,value){GLctx.uniform1fv(GL.uniforms[location],HEAPF32,value>>2,count)}function _emscripten_glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}function _emscripten_glUniform1iv(location,count,value){GLctx.uniform1iv(GL.uniforms[location],HEAP32,value>>2,count)}function _emscripten_glUniform1ui(location,v0){GLctx.uniform1ui(GL.uniforms[location],v0)}function _emscripten_glUniform1uiv(location,count,value){GLctx.uniform1uiv(GL.uniforms[location],HEAPU32,value>>2,count)}function _emscripten_glUniform2f(location,v0,v1){GLctx.uniform2f(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2fv(location,count,value){GLctx.uniform2fv(GL.uniforms[location],HEAPF32,value>>2,count*2)}function _emscripten_glUniform2i(location,v0,v1){GLctx.uniform2i(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2iv(location,count,value){GLctx.uniform2iv(GL.uniforms[location],HEAP32,value>>2,count*2)}function _emscripten_glUniform2ui(location,v0,v1){GLctx.uniform2ui(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2uiv(location,count,value){GLctx.uniform2uiv(GL.uniforms[location],HEAPU32,value>>2,count*2)}function _emscripten_glUniform3f(location,v0,v1,v2){GLctx.uniform3f(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3fv(location,count,value){GLctx.uniform3fv(GL.uniforms[location],HEAPF32,value>>2,count*3)}function _emscripten_glUniform3i(location,v0,v1,v2){GLctx.uniform3i(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3iv(location,count,value){GLctx.uniform3iv(GL.uniforms[location],HEAP32,value>>2,count*3)}function _emscripten_glUniform3ui(location,v0,v1,v2){GLctx.uniform3ui(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3uiv(location,count,value){GLctx.uniform3uiv(GL.uniforms[location],HEAPU32,value>>2,count*3)}function _emscripten_glUniform4f(location,v0,v1,v2,v3){GLctx.uniform4f(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4fv(location,count,value){GLctx.uniform4fv(GL.uniforms[location],HEAPF32,value>>2,count*4)}function _emscripten_glUniform4i(location,v0,v1,v2,v3){GLctx.uniform4i(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4iv(location,count,value){GLctx.uniform4iv(GL.uniforms[location],HEAP32,value>>2,count*4)}function _emscripten_glUniform4ui(location,v0,v1,v2,v3){GLctx.uniform4ui(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4uiv(location,count,value){GLctx.uniform4uiv(GL.uniforms[location],HEAPU32,value>>2,count*4)}function _emscripten_glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _emscripten_glUniformMatrix2fv(location,count,transpose,value){GLctx.uniformMatrix2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*4)}function _emscripten_glUniformMatrix2x3fv(location,count,transpose,value){GLctx.uniformMatrix2x3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*6)}function _emscripten_glUniformMatrix2x4fv(location,count,transpose,value){GLctx.uniformMatrix2x4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*8)}function _emscripten_glUniformMatrix3fv(location,count,transpose,value){GLctx.uniformMatrix3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*9)}function _emscripten_glUniformMatrix3x2fv(location,count,transpose,value){GLctx.uniformMatrix3x2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*6)}function _emscripten_glUniformMatrix3x4fv(location,count,transpose,value){GLctx.uniformMatrix3x4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*12)}function _emscripten_glUniformMatrix4fv(location,count,transpose,value){GLctx.uniformMatrix4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*16)}function _emscripten_glUniformMatrix4x2fv(location,count,transpose,value){GLctx.uniformMatrix4x2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*8)}function _emscripten_glUniformMatrix4x3fv(location,count,transpose,value){GLctx.uniformMatrix4x3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*12)}function _emscripten_glUnmapBuffer(target){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glUnmapBuffer");return 0}var buffer=emscriptenWebGLGetBufferBinding(target);var mapping=GL.mappedBuffers[buffer];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glUnmapBuffer");return 0}GL.mappedBuffers[buffer]=null;if(!(mapping.access&16))if(true){GLctx.bufferSubData(target,mapping.offset,HEAPU8,mapping.mem,mapping.length)}else{GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem,mapping.mem+mapping.length))}_free(mapping.mem);return 1}function _emscripten_glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _emscripten_glValidateProgram(program){GLctx.validateProgram(GL.programs[program])}function _emscripten_glVertexAttrib1f(x0,x1){GLctx["vertexAttrib1f"](x0,x1)}function _emscripten_glVertexAttrib1fv(index,v){GLctx.vertexAttrib1f(index,HEAPF32[v>>2])}function _emscripten_glVertexAttrib2f(x0,x1,x2){GLctx["vertexAttrib2f"](x0,x1,x2)}function _emscripten_glVertexAttrib2fv(index,v){GLctx.vertexAttrib2f(index,HEAPF32[v>>2],HEAPF32[v+4>>2])}function _emscripten_glVertexAttrib3f(x0,x1,x2,x3){GLctx["vertexAttrib3f"](x0,x1,x2,x3)}function _emscripten_glVertexAttrib3fv(index,v){GLctx.vertexAttrib3f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2])}function _emscripten_glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttrib4fv(index,v){GLctx.vertexAttrib4f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2],HEAPF32[v+12>>2])}function _emscripten_glVertexAttribDivisor(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorANGLE(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorARB(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorEXT(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorNV(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribI4i(x0,x1,x2,x3,x4){GLctx["vertexAttribI4i"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttribI4iv(index,v){GLctx.vertexAttribI4i(index,HEAP32[v>>2],HEAP32[v+4>>2],HEAP32[v+8>>2],HEAP32[v+12>>2])}function _emscripten_glVertexAttribI4ui(x0,x1,x2,x3,x4){GLctx["vertexAttribI4ui"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttribI4uiv(index,v){GLctx.vertexAttribI4ui(index,HEAPU32[v>>2],HEAPU32[v+4>>2],HEAPU32[v+8>>2],HEAPU32[v+12>>2])}function _emscripten_glVertexAttribIPointer(index,size,type,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=false;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribIPointer(index,size,type,stride,ptr)};return}cb.clientside=false;GLctx["vertexAttribIPointer"](index,size,type,stride,ptr)}function _emscripten_glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _emscripten_glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _emscripten_glWaitSync(sync,flags,timeoutLo,timeoutHi){GLctx.waitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){try{var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _environ_sizes_get(penviron_count,penviron_buf_size){try{var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];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 _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _getentropy(buffer,size){if(!_getentropy.randomDevice){_getentropy.randomDevice=getRandomDevice()}for(var i=0;i>0]=_getentropy.randomDevice()}return 0}function _glActiveTexture(x0){GLctx["activeTexture"](x0)}function _glAttachShader(program,shader){GLctx.attachShader(GL.programs[program],GL.shaders[shader])}function _glBeginQuery(target,id){GLctx["beginQuery"](target,GL.queries[id])}function _glBindBuffer(target,buffer){if(target==34962){GLctx.currentArrayBufferBinding=buffer}else if(target==34963){GLctx.currentElementArrayBufferBinding=buffer}if(target==35051){GLctx.currentPixelPackBufferBinding=buffer}else if(target==35052){GLctx.currentPixelUnpackBufferBinding=buffer}GLctx.bindBuffer(target,GL.buffers[buffer])}function _glBindBufferRange(target,index,buffer,offset,ptrsize){GLctx["bindBufferRange"](target,index,GL.buffers[buffer],offset,ptrsize)}function _glBindFramebuffer(target,framebuffer){GLctx.bindFramebuffer(target,GL.framebuffers[framebuffer])}function _glBindRenderbuffer(target,renderbuffer){GLctx.bindRenderbuffer(target,GL.renderbuffers[renderbuffer])}function _glBindSampler(unit,sampler){GLctx["bindSampler"](unit,GL.samplers[sampler])}function _glBindTexture(target,texture){GLctx.bindTexture(target,GL.textures[texture])}function _glBindVertexArray(vao){GLctx["bindVertexArray"](GL.vaos[vao]);var ibo=GLctx.getParameter(34965);GLctx.currentElementArrayBufferBinding=ibo?ibo.name|0:0}function _glBlendEquationSeparate(x0,x1){GLctx["blendEquationSeparate"](x0,x1)}function _glBlendFuncSeparate(x0,x1,x2,x3){GLctx["blendFuncSeparate"](x0,x1,x2,x3)}function _glBlitFramebuffer(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9){GLctx["blitFramebuffer"](x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)}function _glBufferData(target,size,data,usage){if(true){if(data){GLctx.bufferData(target,HEAPU8,usage,data,size)}else{GLctx.bufferData(target,size,usage)}}else{GLctx.bufferData(target,data?HEAPU8.subarray(data,data+size):size,usage)}}function _glBufferSubData(target,offset,size,data){if(true){GLctx.bufferSubData(target,offset,HEAPU8,data,size);return}GLctx.bufferSubData(target,offset,HEAPU8.subarray(data,data+size))}function _glClearBufferfi(x0,x1,x2,x3){GLctx["clearBufferfi"](x0,x1,x2,x3)}function _glClearBufferfv(buffer,drawbuffer,value){GLctx["clearBufferfv"](buffer,drawbuffer,HEAPF32,value>>2)}function _glClearBufferiv(buffer,drawbuffer,value){GLctx["clearBufferiv"](buffer,drawbuffer,HEAP32,value>>2)}function _glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,imageSize,data)}else{GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,HEAPU8,data,imageSize)}return}GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _glCompressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data)}else{GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,HEAPU8,data,imageSize)}}function _glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _glCullFace(x0){GLctx["cullFace"](x0)}function _glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _glDeleteQueries(n,ids){for(var i=0;i>2];var query=GL.queries[id];if(!query)continue;GLctx["deleteQuery"](query);GL.queries[id]=null}}function _glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _glDeleteSamplers(n,samplers){for(var i=0;i>2];var sampler=GL.samplers[id];if(!sampler)continue;GLctx["deleteSampler"](sampler);sampler.name=0;GL.samplers[id]=null}}function _glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _glDepthFunc(x0){GLctx["depthFunc"](x0)}function _glDepthMask(flag){GLctx.depthMask(!!flag)}function _glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _glDisable(x0){GLctx["disable"](x0)}function _glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _glDrawRangeElements(mode,start,end,count,type,indices){_glDrawElements(mode,count,type,indices)}function _glEnable(x0){GLctx["enable"](x0)}function _glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _glEndQuery(x0){GLctx["endQuery"](x0)}function _glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _glFinish(){GLctx["finish"]()}function _glFlush(){GLctx["flush"]()}function _glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function _glFrontFace(x0){GLctx["frontFace"](x0)}function _glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _glGenQueries(n,ids){__glGenObject(n,ids,"createQuery",GL.queries)}function _glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _glGenSamplers(n,samplers){__glGenObject(n,samplers,"createSampler",GL.samplers)}function _glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function _glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _glGetQueryObjectuiv(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.queries[id];var param=GLctx["getQueryParameter"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function _glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(true)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _glGetStringi(name,index){if(GL.currentContext.version<2){GL.recordError(1282);return 0}var stringiCache=GL.stringiCache[name];if(stringiCache){if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index]}switch(name){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));exts=exts.map(function(e){return stringToNewUTF8(e)});stringiCache=GL.stringiCache[name]=exts;if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index];default:GL.recordError(1280);return 0}}function _glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function _glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]}GLctx["invalidateFramebuffer"](target,list)}function _glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _glMapBufferRange(target,offset,length,access){if(access!=26&&access!=10){err("glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER");return 0}if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glMapBufferRange");return 0}var mem=_malloc(length);if(!mem)return 0;GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)]={offset:offset,length:length,mem:mem,access:access};return mem}function _glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _glReadPixels(x,y,width,height,format,type,pixels){if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _glRenderbufferStorageMultisample(x0,x1,x2,x3,x4){GLctx["renderbufferStorageMultisample"](x0,x1,x2,x3,x4)}function _glSamplerParameteri(sampler,pname,param){GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function _glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}function _glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _glUnmapBuffer(target){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glUnmapBuffer");return 0}var buffer=emscriptenWebGLGetBufferBinding(target);var mapping=GL.mappedBuffers[buffer];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glUnmapBuffer");return 0}GL.mappedBuffers[buffer]=null;if(!(mapping.access&16))if(true){GLctx.bufferSubData(target,mapping.offset,HEAPU8,mapping.mem,mapping.length)}else{GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem,mapping.mem+mapping.length))}_free(mapping.mem);return 1}function _glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _glVertexAttribI4ui(x0,x1,x2,x3,x4){GLctx["vertexAttribI4ui"](x0,x1,x2,x3,x4)}function _glVertexAttribIPointer(index,size,type,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=false;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribIPointer(index,size,type,stride,ptr)};return}cb.clientside=false;GLctx["vertexAttribIPointer"](index,size,type,stride,ptr)}function _glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _glWaitSync(sync,flags,timeoutLo,timeoutHi){GLctx.waitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _pthread_create(){return 6}function _pthread_join(){return 28}function _setTempRet0($i){setTempRet0($i|0)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.indexOf(rule)>=0){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm){return _strftime(s,maxsize,format,tm)}function _sysconf(name){switch(name){case 30:return 16384;case 85:var maxHeapSize=2147483648;return maxHeapSize/16384;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:case 80:case 81:case 79:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}setErrNo(28);return-1}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){var double=ch<105;if(double&&buf&1)buf++;readAsmConstArgsArray.push(double?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var GLctx;for(var i=0;i<32;++i)tempFixedLengthArray.push(new Array(i));function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var asmLibraryArg={"Ga":___sys_fcntl64,"Dg":___sys_ioctl,"Eg":___sys_open,"v":__embind_finalize_value_array,"z":__embind_finalize_value_object,"Hg":__embind_register_bool,"d":__embind_register_class,"l":__embind_register_class_class_function,"n":__embind_register_class_constructor,"a":__embind_register_class_function,"u":__embind_register_class_property,"Gg":__embind_register_emval,"i":__embind_register_enum,"b":__embind_register_enum_value,"Ia":__embind_register_float,"Ka":__embind_register_function,"D":__embind_register_integer,"x":__embind_register_memory_view,"Ja":__embind_register_std_string,"ja":__embind_register_std_wstring,"w":__embind_register_value_array,"f":__embind_register_value_array_element,"A":__embind_register_value_object,"e":__embind_register_value_object_field,"Ig":__embind_register_void,"q":__emval_as,"g":__emval_decref,"r":__emval_get_property,"ha":__emval_incref,"G":__emval_new_cstring,"p":__emval_run_destructors,"s":__emval_take_value,"c":_abort,"wg":_clock_gettime,"tg":_emscripten_asm_const_int,"$f":_emscripten_glActiveTexture,"_f":_emscripten_glAttachShader,"bd":_emscripten_glBeginQuery,"pg":_emscripten_glBeginQueryEXT,"Fc":_emscripten_glBeginTransformFeedback,"Zf":_emscripten_glBindAttribLocation,"Yf":_emscripten_glBindBuffer,"Cc":_emscripten_glBindBufferBase,"Dc":_emscripten_glBindBufferRange,"Xf":_emscripten_glBindFramebuffer,"Wf":_emscripten_glBindRenderbuffer,"Jb":_emscripten_glBindSampler,"Vf":_emscripten_glBindTexture,"Bb":_emscripten_glBindTransformFeedback,"Kc":_emscripten_glBindVertexArray,"hg":_emscripten_glBindVertexArrayOES,"Uf":_emscripten_glBlendColor,"Tf":_emscripten_glBlendEquation,"Sf":_emscripten_glBlendEquationSeparate,"Rf":_emscripten_glBlendFunc,"Qf":_emscripten_glBlendFuncSeparate,"Qc":_emscripten_glBlitFramebuffer,"Pf":_emscripten_glBufferData,"Of":_emscripten_glBufferSubData,"Nf":_emscripten_glCheckFramebufferStatus,"Mf":_emscripten_glClear,"fc":_emscripten_glClearBufferfi,"gc":_emscripten_glClearBufferfv,"ic":_emscripten_glClearBufferiv,"hc":_emscripten_glClearBufferuiv,"Lf":_emscripten_glClearColor,"Kf":_emscripten_glClearDepthf,"Jf":_emscripten_glClearStencil,"Tb":_emscripten_glClientWaitSync,"If":_emscripten_glColorMask,"Hf":_emscripten_glCompileShader,"Gf":_emscripten_glCompressedTexImage2D,"gd":_emscripten_glCompressedTexImage3D,"Ff":_emscripten_glCompressedTexSubImage2D,"fd":_emscripten_glCompressedTexSubImage3D,"dc":_emscripten_glCopyBufferSubData,"Ef":_emscripten_glCopyTexImage2D,"Df":_emscripten_glCopyTexSubImage2D,"id":_emscripten_glCopyTexSubImage3D,"Cf":_emscripten_glCreateProgram,"Bf":_emscripten_glCreateShader,"Af":_emscripten_glCullFace,"zf":_emscripten_glDeleteBuffers,"yf":_emscripten_glDeleteFramebuffers,"xf":_emscripten_glDeleteProgram,"dd":_emscripten_glDeleteQueries,"rg":_emscripten_glDeleteQueriesEXT,"wf":_emscripten_glDeleteRenderbuffers,"Lb":_emscripten_glDeleteSamplers,"vf":_emscripten_glDeleteShader,"Ub":_emscripten_glDeleteSync,"uf":_emscripten_glDeleteTextures,"Ab":_emscripten_glDeleteTransformFeedbacks,"Jc":_emscripten_glDeleteVertexArrays,"gg":_emscripten_glDeleteVertexArraysOES,"tf":_emscripten_glDepthFunc,"sf":_emscripten_glDepthMask,"rf":_emscripten_glDepthRangef,"qf":_emscripten_glDetachShader,"pf":_emscripten_glDisable,"of":_emscripten_glDisableVertexAttribArray,"nf":_emscripten_glDrawArrays,"Yb":_emscripten_glDrawArraysInstanced,"cg":_emscripten_glDrawArraysInstancedANGLE,"kb":_emscripten_glDrawArraysInstancedARB,"pd":_emscripten_glDrawArraysInstancedEXT,"lb":_emscripten_glDrawArraysInstancedNV,"Xc":_emscripten_glDrawBuffers,"nd":_emscripten_glDrawBuffersEXT,"dg":_emscripten_glDrawBuffersWEBGL,"mf":_emscripten_glDrawElements,"Xb":_emscripten_glDrawElementsInstanced,"bg":_emscripten_glDrawElementsInstancedANGLE,"ib":_emscripten_glDrawElementsInstancedARB,"jb":_emscripten_glDrawElementsInstancedEXT,"od":_emscripten_glDrawElementsInstancedNV,"ld":_emscripten_glDrawRangeElements,"lf":_emscripten_glEnable,"kf":_emscripten_glEnableVertexAttribArray,"ad":_emscripten_glEndQuery,"og":_emscripten_glEndQueryEXT,"Ec":_emscripten_glEndTransformFeedback,"Wb":_emscripten_glFenceSync,"jf":_emscripten_glFinish,"hf":_emscripten_glFlush,"Lc":_emscripten_glFlushMappedBufferRange,"gf":_emscripten_glFramebufferRenderbuffer,"ff":_emscripten_glFramebufferTexture2D,"Nc":_emscripten_glFramebufferTextureLayer,"ef":_emscripten_glFrontFace,"df":_emscripten_glGenBuffers,"bf":_emscripten_glGenFramebuffers,"ed":_emscripten_glGenQueries,"sg":_emscripten_glGenQueriesEXT,"af":_emscripten_glGenRenderbuffers,"Mb":_emscripten_glGenSamplers,"$e":_emscripten_glGenTextures,"zb":_emscripten_glGenTransformFeedbacks,"Ic":_emscripten_glGenVertexArrays,"fg":_emscripten_glGenVertexArraysOES,"cf":_emscripten_glGenerateMipmap,"_e":_emscripten_glGetActiveAttrib,"Ze":_emscripten_glGetActiveUniform,"_b":_emscripten_glGetActiveUniformBlockName,"$b":_emscripten_glGetActiveUniformBlockiv,"bc":_emscripten_glGetActiveUniformsiv,"Ye":_emscripten_glGetAttachedShaders,"Xe":_emscripten_glGetAttribLocation,"We":_emscripten_glGetBooleanv,"Nb":_emscripten_glGetBufferParameteri64v,"Ve":_emscripten_glGetBufferParameteriv,"Yc":_emscripten_glGetBufferPointerv,"Ue":_emscripten_glGetError,"Te":_emscripten_glGetFloatv,"rc":_emscripten_glGetFragDataLocation,"Se":_emscripten_glGetFramebufferAttachmentParameteriv,"Ob":_emscripten_glGetInteger64i_v,"Qb":_emscripten_glGetInteger64v,"Gc":_emscripten_glGetIntegeri_v,"Re":_emscripten_glGetIntegerv,"ob":_emscripten_glGetInternalformativ,"vb":_emscripten_glGetProgramBinary,"Pe":_emscripten_glGetProgramInfoLog,"Qe":_emscripten_glGetProgramiv,"jg":_emscripten_glGetQueryObjecti64vEXT,"lg":_emscripten_glGetQueryObjectivEXT,"ig":_emscripten_glGetQueryObjectui64vEXT,"_c":_emscripten_glGetQueryObjectuiv,"kg":_emscripten_glGetQueryObjectuivEXT,"$c":_emscripten_glGetQueryiv,"mg":_emscripten_glGetQueryivEXT,"Oe":_emscripten_glGetRenderbufferParameteriv,"Db":_emscripten_glGetSamplerParameterfv,"Eb":_emscripten_glGetSamplerParameteriv,"Me":_emscripten_glGetShaderInfoLog,"Le":_emscripten_glGetShaderPrecisionFormat,"Ke":_emscripten_glGetShaderSource,"Ne":_emscripten_glGetShaderiv,"Je":_emscripten_glGetString,"ec":_emscripten_glGetStringi,"Pb":_emscripten_glGetSynciv,"Ie":_emscripten_glGetTexParameterfv,"He":_emscripten_glGetTexParameteriv,"Ac":_emscripten_glGetTransformFeedbackVarying,"ac":_emscripten_glGetUniformBlockIndex,"cc":_emscripten_glGetUniformIndices,"Ee":_emscripten_glGetUniformLocation,"Ge":_emscripten_glGetUniformfv,"Fe":_emscripten_glGetUniformiv,"sc":_emscripten_glGetUniformuiv,"yc":_emscripten_glGetVertexAttribIiv,"xc":_emscripten_glGetVertexAttribIuiv,"Be":_emscripten_glGetVertexAttribPointerv,"De":_emscripten_glGetVertexAttribfv,"Ce":_emscripten_glGetVertexAttribiv,"Ae":_emscripten_glHint,"sb":_emscripten_glInvalidateFramebuffer,"rb":_emscripten_glInvalidateSubFramebuffer,"ze":_emscripten_glIsBuffer,"ye":_emscripten_glIsEnabled,"xe":_emscripten_glIsFramebuffer,"we":_emscripten_glIsProgram,"cd":_emscripten_glIsQuery,"qg":_emscripten_glIsQueryEXT,"ve":_emscripten_glIsRenderbuffer,"Kb":_emscripten_glIsSampler,"ue":_emscripten_glIsShader,"Vb":_emscripten_glIsSync,"te":_emscripten_glIsTexture,"yb":_emscripten_glIsTransformFeedback,"Hc":_emscripten_glIsVertexArray,"eg":_emscripten_glIsVertexArrayOES,"se":_emscripten_glLineWidth,"re":_emscripten_glLinkProgram,"Mc":_emscripten_glMapBufferRange,"xb":_emscripten_glPauseTransformFeedback,"qe":_emscripten_glPixelStorei,"pe":_emscripten_glPolygonOffset,"ub":_emscripten_glProgramBinary,"tb":_emscripten_glProgramParameteri,"ng":_emscripten_glQueryCounterEXT,"md":_emscripten_glReadBuffer,"oe":_emscripten_glReadPixels,"ne":_emscripten_glReleaseShaderCompiler,"me":_emscripten_glRenderbufferStorage,"Pc":_emscripten_glRenderbufferStorageMultisample,"wb":_emscripten_glResumeTransformFeedback,"le":_emscripten_glSampleCoverage,"Gb":_emscripten_glSamplerParameterf,"Fb":_emscripten_glSamplerParameterfv,"Ib":_emscripten_glSamplerParameteri,"Hb":_emscripten_glSamplerParameteriv,"ke":_emscripten_glScissor,"je":_emscripten_glShaderBinary,"ie":_emscripten_glShaderSource,"he":_emscripten_glStencilFunc,"ge":_emscripten_glStencilFuncSeparate,"fe":_emscripten_glStencilMask,"ee":_emscripten_glStencilMaskSeparate,"de":_emscripten_glStencilOp,"ce":_emscripten_glStencilOpSeparate,"be":_emscripten_glTexImage2D,"kd":_emscripten_glTexImage3D,"ae":_emscripten_glTexParameterf,"$d":_emscripten_glTexParameterfv,"_d":_emscripten_glTexParameteri,"Zd":_emscripten_glTexParameteriv,"qb":_emscripten_glTexStorage2D,"pb":_emscripten_glTexStorage3D,"Yd":_emscripten_glTexSubImage2D,"jd":_emscripten_glTexSubImage3D,"Bc":_emscripten_glTransformFeedbackVaryings,"Xd":_emscripten_glUniform1f,"Wd":_emscripten_glUniform1fv,"Vd":_emscripten_glUniform1i,"Ud":_emscripten_glUniform1iv,"qc":_emscripten_glUniform1ui,"mc":_emscripten_glUniform1uiv,"Td":_emscripten_glUniform2f,"Sd":_emscripten_glUniform2fv,"Rd":_emscripten_glUniform2i,"Qd":_emscripten_glUniform2iv,"pc":_emscripten_glUniform2ui,"lc":_emscripten_glUniform2uiv,"Pd":_emscripten_glUniform3f,"Od":_emscripten_glUniform3fv,"Md":_emscripten_glUniform3i,"Ld":_emscripten_glUniform3iv,"oc":_emscripten_glUniform3ui,"kc":_emscripten_glUniform3uiv,"Kd":_emscripten_glUniform4f,"Jd":_emscripten_glUniform4fv,"Id":_emscripten_glUniform4i,"Hd":_emscripten_glUniform4iv,"nc":_emscripten_glUniform4ui,"jc":_emscripten_glUniform4uiv,"Zb":_emscripten_glUniformBlockBinding,"Gd":_emscripten_glUniformMatrix2fv,"Wc":_emscripten_glUniformMatrix2x3fv,"Uc":_emscripten_glUniformMatrix2x4fv,"Fd":_emscripten_glUniformMatrix3fv,"Vc":_emscripten_glUniformMatrix3x2fv,"Sc":_emscripten_glUniformMatrix3x4fv,"Ed":_emscripten_glUniformMatrix4fv,"Tc":_emscripten_glUniformMatrix4x2fv,"Rc":_emscripten_glUniformMatrix4x3fv,"Zc":_emscripten_glUnmapBuffer,"Dd":_emscripten_glUseProgram,"Cd":_emscripten_glValidateProgram,"Bd":_emscripten_glVertexAttrib1f,"Ad":_emscripten_glVertexAttrib1fv,"zd":_emscripten_glVertexAttrib2f,"yd":_emscripten_glVertexAttrib2fv,"xd":_emscripten_glVertexAttrib3f,"wd":_emscripten_glVertexAttrib3fv,"vd":_emscripten_glVertexAttrib4f,"ud":_emscripten_glVertexAttrib4fv,"Cb":_emscripten_glVertexAttribDivisor,"ag":_emscripten_glVertexAttribDivisorANGLE,"mb":_emscripten_glVertexAttribDivisorARB,"qd":_emscripten_glVertexAttribDivisorEXT,"nb":_emscripten_glVertexAttribDivisorNV,"wc":_emscripten_glVertexAttribI4i,"uc":_emscripten_glVertexAttribI4iv,"vc":_emscripten_glVertexAttribI4ui,"tc":_emscripten_glVertexAttribI4uiv,"zc":_emscripten_glVertexAttribIPointer,"td":_emscripten_glVertexAttribPointer,"rd":_emscripten_glViewport,"Sb":_emscripten_glWaitSync,"ug":_emscripten_memcpy_big,"vg":_emscripten_resize_heap,"zg":_environ_get,"Ag":_environ_sizes_get,"ia":_fd_close,"Fg":_fd_read,"fb":_fd_seek,"Ha":_fd_write,"xg":_getentropy,"h":_glActiveTexture,"T":_glAttachShader,"Xg":_glBeginQuery,"C":_glBindBuffer,"ra":_glBindBufferRange,"m":_glBindFramebuffer,"H":_glBindRenderbuffer,"U":_glBindSampler,"k":_glBindTexture,"N":_glBindVertexArray,"Tg":_glBlendEquationSeparate,"Sg":_glBlendFuncSeparate,"pa":_glBlitFramebuffer,"M":_glBufferData,"Y":_glBufferSubData,"Mg":_glClearBufferfi,"O":_glClearBufferfv,"Lg":_glClearBufferiv,"gb":_glClientWaitSync,"la":_glColorMask,"ba":_glCompileShader,"Ma":_glCompressedTexSubImage2D,"La":_glCompressedTexSubImage3D,"Aa":_glCreateProgram,"da":_glCreateShader,"ka":_glCullFace,"Ca":_glDeleteBuffers,"S":_glDeleteFramebuffers,"$":_glDeleteProgram,"_a":_glDeleteQueries,"E":_glDeleteRenderbuffers,"na":_glDeleteSamplers,"L":_glDeleteShader,"F":_glDeleteSync,"J":_glDeleteTextures,"Rb":_glDeleteVertexArrays,"Rg":_glDepthFunc,"Qg":_glDepthMask,"Ya":_glDepthRangef,"_":_glDetachShader,"j":_glDisable,"sa":_glDisableVertexAttribArray,"Qa":_glDrawArrays,"Sa":_glDrawBuffers,"Ta":_glDrawRangeElements,"B":_glEnable,"ta":_glEnableVertexAttribArray,"Wg":_glEndQuery,"Z":_glFenceSync,"Da":_glFinish,"Ea":_glFlush,"P":_glFramebufferRenderbuffer,"Q":_glFramebufferTexture2D,"Pa":_glFramebufferTextureLayer,"Ug":_glFrontFace,"W":_glGenBuffers,"R":_glGenFramebuffers,"$a":_glGenQueries,"ga":_glGenRenderbuffers,"oa":_glGenSamplers,"I":_glGenTextures,"eb":_glGenVertexArrays,"Za":_glGenerateMipmap,"Ra":_glGetError,"sd":_glGetFloatv,"o":_glGetIntegerv,"bb":_glGetProgramInfoLog,"ya":_glGetProgramiv,"Vg":_glGetQueryObjectuiv,"ab":_glGetShaderInfoLog,"aa":_glGetShaderiv,"V":_glGetString,"Nd":_glGetStringi,"db":_glGetUniformBlockIndex,"xa":_glGetUniformLocation,"Yg":_glGetVertexAttribiv,"hd":_glHint,"va":_glInvalidateFramebuffer,"ma":_glIsEnabled,"za":_glLinkProgram,"Kg":_glMapBufferRange,"Oc":_glPixelStorei,"Ua":_glPolygonOffset,"qa":_glReadPixels,"ea":_glRenderbufferStorage,"fa":_glRenderbufferStorageMultisample,"t":_glSamplerParameteri,"Ng":_glScissor,"ca":_glShaderSource,"y":_glTexParameteri,"Pg":_glTexStorage2D,"Og":_glTexStorage3D,"Oa":_glTexSubImage2D,"Na":_glTexSubImage3D,"wa":_glUniform1i,"cb":_glUniformBlockBinding,"Jg":_glUnmapBuffer,"K":_glUseProgram,"Va":_glVertexAttrib4f,"Wa":_glVertexAttribI4ui,"Xa":_glVertexAttribIPointer,"ua":_glVertexAttribPointer,"X":_glViewport,"hb":_glWaitSync,"Fa":_pthread_create,"Cg":_pthread_join,"Ba":_setTempRet0,"yg":_strftime_l,"Bg":_sysconf};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["$g"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["ah"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["bh"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["ch"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["dh"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["eh"]).apply(null,arguments)};var dynCall_viijii=Module["dynCall_viijii"]=function(){return(dynCall_viijii=Module["dynCall_viijii"]=Module["asm"]["fh"]).apply(null,arguments)};var dynCall_jii=Module["dynCall_jii"]=function(){return(dynCall_jii=Module["dynCall_jii"]=Module["asm"]["gh"]).apply(null,arguments)};var dynCall_iiij=Module["dynCall_iiij"]=function(){return(dynCall_iiij=Module["dynCall_iiij"]=Module["asm"]["hh"]).apply(null,arguments)};var dynCall_vij=Module["dynCall_vij"]=function(){return(dynCall_vij=Module["dynCall_vij"]=Module["asm"]["ih"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["jh"]).apply(null,arguments)};var dynCall_iiiiij=Module["dynCall_iiiiij"]=function(){return(dynCall_iiiiij=Module["dynCall_iiiiij"]=Module["asm"]["kh"]).apply(null,arguments)};var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=function(){return(dynCall_iiiiijj=Module["dynCall_iiiiijj"]=Module["asm"]["lh"]).apply(null,arguments)};var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=function(){return(dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=Module["asm"]["mh"]).apply(null,arguments)};var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); return Filament.ready diff --git a/docs/remote/filament.wasm b/docs/remote/filament.wasm index 4c3d53e6f6358e7889639b5742063a1d86426eaa..d50836640b575ea0fd9e5572496b489dd4e18ea3 100755 GIT binary patch delta 220356 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�m6TZp|4q~F1R?*i`u?*ktIyMPY? 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 HYcu{2I;3`T delta 216094 zcmbrm2YggT*FSz|=5F6j?(QbplENl{hK>zXP`Mx=B8rO2W2a-Vp@8~WQV2aj-~vM@ z^bWxQi}c=+&_f9|NSBUu{@=NGL-FzXz3=<^Z*up{oS8W@bLN~gXUg5>(@vA|eNGdn z)Z*JOh$Km5v2DNr=lZfglb=5&>G*P_Kln(W()4ul%cn9>KT8At8mSETX!3TacSTm#eJ4W$$TS(P_e6NM{EI@Okz`qRe zKGM>G{iKCx5-n#GY|&D$zGX|v3}h<S{#nbFX943@mxQfKUY2C?P_^ZsR&d*8@e`xAp&IRo3GmCp5+t#m%O zYNhkCwSjD7#M&BZ?OI8dw1&3o=|W__GLpVFGIngG57sxW^nv`=$lu98b~cb*4Dg*% z?t26LU}X8X0aOE7x0OB~^$gN48)@~8v<9stOEXm8u$A7=SB%6)t@HtT)u^Je0bVn* zG%>Qg-bxplHw-dOjVx~(vA0@De(hCzg>)f)|1y%^H;R2?P%dZ0TC~=?*|N1>d8^iX zZ(Fz4D{o`O+8Ur;Yh8!hx7Ky&GXt4s#5x#hpSPC$sPBu`x-5PPnnE+aGO~W%S|5jw zt@XkA#z1~+#5x(V&PKs5M(n%Ry1IRD#C~WkRROVo8!@%DR0grSMyy_IDHgGpjZV}z zKm$P@}mNCPwUaBj+2fb@6FxAm22qf6IuyZGdJ5c*khW zyGHCiqfO2ASUUZe(YE&uMtx%BDQAEdZ4BnO5lTc`wb41-x{c1DHbz?8Hu{LPYom`( zdn4^LBQ4E{b!ekA_H!flMH}fm5c|@IJ^oc2UCqC4qYGfiHo77E#vuBwL9|mFshl>% zS-qUF0CkO|dPWT|8=$@c8nls!cG?-QYfIxcx{SPL)YHTOuN&YEBY#r^ylEicGGcEV z6*M!D?-;Rn+vryJJtIqV1NkphhZenWgMn-{Gjixo$V~y!+ zZKZN3(WI@^0N`~a&l?8OrbgB`4e*u$-ZrXlW`K8$0`H=@wk0b5bqPd1F?wCj$kC#m z&dHYTbS}4QXPD4-hGZJZw(ayjv@>Gu4e%MtX*Hr#D(ME*zS)BiF^YX_#5w_J zU8DCseJs8(o-&ikVlokGqCUn5GxsAzwo{3jn3bAklg}ba%te`GVm1~?enHDs;;ICh zY?c`_K~`j$kdN#EY9SH{)+e%Lmd%pgOo*w1i4jtRb=Gz$)zTTVN#)D*Cb6-W3bL8X zGLt0P%&2TNW8}Ym^UaTCYLSUmwxXyE=f`fhG15hnEm6c_Ba-~gGtq9D1r@~+G(}Z# zTTFHnbrFWlX2PU*dZB6tdRD8&LP0`wMV3G)_yUuqbS8BtGOOl1M`b;7wNis9pUd{v{fnDe(I{dWF3htn9 zvN@N$8?;FdDm`U2o1-PcFk*5@AS&43a7RHD{rYNOktP-Ve1CYu-yI?b|G z7ENIIfKRVj@&6>E$^F3%#u?!dp`sN zBq5s^2x>Rdha^knZMiAL%l-~yZ?tZjXs(fLGSyCf zH;33$Q>pQ>*yJaykJ%k>$!LT5OOxy*OwJ(WB^qy{Xjg1G3r3%yduX$a(ZE0Jq;-u+ ziBE*Yp$j(2lww61K4_sXZL+pJ=6z-|Q!O#JeBdc4m-I8G`WT~t5C`f)K>INEnRF-_ zR7_$&lo6%D3jnhiOXPAwxiFm2FbqQs%8M$P&O?!zQ7J+4Q>1~2_!mtS&7dZkLid(&ZXip{)!WuQSVRN=M6ttO?>m2ueRf z?sR5LF3~qI#`qAM&2Ed2kB>wVK$BjEArVbfO=t^*pUL7+W;QSa1^|pe16g~U9d^zI z>3~iVXd(vKh6RkU6Btx6nrJqZ9kfjZU67c?B!`k

|o^A|`xX&~s{mhCzpH%q4mX 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 z%0D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 this.mouseButtonEvents.push(false)); - this.canvas.addEventListener("pointerdown", e => this.mouseButtonEvents.push(true)); + + this.canvas.addEventListener("pointerup", e => this.mouseButtonEvents.push(null)); + this.canvas.addEventListener("pointerdown", e => this.mouseButtonEvents.push(e)); this.canvas.addEventListener("mousewheel", e => this.mouseWheelY = e.deltaY / 8); + this.canvas.addEventListener("contextmenu", event => event.preventDefault()); + + document.addEventListener("keydown", e => this.simpleViewer.keyDownEvent(e.keyCode)); + document.addEventListener("keyup", e => this.simpleViewer.keyUpEvent(e.keyCode)); + document.addEventListener("keypress", e => this.simpleViewer.keyPressEvent(e.charCode)); + const resize = () => { const dpr = window.devicePixelRatio; const width = this.canvas.clientWidth * dpr; @@ -263,6 +270,8 @@ class App { } const mouseWheel = this.mouseWheelY; this.mouseWheelY = 0; + this.simpleViewer.mouseEvent(this.mouseX, this.mouseY, !!this.mouseButton, + mouseWheel, this.mouseButton && this.mouseButton.ctrlKey); // If there's no connection, let Filament clear the canvas, but do not render the UI view. if (!connection) { @@ -276,8 +285,7 @@ class App { // Draw the UI and potentially mutate the settings object. const deltaTime = 1.0 / 60.0; - this.simpleViewer.renderUserInterface(deltaTime, this.uiview, window.devicePixelRatio, - this.mouseX, this.mouseY, this.mouseButton, mouseWheel); + this.simpleViewer.renderUserInterface(deltaTime, this.uiview, window.devicePixelRatio); // Check if the user has changed any settings. const settingsJson = this.serializer.writeJson(this.simpleViewer.getSettings()).slice(); diff --git a/libs/viewer/include/viewer/SimpleViewer.h b/libs/viewer/include/viewer/SimpleViewer.h index 7f5e7648f2..6573034321 100644 --- a/libs/viewer/include/viewer/SimpleViewer.h +++ b/libs/viewer/include/viewer/SimpleViewer.h @@ -122,8 +122,18 @@ public: * its callback. Note that the first call might be slower since it requires the creation of the * internal ImGuiHelper instance. */ - void renderUserInterface(float timeStepInSeconds, filament::View* guiView, float pixelRatio, - float mouseX, float mouseY, bool mouseButton, float mouseWheelY); + void renderUserInterface(float timeStepInSeconds, filament::View* guiView, float pixelRatio); + + /** + * Event-passing methods, useful only when SimpleViewer manages its own instance of ImGuiHelper. + * The key codes used in these methods are just normal ASCII/ANSI codes. + * @{ + */ + void mouseEvent(float mouseX, float mouseY, bool mouseButton, float mouseWheelY, bool control); + void keyDownEvent(int keyCode); + void keyUpEvent(int keyCode); + void keyPressEvent(int charCode); + /** @}*/ /** * Retrieves the current width of the ImGui "window" which we are using as a sidebar. diff --git a/libs/viewer/src/SimpleViewer.cpp b/libs/viewer/src/SimpleViewer.cpp index 1233cec56e..e0af8cf735 100644 --- a/libs/viewer/src/SimpleViewer.cpp +++ b/libs/viewer/src/SimpleViewer.cpp @@ -418,34 +418,79 @@ void SimpleViewer::applyAnimation(double currentTime) { mAnimator->updateBoneMatrices(); } -void SimpleViewer::renderUserInterface(float timeStepInSeconds, View* guiView, float pixelRatio, - float mouseX, float mouseY, bool mouseButton, float mouseWheelY) { +void SimpleViewer::renderUserInterface(float timeStepInSeconds, View* guiView, float pixelRatio) { if (mImGuiHelper == nullptr) { mImGuiHelper = new ImGuiHelper(mEngine, guiView, ""); + auto& io = ImGui::GetIO(); + + // The following table uses normal ANSI codes, which is consistent with the keyCode that + // comes from a web "keydown" event. + io.KeyMap[ImGuiKey_Tab] = 9; + io.KeyMap[ImGuiKey_LeftArrow] = 37; + io.KeyMap[ImGuiKey_RightArrow] = 39; + io.KeyMap[ImGuiKey_UpArrow] = 38; + io.KeyMap[ImGuiKey_DownArrow] = 40; + io.KeyMap[ImGuiKey_Home] = 36; + io.KeyMap[ImGuiKey_End] = 35; + io.KeyMap[ImGuiKey_Delete] = 46; + io.KeyMap[ImGuiKey_Backspace] = 8; + io.KeyMap[ImGuiKey_Enter] = 13; + io.KeyMap[ImGuiKey_Escape] = 27; + io.KeyMap[ImGuiKey_A] = 65; + io.KeyMap[ImGuiKey_C] = 67; + io.KeyMap[ImGuiKey_V] = 86; + io.KeyMap[ImGuiKey_X] = 88; + io.KeyMap[ImGuiKey_Y] = 89; + io.KeyMap[ImGuiKey_Z] = 90; + // TODO: this is not the best way to handle high DPI in ImGui, but it is fine when using the // proggy font. Users need to refresh their window when dragging between displays with // different pixel ratios. - ImGui::GetIO().FontGlobalScale = pixelRatio; + io.FontGlobalScale = pixelRatio; ImGui::GetStyle().ScaleAllSizes(pixelRatio); } const auto size = guiView->getViewport(); mImGuiHelper->setDisplaySize(size.width, size.height, 1, 1); - ImGuiIO& io = ImGui::GetIO(); - io.MousePos.x = mouseX; - io.MousePos.y = mouseY; - io.MouseWheel += mouseWheelY; - io.MouseDown[0] = mouseButton; - io.MouseDown[1] = false; - io.MouseDown[2] = false; - mImGuiHelper->render(timeStepInSeconds, [this](Engine*, View*) { this->updateUserInterface(); }); } +void SimpleViewer::mouseEvent(float mouseX, float mouseY, bool mouseButton, float mouseWheelY, + bool control) { + if (mImGuiHelper) { + ImGuiIO& io = ImGui::GetIO(); + io.MousePos.x = mouseX; + io.MousePos.y = mouseY; + io.MouseWheel += mouseWheelY; + io.MouseDown[0] = mouseButton != 0; + io.MouseDown[1] = false; + io.MouseDown[2] = false; + io.KeyCtrl = control; + } +} + +void SimpleViewer::keyDownEvent(int keyCode) { + if (mImGuiHelper && keyCode < IM_ARRAYSIZE(ImGui::GetIO().KeysDown)) { + ImGui::GetIO().KeysDown[keyCode] = true; + } +} + +void SimpleViewer::keyUpEvent(int keyCode) { + if (mImGuiHelper && keyCode < IM_ARRAYSIZE(ImGui::GetIO().KeysDown)) { + ImGui::GetIO().KeysDown[keyCode] = false; + } +} + +void SimpleViewer::keyPressEvent(int charCode) { + if (mImGuiHelper) { + ImGui::GetIO().AddInputCharacter(charCode); + } +} + void SimpleViewer::updateUserInterface() { using namespace filament; diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index f44c9374e4..5b34a6dc3a 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -1855,7 +1855,11 @@ class_("JsonSerializer") class_("SimpleViewer") .constructor() .function("renderUserInterface", &SimpleViewer::renderUserInterface, allow_raw_pointers()) - .function("getSettings", &SimpleViewer::getSettings); + .function("getSettings", &SimpleViewer::getSettings) + .function("mouseEvent", &SimpleViewer::mouseEvent) + .function("keyDownEvent", &SimpleViewer::keyDownEvent) + .function("keyUpEvent", &SimpleViewer::keyUpEvent) + .function("keyPressEvent", &SimpleViewer::keyPressEvent); } // EMSCRIPTEN_BINDINGS diff --git a/web/samples/remote.html b/web/samples/remote.html index d9390231be..0488dafcde 100644 --- a/web/samples/remote.html +++ b/web/samples/remote.html @@ -135,7 +135,7 @@ class App { // In the future we might want to draw stuff in the central 3D viewport. const kInitialSidebarWidth = this.canvas.clientWidth * window.devicePixelRatio; - // Clear the central 3D viewport to light gray, whicht is not visible by default. + // Clear the central 3D viewport to light gray, which is not visible by default. const L = 189 / 255; const kBackgroundColor = [L, L, L, 1]; this.renderer.setClearOptions({clearColor: kBackgroundColor, clear: true}); @@ -145,7 +145,7 @@ class App { this.mouseX = -1; this.mouseY = -1; - this.mouseButton = false; + this.mouseButton = null; this.mouseButtonEvents = []; this.mouseWheelY = 0; @@ -155,10 +155,17 @@ class App { this.mouseX = e.offsetX * window.devicePixelRatio; this.mouseY = e.offsetY * window.devicePixelRatio; }); - this.canvas.addEventListener("pointerup", e => this.mouseButtonEvents.push(false)); - this.canvas.addEventListener("pointerdown", e => this.mouseButtonEvents.push(true)); + + this.canvas.addEventListener("pointerup", e => this.mouseButtonEvents.push(null)); + this.canvas.addEventListener("pointerdown", e => this.mouseButtonEvents.push(e)); this.canvas.addEventListener("mousewheel", e => this.mouseWheelY = e.deltaY / 8); + this.canvas.addEventListener("contextmenu", event => event.preventDefault()); + + document.addEventListener("keydown", e => this.simpleViewer.keyDownEvent(e.keyCode)); + document.addEventListener("keyup", e => this.simpleViewer.keyUpEvent(e.keyCode)); + document.addEventListener("keypress", e => this.simpleViewer.keyPressEvent(e.charCode)); + const resize = () => { const dpr = window.devicePixelRatio; const width = this.canvas.clientWidth * dpr; @@ -263,6 +270,8 @@ class App { } const mouseWheel = this.mouseWheelY; this.mouseWheelY = 0; + this.simpleViewer.mouseEvent(this.mouseX, this.mouseY, !!this.mouseButton, + mouseWheel, this.mouseButton && this.mouseButton.ctrlKey); // If there's no connection, let Filament clear the canvas, but do not render the UI view. if (!connection) { @@ -276,8 +285,7 @@ class App { // Draw the UI and potentially mutate the settings object. const deltaTime = 1.0 / 60.0; - this.simpleViewer.renderUserInterface(deltaTime, this.uiview, window.devicePixelRatio, - this.mouseX, this.mouseY, this.mouseButton, mouseWheel); + this.simpleViewer.renderUserInterface(deltaTime, this.uiview, window.devicePixelRatio); // Check if the user has changed any settings. const settingsJson = this.serializer.writeJson(this.simpleViewer.getSettings()).slice(); From 239b933d5ef30940061cb3018812871eccf905ce Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Tue, 30 Mar 2021 14:05:53 -0700 Subject: [PATCH 05/39] Fix VSM on Android (#3719) --- filament/backend/src/opengl/OpenGLDriver.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index 8890bf2e91..2d6e6585f5 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -847,6 +847,17 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, } } + // We can't use FramebufferTexture2DMultisampleEXT with GL_TEXTURE_2D_ARRAY. + if (!(target == GL_TEXTURE_2D || + target == GL_TEXTURE_CUBE_MAP_POSITIVE_X || + target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X || + target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y || + target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y || + target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z || + target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)) { + attachmentTypeNotSupportedByMSRTT = true; + } + if (rt->gl.samples <= 1 || (rt->gl.samples > 1 && t->samples > 1 && gl.features.multisample_texture)) { // on GL3.2 / GLES3.1 and above multisample is handled when creating the texture. @@ -900,6 +911,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, t->gl.id); } + CHECK_GL_ERROR(utils::slog.e) } else #endif if (!any(t->usage & TextureUsage::SAMPLEABLE) && t->samples > 1) { From 625c4d896857de35f9faa0d7653f1131fc82285b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 30 Mar 2021 13:09:10 -0700 Subject: [PATCH 06/39] implement query for texture swizzle unfortunately metal does support texture swizzle on all versions of macos we support. --- android/filament-android/src/main/cpp/Texture.cpp | 7 +++++++ .../java/com/google/android/filament/Texture.java | 12 ++++++++++++ .../backend/include/private/backend/DriverAPI.inc | 1 + filament/backend/src/metal/MetalDriver.mm | 4 ++++ filament/backend/src/noop/NoopDriver.cpp | 4 ++++ filament/backend/src/opengl/OpenGLDriver.cpp | 4 ++++ filament/backend/src/vulkan/VulkanDriver.cpp | 4 ++++ filament/include/filament/Texture.h | 7 +++++++ filament/src/Texture.cpp | 8 ++++++++ filament/src/details/Texture.h | 3 +++ 10 files changed, 54 insertions(+) diff --git a/android/filament-android/src/main/cpp/Texture.cpp b/android/filament-android/src/main/cpp/Texture.cpp index 519c4b9d4d..ba91618afb 100644 --- a/android/filament-android/src/main/cpp/Texture.cpp +++ b/android/filament-android/src/main/cpp/Texture.cpp @@ -51,6 +51,13 @@ Java_com_google_android_filament_Texture_nIsTextureFormatSupported(JNIEnv*, jcla (Texture::InternalFormat) internalFormat); } +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Texture_nIsTextureSwizzleSupported(JNIEnv*, jclass, + jlong nativeEngine) { + Engine *engine = (Engine *) nativeEngine; + return (jboolean) Texture::isTextureSwizzleSupported(*engine); +} + // Texture::Builder... extern "C" JNIEXPORT jlong JNICALL diff --git a/android/filament-android/src/main/java/com/google/android/filament/Texture.java b/android/filament-android/src/main/java/com/google/android/filament/Texture.java index 60ab2905c1..a971fc142d 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/Texture.java +++ b/android/filament-android/src/main/java/com/google/android/filament/Texture.java @@ -562,6 +562,17 @@ public class Texture { return nIsTextureFormatSupported(engine.getNativeObject(), format.ordinal()); } + /** + * Checks whether texture swizzling is supported in this {@link Engine}. + * This depends on the selected backend. + * + * @param engine {@link Engine} + * @return true if texture swizzling. + */ + public static boolean isTextureSwizzleSupported(@NonNull Engine engine) { + return nIsTextureSwizzleSupported(engine.getNativeObject()); + } + /** * Use Builder to construct a Texture object instance. */ @@ -1137,6 +1148,7 @@ public class Texture { } private static native boolean nIsTextureFormatSupported(long nativeEngine, int internalFormat); + private static native boolean nIsTextureSwizzleSupported(long nativeEngine); private static native long nCreateBuilder(); private static native void nDestroyBuilder(long nativeBuilder); diff --git a/filament/backend/include/private/backend/DriverAPI.inc b/filament/backend/include/private/backend/DriverAPI.inc index 3ff09acde1..f11e3d9b64 100644 --- a/filament/backend/include/private/backend/DriverAPI.inc +++ b/filament/backend/include/private/backend/DriverAPI.inc @@ -287,6 +287,7 @@ DECL_DRIVER_API_SYNCHRONOUS_N(void, updateStreams, backend::DriverApi*, driver) DECL_DRIVER_API_SYNCHRONOUS_N(void, destroyFence, backend::FenceHandle, fh) DECL_DRIVER_API_SYNCHRONOUS_N(backend::FenceStatus, wait, backend::FenceHandle, fh, uint64_t, timeout) DECL_DRIVER_API_SYNCHRONOUS_N(bool, isTextureFormatSupported, backend::TextureFormat, format) +DECL_DRIVER_API_SYNCHRONOUS_0(bool, isTextureSwizzleSupported) DECL_DRIVER_API_SYNCHRONOUS_N(bool, isTextureFormatMipmappable, backend::TextureFormat, format) DECL_DRIVER_API_SYNCHRONOUS_N(bool, isRenderTargetFormatSupported, backend::TextureFormat, format) DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchSupported) diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index 19e40c1039..049839c4ad 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -550,6 +550,10 @@ bool MetalDriver::isTextureFormatSupported(TextureFormat format) { TextureReshaper::canReshapeTextureFormat(format); } +bool MetalDriver::isTextureSwizzleSupported() { + return false; +} + bool MetalDriver::isTextureFormatMipmappable(TextureFormat format) { // Derived from the Metal 3.0 Feature Set Tables. // In order for a format to be mipmappable, it must be color-renderable and filterable. diff --git a/filament/backend/src/noop/NoopDriver.cpp b/filament/backend/src/noop/NoopDriver.cpp index 5b843d2f48..96fa53800a 100644 --- a/filament/backend/src/noop/NoopDriver.cpp +++ b/filament/backend/src/noop/NoopDriver.cpp @@ -144,6 +144,10 @@ bool NoopDriver::isTextureFormatSupported(TextureFormat format) { return true; } +bool NoopDriver::isTextureSwizzleSupported() { + return true; +} + bool NoopDriver::isTextureFormatMipmappable(backend::TextureFormat format) { return true; } diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index 2d6e6585f5..a0209573d0 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -1491,6 +1491,10 @@ bool OpenGLDriver::isTextureFormatSupported(TextureFormat format) { return getInternalFormat(format) != 0; } +bool OpenGLDriver::isTextureSwizzleSupported() { + return true; +} + bool OpenGLDriver::isTextureFormatMipmappable(TextureFormat format) { // The OpenGL spec for GenerateMipmap stipulates that it returns INVALID_OPERATION unless // the sized internal format is both color-renderable and texture-filterable. diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 59027c34ee..75d0a2b014 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -795,6 +795,10 @@ bool VulkanDriver::isTextureFormatSupported(TextureFormat format) { return info.optimalTilingFeatures != 0; } +bool VulkanDriver::isTextureSwizzleSupported() { + return false; // TODO: implement texture swizzling +} + bool VulkanDriver::isTextureFormatMipmappable(backend::TextureFormat format) { switch (format) { case TextureFormat::DEPTH16: diff --git a/filament/include/filament/Texture.h b/filament/include/filament/Texture.h index a88cc35f95..d3c0afde48 100644 --- a/filament/include/filament/Texture.h +++ b/filament/include/filament/Texture.h @@ -79,8 +79,12 @@ public: using Usage = backend::TextureUsage; //!< Usage affects texel layout using Swizzle = backend::TextureSwizzle; //!< Texture swizzle + /** @return whether a backend supports a particular format. */ static bool isTextureFormatSupported(Engine& engine, InternalFormat format) noexcept; + /** @return whether a backend supports texture swizzling. */ + static bool isTextureSwizzleSupported(Engine& engine) noexcept; + static size_t computeTextureDataSize(Texture::Format format, Texture::Type type, size_t stride, size_t height, size_t alignment) noexcept; @@ -177,11 +181,14 @@ public: /** * Specifies how a texture's channels map to color components * + * Texture Swizzle is only supported is isTextureSwizzleSupported() returns true. + * * @param r texture channel for red component * @param g texture channel for green component * @param b texture channel for blue component * @param a texture channel for alpha component * @return This Builder, for chaining calls. + * @see Texture::isTextureSwizzleSupported() */ Builder& swizzle(Swizzle r, Swizzle g, Swizzle b, Swizzle a) noexcept; diff --git a/filament/src/Texture.cpp b/filament/src/Texture.cpp index f269e0ded5..07133bec4a 100644 --- a/filament/src/Texture.cpp +++ b/filament/src/Texture.cpp @@ -443,6 +443,10 @@ bool FTexture::isTextureFormatSupported(FEngine& engine, InternalFormat format) return engine.getDriverApi().isTextureFormatSupported(format); } +bool FTexture::isTextureSwizzleSupported(FEngine& engine) noexcept { + return engine.getDriverApi().isTextureSwizzleSupported(); +} + size_t FTexture::computeTextureDataSize(Texture::Format format, Texture::Type type, size_t stride, size_t height, size_t alignment) noexcept { return PixelBufferDescriptor::computeDataSize(format, type, stride, height, alignment); @@ -1090,6 +1094,10 @@ bool Texture::isTextureFormatSupported(Engine& engine, InternalFormat format) no return FTexture::isTextureFormatSupported(upcast(engine), format); } +bool Texture::isTextureSwizzleSupported(Engine& engine) noexcept { + return FTexture::isTextureSwizzleSupported(upcast(engine)); +} + size_t Texture::computeTextureDataSize(Texture::Format format, Texture::Type type, size_t stride, size_t height, size_t alignment) noexcept { return FTexture::computeTextureDataSize(format, type, stride, height, alignment); diff --git a/filament/src/details/Texture.h b/filament/src/details/Texture.h index 1e9f6e9005..b75f475575 100644 --- a/filament/src/details/Texture.h +++ b/filament/src/details/Texture.h @@ -86,6 +86,9 @@ public: // synchronous call to the backend. returns whether a backend supports a particular format. static bool isTextureFormatSupported(FEngine& engine, InternalFormat format) noexcept; + // synchronous call to the backend. returns whether a backend supports texture swizzling. + static bool isTextureSwizzleSupported(FEngine& engine) noexcept; + // storage needed on the CPU side for texture data uploads static size_t computeTextureDataSize(Texture::Format format, Texture::Type type, size_t stride, size_t height, size_t alignment) noexcept; From d11f3f7d5aa4a328f88990ae15ca337af6d2fb8a Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Tue, 30 Mar 2021 15:38:55 -0700 Subject: [PATCH 07/39] Implement Metal texture swizzling (#3720) --- filament/backend/src/metal/MetalDriver.mm | 12 +++++++---- filament/backend/src/metal/MetalEnums.h | 25 ++++++++++++++++++++++ filament/backend/src/metal/MetalHandles.h | 3 ++- filament/backend/src/metal/MetalHandles.mm | 12 ++++++++++- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index 049839c4ad..0515965844 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -176,7 +176,8 @@ void MetalDriver::createTextureR(Handle th, SamplerType target, uint8 TextureFormat format, uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage) { construct_handle(mHandleMap, th, *mContext, target, levels, format, samples, - width, height, depth, usage); + width, height, depth, usage, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_1, + TextureSwizzle::CHANNEL_2, TextureSwizzle::CHANNEL_3); } void MetalDriver::createTextureSwizzledR(Handle th, SamplerType target, uint8_t levels, @@ -184,8 +185,7 @@ void MetalDriver::createTextureSwizzledR(Handle th, SamplerType targe uint32_t depth, TextureUsage usage, TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a) { construct_handle(mHandleMap, th, *mContext, target, levels, format, samples, - width, height, depth, usage); - // TODO: implement texture swizzle + width, height, depth, usage, r, g, b, a); } void MetalDriver::importTextureR(Handle th, intptr_t i, @@ -551,7 +551,11 @@ bool MetalDriver::isTextureFormatSupported(TextureFormat format) { } bool MetalDriver::isTextureSwizzleSupported() { - return false; + if (@available(macOS 10.15, iOS 13, *)) { + return true; + } else { + return false; + } } bool MetalDriver::isTextureFormatMipmappable(TextureFormat format) { diff --git a/filament/backend/src/metal/MetalEnums.h b/filament/backend/src/metal/MetalEnums.h index b22a66067c..cef91ce9b1 100644 --- a/filament/backend/src/metal/MetalEnums.h +++ b/filament/backend/src/metal/MetalEnums.h @@ -419,6 +419,31 @@ constexpr inline MTLCompareFunction getCompareFunction(SamplerCompareFunc compar } } +API_AVAILABLE(macos(10.15), ios(13.0)) +MTLTextureSwizzle getSwizzle(TextureSwizzle swizzle) { + switch (swizzle) { + case TextureSwizzle::SUBSTITUTE_ZERO: + return MTLTextureSwizzleZero; + case TextureSwizzle::SUBSTITUTE_ONE: + return MTLTextureSwizzleOne; + case TextureSwizzle::CHANNEL_0: + return MTLTextureSwizzleRed; + case TextureSwizzle::CHANNEL_1: + return MTLTextureSwizzleGreen; + case TextureSwizzle::CHANNEL_2: + return MTLTextureSwizzleBlue; + case TextureSwizzle::CHANNEL_3: + return MTLTextureSwizzleAlpha; + } +} + +API_AVAILABLE(macos(10.15), ios(13.0)) +MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, + TextureSwizzle a) { + return MTLTextureSwizzleChannelsMake(getSwizzle(r), getSwizzle(g), getSwizzle(b), + getSwizzle(a)); +} + } // namespace backend } // namespace filament diff --git a/filament/backend/src/metal/MetalHandles.h b/filament/backend/src/metal/MetalHandles.h index 8d2587138d..787a7cfc4c 100644 --- a/filament/backend/src/metal/MetalHandles.h +++ b/filament/backend/src/metal/MetalHandles.h @@ -158,7 +158,8 @@ struct MetalProgram : public HwProgram { struct MetalTexture : public HwTexture { MetalTexture(MetalContext& context, SamplerType target, uint8_t levels, TextureFormat format, - uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage) + uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage, + TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a) noexcept; // Constructor for importing an id outside of Filament. diff --git a/filament/backend/src/metal/MetalHandles.mm b/filament/backend/src/metal/MetalHandles.mm index 5a2c67961f..c755edede9 100644 --- a/filament/backend/src/metal/MetalHandles.mm +++ b/filament/backend/src/metal/MetalHandles.mm @@ -416,7 +416,8 @@ static MTLPixelFormat decidePixelFormat(id device, TextureFormat form MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t levels, TextureFormat format, uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, - TextureUsage usage) noexcept + TextureUsage usage, TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, + TextureSwizzle a) noexcept : HwTexture(target, levels, samples, width, height, depth, format, usage), context(context), externalImage(context), reshaper(format) { @@ -467,6 +468,12 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le } }; + auto setUpSwizzle = [r, g, b, a](MTLTextureDescriptor* descriptor) { + if (@available(macOS 10.15, iOS 13, *)) { + descriptor.swizzle = getSwizzleChannels(r, g, b, a); + } + }; + MTLTextureDescriptor* descriptor; switch (target) { case SamplerType::SAMPLER_2D: @@ -481,6 +488,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le descriptor.sampleCount = multisampled ? samples : 1; descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; + setUpSwizzle(descriptor); texture = [context.device newTextureWithDescriptor:descriptor]; ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); break; @@ -493,6 +501,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le descriptor.mipmapLevelCount = levels; descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; + setUpSwizzle(descriptor); texture = [context.device newTextureWithDescriptor:descriptor]; ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); break; @@ -506,6 +515,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le descriptor.mipmapLevelCount = levels; descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; + setUpSwizzle(descriptor); texture = [context.device newTextureWithDescriptor:descriptor]; ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); break; From 67a936d845022b60d64b64e62a5ee0b9792d198b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 30 Mar 2021 15:57:46 -0700 Subject: [PATCH 08/39] fix a linker warning --- filament/backend/src/metal/MetalEnums.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/filament/backend/src/metal/MetalEnums.h b/filament/backend/src/metal/MetalEnums.h index cef91ce9b1..c346bb54fd 100644 --- a/filament/backend/src/metal/MetalEnums.h +++ b/filament/backend/src/metal/MetalEnums.h @@ -420,7 +420,7 @@ constexpr inline MTLCompareFunction getCompareFunction(SamplerCompareFunc compar } API_AVAILABLE(macos(10.15), ios(13.0)) -MTLTextureSwizzle getSwizzle(TextureSwizzle swizzle) { +constexpr inline MTLTextureSwizzle getSwizzle(TextureSwizzle swizzle) { switch (swizzle) { case TextureSwizzle::SUBSTITUTE_ZERO: return MTLTextureSwizzleZero; @@ -438,7 +438,7 @@ MTLTextureSwizzle getSwizzle(TextureSwizzle swizzle) { } API_AVAILABLE(macos(10.15), ios(13.0)) -MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, +inline MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a) { return MTLTextureSwizzleChannelsMake(getSwizzle(r), getSwizzle(g), getSwizzle(b), getSwizzle(a)); From 9fcb8ccb9e753a1a9bc256c829cd96537f5f5c86 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 30 Mar 2021 21:34:22 -0700 Subject: [PATCH 09/39] DoF: document a typo there has been a typo in the DoF code a while, but fixing it looks much worse. we need to understand why. so for now we at least document the typo in the code. --- filament/src/materials/dof/dof.mat | 3 +++ 1 file changed, 3 insertions(+) diff --git a/filament/src/materials/dof/dof.mat b/filament/src/materials/dof/dof.mat index 642429eba5..da1fbdd4de 100644 --- a/filament/src/materials/dof/dof.mat +++ b/filament/src/materials/dof/dof.mat @@ -303,6 +303,9 @@ void accumulate(inout Bucket curr, inout Bucket prev, const Sample tap, void accumulateBackground(inout Bucket curr, inout Bucket prev, const highp vec2 pos, const float radius, const float border, const float mip, const bool first) { Sample tap; + // FIXME: there are typos below. We should use materialParams_background and + // materialParams_cocFgBg's green (background coc) channel. + // however doing so, looks much worse and is much more unstable. tap.s = textureLod(materialParams_foreground, pos, mip); tap.coc = textureLod(materialParams_cocFgBg, pos, mip).r; accumulate(curr, prev, tap, radius, border, mip, first); From ac56efcd95bd5c40e1bd44b154d5cc6de272c296 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 31 Mar 2021 10:08:36 -0700 Subject: [PATCH 10/39] Revert misguided attempt to fix bloom with glTF (#3728) * Revert misguided attempt to fix bloom with glTF * Put back line removed by mistake --- libs/gltfio/src/AssetLoader.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libs/gltfio/src/AssetLoader.cpp b/libs/gltfio/src/AssetLoader.cpp index c00f7c11a3..d051f41f20 100644 --- a/libs/gltfio/src/AssetLoader.cpp +++ b/libs/gltfio/src/AssetLoader.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -989,10 +988,7 @@ MaterialInstance* FAssetLoader::createMaterialInstance(const cgltf_material* inp } const float* e = inputMat->emissive_factor; - // To force emissive to bloom when emissiveFactor is at 1, we multiply by a luminance - // of 6EV. At 6EV, the luminance will be 2^(6-3) = 8 which is about the HDR range of - // our default tone mappers. - mi->setParameter("emissiveFactor", float3(e[0], e[1], e[2]) * Exposure::luminance(6.0f)); + mi->setParameter("emissiveFactor", float3(e[0], e[1], e[2])); const float* c = mrConfig.base_color_factor; mi->setParameter("baseColorFactor", float4(c[0], c[1], c[2], c[3])); From c4eb790065cccc4f7390581a39923e2d0e81a459 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 29 Mar 2021 16:17:21 -0700 Subject: [PATCH 11/39] Add support for texture swizzling in framegraph --- .../backend/include/backend/DriverEnums.h | 2 +- filament/src/ResourceAllocator.cpp | 22 +++++++++++++----- filament/src/ResourceAllocator.h | 23 +++++++++++++------ filament/src/fg2/FrameGraphTexture.cpp | 7 +++++- filament/src/fg2/FrameGraphTexture.h | 10 ++++++++ filament/test/filament_framegraph_test.cpp | 3 ++- 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/filament/backend/include/backend/DriverEnums.h b/filament/backend/include/backend/DriverEnums.h index d116ffa750..1be9eb3d67 100644 --- a/filament/backend/include/backend/DriverEnums.h +++ b/filament/backend/include/backend/DriverEnums.h @@ -513,7 +513,7 @@ enum class TextureUsage : uint8_t { }; //! Texture swizzle -enum class TextureSwizzle { +enum class TextureSwizzle : uint8_t { SUBSTITUTE_ZERO, SUBSTITUTE_ONE, CHANNEL_0, diff --git a/filament/src/ResourceAllocator.cpp b/filament/src/ResourceAllocator.cpp index af743b58da..29deb5eeab 100644 --- a/filament/src/ResourceAllocator.cpp +++ b/filament/src/ResourceAllocator.cpp @@ -109,9 +109,10 @@ void ResourceAllocator::destroyRenderTarget(RenderTargetHandle h) noexcept { } backend::TextureHandle ResourceAllocator::createTexture(const char* name, - backend::SamplerType target, uint8_t levels, - backend::TextureFormat format, uint8_t samples, uint32_t width, uint32_t height, - uint32_t depth, backend::TextureUsage usage) noexcept { + backend::SamplerType target, uint8_t levels, backend::TextureFormat format, uint8_t samples, + uint32_t width, uint32_t height, uint32_t depth, + std::array swizzle, + backend::TextureUsage usage) noexcept { // Some WebGL implementations complain about an incomplete framebuffer when the attachment sizes // are heterogeneous. This merits further investigation. @@ -133,7 +134,7 @@ backend::TextureHandle ResourceAllocator::createTexture(const char* name, TextureHandle handle; if (mEnabled) { auto& textureCache = mTextureCache; - const TextureKey key{ name, target, levels, format, samples, width, height, depth, usage }; + const TextureKey key{ name, target, levels, format, samples, width, height, depth, usage, swizzle }; auto it = textureCache.find(key); if (UTILS_LIKELY(it != textureCache.end())) { // we do, move the entry to the in-use list, and remove from the cache @@ -142,8 +143,17 @@ backend::TextureHandle ResourceAllocator::createTexture(const char* name, textureCache.erase(it); } else { // we don't, allocate a new texture and populate the in-use list - handle = mBackend.createTexture( - target, levels, format, samples, width, height, depth, usage); + using TS = backend::TextureSwizzle; + constexpr const auto defaultSwizzle = std::array{ + TS::CHANNEL_0, TS::CHANNEL_1, TS::CHANNEL_2, TS::CHANNEL_3}; + if (swizzle == defaultSwizzle) { + handle = mBackend.createTexture( + target, levels, format, samples, width, height, depth, usage); + } else { + handle = mBackend.createTextureSwizzled( + target, levels, format, samples, width, height, depth, usage, + swizzle[0], swizzle[1], swizzle[2], swizzle[3]); + } } mInUseTextures.emplace(handle, key); } else { diff --git a/filament/src/ResourceAllocator.h b/filament/src/ResourceAllocator.h index 2df9cd7a12..18d9eb1201 100644 --- a/filament/src/ResourceAllocator.h +++ b/filament/src/ResourceAllocator.h @@ -25,6 +25,7 @@ #include +#include #include #include @@ -47,9 +48,10 @@ public: virtual void destroyRenderTarget(backend::RenderTargetHandle h) noexcept = 0; virtual backend::TextureHandle createTexture(const char* name, backend::SamplerType target, - uint8_t levels, - backend::TextureFormat format, uint8_t samples, uint32_t width, uint32_t height, - uint32_t depth, backend::TextureUsage usage) noexcept = 0; + uint8_t levels,backend::TextureFormat format, uint8_t samples, + uint32_t width, uint32_t height, uint32_t depth, + std::array swizzle, + backend::TextureUsage usage) noexcept = 0; virtual void destroyTexture(backend::TextureHandle h) noexcept = 0; @@ -77,9 +79,10 @@ public: void destroyRenderTarget(backend::RenderTargetHandle h) noexcept override; backend::TextureHandle createTexture(const char* name, backend::SamplerType target, - uint8_t levels, - backend::TextureFormat format, uint8_t samples, uint32_t width, uint32_t height, - uint32_t depth, backend::TextureUsage usage) noexcept override; + uint8_t levels, backend::TextureFormat format, uint8_t samples, + uint32_t width, uint32_t height, uint32_t depth, + std::array swizzle, + backend::TextureUsage usage) noexcept override; void destroyTexture(backend::TextureHandle h) noexcept override; @@ -100,6 +103,7 @@ private: uint32_t height; uint32_t depth; backend::TextureUsage usage; + std::array swizzle; size_t getSize() const noexcept; @@ -111,7 +115,8 @@ private: width == other.width && height == other.height && depth == other.depth && - usage == other.usage; + usage == other.usage && + swizzle == other.swizzle; } friend size_t hash_value(TextureKey const& k) { @@ -124,6 +129,10 @@ private: utils::hash::combine_fast(seed, k.height); utils::hash::combine_fast(seed, k.depth); utils::hash::combine_fast(seed, k.usage); + utils::hash::combine_fast(seed, k.swizzle[0]); + utils::hash::combine_fast(seed, k.swizzle[1]); + utils::hash::combine_fast(seed, k.swizzle[2]); + utils::hash::combine_fast(seed, k.swizzle[3]); return seed; } }; diff --git a/filament/src/fg2/FrameGraphTexture.cpp b/filament/src/fg2/FrameGraphTexture.cpp index 9d922b44c7..a7b03da869 100644 --- a/filament/src/fg2/FrameGraphTexture.cpp +++ b/filament/src/fg2/FrameGraphTexture.cpp @@ -24,10 +24,15 @@ namespace filament { void FrameGraphTexture::create(ResourceAllocatorInterface& resourceAllocator, const char* name, FrameGraphTexture::Descriptor const& descriptor, FrameGraphTexture::Usage usage) noexcept { + std::array swizzle = { + descriptor.swizzle.r, + descriptor.swizzle.g, + descriptor.swizzle.b, + descriptor.swizzle.a }; handle = resourceAllocator.createTexture(name, descriptor.type, descriptor.levels, descriptor.format, descriptor.samples, descriptor.width, descriptor.height, descriptor.depth, - usage); + swizzle, usage); } void FrameGraphTexture::destroy(ResourceAllocatorInterface& resourceAllocator) noexcept { diff --git a/filament/src/fg2/FrameGraphTexture.h b/filament/src/fg2/FrameGraphTexture.h index 86dab22574..a1064bbaad 100644 --- a/filament/src/fg2/FrameGraphTexture.h +++ b/filament/src/fg2/FrameGraphTexture.h @@ -49,6 +49,16 @@ struct FrameGraphTexture { uint8_t samples = 0; // 0=auto, 1=request not multisample, >1 only for NOT SAMPLEABLE backend::SamplerType type = backend::SamplerType::SAMPLER_2D; // texture target type backend::TextureFormat format = backend::TextureFormat::RGBA8; // resource internal format + struct { + using TS = backend::TextureSwizzle; + union { + backend::TextureSwizzle channels[4] = { + TS::CHANNEL_0, TS::CHANNEL_1, TS::CHANNEL_2, TS::CHANNEL_3 }; + struct { + backend::TextureSwizzle r, g, b, a; + }; + }; + } swizzle; }; /** Describes a FrameGraphTexture sub-resource */ diff --git a/filament/test/filament_framegraph_test.cpp b/filament/test/filament_framegraph_test.cpp index 90b77587fc..16cd2d31c8 100644 --- a/filament/test/filament_framegraph_test.cpp +++ b/filament/test/filament_framegraph_test.cpp @@ -51,7 +51,8 @@ public: backend::TextureHandle createTexture(const char* name, backend::SamplerType target, uint8_t levels, backend::TextureFormat format, uint8_t samples, uint32_t width, uint32_t height, - uint32_t depth, backend::TextureUsage usage) noexcept override { + uint32_t depth, std::array, + backend::TextureUsage usage) noexcept override { return backend::TextureHandle(++handle); } From e5bfe81d0c4e241af726ca4074ee86263a3797c1 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 29 Mar 2021 21:28:55 -0700 Subject: [PATCH 12/39] DoF: use only a single low res source for both fg and bg Before we were keeping a foreground and background version of the low resolution source, but in practice it really doesn't make a big difference and we save a fair amount of bandwidth this way. The bulk of the change is to remove a texture/target which mostly affects the downsample and mipmap passes. Also renamed some variables to be less confusing (MaxMin to MinMax for e.g.) and fixed a few typos. --- filament/src/PostProcessManager.cpp | 202 +++++++++---------- filament/src/Renderer.cpp | 4 +- filament/src/materials/dof/dof.mat | 48 ++--- filament/src/materials/dof/dofCoc.mat | 31 ++- filament/src/materials/dof/dofCombine.mat | 4 +- filament/src/materials/dof/dofDilate.mat | 12 -- filament/src/materials/dof/dofDownsample.mat | 65 ++---- filament/src/materials/dof/dofMipmap.mat | 82 ++------ filament/src/materials/dof/dofTiles.mat | 25 +-- filament/src/materials/dof/dofUtils.fs | 20 ++ 10 files changed, 210 insertions(+), 283 deletions(-) diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index 831c6d790c..64a1dacd16 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -940,9 +940,8 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, struct PostProcessDofDownsample { FrameGraphId color; FrameGraphId depth; - FrameGraphId outForeground; - FrameGraphId outBackground; - FrameGraphId outCocFgBg; + FrameGraphId outColor; + FrameGraphId outCoc; }; auto& ppDoFDownsample = fg.addPass("DoF Downsample", @@ -950,21 +949,21 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, data.color = builder.sample(input); data.depth = builder.sample(depth); - data.outForeground = builder.createTexture("dof foreground output", { + data.outColor = builder.createTexture("dof downsample output", { .width = width, .height = height, .levels = mipmapCount, .format = format }); - data.outBackground = builder.createTexture("dof background output", { - .width = width, .height = height, .levels = mipmapCount, .format = format - }); - data.outCocFgBg = builder.createTexture("dof CoC output", { + data.outCoc = builder.createTexture("dof CoC output", { .width = width, .height = height, .levels = mipmapCount, - .format = TextureFormat::RG16F + .format = TextureFormat::R16F, + .swizzle = { + // the next stage expects min/max CoC in the red/green channel + .r = backend::TextureSwizzle::CHANNEL_0, + .g = backend::TextureSwizzle::CHANNEL_0 }, }); - data.outForeground = builder.write(data.outForeground, FrameGraphTexture::Usage::COLOR_ATTACHMENT); - data.outBackground = builder.write(data.outBackground, FrameGraphTexture::Usage::COLOR_ATTACHMENT); - data.outCocFgBg = builder.write(data.outCocFgBg, FrameGraphTexture::Usage::COLOR_ATTACHMENT); + data.outColor = builder.write(data.outColor, FrameGraphTexture::Usage::COLOR_ATTACHMENT); + data.outCoc = builder.write(data.outCoc, FrameGraphTexture::Usage::COLOR_ATTACHMENT); builder.declareRenderPass("DoF Target", { .attachments = { - .color = { data.outForeground, data.outBackground, data.outCocFgBg } + .color = { data.outColor, data.outCoc } } }); }, @@ -990,9 +989,8 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, */ struct PostProcessDofMipmap { - FrameGraphId inOutForeground; - FrameGraphId inOutBackground; - FrameGraphId inOutCocFgBg; + FrameGraphId inOutColor; + FrameGraphId inOutCoc; uint32_t rp[maxMipLevels]; }; @@ -1000,25 +998,22 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, auto& ppDoFMipmap = fg.addPass("DoF Mipmap", [&](FrameGraph::Builder& builder, auto& data) { - data.inOutForeground = builder.sample(ppDoFDownsample->outForeground); - data.inOutBackground = builder.sample(ppDoFDownsample->outBackground); - data.inOutCocFgBg = builder.sample(ppDoFDownsample->outCocFgBg); + data.inOutColor = builder.sample(ppDoFDownsample->outColor); + data.inOutCoc = builder.sample(ppDoFDownsample->outCoc); for (size_t i = 0; i < mipmapCount - 1u; i++) { // make sure inputs are always multiple of two (should be true by construction) // (this is so that we can compute clean mip levels) - assert_invariant((FTexture::valueForLevel(uint8_t(i), fg.getDescriptor(data.inOutForeground).width ) & 0x1u) == 0); - assert_invariant((FTexture::valueForLevel(uint8_t(i), fg.getDescriptor(data.inOutForeground).height) & 0x1u) == 0); + assert_invariant((FTexture::valueForLevel(uint8_t(i), fg.getDescriptor(data.inOutColor).width ) & 0x1u) == 0); + assert_invariant((FTexture::valueForLevel(uint8_t(i), fg.getDescriptor(data.inOutColor).height) & 0x1u) == 0); - auto inOutForeground = builder.createSubresource(data.inOutForeground, "Forground mip", { .level = uint8_t(i + 1) }); - auto inOutBackground = builder.createSubresource(data.inOutBackground, "Background mip", { .level = uint8_t(i + 1) }); - auto inOutCocFgBg = builder.createSubresource(data.inOutCocFgBg , "CocFgBg mip", { .level = uint8_t(i + 1) }); + auto inOutColor = builder.createSubresource(data.inOutColor, "Color mip", { .level = uint8_t(i + 1) }); + auto inOutCoc = builder.createSubresource(data.inOutCoc, "Coc mip", { .level = uint8_t(i + 1) }); - inOutForeground = builder.write(inOutForeground, FrameGraphTexture::Usage::COLOR_ATTACHMENT); - inOutBackground = builder.write(inOutBackground, FrameGraphTexture::Usage::COLOR_ATTACHMENT); - inOutCocFgBg = builder.write(inOutCocFgBg, FrameGraphTexture::Usage::COLOR_ATTACHMENT); + inOutColor = builder.write(inOutColor, FrameGraphTexture::Usage::COLOR_ATTACHMENT); + inOutCoc = builder.write(inOutCoc, FrameGraphTexture::Usage::COLOR_ATTACHMENT); data.rp[i] = builder.declareRenderPass("DoF Target", { .attachments = { - .color = { inOutForeground, inOutBackground, inOutCocFgBg } + .color = { inOutColor, inOutCoc } } }); } @@ -1026,15 +1021,13 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { - auto inOutForeground = resources.getTexture(data.inOutForeground); - auto inOutBackground = resources.getTexture(data.inOutBackground); - auto inOutCocFgBg = resources.getTexture(data.inOutCocFgBg); + auto inOutColor = resources.getTexture(data.inOutColor); + auto inOutCoc = resources.getTexture(data.inOutCoc); auto const& material = getPostProcessMaterial("dofMipmap"); FMaterialInstance* const mi = material.getMaterialInstance(); - mi->setParameter("foreground", inOutForeground, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); - mi->setParameter("background", inOutBackground, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); - mi->setParameter("cocFgBg", inOutCocFgBg, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); + mi->setParameter("color", inOutColor, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); + mi->setParameter("coc", inOutCoc, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); mi->use(driver); const PipelineState pipeline(material.getPipelineState(variant)); @@ -1055,7 +1048,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, * - Generate min/max tiles for far/near fields (continued) */ - auto inTilesCocMaxMin = ppDoFDownsample->outCocFgBg; + auto inTilesCocMinMax = ppDoFDownsample->outCoc; // TODO: Should the tile size be in real pixels? i.e. always 16px instead of being dependant on // the DoF effect resolution? @@ -1067,8 +1060,8 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, const size_t tileReductionCount = std::log2(tileSize / dofResolution); struct PostProcessDofTiling1 { - FrameGraphId inCocMaxMin; - FrameGraphId outTilesCocMaxMin; + FrameGraphId inCocMinMax; + FrameGraphId outTilesCocMinMax; }; for (size_t i = 0; i < tileReductionCount; i++) { @@ -1076,29 +1069,29 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, [&](FrameGraph::Builder& builder, auto& data) { assert_invariant(((tileBufferWidth >> i) & 1u) == 0); assert_invariant(((tileBufferHeight >> i) & 1u) == 0); - data.inCocMaxMin = builder.sample(inTilesCocMaxMin); - data.outTilesCocMaxMin = builder.createTexture("dof tiles output", { + data.inCocMinMax = builder.sample(inTilesCocMinMax); + data.outTilesCocMinMax = builder.createTexture("dof tiles output", { .width = tileBufferWidth >> (i + 1u), .height = tileBufferHeight >> (i + 1u), .format = TextureFormat::RG16F }); - data.outTilesCocMaxMin = builder.declareRenderPass(data.outTilesCocMaxMin); + data.outTilesCocMinMax = builder.declareRenderPass(data.outTilesCocMinMax); }, [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { - auto const& inputDesc = resources.getDescriptor(data.inCocMaxMin); - auto const& outputDesc = resources.getDescriptor(data.outTilesCocMaxMin); + auto const& inputDesc = resources.getDescriptor(data.inCocMinMax); + auto const& outputDesc = resources.getDescriptor(data.outTilesCocMinMax); auto const& out = resources.getRenderPassInfo(); - auto inCocMaxMin = resources.getTexture(data.inCocMaxMin); + auto inCocMinMax = resources.getTexture(data.inCocMinMax); auto const& material = getPostProcessMaterial("dofTiles"); FMaterialInstance* const mi = material.getMaterialInstance(); - mi->setParameter("cocMaxMin", inCocMaxMin, { .filterMin = SamplerMinFilter::NEAREST }); + mi->setParameter("cocMinMax", inCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("uvscale", float4{ outputDesc.width, outputDesc.height, 1.0f / inputDesc.width, 1.0f / inputDesc.height }); commitAndRender(out, material, driver); }); - inTilesCocMaxMin = ppDoFTiling->outTilesCocMaxMin; + inTilesCocMinMax = ppDoFTiling->outTilesCocMinMax; } /* @@ -1109,33 +1102,33 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, auto dilate = [&](FrameGraphId input) -> FrameGraphId { struct PostProcessDofDilate { - FrameGraphId inTilesCocMaxMin; - FrameGraphId outTilesCocMaxMin; + FrameGraphId inTilesCocMinMax; + FrameGraphId outTilesCocMinMax; }; auto& ppDoFDilate = fg.addPass("DoF Dilate", [&](FrameGraph::Builder& builder, auto& data) { auto const& inputDesc = fg.getDescriptor(input); - data.inTilesCocMaxMin = builder.sample(input); - data.outTilesCocMaxMin = builder.createTexture("dof dilated tiles output", inputDesc); - data.outTilesCocMaxMin = builder.declareRenderPass(data.outTilesCocMaxMin ); + data.inTilesCocMinMax = builder.sample(input); + data.outTilesCocMinMax = builder.createTexture("dof dilated tiles output", inputDesc); + data.outTilesCocMinMax = builder.declareRenderPass(data.outTilesCocMinMax ); }, [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { auto const& out = resources.getRenderPassInfo(); - auto inTilesCocMaxMin = resources.getTexture(data.inTilesCocMaxMin); + auto inTilesCocMinMax = resources.getTexture(data.inTilesCocMinMax); auto const& material = getPostProcessMaterial("dofDilate"); FMaterialInstance* const mi = material.getMaterialInstance(); - mi->setParameter("tiles", inTilesCocMaxMin, { .filterMin = SamplerMinFilter::NEAREST }); + mi->setParameter("tiles", inTilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); commitAndRender(out, material, driver); }); - return ppDoFDilate->outTilesCocMaxMin; + return ppDoFDilate->outTilesCocMinMax; }; // Tiles of 16 full-resolution pixels requires two dilate rounds to accommodate our max Coc of 32 pixels // (note: when running at half-res, the tiles are 8 half-resolution pixels, and still need two // dilate rounds to accommodate the mac CoC pf 16 half-resolution pixels) - auto dilated = dilate(inTilesCocMaxMin); + auto dilated = dilate(inTilesCocMinMax); dilated = dilate(dilated); /* @@ -1143,64 +1136,59 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, */ struct PostProcessDof { - FrameGraphId foreground; - FrameGraphId background; - FrameGraphId cocFgBg; - FrameGraphId tilesCocMaxMin; - FrameGraphId outForeground; + FrameGraphId color; + FrameGraphId coc; + FrameGraphId tilesCocMinMax; + FrameGraphId outColor; FrameGraphId outAlpha; }; auto& ppDoF = fg.addPass("DoF", [&](FrameGraph::Builder& builder, auto& data) { - data.foreground = builder.sample(ppDoFMipmap->inOutForeground); - data.background = builder.sample(ppDoFMipmap->inOutBackground); - data.cocFgBg = builder.sample(ppDoFMipmap->inOutCocFgBg); - data.tilesCocMaxMin = builder.sample(dilated); + data.color = builder.sample(ppDoFMipmap->inOutColor); + data.coc = builder.sample(ppDoFMipmap->inOutCoc); + data.tilesCocMinMax = builder.sample(dilated); // The DoF buffer (output) doesn't need to be a multiple of 8 because it's not // mipmapped. We just need to adjust the uv properly. - data.outForeground = builder.createTexture("dof color output", { + data.outColor = builder.createTexture("dof color output", { .width = (colorDesc.width + (dofResolution / 2u)) / dofResolution, .height = (colorDesc.height + (dofResolution / 2u)) / dofResolution, - .format = fg.getDescriptor(data.foreground).format + .format = fg.getDescriptor(data.color).format }); data.outAlpha = builder.createTexture("dof alpha output", { - .width = builder.getDescriptor(data.outForeground).width, - .height = builder.getDescriptor(data.outForeground).height, + .width = builder.getDescriptor(data.outColor).width, + .height = builder.getDescriptor(data.outColor).height, .format = TextureFormat::R8 }); - data.outForeground = builder.write(data.outForeground, FrameGraphTexture::Usage::COLOR_ATTACHMENT); - data.outAlpha = builder.write(data.outAlpha, FrameGraphTexture::Usage::COLOR_ATTACHMENT); + data.outColor = builder.write(data.outColor, FrameGraphTexture::Usage::COLOR_ATTACHMENT); + data.outAlpha = builder.write(data.outAlpha, FrameGraphTexture::Usage::COLOR_ATTACHMENT); builder.declareRenderPass("DoF Target", { - .attachments = { .color = { data.outForeground, data.outAlpha }} + .attachments = { .color = { data.outColor, data.outAlpha }} }); }, [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { auto const& out = resources.getRenderPassInfo(); - auto foreground = resources.getTexture(data.foreground); - auto background = resources.getTexture(data.background); - auto cocFgBg = resources.getTexture(data.cocFgBg); - auto tilesCocMaxMin = resources.getTexture(data.tilesCocMaxMin); + auto color = resources.getTexture(data.color); + auto coc = resources.getTexture(data.coc); + auto tilesCocMinMax = resources.getTexture(data.tilesCocMinMax); - auto const& inputDesc = resources.getDescriptor(data.cocFgBg); - auto const& outputDesc = resources.getDescriptor(data.outForeground); - auto const& tilesDesc = resources.getDescriptor(data.tilesCocMaxMin); + auto const& inputDesc = resources.getDescriptor(data.coc); + auto const& outputDesc = resources.getDescriptor(data.outColor); + auto const& tilesDesc = resources.getDescriptor(data.tilesCocMinMax); auto const& material = getPostProcessMaterial("dof"); FMaterialInstance* const mi = material.getMaterialInstance(); // it's not safe to use bilinear filtering in the general case (causes artifacts around edges) - mi->setParameter("foreground", foreground, + mi->setParameter("color", color, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); - mi->setParameter("foregroundLinear", foreground, + mi->setParameter("colorLinear", color, { .filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST }); - mi->setParameter("background", background, + mi->setParameter("coc", coc, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); - mi->setParameter("cocFgBg", cocFgBg, - { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); - mi->setParameter("tiles", tilesCocMaxMin, + mi->setParameter("tiles", tilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("cocToTexelScale", (1.0f / dofResolution) / float2{ inputDesc.width, inputDesc.height }); mi->setParameter("cocToPixelScale", (1.0f / dofResolution)); @@ -1220,43 +1208,43 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, struct PostProcessDofMedian { - FrameGraphId inForeground; + FrameGraphId inColor; FrameGraphId inAlpha; - FrameGraphId tilesCocMaxMin; - FrameGraphId outForeground; + FrameGraphId tilesCocMinMax; + FrameGraphId outColor; FrameGraphId outAlpha; }; auto& ppDoFMedian = fg.addPass("DoF Median", [&](FrameGraph::Builder& builder, auto& data) { - data.inForeground = builder.sample(ppDoF->outForeground); + data.inColor = builder.sample(ppDoF->outColor); data.inAlpha = builder.sample(ppDoF->outAlpha); - data.tilesCocMaxMin = builder.sample(dilated); + data.tilesCocMinMax = builder.sample(dilated); - data.outForeground = builder.createTexture("dof color output", fg.getDescriptor(data.inForeground)); - data.outAlpha = builder.createTexture("dof alpha output", fg.getDescriptor(data.inAlpha)); - data.outForeground = builder.write(data.outForeground, FrameGraphTexture::Usage::COLOR_ATTACHMENT); - data.outAlpha = builder.write(data.outAlpha, FrameGraphTexture::Usage::COLOR_ATTACHMENT); + data.outColor = builder.createTexture("dof color output", fg.getDescriptor(data.inColor)); + data.outAlpha = builder.createTexture("dof alpha output", fg.getDescriptor(data.inAlpha)); + data.outColor = builder.write(data.outColor, FrameGraphTexture::Usage::COLOR_ATTACHMENT); + data.outAlpha = builder.write(data.outAlpha, FrameGraphTexture::Usage::COLOR_ATTACHMENT); builder.declareRenderPass("DoF Target", { - .attachments = { .color = { data.outForeground, data.outAlpha }} + .attachments = { .color = { data.outColor, data.outAlpha }} }); }, [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { auto const& out = resources.getRenderPassInfo(); - auto inForeground = resources.getTexture(data.inForeground); + auto inColor = resources.getTexture(data.inColor); auto inAlpha = resources.getTexture(data.inAlpha); - auto tilesCocMaxMin = resources.getTexture(data.tilesCocMaxMin); + auto tilesCocMinMax = resources.getTexture(data.tilesCocMinMax); - auto const& outputDesc = resources.getDescriptor(data.outForeground); - auto const& tilesDesc = resources.getDescriptor(data.tilesCocMaxMin); + auto const& outputDesc = resources.getDescriptor(data.outColor); + auto const& tilesDesc = resources.getDescriptor(data.tilesCocMinMax); auto const& material = getPostProcessMaterial("dofMedian"); FMaterialInstance* const mi = material.getMaterialInstance(); - mi->setParameter("dof", inForeground, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); + mi->setParameter("dof", inColor, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); mi->setParameter("alpha", inAlpha, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); - mi->setParameter("tiles", tilesCocMaxMin, { .filterMin = SamplerMinFilter::NEAREST }); + mi->setParameter("tiles", tilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("uvscale", float2{ outputDesc.width / float(tileSize / dofResolution * tilesDesc.width), outputDesc.height / float(tileSize / dofResolution * tilesDesc.height) @@ -1269,10 +1257,10 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, * DoF recombine */ - auto outForeground = ppDoFMedian->outForeground; + auto outColor = ppDoFMedian->outColor; auto outAlpha = ppDoFMedian->outAlpha; if (dofOptions.filter == View::DepthOfFieldOptions::Filter::NONE) { - outForeground = ppDoF->outForeground; + outColor = ppDoF->outColor; outAlpha = ppDoF->outAlpha; } @@ -1280,16 +1268,16 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, FrameGraphId color; FrameGraphId dof; FrameGraphId alpha; - FrameGraphId tilesCocMaxMin; + FrameGraphId tilesCocMinMax; FrameGraphId output; }; auto& ppDoFCombine = fg.addPass("DoF combine", [&](FrameGraph::Builder& builder, auto& data) { data.color = builder.sample(input); - data.dof = builder.sample(outForeground); + data.dof = builder.sample(outColor); data.alpha = builder.sample(outAlpha); - data.tilesCocMaxMin = builder.sample(dilated); + data.tilesCocMinMax = builder.sample(dilated); auto const& inputDesc = fg.getDescriptor(data.color); data.output = builder.createTexture("DoF output", inputDesc); data.output = builder.declareRenderPass(data.output); @@ -1297,20 +1285,20 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { auto const& dofDesc = resources.getDescriptor(data.dof); - auto const& tilesDesc = resources.getDescriptor(data.tilesCocMaxMin); + auto const& tilesDesc = resources.getDescriptor(data.tilesCocMinMax); auto const& out = resources.getRenderPassInfo(); auto color = resources.getTexture(data.color); auto dof = resources.getTexture(data.dof); auto alpha = resources.getTexture(data.alpha); - auto tilesCocMaxMin = resources.getTexture(data.tilesCocMaxMin); + auto tilesCocMinMax = resources.getTexture(data.tilesCocMinMax); auto const& material = getPostProcessMaterial("dofCombine"); FMaterialInstance* const mi = material.getMaterialInstance(); mi->setParameter("color", color, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("dof", dof, { .filterMag = SamplerMagFilter::NEAREST }); mi->setParameter("alpha", alpha, { .filterMag = SamplerMagFilter::NEAREST }); - mi->setParameter("tiles", tilesCocMaxMin, { .filterMin = SamplerMinFilter::NEAREST }); + mi->setParameter("tiles", tilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("uvscale", float4{ colorDesc.width / (dofDesc.width * float(dofResolution)), colorDesc.height / (dofDesc.height * float(dofResolution)), diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index b5667dfa6e..491429eab6 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -445,13 +445,13 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { }); // resolve depth -- which might be needed because of TAA or DoF. This pass will be culled - // if the depth is not use below. + // if the depth is not used below. auto& blackboard = fg.getBlackboard(); auto depth = blackboard.get("depth"); depth = ppm.resolve(fg, "Resolved Depth Buffer", depth); blackboard.put("depth", depth); - // TODO: DoF should be applied here, before TAA -- but if we do this it'll result is a lot + // TODO: DoF should be applied here, before TAA -- but if we do this it'll result in a lot of // fireflies due to the instability of the highlights. This can be fixed with a // dedicated TAA pass for the DoF, as explained in // "Life of a Bokeh" by Guillaume Abadie, SIGGRAPH 2018 diff --git a/filament/src/materials/dof/dof.mat b/filament/src/materials/dof/dof.mat index da1fbdd4de..344ebb175f 100644 --- a/filament/src/materials/dof/dof.mat +++ b/filament/src/materials/dof/dof.mat @@ -3,22 +3,17 @@ material { parameters : [ { type : sampler2d, - name : foreground, + name : color, precision: medium }, { type : sampler2d, - name : foregroundLinear, + name : colorLinear, precision: medium }, { type : sampler2d, - name : background, - precision: medium - }, - { - type : sampler2d, - name : cocFgBg, + name : coc, precision: medium }, { @@ -207,8 +202,9 @@ struct Bucket { precision mediump float; struct Sample { - vec4 s; // sample color - float coc; // sample coc + vec4 s; // sample color + float coc; // sample coc + float inLayer; // whether is sample is in the considered layer }; void initBucket(out Bucket ring) { @@ -268,7 +264,7 @@ void mergeRings(inout Bucket curr, inout Bucket prev, const float count) { void accumulate(inout Bucket curr, inout Bucket prev, const Sample tap, const float radius, const float border, const float mip, const bool first) { - float inLayer = isBackground(tap.coc); + float inLayer = tap.inLayer; float coc = abs(tap.coc); float w = inLayer * intersection(radius, coc, mip) * sampleWeight(coc, mip); @@ -303,11 +299,9 @@ void accumulate(inout Bucket curr, inout Bucket prev, const Sample tap, void accumulateBackground(inout Bucket curr, inout Bucket prev, const highp vec2 pos, const float radius, const float border, const float mip, const bool first) { Sample tap; - // FIXME: there are typos below. We should use materialParams_background and - // materialParams_cocFgBg's green (background coc) channel. - // however doing so, looks much worse and is much more unstable. - tap.s = textureLod(materialParams_foreground, pos, mip); - tap.coc = textureLod(materialParams_cocFgBg, pos, mip).r; + tap.s = textureLod(materialParams_color, pos, mip); + tap.coc = textureLod(materialParams_coc, pos, mip).r; + tap.inLayer = isBackground(tap.coc); accumulate(curr, prev, tap, radius, border, mip, first); } @@ -387,8 +381,8 @@ float foregroundFadding(const float coc) { void accumulateForeground(inout Layer layer[2], const vec2 tiles, const highp vec2 pos, const float border, const float mip) { - float coc = textureLod(materialParams_cocFgBg, pos, mip).r; - vec4 s = textureLod(materialParams_foreground, pos, mip); + float coc = textureLod(materialParams_coc, pos, mip).r; + vec4 s = textureLod(materialParams_color, pos, mip); float inLayer = isForeground(coc) * foregroundFadding(coc); float i = intersection(border, abs(coc), mip) * sampleWeight(coc, mip); @@ -417,12 +411,12 @@ void accumulateForegroundMirror(inout Layer layer[2], const vec2 tiles, // the geometry. highp vec2 pos0 = diaphragm(center, offset); - float coc0 = textureLod(materialParams_cocFgBg, pos0, mip).r; - vec4 s0 = textureLod(materialParams_foreground, pos0, mip); + float coc0 = textureLod(materialParams_coc, pos0, mip).r; + vec4 s0 = textureLod(materialParams_color, pos0, mip); highp vec2 pos1 = diaphragm(center, -offset); - float coc1 = textureLod(materialParams_cocFgBg, pos1, mip).r; - vec4 s1 = textureLod(materialParams_foreground, pos1, mip); + float coc1 = textureLod(materialParams_coc, pos1, mip).r; + vec4 s1 = textureLod(materialParams_color, pos1, mip); float coc = min(coc0, coc1); float inLayer = isForeground(coc) * foregroundFadding(coc); @@ -460,7 +454,7 @@ void fastTile(inout vec4 color, inout float alpha, highp vec2 uvCenter = uv + noise * cocToTexelScale; - color = textureLod(materialParams_foregroundLinear, uvCenter, mip); + color = textureLod(materialParams_colorLinear, uvCenter, mip); for (float i = 1.0; i < ringCountFast; i += 1.0) { float radius; float count; @@ -470,9 +464,9 @@ void fastTile(inout vec4 color, inout float alpha, // we must use this temporary in order to accomodate mediump precision vec4 t = vec4(0.0); for (float j = 0.0; j < count; j += 2.0) { - t += textureLod(materialParams_foregroundLinear, + t += textureLod(materialParams_colorLinear, diaphragm(uvCenter, p * cocToTexelScale), mip) - + textureLod(materialParams_foregroundLinear, + + textureLod(materialParams_colorLinear, diaphragm(uvCenter, -p * cocToTexelScale), mip); p = r * p; } @@ -545,7 +539,7 @@ void backgroundTile(inout vec4 background, inout float bgOpacity, // we select a ring cound per tile, to avoid divergence between pixels float ringCountGather = min(float(RING_COUNT_GATHER), computeNeededRings(tiles.g * cocToPixelScale)); - float centerCoc = textureLod(materialParams_cocFgBg, uv, 0.0).g; + float centerCoc = textureLod(materialParams_coc, uv, 0.0).r; float kernelSize = abs(centerCoc); float mip = getMipLevel(ringCountGather, kernelSize * cocToPixelScale); float noiseRadius = 0.0; @@ -650,7 +644,7 @@ void postProcess(inout PostProcessInputs postProcess) { // TODO: make this a quality setting if (fgOpacity > 0.0 && fgOpacity < 1.0 && bgOpacity == 0.0) { // this happens on very few pixels - float centerCoc = textureLod(materialParams_cocFgBg, uv, 0.0).r; + float centerCoc = textureLod(materialParams_coc, uv, 0.0).r; float correctedOpacity = max(fgOpacity, cocToAlpha(centerCoc)); float updateOpacity = correctedOpacity / fgOpacity; foreground *= updateOpacity; diff --git a/filament/src/materials/dof/dofCoc.mat b/filament/src/materials/dof/dofCoc.mat index c13766c81b..da7a7b830b 100644 --- a/filament/src/materials/dof/dofCoc.mat +++ b/filament/src/materials/dof/dofCoc.mat @@ -31,14 +31,9 @@ material { type : float4 }, { - name : background, + name : coc, target : color, - type : float4 - }, - { - name : cocFgBg, - target : color, - type : float2 + type : float } ], domain : postprocess, @@ -64,26 +59,30 @@ void dummy(){} void postProcess(inout PostProcessInputs postProcess) { highp vec2 uv = variable_vertex.xy; - vec4 color = textureLod(materialParams_color, uv, 0.0); + vec4 outColor = textureLod(materialParams_color, uv, 0.0); float d = textureLod(materialParams_depth, uv, 0.0).r; // Get the CoC radius. // We multiply by 0.5 to convert from diameter to radius. - float coc = getCOC(d, materialParams.cocParams) * 0.5; + float outCoc = getCOC(d, materialParams.cocParams) * 0.5; + + // Clamp to maximum allowable CoC radius. + outCoc = clamp(outCoc, -MAX_COC_RADIUS, MAX_COC_RADIUS); // If CoC is less that 0.5 full resolution pixel, we clamp to 0, this will reduce // artifacts in the "in focus" area and allow us to skip more tiles trivially. - if (abs(coc) < MAX_IN_FOCUS_COC) { - coc = 0.0; + if (abs(outCoc) < MAX_IN_FOCUS_COC) { + outCoc = 0.0; } - // Clamp to maximum allowable CoC radius. - coc = clamp(coc, -MAX_COC_RADIUS, MAX_COC_RADIUS); +#if POST_PROCESS_OPAQUE + // kill the work performed above + outColor.a = 1.0; +#endif // Output to MRTs - postProcess.color = color; - postProcess.background = color; - postProcess.cocFgBg = vec2(coc, coc); + postProcess.color = outColor; + postProcess.coc = outCoc; } } diff --git a/filament/src/materials/dof/dofCombine.mat b/filament/src/materials/dof/dofCombine.mat index b8b81daaf7..c52063d350 100644 --- a/filament/src/materials/dof/dofCombine.mat +++ b/filament/src/materials/dof/dofCombine.mat @@ -64,9 +64,9 @@ void postProcess(inout PostProcessInputs postProcess) { highp vec2 uv0 = variable_vertex.xy; highp vec2 uv1 = variable_vertex.xy * materialParams.uvscale.xy; float alpha = textureLod(materialParams_alpha, uv1, 0.0).r; - vec4 foreground = textureLod(materialParams_dof, uv1, 0.0); + vec4 dof = textureLod(materialParams_dof, uv1, 0.0); color = textureLod(materialParams_color, uv0, 0.0); - color = foreground + (1.0 - alpha) * color; + color = dof + (1.0 - alpha) * color; } #if POST_PROCESS_OPAQUE diff --git a/filament/src/materials/dof/dofDilate.mat b/filament/src/materials/dof/dofDilate.mat index 5b7339fa29..5b194760f7 100644 --- a/filament/src/materials/dof/dofDilate.mat +++ b/filament/src/materials/dof/dofDilate.mat @@ -35,20 +35,8 @@ vec2 tap(const vec2 uv, const vec2 offset) { } vec2 dilate(inout vec2 center, const vec2 tap) { - // 2.24 tiles is the longest distance between 2 pixels of adjacent tiles. - // sqrt(2^2 + 1^2) = 2.24 - const float maxDistance = max(-MAX_COC_RADIUS, -2.24 * TILE_SIZE); - // Tiles that can affect us need to transfer their CoC to us (for the foreground it's // min(ourCoc, theirCoc) because CoC are negative (the min is the larger radius). - - // TODO: However, if their CoC is very large, we can limit it by the distance to that - // tile, because we only need to reach *them*). - // The difficuty here is the this clamping depends on if we're negative or positive. - // e.g. for positive values - // center.g = min(center.g, max(tap.g, maxDistance)); - // center.r = max(center.r, max(tap.r, maxDistance)); - center.r = min(center.r, tap.r); center.g = max(center.g, tap.g); return center; diff --git a/filament/src/materials/dof/dofDownsample.mat b/filament/src/materials/dof/dofDownsample.mat index b7351ef2be..8b4073fd5a 100644 --- a/filament/src/materials/dof/dofDownsample.mat +++ b/filament/src/materials/dof/dofDownsample.mat @@ -31,14 +31,9 @@ material { type : float4 }, { - name : background, + name : coc, target : color, - type : float4 - }, - { - name : cocFgBg, - target : color, - type : float2 + type : float } ], domain : postprocess, @@ -73,63 +68,45 @@ void postProcess(inout PostProcessInputs postProcess) { vec4 hdr; // fireflies/flickering filtering - hdr.x = 1.0 / (1.0 + max3(s00.rgb)); - hdr.y = 1.0 / (1.0 + max3(s11.rgb)); - hdr.z = 1.0 / (1.0 + max3(s10.rgb)); - hdr.w = 1.0 / (1.0 + max3(s00.rgb)); + hdr[0] = 1.0 / (1.0 + max3(s01.rgb)); + hdr[1] = 1.0 / (1.0 + max3(s11.rgb)); + hdr[2] = 1.0 / (1.0 + max3(s10.rgb)); + hdr[3] = 1.0 / (1.0 + max3(s00.rgb)); vec4 d; #if defined(TARGET_VULKAN_ENVIRONMENT) || !defined(TARGET_MOBILE) d = textureGather(materialParams_depth, uv, 0); // 01, 11, 10, 00 #else - d.x = textureLodOffset(materialParams_depth, uv, 0.0, ivec2(0, 1)).r; - d.y = textureLodOffset(materialParams_depth, uv, 0.0, ivec2(1, 1)).r; - d.z = textureLodOffset(materialParams_depth, uv, 0.0, ivec2(1, 0)).r; - d.w = textureLodOffset(materialParams_depth, uv, 0.0, ivec2(0, 0)).r; + d[0] = textureLodOffset(materialParams_depth, uv, 0.0, ivec2(0, 1)).r; + d[1] = textureLodOffset(materialParams_depth, uv, 0.0, ivec2(1, 1)).r; + d[2] = textureLodOffset(materialParams_depth, uv, 0.0, ivec2(1, 0)).r; + d[3] = textureLodOffset(materialParams_depth, uv, 0.0, ivec2(0, 0)).r; #endif // Get the CoC radius of each four samples to downsample. // We multiply by 0.5 to convert from diameter to radius. - vec4 w = getCOC(d, materialParams.cocParams) * 0.5; + vec4 c = getCOC(d, materialParams.cocParams) * 0.5; + float outCoc = downsampleCoC(c); + vec4 w = downsampleCocWeights(c, outCoc, 1.0) * hdr; + vec4 outColor = (s01 * w[0] + s11 * w[1] + s10 * w[2] + s00 * w[3]) * rcp(dot(vec4(1.0), w)); - // We calculates the downsampled CoC to be conservative, that is if any - // of the 4 texels are foreground or background, then the whole new texel is too. - float fgCoc = min2(min(w.xy, w.zw)); - - // The forground bilateral weight is calculated as saturate(1.0 - (fgCoc - w)), which always - // yields 1.0. Note the "missing" abs(), this is because we want to let the background layer - // leak into the foreground layer, to avoid aliasing artifacts. - vec4 foreground = (s01 * hdr.x + s11 * hdr.y + s10 * hdr.z + s00 * hdr.w) * (1.0 / (hdr.x + hdr.y + hdr.z + hdr.w)); - - // the background bilateral weight is calculated as saturate(1.0 - abs(bgCoc - w)), but the - // abs() is not needed since bgCoc - w is guaranteed to be >= 0. - float bgCoc = max2(max(w.xy, w.zw)); - vec4 bw = saturate(1.0 - (bgCoc - w)) * hdr; - vec4 background = (s01 * bw.x + s11 * bw.y + s10 * bw.z + s00 * bw.w) * (1.0 / (bw.x + bw.y + bw.z + bw.w)); + // Clamp to maximum allowable CoC radius. + outCoc = clamp(outCoc, -MAX_COC_RADIUS, MAX_COC_RADIUS); // If CoC is less that 0.5 full resolution pixel, we clamp to 0, this will reduce // artifacts in the "in focus" area and allow us to skip more tiles trivially. - if (abs(fgCoc) < MAX_IN_FOCUS_COC) { - fgCoc = 0.0; + if (abs(outCoc) < MAX_IN_FOCUS_COC) { + outCoc = 0.0; } - if (abs(bgCoc) < MAX_IN_FOCUS_COC){ - bgCoc = 0.0; - } - - // Clamp to maximum allowable CoC radius. - fgCoc = clamp(fgCoc, -MAX_COC_RADIUS, MAX_COC_RADIUS); - bgCoc = clamp(bgCoc, -MAX_COC_RADIUS, MAX_COC_RADIUS); #if POST_PROCESS_OPAQUE // kill the work performed above - foreground.a = 1.0; - background.a = 1.0; + outColor.a = 1.0; #endif // Output to MRTs - postProcess.color = foreground; - postProcess.background = background; - postProcess.cocFgBg = vec2(fgCoc, bgCoc); + postProcess.color = outColor; + postProcess.coc = outCoc; } } diff --git a/filament/src/materials/dof/dofMipmap.mat b/filament/src/materials/dof/dofMipmap.mat index 249b3f4ba3..7d6ee4373f 100644 --- a/filament/src/materials/dof/dofMipmap.mat +++ b/filament/src/materials/dof/dofMipmap.mat @@ -3,17 +3,12 @@ material { parameters : [ { type : sampler2d, - name : foreground, + name : color, precision: medium }, { type : sampler2d, - name : background, - precision: medium - }, - { - type : sampler2d, - name : cocFgBg, + name : coc, precision: medium }, { @@ -35,14 +30,9 @@ material { type : float4 }, { - name : background, + name : coc, target : color, - type : float4 - }, - { - name : cocFgBg, - target : color, - type : float2 + type : float } ], domain : postprocess, @@ -63,7 +53,7 @@ fragment { void dummy(){} void postProcess(inout PostProcessInputs postProcess) { - highp vec2 pixelSize = 1.0 / vec2(textureSize(materialParams_foreground, materialParams.mip)); + highp vec2 pixelSize = 1.0 / vec2(textureSize(materialParams_color, materialParams.mip)); highp vec2 uv = variable_vertex.xy - pixelSize.xy * 0.5; // the source is guaranteed to be a multiple of two, so we now the bilinear weights are 0.25 @@ -72,60 +62,30 @@ void postProcess(inout PostProcessInputs postProcess) { float weightScale = materialParams.weightScale; float mip = float(materialParams.mip); - // fetch the 4 corresponding CoC - vec4 d0, d1; - d0.xy = textureLodOffset(materialParams_cocFgBg, uv, mip, ivec2(0, 1)).rg; - d0.zw = textureLodOffset(materialParams_cocFgBg, uv, mip, ivec2(1, 1)).rg; - d1.xy = textureLodOffset(materialParams_cocFgBg, uv, mip, ivec2(1, 0)).rg; - d1.zw = textureLodOffset(materialParams_cocFgBg, uv, mip, ivec2(0, 0)).rg; - vec4 fw = vec4(d0.xz, d1.xz); - vec4 bw = vec4(d0.yw, d1.yw); + vec4 s01 = textureLodOffset(materialParams_color, uv, mip, ivec2(0, 1)); + vec4 s11 = textureLodOffset(materialParams_color, uv, mip, ivec2(1, 1)); + vec4 s10 = textureLodOffset(materialParams_color, uv, mip, ivec2(1, 0)); + vec4 s00 = textureLodOffset(materialParams_color, uv, mip, ivec2(0, 0)); - /* - * foreground - */ + // fetch the 4 corresponding CoC (textureGather with LOD doesn't exist) + vec4 c; + c[0] = textureLodOffset(materialParams_coc, uv, mip, ivec2(0, 1)).r; + c[1] = textureLodOffset(materialParams_coc, uv, mip, ivec2(1, 1)).r; + c[2] = textureLodOffset(materialParams_coc, uv, mip, ivec2(1, 0)).r; + c[3] = textureLodOffset(materialParams_coc, uv, mip, ivec2(0, 0)).r; - vec4 fg01 = textureLodOffset(materialParams_foreground, uv, mip, ivec2(0, 1)); - vec4 fg11 = textureLodOffset(materialParams_foreground, uv, mip, ivec2(1, 1)); - vec4 fg10 = textureLodOffset(materialParams_foreground, uv, mip, ivec2(1, 0)); - vec4 fg00 = textureLodOffset(materialParams_foreground, uv, mip, ivec2(0, 0)); - - // We calculates the downsampled CoC to be conservative, that is if any - // of the 4 texels are foreground or background, then the whole new texel is too. - float fgCoc = min4(fw); - - // The forground bilateral weight is calculated as saturate(1.0 - (fgCoc - w)), which always - // yields 1.0. Note the "missing" abs(), this is because we want to let the background layer - // leak into the foreground layer, to avoid aliasing artifacts. - vec4 foreground = (fg01 + fg11 + fg10 + fg00) * 0.25; - - /* - * background - */ - - vec4 bg01 = textureLodOffset(materialParams_background, uv, mip, ivec2(0, 1)); - vec4 bg11 = textureLodOffset(materialParams_background, uv, mip, ivec2(1, 1)); - vec4 bg10 = textureLodOffset(materialParams_background, uv, mip, ivec2(1, 0)); - vec4 bg00 = textureLodOffset(materialParams_background, uv, mip, ivec2(0, 0)); - - float bgCoc = max4(bw); - - // The background bilateral weight is calculated as saturate(1.0 - abs(bgCoc - w)), - // but the abs() is not needed since bgCoc - w is guaranteed to be >= 0. - bw = saturate(1.0 - (bgCoc - bw) * weightScale); - float bgScale = 1.0 / (bw.x + bw.y + bw.z + bw.w); - vec4 background = (bg01 * bw.x + bg11 * bw.y + bg10 * bw.z + bg00 * bw.w) * bgScale; + float outCoc = downsampleCoC(c); + vec4 w = downsampleCocWeights(c, outCoc, weightScale); + vec4 outColor = (s01 * w[0] + s11 * w[1] + s10 * w[2] + s00 * w[3]) * rcp(dot(vec4(1.0), w)); #if POST_PROCESS_OPAQUE // kill the work performed above - foreground.a = 1.0; - background.a = 1.0; + outColor.a = 1.0; #endif // Output to MRTs - postProcess.color = foreground; - postProcess.background = background; - postProcess.cocFgBg = vec2(fgCoc, bgCoc); + postProcess.color = outColor; + postProcess.coc = outCoc; } } diff --git a/filament/src/materials/dof/dofTiles.mat b/filament/src/materials/dof/dofTiles.mat index 8ff850d1c3..b84a030eac 100644 --- a/filament/src/materials/dof/dofTiles.mat +++ b/filament/src/materials/dof/dofTiles.mat @@ -3,7 +3,7 @@ material { parameters : [ { type : sampler2d, - name : cocMaxMin, + name : cocMinMax, precision: medium }, { @@ -42,27 +42,28 @@ float min4(const vec4 f) { void postProcess(inout PostProcessInputs postProcess) { highp vec2 uv = variable_vertex.xy; - highp vec2 size = vec2(textureSize(materialParams_cocMaxMin, 0)); + highp vec2 size = vec2(textureSize(materialParams_cocMinMax, 0)); ivec2 i = ivec2(uv * size - 0.5); + // note: the first time, the source texture is swizzled -- so .r and .g are the same channel #if defined(TARGET_VULKAN_ENVIRONMENT) || !defined(TARGET_MOBILE) - vec4 f = textureGather(materialParams_cocMaxMin, uv, 0); // 01, 11, 10, 00 - vec4 b = textureGather(materialParams_cocMaxMin, uv, 1); // 01, 11, 10, 00 + vec4 mi = textureGather(materialParams_cocMinMax, uv, 0); // 01, 11, 10, 00 + vec4 ma = textureGather(materialParams_cocMinMax, uv, 1); // 01, 11, 10, 00 #else - vec2 s01 = texelFetchOffset(materialParams_cocMaxMin, i, 0, ivec2(0, 1)).rg; - vec2 s11 = texelFetchOffset(materialParams_cocMaxMin, i, 0, ivec2(1, 1)).rg; - vec2 s10 = texelFetchOffset(materialParams_cocMaxMin, i, 0, ivec2(1, 0)).rg; - vec2 s00 = texelFetchOffset(materialParams_cocMaxMin, i, 0, ivec2(0, 0)).rg; - vec4 f = vec4(s01.r, s11.r, s10.r, s00.r); - vec4 b = vec4(s01.g, s11.g, s10.g, s00.g); + vec2 s01 = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(0, 1)).rg; + vec2 s11 = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(1, 1)).rg; + vec2 s10 = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(1, 0)).rg; + vec2 s00 = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(0, 0)).rg; + vec4 mi = vec4(s01.r, s11.r, s10.r, s00.r); + vec4 ma = vec4(s01.g, s11.g, s10.g, s00.g); #endif // compute tile's min CoC - postProcess.color.r = min4(min(f, b)); + postProcess.color.r = min4(mi); // compute tile's max CoC - postProcess.color.g = max4(max(f, b)); + postProcess.color.g = max4(ma); } } diff --git a/filament/src/materials/dof/dofUtils.fs b/filament/src/materials/dof/dofUtils.fs index 56db650221..d577ce672c 100644 --- a/filament/src/materials/dof/dofUtils.fs +++ b/filament/src/materials/dof/dofUtils.fs @@ -96,3 +96,23 @@ bool isTrivialTile(const vec2 tiles) { float maxCocRadius = max(abs(tiles.r), abs(tiles.g)); return maxCocRadius < MAX_IN_FOCUS_COC; } + +float downsampleCoC(const vec4 c) { + // We need to compute a suitable CoC to represent the 4 pixels that are downsampled. + // We pick the min because this always selects the most foreground sample if there is one, + // because the foreground can leak on the background, but not the reverse. + return min4(c); +} + +vec4 downsampleCocWeights(const vec4 c, const float outCoc, const float scale) { + // The bilateral weight is normally computed as saturate(1 - |outCoc - c|) which selects + // the sample with the outCoc weight (and does a little bit of cross-fade if other samples + // are close). However, this can also cause some aliasing with dithered objects, so by + // omitting the abs() we allow samples in the background to "leak" into the foreground, which + // is not completely different from the "mirror hole filling" of the DoF pass. + // See "Life of a Bokeh" by Guillaume Abadie, SIGGRAPH 2018. + + // Note: With the implementation of downsampleCoC() above, this always resolves to 1.0; + // return saturate(1.0 - (outCoc - c) * scale); + return vec4(1.0); +} From e7364cdcb368b6cd3fa22cc863d55837bf14b9bd Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 30 Mar 2021 13:40:00 -0700 Subject: [PATCH 13/39] DoF: don't rely on texture swizzle being supported --- filament/CMakeLists.txt | 1 + filament/backend/src/metal/MetalDriver.mm | 1 + filament/src/PostProcessManager.cpp | 6 +- filament/src/materials/dof/dofTiles.mat | 1 + .../src/materials/dof/dofTilesSwizzle.mat | 66 +++++++++++++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 filament/src/materials/dof/dofTilesSwizzle.mat diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index b36532c30f..1f724ad030 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -163,6 +163,7 @@ set(MATERIAL_SRCS src/materials/dof/dofDownsample.mat src/materials/dof/dofCombine.mat src/materials/dof/dofTiles.mat + src/materials/dof/dofTilesSwizzle.mat src/materials/dof/dofDilate.mat src/materials/dof/dofMipmap.mat src/materials/dof/dofMedian.mat diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index 0515965844..cfd6bafc18 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -551,6 +551,7 @@ bool MetalDriver::isTextureFormatSupported(TextureFormat format) { } bool MetalDriver::isTextureSwizzleSupported() { + return false; // FIXME: reenable once textures used as attachments are supported if (@available(macOS 10.15, iOS 13, *)) { return true; } else { diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index 64a1dacd16..4cc34a17a8 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -212,6 +212,7 @@ static const MaterialInfo sMaterialList[] = { { "dofCoc", MATERIAL(DOFCOC) }, { "dofMipmap", MATERIAL(DOFMIPMAP) }, { "dofTiles", MATERIAL(DOFTILES) }, + { "dofTilesSwizzle", MATERIAL(DOFTILESSWIZZLE) }, { "dofDilate", MATERIAL(DOFDILATE) }, { "dof", MATERIAL(DOF) }, { "dofMedian", MATERIAL(DOFMEDIAN) }, @@ -1064,6 +1065,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, FrameGraphId outTilesCocMinMax; }; + const bool textureSwizzleSupported = Texture::isTextureSwizzleSupported(mEngine); for (size_t i = 0; i < tileReductionCount; i++) { auto& ppDoFTiling = fg.addPass("DoF Tiling", [&](FrameGraph::Builder& builder, auto& data) { @@ -1083,7 +1085,9 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, auto const& outputDesc = resources.getDescriptor(data.outTilesCocMinMax); auto const& out = resources.getRenderPassInfo(); auto inCocMinMax = resources.getTexture(data.inCocMinMax); - auto const& material = getPostProcessMaterial("dofTiles"); + auto const& material = (!textureSwizzleSupported && (i == 0)) ? + getPostProcessMaterial("dofTilesSwizzle") : + getPostProcessMaterial("dofTiles"); FMaterialInstance* const mi = material.getMaterialInstance(); mi->setParameter("cocMinMax", inCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("uvscale", float4{ diff --git a/filament/src/materials/dof/dofTiles.mat b/filament/src/materials/dof/dofTiles.mat index b84a030eac..b3c4c3f342 100644 --- a/filament/src/materials/dof/dofTiles.mat +++ b/filament/src/materials/dof/dofTiles.mat @@ -47,6 +47,7 @@ void postProcess(inout PostProcessInputs postProcess) { ivec2 i = ivec2(uv * size - 0.5); // note: the first time, the source texture is swizzled -- so .r and .g are the same channel + // if swizzling is not supported, we use dofTilesSwizzle instead. #if defined(TARGET_VULKAN_ENVIRONMENT) || !defined(TARGET_MOBILE) vec4 mi = textureGather(materialParams_cocMinMax, uv, 0); // 01, 11, 10, 00 vec4 ma = textureGather(materialParams_cocMinMax, uv, 1); // 01, 11, 10, 00 diff --git a/filament/src/materials/dof/dofTilesSwizzle.mat b/filament/src/materials/dof/dofTilesSwizzle.mat new file mode 100644 index 0000000000..e852b57e8c --- /dev/null +++ b/filament/src/materials/dof/dofTilesSwizzle.mat @@ -0,0 +1,66 @@ +material { + name : dofTilesSwizzle, + parameters : [ + { + type : sampler2d, + name : cocMinMax, + precision: medium + }, + { + type : float4, + name : uvscale, + precision: high + } + ], + variables : [ + vertex + ], + domain : postprocess, + depthWrite : false, + depthCulling : false +} + +vertex { + void postProcessVertex(inout PostProcessVertexInputs postProcess) { + postProcess.vertex.xy = (postProcess.normalizedUV * materialParams.uvscale.xy * 2.0 - 0.5) * materialParams.uvscale.zw; + } +} + +fragment { + +void dummy(){} + +float max4(const vec4 f) { + vec2 t = max(f.xy, f.zw); + return max(t.x, t.y); +} + +float min4(const vec4 f) { + vec2 t = min(f.xy, f.zw); + return min(t.x, t.y); +} + +void postProcess(inout PostProcessInputs postProcess) { + highp vec2 uv = variable_vertex.xy; + highp vec2 size = vec2(textureSize(materialParams_cocMinMax, 0)); + + ivec2 i = ivec2(uv * size - 0.5); + +#if defined(TARGET_VULKAN_ENVIRONMENT) || !defined(TARGET_MOBILE) + vec4 mi = textureGather(materialParams_cocMinMax, uv, 0); // 01, 11, 10, 00 +#else + vec4 mi; + mi[0] = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(0, 1)).r; + mi[1] = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(1, 1)).r; + mi[2] = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(1, 0)).r; + mi[3] = texelFetchOffset(materialParams_cocMinMax, i, 0, ivec2(0, 0)).r; +#endif + + // compute tile's min CoC + postProcess.color.r = min4(mi); + + // compute tile's max CoC + postProcess.color.g = max4(mi); +} + +} From 819878a1da2935e8c062627aaa240761dee9eb24 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 31 Mar 2021 12:39:23 -0700 Subject: [PATCH 14/39] DoF: implement "background hole filling" We use the technique used by Jimenez for the foreground applied to the background, where we "guess" the missing background information from neighboring pixels. In several papers it's not deemed useful for the background, however, it does improve the blur quality a lot very shallow DoF, i.e. when a moderately blurred background sits over a strongly blured one. --- filament/src/materials/dof/dof.mat | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/filament/src/materials/dof/dof.mat b/filament/src/materials/dof/dof.mat index 344ebb175f..51568c2dbb 100644 --- a/filament/src/materials/dof/dof.mat +++ b/filament/src/materials/dof/dof.mat @@ -308,8 +308,34 @@ void accumulateBackground(inout Bucket curr, inout Bucket prev, const highp vec2 void accumulateBackgroundMirror(inout Bucket curr, inout Bucket prev, const highp vec2 center, const vec2 offset, const float radius, const float border, const float mip, const bool first) { - accumulateBackground(curr, prev, diaphragm(center, offset), radius, border, mip, first); - accumulateBackground(curr, prev, diaphragm(center, -offset), radius, border, mip, first); + // The code below is equivalent (without hole filling) to: + // accumulateBackground(curr, prev, diaphragm(center, offset), radius, border, mip, first); + // accumulateBackground(curr, prev, diaphragm(center, -offset), radius, border, mip, first); + // return; + // We use the technique used by Jimenez for the foreground applied to the background, where + // we "guess" the missing background information from neighboring pixels. In several papers it's + // not deemed useful for the background, however, it does improve the blur quality a lot very + // shallow DoF, i.e. when a moderately blurred background sits over a strongly blured one. + Sample tap0; + Sample tap1; + + highp vec2 pos0 = diaphragm(center, offset); + tap0.coc = textureLod(materialParams_coc, pos0, mip).r; + + highp vec2 pos1 = diaphragm(center, -offset); + tap1.coc = textureLod(materialParams_coc, pos1, mip).r; + + float coc = min(tap0.coc, tap1.coc); + tap0.coc = + tap1.coc = coc; + tap0.inLayer = + tap1.inLayer = isBackground(coc); + + tap0.s = textureLod(materialParams_color, pos0, mip); + accumulate(curr, prev, tap0, radius, border, mip, first); + + tap1.s = textureLod(materialParams_color, pos1, mip); + accumulate(curr, prev, tap1, radius, border, mip, first); } void accumulateBackgroundCenter(inout Bucket prev, From 9af62251b6a5dc7aa55e4cb93e14b9ab60166e67 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Thu, 1 Apr 2021 10:19:50 -0700 Subject: [PATCH 15/39] Fix Metal texture swizzling (#3732) --- filament/backend/src/metal/MetalDriver.mm | 4 +-- filament/backend/src/metal/MetalHandles.h | 6 ++++ filament/backend/src/metal/MetalHandles.mm | 34 ++++++++++++++++------ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index cfd6bafc18..b2f565e0be 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -551,7 +551,6 @@ bool MetalDriver::isTextureFormatSupported(TextureFormat format) { } bool MetalDriver::isTextureSwizzleSupported() { - return false; // FIXME: reenable once textures used as attachments are supported if (@available(macOS 10.15, iOS 13, *)) { return true; } else { @@ -1220,7 +1219,8 @@ void MetalDriver::draw(backend::PipelineState ps, Handle rph) return; } const auto metalTexture = handle_const_cast(mHandleMap, sampler->t); - texturesToBind[binding] = metalTexture->texture; + texturesToBind[binding] = metalTexture->swizzledTextureView ? metalTexture->swizzledTextureView + : metalTexture->texture; if (metalTexture->externalImage.isValid()) { texturesToBind[binding] = metalTexture->externalImage.getMetalTextureForDraw(); diff --git a/filament/backend/src/metal/MetalHandles.h b/filament/backend/src/metal/MetalHandles.h index 787a7cfc4c..01dce978a5 100644 --- a/filament/backend/src/metal/MetalHandles.h +++ b/filament/backend/src/metal/MetalHandles.h @@ -183,6 +183,12 @@ struct MetalTexture : public HwTexture { MetalContext& context; MetalExternalImage externalImage; id texture = nil; + + // If non-nil, a swizzled texture view to use instead of "texture". + // Filament swizzling only affects texture reads, so this should not be used when the texture is + // bound as a render target attachment. + id swizzledTextureView = nil; + uint8_t bytesPerElement; // The number of bytes per pixel, or block (for compressed texture formats). uint8_t blockWidth; // The number of horizontal pixels per block (only for compressed texture formats). uint8_t blockHeight; // The number of vertical pixels per block (only for compressed texture formats). diff --git a/filament/backend/src/metal/MetalHandles.mm b/filament/backend/src/metal/MetalHandles.mm index c755edede9..506105653b 100644 --- a/filament/backend/src/metal/MetalHandles.mm +++ b/filament/backend/src/metal/MetalHandles.mm @@ -468,12 +468,6 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le } }; - auto setUpSwizzle = [r, g, b, a](MTLTextureDescriptor* descriptor) { - if (@available(macOS 10.15, iOS 13, *)) { - descriptor.swizzle = getSwizzleChannels(r, g, b, a); - } - }; - MTLTextureDescriptor* descriptor; switch (target) { case SamplerType::SAMPLER_2D: @@ -488,7 +482,6 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le descriptor.sampleCount = multisampled ? samples : 1; descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; - setUpSwizzle(descriptor); texture = [context.device newTextureWithDescriptor:descriptor]; ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); break; @@ -501,7 +494,6 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le descriptor.mipmapLevelCount = levels; descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; - setUpSwizzle(descriptor); texture = [context.device newTextureWithDescriptor:descriptor]; ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); break; @@ -515,7 +507,6 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le descriptor.mipmapLevelCount = levels; descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; - setUpSwizzle(descriptor); texture = [context.device newTextureWithDescriptor:descriptor]; ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); break; @@ -525,6 +516,31 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le texture = nil; break; } + + // If swizzling is set, set up a swizzled texture view that we'll use when sampling this texture. + const bool isDefaultSwizzle = + r == TextureSwizzle::CHANNEL_0 && + g == TextureSwizzle::CHANNEL_1 && + b == TextureSwizzle::CHANNEL_2 && + a == TextureSwizzle::CHANNEL_3; + // If texture is nil, then it must be a SAMPLER_EXTERNAL texture. We'll ignore this case for now. + // TODO: implement swizzling for external textures. + if (!isDefaultSwizzle && texture) { + if (@available(macOS 10.15, iOS 13, *)) { + NSUInteger slices = texture.arrayLength; + if (texture.textureType == MTLTextureTypeCube || + texture.textureType == MTLTextureTypeCubeArray) { + slices *= 6; + } + NSUInteger mips = texture.mipmapLevelCount; + MTLTextureSwizzleChannels swizzle = getSwizzleChannels(r, g, b, a); + swizzledTextureView = [texture newTextureViewWithPixelFormat:texture.pixelFormat + textureType:texture.textureType + levels:NSMakeRange(0, mips) + slices:NSMakeRange(0, slices) + swizzle:swizzle]; + } + } } MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t levels, TextureFormat format, From 0a0588aec81350604b5dde4630036740905842b7 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Thu, 1 Apr 2021 12:22:15 -0700 Subject: [PATCH 16/39] Add Metal and Vulkan backend support to Suzanne sample (#3736) --- samples/CMakeLists.txt | 12 +++++---- samples/suzanne.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 4b60fbf1ab..aed52da323 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -117,7 +117,7 @@ function(add_ktxfiles SOURCE TARGET EXTRA_ARGS) set(MONKEY_FILES ${MONKEY_FILES} ${target_path} PARENT_SCOPE) add_custom_command( OUTPUT ${target_path} - COMMAND mipgen --quiet --strip-alpha ${EXTRA_ARGS} ${source_path} ${target_path} + COMMAND mipgen --quiet ${EXTRA_ARGS} ${source_path} ${target_path} MAIN_DEPENDENCY ${source_path} DEPENDS mipgen COMMENT "Generating mip levels for ${source_path}") @@ -146,10 +146,12 @@ endfunction() add_mesh("assets/models/monkey/monkey.obj" "suzanne.filamesh") -add_ktxfiles("assets/models/monkey/albedo.png" "albedo_s3tc.ktx" "--compression=s3tc_rgb_dxt1") -add_ktxfiles("assets/models/monkey/roughness.png" "roughness.ktx" "--grayscale") -add_ktxfiles("assets/models/monkey/metallic.png" "metallic.ktx" "--grayscale") -add_ktxfiles("assets/models/monkey/ao.png" "ao.ktx" "--grayscale") +# Use a RGBA compression format for Metal and Vulkan support. +set (COMPRESSION "--compression=s3tc_rgba_dxt5") +add_ktxfiles("assets/models/monkey/albedo.png" "albedo_s3tc.ktx" "${COMPRESSION}") +add_ktxfiles("assets/models/monkey/roughness.png" "roughness.ktx" "${COMPRESSION};--grayscale") +add_ktxfiles("assets/models/monkey/metallic.png" "metallic.ktx" "${COMPRESSION};--grayscale") +add_ktxfiles("assets/models/monkey/ao.png" "ao.ktx" "${COMPRESSION};--grayscale") add_pngfile("assets/models/monkey/normal.png" "normal.png") diff --git a/samples/suzanne.cpp b/samples/suzanne.cpp index 059d8e49ff..6826597ac7 100644 --- a/samples/suzanne.cpp +++ b/samples/suzanne.cpp @@ -35,8 +35,14 @@ #include #include +#include + +#include + #include +#include + #include "generated/resources/resources.h" #include "generated/resources/monkey.h" @@ -58,6 +64,57 @@ struct App { static const char* IBL_FOLDER = "default_env"; +static void printUsage(char* name) { + std::string exec_name(utils::Path(name).getName()); + std::string usage( + "SHOWCASE renders a Suzanne model with S3TC textures.\n" + "Usage:\n" + " SHOWCASE [options]\n" + "Options:\n" + " --help, -h\n" + " Prints this message\n\n" + " --api, -a\n" + " Specify the backend API: opengl (default), vulkan, or metal\n" + ); + const std::string from("SHOWCASE"); + for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) { + usage.replace(pos, from.length(), exec_name); + } + std::cout << usage; +} + +static int handleCommandLineArguments(int argc, char* argv[], Config* config) { + static constexpr const char* OPTSTR = "ha:"; + static const struct option OPTIONS[] = { + { "help", no_argument, nullptr, 'h' }, + { "api", required_argument, nullptr, 'a' }, + { nullptr, 0, nullptr, 0 } + }; + int opt; + int option_index = 0; + while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) { + std::string arg(optarg ? optarg : ""); + switch (opt) { + default: + case 'h': + printUsage(argv[0]); + exit(0); + case 'a': + if (arg == "opengl") { + config->backend = Engine::Backend::OPENGL; + } else if (arg == "vulkan") { + config->backend = Engine::Backend::VULKAN; + } else if (arg == "metal") { + config->backend = Engine::Backend::METAL; + } else { + std::cerr << "Unrecognized backend. Must be 'opengl'|'vulkan'|'metal'.\n"; + } + break; + } + } + return optind; +} + static Texture* loadNormalMap(Engine* engine, const uint8_t* normals, size_t nbytes) { int w, h, n; unsigned char* data = stbi_load_from_memory(normals, nbytes, &w, &h, &n, 3); @@ -80,6 +137,8 @@ int main(int argc, char** argv) { config.title = "suzanne"; config.iblDirectory = FilamentApp::getRootAssetsPath() + IBL_FOLDER; + handleCommandLineArguments(argc, argv, &config); + App app; auto setup = [config, &app](Engine* engine, View* view, Scene* scene) { auto& tcm = engine->getTransformManager(); From 385a17b8a5005d438c627d31b842d351a7e6cf56 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 31 Mar 2021 17:47:10 -0700 Subject: [PATCH 17/39] DoF: add many user settings - native/half resolution - gather kernel ring counts - circle-of-confusion radius clamps --- .../filament-android/src/main/cpp/View.cpp | 13 +++- .../com/google/android/filament/View.java | 59 ++++++++++++++++++- filament/CMakeLists.txt | 5 ++ filament/include/filament/View.h | 47 +++++++++++++-- filament/src/PostProcessManager.cpp | 19 +++++- filament/src/materials/dof/dof.mat | 52 ++++++++-------- filament/src/materials/dof/dofCoc.mat | 6 +- filament/src/materials/dof/dofDownsample.mat | 6 +- libs/viewer/src/Settings.cpp | 26 +++++++- libs/viewer/src/SimpleViewer.cpp | 23 ++++++-- web/filament-js/jsbindings.cpp | 8 ++- 11 files changed, 218 insertions(+), 46 deletions(-) diff --git a/android/filament-android/src/main/cpp/View.cpp b/android/filament-android/src/main/cpp/View.cpp index 541adb0eed..bdad7b0fae 100644 --- a/android/filament-android/src/main/cpp/View.cpp +++ b/android/filament-android/src/main/cpp/View.cpp @@ -300,7 +300,9 @@ Java_com_google_android_filament_View_nSetBlendMode(JNIEnv *, jclass , jlong nat extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass , - jlong nativeView, jfloat focusDistance, jfloat cocScale, jfloat maxApertureDiameter, jboolean enabled, jint filter) { + jlong nativeView, jfloat focusDistance, jfloat cocScale, jfloat maxApertureDiameter, jboolean enabled, jint filter, + jboolean nativeResolution, jint foregroundRingCount, jint backgroundRingCount, jint fastGatherRingCount, + jint maxForegroundCOC, jint maxBackgroundCOC) { View* view = (View*) nativeView; View::DepthOfFieldOptions::Filter eFilter{}; if (filter == 1) { @@ -308,7 +310,14 @@ Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass , eFilter = View::DepthOfFieldOptions::Filter::MEDIAN; } view->setDepthOfFieldOptions({.focusDistance = focusDistance, .cocScale = cocScale, - .maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled, .filter = eFilter}); + .maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled, .filter = eFilter, + .nativeResolution = (bool)nativeResolution, + .foregroundRingCount = (uint8_t)foregroundRingCount, + .backgroundRingCount = (uint8_t)backgroundRingCount, + .fastGatherRingCount = (uint8_t)fastGatherRingCount, + .maxForegroundCOC = (uint8_t)maxForegroundCOC, + .maxBackgroundCOC = (uint8_t)maxBackgroundCOC, + }); } extern "C" diff --git a/android/filament-android/src/main/java/com/google/android/filament/View.java b/android/filament-android/src/main/java/com/google/android/filament/View.java index ab12538005..8affc43ca9 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/View.java +++ b/android/filament-android/src/main/java/com/google/android/filament/View.java @@ -266,7 +266,7 @@ public class View { /** * Options for Temporal Anti-aliasing (TAA) - * @see View#setTemporalAntiAliasingOptions() + * @see View#setTemporalAntiAliasingOptions */ public static class TemporalAntiAliasingOptions { /** reconstruction filter width typically between 0 (sharper, aliased) and 1 (smoother) */ @@ -465,6 +465,55 @@ public class View { /** filter to use for filling gaps in the kernel */ @NonNull public Filter filter = Filter.MEDIAN; + + /** perform DoF processing at native resolution */ + public boolean nativeResolution = false; + + /** + *

Number of of rings used by the foreground kernel. The number of rings affects quality + * and performance. The actual number of sample per pixel is defined + * as (ringCount * 2 - 1)^2. Here are a few commonly used values:

+ * 3 rings : 25 ( 5x 5 grid) + * 4 rings : 49 ( 7x 7 grid) + * 5 rings : 81 ( 9x 9 grid) + * 17 rings : 1089 (33x33 grid) + * + *

With a maximum circle-of-confusion of 32, it is never necessary to use more than 17 rings.

+ * + *

Usually all three settings below are set to the same value, however, it is often + * acceptable to use a lower ring count for the "fast tiles", which improves performance. + * Fast tiles are regions of the screen where every pixels have a similar + * circle-of-confusion radius.

+ * + *

A value of 0 means default, which is 5 on desktop and 3 on mobile.

+ */ + public int foregroundRingCount = 0; + + /** + * Number of of rings used by the background kernel. The number of rings affects quality + * and performance. + * @see #foregroundRingCount + */ + public int backgroundRingCount = 0; + + /** + * Number of of rings used by the fast gather kernel. The number of rings affects quality + * and performance. + * @see #foregroundRingCount + */ + public int fastGatherRingCount = 0; + + /** + * maximum circle-of-confusion in pixels for the foreground, must be in [0, 32] range. + * A value of 0 means default, which is 32 on desktop and 24 on mobile. + */ + public int maxForegroundCOC = 0; + + /** + * maximum circle-of-confusion in pixels for the background, must be in [0, 32] range. + * A value of 0 means default, which is 32 on desktop and 24 on mobile. + */ + public int maxBackgroundCOC = 0; }; /** @@ -1393,7 +1442,10 @@ public class View { */ public void setDepthOfFieldOptions(@NonNull DepthOfFieldOptions options) { mDepthOfFieldOptions = options; - nSetDepthOfFieldOptions(getNativeObject(), options.focusDistance, options.cocScale, options.maxApertureDiameter, options.enabled, options.filter.ordinal()); + nSetDepthOfFieldOptions(getNativeObject(), options.focusDistance, options.cocScale, + options.maxApertureDiameter, options.enabled, options.filter.ordinal(), + options.nativeResolution, options.foregroundRingCount, options.backgroundRingCount, + options.fastGatherRingCount, options.maxForegroundCOC, options.maxBackgroundCOC); } /** @@ -1452,7 +1504,8 @@ public class View { private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight); private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled); private static native void nSetBlendMode(long nativeView, int blendMode); - private static native void nSetDepthOfFieldOptions(long nativeView, float focusDistance, float cocScale, float maxApertureDiameter, boolean enabled, int filter); + private static native void nSetDepthOfFieldOptions(long nativeView, float focusDistance, float cocScale, float maxApertureDiameter, boolean enabled, int filter, + boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC); private static native void nSetVignetteOptions(long nativeView, float midPoint, float roundness, float feather, float r, float g, float b, float a, boolean enabled); private static native void nSetTemporalAntiAliasingOptions(long nativeView, float feedback, float filterWidth, boolean enabled); private static native boolean nIsShadowingEnabled(long nativeView); diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index 1f724ad030..cdc5cbcc05 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -191,6 +191,11 @@ list(APPEND SRCS ${RESGEN_SOURCE}) # Configuration # ================================================================================================== +# whether we're building for mobile -- this can affect some default quality settings +if (IS_MOBILE_TARGET) + add_definitions(-DFILAMENT_TARGET_MOBILE=1) +endif() + # Size of the DFG lookup table if (NOT DFG_LUT_SIZE) if (IS_MOBILE_TARGET) diff --git a/filament/include/filament/View.h b/filament/include/filament/View.h index 1a7706f6f3..59bee02ceb 100644 --- a/filament/include/filament/View.h +++ b/filament/include/filament/View.h @@ -196,6 +196,43 @@ public: float maxApertureDiameter = 0.01f; //!< maximum aperture diameter in meters (zero to disable rotation) bool enabled = false; //!< enable or disable depth of field effect Filter filter = Filter::MEDIAN; //!< filter to use for filling gaps in the kernel + bool nativeResolution = false; //!< perform DoF processing at native resolution + /** + * Number of of rings used by the gather kernels. The number of rings affects quality + * and performance. The actual number of sample per pixel is defined + * as (ringCount * 2 - 1)^2. Here are a few commonly used values: + * 3 rings : 25 ( 5x 5 grid) + * 4 rings : 49 ( 7x 7 grid) + * 5 rings : 81 ( 9x 9 grid) + * 17 rings : 1089 (33x33 grid) + * + * With a maximum circle-of-confusion of 32, it is never necessary to use more than 17 rings. + * + * Usually all three settings below are set to the same value, however, it is often + * acceptable to use a lower ring count for the "fast tiles", which improves performance. + * Fast tiles are regions of the screen where every pixels have a similar + * circle-of-confusion radius. + * + * A value of 0 means default, which is 5 on desktop and 3 on mobile. + * + * @{ + */ + uint8_t foregroundRingCount = 0; //!< number of kernel rings for foreground tiles + uint8_t backgroundRingCount = 0; //!< number of kernel rings for background tiles + uint8_t fastGatherRingCount = 0; //!< number of kernel rings for fast tiles + /** @}*/ + + /** + * maximum circle-of-confusion in pixels for the foreground, must be in [0, 32] range. + * A value of 0 means default, which is 32 on desktop and 24 on mobile. + */ + uint16_t maxForegroundCOC = 0; + + /** + * maximum circle-of-confusion in pixels for the background, must be in [0, 32] range. + * A value of 0 means default, which is 32 on desktop and 24 on mobile. + */ + uint16_t maxBackgroundCOC = 0; }; /** @@ -434,11 +471,11 @@ public: */ void setBlendMode(BlendMode blendMode) noexcept; - /** - * - * @return blending mode set by setBlendMode - * @see setBlendMode - */ + /** + * + * @return blending mode set by setBlendMode + * @see setBlendMode + */ BlendMode getBlendMode() const noexcept; /** diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index 4cc34a17a8..e79cf27a9e 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -14,6 +14,14 @@ * limitations under the License. */ +#ifdef FILAMENT_TARGET_MOBILE +# define DOF_DEFAULT_RING_COUNT 3 +# define DOF_DEFAULT_MAX_COC 24 +#else +# define DOF_DEFAULT_RING_COUNT 5 +# define DOF_DEFAULT_MAX_COC 32 +#endif + #include "PostProcessManager.h" #include "details/Engine.h" @@ -921,7 +929,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, * dofResolution is used (at compile time for now) to chose between full- or quarter-resolution * for the DoF calculations. Set to [1] for full resolution or [2] for quarter-resolution. */ - const uint32_t dofResolution = 2; + const uint32_t dofResolution = dofOptions.nativeResolution ? 1u : 2u; constexpr const uint32_t maxMipLevels = 4u; // mip levels at full-resolution constexpr const uint32_t maxMipLevelsMask = (1u << maxMipLevels) - 1u; @@ -979,6 +987,9 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, mi->setParameter("color", color, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("depth", depth, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("cocParams", cocParams); + mi->setParameter("cocClamp", float2{ + -(dofOptions.maxForegroundCOC ? dofOptions.maxForegroundCOC : DOF_DEFAULT_MAX_COC), + dofOptions.maxBackgroundCOC ? dofOptions.maxBackgroundCOC : DOF_DEFAULT_MAX_COC}); mi->setParameter("uvscale", float4{ width, height, 1.0f / colorDesc.width, 1.0f / colorDesc.height }); commitAndRender(out, material, driver); @@ -1202,6 +1213,12 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, outputDesc.width / float(tileSize / dofResolution * tilesDesc.width), outputDesc.height / float(tileSize / dofResolution * tilesDesc.height) }); + mi->setParameter("ringCounts", float4{ + dofOptions.foregroundRingCount ? dofOptions.foregroundRingCount : DOF_DEFAULT_RING_COUNT, + dofOptions.backgroundRingCount ? dofOptions.backgroundRingCount : DOF_DEFAULT_RING_COUNT, + dofOptions.fastGatherRingCount ? dofOptions.fastGatherRingCount : DOF_DEFAULT_RING_COUNT, + 0.0 // unused for now + }); mi->setParameter("bokehAngle", bokehAngle); commitAndRender(out, material, driver); }); diff --git a/filament/src/materials/dof/dof.mat b/filament/src/materials/dof/dof.mat index 51568c2dbb..0068554a53 100644 --- a/filament/src/materials/dof/dof.mat +++ b/filament/src/materials/dof/dof.mat @@ -31,14 +31,19 @@ material { name : cocToPixelScale, precision: medium }, + { + type : float, + name : bokehAngle, + }, { type : float4, name : uvscale, precision: high }, { - type : float, - name : bokehAngle, + type : float4, + name : ringCounts, + precision: medium } ], outputs : [ @@ -75,20 +80,6 @@ fragment { #define DOF_DIAPHRAGM_STRAIGHT_BLADES 1 #define DOF_DIAPHRAGM DOF_DIAPHRAGM_CIRCLE -// # of sample w.r.t. ring count and density of 8 -// 3 rings : 25 ( 5^2 grid) -// 4 rings : 49 ( 7^2 grid) -// 5 rings : 81 ( 9^2 grid) -// 17 rings : 1089 (33^2 grid) -- maximum needed for a CoC of 32 - -#if defined(TARGET_MOBILE) -#define RING_COUNT_GATHER 3 -#define RING_COUNT_FAST 3 -#else -#define RING_COUNT_GATHER 4 -#define RING_COUNT_FAST 4 -#endif - // Enabled by default. Mipmaped taps look a lot better, but do cause some // aliasing issues which force us to set all sample weights to 1.0 // This is here mostly for debugging. @@ -106,6 +97,22 @@ struct NoiseState { vec2 randomDisk; }; +// # of sample w.r.t. ring count and density of 8 +// 3 rings : 25 ( 5^2 grid) +// 4 rings : 49 ( 7^2 grid) +// 5 rings : 81 ( 9^2 grid) +// 17 rings : 1089 (33^2 grid) -- maximum needed for a CoC of 32 + +float ringCountForeground() { + return materialParams.ringCounts[0]; +} +float ringCountBackground() { + return materialParams.ringCounts[1]; +} +float ringCountFast() { + return materialParams.ringCounts[2]; +} + float sampleCount(const float ringCount) { float s = (ringCount * 2.0 - 1.0); return s * s; @@ -469,7 +476,7 @@ void fastTile(inout vec4 color, inout float alpha, // The whole tile has mostly the same CoC float kernelSize = (abs(tiles.r) + abs(tiles.g)) * 0.5; - float ringCountFast = min(float(RING_COUNT_FAST), computeNeededRings(kernelSize * cocToPixelScale)); + float ringCountFast = min(ringCountFast(), computeNeededRings(kernelSize * cocToPixelScale)); float mip = getMipLevel(ringCountFast, kernelSize * cocToPixelScale); vec2 noise = vec2(0.0); @@ -510,7 +517,7 @@ void foregroundTile(inout vec4 foreground, inout float fgOpacity, // Here we know that tiles.r < 0, by definition of a foreground tile. // For a foreground tile, the kernel size is the largest CoC radius of the whole tile. float kernelSize = -tiles.r; - float ringCountGather = min(float(RING_COUNT_GATHER), computeNeededRings(kernelSize * cocToPixelScale)); + float ringCountGather = min(ringCountForeground(), computeNeededRings(kernelSize * cocToPixelScale)); float mip = getMipLevel(ringCountGather, kernelSize * cocToPixelScale); vec2 noise = vec2(0.0); @@ -563,7 +570,7 @@ void backgroundTile(inout vec4 background, inout float bgOpacity, float cocToPixelScale = materialParams.cocToPixelScale; // we select a ring cound per tile, to avoid divergence between pixels - float ringCountGather = min(float(RING_COUNT_GATHER), computeNeededRings(tiles.g * cocToPixelScale)); + float ringCountGather = min(ringCountBackground(), computeNeededRings(tiles.g * cocToPixelScale)); float centerCoc = textureLod(materialParams_coc, uv, 0.0).r; float kernelSize = abs(centerCoc); @@ -582,16 +589,9 @@ void backgroundTile(inout vec4 background, inout float bgOpacity, initBucket(prev); accumulateRing(prev, 0.0, ringCountGather, kernelSize, noise, uvCenter, cocToTexelScale, mip, true); - - // the optimizer is not able to remove this loop when it has only one iteration -#if RING_COUNT_GATHER == 3 - accumulateRing(prev, 1.0, ringCountGather, kernelSize, noise, uvCenter, cocToTexelScale, mip, false); -#else for (float i = 1.0; i < ringCountGather - 1.0 ; i += 1.0) { accumulateRing(prev, i, ringCountGather, kernelSize, noise, uvCenter, cocToTexelScale, mip, false); } -#endif - accumulateBackgroundCenter(prev, uvCenter, ringCountGather, kernelSize, noiseRadius, mip); float kernelArea = sampleWeight(kernelSize * ((ringCountGather + 0.5) / ringCountGather), mip); diff --git a/filament/src/materials/dof/dofCoc.mat b/filament/src/materials/dof/dofCoc.mat index da7a7b830b..4ff3d1d3c8 100644 --- a/filament/src/materials/dof/dofCoc.mat +++ b/filament/src/materials/dof/dofCoc.mat @@ -15,6 +15,10 @@ material { type : float2, name : cocParams }, + { + type : float2, + name : cocClamp + }, { type : float4, name : uvscale, @@ -67,7 +71,7 @@ void postProcess(inout PostProcessInputs postProcess) { float outCoc = getCOC(d, materialParams.cocParams) * 0.5; // Clamp to maximum allowable CoC radius. - outCoc = clamp(outCoc, -MAX_COC_RADIUS, MAX_COC_RADIUS); + outCoc = clamp(outCoc, materialParams.cocClamp[0], materialParams.cocClamp[1]); // If CoC is less that 0.5 full resolution pixel, we clamp to 0, this will reduce // artifacts in the "in focus" area and allow us to skip more tiles trivially. diff --git a/filament/src/materials/dof/dofDownsample.mat b/filament/src/materials/dof/dofDownsample.mat index 8b4073fd5a..7bcea00e45 100644 --- a/filament/src/materials/dof/dofDownsample.mat +++ b/filament/src/materials/dof/dofDownsample.mat @@ -15,6 +15,10 @@ material { type : float2, name : cocParams }, + { + type : float2, + name : cocClamp + }, { type : float4, name : uvscale, @@ -91,7 +95,7 @@ void postProcess(inout PostProcessInputs postProcess) { vec4 outColor = (s01 * w[0] + s11 * w[1] + s10 * w[2] + s00 * w[3]) * rcp(dot(vec4(1.0), w)); // Clamp to maximum allowable CoC radius. - outCoc = clamp(outCoc, -MAX_COC_RADIUS, MAX_COC_RADIUS); + outCoc = clamp(outCoc, materialParams.cocClamp[0], materialParams.cocClamp[1]); // If CoC is less that 0.5 full resolution pixel, we clamp to 0, this will reduce // artifacts in the "in focus" area and allow us to skip more tiles trivially. diff --git a/libs/viewer/src/Settings.cpp b/libs/viewer/src/Settings.cpp index 75d8da1b6d..61393afd1f 100644 --- a/libs/viewer/src/Settings.cpp +++ b/libs/viewer/src/Settings.cpp @@ -71,6 +71,12 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, uint8_t* return i + 1; } +static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, uint16_t* val) { + CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE); + *val = strtol(jsonChunk + tokens[i].start, nullptr, 10); + return i + 1; +} + static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, uint32_t* val) { CHECK_TOKTYPE(tokens[i], JSMN_PRIMITIVE); *val = strtol(jsonChunk + tokens[i].start, nullptr, 10); @@ -481,6 +487,18 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, DepthOfF i = parse(tokens, i + 1, jsonChunk, &out->enabled); } else if (0 == compare(tok, jsonChunk, "filter")) { i = parse(tokens, i + 1, jsonChunk, &out->filter); + } else if (0 == compare(tok, jsonChunk, "nativeResolution")) { + i = parse(tokens, i + 1, jsonChunk, &out->nativeResolution); + } else if (0 == compare(tok, jsonChunk, "foregroundRingCount")) { + i = parse(tokens, i + 1, jsonChunk, &out->foregroundRingCount); + } else if (0 == compare(tok, jsonChunk, "backgroundRingCount")) { + i = parse(tokens, i + 1, jsonChunk, &out->backgroundRingCount); + } else if (0 == compare(tok, jsonChunk, "fastGatherRingCount")) { + i = parse(tokens, i + 1, jsonChunk, &out->fastGatherRingCount); + } else if (0 == compare(tok, jsonChunk, "maxForegroundCOC")) { + i = parse(tokens, i + 1, jsonChunk, &out->maxForegroundCOC); + } else if (0 == compare(tok, jsonChunk, "maxBackgroundCOC")) { + i = parse(tokens, i + 1, jsonChunk, &out->maxBackgroundCOC); } else { slog.w << "Invalid dof options key: '" << STR(tok, jsonChunk) << "'" << io::endl; i = parse(tokens, i + 1); @@ -1185,7 +1203,13 @@ static std::ostream& operator<<(std::ostream& out, const DepthOfFieldOptions& in << "\"cocScale\": " << (in.cocScale) << ",\n" << "\"maxApertureDiameter\": " << (in.maxApertureDiameter) << ",\n" << "\"enabled\": " << to_string(in.enabled) << ",\n" - << "\"filter\": " << (in.filter) << "\n" + << "\"filter\": " << (in.filter) << ",\n" + << "\"nativeResolution\": " << (in.nativeResolution) << ",\n" + << "\"foregroundRingCount\": " << (in.foregroundRingCount) << ",\n" + << "\"backgroundRingCount\": " << (in.backgroundRingCount) << ",\n" + << "\"fastGatherRingCount\": " << (in.fastGatherRingCount) << ",\n" + << "\"maxForegroundCOC\": " << (in.maxForegroundCOC) << ",\n" + << "\"maxBackgroundCOC\": " << (in.maxBackgroundCOC) << "\n" << "}"; } diff --git a/libs/viewer/src/SimpleViewer.cpp b/libs/viewer/src/SimpleViewer.cpp index e0af8cf735..aadd51b8c9 100644 --- a/libs/viewer/src/SimpleViewer.cpp +++ b/libs/viewer/src/SimpleViewer.cpp @@ -729,7 +729,11 @@ void SimpleViewer::updateUserInterface() { 16.0f, 90.0f); } - bool median = mSettings.view.dof.filter == View::DepthOfFieldOptions::Filter::MEDIAN; + bool dofMedian = mSettings.view.dof.filter == View::DepthOfFieldOptions::Filter::MEDIAN; + int dofRingCount = mSettings.view.dof.fastGatherRingCount; + int dofMaxCoC = mSettings.view.dof.maxForegroundCOC; + if (!dofRingCount) dofRingCount = 5; + if (!dofMaxCoC) dofMaxCoC = 32; ImGui::SliderFloat("Aperture", &mSettings.viewer.cameraAperture, 1.0f, 32.0f); ImGui::SliderFloat("Speed (1/s)", &mSettings.viewer.cameraSpeed, 1000.0f, 1.0f); @@ -737,10 +741,19 @@ void SimpleViewer::updateUserInterface() { ImGui::Checkbox("DoF", &mSettings.view.dof.enabled); ImGui::SliderFloat("Focus distance", &mSettings.view.dof.focusDistance, 0.0f, 30.0f); ImGui::SliderFloat("Blur scale", &mSettings.view.dof.cocScale, 0.1f, 10.0f); - ImGui::Checkbox("Median Filter", &median); - mSettings.view.dof.filter = median ? - View::DepthOfFieldOptions::Filter::MEDIAN : - View::DepthOfFieldOptions::Filter::NONE; + ImGui::SliderInt("Ring count", &dofRingCount, 1, 17); + ImGui::SliderInt("Max CoC", &dofMaxCoC, 1, 32); + ImGui::Checkbox("Native Resolution", &mSettings.view.dof.nativeResolution); + ImGui::Checkbox("Median Filter", &dofMedian); + + mSettings.view.dof.filter = dofMedian ? + View::DepthOfFieldOptions::Filter::MEDIAN : + View::DepthOfFieldOptions::Filter::NONE; + mSettings.view.dof.backgroundRingCount = dofRingCount; + mSettings.view.dof.foregroundRingCount = dofRingCount; + mSettings.view.dof.fastGatherRingCount = dofRingCount; + mSettings.view.dof.maxForegroundCOC = dofMaxCoC; + mSettings.view.dof.maxBackgroundCOC = dofMaxCoC; if (ImGui::CollapsingHeader("Vignette")) { ImGui::Checkbox("Enabled##vignetteEnabled", &mSettings.view.vignette.enabled); diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index 5b34a6dc3a..5ea32c448d 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -368,7 +368,13 @@ value_object("View$DepthOfFieldOptions") .field("cocScale", &filament::View::DepthOfFieldOptions::cocScale) .field("maxApertureDiameter", &filament::View::DepthOfFieldOptions::maxApertureDiameter) .field("enabled", &filament::View::DepthOfFieldOptions::enabled) - .field("filter", &filament::View::DepthOfFieldOptions::filter); + .field("filter", &filament::View::DepthOfFieldOptions::filter) + .field("nativeResolution", &filament::View::DepthOfFieldOptions::nativeResolution) + .field("foregroundRingCount", &filament::View::DepthOfFieldOptions::foregroundRingCount) + .field("backgroundRingCount", &filament::View::DepthOfFieldOptions::backgroundRingCount) + .field("fastGatherRingCount", &filament::View::DepthOfFieldOptions::fastGatherRingCount) + .field("maxForegroundCOC", &filament::View::DepthOfFieldOptions::maxForegroundCOC) + .field("maxBackgroundCOC", &filament::View::DepthOfFieldOptions::maxBackgroundCOC); value_object("View$BloomOptions") .field("dirtStrength", &filament::View::BloomOptions::dirtStrength) From ded542a5434b86cec19368e923dc88695bd06c30 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Mon, 22 Mar 2021 15:28:15 -0700 Subject: [PATCH 18/39] Introduce BufferObject API. NOTE: after Metal and Vulkan support lands, we can potentially simplify the Driver API by removing some of the old VertexBuffer entry points. This introduces a new API-level object called `BufferObject`, and a new backend-level object called `HwBufferObject`. This encapsulates a single VBO. It's especially useful when clients need to share data between multiple VertexBuffer objects. (e.g. for morphing). In the future, buffer objects could perhaps be used for non-vertex data (e.g. for compute). The existing `VertexBuffer` class can now be configured to use buffer objects by calling `enableBufferObjects` on the builder. By default its API is unchanged. If buffer objects are enabled, then clients should use `setBufferObjectAt` (which takes a buffer object) rather than `setBufferAt` (which takes CPU data). OpenGL is the trickiest backend for this, due to existence of VAOs. The implementation in this PR uses a version-tracking scheme to figure out when to update the VAO. --- android/filament-android/CMakeLists.txt | 1 + .../src/main/cpp/BufferObject.cpp | 99 +++++++++ .../src/main/cpp/VertexBuffer.cpp | 16 ++ .../google/android/filament/BufferObject.java | 210 ++++++++++++++++++ .../google/android/filament/VertexBuffer.java | 36 +++ filament/CMakeLists.txt | 3 + .../backend/include/backend/DriverEnums.h | 5 + filament/backend/include/backend/Handle.h | 2 + .../include/private/backend/DriverAPI.inc | 18 +- filament/backend/src/DriverBase.h | 10 +- filament/backend/src/metal/MetalDriver.mm | 30 ++- filament/backend/src/metal/MetalHandles.h | 2 +- filament/backend/src/metal/MetalHandles.mm | 5 +- filament/backend/src/noop/NoopDriver.cpp | 12 + filament/backend/src/opengl/OpenGLContext.h | 14 ++ filament/backend/src/opengl/OpenGLDriver.cpp | 177 ++++++++++++--- filament/backend/src/opengl/OpenGLDriver.h | 8 + filament/backend/src/vulkan/VulkanDriver.cpp | 37 ++- filament/backend/src/vulkan/VulkanHandles.cpp | 4 +- filament/backend/src/vulkan/VulkanHandles.h | 6 +- filament/backend/test/TrianglePrimitive.cpp | 2 +- filament/include/filament/BufferObject.h | 117 ++++++++++ filament/include/filament/Engine.h | 2 + filament/include/filament/IndexBuffer.h | 2 +- filament/include/filament/VertexBuffer.h | 26 +++ filament/src/BufferObject.cpp | 82 +++++++ filament/src/Engine.cpp | 14 ++ filament/src/VertexBuffer.cpp | 35 ++- filament/src/details/BufferObject.h | 58 +++++ filament/src/details/Engine.h | 4 + filament/src/details/VertexBuffer.h | 5 + java/filament/CMakeLists.txt | 2 + web/filament-js/extensions.js | 12 + web/filament-js/filament.d.ts | 21 ++ web/filament-js/jsbindings.cpp | 25 +++ web/filament-js/jsenums.cpp | 4 + 36 files changed, 1051 insertions(+), 55 deletions(-) create mode 100644 android/filament-android/src/main/cpp/BufferObject.cpp create mode 100644 android/filament-android/src/main/java/com/google/android/filament/BufferObject.java create mode 100644 filament/include/filament/BufferObject.h create mode 100644 filament/src/BufferObject.cpp create mode 100644 filament/src/details/BufferObject.h diff --git a/android/filament-android/CMakeLists.txt b/android/filament-android/CMakeLists.txt index 09cb594a78..8c89028b85 100644 --- a/android/filament-android/CMakeLists.txt +++ b/android/filament-android/CMakeLists.txt @@ -56,6 +56,7 @@ set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libfilament-jni.map") set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}") add_library(filament-jni SHARED + src/main/cpp/BufferObject.cpp src/main/cpp/Camera.cpp src/main/cpp/Colors.cpp src/main/cpp/ColorGrading.cpp diff --git a/android/filament-android/src/main/cpp/BufferObject.cpp b/android/filament-android/src/main/cpp/BufferObject.cpp new file mode 100644 index 0000000000..e86d81bd5c --- /dev/null +++ b/android/filament-android/src/main/cpp/BufferObject.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +#include + +#include + +#include "common/CallbackUtils.h" +#include "common/NioUtils.h" + +using namespace filament; +using namespace backend; + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_BufferObject_nCreateBuilder(JNIEnv *env, jclass type) { + return (jlong) new BufferObject::Builder(); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_BufferObject_nDestroyBuilder(JNIEnv *env, jclass type, + jlong nativeBuilder) { + BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder; + delete builder; +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_BufferObject_nBuilderSize(JNIEnv *env, jclass type, + jlong nativeBuilder, jint byteCount) { + BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder; + builder->size((uint32_t) byteCount); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_BufferObject_nBuilderBindingType(JNIEnv *env, jclass type, + jlong nativeBuilder, jint bindingType) { + using BindingType = BufferObject::BindingType; + BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder; + BindingType types[] = {BindingType::VERTEX}; + builder->bindingType(types[bindingType]); +} + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_BufferObject_nBuilderBuild(JNIEnv *env, jclass type, + jlong nativeBuilder, jlong nativeEngine) { + BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder; + Engine *engine = (Engine *) nativeEngine; + return (jlong) builder->build(*engine); +} + +extern "C" JNIEXPORT jint JNICALL +Java_com_google_android_filament_BufferObject_nGetByteCount(JNIEnv *env, jclass type, + jlong nativeBufferObject) { + BufferObject *bufferObject = (BufferObject *) nativeBufferObject; + return (jint) bufferObject->getByteCount(); +} + +extern "C" JNIEXPORT int JNICALL +Java_com_google_android_filament_BufferObject_nSetBuffer(JNIEnv *env, jclass type, + jlong nativeBufferObject, jlong nativeEngine, jobject buffer, int remaining, + jint destOffsetInBytes, jint count, + jobject handler, jobject runnable) { + BufferObject *bufferObject = (BufferObject *) nativeBufferObject; + Engine *engine = (Engine *) nativeEngine; + + AutoBuffer nioBuffer(env, buffer, count); + void* data = nioBuffer.getData(); + size_t sizeInBytes = nioBuffer.getSize(); + if (sizeInBytes > (remaining << nioBuffer.getShift())) { + // BufferOverflowException + return -1; + } + + auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer)); + + BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback); + + bufferObject->setBuffer(*engine, std::move(desc), (uint32_t) destOffsetInBytes); + + return 0; +} diff --git a/android/filament-android/src/main/cpp/VertexBuffer.cpp b/android/filament-android/src/main/cpp/VertexBuffer.cpp index 60d613ed75..ed9460e17a 100644 --- a/android/filament-android/src/main/cpp/VertexBuffer.cpp +++ b/android/filament-android/src/main/cpp/VertexBuffer.cpp @@ -50,6 +50,13 @@ Java_com_google_android_filament_VertexBuffer_nBuilderVertexCount(JNIEnv *env, j builder->vertexCount((uint32_t) vertexCount); } +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_VertexBuffer_nBuilderEnableBufferObjects(JNIEnv *env, jclass type, + jlong nativeBuilder, jboolean enabled) { + VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder; + builder->enableBufferObjects(enabled); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_VertexBuffer_nBuilderBufferCount(JNIEnv *env, jclass type, jlong nativeBuilder, jint bufferCount) { @@ -115,6 +122,15 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t return 0; } +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_VertexBuffer_nSetBufferObjectAt(JNIEnv *env, jclass type, + jlong nativeVertexBuffer, jlong nativeEngine, jint bufferIndex, jlong nativeBufferObject) { + VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer; + Engine *engine = (Engine *) nativeEngine; + BufferObject *bufferObject = (BufferObject *) nativeBufferObject; + vertexBuffer->setBufferObjectAt(*engine, (uint8_t) bufferIndex, bufferObject); +} + extern "C" [[deprecated]] JNIEXPORT void JNICALL Java_com_google_android_filament_VertexBuffer_nPopulateTangentQuaternions(JNIEnv *env, jclass type, jint quatType, jint quatCount, jobject outBuffer, jint outRemaining, diff --git a/android/filament-android/src/main/java/com/google/android/filament/BufferObject.java b/android/filament-android/src/main/java/com/google/android/filament/BufferObject.java new file mode 100644 index 0000000000..7fc63e3652 --- /dev/null +++ b/android/filament-android/src/main/java/com/google/android/filament/BufferObject.java @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.filament; + +import androidx.annotation.IntRange; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.nio.Buffer; +import java.nio.BufferOverflowException; + +/** + * A generic GPU buffer containing data. + * + * Usage of this BufferObject is optional. For simple use cases it is not necessary. It is useful + * only when you need to share data between multiple VertexBuffer instances. It also allows you to + * efficiently swap-out the buffers in VertexBuffer. + * + * NOTE: For now this is only used for vertex data, but in the future we may use it for other things + * (e.g. compute). + * + * @see VertexBuffer + */ +public class BufferObject { + private long mNativeObject; + + private BufferObject(long nativeBufferObject) { + mNativeObject = nativeBufferObject; + } + + public static class Builder { + @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) + // Keep to finalize native resources + private final BuilderFinalizer mFinalizer; + private final long mNativeBuilder; + + public enum BindingType { + VERTEX, + } + + public Builder() { + mNativeBuilder = nCreateBuilder(); + mFinalizer = new BuilderFinalizer(mNativeBuilder); + } + + /** + * Size of the buffer in bytes. + * + * @param byteCount Maximum number of bytes the BufferObject can hold. + * @return A reference to this Builder for chaining calls. + */ + @NonNull + public Builder size(@IntRange(from = 1) int byteCount) { + nBuilderSize(mNativeBuilder, byteCount); + return this; + } + + /** + * The binding type for this buffer object. (defaults to VERTEX) + * + * @param BindingType Distinguishes between SSBO, VBO, etc. For now this must be VERTEX. + * @return A reference to this Builder for chaining calls. + */ + @NonNull + public Builder bindingType(@NonNull BindingType bindingType) { + nBuilderBindingType(mNativeBuilder, bindingType.ordinal()); + return this; + } + + /** + * Creates and returns the BufferObject object. After creation, the buffer + * is uninitialized. Use {@link #setBuffer} to initialize the BufferObject. + * + * @param engine reference to the {@link Engine} to associate this BufferObject + * with + * + * @return the newly created BufferObject object + * + * @exception IllegalStateException if the BufferObject could not be created + * + * @see #setBuffer + */ + @NonNull + public BufferObject build(@NonNull Engine engine) { + long nativeBufferObject = nBuilderBuild(mNativeBuilder, engine.getNativeObject()); + if (nativeBufferObject == 0) + throw new IllegalStateException("Couldn't create BufferObject"); + return new BufferObject(nativeBufferObject); + } + + private static class BuilderFinalizer { + private final long mNativeObject; + + BuilderFinalizer(long nativeObject) { + mNativeObject = nativeObject; + } + + @Override + public void finalize() { + try { + super.finalize(); + } catch (Throwable t) { // Ignore + } finally { + nDestroyBuilder(mNativeObject); + } + } + } + } + + /** + * Returns the size of this BufferObject in elements. + * + * @return the number of bytes the BufferObject holds + */ + @IntRange(from = 0) + public int getByteCount() { + return nGetByteCount(getNativeObject()); + } + + /** + * Asynchronously copy-initializes this BufferObject from the data provided. + * + * @param engine reference to the {@link Engine} to associate this + * BufferObject with + * @param buffer a CPU-side {@link Buffer} with the data used to initialize the + * BufferObject. + */ + public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer) { + setBuffer(engine, buffer, 0, 0, null, null); + } + + /** + * Asynchronously copy-initializes a region of this BufferObject from the data + * provided. + * + * @param engine reference to the {@link Engine} to associate this + * BufferObject with + * @param buffer a CPU-side {@link Buffer} with the data used to initialize the + * BufferObject. + * @param destOffsetInBytes offset in bytes into the BufferObject + * @param count number of bytes to consume, defaults to + * buffer.remaining() + */ + public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer, + @IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count) { + setBuffer(engine, buffer, destOffsetInBytes, count, null, null); + } + + /** + * Asynchronously copy-initializes a region of this BufferObject from the data + * provided. + * + * @param engine reference to the {@link Engine} to associate this + * BufferObject with + * @param buffer a CPU-side {@link Buffer} with the data used to initialize the + * BufferObject. + * @param destOffsetInBytes offset in bytes into the BufferObject + * @param count number of bytes to consume, defaults to + * buffer.remaining() + * @param handler an {@link java.util.concurrent.Executor Executor}. On Android this + * can also be a {@link android.os.Handler Handler}. + * @param callback a callback executed by handler when buffer + * is no longer needed. + */ + public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer, + @IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count, + @Nullable Object handler, @Nullable Runnable callback) { + int result = nSetBuffer(getNativeObject(), engine.getNativeObject(), buffer, buffer.remaining(), + destOffsetInBytes, count == 0 ? buffer.remaining() : count, handler, callback); + if (result < 0) { + throw new BufferOverflowException(); + } + } + + public long getNativeObject() { + if (mNativeObject == 0) { + throw new IllegalStateException("Calling method on destroyed BufferObject"); + } + return mNativeObject; + } + + void clearNativeObject() { + mNativeObject = 0; + } + + private static native long nCreateBuilder(); + private static native void nDestroyBuilder(long nativeBuilder); + private static native void nBuilderSize(long nativeBuilder, int byteCount); + private static native void nBuilderBindingType(long nativeBuilder, int bindingType); + private static native long nBuilderBuild(long nativeBuilder, long nativeEngine); + + private static native int nGetByteCount(long nativeBufferObject); + private static native int nSetBuffer(long nativeBufferObject, long nativeEngine, + Buffer buffer, int remaining, + int destOffsetInBytes, int count, Object handler, Runnable callback); +} diff --git a/android/filament-android/src/main/java/com/google/android/filament/VertexBuffer.java b/android/filament-android/src/main/java/com/google/android/filament/VertexBuffer.java index 6d56e12cba..0ff6f52c2e 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/VertexBuffer.java +++ b/android/filament-android/src/main/java/com/google/android/filament/VertexBuffer.java @@ -170,6 +170,21 @@ public class VertexBuffer { return this; } + /** + * Allows buffers to be swapped out and shared using BufferObject. + * + * If buffer objects mode is enabled, clients must call setBufferObjectAt rather than + * setBufferAt. This allows sharing of data between VertexBuffer objects, but it may + * slightly increase the memory footprint of Filament's internal bookkeeping. + * + * @param enabled If true, enables buffer object mode. False by default. + */ + @NonNull + public Builder enableBufferObjects(boolean enabled) { + nBuilderEnableBufferObjects(mNativeBuilder, enabled); + return this; + } + /** * Defines how many buffers will be created in this vertex buffer set. These buffers are * later referenced by index from 0 to bufferCount - 1. @@ -397,6 +412,23 @@ public class VertexBuffer { throw new BufferOverflowException(); } } + + /** + * Swaps in the given buffer object. + * + * To use this, you must first call enableBufferObjects() on the Builder. + * + * @param engine Reference to the filament::Engine to associate this VertexBuffer with. + * @param bufferIndex Index of the buffer to initialize. Must be between 0 + * and Builder::bufferCount() - 1. + * @param bufferObject The handle to the GPU data that will be used in this buffer slot. + */ + public void setBufferObjectAt(@NonNull Engine engine, int bufferIndex, + @NonNull BufferObject bufferObject) { + nSetBufferObjectAt(getNativeObject(), engine.getNativeObject(), bufferIndex, + bufferObject.getNativeObject()); + } + /** * Convenience function that consumes normal vectors (and, optionally, tangent vectors) and * produces quaternions that can be passed into a TANGENTS buffer. @@ -443,6 +475,7 @@ public class VertexBuffer { private static native long nCreateBuilder(); private static native void nDestroyBuilder(long nativeBuilder); private static native void nBuilderVertexCount(long nativeBuilder, int vertexCount); + private static native void nBuilderEnableBufferObjects(long nativeBuilder, boolean enabled); private static native void nBuilderBufferCount(long nativeBuilder, int bufferCount); private static native void nBuilderAttribute(long nativeBuilder, int attribute, int bufferIndex, int attributeType, int byteOffset, int byteStride); @@ -455,6 +488,9 @@ public class VertexBuffer { int bufferIndex, Buffer buffer, int remaining, int destOffsetInBytes, int count, Object handler, Runnable callback); + private static native void nSetBufferObjectAt(long nativeVertexBuffer, long nativeEngine, + int bufferIndex, long nativeBufferObject); + private static native void nPopulateTangentQuaternions(int quatType, int quatCount, Buffer outBuffer, int outRemaining, int outStride, Buffer normals, int normalsRemaining, int normalsStride, Buffer tangents, int tangentsRemaining, int tangentsStride); diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index cdc5cbcc05..5da39dcf42 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -13,6 +13,7 @@ set(MATERIAL_DIR "${GENERATION_ROOT}/generated/material") set(PUBLIC_HDRS include/filament/Box.h + include/filament/BufferObject.h include/filament/Camera.h include/filament/Color.h include/filament/ColorGrading.h @@ -44,6 +45,7 @@ set(PUBLIC_HDRS set(SRCS src/Box.cpp + src/BufferObject.cpp src/Camera.cpp src/Color.cpp src/ColorGrading.cpp @@ -112,6 +114,7 @@ set(PRIVATE_HDRS src/components/RenderableManager.h src/components/TransformManager.h src/details/Allocators.h + src/details/BufferObject.h src/details/Camera.h src/details/ColorGrading.h src/details/Culler.h diff --git a/filament/backend/include/backend/DriverEnums.h b/filament/backend/include/backend/DriverEnums.h index 1be9eb3d67..791becb8ba 100644 --- a/filament/backend/include/backend/DriverEnums.h +++ b/filament/backend/include/backend/DriverEnums.h @@ -263,6 +263,11 @@ enum class ElementType : uint8_t { HALF4, }; +//! Buffer object binding type +enum class BufferObjectBinding : uint8_t { + VERTEX, +}; + //! Face culling Mode enum class CullingMode : uint8_t { NONE, //!< No culling, front and back faces are visible diff --git a/filament/backend/include/backend/Handle.h b/filament/backend/include/backend/Handle.h index ae46710f10..62572c728c 100644 --- a/filament/backend/include/backend/Handle.h +++ b/filament/backend/include/backend/Handle.h @@ -24,6 +24,7 @@ namespace filament { namespace backend { +struct HwBufferObject; struct HwFence; struct HwIndexBuffer; struct HwProgram; @@ -96,6 +97,7 @@ private: // Types used by the command stream // (we use this renaming because the macro-system doesn't deal well with "<" and ">") +using BufferObjectHandle = Handle; using FenceHandle = Handle; using IndexBufferHandle = Handle; using ProgramHandle = Handle; diff --git a/filament/backend/include/private/backend/DriverAPI.inc b/filament/backend/include/private/backend/DriverAPI.inc index f11e3d9b64..1cb402eee2 100644 --- a/filament/backend/include/private/backend/DriverAPI.inc +++ b/filament/backend/include/private/backend/DriverAPI.inc @@ -168,13 +168,18 @@ DECL_DRIVER_API_R_N(backend::VertexBufferHandle, createVertexBuffer, uint8_t, attributeCount, uint32_t, vertexCount, backend::AttributeArray, attributes, - backend::BufferUsage, usage) + backend::BufferUsage, usage, + bool, bufferObjectsEnabled) DECL_DRIVER_API_R_N(backend::IndexBufferHandle, createIndexBuffer, backend::ElementType, elementType, uint32_t, indexCount, backend::BufferUsage, usage) +DECL_DRIVER_API_R_N(backend::BufferObjectHandle, createBufferObject, + uint32_t, byteCount, + backend::BufferObjectBinding, bindingType) + DECL_DRIVER_API_R_N(backend::TextureHandle, createTexture, backend::SamplerType, target, uint8_t, levels, @@ -261,6 +266,7 @@ DECL_DRIVER_API_R_0(backend::TimerQueryHandle, createTimerQuery) DECL_DRIVER_API_N(destroyVertexBuffer, backend::VertexBufferHandle, vbh) DECL_DRIVER_API_N(destroyIndexBuffer, backend::IndexBufferHandle, ibh) +DECL_DRIVER_API_N(destroyBufferObject, backend::BufferObjectHandle, ibh) DECL_DRIVER_API_N(destroyRenderPrimitive, backend::RenderPrimitiveHandle, rph) DECL_DRIVER_API_N(destroyProgram, backend::ProgramHandle, ph) DECL_DRIVER_API_N(destroySamplerGroup, backend::SamplerGroupHandle, sbh) @@ -311,11 +317,21 @@ DECL_DRIVER_API_N(updateVertexBuffer, backend::BufferDescriptor&&, data, uint32_t, byteOffset) +DECL_DRIVER_API_N(setVertexBufferObject, + backend::VertexBufferHandle, vbh, + size_t, index, + backend::BufferObjectHandle, bufferObject) + DECL_DRIVER_API_N(updateIndexBuffer, backend::IndexBufferHandle, ibh, backend::BufferDescriptor&&, data, uint32_t, byteOffset) +DECL_DRIVER_API_N(updateBufferObject, + backend::BufferObjectHandle, ibh, + backend::BufferDescriptor&&, data, + uint32_t, byteOffset) + DECL_DRIVER_API_N(loadUniformBuffer, backend::UniformBufferHandle, ubh, backend::BufferDescriptor&&, buffer) diff --git a/filament/backend/src/DriverBase.h b/filament/backend/src/DriverBase.h index 5cedddc76e..75017f7a35 100644 --- a/filament/backend/src/DriverBase.h +++ b/filament/backend/src/DriverBase.h @@ -55,18 +55,22 @@ struct HwVertexBuffer : public HwBase { uint32_t vertexCount{}; // 4 uint8_t bufferCount{}; // 1 uint8_t attributeCount{}; // 1 - uint8_t padding[2]{}; // 2 -> total struct is 136 bytes + bool bufferObjectsEnabled{}; // 1 + uint8_t bufferObjectsVersion{}; // 1 -> total struct is 136 bytes HwVertexBuffer() noexcept = default; HwVertexBuffer(uint8_t bufferCount, uint8_t attributeCount, uint32_t elementCount, - AttributeArray const& attributes) noexcept + AttributeArray const& attributes, bool bufferObjectsEnabled) noexcept : attributes(attributes), vertexCount(elementCount), bufferCount(bufferCount), - attributeCount(attributeCount) { + attributeCount(attributeCount), + bufferObjectsEnabled(bufferObjectsEnabled) { } }; +struct HwBufferObject : public HwBase {}; + struct HwIndexBuffer : public HwBase { uint32_t count{}; uint8_t elementSize{}; diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index b2f565e0be..39f38578b6 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -160,10 +160,10 @@ void MetalDriver::finish(int) { void MetalDriver::createVertexBufferR(Handle vbh, uint8_t bufferCount, uint8_t attributeCount, uint32_t vertexCount, AttributeArray attributes, - BufferUsage usage) { + BufferUsage usage, bool bufferObjectsEnabled) { // TODO: Take BufferUsage into account when creating the buffer. construct_handle(mHandleMap, vbh, *mContext, bufferCount, - attributeCount, vertexCount, attributes); + attributeCount, vertexCount, attributes, bufferObjectsEnabled); } void MetalDriver::createIndexBufferR(Handle ibh, ElementType elementType, @@ -172,6 +172,11 @@ void MetalDriver::createIndexBufferR(Handle ibh, ElementType elem construct_handle(mHandleMap, ibh, *mContext, elementSize, indexCount); } +void MetalDriver::createBufferObjectR(Handle boh, uint32_t byteCount, + BufferObjectBinding bindingType) { + // TODO +} + void MetalDriver::createTextureR(Handle th, SamplerType target, uint8_t levels, TextureFormat format, uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage) { @@ -321,6 +326,11 @@ Handle MetalDriver::createIndexBufferS() noexcept { return alloc_handle(); } +Handle MetalDriver::createBufferObjectS() noexcept { + // TODO + return {}; +} + Handle MetalDriver::createTextureS() noexcept { return alloc_handle(); } @@ -399,6 +409,12 @@ void MetalDriver::destroyIndexBuffer(Handle ibh) { } } +void MetalDriver::destroyBufferObject(Handle boh) { + if (boh) { + // TODO + } +} + void MetalDriver::destroyRenderPrimitive(Handle rph) { if (rph) { destruct_handle(mHandleMap, rph); @@ -650,6 +666,16 @@ void MetalDriver::updateIndexBuffer(Handle ibh, BufferDescriptor& scheduleDestroy(std::move(data)); } +void MetalDriver::updateBufferObject(Handle boh, BufferDescriptor&& data, + uint32_t byteOffset) { + // TODO +} + +void MetalDriver::setVertexBufferObject(Handle vbh, size_t index, + Handle boh) { + // TODO +} + void MetalDriver::update2DImage(Handle th, uint32_t level, uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height, PixelBufferDescriptor&& data) { ASSERT_PRECONDITION(!isInRenderPass(mContext), diff --git a/filament/backend/src/metal/MetalHandles.h b/filament/backend/src/metal/MetalHandles.h index 01dce978a5..7d021b6c80 100644 --- a/filament/backend/src/metal/MetalHandles.h +++ b/filament/backend/src/metal/MetalHandles.h @@ -114,7 +114,7 @@ private: struct MetalVertexBuffer : public HwVertexBuffer { MetalVertexBuffer(MetalContext& context, uint8_t bufferCount, uint8_t attributeCount, - uint32_t vertexCount, AttributeArray const& attributes); + uint32_t vertexCount, AttributeArray const& attributes, bool bufferObjectsEnabled); ~MetalVertexBuffer(); std::vector buffers; diff --git a/filament/backend/src/metal/MetalHandles.mm b/filament/backend/src/metal/MetalHandles.mm index 506105653b..a7186e0c88 100644 --- a/filament/backend/src/metal/MetalHandles.mm +++ b/filament/backend/src/metal/MetalHandles.mm @@ -267,8 +267,9 @@ void MetalSwapChain::scheduleFrameCompletedCallback() { } MetalVertexBuffer::MetalVertexBuffer(MetalContext& context, uint8_t bufferCount, - uint8_t attributeCount, uint32_t vertexCount, AttributeArray const& attributes) - : HwVertexBuffer(bufferCount, attributeCount, vertexCount, attributes) { + uint8_t attributeCount, uint32_t vertexCount, AttributeArray const& attributes, + bool bufferObjectsEnabled) + : HwVertexBuffer(bufferCount, attributeCount, vertexCount, attributes, bufferObjectsEnabled) { buffers.reserve(bufferCount); for (uint8_t bufferIndex = 0; bufferIndex < bufferCount; ++bufferIndex) { diff --git a/filament/backend/src/noop/NoopDriver.cpp b/filament/backend/src/noop/NoopDriver.cpp index 96fa53800a..2b89aa19c3 100644 --- a/filament/backend/src/noop/NoopDriver.cpp +++ b/filament/backend/src/noop/NoopDriver.cpp @@ -85,6 +85,9 @@ void NoopDriver::destroyVertexBuffer(Handle vbh) { void NoopDriver::destroyIndexBuffer(Handle ibh) { } +void NoopDriver::destroyBufferObject(Handle boh) { +} + void NoopDriver::destroyTexture(Handle th) { } @@ -182,6 +185,15 @@ void NoopDriver::updateIndexBuffer(Handle ibh, BufferDescriptor&& scheduleDestroy(std::move(p)); } +void NoopDriver::updateBufferObject(Handle ibh, BufferDescriptor&& p, + uint32_t byteOffset) { + scheduleDestroy(std::move(p)); +} + +void NoopDriver::setVertexBufferObject(Handle vbh, size_t index, + Handle boh) { +} + void NoopDriver::update2DImage(Handle th, uint32_t level, uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height, PixelBufferDescriptor&& data) { diff --git a/filament/backend/src/opengl/OpenGLContext.h b/filament/backend/src/opengl/OpenGLContext.h index d72997526d..1b246b9913 100644 --- a/filament/backend/src/opengl/OpenGLContext.h +++ b/filament/backend/src/opengl/OpenGLContext.h @@ -22,6 +22,8 @@ #include #include +#include + #include "GLUtils.h" #include @@ -35,11 +37,23 @@ public: typedef math::details::TVec4 vec4gli; typedef math::details::TVec2 vec2glf; + // TODO: the footprint of this structure can be reduced. We need only 1 bit for index type, 16 + // bits for vertexAttribArray. We can also use fewer bits for vertexBufferVersion, although + // this will require a corollary update in OpenGLDriver::setVertexBufferObject(). struct RenderPrimitive { GLuint vao = 0; GLenum indicesType = GL_UNSIGNED_INT; GLuint elementArray = 0; utils::bitset32 vertexAttribArray; + + // The optional 32-bit handle to a GLVertexBuffer is necessary only if the referenced + // VertexBuffer supports buffer objects. If this is zero, then the VBO handles array is + // immutable. + backend::Handle vertexBufferWithObjects = {}; + + // If this version number does not match vertexBufferWithObjects->bufferObjectsVersion, + // then the VAO needs to be updated. + uint8_t vertexBufferVersion = 0; } gl; OpenGLContext() noexcept; diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index a0209573d0..d7af3e13e5 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -412,6 +412,10 @@ Handle OpenGLDriver::createIndexBufferS() noexcept { return initHandle(); } +Handle OpenGLDriver::createBufferObjectS() noexcept { + return initHandle(); +} + Handle OpenGLDriver::createRenderPrimitiveS() noexcept { return initHandle(); } @@ -478,12 +482,13 @@ void OpenGLDriver::createVertexBufferR( uint8_t attributeCount, uint32_t elementCount, AttributeArray attributes, - BufferUsage usage) { + BufferUsage usage, + bool bufferObjectsEnabled) { DEBUG_MARKER() auto& gl = mContext; GLVertexBuffer* vb = construct(vbh, - bufferCount, attributeCount, elementCount, attributes); + bufferCount, attributeCount, elementCount, attributes, bufferObjectsEnabled); GLsizei n = GLsizei(vb->bufferCount); @@ -524,6 +529,24 @@ void OpenGLDriver::createIndexBufferR( CHECK_GL_ERROR(utils::slog.e) } +void OpenGLDriver::createBufferObjectR( + Handle boh, + uint32_t byteCount, + BufferObjectBinding bindingType) { + DEBUG_MARKER() + + auto& gl = mContext; + GLBufferObject* bo = construct(boh); + glGenBuffers(1, &bo->gl.id); + gl.bindVertexArray(nullptr); + + assert_invariant(bindingType == BufferObjectBinding::VERTEX); + + gl.bindBuffer(GL_ARRAY_BUFFER, bo->gl.id); + glBufferData(GL_ARRAY_BUFFER, byteCount, nullptr, GL_STATIC_DRAW); + CHECK_GL_ERROR(utils::slog.e) +} + void OpenGLDriver::createRenderPrimitiveR(Handle rph, int) { DEBUG_MARKER() @@ -757,6 +780,57 @@ void OpenGLDriver::importTextureR(Handle th, intptr_t id, CHECK_GL_ERROR(utils::slog.e) } +void OpenGLDriver::updateVertexArrayObject(GLRenderPrimitive* rp, GLVertexBuffer const* vb) { + + auto& gl = mContext; + + // NOTE: this is called from draw() and must be as efficient as possible. + + // The VAO for the given render primitive must already be bound. + #ifndef NDEBUG + GLint vaoBinding; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vaoBinding); + assert_invariant(vaoBinding == (GLint) rp->gl.vao); + #endif + + rp->gl.vertexBufferVersion = vb->bufferObjectsVersion; + rp->maxVertexCount = vb->vertexCount; + for (size_t i = 0, n = vb->attributes.size(); i < n; i++) { + const auto& attribute = vb->attributes[i]; + if (attribute.buffer != Attribute::BUFFER_UNUSED) { + uint8_t bi = attribute.buffer; + gl.bindBuffer(GL_ARRAY_BUFFER, vb->gl.buffers[bi]); + if (UTILS_UNLIKELY(attribute.flags & Attribute::FLAG_INTEGER_TARGET)) { + glVertexAttribIPointer(GLuint(i), + getComponentCount(attribute.type), + getComponentType(attribute.type), + attribute.stride, + (void*) uintptr_t(attribute.offset)); + } else { + glVertexAttribPointer(GLuint(i), + getComponentCount(attribute.type), + getComponentType(attribute.type), + getNormalization(attribute.flags & Attribute::FLAG_NORMALIZED), + attribute.stride, + (void*) uintptr_t(attribute.offset)); + } + + gl.enableVertexAttribArray(GLuint(i)); + } else { + + // In some OpenGL implementations, we must supply a properly-typed placeholder for + // every integer input that is declared in the vertex shader. + if (UTILS_UNLIKELY(attribute.flags & Attribute::FLAG_INTEGER_TARGET)) { + glVertexAttribI4ui(GLuint(i), 0, 0, 0, 0); + } else { + glVertexAttrib4f(GLuint(i), 0, 0, 0, 0); + } + + gl.disableVertexAttribArray(GLuint(i)); + } + } +} + void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, GLRenderTarget const* rt, GLenum attachment) noexcept { @@ -1223,6 +1297,17 @@ void OpenGLDriver::destroyIndexBuffer(Handle ibh) { } } +void OpenGLDriver::destroyBufferObject(Handle boh) { + DEBUG_MARKER() + + if (boh) { + auto& gl = mContext; + GLBufferObject const* bo = handle_cast(boh); + gl.deleteBuffers(1, &bo->gl.id, GL_ARRAY_BUFFER); + destruct(boh, bo); + } +} + void OpenGLDriver::destroyRenderPrimitive(Handle rph) { DEBUG_MARKER() @@ -1633,6 +1718,7 @@ void OpenGLDriver::updateVertexBuffer(Handle vbh, auto& gl = mContext; GLVertexBuffer* eb = handle_cast(vbh); + assert_invariant(!eb->bufferObjectsEnabled && "Please use setVertexBufferObject() instead."); gl.bindBuffer(GL_ARRAY_BUFFER, eb->gl.buffers[index]); glBufferSubData(GL_ARRAY_BUFFER, byteOffset, p.size, p.buffer); @@ -1642,6 +1728,29 @@ void OpenGLDriver::updateVertexBuffer(Handle vbh, CHECK_GL_ERROR(utils::slog.e) } +void OpenGLDriver::setVertexBufferObject(Handle vbh, + size_t index, Handle boh) { + DEBUG_MARKER() + + GLVertexBuffer* vb = handle_cast(vbh); + assert_invariant(vb->bufferObjectsEnabled && "Please use updateVertexBuffer() instead."); + + GLBufferObject* bo = handle_cast(boh); + + // If the specified VBO handle is different from what's already in the slot, then update the + // slot and bump the cyclical version number. Dependent VAOs use the version number to detect + // when they should be updated. + if (vb->gl.buffers[index] != bo->gl.id) { + vb->gl.buffers[index] = bo->gl.id; + static constexpr uint32_t kMaxVersion = + std::numeric_limitsbufferObjectsVersion)>::max(); + const uint32_t version = vb->bufferObjectsVersion; + vb->bufferObjectsVersion = (version + 1) % kMaxVersion; + } + + CHECK_GL_ERROR(utils::slog.e) +} + void OpenGLDriver::updateIndexBuffer( Handle ibh, BufferDescriptor&& p, uint32_t byteOffset) { DEBUG_MARKER() @@ -1659,6 +1768,22 @@ void OpenGLDriver::updateIndexBuffer( CHECK_GL_ERROR(utils::slog.e) } +void OpenGLDriver::updateBufferObject( + Handle boh, BufferDescriptor&& bd, uint32_t byteOffset) { + DEBUG_MARKER() + + auto& gl = mContext; + GLBufferObject* bo = handle_cast(boh); + + gl.bindVertexArray(nullptr); + gl.bindBuffer(GL_ARRAY_BUFFER, bo->gl.id); + glBufferSubData(GL_ARRAY_BUFFER, byteOffset, bd.size, bd.buffer); + + scheduleDestroy(std::move(bd)); + + CHECK_GL_ERROR(utils::slog.e) +} + void OpenGLDriver::loadUniformBuffer(Handle ubh, BufferDescriptor&& p) { DEBUG_MARKER() @@ -2389,41 +2514,13 @@ void OpenGLDriver::setRenderPrimitiveBuffer(Handle rph, CHECK_GL_ERROR(utils::slog.e) rp->gl.indicesType = ib->elementSize == 4 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; - rp->maxVertexCount = eb->vertexCount; - for (size_t i = 0, n = eb->attributes.size(); i < n; i++) { - const auto& attribute = eb->attributes[i]; - if (attribute.buffer != Attribute::BUFFER_UNUSED) { - uint8_t bi = attribute.buffer; - gl.bindBuffer(GL_ARRAY_BUFFER, eb->gl.buffers[bi]); - if (UTILS_UNLIKELY(attribute.flags & Attribute::FLAG_INTEGER_TARGET)) { - glVertexAttribIPointer(GLuint(i), - getComponentCount(attribute.type), - getComponentType(attribute.type), - attribute.stride, - (void*) uintptr_t(attribute.offset)); - } else { - glVertexAttribPointer(GLuint(i), - getComponentCount(attribute.type), - getComponentType(attribute.type), - getNormalization(attribute.flags & Attribute::FLAG_NORMALIZED), - attribute.stride, - (void*) uintptr_t(attribute.offset)); - } - gl.enableVertexAttribArray(GLuint(i)); - } else { + rp->gl.vertexBufferWithObjects = eb->bufferObjectsEnabled ? vbh : + backend::Handle {}; - // In some OpenGL implementations, we must supply a properly-typed placeholder for - // every integer input that is declared in the vertex shader. - if (UTILS_UNLIKELY(attribute.flags & Attribute::FLAG_INTEGER_TARGET)) { - glVertexAttribI4ui(GLuint(i), 0, 0, 0, 0); - } else { - glVertexAttrib4f(GLuint(i), 0, 0, 0, 0); - } + // update the VBO bindings in the VAO + updateVertexArrayObject(rp, eb); - gl.disableVertexAttribArray(GLuint(i)); - } - } // this records the index buffer into the currently bound VAO gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib->gl.buffer); @@ -3120,9 +3217,19 @@ void OpenGLDriver::draw(PipelineState state, Handle rph) { useProgram(p); - const GLRenderPrimitive* rp = handle_cast(rph); + GLRenderPrimitive* rp = handle_cast(rph); + gl.bindVertexArray(&rp->gl); + // If necessary, mutate the bindings in the VAO. + VertexBufferHandle vbwo = rp->gl.vertexBufferWithObjects; + if (UTILS_UNLIKELY(vbwo)) { + const GLVertexBuffer* vb = handle_cast(vbwo); + if (rp->gl.vertexBufferVersion != vb->bufferObjectsVersion) { + updateVertexArrayObject(rp, vb); + } + } + setRasterState(state.rasterState); gl.polygonOffset(state.polygonOffset.slope, state.polygonOffset.constant); diff --git a/filament/backend/src/opengl/OpenGLDriver.h b/filament/backend/src/opengl/OpenGLDriver.h index 1b306184f7..46e84b8127 100644 --- a/filament/backend/src/opengl/OpenGLDriver.h +++ b/filament/backend/src/opengl/OpenGLDriver.h @@ -69,6 +69,12 @@ public: backend::BufferUsage usage = {}; }; + struct GLBufferObject : public backend::HwBufferObject { + struct { + GLuint id = 0; + } gl; + }; + struct GLVertexBuffer : public backend::HwVertexBuffer { using HwVertexBuffer::HwVertexBuffer; struct { @@ -315,6 +321,8 @@ private: /* Misc... */ + void updateVertexArrayObject(GLRenderPrimitive* rp, GLVertexBuffer const* vb); + void framebufferTexture(backend::TargetBufferInfo const& binfo, GLRenderTarget const* rt, GLenum attachment) noexcept; diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 75d0a2b014..2662b5250d 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -446,9 +446,9 @@ void VulkanDriver::destroyRenderPrimitive(Handle rph) { void VulkanDriver::createVertexBufferR(Handle vbh, uint8_t bufferCount, uint8_t attributeCount, uint32_t elementCount, AttributeArray attributes, - BufferUsage usage) { + BufferUsage usage, bool bufferObjectsEnabled) { auto vertexBuffer = construct_handle(mHandleMap, vbh, mContext, mStagePool, - mDisposer, bufferCount, attributeCount, elementCount, attributes); + mDisposer, bufferCount, attributeCount, elementCount, attributes, bufferObjectsEnabled); mDisposer.createDisposable(vertexBuffer, [this, vbh] () { destruct_handle(mHandleMap, vbh); }); @@ -478,6 +478,22 @@ void VulkanDriver::destroyIndexBuffer(Handle ibh) { } } +void VulkanDriver::createBufferObjectR(Handle boh, + uint32_t byteCount, BufferObjectBinding bindingType) { + // TODO: pass constructor args + auto bufferObject = construct_handle(mHandleMap, boh); + mDisposer.createDisposable(bufferObject, [this, boh] () { + destruct_handle(mHandleMap, boh); + }); +} + +void VulkanDriver::destroyBufferObject(Handle boh) { + if (boh) { + auto bufferObject = handle_cast(mHandleMap, boh); + mDisposer.removeReference(bufferObject); + } +} + void VulkanDriver::createTextureR(Handle th, SamplerType target, uint8_t levels, TextureFormat format, uint8_t samples, uint32_t w, uint32_t h, uint32_t depth, TextureUsage usage) { @@ -622,6 +638,10 @@ Handle VulkanDriver::createIndexBufferS() noexcept { return alloc_handle(); } +Handle VulkanDriver::createBufferObjectS() noexcept { + return alloc_handle(); +} + Handle VulkanDriver::createTextureS() noexcept { return alloc_handle(); } @@ -851,6 +871,11 @@ void VulkanDriver::updateVertexBuffer(Handle vbh, size_t index, scheduleDestroy(std::move(p)); } +void VulkanDriver::setVertexBufferObject(Handle vbh, size_t index, + Handle boh) { + // TODO +} + void VulkanDriver::updateIndexBuffer(Handle ibh, BufferDescriptor&& p, uint32_t byteOffset) { auto& ib = *handle_cast(mHandleMap, ibh); @@ -858,6 +883,13 @@ void VulkanDriver::updateIndexBuffer(Handle ibh, BufferDescriptor scheduleDestroy(std::move(p)); } +void VulkanDriver::updateBufferObject(Handle boh, BufferDescriptor&& bd, + uint32_t byteOffset) { + auto& bo = *handle_cast(mHandleMap, boh); + bo.buffer->loadFromCpu(bd.buffer, byteOffset, bd.size); + scheduleDestroy(std::move(bd)); +} + void VulkanDriver::update2DImage(Handle th, uint32_t level, uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height, PixelBufferDescriptor&& data) { @@ -1765,6 +1797,7 @@ void VulkanDriver::debugCommand(const char* methodName) { "loadUniformBuffer", "updateVertexBuffer", "updateIndexBuffer", + "updateBufferObject", "update2DImage", "updateCubeImage", }; diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 9851e50248..28d623df5f 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -403,8 +403,8 @@ bool VulkanRenderTarget::invalidate() { VulkanVertexBuffer::VulkanVertexBuffer(VulkanContext& context, VulkanStagePool& stagePool, VulkanDisposer& disposer, uint8_t bufferCount, uint8_t attributeCount, - uint32_t elementCount, AttributeArray const& attributes) : - HwVertexBuffer(bufferCount, attributeCount, elementCount, attributes) { + uint32_t elementCount, AttributeArray const& attributes, bool boEnabled) : + HwVertexBuffer(bufferCount, attributeCount, elementCount, attributes, boEnabled) { buffers.reserve(bufferCount); for (uint8_t bufferIndex = 0; bufferIndex < bufferCount; ++bufferIndex) { uint32_t size = 0; diff --git a/filament/backend/src/vulkan/VulkanHandles.h b/filament/backend/src/vulkan/VulkanHandles.h index 5de32730fb..d8f1e251ad 100644 --- a/filament/backend/src/vulkan/VulkanHandles.h +++ b/filament/backend/src/vulkan/VulkanHandles.h @@ -83,7 +83,7 @@ struct VulkanSwapChain : public HwSwapChain { struct VulkanVertexBuffer : public HwVertexBuffer { VulkanVertexBuffer(VulkanContext& context, VulkanStagePool& stagePool, VulkanDisposer& disposer, uint8_t bufferCount, uint8_t attributeCount, uint32_t elementCount, - AttributeArray const& attributes); + AttributeArray const& attributes, bool bufferObjectsEnabled); std::vector> buffers; }; @@ -97,6 +97,10 @@ struct VulkanIndexBuffer : public HwIndexBuffer { const std::unique_ptr buffer; }; +struct VulkanBufferObject : public HwBufferObject { + const std::unique_ptr buffer; +}; + struct VulkanUniformBuffer : public HwUniformBuffer { VulkanUniformBuffer(VulkanContext& context, VulkanStagePool& stagePool, VulkanDisposer& disposer, uint32_t numBytes, backend::BufferUsage usage); diff --git a/filament/backend/test/TrianglePrimitive.cpp b/filament/backend/test/TrianglePrimitive.cpp index ad48fad0fa..594f6d5ffd 100644 --- a/filament/backend/test/TrianglePrimitive.cpp +++ b/filament/backend/test/TrianglePrimitive.cpp @@ -48,7 +48,7 @@ TrianglePrimitive::TrianglePrimitive(filament::backend::DriverApi& driverApi, enabledAttributes.set(VertexAttribute::POSITION); mVertexBuffer = mDriverApi.createVertexBuffer(1, 1, mVertexCount, attributes, - BufferUsage::STATIC); + BufferUsage::STATIC, false); BufferDescriptor vertexBufferDesc(gVertices, sizeof(filament::math::float2) * 3, nullptr); mDriverApi.updateVertexBuffer(mVertexBuffer, 0, std::move(vertexBufferDesc), 0); diff --git a/filament/include/filament/BufferObject.h b/filament/include/filament/BufferObject.h new file mode 100644 index 0000000000..1ede31b8cb --- /dev/null +++ b/filament/include/filament/BufferObject.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//! \file + +#ifndef TNT_FILAMENT_BUFFEROBJECT_H +#define TNT_FILAMENT_BUFFEROBJECT_H + +#include + +#include + +#include + +#include + +namespace filament { + +class FBufferObject; + +class Engine; + +/** + * A generic GPU buffer containing data. + * + * Usage of this BufferObject is optional. For simple use cases it is not necessary. It is useful + * only when you need to share data between multiple VertexBuffer instances. It also allows you to + * efficiently swap-out the buffers in VertexBuffer. + * + * NOTE: For now this is only used for vertex data, but in the future we may use it for other things + * (e.g. compute). + * + * @see VertexBuffer + */ +class UTILS_PUBLIC BufferObject : public FilamentAPI { + struct BuilderDetails; + +public: + using BufferDescriptor = backend::BufferDescriptor; + using BindingType = backend::BufferObjectBinding; + + class Builder : public BuilderBase { + friend struct BuilderDetails; + public: + Builder() noexcept; + Builder(Builder const& rhs) noexcept; + Builder(Builder&& rhs) noexcept; + ~Builder() noexcept; + Builder& operator=(Builder const& rhs) noexcept; + Builder& operator=(Builder&& rhs) noexcept; + + /** + * Size of the buffer in bytes. + * @param byteCount Maximum number of bytes the BufferObject can hold. + * @return A reference to this Builder for chaining calls. + */ + Builder& size(uint32_t byteCount) noexcept; + + /** + * The binding type for this buffer object. (defaults to VERTEX) + * @param BindingType Distinguishes between SSBO, VBO, etc. For now this must be VERTEX. + * @return A reference to this Builder for chaining calls. + */ + Builder& bindingType(BindingType bindingType) noexcept; + + /** + * Creates the BufferObject and returns a pointer to it. After creation, the buffer + * object is uninitialized. Use BufferObject::setBuffer() to initialize it. + * + * @param engine Reference to the filament::Engine to associate this BufferObject with. + * + * @return pointer to the newly created object or nullptr if exceptions are disabled and + * an error occurred. + * + * @exception utils::PostConditionPanic if a runtime error occurred, such as running out of + * memory or other resources. + * @exception utils::PreConditionPanic if a parameter to a builder function was invalid. + * + * @see IndexBuffer::setBuffer + */ + BufferObject* build(Engine& engine); + private: + friend class FBufferObject; + }; + + /** + * Asynchronously copy-initializes a region of this BufferObject from the data provided. + * + * @param engine Reference to the filament::Engine associated with this BufferObject. + * @param buffer A BufferDescriptor representing the data used to initialize the BufferObject. + * @param byteOffset Offset in bytes into the BufferObject + */ + void setBuffer(Engine& engine, BufferDescriptor&& buffer, uint32_t byteOffset = 0); + + /** + * Returns the size of this BufferObject in elements. + * @return The maximum capacity of the BufferObject. + */ + size_t getByteCount() const noexcept; +}; + +} // namespace filament + +#endif // TNT_FILAMENT_BUFFEROBJECT_H diff --git a/filament/include/filament/Engine.h b/filament/include/filament/Engine.h index df494912cc..301424a96b 100644 --- a/filament/include/filament/Engine.h +++ b/filament/include/filament/Engine.h @@ -28,6 +28,7 @@ class JobSystem; namespace filament { +class BufferObject; class Camera; class ColorGrading; class DebugRegistry; @@ -390,6 +391,7 @@ public: */ Fence* createFence() noexcept; + bool destroy(const BufferObject* p); //!< Destroys a BufferObject object. bool destroy(const VertexBuffer* p); //!< Destroys an VertexBuffer object. bool destroy(const Fence* p); //!< Destroys a Fence object. bool destroy(const IndexBuffer* p); //!< Destroys an IndexBuffer object. diff --git a/filament/include/filament/IndexBuffer.h b/filament/include/filament/IndexBuffer.h index c3f5897a4b..09b479296d 100644 --- a/filament/include/filament/IndexBuffer.h +++ b/filament/include/filament/IndexBuffer.h @@ -84,7 +84,7 @@ public: /** * Creates the IndexBuffer object and returns a pointer to it. After creation, the index - * buffer is uninitialized. Use IndexBuffer::setBuffer() to initialized the IndexBuffer. + * buffer is uninitialized. Use IndexBuffer::setBuffer() to initialize the IndexBuffer. * * @param engine Reference to the filament::Engine to associate this IndexBuffer with. * diff --git a/filament/include/filament/VertexBuffer.h b/filament/include/filament/VertexBuffer.h index 70545b1c48..4cd677dad2 100644 --- a/filament/include/filament/VertexBuffer.h +++ b/filament/include/filament/VertexBuffer.h @@ -31,6 +31,7 @@ namespace filament { class FVertexBuffer; +class BufferObject; class Engine; /** @@ -86,6 +87,17 @@ public: */ Builder& vertexCount(uint32_t vertexCount) noexcept; + /** + * Allows buffers to be swapped out and shared using BufferObject. + * + * If buffer objects mode is enabled, clients must call setBufferObjectAt rather than + * setBufferAt. This allows sharing of data between VertexBuffer objects, but it may + * slightly increase the memory footprint of Filament's internal bookkeeping. + * + * @param enabled If true, enables buffer object mode. False by default. + */ + Builder& enableBufferObjects(bool enabled = true) noexcept; + /** * Sets up an attribute for this vertex buffer set. * @@ -154,6 +166,8 @@ public: /** * Asynchronously copy-initializes the specified buffer from the given buffer data. * + * Do not use this if you called enableBufferObjects() on the Builder. + * * @param engine Reference to the filament::Engine to associate this VertexBuffer with. * @param bufferIndex Index of the buffer to initialize. Must be between 0 * and Builder::bufferCount() - 1. @@ -166,6 +180,18 @@ public: void setBufferAt(Engine& engine, uint8_t bufferIndex, BufferDescriptor&& buffer, uint32_t byteOffset = 0); + /** + * Swaps in the given buffer object. + * + * To use this, you must first call enableBufferObjects() on the Builder. + * + * @param engine Reference to the filament::Engine to associate this VertexBuffer with. + * @param bufferIndex Index of the buffer to initialize. Must be between 0 + * and Builder::bufferCount() - 1. + * @param bufferObject The handle to the GPU data that will be used in this buffer slot. + */ + void setBufferObjectAt(Engine& engine, uint8_t bufferIndex, BufferObject const* bufferObject); + /** * Specifies the quaternion type for the "populateTangentQuaternions" utility. */ diff --git a/filament/src/BufferObject.cpp b/filament/src/BufferObject.cpp new file mode 100644 index 0000000000..7a7503dc8c --- /dev/null +++ b/filament/src/BufferObject.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "details/BufferObject.h" + +#include "details/Engine.h" + +#include "FilamentAPI-impl.h" + +namespace filament { + +struct BufferObject::BuilderDetails { + BindingType mBindingType = BindingType::VERTEX; + uint32_t mByteCount = 0; +}; + +using BuilderType = BufferObject; +BuilderType::Builder::Builder() noexcept = default; +BuilderType::Builder::~Builder() noexcept = default; +BuilderType::Builder::Builder(BuilderType::Builder const& rhs) noexcept = default; +BuilderType::Builder::Builder(BuilderType::Builder&& rhs) noexcept = default; +BuilderType::Builder& BuilderType::Builder::operator=(BuilderType::Builder const& rhs) noexcept = default; +BuilderType::Builder& BuilderType::Builder::operator=(BuilderType::Builder&& rhs) noexcept = default; + +BufferObject::Builder& BufferObject::Builder::size(uint32_t byteCount) noexcept { + mImpl->mByteCount = byteCount; + return *this; +} + +BufferObject::Builder& BufferObject::Builder::bindingType(BindingType bindingType) noexcept { + mImpl->mBindingType = bindingType; + return *this; +} + +BufferObject* BufferObject::Builder::build(Engine& engine) { + return upcast(engine).createBufferObject(*this); +} + +// ------------------------------------------------------------------------------------------------ + +FBufferObject::FBufferObject(FEngine& engine, const BufferObject::Builder& builder) + : mByteCount(builder->mByteCount), mBindingType(builder->mBindingType) { + FEngine::DriverApi& driver = engine.getDriverApi(); + mHandle = driver.createBufferObject(builder->mByteCount, builder->mBindingType); +} + +void FBufferObject::terminate(FEngine& engine) { + FEngine::DriverApi& driver = engine.getDriverApi(); + driver.destroyBufferObject(mHandle); +} + +void FBufferObject::setBuffer(FEngine& engine, BufferDescriptor&& buffer, uint32_t byteOffset) { + engine.getDriverApi().updateBufferObject(mHandle, std::move(buffer), byteOffset); +} + +// ------------------------------------------------------------------------------------------------ +// Trampoline calling into private implementation +// ------------------------------------------------------------------------------------------------ + +void BufferObject::setBuffer(Engine& engine, + BufferObject::BufferDescriptor&& buffer, uint32_t byteOffset) { + upcast(this)->setBuffer(upcast(engine), std::move(buffer), byteOffset); +} + +size_t BufferObject::getByteCount() const noexcept { + return upcast(this)->getByteCount(); +} + +} // namespace filament diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp index 7b3e633989..0bd5381693 100644 --- a/filament/src/Engine.cpp +++ b/filament/src/Engine.cpp @@ -20,6 +20,7 @@ #include "ResourceAllocator.h" #include "backend/DriverEnums.h" +#include "details/BufferObject.h" #include "details/DFG.h" #include "details/VertexBuffer.h" #include "details/Fence.h" @@ -318,6 +319,7 @@ void FEngine::shutdown() { // this must be done after Skyboxes and before materials destroy(mSkyboxMaterial); + cleanupResourceList(mBufferObjects); cleanupResourceList(mIndexBuffers); cleanupResourceList(mVertexBuffers); cleanupResourceList(mTextures); @@ -546,6 +548,10 @@ inline T* FEngine::create(ResourceList& list, typename T::Builder const& buil return p; } +FBufferObject* FEngine::createBufferObject(const BufferObject::Builder& builder) noexcept { + return create(mBufferObjects, builder); +} + FVertexBuffer* FEngine::createVertexBuffer(const VertexBuffer::Builder& builder) noexcept { return create(mVertexBuffers, builder); } @@ -724,6 +730,10 @@ bool FEngine::terminateAndDestroy(const T* ptr, ResourceList& list) { // ----------------------------------------------------------------------------------------------- +bool FEngine::destroy(const FBufferObject* p) { + return terminateAndDestroy(p, mBufferObjects); +} + bool FEngine::destroy(const FVertexBuffer* p) { return terminateAndDestroy(p, mVertexBuffers); } @@ -925,6 +935,10 @@ SwapChain* Engine::createSwapChain(uint32_t width, uint32_t height, uint64_t fla return upcast(this)->createSwapChain(width, height, flags); } +bool Engine::destroy(const BufferObject* p) { + return upcast(this)->destroy(upcast(p)); +} + bool Engine::destroy(const VertexBuffer* p) { return upcast(this)->destroy(upcast(p)); } diff --git a/filament/src/VertexBuffer.cpp b/filament/src/VertexBuffer.cpp index 80878cb65a..f11af61f86 100644 --- a/filament/src/VertexBuffer.cpp +++ b/filament/src/VertexBuffer.cpp @@ -16,6 +16,7 @@ #include "details/VertexBuffer.h" +#include "details/BufferObject.h" #include "details/Engine.h" #include "FilamentAPI-impl.h" @@ -36,6 +37,7 @@ struct VertexBuffer::BuilderDetails { AttributeBitset mDeclaredAttributes; uint32_t mVertexCount = 0; uint8_t mBufferCount = 0; + bool mBufferObjectsEnabled = false; }; using BuilderType = VertexBuffer; @@ -51,6 +53,11 @@ VertexBuffer::Builder& VertexBuffer::Builder::vertexCount(uint32_t vertexCount) return *this; } +VertexBuffer::Builder& VertexBuffer::Builder::enableBufferObjects(bool enabled) noexcept { + mImpl->mBufferObjectsEnabled = enabled; + return *this; +} + VertexBuffer::Builder& VertexBuffer::Builder::bufferCount(uint8_t bufferCount) noexcept { mImpl->mBufferCount = bufferCount; return *this; @@ -140,7 +147,8 @@ VertexBuffer* VertexBuffer::Builder::build(Engine& engine) { // ------------------------------------------------------------------------------------------------ FVertexBuffer::FVertexBuffer(FEngine& engine, const VertexBuffer::Builder& builder) - : mVertexCount(builder->mVertexCount), mBufferCount(builder->mBufferCount) { + : mVertexCount(builder->mVertexCount), mBufferCount(builder->mBufferCount), + mBufferObjectsEnabled(builder->mBufferObjectsEnabled) { std::copy(std::begin(builder->mAttributes), std::end(builder->mAttributes), mAttributes.begin()); mDeclaredAttributes = builder->mDeclaredAttributes; @@ -174,7 +182,8 @@ FVertexBuffer::FVertexBuffer(FEngine& engine, const VertexBuffer::Builder& build FEngine::DriverApi& driver = engine.getDriverApi(); mHandle = driver.createVertexBuffer( - mBufferCount, attributeCount, mVertexCount, attributeArray, backend::BufferUsage::STATIC); + mBufferCount, attributeCount, mVertexCount, attributeArray, + backend::BufferUsage::STATIC, mBufferObjectsEnabled); } void FVertexBuffer::terminate(FEngine& engine) { @@ -188,12 +197,25 @@ size_t FVertexBuffer::getVertexCount() const noexcept { void FVertexBuffer::setBufferAt(FEngine& engine, uint8_t bufferIndex, backend::BufferDescriptor&& buffer, uint32_t byteOffset) { + ASSERT_PRECONDITION(!mBufferObjectsEnabled, "Please use setBufferObjectAt()"); if (bufferIndex < mBufferCount) { engine.getDriverApi().updateVertexBuffer(mHandle, bufferIndex, std::move(buffer), byteOffset); } else { - ASSERT_PRECONDITION_NON_FATAL(bufferIndex < mBufferCount, - "bufferIndex must be < bufferCount"); + ASSERT_PRECONDITION(bufferIndex < mBufferCount, "bufferIndex must be < bufferCount"); + } +} + +void FVertexBuffer::setBufferObjectAt(FEngine& engine, uint8_t bufferIndex, + FBufferObject const * bufferObject) { + ASSERT_PRECONDITION(mBufferObjectsEnabled, "Please use setBufferAt()"); + ASSERT_PRECONDITION(bufferObject->getBindingType() == BufferObject::BindingType::VERTEX, + "Binding type must be VERTEX."); + if (bufferIndex < mBufferCount) { + auto hwBufferObject = bufferObject->getHwHandle(); + engine.getDriverApi().setVertexBufferObject(mHandle, bufferIndex, hwBufferObject); + } else { + ASSERT_PRECONDITION(bufferIndex < mBufferCount, "bufferIndex must be < bufferCount"); } } @@ -210,6 +232,11 @@ void VertexBuffer::setBufferAt(Engine& engine, uint8_t bufferIndex, upcast(this)->setBufferAt(upcast(engine), bufferIndex, std::move(buffer), byteOffset); } +void VertexBuffer::setBufferObjectAt(Engine& engine, uint8_t bufferIndex, + BufferObject const* bufferObject) { + upcast(this)->setBufferObjectAt(upcast(engine), bufferIndex, upcast(bufferObject)); +} + void VertexBuffer::populateTangentQuaternions(const QuatTangentContext& ctx) { auto* quats = geometry::SurfaceOrientation::Builder() .vertexCount(ctx.quatCount) diff --git a/filament/src/details/BufferObject.h b/filament/src/details/BufferObject.h new file mode 100644 index 0000000000..ef74b52a10 --- /dev/null +++ b/filament/src/details/BufferObject.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_FILAMENT_DETAILS_BUFFEROBJECT_H +#define TNT_FILAMENT_DETAILS_BUFFEROBJECT_H + +#include "upcast.h" + +#include + +#include + +#include + +namespace filament { + +class FEngine; + +class FBufferObject : public BufferObject { +public: + FBufferObject(FEngine& engine, const Builder& builder); + + // frees driver resources, object becomes invalid + void terminate(FEngine& engine); + + backend::Handle getHwHandle() const noexcept { return mHandle; } + + size_t getByteCount() const noexcept { return mByteCount; } + + void setBuffer(FEngine& engine, BufferDescriptor&& buffer, uint32_t byteOffset = 0); + + BindingType getBindingType() const noexcept { return mBindingType; } + +private: + friend class BufferObject; + backend::Handle mHandle; + uint32_t mByteCount; + BindingType mBindingType; +}; + +FILAMENT_UPCAST(BufferObject) + +} // namespace filament + +#endif // TNT_FILAMENT_DETAILS_BUFFEROBJECT_H diff --git a/filament/src/details/Engine.h b/filament/src/details/Engine.h index 568099e290..1260c036d1 100644 --- a/filament/src/details/Engine.h +++ b/filament/src/details/Engine.h @@ -26,6 +26,7 @@ #include "components/RenderableManager.h" #include "details/Allocators.h" +#include "details/BufferObject.h" #include "details/Camera.h" #include "details/DebugRegistry.h" #include "details/Fence.h" @@ -223,6 +224,7 @@ public: template T* create(ResourceList& list, typename T::Builder const& builder) noexcept; + FBufferObject* createBufferObject(const BufferObject::Builder& builder) noexcept; FVertexBuffer* createVertexBuffer(const VertexBuffer::Builder& builder) noexcept; FIndexBuffer* createIndexBuffer(const IndexBuffer::Builder& builder) noexcept; FIndirectLight* createIndirectLight(const IndirectLight::Builder& builder) noexcept; @@ -250,6 +252,7 @@ public: void destroyCameraComponent(utils::Entity entity) noexcept; + bool destroy(const FBufferObject* p); bool destroy(const FVertexBuffer* p); bool destroy(const FFence* p); bool destroy(const FIndexBuffer* p); @@ -340,6 +343,7 @@ private: FCameraManager mCameraManager; ResourceAllocator* mResourceAllocator = nullptr; + ResourceList mBufferObjects{ "BufferObject" }; ResourceList mRenderers{ "Renderer" }; ResourceList mViews{ "View" }; ResourceList mScenes{ "Scene" }; diff --git a/filament/src/details/VertexBuffer.h b/filament/src/details/VertexBuffer.h index 09992e2f4f..07b5c6aedb 100644 --- a/filament/src/details/VertexBuffer.h +++ b/filament/src/details/VertexBuffer.h @@ -32,6 +32,7 @@ namespace filament { +class FBufferObject; class FEngine; class FVertexBuffer : public VertexBuffer { @@ -53,6 +54,9 @@ public: void setBufferAt(FEngine& engine, uint8_t bufferIndex, backend::BufferDescriptor&& buffer, uint32_t byteOffset = 0); + void setBufferObjectAt(FEngine& engine, uint8_t bufferIndex, + FBufferObject const * bufferObject); + private: friend class VertexBuffer; @@ -65,6 +69,7 @@ private: AttributeBitset mDeclaredAttributes; uint32_t mVertexCount = 0; uint8_t mBufferCount = 0; + bool mBufferObjectsEnabled = false; }; FILAMENT_UPCAST(VertexBuffer) diff --git a/java/filament/CMakeLists.txt b/java/filament/CMakeLists.txt index b4cfed5c78..e39f25508b 100644 --- a/java/filament/CMakeLists.txt +++ b/java/filament/CMakeLists.txt @@ -40,6 +40,7 @@ set(COMMON_DIR ${ANDROID_DIR}/common) include_directories(${JNI_INCLUDE_DIRS} ${ANDROID_DIR}) set(JNI_SOURCE_FILES + ${FILAMENT_DIR}/src/main/cpp/BufferObject.cpp ${FILAMENT_DIR}/src/main/cpp/Camera.cpp ${FILAMENT_DIR}/src/main/cpp/Colors.cpp ${FILAMENT_DIR}/src/main/cpp/ColorGrading.cpp @@ -116,6 +117,7 @@ get_filename_component(FILAMENT_JAVA_DIR ${FILAMENT_JAVA_DIR} ABSOLUTE) set(JAVA_SOURCE_FILES ${FILAMENT_JAVA_DIR}/com/google/android/filament/Asserts.java ${FILAMENT_JAVA_DIR}/com/google/android/filament/Box.java + ${FILAMENT_JAVA_DIR}/com/google/android/filament/BufferObject.java ${FILAMENT_JAVA_DIR}/com/google/android/filament/Camera.java ${FILAMENT_JAVA_DIR}/com/google/android/filament/Colors.java ${FILAMENT_JAVA_DIR}/com/google/android/filament/ColorGrading.java diff --git a/web/filament-js/extensions.js b/web/filament-js/extensions.js index ef05f7e89e..32d6938812 100644 --- a/web/filament-js/extensions.js +++ b/web/filament-js/extensions.js @@ -306,6 +306,18 @@ Filament.loadClassExtensions = function() { this._setVignetteOptions(options); }; + /// BufferObject ::core class:: + + /// setBuffer ::method:: + /// engine ::argument:: [Engine] + /// buffer ::argument:: asset string, or Uint8Array, or [Buffer] + /// byteOffset ::argument:: non-negative integer + Filament.BufferObject.prototype.setBuffer = function(engine, buffer, byteOffset = 0) { + buffer = getBufferDescriptor(buffer); + this._setBuffer(engine, buffer, byteOffset); + buffer.delete(); + }; + /// VertexBuffer ::core class:: /// setBufferAt ::method:: diff --git a/web/filament-js/filament.d.ts b/web/filament-js/filament.d.ts index 8642bd6ad8..a3231463ff 100644 --- a/web/filament-js/filament.d.ts +++ b/web/filament-js/filament.d.ts @@ -225,6 +225,7 @@ export class VertexBuffer$Builder { public bufferCount(count: number): VertexBuffer$Builder; public attribute(attrib: VertexAttribute, bufindex: number, atype: VertexBuffer$AttributeType, offset: number, stride: number): VertexBuffer$Builder; + public enableBufferObjects(enabled: boolean): VertexBuffer$Builder; public normalized(attrib: VertexAttribute): VertexBuffer$Builder; public normalizedIf(attrib: VertexAttribute, normalized: boolean): VertexBuffer$Builder; public build(engine: Engine): VertexBuffer; @@ -236,6 +237,12 @@ export class IndexBuffer$Builder { public build(engine: Engine): IndexBuffer; } +export class BufferObject$Builder { + public size(byteCount: number): BufferObject$Builder; + public bindingType(type: BufferObject$BindingType): BufferObject$Builder; + public build(engine: Engine): BufferObject; +} + export class RenderableManager$Builder { public geometry(slot: number, ptype: RenderableManager$PrimitiveType, vb: VertexBuffer, ib: IndexBuffer): RenderableManager$Builder; @@ -364,6 +371,12 @@ export class VertexBuffer { public static Builder(): VertexBuffer$Builder; public setBufferAt(engine: Engine, bufindex: number, f32array: BufferReference, byteOffset?: number): void; + public setBufferObjectAt(engine: Engine, bufindex: number, bo: BufferObject): void; +} + +export class BufferObject { + public static Builder(): BufferObject$Builder; + public setBuffer(engine: Engine, data: BufferReference, byteOffset?: number): void; } export class IndexBuffer { @@ -719,6 +732,10 @@ export enum IndexBuffer$IndexType { UINT, } +export enum BufferObject$BindingType { + VERTEX_BINDING, +} + export enum LightManager$Type { SUN, DIRECTIONAL, @@ -955,6 +972,10 @@ export enum VertexAttribute { MORPH_TANGENTS_3 = CUSTOM7, } +export enum BufferObject$BindingType { + VERTEX, +} + export enum VertexBuffer$AttributeType { BYTE, BYTE2, diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index 5ea32c448d..33a7c27cc9 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -34,6 +34,7 @@ #include +#include #include #include #include @@ -117,6 +118,7 @@ namespace emscripten { namespace internal { BIND(Animator) BIND(AssetLoader) + BIND(BufferObject) BIND(Camera) BIND(ColorGrading) BIND(Engine) @@ -204,6 +206,7 @@ using SkyBuilder = Skybox::Builder; using SurfaceBuilder = SurfaceOrientation::Builder; using TexBuilder = Texture::Builder; using VertexBuilder = VertexBuffer::Builder; +using BufferBuilder = BufferObject::Builder; // We avoid directly exposing backend::BufferDescriptor because embind does not support move // semantics and void* doesn't make sense to JavaScript anyway. This little wrapper class is exposed @@ -1162,6 +1165,25 @@ class_("LightManager") class_("LightManager$Instance"); /// delete ::method:: Frees an instance obtained via `getInstance` +class_("BufferObject$Builder") + .function("_build", EMBIND_LAMBDA(BufferObject*, (BufferBuilder* builder, Engine* engine), { + return builder->build(*engine); + }), allow_raw_pointers()) + .BUILDER_FUNCTION("bindingType", BufferBuilder, (BufferBuilder* builder, + BufferObject::BindingType bt), { + return &builder->bindingType(bt); }) + .BUILDER_FUNCTION("size", BufferBuilder, (BufferBuilder* builder, int byteCount), { + return &builder->size(byteCount); }); + +/// BufferObject ::core class:: Represents a single GPU buffer. +class_("BufferObject") + .class_function("Builder", (BufferBuilder (*)()) [] { return BufferBuilder(); }) + .function("getByteCount", &BufferObject::getByteCount) + .function("_setBuffer", EMBIND_LAMBDA(void, (BufferObject* self, + Engine* engine, BufferDescriptor bd, uint32_t byteOffset), { + self->setBuffer(*engine, std::move(*bd.bd), byteOffset); + }), allow_raw_pointers()); + class_("VertexBuffer$Builder") .function("_build", EMBIND_LAMBDA(VertexBuffer*, (VertexBuilder* builder, Engine* engine), { return builder->build(*engine); @@ -1175,6 +1197,8 @@ class_("VertexBuffer$Builder") return &builder->attribute(attr, bufferIndex, attrType, byteOffset, byteStride); }) .BUILDER_FUNCTION("vertexCount", VertexBuilder, (VertexBuilder* builder, int count), { return &builder->vertexCount(count); }) + .BUILDER_FUNCTION("enableBufferObjects", VertexBuilder, (VertexBuilder* builder, bool enable), { + return &builder->enableBufferObjects(enable); }) .BUILDER_FUNCTION("normalized", VertexBuilder, (VertexBuilder* builder, VertexAttribute attrib), { return &builder->normalized(attrib); }) @@ -1187,6 +1211,7 @@ class_("VertexBuffer$Builder") /// VertexBuffer ::core class:: Bundle of buffers and associated vertex attributes. class_("VertexBuffer") .class_function("Builder", (VertexBuilder (*)()) [] { return VertexBuilder(); }) + .function("setBufferObjectAt", &VertexBuffer::setBufferObjectAt, allow_raw_pointers()) .function("_setBufferAt", EMBIND_LAMBDA(void, (VertexBuffer* self, Engine* engine, uint8_t bufferIndex, BufferDescriptor vbd, uint32_t byteOffset), { self->setBufferAt(*engine, bufferIndex, std::move(*vbd.bd), byteOffset); diff --git a/web/filament-js/jsenums.cpp b/web/filament-js/jsenums.cpp index 9e63c23213..226b60b42c 100644 --- a/web/filament-js/jsenums.cpp +++ b/web/filament-js/jsenums.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -69,6 +70,9 @@ enum_("VertexAttribute") .value("MORPH_TANGENTS_2", MORPH_TANGENTS_2) .value("MORPH_TANGENTS_3", MORPH_TANGENTS_3); +enum_("BufferObject$BindingType") + .value("VERTEX_BINDING", BufferObject::BindingType::VERTEX); + enum_("VertexBuffer$AttributeType") .value("BYTE", VertexBuffer::AttributeType::BYTE) .value("BYTE2", VertexBuffer::AttributeType::BYTE2) From 0969cec45d15db272121a072ef740631c0153f7d Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Wed, 31 Mar 2021 12:19:00 -0700 Subject: [PATCH 19/39] BufferObject API: add Vulkan support. --- filament/backend/src/vulkan/VulkanDriver.cpp | 52 ++++++++++++++---- filament/backend/src/vulkan/VulkanHandles.cpp | 54 +------------------ filament/backend/src/vulkan/VulkanHandles.h | 16 +++--- 3 files changed, 52 insertions(+), 70 deletions(-) diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 2662b5250d..b12846f489 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -480,8 +480,8 @@ void VulkanDriver::destroyIndexBuffer(Handle ibh) { void VulkanDriver::createBufferObjectR(Handle boh, uint32_t byteCount, BufferObjectBinding bindingType) { - // TODO: pass constructor args - auto bufferObject = construct_handle(mHandleMap, boh); + auto bufferObject = construct_handle(mHandleMap, boh, mContext, mStagePool, + mDisposer, byteCount); mDisposer.createDisposable(bufferObject, [this, boh] () { destruct_handle(mHandleMap, boh); }); @@ -520,7 +520,7 @@ void VulkanDriver::importTextureR(Handle th, intptr_t id, SamplerType target, uint8_t levels, TextureFormat format, uint8_t samples, uint32_t w, uint32_t h, uint32_t depth, TextureUsage usage) { - // not support in this backend + // not supported in this backend } void VulkanDriver::destroyTexture(Handle th) { @@ -873,7 +873,9 @@ void VulkanDriver::updateVertexBuffer(Handle vbh, size_t index, void VulkanDriver::setVertexBufferObject(Handle vbh, size_t index, Handle boh) { - // TODO + auto& vb = *handle_cast(mHandleMap, vbh); + auto& bo = *handle_cast(mHandleMap, boh); + vb.buffers[index] = bo.buffer; } void VulkanDriver::updateIndexBuffer(Handle ibh, BufferDescriptor&& p, @@ -1647,13 +1649,46 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle r mContext.rasterState.colorTargetCount = rt->getColorTargetCount(mContext.currentRenderPass); - VulkanBinder::ProgramBundle shaderHandles = program->bundle; + // Declare fixed-size arrays that get passed to the binder and to vkCmdBindVertexBuffers. + VulkanBinder::VertexArray varray = {}; + VkBuffer buffers[backend::MAX_VERTEX_ATTRIBUTE_COUNT] = {}; + VkDeviceSize offsets[backend::MAX_VERTEX_ATTRIBUTE_COUNT] = {}; + + // For each attribute, append to each of the above lists. + const uint32_t bufferCount = prim.vertexBuffer->attributes.size(); + for (uint32_t attribIndex = 0; attribIndex < bufferCount; attribIndex++) { + Attribute attrib = prim.vertexBuffer->attributes[attribIndex]; + VkFormat vkformat = getVkFormat(attrib.type, attrib.flags & Attribute::FLAG_NORMALIZED); + + // HACK: Re-use the positions buffer as a dummy buffer for disabled attributes. Filament's + // vertex shaders declare all attributes as either vec4 or uvec4 (the latter for bone + // indices), and positions are always at least 32 bits per element. Therefore we can assign + // a dummy type of either R8G8B8A8_UINT or R8G8B8A8_SNORM, depending on whether the shader + // expects to receive floats or ints. + if (attrib.buffer == Attribute::BUFFER_UNUSED) { + const bool isInteger = attrib.flags & Attribute::FLAG_INTEGER_TARGET; + vkformat = isInteger ? VK_FORMAT_R8G8B8A8_UINT : VK_FORMAT_R8G8B8A8_SNORM; + attrib = prim.vertexBuffer->attributes[0]; + } + + buffers[attribIndex] = prim.vertexBuffer->buffers[attrib.buffer]->getGpuBuffer(); + offsets[attribIndex] = attrib.offset; + varray.attributes[attribIndex] = { + .location = attribIndex, // matches the GLSL layout specifier + .binding = attribIndex, // matches the position within vkCmdBindVertexBuffers + .format = vkformat, + }; + varray.buffers[attribIndex] = { + .binding = attribIndex, + .stride = attrib.stride, + }; + } // Push state changes to the VulkanBinder instance. This is fast and does not make VK calls. - mBinder.bindProgramBundle(shaderHandles); + mBinder.bindProgramBundle(program->bundle); mBinder.bindRasterState(mContext.rasterState); mBinder.bindPrimitiveTopology(prim.primitiveTopology); - mBinder.bindVertexArray(prim.varray); + mBinder.bindVertexArray(varray); // Query the program for the mapping from (SamplerGroupBinding,Offset) to (SamplerBinding), // where "SamplerBinding" is the integer in the GLSL, and SamplerGroupBinding is the abstract @@ -1744,8 +1779,7 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle r // Next bind the vertex buffers and index buffer. One potential performance improvement is to // avoid rebinding these if they are already bound, but since we do not (yet) support subranges // it would be rare for a client to make consecutive draw calls with the same render primitive. - vkCmdBindVertexBuffers(cmdbuffer, 0, (uint32_t) prim.buffers.size(), - prim.buffers.data(), prim.offsets.data()); + vkCmdBindVertexBuffers(cmdbuffer, 0, bufferCount, buffers, offsets); vkCmdBindIndexBuffer(cmdbuffer, prim.indexBuffer->buffer->getGpuBuffer(), 0, prim.indexBuffer->indexType); diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 28d623df5f..e266ce1c47 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -410,11 +410,11 @@ VulkanVertexBuffer::VulkanVertexBuffer(VulkanContext& context, VulkanStagePool& uint32_t size = 0; for (auto const& item : attributes) { if (item.buffer == bufferIndex) { - uint32_t end = item.offset + elementCount * item.stride; + uint32_t end = item.offset + elementCount * item.stride; size = std::max(size, end); } } - buffers.emplace_back(new VulkanBuffer(context, stagePool, disposer, this, + buffers.push_back(std::make_shared(context, stagePool, disposer, this, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, size)); } } @@ -868,56 +868,6 @@ void VulkanRenderPrimitive::setBuffers(VulkanVertexBuffer* vertexBuffer, VulkanIndexBuffer* indexBuffer) { this->vertexBuffer = vertexBuffer; this->indexBuffer = indexBuffer; - const size_t nattrs = vertexBuffer->attributes.size(); - - // These vectors are passed to vkCmdBindVertexBuffers at every draw call. This binds the - // VkBuffer objects, but does not describe the structure of a vertex. - buffers.clear(); - buffers.reserve(nattrs); - offsets.clear(); - offsets.reserve(nattrs); - - // The following fixed-size arrays are consumed by VulkanBinder. They describe the vertex - // structure, but do not specify the actual buffer objects to bind. - memset(varray.attributes, 0, sizeof(varray.attributes)); - memset(varray.buffers, 0, sizeof(varray.buffers)); - - // For each enabled attribute, append to each of the above lists. Note that a single VkBuffer - // handle might be appended more than once, which is perfectly fine. - uint32_t bufferIndex = 0; - for (uint32_t attribIndex = 0; attribIndex < nattrs; attribIndex++) { - Attribute attrib = vertexBuffer->attributes[attribIndex]; - VkFormat vkformat = getVkFormat(attrib.type, attrib.flags & Attribute::FLAG_NORMALIZED); - - // HACK: Re-use the positions buffer as a dummy buffer for disabled attributes. - // We know that position exists (see earlier assert) - if (attrib.buffer == Attribute::BUFFER_UNUSED) { - - // HACK: Presently, Filament's vertex shaders declare all attributes as either vec4 or - // uvec4 (the latter is for bone indices), and positions are always at least 32 bits per - // element. Therefore we can assign a dummy type of either R8G8B8A8_UINT or - // R8G8B8A8_SNORM, depending on whether the shader expects to receive floats or ints. - const bool isInteger = attrib.flags & Attribute::FLAG_INTEGER_TARGET; - vkformat = isInteger ? VK_FORMAT_R8G8B8A8_UINT : VK_FORMAT_R8G8B8A8_SNORM; - - attrib = vertexBuffer->attributes[0]; - } - - buffers.push_back(vertexBuffer->buffers[attrib.buffer]->getGpuBuffer()); - offsets.push_back(attrib.offset); - varray.attributes[bufferIndex] = { - .location = attribIndex, // matches the GLSL layout specifier - .binding = bufferIndex, // matches the position within vkCmdBindVertexBuffers - .format = vkformat, - .offset = 0 - }; - varray.buffers[bufferIndex] = { - .binding = bufferIndex, - .stride = attrib.stride, - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX - }; - bufferIndex++; - } } VulkanTimerQuery::VulkanTimerQuery(VulkanContext& context) : mContext(context) { diff --git a/filament/backend/src/vulkan/VulkanHandles.h b/filament/backend/src/vulkan/VulkanHandles.h index d8f1e251ad..e1c3509e5a 100644 --- a/filament/backend/src/vulkan/VulkanHandles.h +++ b/filament/backend/src/vulkan/VulkanHandles.h @@ -84,7 +84,7 @@ struct VulkanVertexBuffer : public HwVertexBuffer { VulkanVertexBuffer(VulkanContext& context, VulkanStagePool& stagePool, VulkanDisposer& disposer, uint8_t bufferCount, uint8_t attributeCount, uint32_t elementCount, AttributeArray const& attributes, bool bufferObjectsEnabled); - std::vector> buffers; + std::vector> buffers; }; struct VulkanIndexBuffer : public HwIndexBuffer { @@ -92,13 +92,17 @@ struct VulkanIndexBuffer : public HwIndexBuffer { uint8_t elementSize, uint32_t indexCount) : HwIndexBuffer(elementSize, indexCount), indexType(elementSize == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32), buffer(new VulkanBuffer(context, stagePool, disposer, this, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT, elementSize * indexCount)) {} + VK_BUFFER_USAGE_INDEX_BUFFER_BIT, elementSize * indexCount)) {} const VkIndexType indexType; const std::unique_ptr buffer; }; struct VulkanBufferObject : public HwBufferObject { - const std::unique_ptr buffer; + VulkanBufferObject(VulkanContext& context, VulkanStagePool& stagePool, VulkanDisposer& disposer, + uint32_t byteCount) : + buffer(new VulkanBuffer(context, stagePool, disposer, this, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, byteCount)) {} + const std::shared_ptr buffer; }; struct VulkanUniformBuffer : public HwUniformBuffer { @@ -186,12 +190,6 @@ struct VulkanRenderPrimitive : public HwRenderPrimitive { VulkanVertexBuffer* vertexBuffer = nullptr; VulkanIndexBuffer* indexBuffer = nullptr; VkPrimitiveTopology primitiveTopology; - // The "varray" field describes the structure of the vertex and gets passed to VulkanBinder, - // which in turn passes it to vkCreateGraphicsPipelines. The "buffers" and "offsets" vectors are - // passed to vkCmdBindVertexBuffers at draw call time. - VulkanBinder::VertexArray varray; - std::vector buffers; - std::vector offsets; }; struct VulkanFence : public HwFence { From 53f5fd91b7219e0047c3355ce1437cba3280f8d1 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Thu, 1 Apr 2021 12:49:40 -0700 Subject: [PATCH 20/39] Add print operator for BufferObjectBinding. --- filament/backend/src/CommandStream.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/filament/backend/src/CommandStream.cpp b/filament/backend/src/CommandStream.cpp index 9b11772196..f701b733b4 100644 --- a/filament/backend/src/CommandStream.cpp +++ b/filament/backend/src/CommandStream.cpp @@ -606,6 +606,13 @@ io::ostream& operator<<(io::ostream& out, RenderPassParams const& params) { return out; } +io::ostream& operator<<(io::ostream& out, BufferObjectBinding wrap) { + switch (wrap) { + CASE(BufferObjectBinding, VERTEX) + } + return out; +} + #undef CASE #endif // !NDEBUG From deee5d2815726adc4710ef9808bf35ce73d189dd Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Thu, 1 Apr 2021 18:00:49 -0700 Subject: [PATCH 21/39] Update the remote web page. --- docs/remote/filament.js | 14 +++++++++++++- docs/remote/filament.wasm | Bin 3839296 -> 3844375 bytes 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/remote/filament.js b/docs/remote/filament.js index 34411860de..23adc9dcbb 100644 --- a/docs/remote/filament.js +++ b/docs/remote/filament.js @@ -6,7 +6,7 @@ var Filament = (function() { function(Filament) { Filament = Filament || {}; -var Module=typeof Filament!=="undefined"?Filament:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[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(Module["locateFile"]){return Module["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{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(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);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}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"){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(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;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>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=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=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"):undefined;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 str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>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===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=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=55296&&codeUnit<=57343)++i;len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}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 updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;__ATINIT__.push({func:function(){___wasm_call_ctors()}});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;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;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 addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}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"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}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://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="filament.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){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(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["Zg"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["_g"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var tempDouble;var tempI64;var ASM_CONSTS={10272:function(){const handle=GL.registerContext(Filament.glContext,Filament.glOptions);GL.makeContextCurrent(handle)}};function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){var alignedSize=alignMemory(size,16384);var ptr=_malloc(alignedSize);while(size=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){FS.forceLoadFile(node);var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=varargs?SYSCALLS.get():0;var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var tupleRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}return Module["dynCall_"+sig].call(null,ptr)}function dynCall(sig,ptr,args){if(sig.indexOf("j")!=-1){return dynCallLegacy(sig,ptr,args)}return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){assert(sig.indexOf("j")>=0,"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i>2)+i])}return array}function __embind_register_class_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,fn){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.constructor;if(undefined===proto[methodName]){unboundTypesHandler.argCount=argCount-1;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-1]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));var func=craftInvokerFunction(humanName,invokerArgsArray,null,rawInvoker,fn);if(undefined===proto[methodName].overloadTable){func.argCount=argCount-1;proto[methodName]=func}else{proto[methodName].overloadTable[argCount-1]=func}return[]});return[]})}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>1])};case 2:return function(pointer){var heap=signed?HEAP32:HEAPU32;return this["fromWireType"](heap[pointer>>2])};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_enum(rawType,name,size,isSigned){var shift=getShiftFromSize(size);name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":function(destructors,c){return c.value},"argPackAdvance":8,"readValueFromPointer":enumReadValueFromPointer(name,shift,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __embind_register_enum_value(rawEnumType,name,enumValue){var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(enumType.name+"_"+name,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_array(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){tupleRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),elements:[]}}function __embind_register_value_array_element(rawTupleType,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){tupleRegistrations[rawTupleType].elements.push({getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireHandle(handle){if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value}function __emval_as(handle,returnType,destructorsRef){handle=requireHandle(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=__emval_register(destructors);HEAP32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}function __emval_get_property(handle,key){handle=requireHandle(handle);key=requireHandle(key);return __emval_register(handle[key])}function __emval_incref(handle){if(handle>4){emval_handle_array[handle].refcount+=1}}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function __emval_take_value(type,argv){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](argv);return __emval_register(v)}function _abort(){abort()}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else if(typeof dateNow!=="undefined"){_emscripten_get_now=dateNow}else _emscripten_get_now=function(){return performance.now()};var _emscripten_get_now_is_monotonic=true;function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if((clk_id===1||clk_id===4)&&_emscripten_get_now_is_monotonic){now=_emscripten_get_now()}else{setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}function __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(ctx){return!!(ctx.dibvbi=ctx.getExtension("WEBGL_draw_instanced_base_vertex_base_instance"))}function __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(ctx){return!!(ctx.mdibvbi=ctx.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance"))}function __webgl_enable_WEBGL_multi_draw(ctx){return!!(ctx.multiDrawWebgl=ctx.getExtension("WEBGL_multi_draw"))}var GL={counter:1,buffers:[],mappedBuffers:{},programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},timerQueriesEXT:[],queries:[],samplers:[],transformFeedbacks:[],syncs:[],byteSizeByTypeRoot:5120,byteSizeByType:[1,1,2,2,4,4,4,2,3,4,8],programInfos:{},stringCache:{},stringiCache:{},unpackAlignment:4,recordError:function recordError(errorCode){if(!GL.lastError){GL.lastError=errorCode}},getNewId:function(table){var ret=GL.counter++;for(var i=table.length;i>1;var quadIndexes=new Uint16Array(numIndexes);var i=0,v=0;while(1){quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+1;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v+3;if(i>=numIndexes)break;v+=4}context.GLctx.bufferData(34963,quadIndexes,35044);context.GLctx.bindBuffer(34963,null)}},getTempVertexBuffer:function getTempVertexBuffer(sizeBytes){var idx=GL.log2ceilLookup(sizeBytes);var ringbuffer=GL.currentContext.tempVertexBuffers1[idx];var nextFreeBufferIndex=GL.currentContext.tempVertexBufferCounters1[idx];GL.currentContext.tempVertexBufferCounters1[idx]=GL.currentContext.tempVertexBufferCounters1[idx]+1&GL.numTempVertexBuffersPerSize-1;var vbo=ringbuffer[nextFreeBufferIndex];if(vbo){return vbo}var prevVBO=GLctx.getParameter(34964);ringbuffer[nextFreeBufferIndex]=GLctx.createBuffer();GLctx.bindBuffer(34962,ringbuffer[nextFreeBufferIndex]);GLctx.bufferData(34962,1<>2]:-1;source+=UTF8ToString(HEAP32[string+i*4>>2],len<0?undefined:len)}return source},calcBufLength:function calcBufLength(size,type,stride,count){if(stride>0){return count*stride}var typeSize=GL.byteSizeByType[type-GL.byteSizeByTypeRoot];return size*typeSize*count},usedTempBuffers:[],preDrawHandleClientVertexAttribBindings:function preDrawHandleClientVertexAttribBindings(count){GL.resetBufferBinding=false;for(var i=0;i>2)}function _emscripten_glClearBufferiv(buffer,drawbuffer,value){GLctx["clearBufferiv"](buffer,drawbuffer,HEAP32,value>>2)}function _emscripten_glClearBufferuiv(buffer,drawbuffer,value){GLctx["clearBufferuiv"](buffer,drawbuffer,HEAPU32,value>>2)}function _emscripten_glClearColor(x0,x1,x2,x3){GLctx["clearColor"](x0,x1,x2,x3)}function _emscripten_glClearDepthf(x0){GLctx["clearDepth"](x0)}function _emscripten_glClearStencil(x0){GLctx["clearStencil"](x0)}function convertI32PairToI53(lo,hi){return(lo>>>0)+hi*4294967296}function _emscripten_glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _emscripten_glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _emscripten_glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _emscripten_glCompressedTexImage2D(target,level,internalFormat,width,height,border,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,imageSize,data)}else{GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,HEAPU8,data,imageSize)}return}GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexImage3D(target,level,internalFormat,width,height,depth,border,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexImage3D"](target,level,internalFormat,width,height,depth,border,imageSize,data)}else{GLctx["compressedTexImage3D"](target,level,internalFormat,width,height,depth,border,HEAPU8,data,imageSize)}}function _emscripten_glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,imageSize,data)}else{GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,HEAPU8,data,imageSize)}return}GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data)}else{GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,HEAPU8,data,imageSize)}}function _emscripten_glCopyBufferSubData(x0,x1,x2,x3,x4){GLctx["copyBufferSubData"](x0,x1,x2,x3,x4)}function _emscripten_glCopyTexImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexSubImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage3D(x0,x1,x2,x3,x4,x5,x6,x7,x8){GLctx["copyTexSubImage3D"](x0,x1,x2,x3,x4,x5,x6,x7,x8)}function _emscripten_glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _emscripten_glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _emscripten_glCullFace(x0){GLctx["cullFace"](x0)}function _emscripten_glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _emscripten_glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _emscripten_glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _emscripten_glDeleteQueries(n,ids){for(var i=0;i>2];var query=GL.queries[id];if(!query)continue;GLctx["deleteQuery"](query);GL.queries[id]=null}}function _emscripten_glDeleteQueriesEXT(n,ids){for(var i=0;i>2];var query=GL.timerQueriesEXT[id];if(!query)continue;GLctx.disjointTimerQueryExt["deleteQueryEXT"](query);GL.timerQueriesEXT[id]=null}}function _emscripten_glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _emscripten_glDeleteSamplers(n,samplers){for(var i=0;i>2];var sampler=GL.samplers[id];if(!sampler)continue;GLctx["deleteSampler"](sampler);sampler.name=0;GL.samplers[id]=null}}function _emscripten_glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _emscripten_glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _emscripten_glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _emscripten_glDeleteTransformFeedbacks(n,ids){for(var i=0;i>2];var transformFeedback=GL.transformFeedbacks[id];if(!transformFeedback)continue;GLctx["deleteTransformFeedback"](transformFeedback);transformFeedback.name=0;GL.transformFeedbacks[id]=null}}function _emscripten_glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDeleteVertexArraysOES(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDepthFunc(x0){GLctx["depthFunc"](x0)}function _emscripten_glDepthMask(flag){GLctx.depthMask(!!flag)}function _emscripten_glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _emscripten_glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _emscripten_glDisable(x0){GLctx["disable"](x0)}function _emscripten_glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _emscripten_glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _emscripten_glDrawArraysInstanced(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedANGLE(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedARB(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedEXT(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedNV(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}var tempFixedLengthArray=[];function _emscripten_glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawBuffersEXT(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawBuffersWEBGL(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawElements(mode,count,type,indices){var buf;if(!GLctx.currentElementArrayBufferBinding){var size=GL.calcBufLength(1,type,0,count);buf=GL.getTempIndexBuffer(size);GLctx.bindBuffer(34963,buf);GLctx.bufferSubData(34963,0,HEAPU8.subarray(indices,indices+size));indices=0}GL.preDrawHandleClientVertexAttribBindings(count);GLctx.drawElements(mode,count,type,indices);GL.postDrawHandleClientVertexAttribBindings(count);if(!GLctx.currentElementArrayBufferBinding){GLctx.bindBuffer(34963,null)}}function _emscripten_glDrawElementsInstanced(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedANGLE(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedARB(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedEXT(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedNV(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _glDrawElements(mode,count,type,indices){var buf;if(!GLctx.currentElementArrayBufferBinding){var size=GL.calcBufLength(1,type,0,count);buf=GL.getTempIndexBuffer(size);GLctx.bindBuffer(34963,buf);GLctx.bufferSubData(34963,0,HEAPU8.subarray(indices,indices+size));indices=0}GL.preDrawHandleClientVertexAttribBindings(count);GLctx.drawElements(mode,count,type,indices);GL.postDrawHandleClientVertexAttribBindings(count);if(!GLctx.currentElementArrayBufferBinding){GLctx.bindBuffer(34963,null)}}function _emscripten_glDrawRangeElements(mode,start,end,count,type,indices){_glDrawElements(mode,count,type,indices)}function _emscripten_glEnable(x0){GLctx["enable"](x0)}function _emscripten_glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _emscripten_glEndQuery(x0){GLctx["endQuery"](x0)}function _emscripten_glEndQueryEXT(target){GLctx.disjointTimerQueryExt["endQueryEXT"](target)}function _emscripten_glEndTransformFeedback(){GLctx["endTransformFeedback"]()}function _emscripten_glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _emscripten_glFinish(){GLctx["finish"]()}function _emscripten_glFlush(){GLctx["flush"]()}function emscriptenWebGLGetBufferBinding(target){switch(target){case 34962:target=34964;break;case 34963:target=34965;break;case 35051:target=35053;break;case 35052:target=35055;break;case 35982:target=35983;break;case 36662:target=36662;break;case 36663:target=36663;break;case 35345:target=35368;break}var buffer=GLctx.getParameter(target);if(buffer)return buffer.name|0;else return 0}function emscriptenWebGLValidateMapBufferTarget(target){switch(target){case 34962:case 34963:case 36662:case 36663:case 35051:case 35052:case 35882:case 35982:case 35345:return true;default:return false}}function _emscripten_glFlushMappedBufferRange(target,offset,length){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glFlushMappedBufferRange");return}var mapping=GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glFlushMappedBufferRange");return}if(!(mapping.access&16)){GL.recordError(1282);err("buffer was not mapped with GL_MAP_FLUSH_EXPLICIT_BIT in glFlushMappedBufferRange");return}if(offset<0||length<0||offset+length>mapping.length){GL.recordError(1281);err("invalid range in glFlushMappedBufferRange");return}GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem+offset,mapping.mem+offset+length))}function _emscripten_glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _emscripten_glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _emscripten_glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function _emscripten_glFrontFace(x0){GLctx["frontFace"](x0)}function __glGenObject(n,buffers,createFunction,objectTable){for(var i=0;i>2]=id}}function _emscripten_glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _emscripten_glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _emscripten_glGenQueries(n,ids){__glGenObject(n,ids,"createQuery",GL.queries)}function _emscripten_glGenQueriesEXT(n,ids){for(var i=0;i>2]=0;return}var id=GL.getNewId(GL.timerQueriesEXT);query.name=id;GL.timerQueriesEXT[id]=query;HEAP32[ids+i*4>>2]=id}}function _emscripten_glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _emscripten_glGenSamplers(n,samplers){__glGenObject(n,samplers,"createSampler",GL.samplers)}function _emscripten_glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _emscripten_glGenTransformFeedbacks(n,ids){__glGenObject(n,ids,"createTransformFeedback",GL.transformFeedbacks)}function _emscripten_glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenVertexArraysOES(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function __glGetActiveAttribOrUniform(funcName,program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx[funcName](program,index);if(info){var numBytesWrittenExclNull=name&&stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull;if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}}function _emscripten_glGetActiveAttrib(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveAttrib",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniform(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveUniform",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniformBlockName(program,uniformBlockIndex,bufSize,length,uniformBlockName){program=GL.programs[program];var result=GLctx["getActiveUniformBlockName"](program,uniformBlockIndex);if(!result)return;if(uniformBlockName&&bufSize>0){var numBytesWrittenExclNull=stringToUTF8(result,uniformBlockName,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull}else{if(length)HEAP32[length>>2]=0}}function _emscripten_glGetActiveUniformBlockiv(program,uniformBlockIndex,pname,params){if(!params){GL.recordError(1281);return}program=GL.programs[program];switch(pname){case 35393:var name=GLctx["getActiveUniformBlockName"](program,uniformBlockIndex);HEAP32[params>>2]=name.length+1;return;default:var result=GLctx["getActiveUniformBlockParameter"](program,uniformBlockIndex,pname);if(!result)return;if(typeof result=="number"){HEAP32[params>>2]=result}else{for(var i=0;i>2]=result[i]}}}}function _emscripten_glGetActiveUniformsiv(program,uniformCount,uniformIndices,pname,params){if(!params){GL.recordError(1281);return}if(uniformCount>0&&uniformIndices==0){GL.recordError(1281);return}program=GL.programs[program];var ids=[];for(var i=0;i>2])}var result=GLctx["getActiveUniforms"](program,ids,pname);if(!result)return;var len=result.length;for(var i=0;i>2]=result[i]}}function _emscripten_glGetAttachedShaders(program,maxCount,count,shaders){var result=GLctx.getAttachedShaders(GL.programs[program]);var len=result.length;if(len>maxCount){len=maxCount}HEAP32[count>>2]=len;for(var i=0;i>2]=id}}function _emscripten_glGetAttribLocation(program,name){return GLctx.getAttribLocation(GL.programs[program],UTF8ToString(name))}function writeI53ToI64(ptr,num){HEAPU32[ptr>>2]=num;HEAPU32[ptr+4>>2]=(num-HEAPU32[ptr>>2])/4294967296}function emscriptenWebGLGet(name_,p,type){if(!p){GL.recordError(1281);return}var ret=undefined;switch(name_){case 36346:ret=1;break;case 36344:if(type!=0&&type!=1){GL.recordError(1280)}return;case 34814:case 36345:ret=0;break;case 34466:var formats=GLctx.getParameter(34467);ret=formats?formats.length:0;break;case 33309:if(GL.currentContext.version<2){GL.recordError(1282);return}var exts=GLctx.getSupportedExtensions()||[];ret=2*exts.length;break;case 33307:case 33308:if(GL.currentContext.version<2){GL.recordError(1280);return}ret=name_==33307?3:0;break}if(ret===undefined){var result=GLctx.getParameter(name_);switch(typeof result){case"number":ret=result;break;case"boolean":ret=result?1:0;break;case"string":GL.recordError(1280);return;case"object":if(result===null){switch(name_){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:{ret=0;break}default:{GL.recordError(1280);return}}}else if(result instanceof Float32Array||result instanceof Uint32Array||result instanceof Int32Array||result instanceof Array){for(var i=0;i>2]=result[i];break;case 2:HEAPF32[p+i*4>>2]=result[i];break;case 4:HEAP8[p+i>>0]=result[i]?1:0;break}}return}else{try{ret=result.name|0}catch(e){GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Unknown object returned from WebGL getParameter("+name_+")! (error: "+e+")");return}}break;default:GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Native code calling glGet"+type+"v("+name_+") and it returns "+result+" of type "+typeof result+"!");return}}switch(type){case 1:writeI53ToI64(p,ret);break;case 0:HEAP32[p>>2]=ret;break;case 2:HEAPF32[p>>2]=ret;break;case 4:HEAP8[p>>0]=ret?1:0;break}}function _emscripten_glGetBooleanv(name_,p){emscriptenWebGLGet(name_,p,4)}function _emscripten_glGetBufferParameteri64v(target,value,data){if(!data){GL.recordError(1281);return}writeI53ToI64(data,GLctx.getBufferParameter(target,value))}function _emscripten_glGetBufferParameteriv(target,value,data){if(!data){GL.recordError(1281);return}HEAP32[data>>2]=GLctx.getBufferParameter(target,value)}function _emscripten_glGetBufferPointerv(target,pname,params){if(pname==35005){var ptr=0;var mappedBuffer=GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)];if(mappedBuffer){ptr=mappedBuffer.mem}HEAP32[params>>2]=ptr}else{GL.recordError(1280);err("GL_INVALID_ENUM in glGetBufferPointerv")}}function _emscripten_glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _emscripten_glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _emscripten_glGetFragDataLocation(program,name){return GLctx["getFragDataLocation"](GL.programs[program],UTF8ToString(name))}function _emscripten_glGetFramebufferAttachmentParameteriv(target,attachment,pname,params){var result=GLctx.getFramebufferAttachmentParameter(target,attachment,pname);if(result instanceof WebGLRenderbuffer||result instanceof WebGLTexture){result=result.name|0}HEAP32[params>>2]=result}function emscriptenWebGLGetIndexed(target,index,data,type){if(!data){GL.recordError(1281);return}var result=GLctx["getIndexedParameter"](target,index);var ret;switch(typeof result){case"boolean":ret=result?1:0;break;case"number":ret=result;break;case"object":if(result===null){switch(target){case 35983:case 35368:ret=0;break;default:{GL.recordError(1280);return}}}else if(result instanceof WebGLBuffer){ret=result.name|0}else{GL.recordError(1280);return}break;default:GL.recordError(1280);return}switch(type){case 1:writeI53ToI64(data,ret);break;case 0:HEAP32[data>>2]=ret;break;case 2:HEAPF32[data>>2]=ret;break;case 4:HEAP8[data>>0]=ret?1:0;break;default:throw"internal emscriptenWebGLGetIndexed() error, bad type: "+type}}function _emscripten_glGetInteger64i_v(target,index,data){emscriptenWebGLGetIndexed(target,index,data,1)}function _emscripten_glGetInteger64v(name_,p){emscriptenWebGLGet(name_,p,1)}function _emscripten_glGetIntegeri_v(target,index,data){emscriptenWebGLGetIndexed(target,index,data,0)}function _emscripten_glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _emscripten_glGetInternalformativ(target,internalformat,pname,bufSize,params){if(bufSize<0){GL.recordError(1281);return}if(!params){GL.recordError(1281);return}var ret=GLctx["getInternalformatParameter"](target,internalformat,pname);if(ret===null)return;for(var i=0;i>2]=ret[i]}}function _emscripten_glGetProgramBinary(program,bufSize,length,binaryFormat,binary){GL.recordError(1282)}function _emscripten_glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _emscripten_glGetQueryObjecti64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectui64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectuiv(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.queries[id];var param=GLctx["getQueryParameter"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectuivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryiv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx["getQuery"](target,pname)}function _emscripten_glGetQueryivEXT(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.disjointTimerQueryExt["getQueryEXT"](target,pname)}function _emscripten_glGetRenderbufferParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getRenderbufferParameter(target,pname)}function _emscripten_glGetSamplerParameterfv(sampler,pname,params){if(!params){GL.recordError(1281);return}sampler=GL.samplers[sampler];HEAPF32[params>>2]=GLctx["getSamplerParameter"](sampler,pname)}function _emscripten_glGetSamplerParameteriv(sampler,pname,params){if(!params){GL.recordError(1281);return}sampler=GL.samplers[sampler];HEAP32[params>>2]=GLctx["getSamplerParameter"](sampler,pname)}function _emscripten_glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderPrecisionFormat(shaderType,precisionType,range,precision){var result=GLctx.getShaderPrecisionFormat(shaderType,precisionType);HEAP32[range>>2]=result.rangeMin;HEAP32[range+4>>2]=result.rangeMax;HEAP32[precision>>2]=result.precision}function _emscripten_glGetShaderSource(shader,bufSize,length,source){var result=GLctx.getShaderSource(GL.shaders[shader]);if(!result)return;var numBytesWrittenExclNull=bufSize>0&&source?stringToUTF8(result,source,bufSize):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function stringToNewUTF8(jsString){var length=lengthBytesUTF8(jsString)+1;var cString=_malloc(length);stringToUTF8(jsString,cString,length);return cString}function _emscripten_glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(true)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _emscripten_glGetStringi(name,index){if(GL.currentContext.version<2){GL.recordError(1282);return 0}var stringiCache=GL.stringiCache[name];if(stringiCache){if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index]}switch(name){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));exts=exts.map(function(e){return stringToNewUTF8(e)});stringiCache=GL.stringiCache[name]=exts;if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index];default:GL.recordError(1280);return 0}}function _emscripten_glGetSynciv(sync,pname,bufSize,length,values){if(bufSize<0){GL.recordError(1281);return}if(!values){GL.recordError(1281);return}var ret=GLctx.getSyncParameter(GL.syncs[sync],pname);HEAP32[length>>2]=ret;if(ret!==null&&length)HEAP32[length>>2]=1}function _emscripten_glGetTexParameterfv(target,pname,params){if(!params){GL.recordError(1281);return}HEAPF32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTexParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTransformFeedbackVarying(program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx["getTransformFeedbackVarying"](program,index);if(!info)return;if(name&&bufSize>0){var numBytesWrittenExclNull=stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull}else{if(length)HEAP32[length>>2]=0}if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}function _emscripten_glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function _emscripten_glGetUniformIndices(program,uniformCount,uniformNames,uniformIndices){if(!uniformIndices){GL.recordError(1281);return}if(uniformCount>0&&(uniformNames==0||uniformIndices==0)){GL.recordError(1281);return}program=GL.programs[program];var names=[];for(var i=0;i>2]));var result=GLctx["getUniformIndices"](program,names);if(!result)return;var len=result.length;for(var i=0;i>2]=result[i]}}function jstoi_q(str){return parseInt(str)}function _emscripten_glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]=data;break;case 2:HEAPF32[params>>2]=data;break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break}}}}function _emscripten_glGetUniformfv(program,location,params){emscriptenWebGLGetUniform(program,location,params,2)}function _emscripten_glGetUniformiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function _emscripten_glGetUniformuiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function emscriptenWebGLGetVertexAttrib(index,pname,params,type){if(!params){GL.recordError(1281);return}if(GL.currentContext.clientBuffers[index].enabled){err("glGetVertexAttrib*v on client-side array: not supported, bad data returned")}var data=GLctx.getVertexAttrib(index,pname);if(pname==34975){HEAP32[params>>2]=data&&data["name"]}else if(typeof data=="number"||typeof data=="boolean"){switch(type){case 0:HEAP32[params>>2]=data;break;case 2:HEAPF32[params>>2]=data;break;case 5:HEAP32[params>>2]=Math.fround(data);break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break;case 5:HEAP32[params+i*4>>2]=Math.fround(data[i]);break}}}}function _emscripten_glGetVertexAttribIiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,0)}function _emscripten_glGetVertexAttribIuiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,0)}function _emscripten_glGetVertexAttribPointerv(index,pname,pointer){if(!pointer){GL.recordError(1281);return}if(GL.currentContext.clientBuffers[index].enabled){err("glGetVertexAttribPointer on client-side array: not supported, bad data returned")}HEAP32[pointer>>2]=GLctx.getVertexAttribOffset(index,pname)}function _emscripten_glGetVertexAttribfv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,2)}function _emscripten_glGetVertexAttribiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,5)}function _emscripten_glHint(x0,x1){GLctx["hint"](x0,x1)}function _emscripten_glInvalidateFramebuffer(target,numAttachments,attachments){var list=tempFixedLengthArray[numAttachments];for(var i=0;i>2]}GLctx["invalidateFramebuffer"](target,list)}function _emscripten_glInvalidateSubFramebuffer(target,numAttachments,attachments,x,y,width,height){var list=tempFixedLengthArray[numAttachments];for(var i=0;i>2]}GLctx["invalidateSubFramebuffer"](target,list,x,y,width,height)}function _emscripten_glIsBuffer(buffer){var b=GL.buffers[buffer];if(!b)return 0;return GLctx.isBuffer(b)}function _emscripten_glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _emscripten_glIsFramebuffer(framebuffer){var fb=GL.framebuffers[framebuffer];if(!fb)return 0;return GLctx.isFramebuffer(fb)}function _emscripten_glIsProgram(program){program=GL.programs[program];if(!program)return 0;return GLctx.isProgram(program)}function _emscripten_glIsQuery(id){var query=GL.queries[id];if(!query)return 0;return GLctx["isQuery"](query)}function _emscripten_glIsQueryEXT(id){var query=GL.timerQueriesEXT[id];if(!query)return 0;return GLctx.disjointTimerQueryExt["isQueryEXT"](query)}function _emscripten_glIsRenderbuffer(renderbuffer){var rb=GL.renderbuffers[renderbuffer];if(!rb)return 0;return GLctx.isRenderbuffer(rb)}function _emscripten_glIsSampler(id){var sampler=GL.samplers[id];if(!sampler)return 0;return GLctx["isSampler"](sampler)}function _emscripten_glIsShader(shader){var s=GL.shaders[shader];if(!s)return 0;return GLctx.isShader(s)}function _emscripten_glIsSync(sync){return GLctx.isSync(GL.syncs[sync])}function _emscripten_glIsTexture(id){var texture=GL.textures[id];if(!texture)return 0;return GLctx.isTexture(texture)}function _emscripten_glIsTransformFeedback(id){return GLctx["isTransformFeedback"](GL.transformFeedbacks[id])}function _emscripten_glIsVertexArray(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glIsVertexArrayOES(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glLineWidth(x0){GLctx["lineWidth"](x0)}function _emscripten_glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _emscripten_glMapBufferRange(target,offset,length,access){if(access!=26&&access!=10){err("glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER");return 0}if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glMapBufferRange");return 0}var mem=_malloc(length);if(!mem)return 0;GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)]={offset:offset,length:length,mem:mem,access:access};return mem}function _emscripten_glPauseTransformFeedback(){GLctx["pauseTransformFeedback"]()}function _emscripten_glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _emscripten_glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _emscripten_glProgramBinary(program,binaryFormat,binary,length){GL.recordError(1280)}function _emscripten_glProgramParameteri(program,pname,value){GL.recordError(1280)}function _emscripten_glQueryCounterEXT(id,target){GLctx.disjointTimerQueryExt["queryCounterEXT"](GL.timerQueriesEXT[id],target)}function _emscripten_glReadBuffer(x0){GLctx["readBuffer"](x0)}function computeUnpackAlignedImageSize(width,height,sizePerPixel,alignment){function roundedToNextMultipleOf(x,y){return x+y-1&-y}var plainRowSize=width*sizePerPixel;var alignedRowSize=roundedToNextMultipleOf(plainRowSize,alignment);return height*alignedRowSize}function __colorChannelsInGlTextureFormat(format){var colorChannels={5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4};return colorChannels[format-6402]||1}function heapObjectForWebGLType(type){type-=5120;if(type==0)return HEAP8;if(type==1)return HEAPU8;if(type==2)return HEAP16;if(type==4)return HEAP32;if(type==6)return HEAPF32;if(type==5||type==28922||type==28520||type==30779||type==30782)return HEAPU32;return HEAPU16}function heapAccessShiftForWebGLHeap(heap){return 31-Math.clz32(heap.BYTES_PER_ELEMENT)}function emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat){var heap=heapObjectForWebGLType(type);var shift=heapAccessShiftForWebGLHeap(heap);var byteSize=1<>shift,pixels+bytes>>shift)}function _emscripten_glReadPixels(x,y,width,height,format,type,pixels){if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _emscripten_glReleaseShaderCompiler(){}function _emscripten_glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _emscripten_glRenderbufferStorageMultisample(x0,x1,x2,x3,x4){GLctx["renderbufferStorageMultisample"](x0,x1,x2,x3,x4)}function _emscripten_glResumeTransformFeedback(){GLctx["resumeTransformFeedback"]()}function _emscripten_glSampleCoverage(value,invert){GLctx.sampleCoverage(value,!!invert)}function _emscripten_glSamplerParameterf(sampler,pname,param){GLctx["samplerParameterf"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameterfv(sampler,pname,params){var param=HEAPF32[params>>2];GLctx["samplerParameterf"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameteri(sampler,pname,param){GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameteriv(sampler,pname,params){var param=HEAP32[params>>2];GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _emscripten_glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _emscripten_glShaderBinary(){GL.recordError(1280)}function _emscripten_glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _emscripten_glStencilFunc(x0,x1,x2){GLctx["stencilFunc"](x0,x1,x2)}function _emscripten_glStencilFuncSeparate(x0,x1,x2,x3){GLctx["stencilFuncSeparate"](x0,x1,x2,x3)}function _emscripten_glStencilMask(x0){GLctx["stencilMask"](x0)}function _emscripten_glStencilMaskSeparate(x0,x1){GLctx["stencilMaskSeparate"](x0,x1)}function _emscripten_glStencilOp(x0,x1,x2){GLctx["stencilOp"](x0,x1,x2)}function _emscripten_glStencilOpSeparate(x0,x1,x2,x3){GLctx["stencilOpSeparate"](x0,x1,x2,x3)}function _emscripten_glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,null)}return}GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels?emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat):null)}function _emscripten_glTexImage3D(target,level,internalFormat,width,height,depth,border,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,null)}}function _emscripten_glTexParameterf(x0,x1,x2){GLctx["texParameterf"](x0,x1,x2)}function _emscripten_glTexParameterfv(target,pname,params){var param=HEAPF32[params>>2];GLctx.texParameterf(target,pname,param)}function _emscripten_glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _emscripten_glTexParameteriv(target,pname,params){var param=HEAP32[params>>2];GLctx.texParameteri(target,pname,param)}function _emscripten_glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _emscripten_glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _emscripten_glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _emscripten_glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function _emscripten_glTransformFeedbackVaryings(program,count,varyings,bufferMode){program=GL.programs[program];var vars=[];for(var i=0;i>2]));GLctx["transformFeedbackVaryings"](program,vars,bufferMode)}function _emscripten_glUniform1f(location,v0){GLctx.uniform1f(GL.uniforms[location],v0)}function _emscripten_glUniform1fv(location,count,value){GLctx.uniform1fv(GL.uniforms[location],HEAPF32,value>>2,count)}function _emscripten_glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}function _emscripten_glUniform1iv(location,count,value){GLctx.uniform1iv(GL.uniforms[location],HEAP32,value>>2,count)}function _emscripten_glUniform1ui(location,v0){GLctx.uniform1ui(GL.uniforms[location],v0)}function _emscripten_glUniform1uiv(location,count,value){GLctx.uniform1uiv(GL.uniforms[location],HEAPU32,value>>2,count)}function _emscripten_glUniform2f(location,v0,v1){GLctx.uniform2f(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2fv(location,count,value){GLctx.uniform2fv(GL.uniforms[location],HEAPF32,value>>2,count*2)}function _emscripten_glUniform2i(location,v0,v1){GLctx.uniform2i(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2iv(location,count,value){GLctx.uniform2iv(GL.uniforms[location],HEAP32,value>>2,count*2)}function _emscripten_glUniform2ui(location,v0,v1){GLctx.uniform2ui(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2uiv(location,count,value){GLctx.uniform2uiv(GL.uniforms[location],HEAPU32,value>>2,count*2)}function _emscripten_glUniform3f(location,v0,v1,v2){GLctx.uniform3f(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3fv(location,count,value){GLctx.uniform3fv(GL.uniforms[location],HEAPF32,value>>2,count*3)}function _emscripten_glUniform3i(location,v0,v1,v2){GLctx.uniform3i(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3iv(location,count,value){GLctx.uniform3iv(GL.uniforms[location],HEAP32,value>>2,count*3)}function _emscripten_glUniform3ui(location,v0,v1,v2){GLctx.uniform3ui(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3uiv(location,count,value){GLctx.uniform3uiv(GL.uniforms[location],HEAPU32,value>>2,count*3)}function _emscripten_glUniform4f(location,v0,v1,v2,v3){GLctx.uniform4f(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4fv(location,count,value){GLctx.uniform4fv(GL.uniforms[location],HEAPF32,value>>2,count*4)}function _emscripten_glUniform4i(location,v0,v1,v2,v3){GLctx.uniform4i(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4iv(location,count,value){GLctx.uniform4iv(GL.uniforms[location],HEAP32,value>>2,count*4)}function _emscripten_glUniform4ui(location,v0,v1,v2,v3){GLctx.uniform4ui(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4uiv(location,count,value){GLctx.uniform4uiv(GL.uniforms[location],HEAPU32,value>>2,count*4)}function _emscripten_glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _emscripten_glUniformMatrix2fv(location,count,transpose,value){GLctx.uniformMatrix2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*4)}function _emscripten_glUniformMatrix2x3fv(location,count,transpose,value){GLctx.uniformMatrix2x3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*6)}function _emscripten_glUniformMatrix2x4fv(location,count,transpose,value){GLctx.uniformMatrix2x4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*8)}function _emscripten_glUniformMatrix3fv(location,count,transpose,value){GLctx.uniformMatrix3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*9)}function _emscripten_glUniformMatrix3x2fv(location,count,transpose,value){GLctx.uniformMatrix3x2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*6)}function _emscripten_glUniformMatrix3x4fv(location,count,transpose,value){GLctx.uniformMatrix3x4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*12)}function _emscripten_glUniformMatrix4fv(location,count,transpose,value){GLctx.uniformMatrix4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*16)}function _emscripten_glUniformMatrix4x2fv(location,count,transpose,value){GLctx.uniformMatrix4x2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*8)}function _emscripten_glUniformMatrix4x3fv(location,count,transpose,value){GLctx.uniformMatrix4x3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*12)}function _emscripten_glUnmapBuffer(target){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glUnmapBuffer");return 0}var buffer=emscriptenWebGLGetBufferBinding(target);var mapping=GL.mappedBuffers[buffer];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glUnmapBuffer");return 0}GL.mappedBuffers[buffer]=null;if(!(mapping.access&16))if(true){GLctx.bufferSubData(target,mapping.offset,HEAPU8,mapping.mem,mapping.length)}else{GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem,mapping.mem+mapping.length))}_free(mapping.mem);return 1}function _emscripten_glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _emscripten_glValidateProgram(program){GLctx.validateProgram(GL.programs[program])}function _emscripten_glVertexAttrib1f(x0,x1){GLctx["vertexAttrib1f"](x0,x1)}function _emscripten_glVertexAttrib1fv(index,v){GLctx.vertexAttrib1f(index,HEAPF32[v>>2])}function _emscripten_glVertexAttrib2f(x0,x1,x2){GLctx["vertexAttrib2f"](x0,x1,x2)}function _emscripten_glVertexAttrib2fv(index,v){GLctx.vertexAttrib2f(index,HEAPF32[v>>2],HEAPF32[v+4>>2])}function _emscripten_glVertexAttrib3f(x0,x1,x2,x3){GLctx["vertexAttrib3f"](x0,x1,x2,x3)}function _emscripten_glVertexAttrib3fv(index,v){GLctx.vertexAttrib3f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2])}function _emscripten_glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttrib4fv(index,v){GLctx.vertexAttrib4f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2],HEAPF32[v+12>>2])}function _emscripten_glVertexAttribDivisor(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorANGLE(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorARB(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorEXT(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorNV(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribI4i(x0,x1,x2,x3,x4){GLctx["vertexAttribI4i"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttribI4iv(index,v){GLctx.vertexAttribI4i(index,HEAP32[v>>2],HEAP32[v+4>>2],HEAP32[v+8>>2],HEAP32[v+12>>2])}function _emscripten_glVertexAttribI4ui(x0,x1,x2,x3,x4){GLctx["vertexAttribI4ui"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttribI4uiv(index,v){GLctx.vertexAttribI4ui(index,HEAPU32[v>>2],HEAPU32[v+4>>2],HEAPU32[v+8>>2],HEAPU32[v+12>>2])}function _emscripten_glVertexAttribIPointer(index,size,type,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=false;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribIPointer(index,size,type,stride,ptr)};return}cb.clientside=false;GLctx["vertexAttribIPointer"](index,size,type,stride,ptr)}function _emscripten_glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _emscripten_glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _emscripten_glWaitSync(sync,flags,timeoutLo,timeoutHi){GLctx.waitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){try{var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _environ_sizes_get(penviron_count,penviron_buf_size){try{var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];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 _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _getentropy(buffer,size){if(!_getentropy.randomDevice){_getentropy.randomDevice=getRandomDevice()}for(var i=0;i>0]=_getentropy.randomDevice()}return 0}function _glActiveTexture(x0){GLctx["activeTexture"](x0)}function _glAttachShader(program,shader){GLctx.attachShader(GL.programs[program],GL.shaders[shader])}function _glBeginQuery(target,id){GLctx["beginQuery"](target,GL.queries[id])}function _glBindBuffer(target,buffer){if(target==34962){GLctx.currentArrayBufferBinding=buffer}else if(target==34963){GLctx.currentElementArrayBufferBinding=buffer}if(target==35051){GLctx.currentPixelPackBufferBinding=buffer}else if(target==35052){GLctx.currentPixelUnpackBufferBinding=buffer}GLctx.bindBuffer(target,GL.buffers[buffer])}function _glBindBufferRange(target,index,buffer,offset,ptrsize){GLctx["bindBufferRange"](target,index,GL.buffers[buffer],offset,ptrsize)}function _glBindFramebuffer(target,framebuffer){GLctx.bindFramebuffer(target,GL.framebuffers[framebuffer])}function _glBindRenderbuffer(target,renderbuffer){GLctx.bindRenderbuffer(target,GL.renderbuffers[renderbuffer])}function _glBindSampler(unit,sampler){GLctx["bindSampler"](unit,GL.samplers[sampler])}function _glBindTexture(target,texture){GLctx.bindTexture(target,GL.textures[texture])}function _glBindVertexArray(vao){GLctx["bindVertexArray"](GL.vaos[vao]);var ibo=GLctx.getParameter(34965);GLctx.currentElementArrayBufferBinding=ibo?ibo.name|0:0}function _glBlendEquationSeparate(x0,x1){GLctx["blendEquationSeparate"](x0,x1)}function _glBlendFuncSeparate(x0,x1,x2,x3){GLctx["blendFuncSeparate"](x0,x1,x2,x3)}function _glBlitFramebuffer(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9){GLctx["blitFramebuffer"](x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)}function _glBufferData(target,size,data,usage){if(true){if(data){GLctx.bufferData(target,HEAPU8,usage,data,size)}else{GLctx.bufferData(target,size,usage)}}else{GLctx.bufferData(target,data?HEAPU8.subarray(data,data+size):size,usage)}}function _glBufferSubData(target,offset,size,data){if(true){GLctx.bufferSubData(target,offset,HEAPU8,data,size);return}GLctx.bufferSubData(target,offset,HEAPU8.subarray(data,data+size))}function _glClearBufferfi(x0,x1,x2,x3){GLctx["clearBufferfi"](x0,x1,x2,x3)}function _glClearBufferfv(buffer,drawbuffer,value){GLctx["clearBufferfv"](buffer,drawbuffer,HEAPF32,value>>2)}function _glClearBufferiv(buffer,drawbuffer,value){GLctx["clearBufferiv"](buffer,drawbuffer,HEAP32,value>>2)}function _glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,imageSize,data)}else{GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,HEAPU8,data,imageSize)}return}GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _glCompressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data)}else{GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,HEAPU8,data,imageSize)}}function _glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _glCullFace(x0){GLctx["cullFace"](x0)}function _glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _glDeleteQueries(n,ids){for(var i=0;i>2];var query=GL.queries[id];if(!query)continue;GLctx["deleteQuery"](query);GL.queries[id]=null}}function _glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _glDeleteSamplers(n,samplers){for(var i=0;i>2];var sampler=GL.samplers[id];if(!sampler)continue;GLctx["deleteSampler"](sampler);sampler.name=0;GL.samplers[id]=null}}function _glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _glDepthFunc(x0){GLctx["depthFunc"](x0)}function _glDepthMask(flag){GLctx.depthMask(!!flag)}function _glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _glDisable(x0){GLctx["disable"](x0)}function _glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _glDrawRangeElements(mode,start,end,count,type,indices){_glDrawElements(mode,count,type,indices)}function _glEnable(x0){GLctx["enable"](x0)}function _glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _glEndQuery(x0){GLctx["endQuery"](x0)}function _glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _glFinish(){GLctx["finish"]()}function _glFlush(){GLctx["flush"]()}function _glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function _glFrontFace(x0){GLctx["frontFace"](x0)}function _glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _glGenQueries(n,ids){__glGenObject(n,ids,"createQuery",GL.queries)}function _glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _glGenSamplers(n,samplers){__glGenObject(n,samplers,"createSampler",GL.samplers)}function _glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function _glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _glGetQueryObjectuiv(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.queries[id];var param=GLctx["getQueryParameter"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function _glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(true)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _glGetStringi(name,index){if(GL.currentContext.version<2){GL.recordError(1282);return 0}var stringiCache=GL.stringiCache[name];if(stringiCache){if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index]}switch(name){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));exts=exts.map(function(e){return stringToNewUTF8(e)});stringiCache=GL.stringiCache[name]=exts;if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index];default:GL.recordError(1280);return 0}}function _glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function _glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]}GLctx["invalidateFramebuffer"](target,list)}function _glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _glMapBufferRange(target,offset,length,access){if(access!=26&&access!=10){err("glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER");return 0}if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glMapBufferRange");return 0}var mem=_malloc(length);if(!mem)return 0;GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)]={offset:offset,length:length,mem:mem,access:access};return mem}function _glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _glReadPixels(x,y,width,height,format,type,pixels){if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _glRenderbufferStorageMultisample(x0,x1,x2,x3,x4){GLctx["renderbufferStorageMultisample"](x0,x1,x2,x3,x4)}function _glSamplerParameteri(sampler,pname,param){GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function _glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}function _glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _glUnmapBuffer(target){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glUnmapBuffer");return 0}var buffer=emscriptenWebGLGetBufferBinding(target);var mapping=GL.mappedBuffers[buffer];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glUnmapBuffer");return 0}GL.mappedBuffers[buffer]=null;if(!(mapping.access&16))if(true){GLctx.bufferSubData(target,mapping.offset,HEAPU8,mapping.mem,mapping.length)}else{GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem,mapping.mem+mapping.length))}_free(mapping.mem);return 1}function _glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _glVertexAttribI4ui(x0,x1,x2,x3,x4){GLctx["vertexAttribI4ui"](x0,x1,x2,x3,x4)}function _glVertexAttribIPointer(index,size,type,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=false;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribIPointer(index,size,type,stride,ptr)};return}cb.clientside=false;GLctx["vertexAttribIPointer"](index,size,type,stride,ptr)}function _glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _glWaitSync(sync,flags,timeoutLo,timeoutHi){GLctx.waitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _pthread_create(){return 6}function _pthread_join(){return 28}function _setTempRet0($i){setTempRet0($i|0)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.indexOf(rule)>=0){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm){return _strftime(s,maxsize,format,tm)}function _sysconf(name){switch(name){case 30:return 16384;case 85:var maxHeapSize=2147483648;return maxHeapSize/16384;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:case 80:case 81:case 79:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}setErrNo(28);return-1}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){var double=ch<105;if(double&&buf&1)buf++;readAsmConstArgsArray.push(double?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var GLctx;for(var i=0;i<32;++i)tempFixedLengthArray.push(new Array(i));function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var asmLibraryArg={"Ga":___sys_fcntl64,"Dg":___sys_ioctl,"Eg":___sys_open,"v":__embind_finalize_value_array,"z":__embind_finalize_value_object,"Hg":__embind_register_bool,"d":__embind_register_class,"l":__embind_register_class_class_function,"n":__embind_register_class_constructor,"a":__embind_register_class_function,"u":__embind_register_class_property,"Gg":__embind_register_emval,"i":__embind_register_enum,"b":__embind_register_enum_value,"Ia":__embind_register_float,"Ka":__embind_register_function,"D":__embind_register_integer,"x":__embind_register_memory_view,"Ja":__embind_register_std_string,"ja":__embind_register_std_wstring,"w":__embind_register_value_array,"f":__embind_register_value_array_element,"A":__embind_register_value_object,"e":__embind_register_value_object_field,"Ig":__embind_register_void,"q":__emval_as,"g":__emval_decref,"r":__emval_get_property,"ha":__emval_incref,"G":__emval_new_cstring,"p":__emval_run_destructors,"s":__emval_take_value,"c":_abort,"wg":_clock_gettime,"tg":_emscripten_asm_const_int,"$f":_emscripten_glActiveTexture,"_f":_emscripten_glAttachShader,"bd":_emscripten_glBeginQuery,"pg":_emscripten_glBeginQueryEXT,"Fc":_emscripten_glBeginTransformFeedback,"Zf":_emscripten_glBindAttribLocation,"Yf":_emscripten_glBindBuffer,"Cc":_emscripten_glBindBufferBase,"Dc":_emscripten_glBindBufferRange,"Xf":_emscripten_glBindFramebuffer,"Wf":_emscripten_glBindRenderbuffer,"Jb":_emscripten_glBindSampler,"Vf":_emscripten_glBindTexture,"Bb":_emscripten_glBindTransformFeedback,"Kc":_emscripten_glBindVertexArray,"hg":_emscripten_glBindVertexArrayOES,"Uf":_emscripten_glBlendColor,"Tf":_emscripten_glBlendEquation,"Sf":_emscripten_glBlendEquationSeparate,"Rf":_emscripten_glBlendFunc,"Qf":_emscripten_glBlendFuncSeparate,"Qc":_emscripten_glBlitFramebuffer,"Pf":_emscripten_glBufferData,"Of":_emscripten_glBufferSubData,"Nf":_emscripten_glCheckFramebufferStatus,"Mf":_emscripten_glClear,"fc":_emscripten_glClearBufferfi,"gc":_emscripten_glClearBufferfv,"ic":_emscripten_glClearBufferiv,"hc":_emscripten_glClearBufferuiv,"Lf":_emscripten_glClearColor,"Kf":_emscripten_glClearDepthf,"Jf":_emscripten_glClearStencil,"Tb":_emscripten_glClientWaitSync,"If":_emscripten_glColorMask,"Hf":_emscripten_glCompileShader,"Gf":_emscripten_glCompressedTexImage2D,"gd":_emscripten_glCompressedTexImage3D,"Ff":_emscripten_glCompressedTexSubImage2D,"fd":_emscripten_glCompressedTexSubImage3D,"dc":_emscripten_glCopyBufferSubData,"Ef":_emscripten_glCopyTexImage2D,"Df":_emscripten_glCopyTexSubImage2D,"id":_emscripten_glCopyTexSubImage3D,"Cf":_emscripten_glCreateProgram,"Bf":_emscripten_glCreateShader,"Af":_emscripten_glCullFace,"zf":_emscripten_glDeleteBuffers,"yf":_emscripten_glDeleteFramebuffers,"xf":_emscripten_glDeleteProgram,"dd":_emscripten_glDeleteQueries,"rg":_emscripten_glDeleteQueriesEXT,"wf":_emscripten_glDeleteRenderbuffers,"Lb":_emscripten_glDeleteSamplers,"vf":_emscripten_glDeleteShader,"Ub":_emscripten_glDeleteSync,"uf":_emscripten_glDeleteTextures,"Ab":_emscripten_glDeleteTransformFeedbacks,"Jc":_emscripten_glDeleteVertexArrays,"gg":_emscripten_glDeleteVertexArraysOES,"tf":_emscripten_glDepthFunc,"sf":_emscripten_glDepthMask,"rf":_emscripten_glDepthRangef,"qf":_emscripten_glDetachShader,"pf":_emscripten_glDisable,"of":_emscripten_glDisableVertexAttribArray,"nf":_emscripten_glDrawArrays,"Yb":_emscripten_glDrawArraysInstanced,"cg":_emscripten_glDrawArraysInstancedANGLE,"kb":_emscripten_glDrawArraysInstancedARB,"pd":_emscripten_glDrawArraysInstancedEXT,"lb":_emscripten_glDrawArraysInstancedNV,"Xc":_emscripten_glDrawBuffers,"nd":_emscripten_glDrawBuffersEXT,"dg":_emscripten_glDrawBuffersWEBGL,"mf":_emscripten_glDrawElements,"Xb":_emscripten_glDrawElementsInstanced,"bg":_emscripten_glDrawElementsInstancedANGLE,"ib":_emscripten_glDrawElementsInstancedARB,"jb":_emscripten_glDrawElementsInstancedEXT,"od":_emscripten_glDrawElementsInstancedNV,"ld":_emscripten_glDrawRangeElements,"lf":_emscripten_glEnable,"kf":_emscripten_glEnableVertexAttribArray,"ad":_emscripten_glEndQuery,"og":_emscripten_glEndQueryEXT,"Ec":_emscripten_glEndTransformFeedback,"Wb":_emscripten_glFenceSync,"jf":_emscripten_glFinish,"hf":_emscripten_glFlush,"Lc":_emscripten_glFlushMappedBufferRange,"gf":_emscripten_glFramebufferRenderbuffer,"ff":_emscripten_glFramebufferTexture2D,"Nc":_emscripten_glFramebufferTextureLayer,"ef":_emscripten_glFrontFace,"df":_emscripten_glGenBuffers,"bf":_emscripten_glGenFramebuffers,"ed":_emscripten_glGenQueries,"sg":_emscripten_glGenQueriesEXT,"af":_emscripten_glGenRenderbuffers,"Mb":_emscripten_glGenSamplers,"$e":_emscripten_glGenTextures,"zb":_emscripten_glGenTransformFeedbacks,"Ic":_emscripten_glGenVertexArrays,"fg":_emscripten_glGenVertexArraysOES,"cf":_emscripten_glGenerateMipmap,"_e":_emscripten_glGetActiveAttrib,"Ze":_emscripten_glGetActiveUniform,"_b":_emscripten_glGetActiveUniformBlockName,"$b":_emscripten_glGetActiveUniformBlockiv,"bc":_emscripten_glGetActiveUniformsiv,"Ye":_emscripten_glGetAttachedShaders,"Xe":_emscripten_glGetAttribLocation,"We":_emscripten_glGetBooleanv,"Nb":_emscripten_glGetBufferParameteri64v,"Ve":_emscripten_glGetBufferParameteriv,"Yc":_emscripten_glGetBufferPointerv,"Ue":_emscripten_glGetError,"Te":_emscripten_glGetFloatv,"rc":_emscripten_glGetFragDataLocation,"Se":_emscripten_glGetFramebufferAttachmentParameteriv,"Ob":_emscripten_glGetInteger64i_v,"Qb":_emscripten_glGetInteger64v,"Gc":_emscripten_glGetIntegeri_v,"Re":_emscripten_glGetIntegerv,"ob":_emscripten_glGetInternalformativ,"vb":_emscripten_glGetProgramBinary,"Pe":_emscripten_glGetProgramInfoLog,"Qe":_emscripten_glGetProgramiv,"jg":_emscripten_glGetQueryObjecti64vEXT,"lg":_emscripten_glGetQueryObjectivEXT,"ig":_emscripten_glGetQueryObjectui64vEXT,"_c":_emscripten_glGetQueryObjectuiv,"kg":_emscripten_glGetQueryObjectuivEXT,"$c":_emscripten_glGetQueryiv,"mg":_emscripten_glGetQueryivEXT,"Oe":_emscripten_glGetRenderbufferParameteriv,"Db":_emscripten_glGetSamplerParameterfv,"Eb":_emscripten_glGetSamplerParameteriv,"Me":_emscripten_glGetShaderInfoLog,"Le":_emscripten_glGetShaderPrecisionFormat,"Ke":_emscripten_glGetShaderSource,"Ne":_emscripten_glGetShaderiv,"Je":_emscripten_glGetString,"ec":_emscripten_glGetStringi,"Pb":_emscripten_glGetSynciv,"Ie":_emscripten_glGetTexParameterfv,"He":_emscripten_glGetTexParameteriv,"Ac":_emscripten_glGetTransformFeedbackVarying,"ac":_emscripten_glGetUniformBlockIndex,"cc":_emscripten_glGetUniformIndices,"Ee":_emscripten_glGetUniformLocation,"Ge":_emscripten_glGetUniformfv,"Fe":_emscripten_glGetUniformiv,"sc":_emscripten_glGetUniformuiv,"yc":_emscripten_glGetVertexAttribIiv,"xc":_emscripten_glGetVertexAttribIuiv,"Be":_emscripten_glGetVertexAttribPointerv,"De":_emscripten_glGetVertexAttribfv,"Ce":_emscripten_glGetVertexAttribiv,"Ae":_emscripten_glHint,"sb":_emscripten_glInvalidateFramebuffer,"rb":_emscripten_glInvalidateSubFramebuffer,"ze":_emscripten_glIsBuffer,"ye":_emscripten_glIsEnabled,"xe":_emscripten_glIsFramebuffer,"we":_emscripten_glIsProgram,"cd":_emscripten_glIsQuery,"qg":_emscripten_glIsQueryEXT,"ve":_emscripten_glIsRenderbuffer,"Kb":_emscripten_glIsSampler,"ue":_emscripten_glIsShader,"Vb":_emscripten_glIsSync,"te":_emscripten_glIsTexture,"yb":_emscripten_glIsTransformFeedback,"Hc":_emscripten_glIsVertexArray,"eg":_emscripten_glIsVertexArrayOES,"se":_emscripten_glLineWidth,"re":_emscripten_glLinkProgram,"Mc":_emscripten_glMapBufferRange,"xb":_emscripten_glPauseTransformFeedback,"qe":_emscripten_glPixelStorei,"pe":_emscripten_glPolygonOffset,"ub":_emscripten_glProgramBinary,"tb":_emscripten_glProgramParameteri,"ng":_emscripten_glQueryCounterEXT,"md":_emscripten_glReadBuffer,"oe":_emscripten_glReadPixels,"ne":_emscripten_glReleaseShaderCompiler,"me":_emscripten_glRenderbufferStorage,"Pc":_emscripten_glRenderbufferStorageMultisample,"wb":_emscripten_glResumeTransformFeedback,"le":_emscripten_glSampleCoverage,"Gb":_emscripten_glSamplerParameterf,"Fb":_emscripten_glSamplerParameterfv,"Ib":_emscripten_glSamplerParameteri,"Hb":_emscripten_glSamplerParameteriv,"ke":_emscripten_glScissor,"je":_emscripten_glShaderBinary,"ie":_emscripten_glShaderSource,"he":_emscripten_glStencilFunc,"ge":_emscripten_glStencilFuncSeparate,"fe":_emscripten_glStencilMask,"ee":_emscripten_glStencilMaskSeparate,"de":_emscripten_glStencilOp,"ce":_emscripten_glStencilOpSeparate,"be":_emscripten_glTexImage2D,"kd":_emscripten_glTexImage3D,"ae":_emscripten_glTexParameterf,"$d":_emscripten_glTexParameterfv,"_d":_emscripten_glTexParameteri,"Zd":_emscripten_glTexParameteriv,"qb":_emscripten_glTexStorage2D,"pb":_emscripten_glTexStorage3D,"Yd":_emscripten_glTexSubImage2D,"jd":_emscripten_glTexSubImage3D,"Bc":_emscripten_glTransformFeedbackVaryings,"Xd":_emscripten_glUniform1f,"Wd":_emscripten_glUniform1fv,"Vd":_emscripten_glUniform1i,"Ud":_emscripten_glUniform1iv,"qc":_emscripten_glUniform1ui,"mc":_emscripten_glUniform1uiv,"Td":_emscripten_glUniform2f,"Sd":_emscripten_glUniform2fv,"Rd":_emscripten_glUniform2i,"Qd":_emscripten_glUniform2iv,"pc":_emscripten_glUniform2ui,"lc":_emscripten_glUniform2uiv,"Pd":_emscripten_glUniform3f,"Od":_emscripten_glUniform3fv,"Md":_emscripten_glUniform3i,"Ld":_emscripten_glUniform3iv,"oc":_emscripten_glUniform3ui,"kc":_emscripten_glUniform3uiv,"Kd":_emscripten_glUniform4f,"Jd":_emscripten_glUniform4fv,"Id":_emscripten_glUniform4i,"Hd":_emscripten_glUniform4iv,"nc":_emscripten_glUniform4ui,"jc":_emscripten_glUniform4uiv,"Zb":_emscripten_glUniformBlockBinding,"Gd":_emscripten_glUniformMatrix2fv,"Wc":_emscripten_glUniformMatrix2x3fv,"Uc":_emscripten_glUniformMatrix2x4fv,"Fd":_emscripten_glUniformMatrix3fv,"Vc":_emscripten_glUniformMatrix3x2fv,"Sc":_emscripten_glUniformMatrix3x4fv,"Ed":_emscripten_glUniformMatrix4fv,"Tc":_emscripten_glUniformMatrix4x2fv,"Rc":_emscripten_glUniformMatrix4x3fv,"Zc":_emscripten_glUnmapBuffer,"Dd":_emscripten_glUseProgram,"Cd":_emscripten_glValidateProgram,"Bd":_emscripten_glVertexAttrib1f,"Ad":_emscripten_glVertexAttrib1fv,"zd":_emscripten_glVertexAttrib2f,"yd":_emscripten_glVertexAttrib2fv,"xd":_emscripten_glVertexAttrib3f,"wd":_emscripten_glVertexAttrib3fv,"vd":_emscripten_glVertexAttrib4f,"ud":_emscripten_glVertexAttrib4fv,"Cb":_emscripten_glVertexAttribDivisor,"ag":_emscripten_glVertexAttribDivisorANGLE,"mb":_emscripten_glVertexAttribDivisorARB,"qd":_emscripten_glVertexAttribDivisorEXT,"nb":_emscripten_glVertexAttribDivisorNV,"wc":_emscripten_glVertexAttribI4i,"uc":_emscripten_glVertexAttribI4iv,"vc":_emscripten_glVertexAttribI4ui,"tc":_emscripten_glVertexAttribI4uiv,"zc":_emscripten_glVertexAttribIPointer,"td":_emscripten_glVertexAttribPointer,"rd":_emscripten_glViewport,"Sb":_emscripten_glWaitSync,"ug":_emscripten_memcpy_big,"vg":_emscripten_resize_heap,"zg":_environ_get,"Ag":_environ_sizes_get,"ia":_fd_close,"Fg":_fd_read,"fb":_fd_seek,"Ha":_fd_write,"xg":_getentropy,"h":_glActiveTexture,"T":_glAttachShader,"Xg":_glBeginQuery,"C":_glBindBuffer,"ra":_glBindBufferRange,"m":_glBindFramebuffer,"H":_glBindRenderbuffer,"U":_glBindSampler,"k":_glBindTexture,"N":_glBindVertexArray,"Tg":_glBlendEquationSeparate,"Sg":_glBlendFuncSeparate,"pa":_glBlitFramebuffer,"M":_glBufferData,"Y":_glBufferSubData,"Mg":_glClearBufferfi,"O":_glClearBufferfv,"Lg":_glClearBufferiv,"gb":_glClientWaitSync,"la":_glColorMask,"ba":_glCompileShader,"Ma":_glCompressedTexSubImage2D,"La":_glCompressedTexSubImage3D,"Aa":_glCreateProgram,"da":_glCreateShader,"ka":_glCullFace,"Ca":_glDeleteBuffers,"S":_glDeleteFramebuffers,"$":_glDeleteProgram,"_a":_glDeleteQueries,"E":_glDeleteRenderbuffers,"na":_glDeleteSamplers,"L":_glDeleteShader,"F":_glDeleteSync,"J":_glDeleteTextures,"Rb":_glDeleteVertexArrays,"Rg":_glDepthFunc,"Qg":_glDepthMask,"Ya":_glDepthRangef,"_":_glDetachShader,"j":_glDisable,"sa":_glDisableVertexAttribArray,"Qa":_glDrawArrays,"Sa":_glDrawBuffers,"Ta":_glDrawRangeElements,"B":_glEnable,"ta":_glEnableVertexAttribArray,"Wg":_glEndQuery,"Z":_glFenceSync,"Da":_glFinish,"Ea":_glFlush,"P":_glFramebufferRenderbuffer,"Q":_glFramebufferTexture2D,"Pa":_glFramebufferTextureLayer,"Ug":_glFrontFace,"W":_glGenBuffers,"R":_glGenFramebuffers,"$a":_glGenQueries,"ga":_glGenRenderbuffers,"oa":_glGenSamplers,"I":_glGenTextures,"eb":_glGenVertexArrays,"Za":_glGenerateMipmap,"Ra":_glGetError,"sd":_glGetFloatv,"o":_glGetIntegerv,"bb":_glGetProgramInfoLog,"ya":_glGetProgramiv,"Vg":_glGetQueryObjectuiv,"ab":_glGetShaderInfoLog,"aa":_glGetShaderiv,"V":_glGetString,"Nd":_glGetStringi,"db":_glGetUniformBlockIndex,"xa":_glGetUniformLocation,"Yg":_glGetVertexAttribiv,"hd":_glHint,"va":_glInvalidateFramebuffer,"ma":_glIsEnabled,"za":_glLinkProgram,"Kg":_glMapBufferRange,"Oc":_glPixelStorei,"Ua":_glPolygonOffset,"qa":_glReadPixels,"ea":_glRenderbufferStorage,"fa":_glRenderbufferStorageMultisample,"t":_glSamplerParameteri,"Ng":_glScissor,"ca":_glShaderSource,"y":_glTexParameteri,"Pg":_glTexStorage2D,"Og":_glTexStorage3D,"Oa":_glTexSubImage2D,"Na":_glTexSubImage3D,"wa":_glUniform1i,"cb":_glUniformBlockBinding,"Jg":_glUnmapBuffer,"K":_glUseProgram,"Va":_glVertexAttrib4f,"Wa":_glVertexAttribI4ui,"Xa":_glVertexAttribIPointer,"ua":_glVertexAttribPointer,"X":_glViewport,"hb":_glWaitSync,"Fa":_pthread_create,"Cg":_pthread_join,"Ba":_setTempRet0,"yg":_strftime_l,"Bg":_sysconf};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["$g"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["ah"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["bh"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["ch"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["dh"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["eh"]).apply(null,arguments)};var dynCall_viijii=Module["dynCall_viijii"]=function(){return(dynCall_viijii=Module["dynCall_viijii"]=Module["asm"]["fh"]).apply(null,arguments)};var dynCall_jii=Module["dynCall_jii"]=function(){return(dynCall_jii=Module["dynCall_jii"]=Module["asm"]["gh"]).apply(null,arguments)};var dynCall_iiij=Module["dynCall_iiij"]=function(){return(dynCall_iiij=Module["dynCall_iiij"]=Module["asm"]["hh"]).apply(null,arguments)};var dynCall_vij=Module["dynCall_vij"]=function(){return(dynCall_vij=Module["dynCall_vij"]=Module["asm"]["ih"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["jh"]).apply(null,arguments)};var dynCall_iiiiij=Module["dynCall_iiiiij"]=function(){return(dynCall_iiiiij=Module["dynCall_iiiiij"]=Module["asm"]["kh"]).apply(null,arguments)};var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=function(){return(dynCall_iiiiijj=Module["dynCall_iiiiijj"]=Module["asm"]["lh"]).apply(null,arguments)};var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=function(){return(dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=Module["asm"]["mh"]).apply(null,arguments)};var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); +var Module=typeof Filament!=="undefined"?Filament:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[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(Module["locateFile"]){return Module["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{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(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);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}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"){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(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;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>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=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=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"):undefined;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 str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>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===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=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=55296&&codeUnit<=57343)++i;len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}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 updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;__ATINIT__.push({func:function(){___wasm_call_ctors()}});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;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;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 addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}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"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}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://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="filament.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){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(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["Zg"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["_g"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var tempDouble;var tempI64;var ASM_CONSTS={10520:function(){const handle=GL.registerContext(Filament.glContext,Filament.glOptions);GL.makeContextCurrent(handle)}};function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){var alignedSize=alignMemory(size,16384);var ptr=_malloc(alignedSize);while(size=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){FS.forceLoadFile(node);var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=varargs?SYSCALLS.get():0;var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var tupleRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}return Module["dynCall_"+sig].call(null,ptr)}function dynCall(sig,ptr,args){if(sig.indexOf("j")!=-1){return dynCallLegacy(sig,ptr,args)}return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){assert(sig.indexOf("j")>=0,"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i>2)+i])}return array}function __embind_register_class_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,fn){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.constructor;if(undefined===proto[methodName]){unboundTypesHandler.argCount=argCount-1;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-1]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));var func=craftInvokerFunction(humanName,invokerArgsArray,null,rawInvoker,fn);if(undefined===proto[methodName].overloadTable){func.argCount=argCount-1;proto[methodName]=func}else{proto[methodName].overloadTable[argCount-1]=func}return[]});return[]})}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>1])};case 2:return function(pointer){var heap=signed?HEAP32:HEAPU32;return this["fromWireType"](heap[pointer>>2])};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_enum(rawType,name,size,isSigned){var shift=getShiftFromSize(size);name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":function(destructors,c){return c.value},"argPackAdvance":8,"readValueFromPointer":enumReadValueFromPointer(name,shift,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __embind_register_enum_value(rawEnumType,name,enumValue){var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(enumType.name+"_"+name,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_array(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){tupleRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),elements:[]}}function __embind_register_value_array_element(rawTupleType,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){tupleRegistrations[rawTupleType].elements.push({getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireHandle(handle){if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value}function __emval_as(handle,returnType,destructorsRef){handle=requireHandle(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=__emval_register(destructors);HEAP32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}function __emval_get_property(handle,key){handle=requireHandle(handle);key=requireHandle(key);return __emval_register(handle[key])}function __emval_incref(handle){if(handle>4){emval_handle_array[handle].refcount+=1}}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function __emval_take_value(type,argv){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](argv);return __emval_register(v)}function _abort(){abort()}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else if(typeof dateNow!=="undefined"){_emscripten_get_now=dateNow}else _emscripten_get_now=function(){return performance.now()};var _emscripten_get_now_is_monotonic=true;function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if((clk_id===1||clk_id===4)&&_emscripten_get_now_is_monotonic){now=_emscripten_get_now()}else{setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}function __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(ctx){return!!(ctx.dibvbi=ctx.getExtension("WEBGL_draw_instanced_base_vertex_base_instance"))}function __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(ctx){return!!(ctx.mdibvbi=ctx.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance"))}function __webgl_enable_WEBGL_multi_draw(ctx){return!!(ctx.multiDrawWebgl=ctx.getExtension("WEBGL_multi_draw"))}var GL={counter:1,buffers:[],mappedBuffers:{},programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},timerQueriesEXT:[],queries:[],samplers:[],transformFeedbacks:[],syncs:[],byteSizeByTypeRoot:5120,byteSizeByType:[1,1,2,2,4,4,4,2,3,4,8],programInfos:{},stringCache:{},stringiCache:{},unpackAlignment:4,recordError:function recordError(errorCode){if(!GL.lastError){GL.lastError=errorCode}},getNewId:function(table){var ret=GL.counter++;for(var i=table.length;i>1;var quadIndexes=new Uint16Array(numIndexes);var i=0,v=0;while(1){quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+1;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v+3;if(i>=numIndexes)break;v+=4}context.GLctx.bufferData(34963,quadIndexes,35044);context.GLctx.bindBuffer(34963,null)}},getTempVertexBuffer:function getTempVertexBuffer(sizeBytes){var idx=GL.log2ceilLookup(sizeBytes);var ringbuffer=GL.currentContext.tempVertexBuffers1[idx];var nextFreeBufferIndex=GL.currentContext.tempVertexBufferCounters1[idx];GL.currentContext.tempVertexBufferCounters1[idx]=GL.currentContext.tempVertexBufferCounters1[idx]+1&GL.numTempVertexBuffersPerSize-1;var vbo=ringbuffer[nextFreeBufferIndex];if(vbo){return vbo}var prevVBO=GLctx.getParameter(34964);ringbuffer[nextFreeBufferIndex]=GLctx.createBuffer();GLctx.bindBuffer(34962,ringbuffer[nextFreeBufferIndex]);GLctx.bufferData(34962,1<>2]:-1;source+=UTF8ToString(HEAP32[string+i*4>>2],len<0?undefined:len)}return source},calcBufLength:function calcBufLength(size,type,stride,count){if(stride>0){return count*stride}var typeSize=GL.byteSizeByType[type-GL.byteSizeByTypeRoot];return size*typeSize*count},usedTempBuffers:[],preDrawHandleClientVertexAttribBindings:function preDrawHandleClientVertexAttribBindings(count){GL.resetBufferBinding=false;for(var i=0;i>2)}function _emscripten_glClearBufferiv(buffer,drawbuffer,value){GLctx["clearBufferiv"](buffer,drawbuffer,HEAP32,value>>2)}function _emscripten_glClearBufferuiv(buffer,drawbuffer,value){GLctx["clearBufferuiv"](buffer,drawbuffer,HEAPU32,value>>2)}function _emscripten_glClearColor(x0,x1,x2,x3){GLctx["clearColor"](x0,x1,x2,x3)}function _emscripten_glClearDepthf(x0){GLctx["clearDepth"](x0)}function _emscripten_glClearStencil(x0){GLctx["clearStencil"](x0)}function convertI32PairToI53(lo,hi){return(lo>>>0)+hi*4294967296}function _emscripten_glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _emscripten_glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _emscripten_glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _emscripten_glCompressedTexImage2D(target,level,internalFormat,width,height,border,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,imageSize,data)}else{GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,HEAPU8,data,imageSize)}return}GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexImage3D(target,level,internalFormat,width,height,depth,border,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexImage3D"](target,level,internalFormat,width,height,depth,border,imageSize,data)}else{GLctx["compressedTexImage3D"](target,level,internalFormat,width,height,depth,border,HEAPU8,data,imageSize)}}function _emscripten_glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,imageSize,data)}else{GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,HEAPU8,data,imageSize)}return}GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data)}else{GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,HEAPU8,data,imageSize)}}function _emscripten_glCopyBufferSubData(x0,x1,x2,x3,x4){GLctx["copyBufferSubData"](x0,x1,x2,x3,x4)}function _emscripten_glCopyTexImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexSubImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage3D(x0,x1,x2,x3,x4,x5,x6,x7,x8){GLctx["copyTexSubImage3D"](x0,x1,x2,x3,x4,x5,x6,x7,x8)}function _emscripten_glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _emscripten_glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _emscripten_glCullFace(x0){GLctx["cullFace"](x0)}function _emscripten_glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _emscripten_glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _emscripten_glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _emscripten_glDeleteQueries(n,ids){for(var i=0;i>2];var query=GL.queries[id];if(!query)continue;GLctx["deleteQuery"](query);GL.queries[id]=null}}function _emscripten_glDeleteQueriesEXT(n,ids){for(var i=0;i>2];var query=GL.timerQueriesEXT[id];if(!query)continue;GLctx.disjointTimerQueryExt["deleteQueryEXT"](query);GL.timerQueriesEXT[id]=null}}function _emscripten_glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _emscripten_glDeleteSamplers(n,samplers){for(var i=0;i>2];var sampler=GL.samplers[id];if(!sampler)continue;GLctx["deleteSampler"](sampler);sampler.name=0;GL.samplers[id]=null}}function _emscripten_glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _emscripten_glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _emscripten_glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _emscripten_glDeleteTransformFeedbacks(n,ids){for(var i=0;i>2];var transformFeedback=GL.transformFeedbacks[id];if(!transformFeedback)continue;GLctx["deleteTransformFeedback"](transformFeedback);transformFeedback.name=0;GL.transformFeedbacks[id]=null}}function _emscripten_glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDeleteVertexArraysOES(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDepthFunc(x0){GLctx["depthFunc"](x0)}function _emscripten_glDepthMask(flag){GLctx.depthMask(!!flag)}function _emscripten_glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _emscripten_glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _emscripten_glDisable(x0){GLctx["disable"](x0)}function _emscripten_glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _emscripten_glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _emscripten_glDrawArraysInstanced(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedANGLE(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedARB(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedEXT(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}function _emscripten_glDrawArraysInstancedNV(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}var tempFixedLengthArray=[];function _emscripten_glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawBuffersEXT(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawBuffersWEBGL(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawElements(mode,count,type,indices){var buf;if(!GLctx.currentElementArrayBufferBinding){var size=GL.calcBufLength(1,type,0,count);buf=GL.getTempIndexBuffer(size);GLctx.bindBuffer(34963,buf);GLctx.bufferSubData(34963,0,HEAPU8.subarray(indices,indices+size));indices=0}GL.preDrawHandleClientVertexAttribBindings(count);GLctx.drawElements(mode,count,type,indices);GL.postDrawHandleClientVertexAttribBindings(count);if(!GLctx.currentElementArrayBufferBinding){GLctx.bindBuffer(34963,null)}}function _emscripten_glDrawElementsInstanced(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedANGLE(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedARB(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedEXT(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glDrawElementsInstancedNV(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _glDrawElements(mode,count,type,indices){var buf;if(!GLctx.currentElementArrayBufferBinding){var size=GL.calcBufLength(1,type,0,count);buf=GL.getTempIndexBuffer(size);GLctx.bindBuffer(34963,buf);GLctx.bufferSubData(34963,0,HEAPU8.subarray(indices,indices+size));indices=0}GL.preDrawHandleClientVertexAttribBindings(count);GLctx.drawElements(mode,count,type,indices);GL.postDrawHandleClientVertexAttribBindings(count);if(!GLctx.currentElementArrayBufferBinding){GLctx.bindBuffer(34963,null)}}function _emscripten_glDrawRangeElements(mode,start,end,count,type,indices){_glDrawElements(mode,count,type,indices)}function _emscripten_glEnable(x0){GLctx["enable"](x0)}function _emscripten_glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _emscripten_glEndQuery(x0){GLctx["endQuery"](x0)}function _emscripten_glEndQueryEXT(target){GLctx.disjointTimerQueryExt["endQueryEXT"](target)}function _emscripten_glEndTransformFeedback(){GLctx["endTransformFeedback"]()}function _emscripten_glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _emscripten_glFinish(){GLctx["finish"]()}function _emscripten_glFlush(){GLctx["flush"]()}function emscriptenWebGLGetBufferBinding(target){switch(target){case 34962:target=34964;break;case 34963:target=34965;break;case 35051:target=35053;break;case 35052:target=35055;break;case 35982:target=35983;break;case 36662:target=36662;break;case 36663:target=36663;break;case 35345:target=35368;break}var buffer=GLctx.getParameter(target);if(buffer)return buffer.name|0;else return 0}function emscriptenWebGLValidateMapBufferTarget(target){switch(target){case 34962:case 34963:case 36662:case 36663:case 35051:case 35052:case 35882:case 35982:case 35345:return true;default:return false}}function _emscripten_glFlushMappedBufferRange(target,offset,length){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glFlushMappedBufferRange");return}var mapping=GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glFlushMappedBufferRange");return}if(!(mapping.access&16)){GL.recordError(1282);err("buffer was not mapped with GL_MAP_FLUSH_EXPLICIT_BIT in glFlushMappedBufferRange");return}if(offset<0||length<0||offset+length>mapping.length){GL.recordError(1281);err("invalid range in glFlushMappedBufferRange");return}GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem+offset,mapping.mem+offset+length))}function _emscripten_glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _emscripten_glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _emscripten_glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function _emscripten_glFrontFace(x0){GLctx["frontFace"](x0)}function __glGenObject(n,buffers,createFunction,objectTable){for(var i=0;i>2]=id}}function _emscripten_glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _emscripten_glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _emscripten_glGenQueries(n,ids){__glGenObject(n,ids,"createQuery",GL.queries)}function _emscripten_glGenQueriesEXT(n,ids){for(var i=0;i>2]=0;return}var id=GL.getNewId(GL.timerQueriesEXT);query.name=id;GL.timerQueriesEXT[id]=query;HEAP32[ids+i*4>>2]=id}}function _emscripten_glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _emscripten_glGenSamplers(n,samplers){__glGenObject(n,samplers,"createSampler",GL.samplers)}function _emscripten_glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _emscripten_glGenTransformFeedbacks(n,ids){__glGenObject(n,ids,"createTransformFeedback",GL.transformFeedbacks)}function _emscripten_glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenVertexArraysOES(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function __glGetActiveAttribOrUniform(funcName,program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx[funcName](program,index);if(info){var numBytesWrittenExclNull=name&&stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull;if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}}function _emscripten_glGetActiveAttrib(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveAttrib",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniform(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveUniform",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniformBlockName(program,uniformBlockIndex,bufSize,length,uniformBlockName){program=GL.programs[program];var result=GLctx["getActiveUniformBlockName"](program,uniformBlockIndex);if(!result)return;if(uniformBlockName&&bufSize>0){var numBytesWrittenExclNull=stringToUTF8(result,uniformBlockName,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull}else{if(length)HEAP32[length>>2]=0}}function _emscripten_glGetActiveUniformBlockiv(program,uniformBlockIndex,pname,params){if(!params){GL.recordError(1281);return}program=GL.programs[program];switch(pname){case 35393:var name=GLctx["getActiveUniformBlockName"](program,uniformBlockIndex);HEAP32[params>>2]=name.length+1;return;default:var result=GLctx["getActiveUniformBlockParameter"](program,uniformBlockIndex,pname);if(!result)return;if(typeof result=="number"){HEAP32[params>>2]=result}else{for(var i=0;i>2]=result[i]}}}}function _emscripten_glGetActiveUniformsiv(program,uniformCount,uniformIndices,pname,params){if(!params){GL.recordError(1281);return}if(uniformCount>0&&uniformIndices==0){GL.recordError(1281);return}program=GL.programs[program];var ids=[];for(var i=0;i>2])}var result=GLctx["getActiveUniforms"](program,ids,pname);if(!result)return;var len=result.length;for(var i=0;i>2]=result[i]}}function _emscripten_glGetAttachedShaders(program,maxCount,count,shaders){var result=GLctx.getAttachedShaders(GL.programs[program]);var len=result.length;if(len>maxCount){len=maxCount}HEAP32[count>>2]=len;for(var i=0;i>2]=id}}function _emscripten_glGetAttribLocation(program,name){return GLctx.getAttribLocation(GL.programs[program],UTF8ToString(name))}function writeI53ToI64(ptr,num){HEAPU32[ptr>>2]=num;HEAPU32[ptr+4>>2]=(num-HEAPU32[ptr>>2])/4294967296}function emscriptenWebGLGet(name_,p,type){if(!p){GL.recordError(1281);return}var ret=undefined;switch(name_){case 36346:ret=1;break;case 36344:if(type!=0&&type!=1){GL.recordError(1280)}return;case 34814:case 36345:ret=0;break;case 34466:var formats=GLctx.getParameter(34467);ret=formats?formats.length:0;break;case 33309:if(GL.currentContext.version<2){GL.recordError(1282);return}var exts=GLctx.getSupportedExtensions()||[];ret=2*exts.length;break;case 33307:case 33308:if(GL.currentContext.version<2){GL.recordError(1280);return}ret=name_==33307?3:0;break}if(ret===undefined){var result=GLctx.getParameter(name_);switch(typeof result){case"number":ret=result;break;case"boolean":ret=result?1:0;break;case"string":GL.recordError(1280);return;case"object":if(result===null){switch(name_){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:{ret=0;break}default:{GL.recordError(1280);return}}}else if(result instanceof Float32Array||result instanceof Uint32Array||result instanceof Int32Array||result instanceof Array){for(var i=0;i>2]=result[i];break;case 2:HEAPF32[p+i*4>>2]=result[i];break;case 4:HEAP8[p+i>>0]=result[i]?1:0;break}}return}else{try{ret=result.name|0}catch(e){GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Unknown object returned from WebGL getParameter("+name_+")! (error: "+e+")");return}}break;default:GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Native code calling glGet"+type+"v("+name_+") and it returns "+result+" of type "+typeof result+"!");return}}switch(type){case 1:writeI53ToI64(p,ret);break;case 0:HEAP32[p>>2]=ret;break;case 2:HEAPF32[p>>2]=ret;break;case 4:HEAP8[p>>0]=ret?1:0;break}}function _emscripten_glGetBooleanv(name_,p){emscriptenWebGLGet(name_,p,4)}function _emscripten_glGetBufferParameteri64v(target,value,data){if(!data){GL.recordError(1281);return}writeI53ToI64(data,GLctx.getBufferParameter(target,value))}function _emscripten_glGetBufferParameteriv(target,value,data){if(!data){GL.recordError(1281);return}HEAP32[data>>2]=GLctx.getBufferParameter(target,value)}function _emscripten_glGetBufferPointerv(target,pname,params){if(pname==35005){var ptr=0;var mappedBuffer=GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)];if(mappedBuffer){ptr=mappedBuffer.mem}HEAP32[params>>2]=ptr}else{GL.recordError(1280);err("GL_INVALID_ENUM in glGetBufferPointerv")}}function _emscripten_glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _emscripten_glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _emscripten_glGetFragDataLocation(program,name){return GLctx["getFragDataLocation"](GL.programs[program],UTF8ToString(name))}function _emscripten_glGetFramebufferAttachmentParameteriv(target,attachment,pname,params){var result=GLctx.getFramebufferAttachmentParameter(target,attachment,pname);if(result instanceof WebGLRenderbuffer||result instanceof WebGLTexture){result=result.name|0}HEAP32[params>>2]=result}function emscriptenWebGLGetIndexed(target,index,data,type){if(!data){GL.recordError(1281);return}var result=GLctx["getIndexedParameter"](target,index);var ret;switch(typeof result){case"boolean":ret=result?1:0;break;case"number":ret=result;break;case"object":if(result===null){switch(target){case 35983:case 35368:ret=0;break;default:{GL.recordError(1280);return}}}else if(result instanceof WebGLBuffer){ret=result.name|0}else{GL.recordError(1280);return}break;default:GL.recordError(1280);return}switch(type){case 1:writeI53ToI64(data,ret);break;case 0:HEAP32[data>>2]=ret;break;case 2:HEAPF32[data>>2]=ret;break;case 4:HEAP8[data>>0]=ret?1:0;break;default:throw"internal emscriptenWebGLGetIndexed() error, bad type: "+type}}function _emscripten_glGetInteger64i_v(target,index,data){emscriptenWebGLGetIndexed(target,index,data,1)}function _emscripten_glGetInteger64v(name_,p){emscriptenWebGLGet(name_,p,1)}function _emscripten_glGetIntegeri_v(target,index,data){emscriptenWebGLGetIndexed(target,index,data,0)}function _emscripten_glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _emscripten_glGetInternalformativ(target,internalformat,pname,bufSize,params){if(bufSize<0){GL.recordError(1281);return}if(!params){GL.recordError(1281);return}var ret=GLctx["getInternalformatParameter"](target,internalformat,pname);if(ret===null)return;for(var i=0;i>2]=ret[i]}}function _emscripten_glGetProgramBinary(program,bufSize,length,binaryFormat,binary){GL.recordError(1282)}function _emscripten_glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _emscripten_glGetQueryObjecti64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectui64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectuiv(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.queries[id];var param=GLctx["getQueryParameter"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectuivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryiv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx["getQuery"](target,pname)}function _emscripten_glGetQueryivEXT(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.disjointTimerQueryExt["getQueryEXT"](target,pname)}function _emscripten_glGetRenderbufferParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getRenderbufferParameter(target,pname)}function _emscripten_glGetSamplerParameterfv(sampler,pname,params){if(!params){GL.recordError(1281);return}sampler=GL.samplers[sampler];HEAPF32[params>>2]=GLctx["getSamplerParameter"](sampler,pname)}function _emscripten_glGetSamplerParameteriv(sampler,pname,params){if(!params){GL.recordError(1281);return}sampler=GL.samplers[sampler];HEAP32[params>>2]=GLctx["getSamplerParameter"](sampler,pname)}function _emscripten_glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderPrecisionFormat(shaderType,precisionType,range,precision){var result=GLctx.getShaderPrecisionFormat(shaderType,precisionType);HEAP32[range>>2]=result.rangeMin;HEAP32[range+4>>2]=result.rangeMax;HEAP32[precision>>2]=result.precision}function _emscripten_glGetShaderSource(shader,bufSize,length,source){var result=GLctx.getShaderSource(GL.shaders[shader]);if(!result)return;var numBytesWrittenExclNull=bufSize>0&&source?stringToUTF8(result,source,bufSize):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function stringToNewUTF8(jsString){var length=lengthBytesUTF8(jsString)+1;var cString=_malloc(length);stringToUTF8(jsString,cString,length);return cString}function _emscripten_glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(true)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _emscripten_glGetStringi(name,index){if(GL.currentContext.version<2){GL.recordError(1282);return 0}var stringiCache=GL.stringiCache[name];if(stringiCache){if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index]}switch(name){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));exts=exts.map(function(e){return stringToNewUTF8(e)});stringiCache=GL.stringiCache[name]=exts;if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index];default:GL.recordError(1280);return 0}}function _emscripten_glGetSynciv(sync,pname,bufSize,length,values){if(bufSize<0){GL.recordError(1281);return}if(!values){GL.recordError(1281);return}var ret=GLctx.getSyncParameter(GL.syncs[sync],pname);HEAP32[length>>2]=ret;if(ret!==null&&length)HEAP32[length>>2]=1}function _emscripten_glGetTexParameterfv(target,pname,params){if(!params){GL.recordError(1281);return}HEAPF32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTexParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTransformFeedbackVarying(program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx["getTransformFeedbackVarying"](program,index);if(!info)return;if(name&&bufSize>0){var numBytesWrittenExclNull=stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull}else{if(length)HEAP32[length>>2]=0}if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}function _emscripten_glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function _emscripten_glGetUniformIndices(program,uniformCount,uniformNames,uniformIndices){if(!uniformIndices){GL.recordError(1281);return}if(uniformCount>0&&(uniformNames==0||uniformIndices==0)){GL.recordError(1281);return}program=GL.programs[program];var names=[];for(var i=0;i>2]));var result=GLctx["getUniformIndices"](program,names);if(!result)return;var len=result.length;for(var i=0;i>2]=result[i]}}function jstoi_q(str){return parseInt(str)}function _emscripten_glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]=data;break;case 2:HEAPF32[params>>2]=data;break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break}}}}function _emscripten_glGetUniformfv(program,location,params){emscriptenWebGLGetUniform(program,location,params,2)}function _emscripten_glGetUniformiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function _emscripten_glGetUniformuiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function emscriptenWebGLGetVertexAttrib(index,pname,params,type){if(!params){GL.recordError(1281);return}if(GL.currentContext.clientBuffers[index].enabled){err("glGetVertexAttrib*v on client-side array: not supported, bad data returned")}var data=GLctx.getVertexAttrib(index,pname);if(pname==34975){HEAP32[params>>2]=data&&data["name"]}else if(typeof data=="number"||typeof data=="boolean"){switch(type){case 0:HEAP32[params>>2]=data;break;case 2:HEAPF32[params>>2]=data;break;case 5:HEAP32[params>>2]=Math.fround(data);break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break;case 5:HEAP32[params+i*4>>2]=Math.fround(data[i]);break}}}}function _emscripten_glGetVertexAttribIiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,0)}function _emscripten_glGetVertexAttribIuiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,0)}function _emscripten_glGetVertexAttribPointerv(index,pname,pointer){if(!pointer){GL.recordError(1281);return}if(GL.currentContext.clientBuffers[index].enabled){err("glGetVertexAttribPointer on client-side array: not supported, bad data returned")}HEAP32[pointer>>2]=GLctx.getVertexAttribOffset(index,pname)}function _emscripten_glGetVertexAttribfv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,2)}function _emscripten_glGetVertexAttribiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,5)}function _emscripten_glHint(x0,x1){GLctx["hint"](x0,x1)}function _emscripten_glInvalidateFramebuffer(target,numAttachments,attachments){var list=tempFixedLengthArray[numAttachments];for(var i=0;i>2]}GLctx["invalidateFramebuffer"](target,list)}function _emscripten_glInvalidateSubFramebuffer(target,numAttachments,attachments,x,y,width,height){var list=tempFixedLengthArray[numAttachments];for(var i=0;i>2]}GLctx["invalidateSubFramebuffer"](target,list,x,y,width,height)}function _emscripten_glIsBuffer(buffer){var b=GL.buffers[buffer];if(!b)return 0;return GLctx.isBuffer(b)}function _emscripten_glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _emscripten_glIsFramebuffer(framebuffer){var fb=GL.framebuffers[framebuffer];if(!fb)return 0;return GLctx.isFramebuffer(fb)}function _emscripten_glIsProgram(program){program=GL.programs[program];if(!program)return 0;return GLctx.isProgram(program)}function _emscripten_glIsQuery(id){var query=GL.queries[id];if(!query)return 0;return GLctx["isQuery"](query)}function _emscripten_glIsQueryEXT(id){var query=GL.timerQueriesEXT[id];if(!query)return 0;return GLctx.disjointTimerQueryExt["isQueryEXT"](query)}function _emscripten_glIsRenderbuffer(renderbuffer){var rb=GL.renderbuffers[renderbuffer];if(!rb)return 0;return GLctx.isRenderbuffer(rb)}function _emscripten_glIsSampler(id){var sampler=GL.samplers[id];if(!sampler)return 0;return GLctx["isSampler"](sampler)}function _emscripten_glIsShader(shader){var s=GL.shaders[shader];if(!s)return 0;return GLctx.isShader(s)}function _emscripten_glIsSync(sync){return GLctx.isSync(GL.syncs[sync])}function _emscripten_glIsTexture(id){var texture=GL.textures[id];if(!texture)return 0;return GLctx.isTexture(texture)}function _emscripten_glIsTransformFeedback(id){return GLctx["isTransformFeedback"](GL.transformFeedbacks[id])}function _emscripten_glIsVertexArray(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glIsVertexArrayOES(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glLineWidth(x0){GLctx["lineWidth"](x0)}function _emscripten_glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _emscripten_glMapBufferRange(target,offset,length,access){if(access!=26&&access!=10){err("glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER");return 0}if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glMapBufferRange");return 0}var mem=_malloc(length);if(!mem)return 0;GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)]={offset:offset,length:length,mem:mem,access:access};return mem}function _emscripten_glPauseTransformFeedback(){GLctx["pauseTransformFeedback"]()}function _emscripten_glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _emscripten_glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _emscripten_glProgramBinary(program,binaryFormat,binary,length){GL.recordError(1280)}function _emscripten_glProgramParameteri(program,pname,value){GL.recordError(1280)}function _emscripten_glQueryCounterEXT(id,target){GLctx.disjointTimerQueryExt["queryCounterEXT"](GL.timerQueriesEXT[id],target)}function _emscripten_glReadBuffer(x0){GLctx["readBuffer"](x0)}function computeUnpackAlignedImageSize(width,height,sizePerPixel,alignment){function roundedToNextMultipleOf(x,y){return x+y-1&-y}var plainRowSize=width*sizePerPixel;var alignedRowSize=roundedToNextMultipleOf(plainRowSize,alignment);return height*alignedRowSize}function __colorChannelsInGlTextureFormat(format){var colorChannels={5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4};return colorChannels[format-6402]||1}function heapObjectForWebGLType(type){type-=5120;if(type==0)return HEAP8;if(type==1)return HEAPU8;if(type==2)return HEAP16;if(type==4)return HEAP32;if(type==6)return HEAPF32;if(type==5||type==28922||type==28520||type==30779||type==30782)return HEAPU32;return HEAPU16}function heapAccessShiftForWebGLHeap(heap){return 31-Math.clz32(heap.BYTES_PER_ELEMENT)}function emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat){var heap=heapObjectForWebGLType(type);var shift=heapAccessShiftForWebGLHeap(heap);var byteSize=1<>shift,pixels+bytes>>shift)}function _emscripten_glReadPixels(x,y,width,height,format,type,pixels){if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _emscripten_glReleaseShaderCompiler(){}function _emscripten_glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _emscripten_glRenderbufferStorageMultisample(x0,x1,x2,x3,x4){GLctx["renderbufferStorageMultisample"](x0,x1,x2,x3,x4)}function _emscripten_glResumeTransformFeedback(){GLctx["resumeTransformFeedback"]()}function _emscripten_glSampleCoverage(value,invert){GLctx.sampleCoverage(value,!!invert)}function _emscripten_glSamplerParameterf(sampler,pname,param){GLctx["samplerParameterf"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameterfv(sampler,pname,params){var param=HEAPF32[params>>2];GLctx["samplerParameterf"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameteri(sampler,pname,param){GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _emscripten_glSamplerParameteriv(sampler,pname,params){var param=HEAP32[params>>2];GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _emscripten_glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _emscripten_glShaderBinary(){GL.recordError(1280)}function _emscripten_glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _emscripten_glStencilFunc(x0,x1,x2){GLctx["stencilFunc"](x0,x1,x2)}function _emscripten_glStencilFuncSeparate(x0,x1,x2,x3){GLctx["stencilFuncSeparate"](x0,x1,x2,x3)}function _emscripten_glStencilMask(x0){GLctx["stencilMask"](x0)}function _emscripten_glStencilMaskSeparate(x0,x1){GLctx["stencilMaskSeparate"](x0,x1)}function _emscripten_glStencilOp(x0,x1,x2){GLctx["stencilOp"](x0,x1,x2)}function _emscripten_glStencilOpSeparate(x0,x1,x2,x3){GLctx["stencilOpSeparate"](x0,x1,x2,x3)}function _emscripten_glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,null)}return}GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels?emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat):null)}function _emscripten_glTexImage3D(target,level,internalFormat,width,height,depth,border,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texImage3D"](target,level,internalFormat,width,height,depth,border,format,type,null)}}function _emscripten_glTexParameterf(x0,x1,x2){GLctx["texParameterf"](x0,x1,x2)}function _emscripten_glTexParameterfv(target,pname,params){var param=HEAPF32[params>>2];GLctx.texParameterf(target,pname,param)}function _emscripten_glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _emscripten_glTexParameteriv(target,pname,params){var param=HEAP32[params>>2];GLctx.texParameteri(target,pname,param)}function _emscripten_glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _emscripten_glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _emscripten_glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _emscripten_glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function _emscripten_glTransformFeedbackVaryings(program,count,varyings,bufferMode){program=GL.programs[program];var vars=[];for(var i=0;i>2]));GLctx["transformFeedbackVaryings"](program,vars,bufferMode)}function _emscripten_glUniform1f(location,v0){GLctx.uniform1f(GL.uniforms[location],v0)}function _emscripten_glUniform1fv(location,count,value){GLctx.uniform1fv(GL.uniforms[location],HEAPF32,value>>2,count)}function _emscripten_glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}function _emscripten_glUniform1iv(location,count,value){GLctx.uniform1iv(GL.uniforms[location],HEAP32,value>>2,count)}function _emscripten_glUniform1ui(location,v0){GLctx.uniform1ui(GL.uniforms[location],v0)}function _emscripten_glUniform1uiv(location,count,value){GLctx.uniform1uiv(GL.uniforms[location],HEAPU32,value>>2,count)}function _emscripten_glUniform2f(location,v0,v1){GLctx.uniform2f(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2fv(location,count,value){GLctx.uniform2fv(GL.uniforms[location],HEAPF32,value>>2,count*2)}function _emscripten_glUniform2i(location,v0,v1){GLctx.uniform2i(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2iv(location,count,value){GLctx.uniform2iv(GL.uniforms[location],HEAP32,value>>2,count*2)}function _emscripten_glUniform2ui(location,v0,v1){GLctx.uniform2ui(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2uiv(location,count,value){GLctx.uniform2uiv(GL.uniforms[location],HEAPU32,value>>2,count*2)}function _emscripten_glUniform3f(location,v0,v1,v2){GLctx.uniform3f(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3fv(location,count,value){GLctx.uniform3fv(GL.uniforms[location],HEAPF32,value>>2,count*3)}function _emscripten_glUniform3i(location,v0,v1,v2){GLctx.uniform3i(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3iv(location,count,value){GLctx.uniform3iv(GL.uniforms[location],HEAP32,value>>2,count*3)}function _emscripten_glUniform3ui(location,v0,v1,v2){GLctx.uniform3ui(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3uiv(location,count,value){GLctx.uniform3uiv(GL.uniforms[location],HEAPU32,value>>2,count*3)}function _emscripten_glUniform4f(location,v0,v1,v2,v3){GLctx.uniform4f(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4fv(location,count,value){GLctx.uniform4fv(GL.uniforms[location],HEAPF32,value>>2,count*4)}function _emscripten_glUniform4i(location,v0,v1,v2,v3){GLctx.uniform4i(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4iv(location,count,value){GLctx.uniform4iv(GL.uniforms[location],HEAP32,value>>2,count*4)}function _emscripten_glUniform4ui(location,v0,v1,v2,v3){GLctx.uniform4ui(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4uiv(location,count,value){GLctx.uniform4uiv(GL.uniforms[location],HEAPU32,value>>2,count*4)}function _emscripten_glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _emscripten_glUniformMatrix2fv(location,count,transpose,value){GLctx.uniformMatrix2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*4)}function _emscripten_glUniformMatrix2x3fv(location,count,transpose,value){GLctx.uniformMatrix2x3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*6)}function _emscripten_glUniformMatrix2x4fv(location,count,transpose,value){GLctx.uniformMatrix2x4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*8)}function _emscripten_glUniformMatrix3fv(location,count,transpose,value){GLctx.uniformMatrix3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*9)}function _emscripten_glUniformMatrix3x2fv(location,count,transpose,value){GLctx.uniformMatrix3x2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*6)}function _emscripten_glUniformMatrix3x4fv(location,count,transpose,value){GLctx.uniformMatrix3x4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*12)}function _emscripten_glUniformMatrix4fv(location,count,transpose,value){GLctx.uniformMatrix4fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*16)}function _emscripten_glUniformMatrix4x2fv(location,count,transpose,value){GLctx.uniformMatrix4x2fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*8)}function _emscripten_glUniformMatrix4x3fv(location,count,transpose,value){GLctx.uniformMatrix4x3fv(GL.uniforms[location],!!transpose,HEAPF32,value>>2,count*12)}function _emscripten_glUnmapBuffer(target){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glUnmapBuffer");return 0}var buffer=emscriptenWebGLGetBufferBinding(target);var mapping=GL.mappedBuffers[buffer];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glUnmapBuffer");return 0}GL.mappedBuffers[buffer]=null;if(!(mapping.access&16))if(true){GLctx.bufferSubData(target,mapping.offset,HEAPU8,mapping.mem,mapping.length)}else{GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem,mapping.mem+mapping.length))}_free(mapping.mem);return 1}function _emscripten_glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _emscripten_glValidateProgram(program){GLctx.validateProgram(GL.programs[program])}function _emscripten_glVertexAttrib1f(x0,x1){GLctx["vertexAttrib1f"](x0,x1)}function _emscripten_glVertexAttrib1fv(index,v){GLctx.vertexAttrib1f(index,HEAPF32[v>>2])}function _emscripten_glVertexAttrib2f(x0,x1,x2){GLctx["vertexAttrib2f"](x0,x1,x2)}function _emscripten_glVertexAttrib2fv(index,v){GLctx.vertexAttrib2f(index,HEAPF32[v>>2],HEAPF32[v+4>>2])}function _emscripten_glVertexAttrib3f(x0,x1,x2,x3){GLctx["vertexAttrib3f"](x0,x1,x2,x3)}function _emscripten_glVertexAttrib3fv(index,v){GLctx.vertexAttrib3f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2])}function _emscripten_glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttrib4fv(index,v){GLctx.vertexAttrib4f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2],HEAPF32[v+12>>2])}function _emscripten_glVertexAttribDivisor(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorANGLE(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorARB(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorEXT(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribDivisorNV(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribI4i(x0,x1,x2,x3,x4){GLctx["vertexAttribI4i"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttribI4iv(index,v){GLctx.vertexAttribI4i(index,HEAP32[v>>2],HEAP32[v+4>>2],HEAP32[v+8>>2],HEAP32[v+12>>2])}function _emscripten_glVertexAttribI4ui(x0,x1,x2,x3,x4){GLctx["vertexAttribI4ui"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttribI4uiv(index,v){GLctx.vertexAttribI4ui(index,HEAPU32[v>>2],HEAPU32[v+4>>2],HEAPU32[v+8>>2],HEAPU32[v+12>>2])}function _emscripten_glVertexAttribIPointer(index,size,type,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=false;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribIPointer(index,size,type,stride,ptr)};return}cb.clientside=false;GLctx["vertexAttribIPointer"](index,size,type,stride,ptr)}function _emscripten_glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _emscripten_glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _emscripten_glWaitSync(sync,flags,timeoutLo,timeoutHi){GLctx.waitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){try{var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _environ_sizes_get(penviron_count,penviron_buf_size){try{var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];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 _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _getentropy(buffer,size){if(!_getentropy.randomDevice){_getentropy.randomDevice=getRandomDevice()}for(var i=0;i>0]=_getentropy.randomDevice()}return 0}function _glActiveTexture(x0){GLctx["activeTexture"](x0)}function _glAttachShader(program,shader){GLctx.attachShader(GL.programs[program],GL.shaders[shader])}function _glBeginQuery(target,id){GLctx["beginQuery"](target,GL.queries[id])}function _glBindBuffer(target,buffer){if(target==34962){GLctx.currentArrayBufferBinding=buffer}else if(target==34963){GLctx.currentElementArrayBufferBinding=buffer}if(target==35051){GLctx.currentPixelPackBufferBinding=buffer}else if(target==35052){GLctx.currentPixelUnpackBufferBinding=buffer}GLctx.bindBuffer(target,GL.buffers[buffer])}function _glBindBufferRange(target,index,buffer,offset,ptrsize){GLctx["bindBufferRange"](target,index,GL.buffers[buffer],offset,ptrsize)}function _glBindFramebuffer(target,framebuffer){GLctx.bindFramebuffer(target,GL.framebuffers[framebuffer])}function _glBindRenderbuffer(target,renderbuffer){GLctx.bindRenderbuffer(target,GL.renderbuffers[renderbuffer])}function _glBindSampler(unit,sampler){GLctx["bindSampler"](unit,GL.samplers[sampler])}function _glBindTexture(target,texture){GLctx.bindTexture(target,GL.textures[texture])}function _glBindVertexArray(vao){GLctx["bindVertexArray"](GL.vaos[vao]);var ibo=GLctx.getParameter(34965);GLctx.currentElementArrayBufferBinding=ibo?ibo.name|0:0}function _glBlendEquationSeparate(x0,x1){GLctx["blendEquationSeparate"](x0,x1)}function _glBlendFuncSeparate(x0,x1,x2,x3){GLctx["blendFuncSeparate"](x0,x1,x2,x3)}function _glBlitFramebuffer(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9){GLctx["blitFramebuffer"](x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)}function _glBufferData(target,size,data,usage){if(true){if(data){GLctx.bufferData(target,HEAPU8,usage,data,size)}else{GLctx.bufferData(target,size,usage)}}else{GLctx.bufferData(target,data?HEAPU8.subarray(data,data+size):size,usage)}}function _glBufferSubData(target,offset,size,data){if(true){GLctx.bufferSubData(target,offset,HEAPU8,data,size);return}GLctx.bufferSubData(target,offset,HEAPU8.subarray(data,data+size))}function _glClearBufferfi(x0,x1,x2,x3){GLctx["clearBufferfi"](x0,x1,x2,x3)}function _glClearBufferfv(buffer,drawbuffer,value){GLctx["clearBufferfv"](buffer,drawbuffer,HEAPF32,value>>2)}function _glClearBufferiv(buffer,drawbuffer,value){GLctx["clearBufferiv"](buffer,drawbuffer,HEAP32,value>>2)}function _glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,imageSize,data)}else{GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,HEAPU8,data,imageSize)}return}GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _glCompressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data){if(GLctx.currentPixelUnpackBufferBinding){GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,imageSize,data)}else{GLctx["compressedTexSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,HEAPU8,data,imageSize)}}function _glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _glCullFace(x0){GLctx["cullFace"](x0)}function _glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _glDeleteQueries(n,ids){for(var i=0;i>2];var query=GL.queries[id];if(!query)continue;GLctx["deleteQuery"](query);GL.queries[id]=null}}function _glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _glDeleteSamplers(n,samplers){for(var i=0;i>2];var sampler=GL.samplers[id];if(!sampler)continue;GLctx["deleteSampler"](sampler);sampler.name=0;GL.samplers[id]=null}}function _glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _glDepthFunc(x0){GLctx["depthFunc"](x0)}function _glDepthMask(flag){GLctx.depthMask(!!flag)}function _glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _glDisable(x0){GLctx["disable"](x0)}function _glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}function _glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _glDrawRangeElements(mode,start,end,count,type,indices){_glDrawElements(mode,count,type,indices)}function _glEnable(x0){GLctx["enable"](x0)}function _glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _glEndQuery(x0){GLctx["endQuery"](x0)}function _glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _glFinish(){GLctx["finish"]()}function _glFlush(){GLctx["flush"]()}function _glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function _glFrontFace(x0){GLctx["frontFace"](x0)}function _glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _glGenQueries(n,ids){__glGenObject(n,ids,"createQuery",GL.queries)}function _glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _glGenSamplers(n,samplers){__glGenObject(n,samplers,"createSampler",GL.samplers)}function _glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function _glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _glGetQueryObjectuiv(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.queries[id];var param=GLctx["getQueryParameter"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function _glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(true)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _glGetStringi(name,index){if(GL.currentContext.version<2){GL.recordError(1282);return 0}var stringiCache=GL.stringiCache[name];if(stringiCache){if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index]}switch(name){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));exts=exts.map(function(e){return stringToNewUTF8(e)});stringiCache=GL.stringiCache[name]=exts;if(index<0||index>=stringiCache.length){GL.recordError(1281);return 0}return stringiCache[index];default:GL.recordError(1280);return 0}}function _glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function _glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]}GLctx["invalidateFramebuffer"](target,list)}function _glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _glMapBufferRange(target,offset,length,access){if(access!=26&&access!=10){err("glMapBufferRange is only supported when access is MAP_WRITE|INVALIDATE_BUFFER");return 0}if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glMapBufferRange");return 0}var mem=_malloc(length);if(!mem)return 0;GL.mappedBuffers[emscriptenWebGLGetBufferBinding(target)]={offset:offset,length:length,mem:mem,access:access};return mem}function _glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _glReadPixels(x,y,width,height,format,type,pixels){if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _glRenderbufferStorageMultisample(x0,x1,x2,x3,x4){GLctx["renderbufferStorageMultisample"](x0,x1,x2,x3,x4)}function _glSamplerParameteri(sampler,pname,param){GLctx["samplerParameteri"](GL.samplers[sampler],pname,param)}function _glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function _glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}function _glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _glUnmapBuffer(target){if(!emscriptenWebGLValidateMapBufferTarget(target)){GL.recordError(1280);err("GL_INVALID_ENUM in glUnmapBuffer");return 0}var buffer=emscriptenWebGLGetBufferBinding(target);var mapping=GL.mappedBuffers[buffer];if(!mapping){GL.recordError(1282);err("buffer was never mapped in glUnmapBuffer");return 0}GL.mappedBuffers[buffer]=null;if(!(mapping.access&16))if(true){GLctx.bufferSubData(target,mapping.offset,HEAPU8,mapping.mem,mapping.length)}else{GLctx.bufferSubData(target,mapping.offset,HEAPU8.subarray(mapping.mem,mapping.mem+mapping.length))}_free(mapping.mem);return 1}function _glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _glVertexAttribI4ui(x0,x1,x2,x3,x4){GLctx["vertexAttribI4ui"](x0,x1,x2,x3,x4)}function _glVertexAttribIPointer(index,size,type,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=false;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribIPointer(index,size,type,stride,ptr)};return}cb.clientside=false;GLctx["vertexAttribIPointer"](index,size,type,stride,ptr)}function _glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _glWaitSync(sync,flags,timeoutLo,timeoutHi){GLctx.waitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _pthread_create(){return 6}function _pthread_join(){return 28}function _setTempRet0($i){setTempRet0($i|0)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.indexOf(rule)>=0){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm){return _strftime(s,maxsize,format,tm)}function _sysconf(name){switch(name){case 30:return 16384;case 85:var maxHeapSize=2147483648;return maxHeapSize/16384;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:case 80:case 81:case 79:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}setErrNo(28);return-1}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){var double=ch<105;if(double&&buf&1)buf++;readAsmConstArgsArray.push(double?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var GLctx;for(var i=0;i<32;++i)tempFixedLengthArray.push(new Array(i));function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var asmLibraryArg={"Ga":___sys_fcntl64,"Bg":___sys_ioctl,"Cg":___sys_open,"v":__embind_finalize_value_array,"A":__embind_finalize_value_object,"Fg":__embind_register_bool,"e":__embind_register_class,"k":__embind_register_class_class_function,"n":__embind_register_class_constructor,"a":__embind_register_class_function,"u":__embind_register_class_property,"Eg":__embind_register_emval,"i":__embind_register_enum,"b":__embind_register_enum_value,"Ia":__embind_register_float,"Ka":__embind_register_function,"D":__embind_register_integer,"y":__embind_register_memory_view,"Ja":__embind_register_std_string,"la":__embind_register_std_wstring,"x":__embind_register_value_array,"f":__embind_register_value_array_element,"B":__embind_register_value_object,"d":__embind_register_value_object_field,"Gg":__embind_register_void,"q":__emval_as,"g":__emval_decref,"r":__emval_get_property,"ja":__emval_incref,"H":__emval_new_cstring,"p":__emval_run_destructors,"s":__emval_take_value,"c":_abort,"ug":_clock_gettime,"rg":_emscripten_asm_const_int,"Zf":_emscripten_glActiveTexture,"Yf":_emscripten_glAttachShader,"$c":_emscripten_glBeginQuery,"ng":_emscripten_glBeginQueryEXT,"Dc":_emscripten_glBeginTransformFeedback,"Xf":_emscripten_glBindAttribLocation,"Wf":_emscripten_glBindBuffer,"Ac":_emscripten_glBindBufferBase,"Bc":_emscripten_glBindBufferRange,"Vf":_emscripten_glBindFramebuffer,"Uf":_emscripten_glBindRenderbuffer,"Hb":_emscripten_glBindSampler,"Tf":_emscripten_glBindTexture,"zb":_emscripten_glBindTransformFeedback,"Ic":_emscripten_glBindVertexArray,"fg":_emscripten_glBindVertexArrayOES,"Sf":_emscripten_glBlendColor,"Rf":_emscripten_glBlendEquation,"Qf":_emscripten_glBlendEquationSeparate,"Pf":_emscripten_glBlendFunc,"Of":_emscripten_glBlendFuncSeparate,"Oc":_emscripten_glBlitFramebuffer,"Nf":_emscripten_glBufferData,"Mf":_emscripten_glBufferSubData,"Lf":_emscripten_glCheckFramebufferStatus,"Kf":_emscripten_glClear,"dc":_emscripten_glClearBufferfi,"ec":_emscripten_glClearBufferfv,"gc":_emscripten_glClearBufferiv,"fc":_emscripten_glClearBufferuiv,"Jf":_emscripten_glClearColor,"If":_emscripten_glClearDepthf,"Hf":_emscripten_glClearStencil,"Rb":_emscripten_glClientWaitSync,"Gf":_emscripten_glColorMask,"Ff":_emscripten_glCompileShader,"Ef":_emscripten_glCompressedTexImage2D,"ed":_emscripten_glCompressedTexImage3D,"Df":_emscripten_glCompressedTexSubImage2D,"dd":_emscripten_glCompressedTexSubImage3D,"bc":_emscripten_glCopyBufferSubData,"Cf":_emscripten_glCopyTexImage2D,"Bf":_emscripten_glCopyTexSubImage2D,"gd":_emscripten_glCopyTexSubImage3D,"Af":_emscripten_glCreateProgram,"zf":_emscripten_glCreateShader,"yf":_emscripten_glCullFace,"xf":_emscripten_glDeleteBuffers,"wf":_emscripten_glDeleteFramebuffers,"vf":_emscripten_glDeleteProgram,"bd":_emscripten_glDeleteQueries,"pg":_emscripten_glDeleteQueriesEXT,"uf":_emscripten_glDeleteRenderbuffers,"Jb":_emscripten_glDeleteSamplers,"tf":_emscripten_glDeleteShader,"Sb":_emscripten_glDeleteSync,"sf":_emscripten_glDeleteTextures,"yb":_emscripten_glDeleteTransformFeedbacks,"Hc":_emscripten_glDeleteVertexArrays,"eg":_emscripten_glDeleteVertexArraysOES,"rf":_emscripten_glDepthFunc,"qf":_emscripten_glDepthMask,"pf":_emscripten_glDepthRangef,"of":_emscripten_glDetachShader,"nf":_emscripten_glDisable,"mf":_emscripten_glDisableVertexAttribArray,"lf":_emscripten_glDrawArrays,"Wb":_emscripten_glDrawArraysInstanced,"ag":_emscripten_glDrawArraysInstancedANGLE,"ib":_emscripten_glDrawArraysInstancedARB,"nd":_emscripten_glDrawArraysInstancedEXT,"jb":_emscripten_glDrawArraysInstancedNV,"Vc":_emscripten_glDrawBuffers,"ld":_emscripten_glDrawBuffersEXT,"bg":_emscripten_glDrawBuffersWEBGL,"kf":_emscripten_glDrawElements,"Vb":_emscripten_glDrawElementsInstanced,"$f":_emscripten_glDrawElementsInstancedANGLE,"gb":_emscripten_glDrawElementsInstancedARB,"hb":_emscripten_glDrawElementsInstancedEXT,"md":_emscripten_glDrawElementsInstancedNV,"jd":_emscripten_glDrawRangeElements,"jf":_emscripten_glEnable,"hf":_emscripten_glEnableVertexAttribArray,"_c":_emscripten_glEndQuery,"mg":_emscripten_glEndQueryEXT,"Cc":_emscripten_glEndTransformFeedback,"Ub":_emscripten_glFenceSync,"gf":_emscripten_glFinish,"ff":_emscripten_glFlush,"Jc":_emscripten_glFlushMappedBufferRange,"ef":_emscripten_glFramebufferRenderbuffer,"df":_emscripten_glFramebufferTexture2D,"Lc":_emscripten_glFramebufferTextureLayer,"cf":_emscripten_glFrontFace,"bf":_emscripten_glGenBuffers,"$e":_emscripten_glGenFramebuffers,"cd":_emscripten_glGenQueries,"qg":_emscripten_glGenQueriesEXT,"_e":_emscripten_glGenRenderbuffers,"Kb":_emscripten_glGenSamplers,"Ze":_emscripten_glGenTextures,"xb":_emscripten_glGenTransformFeedbacks,"Gc":_emscripten_glGenVertexArrays,"dg":_emscripten_glGenVertexArraysOES,"af":_emscripten_glGenerateMipmap,"Ye":_emscripten_glGetActiveAttrib,"Xe":_emscripten_glGetActiveUniform,"Yb":_emscripten_glGetActiveUniformBlockName,"Zb":_emscripten_glGetActiveUniformBlockiv,"$b":_emscripten_glGetActiveUniformsiv,"We":_emscripten_glGetAttachedShaders,"Ve":_emscripten_glGetAttribLocation,"Ue":_emscripten_glGetBooleanv,"Lb":_emscripten_glGetBufferParameteri64v,"Te":_emscripten_glGetBufferParameteriv,"Wc":_emscripten_glGetBufferPointerv,"Se":_emscripten_glGetError,"Re":_emscripten_glGetFloatv,"pc":_emscripten_glGetFragDataLocation,"Qe":_emscripten_glGetFramebufferAttachmentParameteriv,"Mb":_emscripten_glGetInteger64i_v,"Ob":_emscripten_glGetInteger64v,"Ec":_emscripten_glGetIntegeri_v,"Pe":_emscripten_glGetIntegerv,"mb":_emscripten_glGetInternalformativ,"tb":_emscripten_glGetProgramBinary,"Ne":_emscripten_glGetProgramInfoLog,"Oe":_emscripten_glGetProgramiv,"hg":_emscripten_glGetQueryObjecti64vEXT,"jg":_emscripten_glGetQueryObjectivEXT,"gg":_emscripten_glGetQueryObjectui64vEXT,"Yc":_emscripten_glGetQueryObjectuiv,"ig":_emscripten_glGetQueryObjectuivEXT,"Zc":_emscripten_glGetQueryiv,"kg":_emscripten_glGetQueryivEXT,"Me":_emscripten_glGetRenderbufferParameteriv,"Bb":_emscripten_glGetSamplerParameterfv,"Cb":_emscripten_glGetSamplerParameteriv,"Ke":_emscripten_glGetShaderInfoLog,"Je":_emscripten_glGetShaderPrecisionFormat,"Ie":_emscripten_glGetShaderSource,"Le":_emscripten_glGetShaderiv,"He":_emscripten_glGetString,"cc":_emscripten_glGetStringi,"Nb":_emscripten_glGetSynciv,"Ge":_emscripten_glGetTexParameterfv,"Fe":_emscripten_glGetTexParameteriv,"yc":_emscripten_glGetTransformFeedbackVarying,"_b":_emscripten_glGetUniformBlockIndex,"ac":_emscripten_glGetUniformIndices,"Ce":_emscripten_glGetUniformLocation,"Ee":_emscripten_glGetUniformfv,"De":_emscripten_glGetUniformiv,"qc":_emscripten_glGetUniformuiv,"wc":_emscripten_glGetVertexAttribIiv,"vc":_emscripten_glGetVertexAttribIuiv,"ze":_emscripten_glGetVertexAttribPointerv,"Be":_emscripten_glGetVertexAttribfv,"Ae":_emscripten_glGetVertexAttribiv,"ye":_emscripten_glHint,"qb":_emscripten_glInvalidateFramebuffer,"pb":_emscripten_glInvalidateSubFramebuffer,"xe":_emscripten_glIsBuffer,"we":_emscripten_glIsEnabled,"ve":_emscripten_glIsFramebuffer,"ue":_emscripten_glIsProgram,"ad":_emscripten_glIsQuery,"og":_emscripten_glIsQueryEXT,"te":_emscripten_glIsRenderbuffer,"Ib":_emscripten_glIsSampler,"se":_emscripten_glIsShader,"Tb":_emscripten_glIsSync,"re":_emscripten_glIsTexture,"wb":_emscripten_glIsTransformFeedback,"Fc":_emscripten_glIsVertexArray,"cg":_emscripten_glIsVertexArrayOES,"qe":_emscripten_glLineWidth,"pe":_emscripten_glLinkProgram,"Kc":_emscripten_glMapBufferRange,"vb":_emscripten_glPauseTransformFeedback,"oe":_emscripten_glPixelStorei,"ne":_emscripten_glPolygonOffset,"sb":_emscripten_glProgramBinary,"rb":_emscripten_glProgramParameteri,"lg":_emscripten_glQueryCounterEXT,"kd":_emscripten_glReadBuffer,"me":_emscripten_glReadPixels,"le":_emscripten_glReleaseShaderCompiler,"ke":_emscripten_glRenderbufferStorage,"Nc":_emscripten_glRenderbufferStorageMultisample,"ub":_emscripten_glResumeTransformFeedback,"je":_emscripten_glSampleCoverage,"Eb":_emscripten_glSamplerParameterf,"Db":_emscripten_glSamplerParameterfv,"Gb":_emscripten_glSamplerParameteri,"Fb":_emscripten_glSamplerParameteriv,"ie":_emscripten_glScissor,"he":_emscripten_glShaderBinary,"ge":_emscripten_glShaderSource,"fe":_emscripten_glStencilFunc,"ee":_emscripten_glStencilFuncSeparate,"de":_emscripten_glStencilMask,"ce":_emscripten_glStencilMaskSeparate,"be":_emscripten_glStencilOp,"ae":_emscripten_glStencilOpSeparate,"$d":_emscripten_glTexImage2D,"id":_emscripten_glTexImage3D,"_d":_emscripten_glTexParameterf,"Zd":_emscripten_glTexParameterfv,"Yd":_emscripten_glTexParameteri,"Xd":_emscripten_glTexParameteriv,"ob":_emscripten_glTexStorage2D,"nb":_emscripten_glTexStorage3D,"Wd":_emscripten_glTexSubImage2D,"hd":_emscripten_glTexSubImage3D,"zc":_emscripten_glTransformFeedbackVaryings,"Vd":_emscripten_glUniform1f,"Ud":_emscripten_glUniform1fv,"Td":_emscripten_glUniform1i,"Sd":_emscripten_glUniform1iv,"oc":_emscripten_glUniform1ui,"kc":_emscripten_glUniform1uiv,"Rd":_emscripten_glUniform2f,"Qd":_emscripten_glUniform2fv,"Pd":_emscripten_glUniform2i,"Od":_emscripten_glUniform2iv,"nc":_emscripten_glUniform2ui,"jc":_emscripten_glUniform2uiv,"Nd":_emscripten_glUniform3f,"Md":_emscripten_glUniform3fv,"Kd":_emscripten_glUniform3i,"Jd":_emscripten_glUniform3iv,"mc":_emscripten_glUniform3ui,"ic":_emscripten_glUniform3uiv,"Id":_emscripten_glUniform4f,"Hd":_emscripten_glUniform4fv,"Gd":_emscripten_glUniform4i,"Fd":_emscripten_glUniform4iv,"lc":_emscripten_glUniform4ui,"hc":_emscripten_glUniform4uiv,"Xb":_emscripten_glUniformBlockBinding,"Ed":_emscripten_glUniformMatrix2fv,"Uc":_emscripten_glUniformMatrix2x3fv,"Sc":_emscripten_glUniformMatrix2x4fv,"Dd":_emscripten_glUniformMatrix3fv,"Tc":_emscripten_glUniformMatrix3x2fv,"Qc":_emscripten_glUniformMatrix3x4fv,"Cd":_emscripten_glUniformMatrix4fv,"Rc":_emscripten_glUniformMatrix4x2fv,"Pc":_emscripten_glUniformMatrix4x3fv,"Xc":_emscripten_glUnmapBuffer,"Bd":_emscripten_glUseProgram,"Ad":_emscripten_glValidateProgram,"zd":_emscripten_glVertexAttrib1f,"yd":_emscripten_glVertexAttrib1fv,"xd":_emscripten_glVertexAttrib2f,"wd":_emscripten_glVertexAttrib2fv,"vd":_emscripten_glVertexAttrib3f,"ud":_emscripten_glVertexAttrib3fv,"td":_emscripten_glVertexAttrib4f,"sd":_emscripten_glVertexAttrib4fv,"Ab":_emscripten_glVertexAttribDivisor,"_f":_emscripten_glVertexAttribDivisorANGLE,"kb":_emscripten_glVertexAttribDivisorARB,"od":_emscripten_glVertexAttribDivisorEXT,"lb":_emscripten_glVertexAttribDivisorNV,"uc":_emscripten_glVertexAttribI4i,"sc":_emscripten_glVertexAttribI4iv,"tc":_emscripten_glVertexAttribI4ui,"rc":_emscripten_glVertexAttribI4uiv,"xc":_emscripten_glVertexAttribIPointer,"rd":_emscripten_glVertexAttribPointer,"pd":_emscripten_glViewport,"Qb":_emscripten_glWaitSync,"sg":_emscripten_memcpy_big,"tg":_emscripten_resize_heap,"xg":_environ_get,"yg":_environ_sizes_get,"ka":_fd_close,"Dg":_fd_read,"db":_fd_seek,"Ha":_fd_write,"vg":_getentropy,"h":_glActiveTexture,"V":_glAttachShader,"Yg":_glBeginQuery,"w":_glBindBuffer,"ua":_glBindBufferRange,"m":_glBindFramebuffer,"I":_glBindRenderbuffer,"W":_glBindSampler,"l":_glBindTexture,"G":_glBindVertexArray,"Ug":_glBlendEquationSeparate,"Tg":_glBlendFuncSeparate,"sa":_glBlitFramebuffer,"K":_glBufferData,"T":_glBufferSubData,"Kg":_glClearBufferfi,"P":_glClearBufferfv,"Jg":_glClearBufferiv,"eb":_glClientWaitSync,"Y":_glColorMask,"da":_glCompileShader,"Ma":_glCompressedTexSubImage2D,"La":_glCompressedTexSubImage3D,"Aa":_glCreateProgram,"fa":_glCreateShader,"ma":_glCullFace,"Ca":_glDeleteBuffers,"U":_glDeleteFramebuffers,"ba":_glDeleteProgram,"Ya":_glDeleteQueries,"E":_glDeleteRenderbuffers,"qa":_glDeleteSamplers,"N":_glDeleteShader,"F":_glDeleteSync,"L":_glDeleteTextures,"Pb":_glDeleteVertexArrays,"Sg":_glDepthFunc,"Rg":_glDepthMask,"Wa":_glDepthRangef,"aa":_glDetachShader,"j":_glDisable,"na":_glDisableVertexAttribArray,"Ra":_glDrawArrays,"Ta":_glDrawBuffers,"Ua":_glDrawRangeElements,"C":_glEnable,"pa":_glEnableVertexAttribArray,"Xg":_glEndQuery,"$":_glFenceSync,"Da":_glFinish,"Ea":_glFlush,"Q":_glFramebufferRenderbuffer,"R":_glFramebufferTexture2D,"Pa":_glFramebufferTextureLayer,"Vg":_glFrontFace,"O":_glGenBuffers,"S":_glGenFramebuffers,"Za":_glGenQueries,"ia":_glGenRenderbuffers,"ra":_glGenSamplers,"J":_glGenTextures,"cb":_glGenVertexArrays,"Xa":_glGenerateMipmap,"Sa":_glGetError,"qd":_glGetFloatv,"o":_glGetIntegerv,"$a":_glGetProgramInfoLog,"ya":_glGetProgramiv,"Wg":_glGetQueryObjectuiv,"_a":_glGetShaderInfoLog,"ca":_glGetShaderiv,"X":_glGetString,"Ld":_glGetStringi,"bb":_glGetUniformBlockIndex,"xa":_glGetUniformLocation,"Qa":_glGetVertexAttribiv,"fd":_glHint,"va":_glInvalidateFramebuffer,"Z":_glIsEnabled,"za":_glLinkProgram,"Ig":_glMapBufferRange,"Mc":_glPixelStorei,"Va":_glPolygonOffset,"ta":_glReadPixels,"ga":_glRenderbufferStorage,"ha":_glRenderbufferStorageMultisample,"t":_glSamplerParameteri,"Lg":_glScissor,"ea":_glShaderSource,"z":_glTexParameteri,"Qg":_glTexStorage2D,"Pg":_glTexStorage3D,"Oa":_glTexSubImage2D,"Na":_glTexSubImage3D,"wa":_glUniform1i,"ab":_glUniformBlockBinding,"Hg":_glUnmapBuffer,"M":_glUseProgram,"Mg":_glVertexAttrib4f,"Ng":_glVertexAttribI4ui,"Og":_glVertexAttribIPointer,"oa":_glVertexAttribPointer,"_":_glViewport,"fb":_glWaitSync,"Fa":_pthread_create,"Ag":_pthread_join,"Ba":_setTempRet0,"wg":_strftime_l,"zg":_sysconf};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["$g"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["ah"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["bh"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["ch"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["dh"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["eh"]).apply(null,arguments)};var dynCall_viijii=Module["dynCall_viijii"]=function(){return(dynCall_viijii=Module["dynCall_viijii"]=Module["asm"]["fh"]).apply(null,arguments)};var dynCall_jii=Module["dynCall_jii"]=function(){return(dynCall_jii=Module["dynCall_jii"]=Module["asm"]["gh"]).apply(null,arguments)};var dynCall_iiij=Module["dynCall_iiij"]=function(){return(dynCall_iiij=Module["dynCall_iiij"]=Module["asm"]["hh"]).apply(null,arguments)};var dynCall_vij=Module["dynCall_vij"]=function(){return(dynCall_vij=Module["dynCall_vij"]=Module["asm"]["ih"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["jh"]).apply(null,arguments)};var dynCall_iiiiij=Module["dynCall_iiiiij"]=function(){return(dynCall_iiiiij=Module["dynCall_iiiiij"]=Module["asm"]["kh"]).apply(null,arguments)};var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=function(){return(dynCall_iiiiijj=Module["dynCall_iiiiijj"]=Module["asm"]["lh"]).apply(null,arguments)};var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=function(){return(dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=Module["asm"]["mh"]).apply(null,arguments)};var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); return Filament.ready @@ -441,6 +441,18 @@ Filament.loadClassExtensions = function() { this._setVignetteOptions(options); }; + /// BufferObject ::core class:: + + /// setBuffer ::method:: + /// engine ::argument:: [Engine] + /// buffer ::argument:: asset string, or Uint8Array, or [Buffer] + /// byteOffset ::argument:: non-negative integer + Filament.BufferObject.prototype.setBuffer = function(engine, buffer, byteOffset = 0) { + buffer = getBufferDescriptor(buffer); + this._setBuffer(engine, buffer, byteOffset); + buffer.delete(); + }; + /// VertexBuffer ::core class:: /// setBufferAt ::method:: diff --git a/docs/remote/filament.wasm b/docs/remote/filament.wasm index d50836640b575ea0fd9e5572496b489dd4e18ea3..f890818b5496d77d41c1286c30f1e356b1efc43f 100755 GIT binary patch delta 260756 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

2m;dPRbRX~mt@+y!TLP~%f zB4jm?YC>KEQboubAiD`!3j`Vt-CPF*Dh}Oz9Y_Ts0U+gstOo)mxNg1yq?C|1f%rEN z_7<@9glqt^mXNoBlo0X`kQIb%1hSlvQXq>7*#xARkavL;5%M08LPE-b6cDl*NIoH3 zfJ`CeeIU@Y>1H{QJU?Muf#nji4ajJ~?SP{ID*zt>+yOWOa3|m}zz+Zi16Bgw2lyf2 zAi$3R?*#l9a3J6=zyW}t0QLv`6tExQKLD=++|AI3dIQ-55AdhC7ZB%5&3%B`fK`AU z0Y3w554azYy50dm>U-6IEdUP!`T#!%Oac4?5FOS$1W4DQdx7>F_|HA=eV!hm49314BTaJ%I#3J~TcqTb6j7wOPXz5)nF1>`M`6a%=qofjU zo%IC!pQD?$o{C4Ml>kcFR9x)p>|9R1i$f91Ldkc9&4rjc(*R`hJvSuaR{7vxP^l%2t1I9xq_(%7Da zlj-9VF=0Sm(Bc`uj2}9bOfr!fiMle%p#BLvN?%tIDRthC!gF{Pks7seZ!gh53} zQL(X$7**m_N45m3{5h9l!CEd#FJqlj=aVWG=F%D#P%b(KL8O|lhe+O;(-V10piw8* zNTU@*`_7n+2gHcZtmid(5IxrDhMts%`yghc&u|Y7ZpbZHZp_Q^HCHoVLYR}nta32= zj+Djd=2Ih4j5yPor8m6FO%rj%z?Lsvs$s@p^RAC*p3OSO)Z+VK_bBepW^EdhgWBv2 znWH3|xOR@swE;vno^N&}s%NVAjDZ_Ao7S@#1%$N6IO>dM_3k`Q%Qat=`?``F9H%CjE zT=iKhFxK2&r$Be>@HmfwPx$~z#UZg0`8K7gjGD&8V#=Z>Q~Z$Iy(2;EEROVG7rUlo zM@#S=)*vf(4*nXnU-dv1-6@prt49n= z-`Bvb!7~2PblulQtm@4+Xzv7uUdhrlt%Z2L4{Io1?ZYlfHS$oRqR9}|jZ6W7r5E~+{v3ov_0*eptU=1;GC3%3WTTna=qgZmHtJ9Rw)DSt{ z`Y!zsA!&w1l7o~Lgu5WxsIqtqcdko|#ff~=Cl+4K27<|cyqY}=J|6QY*2vr32Q^^C zGWn%Hv3s=pMBFv3osLy=*K1glo>$PP_+WFf3Az}di98Kd$C&!{U>Wj5HDMhV#V&~e{f#o>lklnx3HVU!GrEAsng_ZV$8Kr ztle}StJf$PfgeHlLHkdG1r9F|PhZEbM8WS}$EKlCZn_>aCSN>yJ-bq0z{KURK-TQP zo?V8s?)Ce#OIR=$;wnV%&w4ko{Zb*ra24z#9Tk3=Ska$dM+%*Lhp~onRZ`D{?R=4Z z18d{1lJX85Z|)ZTZ$Kxi77yRRW*~YX=0?_0t6R*~H?hHW{Wjjj`hwD!0j#wb4-w*X zal34DS~U@2JqEBwq!$9COKCIE>jdLt@@fSSAHcdK*mS%31MXb0^A46Ib`F4UEMFWL zz!IZplChms!K5V?OWP>SBA|PrQ3%qz*yDERQK~d?+s(|~EZ;+`ebvb@fkY?e$igWn z7ZPEOXrVK5` z-2+*QB0cE>rS8$GvJ%D4fy@ow*^3nZTzStca?69pl;(>xr_O~UU=DQ-kCl5{kddwr z09AOT#W5sRN@AKqDP7%frG-XVss$kfiP)yp`(oi`axwfiHps5=3-GSZ@u0c|D!^&A zwcW_53Z=O6p+17moqU1jE7jGYBWnR#PAeb#lcf3|wXs2Ly`5$1TVlmKU0Fkj8+He4 zI=H3Xds|WyBwC+CVhj~Totb(u0AJ;=J0bh5l!!E@W$ z5OEIoqr!VFOT1U6lA1;=LFGgmUx;Rv-B@NUi^H4%Qypq>8Z(q$TFz1-pr!T!mzHKZ zCSZC!1Ur5sx&n2(KfxXkeMAeeeC1uNiU0rKq{byDHE3l_YAifTl21Re_Lp<}%VGYB z*T1P|tdnNI#IU>BMPk`q*hu?>2%>2Wi3GbT{vCp_w^!1KH5MiJumsTc`rWLJ_KrAs zH#1XP&{PG|4J!y-s>!qD+5=x?eWMFad)M6%=l9(M0hBMs+{3y9ymJq`J!&&q3=3@# z7H4JRvO%l|#thYOssE&+EBkN(PFvz7GhgHnVlA$H0y`3NjYrFOAM}Y3N>ZVYRR0;DAZCYN12I_n2C?_Byst@_|SYY_+Bh7Hj5AM#ZF0? z`1)Qp3!Zs@W?kXA@z2=dC=>ht%=(1rM?)rpVt9%tc9A;nAfZ^F zpP$ed|H3ZLOd?LPC?sV#x7_@GcUZT{LARM~3o)E$pqaB2iDe?;K9*b`IwbN$T@9v- zsI0N2`+Y2pKOjeyu=;-RKGp>EP5}t+Io46yV_tV&dhHLg_Eu=m@yLDblHLyxPe8#= z?;SX-F%>tOQdgy|*|0@MQ0x+|_0ybcQIFbrQQZAk)~Mm4Mzk#zk|8t}x@U>!{>m=) zmq0|2rpSjy+EtcP1}Y@TnVg|`p1|^`wt};j&c<@Jw_KH$E8TLHTP~mFDz#jR(nSUE z&Q4N}g{@4)Wq)I-*}0k;lS$1WxfHxC^_>zz-+&<$-vgZju5lij>eA72S&k>gygfva~m72m{M4l!#4`!D#G^--*xTZyk(_qVvM1WKgk#ds4<^GOb=0-yv z$!5V=i28bjEF=7VP`J4M0oKTG4IWyW6XSClCdi>REFS;B8Wu{@M7e|o;yZW!3QtDWQ5210Q5pggF;H$QmYw36|~HJUP=HYTT z__5*a@&R>nht3WKV2KrXVdY+MM!Y(Lr8T}#c%ck$=Orajky1CsV4t=~oEX9G>bRd&u;Z~U zndQhvFXqyn2Y0%jZaKzDM zN|_mD&Ci`?3h94zGQuFXPN8`K;V3c%D{-mZz|M9I2_l>ej>E+MYAZT0#BCv!x5E1n z%WF2jk-aXqw&X1lQz>`*)Ae0q?L%ykyHc)-(YehE(d=RH+%D1cVRi~vO?Q5TeXPAD z+>grk&3u$4^R?K1Hbn!o>Znp9-})%K%Ku-gChDuO;gIuf>d!n=c3;|PC8Z+WUr444 z#dZY}d&WLY5);0`Y9$G53nV{{g|z7T4cRT%LDjQ$GAoEhZCwn*08rzhiX1Z37e|bW zYQ>Wos8g%1err`k&Eku*CQmV#JS}((ii{m%(_`!wQhmrqhpi17$dYx`b=yA923%(| zfE1Zho9&{}1?2R%7Dd0R(uO>Q0-5@wQfXH_&bqsx(%vjQquAeR9I*NZnG?WbhN@?x zVmWl_iKr>w3iXZUD6Ipby_}Lr!vP81@X=n1VwlU2*p->sszYRg?uyJUu}ifOCU)_R zyiyjD+(o_!PsbQZd;C;rrs@-x)Wjrag3?G5UDae)U=2mGb&xJaY2CwA@pNKFsp93B zw*p^msklL!xbg|cJCkzW2{pPLT7mF1?9jEr9x7ev4g|ZZQFq8?vM(x|T#!`RP2{P{^X)v{a4J4E(V$>QRt7_LDIIa0)qCM=$OWy3|ff6=*8fw3v#eGk+ zVJcyY_~vPLz3BH02C`Lwq0g{Jdh((8RD3GYF@H2LFPB}fYcs^xV_A}W zF?O5yk1mHB=ij{Jpzcpfg1v=IiYmkUtp$3gmaY4I4sm}TYoRYbBc|qI2L6&L&tpw4 zU+W%1lK_Xg5vrz_o$j`BI3ndWN_VAUmr(955j&!-Nb$86w_+nQrm(Mw?&DdL)|V2G zq(O|7HRLI%_bkk-a?Jcj%8?2OZ6}G`@vLFrj+Ac-ZzZ+FKv7ek?jkI^$v(=5H=JM}g*)7^qbFy!9FFC-1GY+LvF$+BTSc~)Q*zAO#m;A0vj1Wt zA4K8?d445I)6Hko0gx;2Eg@NY$WP_?R2RIQ{9a@%r-*Q&cFEqf4`nW=DY3j$5cgPk zEN@L-9t&{ZS*EH_YLP~7V5y?MMZ-}Dm0e%qpTMs3*X$2|7fe^|PodfB>RCGPMmylN zn+~Z#2Ivmnm5PbwT_iBa2sAB?ec4D*VkaOmMhT$UR0%v*0#8H&j>+lumX(&wvt8In zSvbF5dYNPGVy=^J-pcYW1iAcLl+n-r+DtKbBG?s|vlGY{-bpN}%}AOLw&2YmCyB)& zKrs@#_zR8n96g7+U|~X99KixHU=n-K11lNbO~yXydXd;UiKS$omUhUbaKJ_jC8r%L zQm56#NMjqC7uCcdS0`^T8ct^IMfEb)PHcOgHOQzW`&MvLu1lHP0Ylrn@JbkVa6hvw z#5D8$&&2S_EZOxwe8j;y_3Fjzc-I5(2*l%^tXC$(wC!ChE|!xh28Pp4O7q!dY|L#D z&gWRgpSr<|=HYp`CmoNFgJrrRW*5jZY9^OC1wPsMV${YI7rm_k$*at?F=>Nu9}_u`$bQXYpD{8GU~ z3VxyB=L#NFuv)~aEF2w3T{_$n}S;vELZS-1-B@;S-~;|-&642y@Rbf+oU{772K%cI|{z7 z;06WXQt(X$-%xP9f&m3zS8$#DfU`ss5;D%8qO`n9gw2-xpZG*uPYUYc@;6mopr|uDx3t4KDObjE< zFc(Eca|yl@Hg-0O7aGe8S)1lr2-^Php>Lj))|#%KGhvoia^!>KD{=mDF-6|IM>Lqt zQj^*OZwd=c^4lZx%C}H){cP42ciBEO8ztB75ycd{Jz}MG(ofOwI|GdgQ&bBTdl5VF z5_mU(4J!Gqlfl(MahZp24ogqWfNx7!pHk?@GPIIHUl4;R^iue?f?kJ0&&beH3M~-D z2-P}>t#fcJsCb_^G6%;0okiSSI5+GQ8FN{)#EwYQLK@n-%&m}J($v<)XNW;_S?ea9 z5Q^%8iLJ~0Muz6vD5`5QqG;Kog7SO5N*tey9n3Bmi8a$na{^u7r-?BdrhXVkU1qhD z#_zH5dMvJkZ7xq7&~vm7+T_Ik69H**Crzzsb%7}^d14A0vd~6+OouVQ$;F^f4vf|P z09p)5i|y$^8>tL4t+bd-BMS|4RdWoM>Z1taLAyt+&|v^$(7t%O_dcM{=8ny+&h>SM zc`N*9kWDxqOd5bRXK^1t3~=J4m5;;Ba}OcHsQ6qggpe_zwedp|Z10otLwdSIgL$lt z-}YL8m>`y7RuC!;AkA{Mkb-Y%FxSxMuE&(fEI|OMJo~UL5+0cKkgY9hLaLu~ui%$7 zHpk!>H_?ohjwwQiA5CFI(LB}?3wo?+m{|gQ5C_fDnYk9IlQY>~1?WEf1sCRbvb9W_ ziD~BCNZ)QM5Fy2pA+mN+tKBKpGAoR3UX+>jpv?Sua62+hH>-@bmM_=^N43K6cf;`V zFuXDh|2Pca7lt1Q!@sa_dQZ(F=L)LO9LxSx?3|D7v408o0`^xNVjH;tE9p%le*xRu zC>_x-y(iNQR9qqWlB7vbF$SjVeJ+-{WjT6aGWp9S-G}#=u_^bQ(9N-F{4;!amZJ+M z)C-}hIS1PZl%3r9!UGupDrP;jt%1uIvc`0DbKoLYij$m4FS4g~ttcRtu=={5 zyIZVW#**S|aPAAdg9;W0ma!{w<+jguDc#kdT)XaK-?p z_?r0&yhtBzt^hKHkd;87uR{j_l1Ip^KynEw0WunJHQ*?~*8m>@Tmv`)a4q04z;%Ey zEHGaOybmw{I0$e(;GKYP0Qv_4c@xM0z_$Ql$6#&%><9QZ;8lRQbpn!BGdBW~oGu0I z4!8+08<4J&z%GyZ9$IvDcncLt|A8p#dthm%S>_BGIK78u8fC0m8&ndw=%x`eY6}Lq#1(U*6BAp=UW~X9 zhn87D3uzW0at6UVZv6@vT1;NSJjh+FfbLBevJxxo$t&44O|ZBj34w(s{wLCzm*C5+ zv*H4WSHccXbS{A@+o_MO(~y8mO4xmFN(ghQ3Oai1Sq(dg@#2!ztV7fBBs;;x)WxCW z!8RIgy^yfN*Qblgt8wCYnI+T0*k8w@=e#A{tr}%5CDOwX6fI6x*$1g$*{xqal$pw}(%oiZ{2!dz*=>bu8U_dnx#$r}uT%(sYpMz$F`$gBWM%9QzqWrbJTTgmM4Fi_**`=GEJMgnnVfL%lH-pv3E zdmr?0fcYA#>*q4`Lzl?ukPqi6__xba)-&BtEekG8b6~^?wk@RoTBk`ta?0U0sTu58 z!G^G6QILvN7M9lrYHMqfLwQk)QILv7++)WI z@{bjZf>f-ku)KBw4-uAOQkaUiAuO}Cz(di@4Yi`zTkKL#g_RQ~O68};n77!i#7SBO zOSw06{f(rE4qjTlipbMxZUo+;4}lxoq4YeO>~wJA%iSjBEba59FWErh&RkWR0~cJL z7RFxIGKRdU?CF&l-z!dwg>N%?$^8Eu4Jmxb>@{bfvgspY9)Fvq{|AT}v6H2U;qS1x z{{^-3A8(oeHI)HETBa&CwYXg#b<=Z9>Y%c-nk#CFaTCScZ?WWG??HA4w|kJv!|p*U zSoWY5$lmHfPZfro?W}>Q zejnnN{LNiz5VENGjV|zE%^d=+s2(t&YXl9IiO)goaMe!to;tc3@IvQS=*a^@kEe z!*>kPM>G`e{EyHeXSy~Ga;Ez~Uk@bh&TW+c5HbIIE99Y%Sehq4DC7!$w~(`!ly(nN zdDuNj1$%k2?c&qbJ?TQ1ezyDLi$^7-7)<#=9)nqTJ)Ual8 z8yKD0E?9)yFUZrzUabpn`l{I>EK>OgxH*e%NS91WaWk+zMH}53--WM+CF^Um(&}f^ zwu%qHXD&WD0}N%x6@fWgn2lip<#`OUQ*{CKItqrRA zBHu*?NNYK`j~C29zT(J1_6(ji9{f4Wj2q{EJ++~)InNXGK4(1NCL$GOwLy9M zp=4KimDG(VRo@XQ!C0)Nos`*2CRh<*B@*E#q)Q3p7 zR~tbe@%IzVFJg~iC*+LiPT+en;s|b4eLhM|JHqaxtHVZSYHo~_+P*%OKQtEhX}9U2$;!q%PhuSL>H zY{_jGSDa+YF$X~db&WwMS%Z{NRK6RQvDQ_t571URVoX2DMzaHPayyWIviW9_{4Fk; z*ew3?Ez1;de~ViU7ktZ_Ui1Zy16$jBPH9hy6P6!*i~IO~pt7Jkx=IYH(R+z&zhh}s z7bCxe8uSFH`-Pk`ukvYg$?tc#9o9Kcv)C}xq zU2X<=EiV!$4s zh<~yjvF?M|2qSxC7q1q>e`dFk2c)O;2vq(Ivktx3CA2bcrx*Ti4AP2U*l9Eu{anT~ z>%KLv)h^2QT$uoaCNkPa-Jvp%ivGIMGzYoh@Vd+e7#UEYb|Ge9)GS*KpQH0!54|Gn z#Cdv(%6V9#z$)FiSJRFQ?lQUuwz-U!8bh#y8U&;Q6P5cDvc+Z5MlbD%cp}j{#LZnk-o!@Eq;tPT3_^WY#O}4I`ZZuka|LNh%uhkzeyC;2|Q7J9AmT-jXcJE zG1KEfRL;=AFEPe#y8dH|sEpFu1t!HC&uj6w($$sJ7C(z=9s@5?1a^9i+qA@AwnIdN88{-dcZ{8L48WVO$e;C0HJGRGbjiml@5(24*z4XpU`W((~Lv zZH`DZj2B{XfDa?p2{HU>BT3|N!=)pOKHNyfhY#k)53U|a8@wDkR{T`YXd-G2BRz1p z*LYGFiS>;v9EM`s5aC>*pMJ~;N+4zf)6&~}hn z!dBZsHVK=)7T!c7OSEiY^v;;_jmnzR3~p%j@3akpSq_+i5v}jqF{#`)Z3mV6n(d%GUjD|SHMx;-S;iN3 zNF#()*$zsx%XUzj3YBIl(sY_~LVX_DKN9C(LM(Es+Y9{$2^x5$Z2KF)#;-5_sQB~Z@TfJHc3p&GAJqB9c>OzrQ#a(Ad2rs@>+$EN`P0i43!>veb6+cU}0w*35-p5L4(^n(H6jyZ8Whz4UHo!T7H`4P))J;s8ttsjN{oxoHj-LkZtU} zC}^sa-_){ZUanWy6gZPe!`ebHzuG7!RVY%}0%Hc+unON9{UpFESo8u0lmW z^cZB&Y*F->;RAU4F_1S#eD;{p6*ZLjxU8sQ5F$;dc~bF&9Tq(~L$S1R8g33FG1cQE zxx5uxab9O5QTRp~ndm9kj*=Z_^eE$Em^dvT1t$Db)O*6XxZZIo=5XGLR!S&Qr#-&pBJ!K3g zm^9kxh@{tzmc>6k+Gv@x8|UoIY&lbEPt&E2d1qW8qv#d6zPXP69@f9k2>xSBIn8a_4O4A;`>}9TQAx# zvc?!KS`_Uk@kEnl6hapVS6Ch%81b|xqgsvEh)2g5X>BhQ6SE|k>ZJe_9HzWzK~Qm6 zY#w85N?8GMp(YK{=3?6si~A^wjszBsH9Q*DMX!!S162j8#$gZ;Ipd8Jc%HNUvuOG~ zfuYYDRhqUyTs6`7o3O=$9!HdLO&l?-TBbGNi1#$o#Klh=U6Y9a z&8n}gFO>C1hQaU=N2VAn#79$&8r(B=ZfBQ znMO;!^eb`EOk=c;ETy}kMg(R;UhWdP1*qkc8u4ZU_+g$$^nbxfZB&FgwnlH8k>xWa z7w0eHGONDgx}T#n#OfD}dovc|igR7g@e#@2*PSFgFbN#lhjFwJ$sFE34v{*`_)?oM zVubMqz$RhbqE{t}4uz=9A~C4Y=;y8cQhm8uD6vFgt~3(SI{U@OA8@fKc;Lgvym4wV z&h*RL8EtXY?@Xr^i+Qt+Mre<9vyE2zLXUW8j&Y0FKO2*h7e(qEk(+RDZ(94xXA8&Aqr>HJa1q9S2W{ZS#$BX8Fes=!~GCDz%VUbG?Pc znI#qyZ!WhGw^?i<9<$Iw63qOM#q$e{p*pf-?;DMxzrZUsK9@MznO`h!ejh7@`-+Xv z#glWv#|y=}xe#az#V2zid=>_@BJ|QgpM}QdIzN$QYPe5GiD~|gnE4{)MUg0f(YOJi z@nUp}qQC=-A%<|+e(4e;{gQmlR7qPz$|^r(;jk6_%UHA8A$u!6@=$O*q;;H=e<6NZ zVkC>ZRvKp1^HEy7Uu;@yGz?s}6uf}OyJws1OwG0%&7JNqY>uftAXcwLjSksqc*1=H z@D-Z&g}C}vNaZiYJP88dzG|G&wKIWNKE_hAv7Jl0-cQ|`Ppd{Oc~qwDJ~2GM5vi$I zv(_lW#GwB=<9dMNbq1}`zmg!(_H|=^tYBM=hUahK>@CJFyJhsxPl(p<8>M*jsOEj6 zS=?}o$#cIDXAc;?b(^Mpsv(Uc{F(+{+Gu1%QH(DS8?Wf)pNlb@jaHtrLsUt)l*T;y zg(&+94SY!a@)cAuuQ>%wDEkDiFEk}FWj=u))_*%pLTd|sohd;S+HGlJ|;fd2r zsv~Mj&Ra?UfR*#C=*I40R((dsY8t4lHY%gyT3LZsB{!|NUB~mi&Sxks4YiUZWZjk? zuN_ zEYsJcHNQ44#q6TpH%4R8@tDyem_X(-@xXaj^OZgs$d$m%^RXT>I zIcZh{@y`!S6$j?FbZH|F%Fv~7CUih}XQUYYpSnK`;`Q*pPdXd)eNxvz5h*%+2ig3E zxaK>k6^g~*$yF@Ie`gHWW{H1(heai7wBh&0e7*XRc>R0h5p7Q3;!^XN~)VjwgS?&@7|v&?Wer7HAN~uhD3&`7W(B7yJ}`HAd-!Zl0_y z3QT7Jf$A8ZqzNsKUj?EfLdL}Ndo;+(2+za>ekTq5Af6vdp=N;(R9N)#Hg; zm3X}#-vaP-eO{=47AvlaYM;#==OBNfK3kp%H%SQeH3cWExL! z>TiYn&&cFyf%{wW{kpzE`Zo;RmBBA_ih(^sxhFOY<-R_GsNb6|vD+KK!BfCl77s|e*9d~J6M9D%N_8HR~_kFL;4AGI_BNVZIPN-u0 z=LG$=cLFb%{FJ7D5TZmi^y|I3+o^wO`3JxN3!M5#ikv(8aeEYxLXFTxo~RM3_3{09 zrBz)zs*9Q=+G-M6T^QC!T+6>>!Lxo+i59r`I*zyVHiA84T8pgy{7m%j&!kQ(^9Ihe zW_ufZ)I_`cl{c=DNKitF@XrBdU4d7d~s0p6NrY3H`l{XiEy@g++ zFaAtSxRv98gQZerw5nW1m$6{X4TS}uZmg%_zO>B)d6rfpz8}bM7gKM?R#TpeYo#A8 zKE91-N7v#KG=5xoZ|9@MtGDwTpq$q3-~&?jRbi-dI665pUXFCH-N~QHC`Z(wTD8o6m{8{HzoEIuN9EAr5f4 z=)#K`e0xl4oQ@SaL^WJr$EG3I#rkN5ND@!#&E zdw;SqqKkVU;Efu-7e&p6r2;PmKOrYNzJx93!Q2;rM#k+yai1BCOJ^p0LTND@$die1 zkd!v+=6xbsJit5D%{ehLXUzPqytj+|2Y6Ean=&t%_nHUz0)1QqF<=PK$e=TLDRNA~ zoC5cv;R3T(=Fi$lpN5w~TH)|)2k^03zRM%VG-A!giXps#Gu#y`P7LAh)@K{L8&Jf> zyX39t)-Z%Qo;&>6<;ATj6Ozw(E2N8;OD$dhUE;8knR6>rU$Yp*h zlNN;+QG_C{G>^(uYw)%iQkf^D>$K(4bIgAd(PHlio_X!q_ld|#C!M`_nv>u6@NrS* zROwkNJ$2i2mh>#N$}(5Mg&WB9AuxDwIC||fuI|D2h?_?84F6_iGGD6wB(+tTHBQ9+ zj55J~MNzGEtq&#NisVjnTsh^s!S;4Id?tC%l-{Kw@A97Hy;ypeg}h~Kzqv;G?+W?n z%FN%9-n;91e*kYB$;J+@X8P=pt&(xeL2a#+v$z@%^;)I7`LiT~&D`iAsR`6E?Z!91 zl_{#Dhxn};arA$$FNj3kL(xO{)CT4YkRaG>h(?X|@71@LWAsH=(MP-}y~`1&)@`nq zjxlghvu%PaA=K>0gPc`~fb($Had4Jt-7uH)2+l~8lUi1O74Uqp*lJf}bDt~)2lUb8 zRunWkXhU;hllzgbj#50;NG$rbGYuNaQkkvKg)DRHW|^z9JT57c9OIA3ls1Y>on4WY zmE}ad*#vI*NyfJ--DOvL-Zsc3{75_p?MI~^ zl>P+~{(GEgJL-m3TTYC2n_q7WYd@J}iPa0uv(j}o#48rZjonT}6*}vXFApk z&x$@>`cDi+x7fK@dKZPft=OxjcQL$oR8(9Z%w&`FUK|t;Q-DoqKzwL^x;;dHm5g=< z{3olgMmo=;`c}$e1}`j_XQW@PRizME=7b9RoKxpklVo!Uqq%60kZUQ@6g-Cc%BjLUNQz+5i3 z`I5}PMpBg91Nl2-Pk&8%AD7-w_NKC}9xc63O7C)_ru<622Nxl~EB)81w%j6J%R|+D zQVNw%r1y$Ybz6;74R2c+IYw9qnN*t zgMUP?oR}wp;+~b#DS5fM`R`e#brkxc6IY;`6Jc2uOhpcrDivLTB!=d zQ;~yzL{8IAH;p3q3YNHQI^`Ztb zUHR~7-l1EyZWdtHrdHE)Uy`YD8vvCY zQT*Vr)E%xWwTs7?t%}b#sdyLP=jzq+>KRwi$E=mP9Y0TQ!@_gxR$}K?63or|m`ySR zJR5utIU^!6D7G^wu9Lw|nZc>^WbjCM23O_V8RQ2ui1?n1deHamleyu6;&aFuW#{J2 z<#yfX2D7q0<|~;Rw;-L9dbFLInzs8%aHMS7lXwL!ylKCe8Q{&#b27-)!gKIf+c{KQ zImlLVo4+V#1A`UCz+Tv#@*y!>9wM!bHVdR9KO%RGv@c8V0xQm1=_sxnXS?)XY{mKX z!xYN3q)sGwtwn@sV#63d0y`90V|f>V`^WNbe%vdGsgJynDz-0O*n!T5u8j*~)9_dU zO;3D)yRrB|$Zq7aBhhXC@S&2PlRu*JDy{NJUZTq^j5YJ6ca`P6k-U45w~*d7;j#Vj zcboG*Qu)0kW0Zx*pn2SD(!0E__gm7tqK>!Q+@i7rX+>Y*g&}6{kTDCv6`1>hp4=V? zo2U;-6UF18WZWm-8pqoJ9JYWrk9V(Egs1U*&NW1Rw*puOH{$!mpgf-3j`H+*eMx+u z)7QAb*93U|nFYT3uuS&Vzb6?s$-a2AXcJX2mw| z=;L{(juz{oi6dC=C{pTnN=qc^VJV4kJLlV62Of$@d>V*;rjyOGm-+g=C zPsY?rc7&^lr|8YZb@IE*Bfi^`RBs`~h%6sN$k_-naaoQcAZKXAcW*=5XgjU--O+Vu zzpTAV+TJGJ5^?`PQW}cF7|dNKX=9&C>a&xEzPe%(zdJ^KwYX$5Z*VDbuz6U1Caw@W z9St3bc?`~9;o^SJffp-neu7wt__$gm{uM@+iA(LorF9aIgIN9*Mn>XJZma)5`tcvd z)aQ7yziunqjJsR|=jKa6zZ|hoW4S`CYcD{{(7#EO#9vG%=pkDrC}vWfIyM2a9Al!T zg@?}Hi}Jc&Q=lRWz7s)V83zhN&ds4ItFjwphOnshvwAi(X@RpN*8CW=t$7-nu zJb3uPNgEt6e74k5gptCFHn1@F*_O{+waky<|B!U1$SY+~F>Ul}+**$d330zURa6_i zJ!guO4iI@oPVMl z;1G#6Vx+3*&~%>OEEFHhg|3dXFud#+mYL`|gAZ#lH5r=c&*;uOR3`ViGI5Z}-w)r0 z{TgXBL7(%{3_j{+J3E|+fquUbZ?sU6KHWSUC2z%s`4lzoUgQOTd>$6LWE&o3Da~L= z4m1{*8R8vpv@PM#)GV0E`=x9~RHRXx>HFjsEQH5NOz%&Mm;&CZ`}5JDoW9~^@B+O~ zy&Moz@!auwxw(fhr`C%pV2rDqR-{5|$04`}9>Eq*6!2Rz3MpJ2mcc!q(pY1P9Ti9G z@+?2?yTHi;{tRuu4Hx`o|2VKU*$&mJBqtSwkdyxCCNish3xL&|-eU@jI-d02l_jh#~U zLPlBS{_*=AWt+OHHW95n#=4Y`)03M zx)GOiR=`7Ez?n-(F2`HvgrE(f)^V6~)*Lng%h_5Wh*3NX>{1MB zPg?F=TL1lv*r!H%l)e;jbw($pY`baDV@Z1P_UN(M;7%df9NwZwS#)Zgw2Y)1(dm-B zXkVOsJwXaGDbOIt;*}hO1q(4Z$uaZ{5@RFh@Zu)3;u=FSE)R4lDTzpEYU)DoiMDh3 zb65?(IhQwUlD8Qu=NwQ{RVH=MSjVmbLX*jpWny6wZ^Gxepx1@XAYY0cu;U@d%;U{F z+-~i9WTWm(nF)2F*r9kKB$yM7KC!bv*-;p>yK5eA+@7-2DKCw7Pp+q+-zLJWON9G& zB%}|*4O&C-J0$JDo{js~fAbr%Lf;^T-tYK;_|OLgzMjY9HJsL{ozHXhZDpeC0^VJ( zC=;U=@IeIkF5ttR-^RH`WmUcUVo)*9sGq+Dwb-A;A+;CDMO5d!V%|JO)*Xe&YPUiV z1$#9(Qdd>XQ?xbWOfkQuhU7BG;F%iDg$N^i20TH%R=5d3Q_n^V%kFf zWY2T6l?|C9OP2ZTnU21eFo$IBF6}F$B(LaFkH1u0vxq{V=Zbnw#pjE7k0x-T z?Q!236$?#*b#*NWn3C*sif`ZZ)(hP5B9GBUvt|5Gfq_f-iyFuuv5YsixR6R|MI2LW z`Ql8-bIW*AJ>s!!co*5shVcH&c@tIZ*g#q;_Alef7mV22Y95LRCU^ItGD>7pG?a~#6r5QZCH>{Kg}Ukqg&Ea8{;>=N4OE*@}( z;!ZvArwa370PKHO63uyhUFkL zIEW15Z6cSH&U%@*><8+jkVtO)n(x6COD@{KH7g>%`eV50qvSsB`M&xC+{61a&+@;9 zZrtxMbDI?T$)2Cha<#d*F%>7JkTf(FU@40xoKy3l@H0lU>1n zygL+8k0%gB^!RYjH8CQj79mt(D&|@AekZHhqYkqk| z&EIKJG|-}G08!LN@Baso;}3DiuQI|qki&wFGRz`putm;&7CD3d9di5^V$5(R32!i~ zy~;pNs4tAR$Qfmk^N2;xh~Gty|9AG2Unl1S)mYRjxf*yP#LZP? zcEf*Du>xNk`q)ZUs=q=NTmIiv>_QYP$N5Q^3oLpaO2{n7E-lTG3=R&u!&}i@?hneb&iqQY#EDQ#BvUO1CxxZ> z@P_cgn`CWpg?@x=`iH8^P@9}D>p6O`kt4INMsnf^%K21e&fg;FA{A6CgZx2?@-Y1& ziYVFH$YkNIl&eS3Iv1%ZM@yhh(XGBVQMcr1p8i{M^xqtxR-ss%Z}KB4+Mp<+?NK@~{@kwd{DnKq2k0!+#X}8~ht6Wp*B3_?HXT9M;FGQ|$1MY~p~f#pkhQ{S zlcleSOjZ)?ep!wZNn@~u-r6YQU&r#}OGJ@8D<{Lp;F4473#~u4st8y)1SQ047h<0C zaoU>5$o|lW{6l3;b-h-8$FJ1ho^#egXWtIh-ulRDnDkDFQ#V8g`HK)nlM^bnG%{=% zg1joIEHbD73#c&ptT?qoaccQ*a%ylQ<*zfv|MjWM8=#10+eGZHNQyQisDTRF9T~I_ zLG@KoRbzeckj?5f zkwIG#)JRc#JThqhhJ@g{RjxWuf~4T8^WX---{7f{3+nH|6>`ORA%;GV;;hQaa(owA z0b`JsD1kVFVkOJ*J#1hSurkxl1n9{T5UQ)$p{RZt_Y~qX8JE?KyE+tCM*SzE8ZxR; zH|kbIwTNq{{Sevh_lE`5${^KSU`=%H0{#dZhw3{dZ0v~*vC`SdYW@+!m@N-;X`vDN z&WWfkn*sA8gX}Khx1@K0Q_X^%Y8LFYX8IGQ74aXtE{j-};Z>s`Pu5{!If@oKBZsA}7-^i6GshpFm_lhgMKCJmyxx#^bD`E<)JD& zjR>Lf=3ll;bJODbJPNNj5QDlvh}Ifa1hvIWPC4*ic$D3V$VrquY`l8;yd2;~B)j8K zk2iVX>;^tTgH1=?JG}K3V_^s%B4Q1eL)H|P&rJ?7+(vlI#bbL4O;{#IA8?G-=rP| z34+J3#kh?;2UkKpxQTbF2c~u6i+!+X*rldkBB7M$7#kuIm5WO@@$SEws3IcK?%$V) zEdN5})rjbKv8f};OA>dy%bT2+#^>JUy}Ac1;_WYAd(M|156e0od#~~xCe%WPUMu3? zdGN4t6{;MYl;!*Gt0UEw|(4lp(*h5%J2y;+2Z$ z%J`+o5Aia4SuM7^&Ub7&=Q}FG^2^Yxv6-|O%}?L4TV!qKo#N@O*-Xb%cuH4PZ^8K( zXpzjCh(u?@5}gt&H-m^3qIxrLo01n5`lt-OFe;RJew0|XnO~wJCKpFUTpJc~g;=u1 zj@KsV{9k2v7n?7g{Hs{37I0ZYjQPoWPX=AUguQ%o=lX#8K3}6Hg!%1XAJDee@%v_d zVAD3fo#N4<7p*<`J@<{k>!Zlu?c$8mEF|NpND@FQh|t`s!h5pj{`asTTD==G>2u zv2@l>pI3#3l%&oOi8i-{$~b_e_MA1Bw6me0f2ts>il#(cRWy;TK2Sw@Wc8s4qc#FX zVU!8)$GqNOeuJ#w9N{_C0p($pRH#ZSP$lJum301se(U>#1W}sC6PfT z2%@FE&FN4&WI5JGM|6x(JHC(Db$ije3q{_8$TTmpnxa%S#Rk(Ad5(H1+(M*rPy z@ij`aISg=TV3L$FA^l?v9pm>Cupc;Q`{Sq9$C z?d-&*02K8&Pz)D@9s-&!qo(89OBJ=i+1cq6@9*Jh_fjUXC@M`r99V=E;jB-gIzBWH z_(D1WdB_Q4HJS<2FDAXSn^}>UBLa**WWtw#A5{3uz~|B#Y1o;z2>AE%d@VTzZ4Qd; z>uO?rvA7SDtQ@?pMM4$7RjUd7wTf?c##G}xfq86+xTKn2Tu(a2EhU!mB)FY9SaXOE zAC74pm{iT*(X6=BmWt~>=RV6ZcWL0!&-o<1y-c~xO37ey3`4LwULfY7kZ+*vm;CRV zwmndE7&k8ht~kmM#c4|e(@*j7y0%m_I*nt5%L1KFb3+kXxh&A{M_m7@?FjtzGk;dM zD5zW_CTiZ+mZNG(;C0P=OEmIHi1m)w)0TSVjlR*Q|KX8obZ!&IeNJB-u6Q8aW#%sn ztc~~HZ|Aivke1-BgjH4Gd&8UUL^hfAyxWPK+6Las;N7;N_dasYO!TIMx($imClN~^ zR*S$LDc;v8j5YJNtuH_RRjWQ4;jjh<3`gKwm-hip>}1~Pz($|9xrPkCNcH}tN`G~! z__Bq!13Z&jddq{JftuFdXWU|32k-Y6WPIZ`$RNRE~ zgSe@S_g4Oj$1K+QhUhC3Tt1Ikx-#%)7w<$}TNUWl-P^-uHQV-8fk`>uZHmEGt`fKR z^j=zz^2BK;l^eM9%_U+%PwzF_tKwKsZ>m-jNa*ElttYLPZH%MBI4?2OOuE)ZZ0j;} zUlZ3}>0ND=kh?}i_3^f`94MeuA8*!q3wW%L_nF4wjR*S&>vKQ=T8Q=aUXRPu?(XXy z(?~|cC(HVeHR-llw|VFX@k3wlvGl@toQZ)Pi#2Bh%a_<3U{eT_m$K76(YV$t?rLv( zgY(7~eXfR0x-8{ASqh%@T|pKN_`X>FQow(;_Y*C7E-cgI&3W;#P}ln;<5%mGoXTL) zVa^xBukkj~<^`r+<82kI?G$To@}{SR<%jd}_&CbWW73}g2cq^S?}t_;y}2Y%Ilvno z*G$H@xQxsv;z0r>vN#1z^3S`x%j_iL#k;-BJA~DXMKR2b!%|RvNq;wrg@}jEid)RO z$J;akhrF@T0~1Ra@|+E9y2rcSv^H7RkfUsp5_Mya`U_Y9YS9&znpMvENQ7 z#gR}n_^bDOnXVb7TaI+8-_&d2R7fMNbHsH+y^S+6?E}{ki)k9AcX8NwN-UNiQkVx< zH$C$=Z$EwcB2n=-?>4<+ktn?1I|tXvbr|ezlYEHoO4x|wc~rQxl*7dc@~rtQV$@)- zFYaZ8LHR@XNe}iW>67BchQZ!6y2-kFu(u<*8$RIm=`TrlQyup&4}8G;gm+tvWs-+y z(=p4?_&ehB2fUB_sXmTr4x$#f(Mgh(>7_KwlYX&$v+@I{sd%2CA58L;9}oIryjFho zgMPRYO!*}S{Su)lQJyJ5Puvlv{Cq(_U(l~b(62?%FFoj&9`wr$`eg?F+Vi4lx65I= z-Rs?&%MT+bF=D9q(xxRx>Gnr+!(0zvgKLrTW6mrhJT1yxvrv={^$xV-%#!}+jgu&@ z8|F=oErsnY>i0wO_%QEf`tc&MYM8f^{!@`SOmM{?=Md69S^Arxd zX7lVqD-P_C&9!z>|3Xpb7U^n>lBKgcBJf0nYs`E_bMuwaj&i8-W1{1vFMI6 zcSQI_nS0?*1e*p6IT;o~yfwnxG<)2_FfuTO$#O6>Eg7pvnKQ$~;9eN!7T%ERTMXU@!=nK^Uj%bgp+-o9S zTyNc-AI_xRq1EjKjM^O<-GHw9q5=PDh;hrq!TDU3LSK>5Y~At@&TpX84$f!2M@aR> z-yO4?hNbH}M@TJ2arJyAjg;D%ehXGIQVQdNH>IX=Y9Jpd$R>qhKI7MOYe;x`q%<KD#sQ^!lO_RDj_ z*@^jz!ZwYU-VZ&*KkNu{AJ7LBNm+syk`$)FAg0!(Bg^>D={~P-m>}h$D3&-$YWqKE z*r-WTf81bEHc9fp3!aSZ&a!5crDoOkgp)yH^08(vX&gQef=^ODf_8bXzGSjAM8u(7 zb(%B@Udc3R2fTj8Qk#0S8ErqW#C0XGRqDBa2uc+Aw-7#ipTsaN%8|T5zh5uyAXed2(mW0c> z_Ult;OMQiCe{*sr%CD?P9c-urQ<>Bems<5^FnV#BSIJyyGz9zBJgHSEUGk5wFd)_g z=1E2WiH%~N=S#Wh$FJv0t1A_ADTR$e7ml7{1q-Bi9>D1h7Q(izw7Q(Il6IPqmBw^(`!1s?77v_7j)6vMqKo!JJ(3l?ZPi?{yOP5@#m`S{<}ey z*|aaEDiuc5`Y$npaDV!t4bmg{N;3XyDG?ps@@pyCj*c5xDm@*0j=m{5jOFuL0JH&s zH8%~VL{YmsS3g!N6*`16z3UIsYjzefR*Gb2wo1>7>n`cqHq4hWk4Ef(1fOIVcSx-( ze;NXP@9vFi2My_Me35|f;6FVh`2&$)dOYMa_?A_gv^W$v$ZmBbnwe~=xe#-jq zk-Wk&Hg=CR56JkvQpYIDk4__K_96Jp0pJQT0ok!hd!=)r8NN?y@4e$p40YpH1uTty zuHJZ?h2F=;#e(~!ULa}xlhg*@)Ssjbc;Ehnb~wR8_an5CHQO(xd#2(nFHXt!PQ=3z z#tC<)`=CB9By$aDF@}Jtv^nEdE!B%S!gtuhQV8%Q%IOPb3m;G`#I( z?Zd$0o4|H#Ayl`~&8ar`+Dh#AU!@b?t#phX8}5CG9&JoJ3GS`>q2Hur5{r-{(iq{o zKKY0=+nIQ^D%SC#T2gP?wF%`H*wS+kgu#E<)>)~yIwfrogp+H}NYw>a?=Lj#5%%U^ z(q%9=;H=aZjr`?VDY2nB{BO)QrD@L`0;1_CIC^<KDNs|HpdPzEOpw_bSm!+xV+cE6bt5OU7`72Pw!XJ9StI#SKk-M)+)6pQg z*QJjI+-nzcQ#wUGpkKcwNkZ_N5G*#FETxz1)f4YXy#?HEHRW%qE%njCzokEf)%u3J zP|*}lyD!yz&TNSJRzqCl0B;D)f)yHK+rMeFAewK{V;JpkMZvr_R1DkHRHO06PleR6Co#Dx@kC?eZ$z>sQ|)kAv4FNKO>T$FQ6r zc^CV_E-x30c)-gpIplD0QjGqOLvCbOFkjOwjp;bNFYZ8ZY;*Y7fHBfk_G??&jb1+2 zR?eelX&ff^7ueS>IaZjd|K^fMiuOxR7b|%Jto5%XuTQMsVBGY9u!nKG$b9l0)f-&qa;p^Y|`fViWl)ZXO}-%DoUeVHA&ajd;_Dxdf~@=NRj-9iOa3=n zaPDx!mGrRHS#qhy{&ZjPcsUg{I7}UXZhcui1uzXjX9mAFmlNI*FKslU!`iMLl zpM0jamg|ui=Cqb)2p8Cu)^eh7j(OV1ODbK&cZymHzuG>-{RP|HM!phPf-f{_#=*uo ztu~=oU`9CcnIjqCOW3|g<$U21YuZ-+6t5ncz0aP0Os<71H(!5D9tm~La-Ns#vYak* zm|nNN+(2Mw+sctFzk^JQn{DnOHwVp>7vyBt;A#17z|CHi)AT=|mYo8ALcREm+(}r* z+B_?dU@c#eJ#6E%5ULN^k!R(B*eiRoqwE%i%R0(<6_?$0K+eZH$YB6X>KMRQwdS9z|0mU<^w&Lq)3 zlq)*~@m-^7^{d_FpSddD)iP48?ClMS@rylye zQv4jbvzI(YT;X7Qhs)2y)~h`Ng9J%Zd&^ES{EB(SUx@ocI9uOeepO%FSGJ3|>*cHd z@+h`)gxo3oPGkaYC-SGhSfc^*J@Mo6{$5H=H&D*SBUI?|DE7*$vWJ@ctyj_9>)AK2 z%I^rbSneSCZ)|P7JXl@>j+7xlu3&42$S+|6RE8Q16%UmoEw;t&!E9GAc{1LH+A|#e zVz3?9*y?NYL&7)g>DSQaU$cp?$w$SLGg$A}MO=W1IAMlGNrM@uV~+tk8d-D7O_@o5^zH$o(_;(#V0iQS-U4vEs?{+aXuOBk?x! zB^EtJ{s3LFX$semENLo6$WFceRQX}Mc-P6!pA@3m%IRSEuW+{XIgHuTucc7-&`4E@ zq&b{F&_N$S?v7yt$4FDy$|=ydf3v+aK|wMnqu`O7cC@g+HyRNF%# ztAruHBz^Ky`F+8D(jLv4d?3f-Q#}j>* z2A>49fuFbN^2zDH;-fHIgwgh) z3-=iKXirph9gVZQ3WT@9nCBDu2l4oI{m3VBPLN`@)3$qlQQ;G?hxPbeK3iiOE>?Ba z7MD2_B7L-(veMZbpCe^sz6kO~X4$cH)9&44bH0${W2WGZtswUee88zKB2Zh00~y%X z3f5NKXM4Yp(?U!N7PeZBj@ZD-=LaKx`+b(WT8w!E@bR7|xom#p4i%1M<2EY5>nIR`ha1e(MeCo}&m5A^t#pCFY$Xx5>n(Wv*IVbVj18FElVURz` zw9(zDG_$ahAY%p#w!fV}plT))z8j^w>`9JrLP+;g0_jV^2BJL@x9!_Qa5Eh5}gM;_Kj6`>w7r|&v|wFL5{;paQF{U!Ux&>ALLSD z8|(ZdCfbkn)jz`0vNXi!hEC+Ub6t|LRo;kY+qJFoG0eXEw?W}vXW`rBzIgKIwe9k| z!VR{!6U=~&9r6ppO*VB0)Z2At-wEw@lMUM`56854ai=_(Ro*9WWx2a#rHQ2)FP9H_ zREA$zjtR4nugl*cJI5sayPS}Hwo9(w$;7WPDoaYqSnSckWFHos?z`bIVEDR^mJ~Lv zIyTO*x^$nzuNruDT(Is2abJz03#G8J=3a+=f41trq_AeYC)pcgySKiDfQr%4L_fMbM_gv$-d+ANI&yI-a@YqLT#nB$%|vP1pzcpb68XHhWCi zjbB;pw4;EH7y#kef)1ER%l!A|Ux$6$M*=T9){i}bZW$<+nS+`sLYXJNrK z@Mn3TxOxWr{b%_x*7|__YR$VOzUDJWHhKkyOnX|M(>4f968xlIRkE>f56Fugv&Ud_ zk7;8RFXTuGWn+GkTR9d08O$PEE4B6OzsQmxzCVt&Z=)o#I)~&wj^*QUn11kc1%m z#5q_yTb^X^FLHIZ_pm%iSjT!Dku}e{5XiUfNqnUrUW-1M5ALl^8_T{qB99a2jD;Br zetI3n6mw-9OF1SN)jCFep?EC!xOm`RMyy19ReY7*yg*2eL;H3-I|gFMhOs!3gH3NG zo=rL~=ZL$;v-8L0WXN*#3Av|mQy+CgE)*PVh(BIe*5D8Mp0I({KZ$iN_;~uHJj?Ml zqFpTIG#2f`pK=|M80+9t67{D}%S#0DoiTdZ8TpCw_Un39?jwSQooD4&#b3s=7U$%F zVZV>3Geu~&U_4g}ZF>Bi+#-76O#b_@i=Mg&*2LZk!E~9pLn|B48lRV2hy9I2d{Z`v zUA`_q?^Z1;Z2tslql(z&^KuJuToFsZASV<|DGJAm-)Nc;jW5T{Oz|CfkT#=2G=2e~ zO)g$0k7gC3ag4KK^uh|!{Aa_!)Ju!P;{poDRUH+Re*j)DpiMt6VxEigM`+@W7v*^I zvm$oi(ARsf$VL9Hee=lBa%Y(F|MYB68qb;^(-%)y5T(NP2vRVAIh&?7MiyXWx z*1k-Bk#_-m+^#5QDg8xczsIih=Q#%{1IvZh=#bbHtGiGnZ|kiXPb8-ig4lvBeFeXg z45$aq^t?lHi~kg{e1{S*7ENFi$)7QSee6(T#rYH1HiyziTsna%!Ae5H2NTNGK!}Dt zhit19^k|T_Y69yRjN}_8=);1Q@mMvE!3(cSJZE1(YT|;ttfYp zpG#Fbg>0~|#Y1lbdmhthkEeLG0J6QWv72pH-C*yd^P_UG*sMJ1(J|2&SFI zHdmyKX4&B7tR+S%b;J$#*^^Od=?&~a6gb^}e@vv+E6;&)_`xLhXS}l0fz^vvi5;!M(?lj9&FrbHegbdJwFzj=kEXKY5XPFERjWh4 zM77j^wO4KT3ifGjr8dj2j;4A#QR!~<^7$Ypsp#bciApv&i>wBoXH8;Ft0{BBrXweN zg$g#Pu1pi}PGqIkl_lZ_Q&?^d-kBR}fVZ_%*l!5>AUt$MUg1Vpwun2u%-O(_$=y>7 zQLRx?3XfZzTtO0Q8bovkjBd=iGleawS+T{Q7tc&&*|n5`;)O|Uc`apr7#0&aHC#SU zdL{85+m)mwB`rgbNfZZjs9colRg^bcg2dHUUO;P%sIA0S`3i|V|7y=rJ)r9YZOjp%nK$Mi$x3N3R}wa(-Y<1gG8`TpD%!yA)>obl`wKQC zHwNvDEIa+J28trMEL8{_&CrEVw)I)TlTaBKQj`WF441f6rMbAGnB}BmB(5uFg{g{< z!tbOi?~30Svo>i;E;{C;G$qclw;1yU8zm{7VglRNZHXK=h7J_77U@cEd>}<-i^3Ah z--=mjI+x_C8A=TG99N0YXDGir)}fSeL+871%c1P$Ol7EeqL}T^q$)%nNMs@n<`TrMJPVlFlKKyRm#L^#jL@TN)^_WG`6dm(q5cfOv=T? z6f{%X`Aa(AETE*3&6W9rYcG1(iP}(K@-BW@Q(U~X4lN<{ho-TkEtR2;6Bs-w^|IWR zt!t%J^5^(*ccm`7*cPfN?qMa}UyGp+D==(+9ixZ0R$5w<@)YsRGO{J zGQcu;#W}h9xzS7NSl>6ef zVs`6UXt~?PtanFchpIi0qK7h95bup)zvd}#ievbyk`EnKAKTL$IuPbWw*D2Qf>0*)QeF}q zAM(mY9F}v~nS9v0pG;@}2R|C%#stEISRT0eBX}w_pZJy57_l7dtI-MORe;3Gm zW4c6ZVl^Ab8uu|+q9v`qwU07W5EoC^yYy3Vj0vM?X@5*5M~j$ufHF_qafPiKpu8IX zD~d8yNkCCf)^?y$jU=M~K$HVfm_|NiU?ur$#<9Hvp-cnHt;^JVaT?8_+XMDJCp2%C-(uwwm2uzJ0KExRT>o16c_6i+8l%b_6U(+C%92 znleQ^Hk}j{nS;Y$hk*V$ot3=K74P4#D^ojPzR^K4yr!4Pzkn%=p?j|j_Dy%6c3Npn~hOA3XXH2mxzqv zgHVlSCF7M*VMQ?hLrLd5NFt)yBSlI#amG0IQIRrEoIj4GPEaOOi*KBOu-UeH{zN5* zINUl(Y0c_RRu;0z$x00SakBCdu#PE8CcGw7lzQ-bO;M6isp(S`heP;LXET%xK^hf7 zn+3S%(Bb2^sk_)`BjguY*=D&CJ2F#w3csu+&r<5bdtsKc9q(n=n5~S)S2(2~hIsYr zbCixj;yowZ^Gr}CTRC5m;(xpV>w|0i^6k1~7x=!Opk2Dij?Y&XU`y(a1xf;br&+u} zsY}1pM8X_6$o4K!s^je1jRi^^ey8y)RN7X(6paN5U0Q3`_J>G8v{Q@ICiUR$Wv?yd zbaNLfHSv4S#)V3+S|{yzk^|>y>6iHodSxox4U`BJ&Y$4+MMAZ3pJY!iQljyjN&X_G zJ-n|LDT&w%J+er->3*P;eeC373IxDvq^IE>E}(2kQzl=jlRpoB27g~&JPafLgwJYS-u3S(K^Ql&Cl zIcur1rV8E>rHio5Ez&tg9#&r@#NrST{Vo$gaZ@XGKEGF$d@6yIxaA{X<+DGuPgBpahnilqwO&e=q z^>(^)R1n9+vg9w7C&YE<*k@lV$su@63?Gc~z$1jLx?btwSa!~ZOFMJEQo4wvLs^;P z^sw9Om1HKYhm8#4|0~g=6-u;q%;#(mGUm70n66OO(+(s-Z{;VO%cZP=_- zj>Itvolb0(*~MV|u*i1)h`oy2n-xjie}PS}i|6+6G#iYQ{TKAiZX{qc`VRmyG4kIMJ*=SWJ)CkAPIPebQmpMS{~ zWjzk{bl$4eRITWlI2zA$9~Ek2i?%8~oleN7`&?)=6SqMO{$vfeL8a3fj%`Y$ymKD59I)B4NBPx0$1#OXOORvO zroBp?gq^2cN%X)X+Ftwq6uwu%x94;?2k*=C!#PDPd>@to<7L))A8Zjk*u77Q^Q^%M zR{G5pI@37G12w#s?b)YvaZNhwa^ImLjY>EAN!df6iiQ1*n$R)NHRwb3+yUil_H0jk zbb)J{AcWGl5xzc&4*YP8lZQ^&ob>Qu0={;mX2D^hWLpFdO4=I;_~w&B;R$&65J%h- z@VhFA1ewmOsze89=iKeFBjm5+t*nfH+LC{Ehu98zA@ zoBpau0_*sjvIBLb-h7z(4l9|CvL$x+`|QQTN;}8+5&~Bo#?&~O?K!5zx`S=nnI(2t zALHct!o}?G!%9Cy<{wd>5_c?NUma1}`%W!JGCHq|UyJ;ZcFDy094zNB)(_2(D(PXj zEM$;@oPJbk9edx8Ot#I#haz+|3t3^lw1J(j#}pMuV%@#9F~lkT9EBfF=l@^mCIryU z{V%$tN2i)3lZrk+y_!ye1d=GOVGnvBJOA==%p+&6$pAZ z3zh|-WLuBMHrNUTefCVTGK7xf?WdH747_aM@wq+GKYdC`HZo8R#Kcp|;|8I} zAoLpe(;$qbjC}&K9pe)yb+yyVX_!H-Gs=iCoEyc@hY-=lY~C5AnP>=3J?8ieTH-&D z=@G860?E0cW%Nd?l6YZ{7Au7B7VACFV$l(@4ni_HD4J;(l#K8eHdn7ek<4MkFJP0p zcmeZWRBD)hWp);{;`#Xo((o&@oQulCgna*^^3n@i=F^0MMxC0VZN)_&s(6sa8=na!nCb_1J>yQ*6xP#M5QaSRKXaWj)LC5 z%|5)LtY&TRU_o*|l)ZRUNfdYEwC7DMU9alj-BgN%N^9rYwN>~WbsmO-`)l^%ZKa(Q zh(oDBue%NNeg(UDTj|X5?_ef5#1`FAzQZrS-Tqdt3hx3&a*JgJRjSi%KjL1huL-A#{$Q#t0KxGg0lr9um}c9nW3E z2Zm^Q{&K`S5p>1cm^r)`xoSqUHiaOG{FC_>2IR~VA2lF%7A|M!v6ZvLP6p)561%cv zg4zY8u>?_#sWLIt70#tG*%srTOV?40$SK*@80U>uRU8+}mfO`lc1DEJ^bvF0)!I18 z+1RcQVv#{=c4X;H&JIk5+G0wUojn(%CZ;Zn#pGbKB|y~3R%(p0g(gBaB*w7PTu`+u zXWFg9YnMaxB|+*zLHJ%D5v=wV^ot?tJ9MxcFP6V$7`HK&JviB|*9}u=ifo=seN%rV zLUrTyj~UP>HXI);n#qA+t6JIzo=v(Skz zQd^KI_g1DQsQvg<%yMd~_)*TSCa`^(YR6D|9|SXQ0*<%uf0yd2z9!}wytOmv$PBW=f^OP$4#PlnXp0Tl?%o)zePh5jz=<|( z(+u`lJ#~UO&B=bQr#8aKj!ae?3cs?}$trz7;Jy;-aYEsp45M>oDP>NT+3TyZY;T6@ z6|iH}Qa#Ij_0^cfi}WfEwa82ymV=JOAQxNUq0I{=NZ1QD?&V)dGTPGG$0MeATR(TsRFbn(8c7ZERk9O?L~zoA4bD~v3&+{%Y_%;8Ql>Uis|3Nief%NyTOEyqk0>fNQy&S6->s)Y#iJFggOQ3yR}m@^yi;cVQJ23rzQcjv7I{Cu}Z)r3ha|o%rHgz7f-1g zjSvP{T`e3>ce>#y~P1JI3MI52TPyI9z&~RDD*OX z{)7d;tG9O2MqfceJ=~f~dN)gW6mW|^TA3L{vDz6E#_cBBaTCV%CfY$0hBm_UQD(r0 zh%F{e>ZsI&@xhZe9|aor1~D-gp|~bwMrm^Z8c%j;vjAeEA?##V@0O!*tP_(Uf-Udk zFCLHNV0zOQqXMFa+blO5{5OEzPk9*CJC20-K8<+C^KbaPN<#YbesEvFhQxDf7QUaH z{+xQu!A8HNR&9DWl%9HlywKMZ+o98VfjA;di#Xh@@?Yo>6U`321mU^E#Fy3j;mC+~ z&p176`m&lS5r+0RjEr&n4IBNk+LsgJ(maFk&dX{d6lZJ~HIY5uMXgG{}>c_ME+x0%q6Q z*HOUiI{Qirn0;qoMuF0)Y+H_cLL3{(KIy8yAk1bVxoW&HPp_4$euVjq?d_&kOP)i0 zI|i53AYXfL?KpJ_mY87(m*9Zzs7h$15=dhx*0YybLU*->Fow11uGX)5J`M{=JdTMQ z&}L$Apo@@_ z#TU;ul7urvbrL8ntEnwPd^}uiflm&dLlT{ImM!EHT77u2l?OC3ND|9f_nvA!G<9)L zwHgjmveiA+>OuxP)KiTUnzCCx)fb}w!49xrn%tM-V9b6Bv8ioe$NIbi8e`RZ$8p~w#8tIvveBUruOYK&)-^l&==yW0GncX2SJ1$cgs zz1$ley@P$!TOEk6FQfZFxo=@l^--((NR-Hy#8FJhC_Z|{bKJB>$0c{RHjQo9*u*~S z-b(9?K?fTE2fnB3`F+(Mf*H7%)5JcYyl z=&wE{++*nj)b9B5m<>?tS9=fN7umGpP&({lcfTEvZ=40(ZEzC_(aXfb4R&ULn#Q!( zRd3|G_$=lv2Q;1d7Gh_y+5^>Ce6-bOp!!hcY-jIen+;Qepv`q^3)#$p>XYpkIuY=R zRcS9Fgbt3=*>2ogg;Im2CkD|;a@f+@;#@qShsW4Rcg}UrB4ycZ)>QJeSw6??L=^3HcO52W87&h%LH)UzBkyiP*Av6rXa+7kx+8G{h+u)|D26Gl04i}wK4zh8x z*~AfQQcO`O+0Rzu3du6Ci{h-xiJP*EBh=>5$N`uqUsF?YM!xVhHM(NN`q$K^ZRZO3 z_Oh`Jl589gCw{mg4Sq@lVhDqrYAn(~pgQe|psT@d@emntNJwj5_T1}gv#8r~JRcYp zFB&^KE2q%vnXQ;E$2;D$_i?XbyI)sRgZ~pg#;_tpG%=XK_U{+8g@1=dzNL16 zO`rP~EaDsNy|>g(*v|RqEj2IX1|G(PzGKVZQj^)70$3_H*v0~Ny0~%*d%957LUg<+ z8H{U<<`=4&58E0D#q_d=!!*@Klb(etD8z;!u4Ts&L3~(%*t&$G-$GM*)6&JKZJ0t= z#?bwGr`g>?wN8j(>a}FmMyXk0+j%Trv^~vwj8d0}o#x@B-tJw@_cj^)_$u$A(O3Xn zV|_>eE516=kG!q63%g@wvy&}+8~Ye**bi^31qqW$cF~VC@8c@f1e~ehj0xJeX5D&@ zLA|fBX=AW7Ji=nes-46mli9Gbs!#ZVv9Xxt*RTy^)scGhaq5=>?moCZ9;*T@UtJSm zdri~xC#a|B*QoZB)L!aBvRd%EyDtRNYg^@=NamWUMvJF|*!rEp zRd7LrhM?ng5VpqHWhul9%{&^I4(^s6zCqu-6WV)D_( z23Jgp)ZJXo+`>8l+KH~vWs~jhT_N;YG=@7ZI$ z>F=P;8k(8dmxS!K6c#R?LRJ}~$w3X^;^4F|VU$hGsb@v)I zoWikd)rNMAlxM$$)we@m_oX_-0b4YABaGRbtkXvIP&1=4iB)NmaA?Ke-iflwWMYhg zn+u#`)*><1z?A@}qMB?#samtfI^H0O@wl$ji%eE{u@(giOHhns+;xTU`APa$rC1fA zjz>1B@6<8+A`v1$6t`q5*65SO1OrzFoPxg5KiaG|pnbMO->b{SiSg|1AJm(u+sGf) zlLCz1u3Ob8aY8(MZL7Lb_>nc*rgn(<(J?cjuCE6E)p7sG*f!YgKk8p^Q{SaV$=#uP z$REB_Z9x8qyVP-z6}|pXYAq4|b3bEy2>y}-*p_I&1s4GO`_tx&@OP)p=kfQZ&8J#Y zf%-)HGRe5*4S|o+%A3NCW?=OWsxj2#j~!J1LMa)CR1u}Jtl!l0dh%g)oI~iro(y$V zV~x(Kn*PNJR92YDKK?`PYu_`$&aaIU_e{`RoK#;F)kUHB8PMjd?FN8nt9{i0=%1ca zUkTEOcXn>I<8m4;2V2m4Ca_~UP7gM3i*uaqDh3;~23?)XgSc7$fxG=5xGuT>PW$bD z;F7vkpnIm9Gabv{@!eo#{uIGhb#qpQukY&Sd``rNfi?1+)u43R<~g4e=IAAP&K<#c z@00cK>#RXrgtPlPo50ui^>x-4687Wm418}!_RszZ*Rmk|Y;62YBI0KfsKE&=p}%u* zr=kglNWKJIu?hD8JlBN#0xmIOJdmv|GvPM?uQcH?0s`yI0DY*gl}=#i`#W!WPQnht zETDzpqjWqq>^>0T{yBo(9^g!Sn1hI-8w6Y{1zfWwwh&v;>THUD=@&DxGXhy9+mNBy zj?P?@@dOn}p0Vu{#zwVvCmG z+CKozpY|>6&w@6m=wH}h1?~Je3%l81(qK^&+Rz#j>@^nfvCNUNM&>&M6Zo~E(( z8>1qmm(R2I1D%z*)whuK8|duFa)&s(7yN4dXzW@Zk3C@A3Wj&0=@gUOX@rWLfCU4d zLU(Ek+Ge7fWl`~vNyXtnszpv*Aa15u>BJFzm=Kiudoy)`5&YRGghw4U3gIyBoTua* zz7UZ7vJ;02P5gBy4%C|P=ujL+H{ofaSRa`%3&q(s6J8REkF8Aj!-7z}d13}W3&r~m zCaj0zfTRg;48;%aCj4V4&aj*C?tlW02NZBQpn%a~<@wJHE6@MEFeCp0YK%2uBpT-jp0Z?&3A&FphgrOLF+4i`SIH zH|Xmj6OZHiXvqSD2xkx7Rs=p1kSrL7r*Zj%K{J~^VKL!_^xcRFzf0ddnDBDCzubgB z3&&mGCX6e=D_bz0JgEZs2WqWN1-OEW%Q_F5d~?`j<3}R<#iHV&zruNQbNB*ckQs+> z(`ET4e4jo?G2zJ(yt%hfPSYdI@_1-fL;=r=2i749NjUsXK$0yH+I@=HO6hl6>3Qf_ z1W(T4KaAuYJ{!R~;qavh&dD}PecejUL&(@xfQ)%y5^iGzyq(C30rN)Tp(T}gAsqg| zpxQxHpIcNsw9BC4@IHfTCs7@>sCbBqL@69DBdP*H+r>Gv$au&kBRTtfh-$q>#X~y{Dh?kqsP+=oF~C%Rr)C5V&Nyr~C5O$X44fZ8&^h=GunC zmt`&5N_$h*ssb+H5%***#)=rD;EfNnfSHOGXTkFnE#89PQ8b?gf2wE+7Q9B$5-s=} zMXP4PKPXyt3*M<{H7xjmQlQne0;d(NmIdEdv?L40mPTz0E>g8R7CcSW>RRw@6&G%r zOfOWmWD9;r)#_XDa#d?!!C$Ca3WrJl*Q;8p6|q^>(kytJs-;`-URBGm;6tjGX~Dm% zT0;vyt7=&md_~o=EqIhiYh=L_Jz8T6p6}6`kpAOc@SaC&YQdj*w1+HsgGXy-!P`7q za|=G?(MoB^^TdC7v`zlN6%YN4X2#t0Xy5t+$%G$5~z?#b1Z~nmc%DDE@Vy@ss zW$lPRbhEN{)E}5qMLXsXyjMlT4`F7buCJn<@CWu)(SG*_&Q{U>@CQam)9Nr0N1}O5oM8WismYi6YY!Uii^X4MsuCS;j(D1KREn%G#`n-P!SWV znnm!?BAgLKt{h&57z_TQDldWKzo}ZlwJZ;8#p^>B(f+DjPadRfkI}0{G!5_&EMm%* z!*`8r4-wVq7_)F5ni0dPI6Mn6NWtO7F}!dNFO5Oj(7!yeB8C^v;gvDGa1L*X;qwuP zH^p!r&EZ`!TrYF@XbjiO96lez_42R8(iMv(9)i(HjB^+UE3pI^<-_PAvx!H*&?K{o z!!W?8Jva>ekZgPo!^R^UpTn>Z$w=jJVJv5f!?R;KOTQ5tC9&r0#Y0dM#0H0_yA1Wf;ihzcoWd|pMf*{+M!%z=o`*IlCfoxw6LpjiF#9`a;qBMw6k&}_tE zr~#UdI1DX7vk`}(1ZXxoOp>rJ)*K@|v?&&nfco>mZbVsR2Ouzjk5H0RRuUd6qa9G9J=lmm+Q)xbA&teiGtHL>v28$Z}oYhR?DG1d*%&#s$1{8?nA1#%+Kl@0hoR)2$e7NnCZS;Y6)h4cj{<%Z)hvhw;H+Vqbp+oWq^tbgK zFevYpK?8>N@9{JewgNE3)-AVtp9gV0a|aJ;lRKnW-k@^2ez_xB`;)hNs+A3hmj1Ma zcrHJ0c=eWj2Mp-<)IcguUmxPhuJl+%o`>f5?U6Ug)-8bd!TGP}*#fC-ujCDB`Pz^? zgTb7^2=RKeD;`fhC9i*Ox4wCS^n+Qf*OMms>5TT#hOj5So`>~CUeB-~y>eAgNs#)% zPd1lW*c^9dTEMQK*p7Hl3-7G`Hdm)#>^9p$xI=Ki!u`e)eV(=jcM!)@P5c=zZ4@>i zICOBY9BMb)pghiee!gv(&1MtV)vyJ@k?(-hN3F2H|OgSv3q%3p1+nRd#9P*ho} zh!wt${HZ0aI15j{RbdOJidwM6JJD=MdU90UCGx3!i;xiXXN7MgOwI~Z;TC)|0KOFf z{~ZA1aymc#KLPMIz~qRD0xQFvK#(J(g$pd)YEkM&tNREhX(z_&KY*`}Fy%uu4d6&T zi6#~955N=$xPS-#0wN8FpWstwM07O(rg&}75u58-N=A*l2bgpJ!;uo`!T*f5B>D$w zcOxz6dK7>zA3c8*Juh0BKS)f3_~SfNX2icmV-!|i&{@P$Jkec%p8@}*>09|zyxGwO zobU_~mZJKoNJ~%1i=kH5%!ZxRnV%4BvvA114IM z>dIz3F=T~_mY56-TTE)De`1P5OaV_yq!blMO2t}5Q~ZNj(>zBkYsIH*u4e*MS|V!s zG@>v>Fh*>gA*ul7NT~~~Kwt(GLGz?mhOB!~qgzxI^B`rQcu+h!V-S-FRBR85BYHm_ zmwzJDj-R%Q|ACK z;0UXyC}DeKKrD8Ev*0HH|A;tpgrhi%mSAn=S(_`9xFZXOFjN#di`tSNE1pWEPAVWB zhQx1kd2rDYjv9x2a^C@O!PI!q()c4;cma`= z0VSdY@o?1Rq;@)+IP%GT3p@>$@8O7sVDQBMsG1fX6=1={kOfnEKOOZyA&B5bz*^x2 zQw*tS1&*>O_Ouejv>_%bhM1%ni&0bHxsL2=#*z5cudTcYHB8JGJiUF>`UuIwhj)9o|dZGLyfRDl* zhU<$kCGG=9eM2zuY4t`wGu+?Akx!1q#Db~UEOf8-feX@FC!Sh0~T@wYhc+w0b=Z zcf?%19)(YT7Wr==B{`=uDJ#Oi4QGvyF@ULo2}d-PJ;4Q31_6|T6>0gDh%%t?6~tRG z@jKSUI|6)Sh#G(zXEYoYGyy(on2GR-F$z-}t?)X`9KQasP$a6fDyFbjg6LLL0a0dD za1k7}AmM77J`G(8PlqEKYJu7CEk^}wWyqsnHnG(1-kyb zj?z$=GND2UriP+8Vv534SS2{3c?XW@DEuxQ(GuNz1^Dkn6G0J_kizkB^cNVW)};(6 zp74|b!BnVr{Fcr2{Bl5)HFZ2Wq97cxOF0tG3L7x$PgzmJeGK19uo5sOB7X&(R(cyf z^93NvJ_fET95JLFM+`R_D3Fj>0XJz`FyVxlz!~W7Y7H|qcFfjOP&8FQWECDnAF@X>MVZWz&R@eRgo{6{u z;G4}tVe>yRdQZWfhC2iI7u;F6bNZ%qPs^_1fg4~CSo}u=F?V>CC8uGXfcLVMw+%34{(-v(cOTA%S4QXVFmn)s zu-ye`hYNypzy*U~0|>^1QW+t@IN?I!!r)v%$RIq(#=0)>bYYFwdcyTp^F3lv#Lp(X zM*-~DOBZ`0?O_`}vDvdwl4Ej zD_D6}bfx;tToQOL-EIBy2ik_`<-gKv$TK`)E6UkN*j59&b6-1;bTt#rbk&S>?ehD# z%N@as8A2`R8!&Xpz@bBI+QM_9Ye03AxCSRihEL@8&tpqJ@>B~OWbF$NX5W6~Y0zrc zdC?`+H0f)>&+R*~S1xQD;JryEzBc@a2ekGVvImhZ>zI*sS>|$2llX-fL|0fn6PFB0 zSqVf=eG}1uOQnj*I#xC zV#6Amv02FC3m}9RHXQFU{NLcGmeSzGnA~VOV|@C<{y4%LG}`&p^GcV= zmqk~VY_pg~@Oi)X@UyWJ@nMb4_$FZEJ0L1IH4zWN=iBnb@_g-c2M@+UYD8x@Gozcc z;uW4$_46y{$oRnme!Zgqyux!?czVwbWdDds-Wu7TBt#n%@hA|t2+`I=JO;$%n?O8n zBAx)E1ckm z2j}^Q!u@L>KZ&ump6aajT2HNDV{f0eU+YPDsr!KbgNOKf=3{8(^&ir>aqB>x=&MuP z_FtK5Ly~IS%%4ttL-5;)uisGQ(k;(t{DxBB7KW*$h?TDObf~^~0$xlZh5fk&`~ctv z)H9bK{CCaH7OeL~v!`^=zAC#WndHA)zzqPy3Y)Wq?#l7(g>|0i>)e}c(#)7*0v`Z) zxje_-XsbSOec7+;JWo81?>Jo5`XNkeu0LFl`or);Oa1Ps^q}0F+#xvw2Iaq!-yd@h zD1*7Ug5d)QaL&(Kz`d#Zt6zHd3OV~`m{F%J;En}M#q||D)j|MO2cfjVa6{mR!VM$8 zf1mzPTxcRt)EN%U2)NhaUWXeAhja0ss1)rQ;>Uzkzt7YB={GRCs<@KOzbMP?H`@nnv_aWReIHLLpZaItE9!F>+*1>9=59=U`14CsrW_g)#4mxt~+4#Eo}Th$`D zvYxcr^SmG)c$ba(*7J7ovG?q*P1$T|>tv4}|DC6PjQH^p{i)-g<5A+&DJ=DtC*HAY zN{}m>CDioB1n&p9p);Fyz}tc~d9P6|Hf?=s;@aDu=JkZ}?BY>K`inKZ8LXs+*TbgP z@XCQRhBm>g2(4I)8s3(Rv4FRw@b(0&7bY{zL& zwC>yJ{md?AX0g4Sy+c{opr~+mqIsg1ef_OhwdWANt~UxF1Z>*k$zY#O^E!ii_8pMR zvbTHUSo(L~x~w=V%E2y9^VYUws%EL*d6PrUX)$*Y1?#dFtGyvCXSerp*5HV@3LBd2 z&5X^=ZrH@eIm*e%%+6|p`PK}kW@fU~>QQm5WSuvuAhlsuy6+)h4zQW^M>Mff;X@E? zn3Vx^Znwcn1gF;yjLGyTcr6g!Fd#uD66E*vCEOO#217YoY zzQOtZP1r1!mzn8H=7pxC(1&~+)sQ`&;;omGl}=UQm<(TCi?ceul=_+F70OC)1frZ& z5VI4SS7Gg|)e0?0&B{mxx*tmHmpdeHP=0P-!;q?5ru~FH2?t!%h|}zppNJ};FUDWHx?P!;Uw9}xfhJDfxI~=+ssC6 zR9|nE1kh!oo$C0KI47ArL1tD~Z7U^nw~ta;%Aeja7i0rvQD>yEQJ+L578t{UdJFlH zhw@R9AxWv(sgNrCQtwML6Bi&_bsH}N4C1e#LPj8q=XHY$u%$ce|+<+Qc^VwT;I zNU~9J)Cv?4jRI=kkVW_KRx3cRfkjP#V>Mvq*s?E;+z7 zbf z?jeH!na$2l_scB7l#A6>X7}@qsliacAj*PGO83UVC)vYbFq9OZPgH8f77M@&k++?ZaE&;+Od{ygoK?wbv0-K^*u{$;!6Gf;Im6`%rBedu{KToWkW{zLNn56uIf#0eZxdgHD z3Fe$q8|Coy23>}M=8Pg4f;~GJIx-_84IyJ>WMrg6$CAe5>JlA8Dy_UOnZyo+45~Ds zhMByu)JB;sLG!Anf@zdVmHSTxGs3T68X@U}3MMV3k;x@;sHkAlQh8&V3Wf;%Tp)^u zps8RQwL`|JI3+NKJ&mA7)*RtiD~(VgY9C9jnDiACQX?pBD5PjR(o+R-Ejm_YhgqNG6xaf$RJ9E(UuD zXQSi5tvTAW(Bu^4Tv2&O5L0o**&z*rifUW414{F=pO%)I%BuG8CKfz^rE$h*2cifN zgS1pCjn58dj4?Z;rKQo-8!$T{Ivotb%PgNAC}bd^uLHP9FGxdbb9MkL|C$}BFy77> zM`>x?q$r;XfJn2Z0uEbK0Szxq1vF5NsQ_6A7Mnq(_RZ`6%8-Iy5IoA4%ovPQP*MJ9 z-^?sSb!AcgxU6tZmSrk9Lp0D;Myw%cnOR1kpsNgGQo%g`2gD#Vi#ULet7FXjX(R{K zUk^@2X(_2hN$jvyO}y0}Nl&LajE{Tbnc^!NGHL1Qyj0Q*ph!yQG=a5;UU{OYw|XV& z5M)Ol)CYU2sW-8Mfurf2tCad90urWkRbVKIG}uD{{n&_@GL-}xlqfNh)6z21*llQw zERb_`0sp_$1x5c$T_6*dlI`_YOKW6|zciF$X%o^Hlqx`9RF7@MyDE+7cIO6_k4Zym#@uP(8~!T=sZmOi z=}$pAlgu9jZwN;LjUcGfa)C=DdOq2k$|fy^8{DKQEW4CuIb#CjCNF{k-I30vi>7N( zRh-|g9Mid2(}c!uHS@}Cc@d=0QIy$3NJ$NVya*3JaO9?NWn^l0u8Rz!Y&NR7SB*|f z$)r9jk8fyZlFhUh^}P`p(2IPwr=+YyM{iW)Kog#@O>B962j`&y(|HV8ZGPpOo(ZA1 z(l?~^mAN7@Cuk($;}2wDA~0oI3Ll|FM-qZsP*=eCAn}EPN;3lW1s{-w#w2X$Vu&+1f|8#aH@KF_6-@f;TEYNJSbca1G0Rf5Wbka$; zIuO}J0cCLq!y*WZ2!iXV9TWw3RJ0rg0cCVXQE^^1I*KBqqT_-yxTAuigNh1@46c07 zsjAz3JITB=@0TBcZY`%yZKqCcr|->yQWoiLCkOJdir7|x@@C2zkD1wBa+f(Gs}k{; zs1Q42mcb>EuDnzob`&#ay-*P`Gh@cfgKMz3p6ShuX=3b*8Q06!;EWkBFB2t1iolGC z&jeRp|Lln2Q$*Q{c?Vh*e34 z>5(DvM`y-#*1}4+s!&Njcw|DQI~z=>alKyG8H?C-R}XLKkw1`1#beZtG^I3OmY`L} z^b~9X~dRWU(cD%s|%;X<8DBGSv=4APuW?WX_ZD zc)}9I(JZDP{kbq(w#rMbxTWS4`65^@yUTRXiM*AUGJy4ie00T(SI@jsEaTPPi?@LU zS40uY?2Id-lq`@*3P~yx^%4}u@=_6MQ9HU2`k+B;6H_K#7*Zh=6wwq0zQ$_`L(ayl zcm8lnZ-!%LYSm*ES>QZ^+|qp>i$-NGvl>ijgHZ|5VBJ&og3F|^T7{81Ace80J_XP! z%*GfM7K>^f8c<=7$~sa~WK@{=OdxtDP>hs5$TN$6DM|wsCYkwqA{NzyB%{IzNS|41 zceV->hQZAA&d*n2npyu8l4ewxm7G|qR&)$2tp*RS5he(v98vk5offi+1|m^jnbsI- zs*EhjEHC|>NDF7mr>ZDTE68+EG|kHu+U=slqIz$G zDmH4@G-xbZrRF{s=_#itfn))`Wo6Q0S}n(-m9p-)y~AObtZ{s`ERl94hTgO181N)H zIyx4uC>0&urvg9PSHkOSXc)?9ZIBdsRINsbyQK8=O;YmBtRp2=uuw*LEs+o-73mV| zBToY1WDAjrM9iguV`XqiNBXTKn<+K_u}G0@kfbkc`;v1&0?oQXx;G<a zi6^v+`EU$A)`OiI?e_pTx2S)kp54MMxJYT-+S& zS|S}AP@2+calP?IA{pCyxK)^4Yb;)-9$7b_?U8Y*p2X{`JAx6z>?KZly(JFBvcl1_ z3cZ!z^0fTM;_*r?zbV3Cj*y8UW>q26crsczRMBOV>evR;!fh`as71WeNHaYk4dWB} zEh9sM@OpBcLXu1o{JG2uwr&-XN@AtIbieA&yyl{ZvXyYjTC(#=bv~NF2(Ylq(Cd<> z73%OZJNMeHtsGLxCOUIaBVM{QtG!7iW5sFJXQDO!#!G-m!VUv z7J*1KMv5@o;-Um}&+*WKejAvxZ|Os6JrisAT0LkEm!ufFVwzqCSY~~oDKtMb@Yp*; z%MdwPF1yiwR+Y&qi5z6u0n@v;$xlwXwdN_ZA;M2kR{om@9Tnb~|;dSO+MUazKPNftBb9Huhbo4Lxe^)yGG zRO)Pdkx(AZ&{!1{H5+;(^|mq4WLk}wOhn)~Qqq&GQ0wUj3j?W;G@h17%|;6zitnbJ zvbO536T=aYyUPVz+V@nu@5V^s-UZ>-hmr7*q5+6uX}PF$>&Pex<{U1`Yz6cwwsDK$ z!m2TB>#X5|zVGFLr6L+oj8PH)wBZ65ylLSkMlaZOf{TK|qRI7YNk~W_B5Dm6;&L}Z zFx$F};ewb(^vPaED3G-XELYFUS!w@qz40=ULmC`m0`Wo6?T$4!VHz|S01SLj? z@)W}fnVzI5)`mgfTj&ruCbxxbV8ftwanODt))>Us6@XTe2teWuOX?)wfh642B9*Yr_!S?ZHcA(TDZupgUPLXIg773^{p86QdxLg$!KWBVCHtYDBgT@xZP;# zX+(&6NHz4$ioV?-SYJ>|s2+nnMYya9Rh724Fw>$@FER|R0fSUc+KX|NeZe6$(`RRf zt6fPQD#QtMmm^QJmZks+Bm4G(UVCl+Or}h?wommeqNiR_CUTxb2V`V8p>IRPJ|QTl z2{ZFXi4AIxguaz%RC@#s6lBMdtv%S|>P0ixI%V~=2RDZ@CS(pme1tIFjzpyo=4pdb zW;rMc=nx~O(S$!2q;-bWD5x_meU`RKRC1|?fkG2WuaDr>ifFj0R~A)ojtqCJz}`;! z9x@(MjLeu~JE5*iPOyLpasFiZSP@zm4D#Xc%ib#fb zO|Hk9?qrr{QjP{Uk7!JD^BC3F0Z?f%vx|3|%1$i4rGh!C5JK4(kTBf=tTRvozEtt~ z6TiAdur{$07L#4OEElxGl$J2X7Df`RPYE-@ScvIh>Dn4B6?`&1?`6Zu&gsobJ1+ox_CsbBYC2BY$@R&JFfEBX{LDi<(8jlT`at!CGc8Bq|L_g zHaOGd=37YoNdSs;@rf$8mI~RSqLQtpg0{7>4Gg_VmR7Bj76~zP0G0~UM}awjXfd>q z6qz|dd?rw@B+^{VQnLQ^EfwU}yxtrjnfU`sj1i!g(Pa!R$y}@yX zdSXzar&P3Ee?8yelZzGltNwgbR%%X@gqOZp83r?51knJp#1e|^1q&2rePAfGtpZ0o zfzC(8WNa16^o_*<#^{MMj9ddOtMv5X@5HsagbdlTnA&p; zMpmIS!fmlvFvE{$V_HL^8)yx(wDt=64hxRtls+>+Ye=eq*67tn9|;&bT>|c1*1uTN zK@IE`X|0bvno9-Kl@@zJW37;>w3$=0EeznO4-KSSwNa4dt!*bnWK9b0x?}<++}LrI zRhi8oL)MScCwG|?MnFS*}ek< zS5!tOTHEGvjH;tsF`(@BR;x1EcSkDpxU|!)C^(~yr6R#i3^7c^X3Ne<(@9ghESaPz zWZ^3X3?@Z4Nuh*JWP=(AooudYE7?x!DM_Bb4FV?%G_tW&U>1>1g00pnQbX&Ar|hm@ zAFdnrG@RsS*Gf7&=(VJn3}ueWoCfHW!Lm{;8o*9u+@sklvl{Zx$NlM#^N&8Fcp6>( zTokZWi0ciPZ>d06q%9T31VpF8znSHky`ADFKo+{TnYrW_y=E4ccx3MIEfu(^#oD%Q z##SMyEI9v^_LgHD-JvdX};iO&RP4ZL_oN(-ztSBTruim1ubR*yn5OE;t}t+S@hI7hSo zv?*>$LK{k>$OvXP5v+oq@%+0!EDBg>7;^eXS{vudRtRAyF< zCxS{`3=e+0}k(}u|&Cu9_kWgQPNP%>Y+Mq%RaL9^=0$T!E zWSgG!r^9;EC0jBH3K%TJ5(rVY#3c-ygk7D90K(NQ6sV_}EbOln8j<0OtQD5Xa78I4 z4=(IeC}=ygXxYOfvd2);UYj$?kbrc~-0Enr|GS7%v(6_iwMAd0x56Nx5OBYh1r3Oxq!wZS{6}~BBQay zX99yiScyeb=8jiuEGc1wg}!9ws|7JYATQAoW}%O1MEch$+MTVjgkfeNl3H)g#SnRh zT$aMD|5!SMIU+z+YF6@A>p>@NY?f2L_*kvaQFeNToesisINGJCZOW(h=V`g2%$Cve zj3!B^mIIP35iL(3$i7nK#vl2t&^9N!{NjazHWA^`!d$M8CTfO?Fqvq(6Oj=CwZ5Uw zQlaH~nCTUUoR5oU@jdF1+2M%3UP)_DG2}yn=@yh}_78b57%&5=;Qc=qFAA$QW5Vrk zTOQ7xEYW_FK&O`J`zEbQu_FlV`Lz8&MwLpWf1i@xOu&=m3@?!&V`P9IjVa;vwJHVy zBBTC>C!G|rvPK5FJ#@aAC7`4V7T3t2B_bcW@V7$39!$n4fy}tJ5P?Wzl})5JLX+&Z z{Ggm-QBiDa^_XxMX{r<)GA)@USZ2N#LCXjjYFH#q-{$dCD3i1N`pgFD9gh^sUI=M1 z)QR+AqmF=7Q)sR!J=JOot^Q+}cx&x0j*O@Zf&3tgg$U*ie!c8gjDW*+w74_{P47E23;k0M$rpzvs5FLj((;Bt@ALGjs@ZLjnKd&IvmYDA?}&_< zL1~#aGay5{JYZ%Z>wZyLzO>N9Y10#ypLp%XtSO9@7ahYT589Q18ZEKfQckU03`1RP!(Wn% zSFbq>jF|yLNG?7)$QVWk_(M4@r5LEc8Sa)c$C=p_{s=I3(cH(E#{-vXn4yZQGlM+K z2wIy81O~aJZ^X)gnrJZ~k;7>l7`g&{r7Q)h25;EN)C>upJbQZuhMj69cM15p3NNu^1~AT{e6E zE3IL64|Yq)J-;=Wp#st{wpI0foukD!5R8=cX6rjA4AAun0gCnk|<`#t~szFbOo2!qC!Ubn|d_{Y(GsGF{ z40DD%zxC&R9xf@Jqnr_r>v+!5&N0qNXOuJADR7Q;j&sI1W1Vr%c;|TM1gDz#6P=Ts zlX;%voa#()COW4%HTWhulbtE>o9dkIOmn6?o{HXIB)Q+TyeQJ&b1ro*b5c&Nv%t9= zsw==k=St@)XOXkmxmu^Z#<|wHj&yszKe(-GHKBsfDEA0Afx~k>c~3*pVUaxCwVM;| zRhP@61;@Uq84Y({ayB_HJFhr@b6#~`qad%t`VF3&dA{lV9oIi>$QGV&Id41fSpU1u zd$`_rK5({@ZM%ixSnfXOUpPlD40q@##cbl{x_NHCTi`Zzo4FykIUoGvd&t%MIu)tr zKa>`oU}dz3o@ z_i*QER~>XEKWn0O-IGXhvZXkM=c(=l>znAFhO5S%{KsD8dpU!idJKg%uaA)9} z>7MDH1~4EE^sd=%PZW4upRDP>0ae7au*YFwR??wt$Uq&y?cXuqr1et$-UXVh47{B zt?q5Ea&LG4;NIch>8bT@KfCw450F}w z++Ea5l}s#d+3W@PMfW9wHo5A?tHPa|c+NYnS~9V?^JwXb;m+soKi!?~7w(ttSMDz8 zzP2s$4bN}g-GuD1A>Z-*-rei|VEy~tf8pBi{^%#}ZJG*_oenRtHO+`nwdv#GW^-)c6n*z@n<_-6b^3-oN#l2IK zZUR&jz0>%=#xr6viRWZ*iZ|8zPxq#I({T@X&hTb+Uy3%!f1?_%%wxGwQ7^)B;LP}Q37-#H6#T<%?A$rgH7;=0OP8E3XbO%v-f4FZ6swzZxd@%%;3$N*(%6xL^9sFkMvNTO%#<^kgtqt?veA+ImB{0QYl$Z{Iej&r(U(CRwdKK1KnOV{Nmt|IyKWHCOD{>>J zs?vMH&H6Mb7yFck3Gly4Wu~ZM&bYBdPpDD<+Qda) z>Xz`Be=nxq*Uzg}SBJ02+qW?s%QTY?#E;4 z^WmZD&^yA@{;wj~y|7%ipGJCEsrk-Wsk-T~qV{U#XW@g`J{POa9eLByq-fV>YWqiB z)8W0;UD2*B)Yvoo2ZB-^BYA4`vT#$?{rbLPpGDM*#+jYN;iF2+j1=?sA$|c}!p)3+ zUd-mu&%T^rLNma0*=q2VTqxd{e#4EqXyLHHa^uxVB6FHsh2>UJlFiMW8Oh5N;Fc)4 zNOO~WC4Y~F@sBB6Re)QSEb|);b9NH5H$7(4ar!y)<;_FovfHCXG?IRa z1eI0y-yQDm@zf@=qM{C>#-=t#b;c4Z`arntA+ZGK*^OySGpzKlvy78rwd$jA@9Yuf zqO+HUkH)^KYjgG7jRP7TN>euV3=So%c=b>U2w15VFrHZgrf-p`k3P()WVC2;6$5*} zo3N=8Zo{$pO^YjTGce2RaWezc+#N75?NCB`)7;dO<>5%YltJsuK5oOT(lXPd(2g5K z(@)B^q7>xFs1_45rg58bgKTLHK^GZ2X+}v}U(sz+Evqo9ICKe&5_2w7rSCVYP!Vb2 z)}tgp4~`Tp5Go_1nVhxgF_SeIw8e@HhAQ*Ja6K5#(uWpiFjOS$V8D?*7-Yj891P`J z*RT&m&;0j;K~I~L83Up{jYOw^cfijs^cYB=7wSDTgF?>L%$cG-9H8NX=M@ddK(wz~ zwJOrH(TO=G?>(tMF%zgKWFs!5Y8IuuXP+rb*WA-qCw2B)(foMAVFW-~aRT~A+M;!n@f=I4c(6f#OBg?^I4JVmy({+7FAZSbIn3HD27n21A$2_Nf1 z3qxb(G~F`d(dx=1DQ9F!9y|j)_3Wfo1qHG^ap<9ES(@1mW(;U-m9)+>DP-mnmK*>+ z^isHs8`Q(Pw^3a;g>TFKJIlxp>d8&vn7aG7aK|>Skw0F@ z9C*dFn*3n+eD&VCaJMWexz|d`efgp9+ZieO5Gk3Mz1aJAQqqy@Q-21epc#STRXdFc zO#VUI)?ex*)#W!O7uJ&!c}p;mS^{_eaC|| z5{HdcH=QCawp1)5gxbo9?jIFibTL&CJk z{8Ue5x~!AKF|DS|@s}KWnFFsQ^<~ zUVkP(w5HJLpOaq+Zw{%|>)2m(y_y$9X5N)L)##%u-Z6=;dpAGyYd0fl54LcenRRS` zkIWT=`%?X;Qnb$~{X)`4_odz2l{a`#h5UeH7JIH&KMa>@^Fj69j&RQ$%t2JiN8z5W z?4nrG)x@fzGXEC0vbP%ghdM&J?yhiQo0yrZA=0EGbS!_0%k|GJebPo{E@qa(FwiMQ z<|Ji{tdwfW3Z02L?bb`<7-~dM;>E{gk@}fri5wRWz5q!&v#^!*fh=r|LW$|SJk_c& z(!VF;OpF<*U78zLRC;!m6{XC&>XE`opY9C_GgKL}UX7431k?O7l>Hh~2Fb(-N`8G= zLt)JUfH)As-H|^|qS}HMZP+&0=kkS*+D2A}!sY)QySAjk%X{l;2%_GcM9s zm3$ECm_NvwNJuvc>DFzcljM*@PT>C-7%DGt`@Tkxrt^-tunVZ#2=J zKjw!%?qSqd`8VN_2YFX4Q+p1IT#Z^xgdT2dl8h^e zENklhvfjj8xuGDm$Skw!Zfp~o-^{!99TRicy9J>YN0>DCbctNo)qC+)6+N76-ngx4 z=vT|_jl&~fHuc`RU&nYKJ#gQk;gOc!_Ls!Zl|`q*7V6RuF{J!*Q`69ama6*7X#2Wt z$46%6d*8iNH+o{^fsQ#VuWu%ApPs2kbt){(ss8f~b+s2p9_p0y{tG(%^1M%9Y!-T} ziz&(LOCuXvwtQ|!v(TubBS(y@8DBlBk9u=!q?=lIPoz(d`pl+T`FXR@+PF!xaCM|h zr=0heh4f3V^FCP~3VoU|QPt}sn>**c{*I11U!Ai$5z4QA=iN|f+d-zRk9-*UYe5;G z{rD?iJ9&yvAcDg|_4+SEp=M9<_V1^`I$l}+E&;tI;2E%5-T8T>TWaxFp-}O&_}7Ey zzy|O<*a%(#FM{JH&z?EeseS_5?l0lr1YQQOfWLuP!E4}k!29rbK-X1xz5)IX&+6-T zg+jZ$F2ZgzXp~*u3IB|Yaob( zZ=d?;t4JsB(ckKR{wnfo)99l&HxISZAL=EK_ket;_kG%83lVuA5U>@`4m>OJKg9P@ zUEh6?WjU!OcQg-m+)2O};7jlo*af}@-;m@{A@~;0ZmT?&h|6aP+E8e{7%`L?O@|v;ZwZE6^I&uR{8G6IGH|*jeTM7CFgv>Zbh`+333W zJ=U-ALf5@t-QyP4=04Co^p6}B^$HiML0)0gx+lECVXphII*?O%VeZ=Ip;4}yygk8- zxcBj)l<~QRt<}~4NEE7BxrGIiD>bREeWZEleARtKvYq<0N#Qj2FKR??;aREwX&yRg z%H-3FPMNHC2Q_K%aqJ$+ zBBuv7ko7;1t-~AnNVcJG_@Qha&Kh%Anib#1_5(8?%+4XS?zU!y@tl<&Xj2dQU#O=%%3qKnXY$l-AueG+3~dE3E)I< z5|A%noXqnSa4MJpWVLY`r~$-Rul|sfvnS!33?$_gFckz-o{oPSm=4YWGXR3EB^%+c zbY>E8CO8Ys0%wES;2baq%mq@Mb9v4~5|({Lwo}yHWr=pFiwL_I{2p8a0*oD5E?ovv z-~wRAH%!kDtwE;VsJIM23!lS1J{Eaz>Q#uu)c|8>(j|@ zCPWG=$>iB+G80$5Kb`89|3j*^+oXs~NpWj#im#sFkjxZlEVJ7Q{{uzbsgvD-?@q7` zNUG)FF0cZu1b)p{;l7(xE4NE#_uyL%{s<)1z2H9ZC#nCRfuHPt+z*iKT}jqv4Za7# zL*QYsmYBWim`4ba7LpjA)k{9{oBl6^{11?<9tDk6YYE|xQUB^q>12-+^xrmp?WdAi z9VwmwPXfv8ub{Eao+A8d3jc&owGQ7i;MrWxEhX7{@Eq6xo(FzwY{dNn$#&~xFXDR% zYyy(%W$+648+aA?sb0hVI;sA&L)!2Se4D|W;P2oc#B5B*q_z+wb(Sb;#BCC#<@YT@ z-UgD@JD{<8Nh7`s!`nZTRPW(?AAA6|f)Bw*;A5~2YzLo!Pr(jSZT{@$p>8Po8Q#yq zKY>5YcH*uD{xJIjw?E9j#Qhc61&gJhOUCN8yAqvJ&Rzn40FuW(@Gl5n6@s$;_Vb~6|2VoEaKEp!X9Z0owr||2DuM_ADx`3|4td*FOZup8o z_q>UQVGle#K`&4Ye1^So_aWI%NjCCee0{-LRJI?_{$MulbHE&M2!5%12{;s#s`V=p zT~h16An_?t0?I%Pl!FQo2bG`-BtQ}bb?IUF4+lqp-+_T(5U2)6g27-2#asO)IW!xJ zZx|R($P+r`D10MQHfW0kwGi_n7TylUb@KU?lLYoY8j@qcNH7Wn%P<=MvEVqkF8fOI z8G~=E4OuH8Eyv*-4~_>XK(|TLorv!w>0(K`RTG{}&?(?lFoDqh5~^pxiG-X;p-uv) z;Xaw?Dd1Ev0Zas^ff@lRAKfJxPl9qXm;$B}`l^Jk%#msJbb_XVliJ~t!8#pJnq%GU zRf!t+$TJ9=0cL_T!C7DyI2-6jsNVlA9M`zB2{;GL0ds**c&=)7PvTbZ!9D8UdlIAb zf7=7~*OTR=Prd89uTH#Nn%eu1TU@i*xtMgn2bX|L!DWEXslI&+6wAF@ybHkPK+1as z&xO`4{{KJJ{QoBWFVm^@Zzay`y#8&f@VL8~;=T!_3V#Q>3hME<6a6C2hxk7NAA@aR zJNP6|b>EukGST@G&sSg<_!@izz6HC%9`GIb9_$4_fPLU!U_bZ~{6sU>zDpUF=KYNK z7w{|i4IHTZ@$E!zj<@oo+ul!%%G>-+FQ@2RHSYby7v8pQ>USR`9?P5aZ7*liZuR2_ ziGHWKT%&m)2Q&e>AP?j-Say6OU0HyyDQE^lpgCv(T0*h-Qz(uX9<4xYa1dw%+JbiZ zYQfgT5y_oGrFY)#2@M0;c}GaUa0fB(yM+XG03AUm&>3_AUDf`riRTa9`59CPyfX8QKWACD6uAQ_fAUIRkhxpXxHHm;_d`;>T&xQgkSD0!@E3R zJ-j0kRtrB)>`blxitt0_B;X#RR)ar+d%=C+PhiS4zQ{L>Z+}j6rp-RxI8Y`e(+&7% zNbU#HfDh1s`z1ynEvzB*LGTcG7_0@4K(TC>Pw|(0mGfDmefR415;ROo@dQLqg1>^N zz|&w|zWQ!^qNMxEuc2C(r|mN#bwM7;2Oh}DQO~`V=%Fszo@j0UJAHd%N!{R2663to z&hJV4RjX%U_bgZso&yKyxeYv@2OGf);6?Bfko(-1!7Jcz;8pM%cpba}HiI|8-@!k? z7Vs8$8@vPF1@D3PL6Z;oPgQ@G=v_DPv&1p^IXkXcT6g`fL`9P>cVD;E4Yien5shbg z0+}PKpSezbygSj}d;dDMZ+D_^^Q*3hRDaX(=Id4eJ&A+8XRcSr?@1JSpIoml*n=9Z zy|J$4cZoh;yT@;VwAr9ROjp%>8nD`_e&rT5VsGNl-r`%;-o1$d-uheXdj60&E99+R z^VpJP;?UH)LyH}Ov~Rl+e0msoxczW(`{8KAbhxbZq5cJ|`-%Nt_e@#Q;boigh z*EAJnc&|>~J~TO|!>dm~?fuH&{9atSGV>l_RrsXxh9%!BdwOEABgd4#A;dBXjvhBZ zR>MVTc}>l{8I$=)B-W!Gb_|sqmR(=$temKt4o{BrRz9sx8=fpYr06s{mAJtr$B!R2 zfRmJ+Pm@bdIlu~0c99&a9awMCfb?WZn$w~RUYlzzYY+ci%l6h|PJmq64ws2 z7s=yqKVf0q5eZYvk4yFpOYkIuiwNp2!JtQh>Nh6YQ8#YsdBsj&!ushr^~{)LxLDGR zC%lxfs19d+$ukDZK?R7{4OchDY^l{=P7?OdL?^3 zqU}?{=bvkeG>qgF>6P)xZfeAsR z7z@UM@!)v%-k4;csIc7lA6QP9XUcT~$=a*ej!*VcCyh;Z)@iGVlfQpgoXs}vX@1(? z>ThF{UAjn9uOUu&%U>xyF5OX+q3b^`*`=A#H79PuJT-P)vUf_#dpLgiYb;MY9^$jk znaUTjD{5+Ho;_zMw8E#BbkgpYrjqYz&%%Iu#MGffb^Pjo6Mun?-#EWG7GzK{RX+5q zle2}QU^^Nq*t>I8zwybgDJei9A{r<_)oi{sdfx1*^G8SywvdNg8u33N1)@PFOQV1( zU@ABr$ltrfPs2SONcodu9#XenJmpWOr191*;oB&$`~^E>0`b+if6X}in|ss+rVQu9R*G-|xUj%c zXPlJml3R;sf%@Y3WX%ZSRS2#8)z4##%`ccoDYVtQz9El~-O>w99+yiVYShWePPtd( zyhc58Lh^z!Qj2|1>(T~tXiX~llkjCWJeWfv@zq;)lf$#_ew)L!I)};Al5JZo!Fdz7 z8QdZ{wN-0QOpeqNy2-MZiUhM+Xv2fqY?Ex3eMdHThW1}n>@0=ftw0*Olau_AR12B}y-HH4`7ECD z$DEQ@N*f82BJP$rILY6Ri;JDrxc>;GX!nBqz@NaM!TsO?um(ucg#JO?4}pilTJVTE zZ$h$-y7r`GGqwEW%ag{hFS#yN2 znn{$f>cvz3g3VkjVU|U~CB;r1?k6mZC)Hc0B#${>lCJ*`NtcmS^weK%(x-Sn4c38Y zz_VaIcn)j;&#OHXk`Z;?smY>=Qp8J0FZoR3S-*%&36mnrU+YUvJ{#d7wR{1*2wno4 zz{}tj@Hg-(c+KQfG$C1_>#_Gg@Ly>8zfM}={|49$-UNRK{{UOSTi|WLP5Ojn$04Od z5g;l54ARSAu!)1^-*5T9OIqRo9(W&oz|dbaE7?KqosjID5KdeF1E*z|nU?s(a{83# z4mDz8a%#0S=*2_}n{u8F3Pf1-`d?*exr0)M&1aU)=RE(ZzV_L4C0f|L+X$N~;;MK2 zrrGSUY<5~UU-0}=-E^8Q%?8Wn5}x%-vsKtEuDwl4v$)oj<}1r)7tgPSO?!28O>*=Q zso8XBq)0_P>+`B5top$P@Vc+<0>kPX%j#R6yTKmyVNEiY5>6jlPMaFxw4X3v=uWb% zzO$^p=eZaB0PLh$b@sG*^Cq7$ZJs}8NeKs$u6_wE-?|$oC08}67EMx5QDyWL+~rRO zc>|3>++V=|sJYXU<5EX0MwR3J7wDVI8W8Nq{UaEFy968xe!?H+`7_TL&tG`*Pyf}z zqnfZIf!3iYD+wEne+bxn75kz^W}hSpHWAm8@LqD({tLtc2`nbCw?sf(1)3ZF&ZMi0 zox=z}9LQ!%GLf(&@c$0%#V?Ssf%pf3@uc4cPlvE};9zhGVKadIZQ=QAfvo%03)7Q* z@}yVSFH+x4PnPH<(pKWPEK>c>NXB(syTxky8OgFX(mTfqU;bn=Dp;)Uhel6Qw`YYH zJ2@1}uS2kr{PG4HN$MqkfyQaHZPMG5DU;{ToLV#UoO$!loi_PwRWl>mp`#S8l!}VR z7ZH>U0QAb*SH z$#42x;DH>_1muD|kPqaqIhhMx0SMAH#or8snyT+-CHs{L{~bW{CEX00u6ez5E%3Jl zt(vN1&rbGhCFur1E9t6hm)9*mJNaI5YTHhR>;`u(R-b|a9hkc-*hCEAu44-4&XX}c z*vMd`AI{&*Av(LEyFaI#7!yCRkGn%QjlDeAnalH5j<0Wqu1`nTQN%yfkKaqPLt1~h ztM@xU3~`;oY&ffqb)C0)wmijk#+}xU1>i-lGm(Io`K9&SY-v~A>^fhuoxJ7_*EzEg z`TPq8GF{m;z3Dnp7*F5sI`ccBzJDRZE~M}1$%?aj?U&SLfvXN)nw+271%t1F{N*~; zPk%+6x0hY)7IB4sAZj1D?ipHRmjv26%l2FpVDh_WyX?KXLrKJ54{E4&- tsOn!dA!WSwYf0XWp>zPQo5hzi=y9C2-->hd2AofbGyedCzx1{9{vW#}>@xrW delta 258570 zcmbTf2VfL8(>K1-?p{B8uh`dYb2cRgLQ6tPNPwkxNFgDl5ITW0(vv6288BeFVS%Oh z(7SLkYTcfCkN$U0ABsrfz9 zhIA18+9RoGaRKp9gc!U(6dypZ)sF`*Lb%Q2;f^A`NbGg+NKS|O53(EQtjF>FxtKit4}-d zRL3@~G1{pOt42F>$d5Tlm*%{FSDyO`ukk4_{EXN5oCjaD5&Wp%tqo%<{gNa7ir4#^ z2j8?29NH4ox3LL;XwpWAN6@s5kf6O{4n>?uyvb3$1vsQyv=Pc7c)N}8GJYPR#4P z>)$1&*gW z@Uo8Wgwk3KYsmq=cx`n z=-6IhQ>RmVW9oF~nIH317hcx2y)g|xX)idKNPo(ae#SvRZ*Pps7wwHv>Bcj^T6U)y>EEx+xEuX`;Mo+Z!eTV*$+JRV|$?pQYuf?Y%jziRg1S*n*|W*IvjUh9@OJO z{r1L?H{irH@D?Yg1y8+g&=jHX@MKF) z+q;}mt$1c@9u(t2n-0c|YTLo!Y`YFzY&#f)cId!$Mh9bjI`Oj3yzFD1>e9hrY*(K8 zq=WDu@S^OeJo#A%L&iSuV94PY9Sp73jU)Y%BmJs_P)r-_C>ddT`Ns~%(5oDxCU2+~ z4{GzEP6vZAb$O~D59;%v0S_8-ER8q~jd{?72TeIhGafYOnXeLYp4pO9@h*pK#rxNq2gNu@n~nzW+VY@XM}vj!d8z|Xb?j*Hu2Vfi+<#R%HeBv zG`L)=qtUV29R&{{>+qm%M?(zi@l<_Yp#g8aAx|~xC=^45#vO%*2%7NBrW|K84%r+5 zW9aKV`37(PO&+|(Yqa3?-{zU`@Sr6R-sM3n-rLqZRgBkb(~0x76IZjHxV-Yr4xNmi zbz~_gv<1)Y+zA{h7aQVQw-eX8yy$ZjfzB^@svEEVB~N|DgReUYGC;oJ!M7abyH17_ ze$Rs+IvH!~k36OFpeBc`#Z$FWopGcNM^m?xp+xKPChGIPG~lU*yka8`(wNiRq?1q@ z)tmC}HtS@ls^+}j>%0?h@Ze1j@)k$df@i+Xus|!l!;>v};k(EcZ-sJ0RFq}eEE6hI zpC}U1RGmmRDu}XZp(aW8nFT>~Qc;jas~AYGW-`fCEG9{!Xh$AFXc37V5+xI&GB_hi zgnVQRP&1JP5^6vMlVlQXSQUs|QWgoREdC%+6ACG+S_PXRQkrbF5{VK?mPG;eC5wbX zv=ISNvPA|$p?Hx&BreWeQZiArEeMiHq>^Ycp=;l@XwgQZW{FrN3!0Y&L9p4ZBKc8} z%rV4nC4y9`QY6+Ti6KR?hvb-&F0*WtsgrvQ)2qK%NK%RreXt8ARx#j zMkHG?8KEG{05(bJTScn{tQFB+(~Iwhtb&~iFIh~cSTF{RmF)rm!5$MpO~8+q943nP zkt;hv7HVVmiXv+QuNXPT?Y0UrLP)a8gxE@cVu_(t4A2;eIZcW~L+G>wuA!bN7e`0X zNpwR(Z?$&rl+f3LSi@(rgYT@}c$;LidL$}POQqMe3GQH15!7OgZE|A^{=I-?vIa(3 z+#sS_YJW0-gaV4vtXUDUtt@=i?Ngaj5Nk&BgiwzpIe}M5NDwGwMIf5h)4Y@!F|;Mc z3Kp;l4TDOjNYF{h61Z#vs|2S>a7fxOp6anCvuyD|M3|fbNZa8FMO44)2LVDO0dEO` zAUG@z_Af>TH$-9=A={>R!Y^3u))%ajB)wo2!4V3f?n?%fWP#L>-hw>YT8iSEo!&|^ zRZf=W*WS$}w$xPgfPKtXse+}1&HlC|VNQH0OAg46lul~O)I>#z#ud{(@dhhd!4fBd z9HA!^;tX!FE(x+=p-GT4aNa7&DHhOx4+v#4CTXj^?}~znYQebY5?&JJ?vNOe$7-{o z0tN_#;IsO2{0?RbN~hHgQ*3UNg~j)8DSE{pNk-u%>hUmk}M<+md3~tCOckm z32jRle1ir7L!2P^DX0e5`9Dq{m1GhF7|cxUB-w<8b%WUff%hOEGE8MN0|ml=e83dq zm11HfhpCkZBY~;;J_HHWV&n{>L{3~0NW36fF>q|cfn87mpe`84CcT8F0FO%Oh`~NF z;^ln2v5D?=Aam|AR#FdoYi6-$C^!1x&v#I9BwbSI<;|IjvcB?Sy(vWN^(E8>ffgcG4w zSgCAwLd{~@60io^Ry09aoai7bLjlK1V5`iA+y(IRCEPa1qZ|W7Vg^Y?eFud|TP&Ee zCXuz{6sasH*%+mu5n?G3E4XAsOKjRPMGmo#FhPeV7iCi^WIM%J6l1(0Z2~kTIAi?f z1xPr}BF+Do7vnMn@c}B?W>@SAGyn@ks|{@+$EHvlaoJ>a9wG+1jfmAstr0W|Zb8$6 zCZ}08o6RPZgE;K3*nO`+jaen?_PZHLZa;C`9HP_hHldpilY}=uie0wjgFFG5d3l6o z*`YV8zWSW)IUBLrsuC8%LTn?F-Nya|CwoU&oZ9T7-3~(89}D=K*oj>>+3=6ptZZzE zS$LBWru>ZS=v`586pKfUBY;tbB9_IXrjW&y>J-sK zGZqo_lf5GBC7R4}Ra_7tEK!(&kaQD9oko6XVroLHQg70WG;iM2Bqz!y(k>RP5=tjR zr!cjNkpdxUSQ~pnBTz9$5IPG^3ng(P)TEioj@d$-CNrk3K+PCBf(Ef1QL|G(%V?jm zUXU@z0PB3)0kuR#$&yH8F?TSa7HCMc6bI}~jM>Xcoo++(SS)s9Ar>4Chk)rS+3jwz z2kXLXUJKUCS_IQi5EC&&ikl$%VHD*lkXmRII9`U-&;T+q1=zd=C}Jr>k|`GJ7b-(F z8XwGjRs(S&)s&=oqJ18$8v#)jSY-y{V}b-ND)^vUEdVxVz7rqxA7f*JB8I9+GI~l$ zJXc7V8Th~^0VA<&gRMY=?APuw4wt0hh8GcPeBP`PB?&5vJ_}Qnb~vf14=L<*_^~$ z3O<_%{$Neu!=i|@7`n?6U>zRJaf}et9c<~1U}Xl&&|4a2iv!qGudYaK;2M*EbQpXn zMVYz-y$pdUR)K9|!$*`HW9Q zl>j3gfzWvcs|1zDRzoz(5SgI5O)Lu^^on{-u&ay@j79Xsi@r);wyJoU*n81gkV&y_ zn@m=wej!0j3`{K0v+gf925hb zu`phlCW99gyBwG*hB1N0As>KqGA6--0xqUYK$!!w&jt`}vH^yPhgK~fh#eqN%N5K1 z0xl`m1zVL_7t)@7G}7tcb_AIO6*TOkCo%%5IIxMw(@X(p>U^poB2lK zagl|iozI516ON0y@-dk`tZr@u5j}KVoMryiJTJh*Km5nVZI+FeThdMGbR2Jh#a9-J zvvhi1njvH9{AZ_^*I_tW-o(6gKF&)XP6R89uwJmp1Y{m@r@6Pfj*C-Wqg|N@Sp|mV zsFEXU@Pd{a;loOjFU5{NVWh14CH+ z_JOoN_MCM?>>2AaWRLoLoFp%cR+fC^)Pn>t0`^*odk*3Ga-qIsH_njHi zJ?Axyy+3&MY;O_`lIEpcpOj(Aem5(g(vlG74%#U}~5VumwUyp_<)c_HCM z!jXi73A+mi2ca%gGHJo6Gfk;Ql& z4jpl93#|<;4=o7&8k!Iq5$Y!o3iSy+4)&9826M%Wc#a2u5AH;`Ex0kbI=D1A7iBYo zS&osx9C3m3f%H(EY3>*78JzFjZkp%pXBw1r$TBdgpJ@P|{z?6k9!PzY{t8?UoC+KX z><(lkZ3*;2UhfFN<~nl%%L8)*GXhfsy^x*|&;x@o7t#ZNqkiZ=XT6oU-89g8%YQR* zrunM>vj2?#sQ-z58=mWl>*Z^SYcX$@`zOhZ{8qez{_+0d{=xo!{+|B(zT1}T zz6-uy&SSnkzKy;Wz8rCJQsjZO)jZR@!1t?fGUyrSdm!n)!M;VHdSOy;-!kWdr1?qn zlAgrhj=vOtJbrG{zW6ywTjOUX4Yl?&%}iPsKO<>+(zK*slcpw3Nt%FK6O)$39~ZOY zC&{zpbH!=# zJ?uT`-Rn({-QnF~U2EQs8PGGfx6~uHd+gJgjnD%*-j&|vUe?ND?^KjV=6mOQXL)CM zC&?4Mx#C${uBdtYd;22Z3(r$eu6WP$mxooj=@}cl);uOQ(|XZ!%5%(f&@i_A!ipj|8oN-T*54&^4J?>2r zHv?aV#9}uTk10c%4PZ^4=pOFAXzJtMZhGn(X1nS7(>264*me@}T-QO@Zr2tgz1FqD z6?H9kEp%l_b6wM2V7P0i^edhzcqZeSgp!G_39j+3ajp~MSl1ZWDA!Z#NS6-v#`I=n zglo7w-K800UhET>Y6oH1%_Bm7iFTnx0tuy85_!yL!1; z<#bn1R}a@DS(CfFSU1vK{p6?06Xl`uK)J7gbIM(4$2-aq$6v|}=WS@wGYPkplL_nP zvuN#j!cFCRM7gG1MZurS1^J5dhjLlDq+C=kDCd;hp^K(lc+R5a44%_?ZiY@NCzTV* zwNQq1(!scOHMCwnj{3PMJ>j@$x`L8pSe%Y1hm}LhdifyA4k*7X`;{}+eac>CkFqgg zo_Rw;Z)vx(OL=OI>{NCr+m&s~bo*9NyhYg=%CznP(#^^yWrMO_(d2c?kkDEsN6A*! zD65s*!Bxsi^doy;jbSL(_^MdoQ*mKU?v1gnIV(&}8|WW_GTQnOUtYg#HUh@D>$pBFo~AU-E{c3vE7gt#vDWDKjC8*?n?Xv~qArQ%^c zhwvQ4a{$lpTKKtgke$~DW)vUET1Z)0dfXnkm1Xuo5hBPWy{ zS`%6wT4khGhL%Re-$Ki<+AS5MA;?B(i4k8MV!b{qE(~?I&JWE4GM1hlnq`#EG)iZL zrW>hgp^2gKp>d%xq0ymHp^>2hq5h$Mp}wIs%TU{O*ELs0sCQ_9^w8BSlpbRIz31u~ zy5s5*`peZl^duO05PTH8AAA_R7d&fvYQF5c=(^;(;Ob$~Y`0yvTvvjB1TP0!1=tTW7!TY)pu&A^R3G}i;y0#~0w z^Jn0Xz@=xEabYNy+RA6LaSU?L54Gakk4-5{B2n-Ai z2=oi|4P*rR1o{Vh2YLm126_a#2k!eH_#gWj3HSVW{b!5;yXe2*Kkq;5-|OG!zvLff z-s4YmJheZvPmW-+Z1QjPZ}6}8FZC}Km-rX^nV4nyhl9Bb{afYv{t5nh{<;1;_B-}0 zDgW;;`*zD;_EX|*Jg3BA=GlH$GRx1?r^K258U9n^bpNmZTlQP_sfhpkUxZcOZrN^O z#Zv$_IS=%v{ic1Gd6;>UftVp@5EGFa>mLJ2A20oHe>vi4|0w@;`$)g;XX@;leT9kr zv4J@&jsOniMx?9uRmSYTA`bIk5pVk#<8s6YzI(pAzB|4P_FKLizH7d#zVr5Tc2@GI z?@B>@srZNQvhR}bqVK%#obRk}tnZBPwC|Mfq>mAN!gt)4>pSW@;ydg+bYh5cpt`uO_!`udLBkK3~?y?oi0?1&}Tp6<)^_3-7|yZau;KZ;ND zJ&b=4e?R_S{4x98_&f1`#ovlQE8dL15q~}YTKu2!SK|MOzZ`!t{zCluc*d)9@n>PI zE)~zjFBMP6pEBYn5odW={^E}rIY*ImB>u1wKZN+f_ya~f^1FfLint%iz43eE2S~f( zbIb#zo$*)1-SJbL*DyQ-B$kr{1$5m$K-v+16>t7GHhxsR9zQI8X#9})Ow=6^-#`9F z-1WF?aaZI1j5{2+HZIpWBW`-!@Hjp0FK@2*ckh1h0q-vF6>+_Ht#`F|Rm8i(dq&C; zr+eps;#=tJXPsw}dye~8_Xzh8_jvbcqi++;OFWA`S)N6n z1)lky`R*C+$!^U(*ge)g(%s84);7t*-V=d6@`vdU({73Vt+8DZ=gaeDOsap$yKK6g z2e-Na?%(ppct!%P<{5%_KTihUeLTJKo@?vn834OzuB|7+kID!nkIK76SWKmk6jE2Jp-x2}UfPBi*M;{FMR|&Z z`X~VusYHb^aT0X~1DcVk&3NfsIww;LSFE3~k~hRquxMBWth#`~Ey&bzEBaN|szFOV zr>M?h1p)(MnMN$u9+vY#7#3E*u^7N;Cbweqq6Wz+=6V3g>srtrreUct>CGzz=;BPR zYo&@Tm|Q92fA2`c%Kvc|kVinCwzqQCWTUZUfkq6jFg8+^gvr+_q+1<>Ra)69ONtv@ zN+z@h`!iT$FdUHd>lCvA307HNUSeL)`no<-TmN!7Ix$oG>*X?JU{=vrKBlHQJ#?b< z(1yPHE$OaVU;7W)p4IC$xJ+-H*VWdv8$xYB^&&L;j^3>`2^A64&38tyaaA{;GeVaj z*qs6f7>z3Pvw8_4r|lYSJ?=kReQg*AJlg-x|T{UDUc?W*Ji?DFetxviu`x|@ikl8 zI2+9v(V?|`jDSF`iUDJIDU*OX`2+26+L=&ws`WA5KUCXWt2-OM7Pb3RWS&N_e`wa{ zb>PcJ;Wu?#FtWDSeE~2->wQy!Au$H1NuKB+ku1_0kPS=M6rw84kZ-iagczh~)9RIV z6bK(1@ssr`6lDU-(3lzkoF&30qdu#{#2PPc#9O7c*7cPNk2C`ofa$}G7-LxmqBSFx z0iMQUX%o}%ky!eXrcJCL=g34hm;95OmQz0*bBv=&k$`Bwrd_KaEOHWAWduQ$x;bS- zsPZOPiU^pqnwHw2tg=Z)uOfAwrZ7#G(U{h;L6v{vn$sYGY|^$gNXGk*2Bm2FFwNI6 z6^R-RgLuE!u#}lKrGkL3_)sLVW!r3Im<_*gtE% z*8yYjPpkn66u(XpRYNeL)eJdHVKRlpA=K*<7dBGxkfQ@?xSmt6Gj+7PQE`fa9Q=B+ zIh&y$Fib1bxGc+R);Mg=S6bgTey&(vvB3r4<&(llrHEnD$moog)7VQfDhC@^VnJ+^ zAudA$ni#qH$QCw9OvqC(18f_!tR`%JPw8>B2hsZzFhJ(@MS35hT`blAod8QsduLUi0yCD)Pg@!qtarfQUfJfb@Fyf&s)65V}4zwx~2^-eu+2WiPdSYjgVhXC^uk9Mb31*=s+ zhM-)tWtDiZ3aK_$7uEEUqFPq{ZKN2Mlx>n=M@6MeF|Z)kuI85)S9<|UFv{&f5yrqM z)3veh*QL6oFZL`Jfcpo7L`vSVE7D&{p*?s_7pN3^pPpQdCftt|=0bGPbD~ zO9t4~&>U2PI`+NKbC9pDC&H)RfP zT}VjSzruthKdaeyv?AYhRTS7>s$$3@(`!;z-*0M@lm(e1h2RK7jPP%G+n9x|dpI0lV$Q69MM`T5A8Uo-1L zssTN9eUK)l*P;j-r1uGJGEqy!^fLtUy3jR+78AfU!>UP<_4y5GAhbbBmcYJ?LKn1) zmTL(@+8Skq#F$IdM#t=DrH4?8X{FrLW~GJV*Gnl@Mn;&+;#atL!=R6*l_M)Od-wWe zoAy@s7wrcn)y=R~SGH+GyI(6lDGpX>8Da7JsB559*Q5_8>N>m(Od&LINSoH9zVomI zyAuR6W>~dd=`CH?FbmmyeO28*%9yWOm0okTLH*0nG#xXpv*!YCdqkw4Da1q->SIb^ zLfz}tiDWJ4Q-qK!+U|^s@qbDKk_Cr|iC)`ZruJJ8lkcyYsQjsg`W6L1^}ZE-e_{}L z`QGFgBR?H>XQNyipbs)R{5DaIGz^8MiOLmiZr{>xjI*d>w-_8<;|@iblol<@mAu+U z!azlN$!J~#$;&GO8Hn?#C)h_(OcO?LseVC1*688wQZeo0{w1cA7(mEc?YV)!lN?KO41Kek8PqCHQhX?L^~axE(`tTENb zj40*p5tpw34x5QNf{_Gehexy~wtS0x{W-1X$QPNZeq%RDEXdw`P8&b61+uljMt;nK zk4Cj6TeWqgYO{oO^yf(YFuD>FSqn#Bqk8v!(u=rSp-mW9o&2et7+2MVQFc(fb|b^< zxgsH!FCf*!(j*Lcz44U+7#Sb%8l_=jMeV;OMJ7o=}5q)ap-o5QeO?aWrNjV>QMupZ&@TQPH*S6L*lMS)(VNA@tBCEixsE_ONLa zrj#N(wXIW9+yx6tK9>h*Po@-q@v@XmjiE4%9*eR-O2)8Y;8LJ2)QMc0&{keT&3-yU zf32(R&-!d?OG4IZn|^%`VshL_Ix+tjLS|?mE_{jf($Y4R z)>bckfb{Z3ZzHW_^)lkmX{)lz8R_@628&-IGqTbby9n@%SkeJF9xWM7NUtnCy46I6 zXl+;5XH#O%>I{lh#hf}U^;3?Q0@aXp3~ky5pZ0X!XGWT#_G+s)TD7U0+y!NI(2Sy0 z*pL92rW+~%dD;fb==^^}P;~Q4sM8YfUQ-5cmW>|xv!?C%naEQz9IC8M*wsqwvCB_q zW@uw~eM%Q)X!hN$$SN&&w@4DGAEqv^p6 zEp}fYKzHUUnXPq{vByaZRNp|WTJkmBMoRz50=!%&H0YZ*5c+i%}PDwW;RsSBQ5YAa^yR_ ztw$%~J?rRvyjvYxMGq~~0=b`>55}s8VwJzNfw{@d#$J&7DaqE7j+e%};qe6R=!ve{ zS0~>fOSFwA8xT!XPUWKh)l+QNWHmaSPFT3-%s`TI6-FAS46LYolG5GG7Ejs@vy?`# z{tDHZ8cjRbh}f=TT@}?DU5g1>#V__D^z5Lld6zI+ziA6E52KF;Y4!ei6Nxc@yoUGT zKStpF#g!E8?wtmtil*KzM^0+p?k2uwm~3nZ#Y{Gtn`}i4mC!$5CqVHZwC1TVsvIa- z0}h(BIw#9og2p6KmT0@LgwPA^&nvZIGrsWWcCuP~`e!TBGpp6r5rp*AZd@ykg2d}S z#4BEJiTI%FZ-FCcuJ<8hv%21RiP@SHZ>o5ozBxzCe4=SXZZVX)`m3|7cI=jmp}%(P zKLu+AmXNP+v!y_rbNiVUWZ&%w8KzHa5|f~P{+An9>nKfR-^NnJ^H4gRW8@ zCt$#jT>wsO+L8gGEQ9e+lvQR0mVyTa!16TKaa5D<_MpOO+KwB-P6!vg%?Z+TLdi zxu)NrAOAbEF%8RqATD7>EHLAk%)b9%Ad_+JkB4RDn_lE-Nsof?;l2E*7CEB*{ODD8 zo-NBZe3>s{+Xj$rkG^Desz2831(vS5QpB>)#QQM4x2nIw7CCGJ6k$rS%fLw&qH-yozieB_;B*i}CER z+NZDHl#&EGxUc>RCB+hk_Z`g^vkfFa%# zD>CGGghaaPMP%~I2e)lq9GKgX274EWiA5eE2iOGl9wO)lygZ1&=)hJJ5hkwc6-10Z z&vjcDdkVAI!n7{;S2JVL81}8iuKj+#XQVzP1mc!Thnd+1AL61euy?8JggXXHDyzqE zGr!L;n2M|{OyDhMI4V(#UDbx*TCb9TfxxPYEeRIOG&7qKc z5gdju5v}S_{NLG+LmpXsl5$*cXd=}spD4&c3enI)c~fH8F9o*UdpqV*gQtJQb-}I32Q#ciqs7mY!%c9SV@^V6}=u$ z4iYj=-|Q#fkn4K20O<@7)j#^h5pdBupxj{(6frnc=y^)S6npYcc^M6MSdN zsHl=mo+tWac&JP=%NeaVOCd8Wz#?WqIM{$tDJ7 zEJ4a4WqyvlOb+Ynb7TxsxzCYroKS(Hn%V_BaO|@6)~TeV?M_@Wrn}j$jL?Usl9$wH zKnx=sLs(KwO)*s#m9Q8_042}(7&a?UvDxNJy}f?EvqU$SBswE%Vo8$Z`OOkGv)wqe z<{39c<&eIoBxy|gMw3dBx2fsEdAs`OdHu)d$$vsT4#gD$+(JpoF#$VwR_Ng}B!O>R z{d$Wsq-?Z)S#rfhevMYFNZJ!JN*`T`G$eQQbCpP21obPEzL*Rsd^?(2g_I{`wEphP z&9vTv@NztVSv_#6MIc zFR*ZKHS#*yra!GlUUME~L&NH*Hf4q0pgO5dw(5hblPcs|bW?RQkF8Pqp2PA#Ci6Iz ztja5SX3F-cNd_W6>Z(QdQx>^Uhcq)2U9a4PbRl!~$xX=nuq>Z8A*m%}F*IymDF;Qv z`E{CkIS5-GPhK1Gw&*`>chL3DauOy!)BydgylVeQ}!MO+g3vUaA3*u zo(SrJygbMqBuWOejgsy}eNa#WvXni>zA4YwD%hJthp4H_TuiK*={V2X4S#qzOltN( zynJQ&af#}$O1ucVr`?0)rQd8uHk1q}V;#p}q66U+nQ59ZJA{G_9G06oX%O=OMgB@u zKiQlV#YFd4f~_tVm7((xE%!Pp);Ix3+sN-rK^y5Ljr16(5mw=&l-Vps!cxyV{Tx zy+T{k==GW1;dT+!#|W6BP}%WbSS%xCkQ5WML|FMvK^@+saJfl!G5joseAzZ*2ZwVO z2uLcefpdJ!_x1XX4kREmTco}o+mVba3k}F^p?ny_d@-^Vuy40e*nX+6ALvNN2O(Sq z05!T6vTri=L7m8ZtlShfG5ZH60EO$P>0)OxhfLQObSCjdhgdN(bHpxC!9@90M&DWF zfMMKkr_8UqNx#&Y)Y6mhlEHLAR9|$LbcjCxG1-Bmrc3(6F64!BgRriFCCA{&Gn9T9 z^V*PPwLIfu#O}rFE@4Z-l$xUJ?{_7s3iDRMCd_vgZqo;JCAa9rOM3TD$Z_oX^fsR& z4f$%_o&3WT{pmB3&PsMPqR*^rsh^WMdHMfX2|xJ5QBE)Y1zCgz^Y|B}uNh(I?_r2D z@De`~=Fo`t{1FnwGCV&K=C;+}{fW$Fq2*`N!4T{(ekMype|v(t8=T;f zrea2SUNO7-GZQ6xp*uNZv~+zZxD_s#r!eU+_2hHwAO32+PCDtqnqZrNSc%Qdzk8%q6D879|E@pL@_H65 zgc*dsFn|+^njuGQ;Wh^iASGiLVEb1_*l%JYs@#jyHx3{rpcMWb0HFdMu>(nBTz(J! zzBj`*u+434k_i4BK}xw6qa$Itq_}`orVi#Yh^Fe~ zI;9gc^x$anyJt7{_Qu&}@nJ(#%44T~sJBkXkQY7s^9!CsK?M{X>#f%xLwXppxnoS8 z_Psuagp8b+u_Qh|UkwA=0{t8LDutb^>933>wXom(Wh{B0G2+-*a=_ro;_>8DBT{rC zSw;*r$0y|>CX@3J7nxibu`M65i6L$@8B5yw=%C5OYnYZ(r?Rf0z%>JkdD(RG4r>pI zxkhpJEP|g}S*CB9%cTak>`VqdXC4{C0ISa@4-9&$F3gKm&cc?59E?6#41L5v`bWus zj8U^JH|9*V{&Mn@QL=FbXu7)mM4 zd78C~)MG?Iw1crYWP4_2ytamvXN8}yc}BkVUsjW0|9>i#(bugZ4V)+0*kY9c1!sHf zfo#%%^{st28B54j9bJALS=oon#jv5Z1o%{khD!o?aeih>@u5}dVqCQe7YmmP7t>No zpmbS&Y2hjh@-tIXQDp%MTd>|OAYBZ6oAU}&l4~7}ZLnr&I2n76$1YQ@=jfLc8J##*hqR+2~KZEt)qYY#y#vod56R{c@uWTkb z)wvqgw!nPw-}Z)SP1xJ_;HgNZ={VtRjHMaug&uoGw=dq#r&ya3(lZuc`x9nJ+P~KV&EkG9<$`>!LC!h#&LK;|v||4CW5DFh5N`egNlzDeyT$BVzpP zSE2(9msLLUQuHE8Ne;`UXnB|^_eyn%Za;*sfaIv!1zD z;Pg|fG9#O1@Z>8-0)~8YAu?c9gC7{U{X&-%n7SApX4tcBL1||C3ds_q?tfyntq`x% z&ya@THJrwO_mc7Y2pyTIUvC3l$Zj>|->Hb2 zE|6h1+DFn))^fLx6uL8!Z}DC#IFh<(wJ*0)Tg1xz{z_MD{^8kvfW0#mV->__ zn3xw&MSNslJdAi|UYy-J%gBo>h^HBGOJz9EF@f$!``jd>C2~-IxtHyEz4kr0#V+ZC z?~&~M3&nccLNO4{zE9jF;f4#+p%PrKL1<^5ASNtuq<*P%*RMXn?~&lH*kRrBki6IM zcx+t>$4Q1G1mKdgOG;s;ny4O+H6{#(!#H3!eABX;8;fgFK*-#p7-JmSbWtvfDWVe9 z=RPF$$#(tDLr|5WM<0>@(Ch>Hjwj5{JD^{CLaLaK8K>C#u*YOQ+^_FGVP@JtK=yNx zGEd>(8x#HTDVd6MXI&(83eytCrovKSsWHztp`XC3R+Z8Z8Ne6{(c2&;+mwBJ4yAGM zk{+aVd<|SiGOHt@=xhjQK&$0D_1K;gqwn}c9o7qX)0p((SAp08orH_2a0qAg9!?ZZ zUn0_KG^4lvmq>51@Ule1t@2Nij-6zZtakUSdj{Z6k{J$8I5Q0g!5dsoR;xVg_B58GgJ!BZ zjayr(7+Xx*d-``4nr_9dtvrN|I<&Zr!rP2uM!<_!`Wl>_-K?|$f)!TU0)fj$lb_#) z-D_AXMbDN}9Zbcy_@jqb^&Eiov-8!BFWN_mSYDXXv)My?8|(J#UfQ>DNZ-HlqGzlqy|VX(?LO$lix*_5)a@ z@+>>66fIpf?@;K@0CqAfkwWptTCzccw9t0MN}6K(gUUG4+)Hz zD@0u}5O|rd2fy{r&K1E4WlMBkX{k6pm{175$CwnU zM88IWvP$#|X7H30zo;y>goc=|{k`$C-i(&Dq4{cv3hX zloiHPpY>MVY+x|&=P2}EWob(Cgx=2pVnqQU<}FbVhs0Z`F zOyy{iG%YiA` zIGHxUa!+8BtQ^&gmZzP~o3FCdp=0{c^0Wd(Y<+oJ{^h+^V@XP-BN=j{Y>UlbS^qE_ zR}R&Q653N%Ch?_zw3`A$1{_BghoM)cQR3PkD zW<}s^*Q(5mUU-qdNCv~UQ4d1Bb9Gu4)~Q~de$ir^7dd zjN@ld>|PF(df&cSUZAjm-l5F4Gh-|B?<_@`t-oJ`raDg|&o~h5B`X{BAvI_+ed^U0 z*PvypZk% zqG2mQmK9n|<^NtxGU{9cE8qUyZ@wVs(2L>sQA*bS73Kr7mAJ%h#n{*&!>l5c3XMXVj&& z=*Gx=`vn}k(xdP|BoZ=JFH)bXvA@HCU%1}q^=X+>|E!1c1Z8! z*)fhGLjHd{T8)zbzCZAD6W9>fqE(wx+%~=z{k=KuW#InjeS#iu&~;ci>%K|fLKD%k zZ_*{?nL9Jl4_eTg%!4rTZQ4X6TccOsrR_xXvFo@+zin2uZS~yQtr@Lykul!;8ai5g3P7SmD$4&pOfservB3 zy5{T%`MUD&)h}BAtNQiA)#*K(9>wLqyo-P2w*IgqeL!YK?{uQ0Nlf8w#yU|yIoJ~y zz4|fjMah3%U0Cxm^+&(@1V6$^j_7wkrNt2>en!h9X!;oz%-rZ#pV5bQGBf)5j}#}& zhc4+wexh%}D){OrS`t4d)hu{(Y>`5F#RmBChfWxdhIwnQA0 zvpW*6=~uhcdbn<^SMEVyDfluc<_f-U_Dc_%T=2~*STpRKRVG-&#@80v>$e`1eYHxj z@V%|zyH)zQo|JvPRgX)jmHzAdtyqq*2V-B}!YezS2KYBtVN(6Se81JelJ^xbhNT$3 z&ZwVHr)3IJ%Wg3~OKsU+|3a;+H~q(VSoKl8Y5td3Vf`7M1%0rJV8nl&g6o%@1Aq0V zON#O@ikaB9q2Mc7xPQz5#k}vZMtAg~ZsIy`oIK*oNO^bW_eHN~&_Tp~iCt2|bbt?n zU0yILm-Nhjv?#WZi~G?xyehkh!xYe2;jX$?rk_y{+ixmi3rrArr7Tc&%0>OXp%kZY z`r4s16SqQ2jG)7!7c^Rp7e zI&d!pm)YY+(ofjQR?m^NBE6oa|2C3l;)E;OcoY_hnCmu}9&FzQ`$riO701vLgx>M$ zrN>fsh@>|d3oh@|KOIYxT~Rnz%W6KGkl&X@9& zw2QL9#BO=ARcYm9nyk;BK>q`e_;V9!I@zMnnMi9O_;Vs!$k1Jr=*y(9-e?kSkL7Q{ zB>J2(rZ6Ig3O&n6FH(h`r0V#8!lTil{{}eupMc$_(2x8J z**(ZK+AYPxdT1_1ua{CzGMB)mDfAU|uGm!CoX+U0e>;`FKo|7YXHBKW>2H1YJyU5% zx~{MO@~^anw9u}M)7$+@Z@|K9F^!g{JNxQArqS2v{=Rz7H2NGp(l>f}8vRZp(P-P* z5N%(cDN~Z3tx%axWS&fuYErI6&2uSkqOZ~u=F07%jo+ECM~1&+dY5Nd@Mb*)Z1t!Ob;`VXgs`dvmeTK4u&&l`;;X;=}Pn zhbAY$1(LO#mcs3^i(W}%v7WS4pwYUCwC1y9Id=>ti2DCYA6@8Uv_tr12 zqD8$6`fy)}au3&a!*&cSToOfA(|871c{Qy?7xdPDT1`{S7lI5+Ulstf4MEuSC43FG z6gli<-|=O}DsLxMf3zCE;*G|fYiQBb-5`i9pM@KfVVNe&;@{H5sfYrg{t4 zlJiMCyoTo3r{V5|aq&typ#Pdpi@BEZ4D5CdrwlM1$)=@z8+kT-H@J+A3e2iDDZ}+p z4%O^Ccp((daD90WP4*w>8Sv~3m!Q|Id_IFMH*@F+`bUP|Z!LYzbRSU49DT=Hs#acP zDFlWN8D%}q%-}PIlilxtepL7kR|O_qFPU|-&N^D!^t)tm>)UnE4{3d)>dg zKp(vY_UZwB*%n#}!L=(aSOFNt*n(iP8SLcFG8C3$ zh0O~JarZ$v5beH|t{~)B{k82>C*$?sx6=z`e00?gX4zbemf8#TtM}eRKZJF4ZV$|M zBd-q8f7wUV$o1&ceOTG-^DXu(_$g$=(~|Hz9cOr2a0RAjjIue-p35(`F}^tt(BrIc zR}RqXgznDJ%N(MA(UV3P)Tc=hrhnB>BKo9Z8!O6w<% z;Affv(d`4%KaL)pN9nhukDh*%KFa=rW)ExSG;eKbcFr6z;-X$FW1tr~Yr>7!FRdj?-^k`E{8|4BzK6DB%;dLtz9n zPH+UcfAH)LqNw>Kt!c<&qf@ZbSLm}(!3#KEzjO*lz<537G&0BQJxjNL8xT#^T}3y?FDRl^k~J4^a`PyFY84w)0uRFq_=Lag!QYJsVBG> z(^0U$PRK75he9y2u&rfnDt)4%Kj;(_b`ooD(8uJIzUn4@h+z3GY%@+po86|vDU#>z z&_5CEy9lR`~Z`v;lJE9_UZE<&`xB@h(}mnmgw~! z($o(YIj|F*&rTj-5JZg=h;hiHd3o}`dFQB_J{Pvg7(TkqR9>Z zE{A*OzuWu2#~mI02-^&DRA2L$zTsbOT$1v$`|RimPUDo-6128cAM}(q){~x6n;v;W zUySE)2?cPXDt@A@);B+)BgksK^;4`*tM$H5>5Ag_ElkSIVH;!vb}76IEC=rU{2W+E z_lJKh?m>mBL@XXWVrLt>RO*GR=@4d@vQoyCS2%wTMt>w?eL_y_>!_HGF-sT4LD&#Q zy^?sE+85#S4|lXK(urAYL@r00n8n)Ex;`O=U2spf=*`XIbI}~DxLG7;qWzrW0FkWI zeJ(LM(yM3Q7r~%;p##}l?ux#Qe>lPBYbB(m`2v4YqmN|CE5I&=@M-Jzk>>Z>&p z1W|h)TU4ylmQoj0qO@j7QKeOlJ!-c0sQ>qO?tLQE+xLC{pZ{Nco^#JRzq9vmhAKqS z(na9%Kn5_o;I)_tn?KmLBNVPi+)@%HYI+EI9xMdr7Q1bXVo{6sK6nRFvo_z9Tx}N>yxqZgTAdftkUC$QsoOM09f*BR}4UC$J zf|;7iQ_3nmr4xK{StUcdWha+Yz`d~59+IS_lKWkG<&2EzWywmJct=&*V);gK-aSS6y3_@5l+x5R zH)C314M0Rm!q`bT+Gz+8ae+TuM|nyb#b?)1YTzBer;hTIj7%5TQ{G3W{zsKQMdmTW zpGu-p81F|Ek3Hj21^UoO**W!2^t}7hUis1!K75BgpQrh_qehn z81A`el?Dpjs@H&NyMTS$E$mXDu!nPR(;}i$sT61^avV_@l|w!0 z76#@3w=jfJVHs}+3Ih+fTiC9*-IhI^1zKRg-NLZus4(EOsb!j_Ab(n}s6X0E#fomk z7Zq0d%|Kx1A3 zj~Ov{KR9Ohx)J^RAI1!CZKp5{k=ruCasSXUQ>d^9#*F&ZnIQjR%%1r7Z1)cxGhCBs z%v2gPYy?8KMf3g{N1ecU9jMc`cLEdc zk9U+(&z%(sacGEIbwNq!bkqu8<>mJhsa8y|L%fH%4X%^~EKjNx4IxNrMD{8u*d3L( z(*l!wbXuUSZQYf`=W#7`N~3)W>AMhlt+7*klpzX3sm)RZkq%uz)j?s+0OF%!d|?Zo z3Z*9A>-Doel=4phqO;v)OFf-VLIv1(sK%m}g$ls#fGp{%io&S?AD!w>9|IUYj9)NQ ziM}&`(&HTYN-l##?mjRG+0sA=V6Y;CJ&SHm3Od^tC+h1#z5RIIkzOxU8>btskw?2I zrGgU@iS$B?kH6DJ@h6F>7?4Z?vqG$T5(Rd51Cr=KRr&HRO1XrDH1V{i(Fcay11O9# zQegUc_}DZhsyaL|iQ$+-pu~{yNw^@f`gFe`pnPbE0%ip~P$(~CP?bOau9DQwtp{y3 zib+IT@rBKeHXvwaO29>hCIApdI8HGs(Qbho0R0PiNNegU8PcoNP4Hw(U9F@peh~D? zm*;_x?|N4$-dKEgp~O16(2Ks%6Ft~2W$HWXI-neAU-Ji}=dk9{tsXzt0G1b6rI5dd zoT_$JVxygj!9WN^2SXtbB}N~&?HZUDBfAFX#fq*@YaY}03O-aTKgmhA`Zc2rMwVqfBqn&`Bbp{y& zD_bGZ!sC{vIi*1ho--W$VmBqWD!LOx0l68pmztj#j1NW)r!hiWpD(yM9-s*I_zl$K zk@u7`s0Yoej_)aDoqCLVuTVWoS4c<xbib25~A_RxxE<)NMkpUfOghUARc$e;hewficP(GHuvl5w8z8F-o=V4Q!-bMgE zXwMUy9XXV` zN$+B_V&pbcQ(qP7_k$8iz38E}OkcQzQJ9kl1!5}tJ!mKT79)oP7axk#^|-d62Lr8k zdLMc4?|LYS?kvDQ^**I_d!JG7J1MX&1$sZo?foe|l@ii%P{owTArN`Dr_w^s zyUd^HrIdlUdoQIOo@~2&DYfK-mw9S$B~m)ZOY{cUM&6$R?~A>aMEO`j>?n%OE{NUK zTPY)F2E3EsSIWt!1F&|3_m!8VlvBDzN-KRju?Ek;1%uoi&?^$r!G?Lf1nwb0Ru%{m z;CISUtv@dV1r7Fq?f+6b@dkbHV#v56I}ix%+(&8U$2M0*QtL@mRD^FSNI9wy+|@qH zFzFm0@PRT2j`X225DpT@@);j0)4a0_KzDGfuM$-<^G}@ESvUsVl15_tNRmgYq?5vH zuHe1!ywWS^1apM4Gx*ozmC8k+qQQ~-Q)s^ft7;`)YJyTK62igN6TuKs zMXHKEhEq8)gg2R>)YU;8maS`$Oo?H|-;ltjX4d2c z1WPx^_Y9o7cL!%&yxTBEX;#>S#dI&G4%a6tWx{Z>W8($?8?Br=yxv5-8$F0^pti`t=dCAI zhhx-}s=^7WCsjr^QavfTaPDXwvNjKrTPMu|rq!pX$CK=oQ;f$6FJghy1Hk~RBB4x- zP9;xK;HLyX33iq~fCI}+;Tls5RP!8G3MGQPDRw&giWAALFmTGzc8Oq8cVcB+pna%L znz%uFrVNmd@@3PMqH=x^x5}9Bz*}{?5+mjF=F^oOAOS?rz-w=mZOu^n zNzoa^s$+gBbgsxmTN}SoHb?NhhOAiFrR}n{lUc{V!66Jruk;;3@nB$yoTVgd(sBov%FJEbE2`L*@6TC^4Yk zjdgq>G<1eF#qouvC`s@wb$nqdiUD7S;|nMGbi-PB!|t&_c};5OCK1^M70S+}rCg95 zZ8B~K$j$?POE+_5XTXQ-q82G*wK$@U;(~&^4>m19AjK^U97Uj!uK!$F0vc(TrAqr^ zIk3~{0iN)fMxxZDQ;@h`bNHTRN@7`}9y(#zCvrf=_Esc-{9%)E1r2}(^M(nL#p1o~ zLGVT7{^4$jvcxQ z_`&92JzNjh&Z#Wg4qFbSR#cYZ^WxaBZhKnb!Umm$y{+7RcGnd+CPL-`&jTOmLHYaa z4PPo>OA#Yn@RANRK*!ihBPnElAyEG7DrIEVOTpd=l9;T(Bnes79T^<6)I$UgNDMfx zRo~nQYr7WWrmj|s%Wzk%22N(a{m2>x>8JDWzfx|7{{TE9c2?|Gpo5!tfLT$lfGV)# zYvmadDlD-MTC_*oU#?SnNMN2w%2hVOIhU(EE|2+)*WRGKD*egFZctL>6`%2~8@mr+}YMb}1(yj3VOc-AgU${9MA68XtccD~^47I08Q3yen zSWW^i1jmzr^9A5?J%Hnbzf+PLuUJgV5R*Ni0SRt;l1R32SrX#2lDQ?4@a)z~JZUgE z=;@3Mxd#?FS8xv>*pArv(ajgWQ{sa+M*1O~kNMt!M{ZWemYoWT$GL+sVtlr<{cUb|rBHtOO8j3JbVqW*Y1kDrL` z5$c?;q~&q+MzcA+YxG?u|nd z?U{R(-I5@Y?0ZO(F+Vv;{`^USq5&rfN0LkYrJt3}l&s`0N-DYSe^Ca8?FLq*f^5r_V z{jevI*FJk(X{Umq_S6|1r1SW@!m&r4QEo`mOg`+a@_{tdmd+_L3cPU_VN`l1&$);z z$xJR^!WC^MfAx~m#&Htty_b|;a_mgH3Ke_IgMYp#U(85fwD<;by8UJ4ts){i&KK*8 z@fAaSG{O&DR$fgI;W19KV!mjK0#Mxe@go88^c5uyrL4Y!uY_KY*;SY&= z!mB>@Z;H+h=4juK$80Tkl=#M9mq(&J3^aq@7tr9Z0$Q zimK0(+qCkm4b+;O~aFal9&&sq~Fk-!9zFv++({ zA=Z4K6k)Rjm8jW#c!D~$?qE_niv6Pnp18DUI{qX%D+T8f&ZUJwIbh@T#ACz4?Psv+ zohRe?0vXkQy|`LYEYsm7)GLC%Jg}si7&8bIA|V3zIS_wfSeE=Uc0QDM*rz6x3{1Uy zLd$}n`TBnY^vr())VMHEL3dz)#`)Bu)a-w%Mr7f{|E{i}_&5!!wlb_Juac++6)vVx zqS}-O>!U=qqZqXde)YA$M>B~}ETg_p)euahV4rZv(H7>`fZibqJiMGrI`sY~#hF!B zee8cvW;ZXV787ISN?YD9-a8`6S<+(7+^Y*Z>sXT70Hobg<<+L)d;ct?`)2Q-JakKF zY{aOHjEsxFUeD~Gf;R}RuvhrU<<-*iA6K}qf*Mz30!3%%44(x10Te$J3!{QsGIa8` z6&LZmrJ!jdsDk{daO3z}6;yDyIGzYfpL=cJ&#yYLdtI2d6;x9`b(Qa|0Op-LSNY8f zz|W7kMs6H$SP>aazQ&)ah{$=@ct3JKxyIX6R^uWDBg4FTM>l$%4A(iq{2ZnE<{JNt zVDql=fyv0IaWYCdAOcH-Ud+rr{)Ut2l!&h&UlLJqd~-4q-@e9|RYC#7P{7i>IhWfz zuoJI~a(VGefSGZfSFWU1P;#zAguj{^%X?Kq35&0blsub2z7d}C@-8>bXPLdG*Su?=ewE1^Ju{Hk`oj%=)d912*V}lmD*DC~V{nez-C^EBl7i z#R}{MUsvC#$P{B55g*f+w_=C>98x zEb)`o)e`DamMHW1uY)SuHEXDYWNC|S*HVW_)i*;`B;6iy>k^tLky7miwoHV1JJ7>M zvTB+D0&Y~O_5-VR*A#U?&0oMkW?hN(1y%C+EcJa;_%Fkchri?bQ+OiD6G~Fl`_FP; z9W_$UI>&3*Q6GIN3%BZEJS+&egoj1C`}0BFa%2`QFpa{q zYq)Fz;|lD6Nl&T=0r-|WswMIcyD#tHdwGZXLd1Rf!K4Lw2m3-Eo_E_v)F%HQ^Df5| z>#8M8>KI@n3Oa_jtg9BQ@^AV9FWraN_1vRsGT%^FZ7#)dZ#`rS&KwMmA>MJ|qu9zH zsi(GRLWL3Tmj)M?wSVpybo;{#+fq-hC$b84vkE1l58UbhZ69NZAD$KZIDx`m`Jo^BIbD!Y6*Qt=P|p9iu7H}&O{BeFPL(kiaj6IuQUy!+%KB=f zI!*Vgt3Vlsh?9U4cjMm#J#IgxpZU zxkvFOkqyIRA4o@;@+%DI2OJg>;m8tE2qHtp70JhlG~IG$WGQ_-s>^75}1BIeoWmI;)r`-!-DLh-J`MET`E6g=LD$gQaxTgG5(pg zETpO06|7}_o2r{-FKH5`+axI&eX6-yg#tX(777^FTz#(mk0-}V5stI^dCcLCRDdDy8&dcgeIV3wyi2i|KY0l=|TB*-Uzw!;O z)H~8Rj!F7+mixH{5Lf6lVQ-cc7w(oTD2nmWgoiMlzjN$9GrPbN-&%-w8RFZ6l_#7|FEir7o1U(2*XX0uP<6E|<=g(@YKBbWN;xCY;kWH`Bh-&%aFg{J zt=1^wN*Zq;FZ9hS*6E47{aomq%^QuUvUHv6Ik|18sXZ$0 zg_v5RWbKE8_34<=A&+ZDhoZ$z2oU`CH1&JwYkS*t^#@JbV9)qiO;#wQZS&Mx(*DWw z)mGAI{@Q%C8hGbM%~y*{clhG@Y9rL={CxEaL|WD?#DQ!s#0=#fp3dQaZRnku!qR>66ma8Cm{`-NJp_a>Tuj1w^Q9HrC%%VO?S5HR1{kpRkW^;7HkVj9eiJOzpLW=l>428?|k>$hwuIF zcMQJs+;2K9wz%J5Q?PQ~Z|v$Qp7xC`bT*~hd-BwZ#ASDPw@O@g@9$A9?`q;qCqVGz zeX~dH1La)ZWfo!gaPNcah%p6kOTo+>eKOaPUgT@vzoLW5|g;-`eQJr@e0UmQwiI z))EJ>%@eRAu zF|`3qA=q6`&>jFe$5ZNlXx+{`t=4WbKM2?YCJ zK<{$}6)~HD8ISN^X4Bo}l5 z*;%=-1Nw3GyjoS-XxBQgP6q3_z2l<#8o5b-stJm8&2Dm4tt^{YFmH&_BZQ6-b5Iyx z=Z{RX7hhM~%G&B+ISA}$xZt2rUhS3|8ww^u+>Pm~LJS|Ib~fB)?+P$PkpkL8C<#HH zU^ycdv|xn7#mZqoz$ABB&WM=^*gudF9Nq(3Cd3hfhaPx)ED7AkpsbQ!~H-a04 z-kKr^)fGMBXB3X68=Zw3AgbDX(7{U-R8h$oAAkO~>LauE44WH@~ zs9_gm@6-@q#C}HQfl~$#U}8UW*z^i&C<>#WW=@INOQ~Dp@2D=&cD2Gkb?V85b8BU=f) zm|fhhi!OS7_}I~>=$nwEMQk_ zEYKRXplPW)Y7OY+2R?{<5Y*o$>Sp3GR_oDwDs~P;X3B(k zr&~s8v>J{NS>ma1A`GW;l6+P*hl2r4yd2>y#?DCWcbJqRRA)_9d`rAT%(F@;x)op7q>9=>mVQFb97cTaO!X2d&5|%*jTg+YC3Q|@(^E0Jq|vth$!}$P@clT2lZMMBjqWhqSy;K zw2wrw(ja~7(X1sZ{c1!;)xnD$_!s_q40|hhT|QkJh)IU;h+!!x4>yKvdB<@+KbAeAPdfxoD8OEi zWtA}%p&yu6jAIpp&mRY$ypyb59Ge{cSAlJ z*V#Njp4Ekgy7&avJ$C3JD5%H%M+Md?4lYi4n83DfALH{9*wg5f%YfqDinB_=^F<** znH=Qv;g34^D_TYTCHujQLuDZ97(Z1U$E2bUeJL8Z*m#7h`fSP zV*x)@hQ&RQiEJU0;Igb7W#WR>Ez7F6D@cVKpHHeFFI2H*s}mpdKrPJVI#|0NYr{Pl z;vW@j26rH=2wIfp=y0#s^_gSBz4h>ob!HW|uE$H3V`2PKSr&~a2btTWfaknfU{9i} ztp~W3e&tvkn9g`PR?<6BgoAGn;TtG?3O`tm)lD25mWG@$eMX88^DLpP6l;bPtXNZc zN)oG9WRFZ1)U0K=!Tv}Wrn?6JFo`85yWw*c>q{6|6F08AhR3^40+y>_cOuypdR{p;%HlBx7X7MPyLS>dw;RnnM$(prWrb{UX0;me? zcxGNWrsF4woPvGZiR61LW3g=G;Z<0Zn!9nNU4)#NyLna>RuS8C!8N;+{X-QtI!Kymw|j(jl)X?5g2&uWVtV9bP6d_c*Xpt8__e`c zdsR|tP{3A=(;e3mb28!Y6n^PcP&|L^QC2x97jKp|;ocz<-!(3{7$5g28RrW|%QkSkDUoGIcEq^mD&e%AgC z1^jJFfWPf5FV>Kijm{DVDV=<1rWIz3+rPCSS%580o)g4N?g%OqoiD8OJ}g~K=(fKl zlMdPusVst2v)H9A=9Q##cGX7ME#nKTf%&(uqki_z#;lhVb1OVi+$`xtmtaYC6^0zW z{Jq_(DO)BrpJjSS%97q6-THs0dy;Nwq>*1B=*$J<)zLL~~Pk9{&`EtJDb@n5~Yk6yy9CH9~ z2x1e(*-cIi?vL0l&9nTM*66$guzrC3;s77i24~#?zNQTu2ZhO>X3m?^i6_>UwSloe0QClGPph(Pl~F?X z!xl8GC{qI@3wD)DzsuUkEkBO=T5_0BiKtMU2+kn3vRZvYO) zrF`K4T%K3+ivw8gq@{RzgAtbc4r{724V`H&h432s)f`on=+2Prf$id_(=oS}^1kV; z1e;2CS1KTxZ%b!kDDgl#wu`0wS~_kUQ+eeKb_0P)1KCC(cFzuEizIkoAI&Q8+`%kT z9}oNqUK@PQXx5Fl$YgzrE-l=NtAvODn8{xFf2_8*8qXQRBEyN5xlF+b(=# zBpCXkiI<)@#Xla#cJoR7SrUz0b?F)n+N%^$fj>7K^HBs8jMmxV7_BdO%t!1sj8?CY zSdFAFFj^=T+lw<=t7x>oa7Sxmq0!p)5yoc009GsrI2LOmUh&g-{0LmfuJM!+7^*M$ ziz6^p)A+~{>C!;fj_(c-APkhff;JD)OPDStRD?^wDfU z(XGL8*w`E;6|`}9%%6Gk81}E?xnMsK=MQ!?pVS!_Xeg(24sUZD&mF@O_?)rqHJ$?0 zuXLBsxfNWLUmU|8=eNhQt~lp9k7I)s=|_HHBBVd|aB~uz`F6EQtcM~U;yF`T)3{04 z&&)}|J;_e85c{TU4RK{AB*vRQ7UB?62p(H)|ZMDzG$WW)YJ5GZMj@3)~Fwh=QfK`ZQLSIJjF) zW6viA(yRBdrLQ;y+Q5q5g9)`!Dh7bJ%mxcxGRi!{$p+ zd1mvu%%BfGCx?Ab-SgZ$CK&Q_=CNnXX4sRY$4PtQ6!Afi1G;etOV(nl3&af%na>_= zc{~_*6TF?_Vhv#8cpGA?K|8i&@OvaR@;D?lb4er}{>XgVN@y@5LcIVLM(H+Xa6TUo zh)D`8*wbb#SwjVsy=^{ABg#RoMW`o)3x+Oc&Ee!NW=}@_j`d){enBHVVah90r2b%t z`JGo=!b+x#C>%RJ)rsuW-xNV4%?sF0jijOEwrkWdD--W?*@;c<9Dsktg|8~Wo4Mer z_k;TivajQU0~3c_lN$M)?0xsa2l9>quzg_(>%zh=-xU`m2v1rUp`h-aFIdyCNw{HP zz0r>WJ>_42!ES~KX$slG@`f?8jmv@Ux?8umQkeqO^m!fEgot3xxW&sV_v0&wnE?D2ca|M-e^dMuC` z*!(MbAhAo>a|rAJ^Mt`L(7tEDk3w~ntYTd(_P(Wex8{&w2gDv|+o5{QTw6HXvujz0 za>y1~g&?2zrBF$1R&$mFN_c`8T--3;`)gLCD1ecT6Hl?!kgvXGkCzZT-X^i-K^~?* zq_#9IpZ6gXFK?+Z*ULY&j0*|J%_-i8*y5q1{)a<7Y!lF5TDctMiqIp zO{mrZ&Ns1oaQ19M%@6R{Z!u{O@aG+8)VHiZ45$&x8OK&_`2{%ioZ7}qe8(z;4HAQb zO&mdky!K1qu{*MSaUy?lD{CfaOtNQhWuqi%iCt+sgC3_PeCrOj0pWb)_v}M>^__Se zE#bR%vT1VOCwAvutcC&&QnPon?;IzJ_ua!@F5bZJ!FCYeG~Q35MR=Ov45He2ERQ#i zZ`jMCLr>GOgwv78(8c)Jy{vfXDGCxurGlW76y#th0#GL?NF0I%Q1r6G61taHiF5)& zw~5>_2?Zu@AjJb2Ln+?=ME7b4B`k>ayN7pd-$TLsBxkH-g+<&ukJzeSpdBE9P)6>qvcKv=@ampc1ZaFl`pdd)rz@MOEz zPpqee`^%#JthszUl3(7B2@B5O11vS%RYXSW4HISa5+8Vg2|Hzwm$=W6Q1^WHDu3o@ zW&?#~{KAC6xI4eFSib8QCbY1@Qym!jss~wg$d6GF01zltb31?TAg<`!dHO-tA`He7 zg!XLABj`WkKOJPPpy0RquWWw!+>w(U)+;(|=Zxehf5qXtU*)NXSZSVoh=oi0`J;!} z>&R;AA=dE0tWF$auOO?2zp-vc4zj|)@8>IjWByVHKnsOLdQVIkqr0WN-vb-Qf7xmq zt*#`2mE6ug%)SvHZyZInUJj^lbJRlOY6`WGWX~oY1Zfl6Mm^?0pbwzM+x!$82(}oh z8A=5^2S9Oq8&4`AiMaxIL~GSIA?9aVqCo@pL(`D>Mg$I;p>+`kF=&g@u>CM3Ezs67eL>0>_NBp&T^_)2m<=I0$>*;621 ze9WIcg*(U`-i@3Qd=xpu`C@Xi_*Qa;@sp=O2t>Bt)2w2U4g3qW^jqHWG>ZzKOe(@0 zZjgl%R9|*H4YE)sUv`?!Ee$2@xJu~ak!e^5g_cZnFG;ju8-Q{=kg>kwea^5KLsxhc zp_9@1=vnRk zI~$X*68gN&RYuc96hR8zNj*$a%L(Pav+NT}V2y%Ni+l14n~w88&a&AQLt+jgk%gry zR-eNWienK^^9t}4 zi+HuGtP~Xpwc-!RWZC_$;yG2XV76yS{vbCW^E`wMu}Y!512Ue6&K|2>kiMT21saBv-YFZ* znAl1&)sy5`oQ48vh_ruPXQf-aQN*E;CHYG_H7kkan0!TgH0hog8b}Rh5xn0sNnMVp zW1x(9Tu}osA`=l$djHPzo;O(OM*~HGvR20*?C@3vQw2dmaVkaz77+WWh$X#h1<`!Z z4OTAfyb@0{JfcY=8JFS4O^@4|V! z=SHVH%_)d7~P}!Gnvs5@!ZnLEDMM9EWvxaA6z{=4g zzUwwiFNHwxpK}jxL05<(-3#R!={G}0rC;N0*OK;r%;ZMw}#X4B+b;|FIJp= zOObZFznBCS4U-yb<)Ez)a{fbjNmZ-JkKM&VLcuQ;3aL5iidI@53k!kNojyscniLr6 zU>ZVFXn2{}6l%jEcB?{V_K~z|(k%NENqd}BLTph`V5|aN7^1+oe4(P1bi&;dC&ITv z)mouP!kJbgYLSYy6+)L~*mt+G+ z&V#S$gn{Jv6e&e{#`(;~XERF=Ts2CEXf>pt>{mjx60*M8i<1_G^$*hy1Uz=@a7~wS zg?KYU+k%?dRf=dD`D;gNlfYBBBU1Y=sK7!5pB{zb-_DOlX=GG^KN77y_Xtcr=tSwZ z=sbs{rPo|;m^fn5$;IjP-xWoJ4h7MU#Xg-3&_jqEw~v0>K1!u8@at83z}`}dr?*U;|S?6@bui`vz$sjZ{h{LRjXolr|F zFY%90u)%hd+L(AyvCu3!-!i-(#W?CEp4{N5?C-*zog&^w#cMx8&xmJTf{w_{Ethx3w#URlG zve{Y-k>>AKCp)yzawv)Mgf=Lkh&rBEycSX}63Y=b**7p*PgnX2aX7#oeL~w@c;c*h zvQTC28770As`->QOjHvJsl#z4y3cy;KPIcfpL$w*meOWFtqmw#T2f1=G^nt?Pi{K1 zrS=Bk?K3Sge<@+~bIuOa?&4BP z(!XjCY^P15{TK&Sk67jCnD?&+n;fnIlyJ&SO1#N1f)_vQ?zfaWl zU2RtQCe#(%ycZe*gwpr;u37`i>9wxtRcI=o+Es(y$g4cGo7RThce`m@i+)1~pdcAz ztm(0fZfyP@b`n6?y}N52)uvNGRaa99pN5XU9_&}FbkaVTxZo=|uh zIazp672*Z}iFf|{S_eMnU)nsN@@nu$jyIt6I_vh>({1spmaZU-?+~sGN zp6BKVnx6ih3yLVJ#C@PcsR|3fU6=1>yYoR<3{W835rED6`smrCF6@u@!=h>TU^4-` zbi?kow>>HGqHTxo2gWE8Fkkk87L|VDp>a-IsE;ysE<4=P>7p|(s0ZWaw#F&d+>Kr` zf1uriM5Mj%dSu*CF*$*pb|iqv<4OQ+xdQYX6g_(d#3Mwe0QB0z(ByHUGx3Sa0$KzD z7~IDQ+H!>t_)v=v&q8hmrDRfcl}^uCzG5vBwUD*@|e4lcy1B z8@R~te)^#UH`HmH1xNxPWZ`@K}G5ON8I@L$w;|BJ`@qnt9O)#j2w<0FhaGHjCJs z9_z~oW7R-pres}zFfy5Lv?A#pk9F|DSg51I8ru;qiYXx*V$p7QypBMX$26sn|34t);D@sp2sN^p9NoU7K*`xi&)dW(MH<)m@uAExO{*;55T#+&2X))wKmjClY1>% z?UT?kuyqxR9I(Fncdsq40>@&s8AN0iG1t4Kr1ULx|WR#MzJ7 zAxIwgEep%tTtLfI)DI_Vp^A|Q^^$u8 z>J{%)n>QPQ>&+_OZG=`V7BxOn%tQ=m4)0rPPohWR-gfL1pFKj0ZFcO`1VQ8Rqm96C z3)PtTz{N-wLJ49(#?ru`HV7s1$$YdPqKofaMo(DSrra`5PadfiOV2#*WQJP;tQFrE z??$MiA;v?Z{6LeE`Wh0*#>WiY%-qjxl$G8GDhME!$ zbe=O(tN5~!T7`6U#w8j)jDd3wqWcV|`w%WVDOOPI&`)%^J?C}~MmR}ca&K6c(6Ho) zZismw+bphaSaFL8BTYS37oPx_D*zJi0Tf>t$fB-iAt0PT({hLHU!%0riKybNfwCEo zMeG>6LlxJjJ5!G$g6xzr+HaE3+d$GW57jpTHa~Zb{u@0DKm$Hpzd)C9T8C;M3)>F+ z4`Z|2r&?bhaW_3NbxGeOOoDc&MdU*R(9Px?es`Q!%E0=^AY%1b7?1bv4*u$R?JGD@ z6SNo29ijA=EF`S|;RLO;obxNso}d+nkifbLT3?bstv69irr>ubYVqDH#Vim96u)Yo z;A1A@a(5(@e?CzwU%D_8D*A^W)#xv*#zU^WJox1K?TK0osSJO7l2)D7#Bh}1114#4 zS}pXpcLDcJ4XXiG^F)=sK?aw7*)3qkjR=e$Vt${?=U}n!i zUN%27LrVk$ddN(?mxu9fGqoq65Gr~W-m4pV>MZRDn<=m~zHY zxQ_Rkt(A*E4%|I1Bj9Z) zPiqb*Yo6wl_VPvZv^IG38}qf5GU#6G7izVo+4j|iT6GC-`A@V|V!B9M3?`_;`UEB| z)?SrhZ=~vn&#Q~{HUKkXo*yg!fmY%OdkUdf1t=4HtD>rB>2=2>GKriO=&~LTZ z0iO1)rU2aT`W?=O@J+|YJBOQf3M7*m_JD2LUy?Z!+8#XK-Kui{jy-0N+@Up=p&jmr zo!UX_yU%{m?n*z}pY6tz9PW+%TBa=hY7h8Ddy-`CxBsful(tPigrVDJM<3GSBx#ym z?Kf?l1WL%1!&+^ABOfRx@!bhJcBLa)9UNk@Vw=L`rY!|lbDJO2YROAZ@Qh=4HC;Z& zKRu@Xi`=ruwT2jpw~hnzx|UBqj^5eF*B{rSDe|Y|ST_8;0W5|j|^zpPDz)ANcp9ZvXFa_q%d zwJ=GZaezl$2f^X&eqQgo7FT38kamK#<~d@|gRt=Z@t9LDUDqCyv3#c8#B@B!^;>u< zT|CX3+|q7=dD^3^iG+j2gA%%YaZh2mhd(3f?I4%6Ow#uy z$hjeWU`0LJo?SvOP>*0kJ;H~Qw2V|NMDvD;dXlu%hB5}dK!1Wz!~h)&P{gpj04kW* zDGkss{tim&7;@~|W%bPxxM@ip14nta`4dU{olsc}C>nzU&%8=}^XS)PIIDi*Z`RdE6lhks zR#$Hw(5%2;tEZ2HqTX}$^gRZ61~)X;|8zA<{579{)l5%wAkWUXlbh>fnDnu|_Gx{k z9R0CS<^+;kdQY5$YsW|+h>o3WXFaPQl`*lpyr4g;fNZ$#WxX-H$}2k7-^Vr`RjYL8i|>+dCNES9oSD3-qe$wM4!yITfV6`qWyFHTM!s^LdRtDU7hrk()ZkcM=vRT zZ~yd;9-+jD8q5+(GAvI>2-p}%Kf@>4E8o?(OX0$^G7uZYtMt&5cusfy4g0Nb`rDyS z&L`&bz5OuuyLgfQdL@V%ruNq>!0FsyPjMhF=I}-R_3GtCb{BJmMvkJy%A8J?9)$GK z66|;j@z6^w22QLaTpgf4n|=hCnh4<2>4^gK3r^Mkm@ASOq2!^sq27zha56>=ax{-X zI*e`~sx=VYS){eKAd97Q0$JPxByNWX09BaAox}GJ(7$zBF)D}Wr0X9$o;f-EsSLgR z3!+JL3Q8`5Ygm&|sM`!w*NviP6t05X2?+LD1GW2VcQ?o0mZ3Lrhi&9M9zIx4atfU> zk2e^spLRTJ=JCpzdbH#Dbe{c0rapuesQ)lTFG`jKj}O($MpG9;==FiJdEzj=n3HhN zJl=4a-nHm1bk}|T3+w?U`Od0=WrChKo2@+89|_52Uu4(Bc!Vu=!=S$k$2I~k&f{%9((8c=FzqA# zn6%waAED2|73d=OkJ5X|$1d_Iqx8j<3(qIq>;#<###QfYN8T}^LE6eY#=DQ!N5zRW zcbx(A5>?%uSD((~F=O;CZr{$aPma+mqdR%@IDJy6NVM2Vr1H3N`Zx#fs~rB!czv4V z`96nV8m}iho+CLtc7k5l@n9OYnxHqRAhL01A8zF|Nd+>B9tmF1HVZ9)Zzkw%!Q$bc zsOOYiqWbkj*}909pnI(BybxH(AlVlW5S}<)yHCXmFT4AoS3MMZ?QuSb z>xsUfz}Jl{3`UvwJX{4npUxBtd^BtEOn!vxPe{A%%2V_nL;;;MO|NLI7xsCeTYc{| zy)>5ljcNJ^Vf#XSupptN%Ggz{5Z?VrP#HdNy51aDu?y4n8g}&=`cI_qDR`Ey+%H52 zPIzE^af%9)fL;i3_aR}UMIQ1 zpw5=wjJ_wbQH zzWzw@ZKUQ1y9oAYq8#DW2ZIS%kW^p~7xJeU=rt2&&|fuVhIcu(Y(W! zOL!wZjp>g617EyA-zDw0`!3XnFzHh+eWn*Tuf+?rKVWc+HLu6pl|R!@OAy(KS*pJV zr`J+_0vuzRo`;v;fo1v__}=+K{~1hP3-3e>g|mIR?w4=G^9#%Mx9|peX@&kJF=K_S z)Z?2DLRG9Kxmnm{VcJZYa>qeqdHsvMI3lyz^}pqBz!{Okt3sRZ3lH8$#{NXqqK%H9 zKw*53^J_Iv`(FPPN)Tdp>NSz#sh#@%@ExP+6sHX$&GMOl@S3}j9uf_^^k1Yu?SJKg z>mq8%IUJ2RO#TcZGn@jaKV0ScV~R%EOOEJECHwh3dP!a0If(cAS??roAIJ~=taEwT zK>J_6=-~?g{AvW_^~Mwl;|a6$FuvfBJ`<0tCco)Vg%!q{Twy$7CLRL5ixExuo!|87 zm?hGsh;nvrzP?q6{f;=I{~*EMXzOG8JXyNMm6Lihbb?hqsXs0av-_OHDT!9@KczP) z@f9rK#1nCeY^z()!7p^XkS$1b=32YvX2@uD)5iHR&TG6W6+M$v8olC9kSRgsh&5hsc;uFc(RdHm#|KQHrE!4Wq4e zn->o<7D&JIZ-b1>2wW3vlt$oh!N%)w9`zb^q*HcpuTfHlW!OofU~gT=SB4rb;7DP@ z=MOX91Ic1S7$$4UwWRp~dmyeUVh?n1$Cw^ISW|_T$mQY2ZB<@+k}r!iYRMVGt;)+q z8EsJ7&?w^#=%)KU%9xLRVN{QZD)xqGqmqhU`9holREzy=ya5XU+w4IJ#@pncDQ=90 z%i;cHKjSlMN^E9VL$Cw_ zh2-W4``xleSxNq)INw>sjOCw|GhQkAQ*q$x06^p*tZT_!O#y;I{fZ(nUh>bPQT){k z#-m~LCn=XmminqbnM<@Lb$f(Rdk|BqSS^q&gF< zYvp;*WGD#R$fqV7b^RPd5Q34PkhY*kW4pJq$K%lRSm(wQR(vhLl58}AxJtcBMqGIT zE}lVP*r%gGq%v_6zBu|9n0!M~qp0*oR!%V}hN~vLBL%U)RsA;s4z=3$6mazdC zpXs%YZr*W0!u$*1FYu@oW3#+sG(VJL6o+fyNimuzm?w|bGe!dWlvmFPmkO(3=wjb_ z6e{PWS-eE5Q95BJl&*%=#!4=fUWK^5B_od3QZxo z6eiyvhB=P>%F7V3hYmaO8JQyIiO))&gu0&ny7w(f=}(GBJV4~YQHj7%K{g;U19(U} z)RR^byee{b96rJ_YS?=%BU%Pi{O^w$Pe>!}l*YzY1tKGrn;9`aR~HgE^GJOTHHI)l z$PR{#fLZUu-)?4fgdwBt&5Ro9`Or*+vVrbW&CDR`{3Q8yFzx2h#_pv#4c$dnzQ_Cw zS4zb?^^xH6mYU%^wX>D)dTH<9?|zdyz&!Vx)B$dBzmxEt>wf$2y^6kTc~T_O2e{OY zAk_q8QD6x&;pDMK;}bK5K1bpcwx#GZljk-!qS9{%<9j^nsKC^d^^H?SoaB_oX~14@ znqaE{+%bhtdnmgw_lF_@WXnKQ9w<2|y;G2lyHSFgzA3~xoGrC89pQ2+lAa18VIgO7 zO7Ld|r4c=(vd20rVxUE>0QRfLHKB$E;4^pg2PZ-VhYtYh&YY*@HZA3}l z`g&L-%TYR;E9|9D7;7NCGn99E+IUwUJBc(eC!L@r?>MjUoe(SIrcj*8Zo%; z+k;*smXWXN{KD19dT{OJYmt?u z#92Y;!YyECmCRW|-i0dESVLI3D$GijrYU_9q660>d%ki#Q>-ufb%bRMalYTccb5Cz z1>a-c?_T(x;(qtTceeYTNu#yU_23Tfv6c?uO>abAkHYl#W7=7`6#HOq$;=KiX9w}; zZ$?&cBt8*UmDa^{XI)hCjHH_?mW4-9J|9%9=)1SEfU?TJxE1+gF|g^38mw5GBav!!<$C1gaLZ@Eh8m8=dPSa zc8hQ*EuT<$hxRLE#Au2WjfjkfK4pSmojAS@-aXiUt?WQbf}7}iM7-FZtr>;m#}*6S1= z*~#b%-{4Nd_eCe;Bi!=qzhl&_KbKl4t`x8~M2Z|NSFam(>?#ttjYMB&O1Q1kU3Kri8BJGb+^2#ajiXNT&NC2R@X*hZ^`` z_#oa4fP3)i^>*W9<0D)1F0V7MhEc%;=f~5GnoWiJP>tS_ulVr%C0Ry|EYm(?&AI^% zpOR1?s?p{gPzQ=up*0k{T`JHY+P1S%GJ?YLB%wc4!_cFVV>%o0FH`W3lF$~aVKTe< z;3V|;$s(!9>VOnb7^(=;ZzWHRU$+F&L^M_N!Ik+kYmAH1({1-jMOm7{1^oN zC>UWayBKxrQ`i|d3)2po}!Nb6_e1F`2`^>tc-2Cowq~0(`vHyT;mpCab_m z`AC5lm@{~#u7;zbHHo+AYP`@EiXRif6GCbnN%J7xJnu~jXOv63X`Lz*EGI{)p|}qu z$;m`JA`%k4!b3@mkYiVwU+8KydJN16!Yq`qg!i}nlm3hRtHQRf(J4HjX0Y&V1BK`A zIS`-x?-|t}Z1$6XYxWB~>pkPO^u^cE4)YFHv$Gm>kF^uRm)_T*%?b<7?Ch6Hdw|>% zFMA*^l|4V9HV^K0M;=8t-17tDy$c9~$&FLBi5cYqMAl50?Xw;cDQE(BU z*B6HRSiCq}%`t@5nnW!^ENRaBhEQ+>+N7=r7ND(}h*Pa_5dpQ5E+oS~3NwA>df=V5 zm3Que_t{#$y@ydDcE(lN+KtN&9NKyXHx~{7b0-h$Y1FaX^~8&hx9?{ZlW&G{>#-uE z_}1JYQ{JZWUvh)qphtd-KE`C={tovszQyx;!3Rc1zWhUD67UPn`xA-qlC~TJcC~vXuO1wW`ppC14Q~D<5wbIwH{(D ziQ5#6lL);*`W>Bf1af+$-f;#mHPj$s(wByUGj_54!BC?vuK#?+FxVNr%r6czrim7) zw?e&nJP}%V`SL8I`vVGj2RjOR`Rl`t=6DIsA8w>TX#3D`V`#Ap;JbjOKgFEK{6-IY zaX?3>dBN`ckujC7Oi?4@X4#*QG&*Q_I~JLM=R~oC!BUtzzjWHqXpnqE>nGNmm?z>LRQhw3aGl&SwFW@( zMAnF}MYIb~d|Fg+Fol!4pc!~1f<+G|snJbJqDmPnel1Z|C?n#FLOA-;ZKU|}rJ%Or zD~7a~@pasYOsDrax&>>Nq)3rc>x^mv^$I?7)pF{hI0`MXhNND8!ebgw#9Jp&O@u5z zu_Ly5Jdir1=F$ixz*kZi)ZPob$1oI*3gbQP*5&`O_U7?X7RmqkJTp0-ekR8Q1PCO+ zBq9Vv0YyMSpD>pQ36H`c2v};s8JDvpp(@IQKLqU7&K}G zl!$VlB&rR{=!kc7$vg`3_1 zjD90Yp@I_Gq@VO#mxTJC=HK9p9nS0vq=W`%>xhB$=cXqfQ_X~vl~pkW1ITugjHD)( z-9Tc@Oh7=SF9a&-i6dEl94>7- zGJ85c17F0ENE8rJeke~I-pmZXl{nm04V~MC3sGq_iwq1Sj54J3nxj;&DBi>Ycs*)s z(QqK)VK`81aEMZ524fXvhOGVnl9)XT4Dhh#zQ6z*-uX^+(s@L?M~T5=k}ol2N)9iu z^3uKCyLS&V7hGU;jquVKU^6{o_(il|1gvZB5-!nC-)r|BhDDE{*^Y*^{#W$1^f)$C z(Kvr4GuR_)>F@8gr&tj^_CEW#LrE^IoE`{OgVTK8roeGz6VJWIb9s}TH|K4$-w&8^ zT?6TrUyK`o`7%x}f81hMzkZ)RD7WX+QzNry74;$^0!2Oa&im}s@mRDK=|OVffmC_s zC6a@)3xIGZ1^fyTcy!=Fmu^JJNTjsXNs47=T*^c&!P61*5$nF!Kplg>kMhMc92ZY4 z@jyJYydg%Q;TrVivj|5E_YGu$RiP~DD}ii43cg!pA2J<|1yk3MsVm;5XI(?4t|3!b z5nXJ#0*|ImfnxoCiSEcaSNv9V$>pLtZNAz=ZHHRwx9_)ysGgX#3O4b;u4bahS*?)N+J=T@Bos%kTJfJV@)6zVOA)t$5z?H zz`N&G*#mP*5S_(-1Wh82E~~N&(1_|Pd-P#hV%1U!pmdx#Wj!etv<(r%)+2_Oc^eA? zarj&UQ2;_d2b%$e&pa#$BlyV;Q*nR@MsbAo(GS~$P#C}ITOPK1^c*lT01`y9_6-c8 z0p{l)80|kXFu=saZ#M`PHAUu=*`*8einC{W>3=Qm!7&KO5b&a100W|MJ1(n>WX~+l z@zVZUjGNLTE=D4#heIMc$RUaXgHeufdrmwj_|{9mhNDrD8wo@yje&?8>48W-a*Pog z>-)xS8;;~o2xI}m4FWi88cCZFz;!#3(1ZZ=aU^SGKpKUR-zaQ}m=Gw$C+N?7{6L%L z;Ro{`Ru1W1Clbd58E{K?kI)DV`=>Ws1!mo(+Wd)&OLHIj~8X-7A zQAOQ%u{~%nG{I;Sc7#E+CkkG>PH{Nhlk^?qpp^J?ZH|Vxx^V%ri zh1(B}V{N(r)~$q-jX=fE7aJkZ#J#GJ=K5eNzCX9X} z@j_nP_quW^TC+sgFST2+M!oPEyLiBk@3=O-jF0NDX=z^ac>u4$yf(xB!@Q+bfAb6+ zymeaFV9}{T@2;`?%RHz}4_sy!Bqz8qQAAH&Lp5gW9vkdlQ+yoQIt1o}Sip*qNB)9r zH70w{<`k!s0;Ude{}}lPW;6Nck!AK38HQtY{<9EiFvs*~?bD~MQ+SIc#Hnk2=FDQw zT{5TM0`*k7?#9<~G4LXco?g{=pg|==qu95&R|Q3G0*uS%_10(Yc}H|f7Eke5b{yCJ z4{pMh!;)y0k1I71@nOB|NBz=rdqlJpf<#HQQ4p@qDPy@{)H(R2E}DhU`v!)~XSn|H z<~pJ$1m+=nq*Y>~CtABgh|U~|--%WP2tcz=MqxlLXAV@oQ|3I8 zA2YeDI}7^eV@Wy+Lxv=TNanluxrYYm4b0ppbn5d9-3M)`VBnjThIs^jOJS4ZW;At7 z!E$#sE~ZCm7*KW+DahwQK8ktW-V0LRPP`KIIoiidh-UE5H2v)g41N{5@Hu;=y+4Lc zv|^M#@j3hUXd7`1m}s^07b|0%@f*pW5ZJ_D+jw; znos4!w;e0x;oC7t)XZ)kCF$X0D+58sT3{`rVMo_IZyz&({g75-$y!V%R4O&E*W!1B z^a98zU4WeETUp#;Xt*99vj?3y82FGYNzB2dWu$xJi54syn~EDlTtmi)*f|AsY_WfN_ERX z)O@}@W8VObV(5w=bMb9h;Jb`*0jiD;0fXB!sLC+!9v0k$Al~S}i`_qG6u~(=Jh&^P zXb`oGw*HN!t5!O9nwbqwKsnMP*%l#NBeLNof{Y^05%GBmKG!2T!hvTp#s*#$w97Lv zVZ*YSDY?az>{T1E$p@-XY1zz{l8pxt*TM_M90PvfNF{ z?CX)ejZc#7N{5w*IZQ7oJKPI%L=h@8JUGiO8o=LDw`d>+AnOR3$4EKQ5bg5t3Zw*S zr-Dm&fmQ1d85b(me}BO)o?7Y_7l5ir6v1yP_UC%ds9XkqOCg-E3=B@8K5C@_#=v?L zU=7PN=woQmpS)nN>{TU;p>^0agw+ioz+b)eMSFx-%@4zZorcN`b|6@V!4MiIi%X8h zeL1E{u^|t5+>HbA0qd&8eQ-wRNnKE97g{&z@pblD$5+5|^T6T}s{n&H0E~>Ga*T@| z7>Jk|NWpPZ#2qtK}1xuDVD@WXn6>+V0mJ_xBCdV!J7S|D6eO0V61VPfX7?^(T;X~_DamWa1-@PyHB(lnWbJ} z??k<75sAg=9I2P^eT&3&t!bzVrL(5ZIpab#45Nl`^A~K}=zlA9$A#+sFk94wtFkb1 zpcT-rDZG<+GwFlO#QH(hne*q^>*L9 zPFd1h@-6HYcO58*-2-X*g?f7cSOo(fIukXgcp2G>6uMs_h@Q&<2hzCR1?DtO`s&18{iy46h-+O(RZwA*@M)%cvV)u?HNpnpv=sqDg+o1{(#P z2QiT<)eAThJU`KDW|E)K!RT!@!+SXuI|-#HzH0w5SiMu<@v40o``dffBq4v?;c~c~ z5IBe2GBPmFoftR^L3pjtjrgQ42ZyA2%?VO_h`<1ypf=hI>8m9FVv746^g<+OLf~8e zh9?BR;V;;jyo63U@$jpPA+sHfMXsIv1>>vM~5Rz0D{tWS&A{s}QaL{WxcU zEeMrzFI}vHVtbmN`MOqgA067$qbPvqUuVMske|DeUqCy)R^21 z3GbTXX}?QRov0JTQYXlxcRQyv-X@s%Fs2fCP>5r{@OnK#^y&MoB>MC{{-RIUU@ZlmIw8=^ zU(C+e^B3LO!e8j0HmGMjwj$MTM$2mA)TX8hdF#Qf36&zGb%&C zVIdiq{BS$eLKVY#69O?mt^-snWw`f*0A^`K0Rv6M^FaZ@#yJxM_oqdoLgo6jaiMCT z%C(?!m4t_dY7mdZ>5`@zVVs|ra23LH{BR}0rGB^^;p7QGw4#J_lO;6jHk7arCUeOaajLOiO5u)(SK(htWn*3P zmi@zNVib|rsNVjbgAVy(;>5yT)ObH+rQYIOZu_JEuQW?)yaO$~b6TlNGQ zv8$0V$0(-Kzw51mzuNZO4SP0-Fd6MJ++wOeW<^B+b+s_bAU|wD2=7MpvhjE*$P`W2%xzM z^YzDJO7LApVuD|&Ok3~RQ*~9$o~;jk$L=?@G8^+VURsV_yFprD#i%npSH2B4iLRL- zsBz{Rf78Wby6PQlrk$fddOqvK?8;>K^gU?KN&Z314dcxG-0!xo6s%?%@{R7o+;_FtoqTVvE+PS*uQ+u$!>k~WAI#pYr+6Cfu z^P{)#DSG@K5ziIlZO?K zoAY)Pfip5d=4~<%roZC>tv3*+gQEbo7zm!#5?ltmryZKzhaCLm+Qy}U!FrqRM;VmJ&IAy;Si>zm4MYqTn zMmBVdY&38YdK;go&O=4&YZg6zKC8K&8NN03Xhj&SS5Y8uXLMONJmm>IJBeo@@U*r6 zw0;S+7WT?AN9lT@#&&}UvAY<%q#K@^1fDrNfaeb2sk(c9+Y?b%Xx5G>vfOPDmEya3 z&!8M3Z`bGMtSh&Skp!g)M2m=s4Qt-?YSYg`;Y#Ls%;2d=;91PrS=}l$CxNF1pQCcM zTUE{7+ZITTmN3f-gQz-zsFtytx>cy%z@T&kK2NmSzBf-Nf$Eu|&Y-DFplM?4 z_AY3mAZ7wjEAim2;!><+thtN?YGIBy44&o$o;Jqr?1BeR6(-PZCz>*%SrfbUQdXy( z8JZ26O$jtR5sG@PUw5T*c>+)ASHQ!L?^yHPFJEKsj4mdkPYj~Y1fn@e=v8#9Ph|p6 z1@X)Ro|n{ zs81)+kbgSve`z~c^}L;y z$2J~J^3*WHvj)!+;t@1;j9uRiO#WxKJUnOJ=XG+^Ns zYB7%4)y9C=>L%}KBBDRG0S<_rzft>-e%Ys)0c_B3%r*JO~DUWZ7KNC_X z;m|-@nz|BZQQHK(tz4F-9>eO|vSScFI$a%RHR>M6syw`r_spjx zL5Fx6noVL{X8oo9w^D6#v*Ek# z2S>pr;0MQJW-me5HQd}2s_{QegJZ=HPKTS@59VWHkD%8oKE^pHd5bs*%~ZCOsW8cG z#3ZwmbAB8MRkhedTNze=yr6A6rY0zXo~d>}%(Gq{emH_~rynjsxO9g}KMLVFet0~> zFu=-vP-f@DLR{3u?A&YJu8+@B{SJ5&z9R2ep$3+k-DdjTGvhpjiG$BWSX_6Xf)5ul zb$Wf4+AE01>8)(lPq${Np=2lkCxVks&Q>+xtBf3V4tVLJ9CcQxL5205y;TADX=9Gs z*BYzcTvd#lsYXq-^7Qyzb*igl;L4NN*~qW?Wvunv1(d7rCkd z*|xZ9Z)D5rq5kMD+`w$LA|5zR(5Nr(q52(UkhP^C!)0sYq2LPebmRbp{hZ!*DU~m$ z$<=Il5*OKXJ0+G*4iULndk>{8@PBD9w4_`w?WG1rYfv!MF&qutgznwEo%Ilb1ayzo z3LDh1@jlIaSdvciAq=F*xF(+Q1xcERl?rqUP;{U!vZC}yHkk}xFEhdqonW@vQ(qp$ z##wz#9t3o~uFX>=pv7l->LT>OwBFd2j!x?6jZS)_x9KDR?>a_dfI`3MH~XkTkygAi z4;B)-Va6|tFTFTzIW8Q-vO5%?-BJfd_5cKegebq{IZO?pl272`JeD!b8p`@Rx zL=|4{ha@}o6?>__pbFFbt5r}rZUGkWJNVOIUs|9B4KM}rc>+UJU$m!z6H!`qfhrEp z+Nzrh;0T$&RbRC?Uh5uIsBZBq4!6-SdiUO{Z@Mt0eydQ8up2Ba>O#BdKMYal>vIRF zKcI>=1Eh*s1J!>0O_|`KkZE8Bnm67Qc+x;sin@O=Q0l&Gpw#_>L56%;5j@dMA8Mh!`AdDLZ?*g2}SB4knox!#kb6>iXiG0`m|zo7DyN? z#)3h${;n7rc@HEUr*j6Y%h{FngVB|Gu<1$w*0B;Up8TS8eL{)K@6Tl(pvJ}v zZhlMoo~g@5sQmNb(@M1yxR_^b1n5pl&RcyDr~>OL$g{-ZPc=N<*oA_ksx0`W+!;kS zTu&HE3-Lq`#!}n;K#n`vy7w?O#2<%=gxAbL(Ht{O^^3wf0&MgL)sN5BP{Z6HI0fG@ zTwxgz0}~U9O7X>wU!cahosSwE5Ecr(+BT*W#=@=>;Da@iRV2IKuq&FImj;8X@GwNM z?i`YheeUvNY#+ym%%cq~U%EY~D=3psv>< z=8(}_=u$C^Y!ALYqlvIM0N>OXA+zld@P3A!Py4+h=+}D4Wt#WD=+xj;(%AnI4D`pXn(Ke-Y3e=WQbB z2y`q-O>nRmx+c0Dq+~NdS!kBfHH6t_pO$R*JKRJ|*EjTjf|lSU(DG9`$|l>*@Dg2u zm=2QT*ch*8ED!={ zfB~x=N&WBYIU`lkarlUy!AJCmuj0Wn$tf_pIb`O)E-J=koQ4@m@KpiFa<3DE%T8T5 zU5y-t&lK~E5gQj@VUxu|FN#oHilI3nzWU}-YTVfLIKhp+Lv>)MQA8p2DIyBlg@`_H zTMkbeH0zF0s!w#hv|xNn3(#&JF6;KeXh3e9?)HIVlHxs>gkr^YKz^f=V26t$M8}Af zKyOHoi1G_Tx#)R8RjkWLtITLU1qB3XBw0mJln9FB3yPUHa=h}nni53;5K%-17qVz1 zAZbJUNvoI?(j=p&2#e#30ESK!2Vrr57FJRnE>6?Ogs`iz-2zME@kQM{NcFQ!-hJE>7ceZ846|$xd}jVX0--4ACX9_;7$4 z(-QP(X&O}&?yNA&sX%R1@i1&?@t0oHh6S6sP0wOU*=A@L@?zH)hfs{kxPUNFWQQo} zpta>iFo{KlP>F~!Pf&p|pwovU|6@cNjOcn+#1@Uu&ubH(#Zt|3ASRqX!NM4?FFQaD zJRb%ts?DbJgdGNc?s>qY%9vzMLvKT~0KnwakH(C2yh(s*>L?S!1hd41u*@1UA$wdX z--H7C^Z{yQSXS;q9TcYzE>;D(6~Q75{Vb7Zhq83;P_>`FVT>9SZDil1QF!|{yJS{ z91{2MiF=Rx^~ASFZN^!dQ35hAG6I1`NM8vcK}qmReZ)Sn25Jse1-_NWv=9eyyNn1~3LxAv53szqVCKjMc&J$jZy~fPemJ`0hX?&w)nL9pf2`W4ztItB2Xutr(hQ>l z_2XmJI9Tr+#>yPb9;cq|QHhtnBbY)#7j~))hN#t zQ6lY2_ufcY)t37%&rmGeQ&No%>t1miakIt|3svs19tZWL}3SVEfr^cfZpLyb_ z3QtwKhheBzQP1LDiY=e2I<4@g&sfiL`c(Auhp8!HGwtq3=k(P&TonXoZPWt~S4BM* zZe&V+K#Oqy>P9{Na246RJ~bK*g-(D^P0WM}yhx7IINpaF^}@r|$O#)0Nrfkzh!aoo zP2!8-{t+OY%kV`BxND>S^>9@fyy7_n(i3Eba@pJw55vpIfHP8RP?sNS$5Cy;aT)RiAX6wz^XGf|5 zR&eg7yN^<%$KSI_NQUhT_hMw^cHqVER$=1-&#W`wnSqv2Ag`M`4)^xFP^P#5z4 zfqVX-PUAZX;@NhlD|)tJ866%m)0kAxHdO@dr+}{vZk(=8#w~n3PFKD4c4Q1zeyw*; zhdTrZn@&*ohM)YJryF1wyQ}ouCqTG%=&w&uxAkq};U0LJtvqvt0VXyoyi-^GQRR)e z0Pj&@?wkh4ObACAaJ0|8mLs=0P~p7;XBYGqv|yUINw@t`mGlNdX*_4rs*AA1Q8-JZ z2b`$>6>QwD7o7;%%hw;AsQ!@oF*0M*tlsA&H4OcWAx58el4=Ui{fgOW6t35!PF9DY zqF0`*j_xHR2KHZgcS{1`U9UenSsje;z5fIc_zpe$PwKCGSI57ahH-~UumE*8tux(G zts|$XK2}3)+$nI8!(n^;u6EYXR537aN!{C&zWeA!d7e$2OQhDK`%K| z)dgF&=^1CKS2E$>%*I|!Q|u{cs}uC{v(*9N+fb}zLAl?Y&2nSI&QTp$0?_@>69JoY zo;p644qY1)5d7h6Oy7SVhR=mJFv=X#sAG8-&f5agUo;3vK1B6Wt|c9ALy|B&*j?_bm%;oISn&JZ47 zrI-ChjS5#u1Xvu>x&1E~Wvg_*i{X~5(vvS%!}OV#siAuQ#p;Ot>$iylf=NIV54OWF zY=6SUS3)H`a4Mlu|M8M;#qU2uia%$D6hCW* z+B^Jq7H;T~3t-Cizs^_t>+G56zLWICnb3^Wwfko^E_XUkSi|ndOn_CJuK)CBwU_>A zrrK-olXzIR1?nI}JZtF@8wY+dz8wf*N_^0RE(OWf{aGnoZ?*Z)YNX}pt1ndtMNh)S z!Ma9H^rIgUj3}HerWtOT(x%MB6VBLtNMtxYHVr>8myW;>_5rf59a)A!*Rr3c(bmGP zOVa<75W?v+a00l5oNz1?i2+Y+;9Af)!)wy(E>P!ceVHn-seywY7~+M?z!05Z>VI9R z4vbFSz5C|Uj@^fh3y#2C2h}TkJf9v%~ffkqIJ}k6(V&Gr+i5KDBCp<@v z!luduerRSEMg02%Po_9xe_z$QWMu`gc?mrb!djCaaD@sVe+dw#PY7I`sAi%vs27|1 zgj5N`g}Vx5Wvk|(fftys_)FUI`i2>pc~t4YU4gr{|8g-Hf9Qo+!Tjh7H9FX^Rp@=r zp6Fe~`_g5-CFuFwo}@lV9d zC7ZY#od#b~K7TQl?A7%g>tPTH8O71DvOyF-xL|A(&NI?6+=KWAMze`fMeq}Wae#B0 zvJ}WOnc1@T%7dB+VWx|Hm)vtVxL8j9j^JF>_Chnf>#u@jHw1W|UrtV!L^5U^Q{1ya z?gSa(@yuxM3<#&!iQ57)uR<~>8R0MnIwTT4O7HkTOnkGzi#Ura+S_~X)1X{EAXnVL zKI$nq-S9j(%dXubDipIQs!-e#z`?Y(sEYJ`@!?3H7azf= zSyawAK{_mi4ReJighNDw85(KjL*n&&NfNGbWK|Eb`<`w59_wG{|P%0TxL#Ye3{ygBgX zBrA>aLTK;feg#6BIWiirct(jezDtu+$Zxqjs8J00$0tZR0o6dZNxv(b3^_uk$;gHq zOH5}+_t4u?TuN1a@=i6ynOgbBxlh%sSirTx5POm!H7ZAOQ|$(Atqif5J~< z)H)Ur#};%vB*@cog3*TdrB`IMoAi$2S#O8ZT@ndHc%6bscqZNp0?SbJaQ(_w$ZMdSv5> z>}NB&0#sqPosta`B$F*#7%y{}$ybuhhxIcgAfHQNeonC`K;zfGNzxEPIN87%Q`wDeJ*G#Tg;Bh= zlVJUHuzpTKB%Q2}>tS+d6z3+#Eigd_qcFXT4`qfQq-@xd?{*uka4Z(rvL$7c!-qd| zRkp_k3D?b}MeM|&(Vcm^%7&;c$OdkF@MQxx8zl7TguwBDU=XG%e=&+h|4S%^Grgtc zlJjX2$QS?@gpoWd>Yf5X_yXt*5YMG$O`bH3<(Nj>j@BPCO_^x9CNy=T)l<@g*uK88 z^$B-{`b2ZEq9yvpHbl04{UR6U@C0#2Dy1?Er7}F9QZg4oX*}END;1ENZU-ur|4lV4 zdyIr-O|nT4t%{Qk;*17RiuXjipv*Bbbb1W^hIBsVcvpRba_L9h~JVW>G4WsyK=TEWcg9CER}_TCSJo6U~)S z3U2z8!m{%**2ZSVi^CYC)qY11QP+ren%tVSioYnQqo{PnamJD zhTh|0t)@@C39iJ_AZ^TaxjfOcaluQ_TMH)l?MaR~|D(Hng9dDl=>Yo;Y|aso!_Du? zR+z{(P_jk2Mw-%pUAZG!TqKdNI6>~;k!^4y+Yn@nPFBpud?3>`^*7;wE$( zy6#N&A7=e9#j$KYV?QfkRtj;cGm@cgK}Vz?AN*WmF>Fd#Fndz;w`Qi5lz|uR#<% zo3tzA)lcb#q*;khN9FxaAC7F{xH)7-@Wc zNCp>nOv(Kl2?7<2tPE!FB#{kCK}HP>RhJ_7AYWoM5l)Q{CP_}EzHqwd>z++Y?84yG z7xChlokRF<88v!&+(b-HkNzvCVyTF>Xm?JPYY4GBp*W2T4=4vN&xi>_Y51-ZaKG;= zA8Zn%)4_(V+6R$zwsDcd%DbukplhZNdq==yH ziHV2lHB26bXJrzG8Fq=8AHgdy9IeC*^LOMK5s6B6WTJKfk$*>~QHg@+4Kb4OJF<;Q zWE-25TQ9l^sy4~na7LGORp35vE8hbme5QO42nNsqs(?KNn5xkFrEpRWC9Pj+9x{zj z%pNC10w#xu7!GCp{bnq}zpmHZj750)>8FpFrS>fuBDXHmM~IajSyF^cklO*CRX7Z~ zoQLGy&s6vcea$R2qR$QWK1h_mOTD2TV18!o~_1(KgLq6;Kg#s9k;@FKlD~? zy57O?Q{l~tk4^gUIqGfe4c+55^|JXX)L-AG@`hsPfYgm0jCb5k{ zl!I62Z&$PNaLlsX)rC`5`}Ly`uzp#rUs`+aMCmaFk&u<3$+O<4ux2Ee;=p|pk4T-U&6D;~-B3ytvXa+=qm zA1YVo*2WTDU#?EbN=>5&+^Njra``wyUvj6~yMJm5!NLR6#n??-qO0#zXYTVOHm6}7 z)PuQm7=8$1T^}JVl*#@d4qy4W!l!darxb zvG}?29<|PTA$IJ&YLd0r4>?7!#4!onLkR`ZHv_KSmlH2@7D02yW~yQWm71aiTn9LIc_|F!SQnJ z(1+A>R?nCE;B*)wp@jpu5(!VQY3C7jF`hiS`Vr`l7xmkZsN=HN26=r7mgaEyd9B`i zu^N_%*1g8o9k*B&$Ns)p&9$sGI{h(qO|SQONe*v4h;LfhoUU(r3=75^bnRm*@lu6s z)xy&9D0VsyG-~T{Wgh4luLnM^jvw)s?QX>-5V(kvPaDfs6Nwiz;+aSMCi58m+~aB= zXEiG!YbAQ;<2YnAzl;I)|a{eRgGhx zz$uT_`no67-=YvD_uqWmG;lnXEf%t|$jYw&40k8`TRRqIgol8Mz&##b&V*t{1}i0l zti`(oEx-1N}B-_QM^>K!!6yA@OC`P@*CXPFTE z9$BZZzJ1w(o$&;7m_VQNwCa5U(@lMM&cbICxo`J#PhEZQOAjZq%uV9tF07rz`A*rw z1&M4G@oX)ru?rciTc5_(usig`rRo4Y6?er_$nhQep{3Y=aEESKs*XJT4%Xt$$5P5$ zf{YUT?!6z}>(?Tat-{bk?{sMD`?s%&S1*k_8t%~3pHZjvk_I);c_*GJ9UtnR!Dg2# z{rxj)Y~DwT+h)v#E6@+TUi3qKNDZ{r9s2Jz&`fve*K5?l;oEYN$mk=Tzf48cuh`IC zY=yDk%v+|$kHbMk@J_nd+!}-vCg8pEVbD9stNDl{6CXS&vdl8PC0{0c8$Jrc;Z~<> zmZ_uikak5&(0dJM|693B3wuW1*4fXh6MNmyO@=Hs&Uo)<#4dSOT^H2bR;Yq8@9}zw zaWEus+};nDQtdSPz#IZCKESQH-un0Sgy+=ZcyzM#IrZpRpHpAT4gVv>eu3KP_B>FR zC$%c|3D2up-S62bjOz@(2!#8F(__kuO^>N-(&F;4DP6z%A}IT*{^dn=qn=-<#&o?& z0sfV!d9%E|I=`sX4+*H)GiTLWKuWq1C;q&snAR4%NLG)K$4T{cICmDbYiM zU1N7Pn#4OByCiOw=zjhD*1wvLsU8mf=kbjYTnXSO)|2Yh{W!a|wqCY?#k`lX>nE)& zE$HYgvqSyxD(CIlq2aMlUQv66;!S)xP49k9<@c$ErDM6z@u7KG0GNj?c$EU)d`NoV zoRx3j>YH?L^D8iA!2!`GY=5lQm%pw`#&^#kPqomZ4Du{D?#z+bHoV%`Q!zm0=@ULw zd11MnAG^qL(YD_4x*B$%LC3wlru?*GDy$-4;S`0tR5(HLmcN!j2WFKD>5JY_BY$uH zCmVi~KVt2T4IRX$Q2e zSI*lf-B9?-u|!s5H_b>#5*9YGTU8fZZG3p}Uj zRr2IB&|Lkd8o3uzU`BykX#5mUIRc~DB{bQpVGlEY#1%2HTel&=U->@g-$x++^VBUDd^BXcaEsj;c zrSL{yLvGmc842>=_-yv-MBxcO+pY&TsUdwj{|9^ir|GxZYW00hSPQ?4#KS(^V$N&6 zmZzq$Vf|%MLLr>1@EZLv59!qV;Sz*v{cr@~8b8d_7u9|k=TN*VKa5@BUZo$V0)U=G zXEkDYi%oq8y9%wPvC`F;c^rw3!>)8V^w4n_RG}$??(MnQV@`%gMHkC0in4bYqsLp& zr1Xx!Mo34ua;v?l^E6%mo*FPDA`dlrAdI;e3)lApZ5q+Ku^hfX6bgf5%A3`&!6;aC z(r;6Kmz$b$Xei(PUVpVl^>e<-PJ9@?Mh!P8F!cWx#lj?t>yWZo3WEf7O^MeUlj%^Y zp+gEy14{SQfNjarC9Q4JwqD6++Z`8`Y(H;-~8G!CIwPf1@vgTBWFDPLKoK|OQ<^A-Ii%;xg^`v5;u@Q)Ax+)BMO*5?!EK5%Fj+}dJ_5D&sA}>hDsfy zdodKNkGCq@{Rnn3;-P_ET%OG!6t??0f?hoW8%-RBSobpqEw@c#aAkQSFId~%VA6qY z-A_#r!r^{mf)I3f{V664Ids<{=q>SI)J>ZbnnJ|1BiBOfV@N5sWZjvSX-6GCMskVu zC+c{qoS*6y9_YZUcHeJ;cj#_?!e%u!+Rcw}rlj0MUfjFwmf=!qK0d$$dVGo=Q`Hw% z1-%OVe@D>!1U~`y?X*C6Ryy8k<++wT4uC(b40<;Qy@m1_51X=T+c7vofmv?2M#(Ep ztgaqCI44h!-lB%OHFD#rNrN(1=!>_gvC$RqXT(!if%kv`dK9;c!(1St`M_7etH_z* ze!#$-cz|`klXc%Nb|cau+?)~yVcZum*YoOx#He)Yl%5r?RYh3T4RC?27NRG0H^uqA z0z&}3f}t9=GzJB9&C@W5Sd>*9G@Szu02YH}aaSblZ=^T2qy)%65+GMdpfw6ckP!IT z1jsxRLxz$7FIklUhF%jOKS&IjQvzgH36O;)Kq*`mm&+IfJkIj7kPI7>D?~s?=)vvq zmelLp+tsxG5OGWpLq!%^EgTpCO&}TW-FkbwIx;t59ka9-bM^jTs!`J$6vUZ(+9AVy z3JcqcAl%-|xXjub7U<1)0nm@bLfGk6=XfJ%@KPzDEcZ_65N6vBDq*mpW^h;PXTMZK zCv2wW^b(eT;Leg4DA8Yq&?cBi%R@C&v8$O!hwE1&ze{t?WM7-D=WkVmoCLln^`xz8 zz?dh1Dw0GMNkxU*?TD(Q8>)x&ysc_z_c_NH&N-mdbcYW0c2Fz0xUh+IlHR%%UZG|^ zW*csQXwg@0!#4QEx*Cx42+GD&muQFHu}$q8Y~H2|x2xe%#DV!xGWU&(7tDPWEJPg! zwhp+@%G1E|eCImsJomtMq|jQZE%#%bY+oWclZn1UB7E9`PtbBc*@UiOH=SD?D#8Px z$;*^ZNW1`=;Z>PvYGF83D0x9h8(si~Gk_07(qQB`;CAGAHoK7B^NnaEND--zZm-pS zP&VGuIc|qKI{FM-{M-#zEaW>pVHss~00k@WMU{(ZQW)S^Leh^)}lmRlE z1jy_XAp1)I6Y(;7G$~J2>#TGF^3cyis0Fb{q{f^7OA&QIsn7!?@Cw0B%!tzvgI#ORN1d&Aq7R zJ$l}+dSh@R+v=^)5t{76wTz&Nv<$cEd!<3Hgao`BZz_f3xdp5t<^}G1;`Oxi2Y5@i zVD%gK+PxIq&s`q!BJSLDZ}!R{!r+Tl8Qwh-_Uio;SjISga8j5vDO~s7c&w(YQOjg+(`rf zcd!%MX{|oC6Nly2#{Sl+($WB4zY7jxJh{CKYY=O7uV2*VIN5pAFSxpCt$y+s7>;Z8 zKYxY4cdcIbD|}^Zb&G+V-2&~qTYYJ*UD($diN8lW`&nzByVf}-XJqLvLpr&W;A;fV7zK-g*6{PWjaGv##vn?6dEzT>*MKaHBOi(0e1(Yvfv%HIrUUyzEh& z$){TQ>CH^85peErQM#+$(W#B)YCZ-%MpuuIyVd{gTED*|66cVb6E2&R#|BU z9c2-UD+yD2IsG#+!eTp5i9WBFbCz4@@O@9z0Xv*wqu`b0Ud}%7Yy8y98D=%b2Io2V zk>BfkI}`Bpb8lw|ev11z=jOha9v%;cWCi~fv2gZ5dwp<-Kq4^%F_E@J2473pSL8eW z^uc`{o*ezEuTz4b6Y`xRJwD&bw<=-?UtwE|^ve-vFD!*_jyR|3X+_Q?JQRIPk#lz3 zH}^)azMD_&*;6JgUnBFUAmWZOzi!=kk?wE-MyV3@RK>jnSym0 zD6y5fxB|=RcR`J?Truw59S_}EZ6F*Y7zL=xK)838H|0$r0F@gE_wI63nqwe5 zK}Zv=)IfOZ99IH(o&Sk74RID&*4MFfN}NAg!8b$t<)hP!^vZplyY$TA&KPS!tZKOP z3G0d9sj>PI&f^x=f-c_Axe~cP-p^4%+eWQ9+Q&W{<*c)G@nEO7Uc0~3Y8p3);n#KL z7^ep!o*d&$+FLTf6bPSWS=UFb!w$Otj}ITQ;m$)I_K#n*9rCcdNCyveruXXXM5Qfx z1O{!v?yb&Fec^%5Ik5rboGBrF(FEsFt5au9bYeOGQSy3{TsGt`)@vrBzo0kMBM$WD zv`I*~Qhznc84_HTu1h96qx2C6JJ(t(V=o=-^s(@*WwJBeTBUbSb{;_N1BW;lhD_67 zMC-E-btVLBw(7};It8Jpx8AL-L!F7iB_<-{3ErJ}wm#=jXQ)m;%oz}@mJj)Q(qYct zgEofbvgXiH9HZdv5eFhhba_ni(XFx4!<@6M;3Hf0hQpmf)?WIX_tSfE$rqE4S1>Px z0XR68afE~W6(5TAKhinY!Xocqra6}eAKa=xnC47LJ2DWyM4$DIJ#JzHU!X>BEDnKW z80{9*-r`@kir46@fJ+k7Fx;64cgs>3coseW7(g&x)C-St4$V9wKr^6HZ#c^7AN;Yu z{`n~9W?HGqcQj^we6KNwxun{In!a8i$2joytkd(3bq)sSy?v}R zB7eOUi94g?cwQl%TP-~(=Je6~9_QS8%m;87l$_J1V&)FblGeXa1YM7?Iqsx;CI^PI*L9Y!7wgA%BvTr~mimNUYzTYlqsat@u;o5s zAB&^%3Hx|5p&@LgPuS{i37<$NG=!}|LK5~#{p%Udzk(~a>3^N+jM(puKG0_5X{ zGT0i17s|Fq);)IC*KR`9{YxR<$$lBrFe)Wtks=oI!F0*ew5UGjDH?a()o_A zbgngYE+?HOJ*Lk-o$t)_7W|gZcS%zusiE^CpUxHWHiOQ;z8db?L(&)u*C0*v`?{zh zJSZyBhOYI9Cc{?7v-)(sCs~G}YagRs8c% zl9o4irR7tGmN$`>k{*|1qtfKrn=`#xzoq3ZQhiBkXjy}#Ti;6yc(V;F7TlUlVJKOT z6jTCpd?j#OGJ&CKD?XB@w|67e++;#S(>5d|P0P9^oR>`KD*>OT^W!vq)&fzDI@jCJ zb-oKezD<92o^yh=RUdG^^GI;hZ~@x`#c*w;N~I{o#q8O|0Tz)P=6 zmt5==>jg8Nr>y_z$(K5Pb^ps@lTOf+@sl<&5bmeF%bmPXpvO>s{pHSBXKynG(V$*& zIre=G)E`~$48^6-9Hj<_N6_NP%U!Z`Aw7Uz>l%(%-|EgQoIm&LhuuYDQs9fM>zZNo z$HLh8S30&8tkL??tDHgnop+UUQgBJSzTr~m2EF`h=ZIj(53!%G29bj+@Pfu)VK2?X zjjn%n&d;tZ*DMP2VXp>HfL-g18G>J|7I5IClUaJh4NiV<=*9cU6L{X*l!MVVrqiO%0XfOKxj$!y z^)pdt|6X$z-VF-z);)~W^gPrq)H|ctZ&!;Cl67FI^Kq|On%N%7)m?6rwA|OUbEET- z&bthgvKRG?%bb$4YCFXC5FX|ly@A3>xiZIa?`xT<3y_=jjt#@?zW@oVVfF5y34JbcVY@+q0a(x$ilMGrMKN z-aWVKiL;!cp>;hXy6Wy=KYhb2XTG&rXW!yHif8_Gd8f6H-f)XEUjKSIW@0bs@mDy9 z_SrKP^dYmIGptSezS++A*iU%pt`GfYmOZ8E=K{RfCQ$KhcrbY{{z(i{OZO*+E~< z=NaK?Ubc-w1 zpU!jssq=4ghW|FhU3q)!;WXftHo2AhjdJIdUgg+Y z;dT5V+a|r|(Od4%di0%69*O)C#zS3wnKQWmR5L8NV&$W6cJ>63(LA?BpL3^EVEwHB zc_&;JZ|P-sIsA@Y{x34*8$Q5E2cQ(W0AP;yg)Bs3azf?j=a1u?=>`Al-s6O$W^&?J z8~soc)F0mER9W}xzg0LV_Ph^T9qb}lSq)TYeT8#tG>pw&vrx_2P=7oG9h~Bo1H#jH zczq}ve8W%gaodNa!ea#sap)r5#IFg3B^CpgxAW#y9Hpr^2>3Xd%Bv=hH`6_dKb1%r zO(dJTAn5>r6!?o;Vmw94$EJ`$$#))NURBJr#UW5WYs z;Ff8tC=i-Lrkn|6#c;eJN=`zjb6F=0uW}SD#Ds!AN**HQ<7aY%!F`qYA_4=y5`#&` z;+V*5zXjs?4&J#Vu+sqHgM~j+>t3FyyZca2uZ-1acFGAqMO`9fG+3TZ=$sp`K%xn4 zh>|Awm1mL!Z3y^vXS!~6=U1t_Bx6xbACzaB1pa20@7JCwyVag)rS=R6p_s^Pz0pv< zjzFgmG!j^Jlljs@V1*B~5oq#(?F82QK<8~b3bp4$vu?+ySvMODIu~NKofy_A7~}e>;sz!wD~}^gHXJ7y9jjnpXQ*^Ua8Mz6$HwCpo&11 z4=f>2;{&w>>V2SrK(hf%=a!~+E&=x#QJwDNJ-uBw5f8}2-j#3cUB>#oTZM1kh3nST z-qkl&I{l+wDI&XdB(q9KG9VqvL|#iN2nRMSBe32FDhX`%fyD&2`9KYUZ+xJR!1q4T zNZ=;{qIjr<&~E=z8-dwm67oBNav$gv-hEcJnE0?+!u3Ifmj zKs^Ce4p&8>pe8~u_@7z{tn`6R1YYrh4g# z!fu_+q(^2)p(q)WUS=w<^jBzWD9ZH&7WqIsfm$EfNubpSN|D(s-EH!e5m@X4l?3X2 zU@?JBK2SqorvT{xIzqG9|0uPQK!p#q5LoO3Z3I^Mz;*%+1~8=UNF^-+UlA_t>1`)v z*)~#EK9RDFEeWFi(Bh5w*iBZdU}T6EkCT>Z5~L;Ila>j)k(OUYek2(SVQ}8*$2u9eCY#~1a|nq zVgla)h_XU8gueGb)e-oQ0Ssx|Q%Os}C+)JH-X@ZkjU#F06I;tzGHn(NX0O4R5EO)J z*u*BX&X@$@tiDWA?I)4+Rq{#yv&uPO(ESeQ#BhAm!jEA87?zie1^xiP#0nq6Y{^;` z>-mUtY7mFBZdl?J#mXLa(u3Bk0zAI_aVHpjt*3tHPG@rL`6rw=f|y+~S=y>}E2zsK zb$Z9LpLSY;u)i6tLp50Scu@DPaf-%oO)CmvGK-Qi>swz+A3=fpZAKB69#J1|0Pw2J z0WR!Y@d0rB-TKNJ=WxtBpRaL_I{-)m@CwE4Xn*$jzw?h>hDpG?`kZA>-}DC^&pJZi zaF=tqzJ3|z@w4?K%bd$}C5Mx1NG@K=a0dfxAfAOGm5`$F)Sojtu!!x0T1Zufb#Cc z!U5o&J2+|mzgp)QJ?;hgd5|gkf-{=G&%WU7$IJrbxA%*H7uD*+Uvv)T@9i%-`|Krd z;P0}-M+RVSqKW2Wcyg(?J8)cD)I-AN7oG7#7uAYO3LS1;Gh?I$dR*lNj!gG(Igi<@ zPF8ep(HpVNtltxPxTH#YG+cz*;+B&t5r~`gq?eq2s*F=YY}&B&L!UVP4>=-@`v9XD zKV@G3V8-D@i=&reEV590FGA*oiXq^um+f=sfabx z?d)mX{#eA^Q_3PU1&+^Kfewcx+;W_bKvhwh$5C|j=m6+i4r(RnO2AiOrM}umDIfJz!H;TO8CYC7WkRplZ2@r3d0Bxov z?(UxMuRXm&aFAC{oF5>bGrc|ZD;6MGBe&Wy{S!d{c#9MCj8>%*RDgJi0#t4`v=g8W zs@UBUa=*Y>n!r$xk0s(4$1Ol`t5V*T~N?%63CFo`!X+r{OeJWA`;z$Kp{E4ZR z0g?!s5(pYo5eN`RAVBS>20>$#=~g5$v?MSzr(zHwjzNIxj}3-aBy*d&r_Yo4x+Jbm z30!TdxCDsfiVD=U!5}l~k{GrpFtn#)5Fn00fciFrK!Bzsf}IHj9jOQe5Cl=wyOW=m zwg#|?&yz2$e%p581LpVrO>9dNZN)s~5QZ&hC@zlz#OqawFH@It_axqdhFCLUDQpZ< zstSN0E{`&LeG>Bu!h*Smp*Us%;+O?!_4!JGjs#zMbqNHusR#s!BM_kJ3)TfMvkKIi z#L$qyP@jrHfH(#Ls=hR>5uo(O1RFOc5HzMD5Fm~~fH~V1Mui>*N@8e9U}#RoAV3_0 z0BzrzDhN=MM6f=ApfweN0C5BYM0b8?FbGte#IPxWp)D1I0C5ZgwC^+s1gK9U*q%Vp zo{B(#ID+$|Trz^B5oq3Su*sLw9R`pu$CKEG4ueU6swAd{1g82_OajC)HR1~q zNo3nM29W^ONklCPM9m3A)PDlSF$vK2v%w%hM-s#O1cufG1|Se1jzECcT?T;woe2ct zHNJU>C-{ofu)8QtfB2@e66+2N-*U=|pK`FKW6i+PZYvzXKY1!?JTEtyGLvU_aMj46 zZ#yF*zE*^N=NF2QKLTKL=8Dhs9dA3=SvP6B$r+PKjOBG>DZ%(iCa&11&untW=HA!~ z>!NTgqXOLaq#sz~Ov`vM7uI#~?suGd))GDc9p?}D`Scy<5bIH0+Tu*or>}NS%YTM@ z(?5|5Ub*1m8RN!n*P}ncV)s|8u{p3wzwxe9+Gi=6$Au-Bsb*rywOFmsYIg2F^j%mm zVimc|(&TajVyr?sUNImzdE%u#RKz`NiErhp-}J$2oYBf4a!b?o-_|&{qNcmoIR8ji zk~=C(3_@I++OF?>&-v9_s>|PZ^3rsAQBY6J3J=t;zwg|FS|8iu9Dt=VwDq3+W&fj@ z-y`kN51s3+8ol^KCz`|kaVYxzVBb%iw{WCm z<0sf~_hBsZsgr5xYc@E=eLe;G^H3?=AcKu^{DZg1+Vv8A15MxE;2dZ_?_k1^;g;*H zHs@koYw*`L?0#LL|3B8=13Zc&TLYc$nNgUo9yKTjU?jkZ48|s>#yG4a-rc*lStr)s zU>vc%-d*3dC9(hkA{NnzU@V&?;)q}nAV4-?gu&z>at4t_)ca3$&-Bb70r$Pfhq|Wg z{B`QosZ+VS%6$mjacRzBEV13;xu>v8@8d(*y_>^JPYJKW(-1{FjV%QW9}4W@;}5&i z5=bIihAyUWP3TrDJn_BENxtncR++!$<%eDE5|+5cht2v%m{YpV*3#xB4Hxa=&mD0! zimuE`2On`wcNYrl)5bV(q_2vNOsB9QIO(h_GCE&GgA;7PB@a)Bmc>6m>Z%*I2_pp* z$0MMwo^;K`nz+a&j2$SOawwZR`Em$%cKCB>>4R_{ z-)89Dk^JCkS8abb(N|CC=!vJurld2-rkT9c8Dx_ol+DVffo3+1JX1wBZ9U`4tty*h z>kYx4g!etRo{eoT8eL%yp(nnRL2lwBDAc9MDI>dfoppT^Jl}H2mHKe=Ei2Dq*?cuW zbI#Q?V^VY)<`b~-MDV3GWh51YV6?tCLn}vI1cV8J!89T80S)j9#THXo?N(z81?}=K zHh)urEi`|p<9C7i+k@Zv=5N~FooD{mJPFXN`9ga!#+kpd7o+`oSJQ;a(NF-6oW=eL zY#h=0REK5Bdaj+9o_Dp-RvSAheAK?Y_61iT?1`Fr!PU&0d&?Cj@qJ~kx1{mB{YBT) zAoRP4RqzX|Tn%Cji*~|P>0n(P&qx;CxX_g=!`)Koij!fwCkkEN@tH}N)vmhUg?C(^ zO8m9UuGT1@BQLv_OGW&}E3SA<68`N9HVcj6`>(hXn$L}9v2<#0-p(=jk`P1Z1ia+> zUNpRn^S$6yJw0b9|N5FMxfMneE_n*@{XUwx zNj5+1yJ)7;ewWY~XGSw@AHk(f5EUO$Vn277hj+c^imqp*5Iq5;o9Z;$q(h0y!i&%q zB`R|lX{6@U2G|8b;OUR_+h`_ES}*VgAr0mGUWi$q?}eD<3TDZch9W3oXa@pV&fv+{ zT{+0V+1FhO@oQWR#~(P+LIh%_^S#$Gn>vj<$}uVXEibeyovW{LQOg*CGH1+y;G~hM zn_PeAlgqL58|_NDs|$=H%b`4BygfG7skr$-hZ4=Z-E@7}evDK3i!s}Rsx}NAs4zVs zSz&?63JXkD7$xh*O;-wJj=P1;)z|qaw_MF|jn>p#5VB%ynX5^IVp(?j>v0*(#k8Ga z^>$c2_D;d-u?_h&e_^L<8d?3torcv%?s9dMCq(g0FK7u#q6dZE8qFrP0~go`dOEtS zRq*y@u3SFzwyUH4D+x{TMOO`M>-f_h>^Zs4hupz#lnTE34rYie_?y}%vL%IB9`yqTO}pc6kS;SKokeeAJTbD;dBe+gG!l}7O8;Y$6QBOFR9?UtqfPbP6JlZ|dAIyUG)ZH!i0^41ZG zTSl+BS_~5SdW2GqUOtXcI@Ty~_&ePqFiw^feNrRv&k;&CmUcX`Py^>Z;3)ZYtC>d@ z>}(5LBoIb0h$ z^E6S8(NY^b^#Fs2)CYv5S6xcS6i7F(!TCU*^lQ z6ug`@4O{G?Oz5dgpXx`0q8Ofxt+;zsg;6{>u+7NMiz;@1ao)?VG&Dp))$#Bmjr)Hk zl0OQF)R5na!sh-!k>WLFki@-HH6;w+Gh^SHW~VP^sX@^4`NuVsnzZhv{ml1NQ#wca z?e=vj0cKmjy3$ZH&9?LVzGMokok>t&a(TfW(9vEc@if~SxQj^@xaSt-L zdhsx~jl$gcrFi8z3=umfD5)W)_CbQuI>^-KB`A{{|Nmi2D-x9-LX4=g$g+7ov?(2j z{C~C`kqo~jBlc|Xn<)ymM=a%e)s)80Mm8J9OCxJ2-PyO;Z?6|pdDydqm)AhG^%^hC zb-fgUuDhL1q~w37sXRw8>|-!tKh#uaqffe`wK9+6?)2BuF`dx{C3zd4;ZX*J4aT-@ zy_olEt90d`rz$O^@!q^tB~D_4BCvXh({OP(#x?$Pn(|ki-q5Tzj%ORmU#qQj! zeYjc$!zXa-UhZtyQ<1yqj#22w#v840{XkO;X1@Ym@e^a~D|Mvays)7%6e+*hLW!c! z9HhsUw;VfNt?;F1VSTP-HEm~X3%9SHhw@C zN_^vaB@@X&?$6^xUr?H=RCctBPEi1aRPO{?16X#$cia1QVLJ~I+Aj z(erkFjPWA4(z#Gam++TgRbtxj!eSW;9v!8K-T;m}#MnUu5?}Zy7^f%cm81C7S5XAO zY16Apoo7u91}g$Cz6GLv3zSgO<)_K?T?u;b=Day}^PsyWcSiRD;~KHSev};w*@Sb{ zUsKYf;2NtA=rEFJ{%cB1b@GI`mO9zq;XiKIO=I zic23r-_`A^sc*r@YuEsWr>w>Ci~m*#gQA4uU28j(0fBw@Zt1j!!>_1^uFM2JXI?u#gW3u4?4A;cg6#KzfJlZAldDD~)kGxKeUS)~Ka%LcNMb}JiB%%_hdmTe zhbqaKU>7nF05W8g40j9}VucKGJ{bhbFGGBw3<*Mpl=~t+>7mp}tP;UL`U|A2l8glb zAteDIdR-+`1>l5Kj5kdgq9au`WD z*pRY@kg}#JWuhPrCpvwkS_@K&m(#!UyNDsBN;1ZQMs^ECj*meq7>E}z_~c!PSS8t} zrwI`W01-zJhf#)zwS|avd?E^xKZd#iF;pOilq$(K{ShHzhx;Lf3%Kq{kCv#9qUe?w(KQs&HS$F# zNXrAbG!Bfei4~myuDUN!#DnNYQ*>*M=$eY?n)#v=q}{d5Y7hx(j_5>u9<8O1Azq}0766JD0zM{ycX}#`odxjpeStzC$TgODT{7f)T*%eZCzl`%_ZT%U zH8rgeoxl2REuwq*J;)`1WA6{_glg6RPP#vk>SF^q_5MJi5)t+6`vWsRg-Qf)iAO() zjk`j3ZIBr8Lb_{9i4nShN;s)xrAO2%?Sx9&`&1%GI|HKY5U7%lmP!Qh*!_V*B?5T< z{y8!CKOO)lc562?7D(FJ=L;`b;QbV7V8BoPH8is`456p>I~>qk5PM( zX>TB|W?hEGDuXL!xdC1JAg+|@26SDjKAuuUTz?|2;*FC1v%!^p2=$6&Z3xDz4#$R*9izMek1hT zlD^>~gX2b9e<>BeMdZ8EtRntfkPYrIbL114fq(`YTxC#^|1g7zWCkbGM1kIEn87Z; z83^K?0FieGnZcd_GZ4@LwJkHK6e`R>Kyw}h6=ooy$Xn6kQ6b$+0{Gj%eOBIf70|#` z?+;SY0Ra`sMXD!Js>jt9sXl0=y40U)L0nkds&5VvCx3l&I3U#my1ceki5wxQzY;lW zKt+8cpg#ws`WQj|b>ndZO69n&fbM({R9Lit9)19{N{beu&pu@6dn_8Eu|@CJLk7Rc zqDAC`>R1+iA}GU78X0ERs*M85gZM2%=hUiW8C<3MZ2q}VpEDl>{n!s(`T(K$96xkh zod@Lo89+0Hu=^h%fG|qfW*@T63w4BTo-%Cnv`vdM{Dr+xf9s45Cu{kw=PceZbQeJb zA(DV(i19x#G`znDBL}gOD}&gBAoj{2jv$C52$Eq6>=-83fC%q#>Hp zK$5~MgG2;DA~Gt&L;g9)%H zV92KKfdtqTAY@bbKmtq(5HhKIAYlRe2Zn6w9!!8u0YWx)4ftvQf-hpeJ8>kO_BmjMv zM5a^v%o@DH!VM=}E;y1FGBKGNi0du2Z0BP*oq%~JuullEuh>y8Qm~M4`2xqAf2kz2 z6TZddTVRGB5E6Qz6?)erIu7;)je7E)}82{;!e{Ej&ln1N5XBV~!Ey2#eDc3UkGbab!r0qb%GkVsqPwG2?%g zS_bn1^36hDj*cuFE12U;27e~43nXI;aFFuHTew|>8x1z3l?frZi5Bhx;d0IBCWYW8 z8@MPkvkC&v77Y38|5Xw)ger#PQqwA<$+e=HOt=D5oT(wvOtWzF30Gv|rib8WSh%9} zNB~O=ac)DL)GNLd&LYrD~BXPha|VxK%_ab9BKw%5n`m-)caX?tE_aC(77-b-u> zO*TtI*etVfX9>3nII`R2hTX2P$k*$mQ0xMks-ho#Y<{LRE~Up$R%%xUr#7>J(9SAf zYOTZ;3ig6W{|1P?)Rc0y$(|=mZ({KjGAb_5%B>l;><=+*=UfdH92UI zOD*!~MhHF041GwD;|^Qo85BBCgyy~a;LuHx4T~sHz8UD4&)7`UKW>FyOSly#?t~Aw zkxX$JJvLcJc{122w>1(*c`DQ>-$yb9f5Buo@h>*{pYicGw=t7Zjo07k$oxrh4j0H9wnBhZv<<4b7P_Do1|%hmvIc15zQ@0zb)Z> zTvMTUM05i48wndZ8aQhH?i%7$So9-A&jpz@m5C3Bg1RttY@`v_HNwp{aeYE?eJxzS zCcqV#xPCs|R!Y=zdi;t9HhqaMT7MWUV)gas#xxP>8-VR^zJv@Ej74Z9BvLN{<16^f z@-a3OJjlXLYNBJa_C8dv_#4c7^jG5kHpC*&X`*8XGf2hw%MM{P)WWT5qT^mrV2>=n*3mGRpN@uylw-kRxA)(h< zp}&6=c2x#Uzk~cXLT8B3OCCj)m4n&cJp2`hgcjE*8i^^fLfiE9A-JEdSPqel`QWtz ze;Y$^n=IVvM<2TnaI*!x9K?`M$;L_bLh`$nO0^yj$;-C;m zpx3G`5Ob~>bE#3>4_WjrM4oMu4-0a}5sSQ&$OR_(s88^UL$ioiEpz+g+jmkjo#kFQavGW1gxuvn6yxt~ z2=1JPoB9}KH!x%u=R}>@tmVr!$ z`fW&JW?Hz-tuSE8Jcc8Q@%LQ_F3-a4ZH2Vt1G5Q#-;3xnez3^rNt#lSNSaw8Y-U@y zyChcTaYHO|X%Us5Bc!dPLSXO!#2Bw0%=-0IfIt32RnaDpA#D31KivFK`xNJJs> zQI`s8;xa36ack(L5P_)>EjLuV!Xp1lyh}_OehiUerG?u^xP2yWRS2%o!kwh(%FO6i zhv3#2I5C5Kl^AB8Al>knIVRIZV*0f4``YxiMq<`k+()-T^^%Q1G;g@xNX!O{yda3| zi~J;I;wgHZwz9K0I6HrBBl7YXB_q=`1NiJwX864TZ3?X)i@<0L!fd9RTZ~wR;&{U zS8Q_I9>fh}0t+|&ez+YL?z=P^{#3c1Qj(F?MuCT^SLqrP+tl4x$TP8!YaF;rdmHn%4% zMz<*)IY3i&bkZnXrz~>6b|6nO$)^RGcbkZ6MnpC8UTWf5EAW(i$vnd!cvd@PT|QV- zC3N0kJ=aggBnPIl&4|kkxh`6)z4r!AykwD!DCUsRmo4(vdqcl>#Uk$s3hh&_SyHcB zxFf`-1TvQ5?^+1%x`iuiN6kDi{jlAm+(^p}i`=(8gv|zN9R6+^8Ttv%|d!A7GJ(cep3vJm(vq?M=NmFkb~~j7Zl)3Y%{xdytW?jKLOf(Sh^Z zwJ+<+NF^8PamgyaLmWZ9<+U9|@y&LiRk%#3EA+T(;fDs}cN_R&j(}ESxDZ5y7GvZ> z2ukHIht}Hzy7wb2-1!dZ4V4fMeSuwO?2`<)hT?I*dY zcZE2^J3?--$c@%z>A@M?r98w zXly^pp-*;Td|;NgZ$y*=x40wCP(!q0{7vzRR!$M!pvO%s%G}^6*BDVwr6^6l(*$1; zSmZzn#ZOr<-N)Dj&ai+xD9!tX#vp45Zl;AhM7WbC?mHju7Kyit9=9z)^DIGW0H~ie zB>kQw6#;~Du7DTm<_Cv9D?m51MU(1wHOsQO>oZq!{~l z64^1&k%1_K2Y>m3zhIKxiDoRppN4Sref&)oEwFG?0&xpNaEmP5+)hx@B=94ZFBUi+ zHeJ#FA!1uYT=LA=ygn`!l!pHF$hT5c5S*Hyjnpg+$mwMwRuNe6%@=%m=5(06@ZH-9 zCSM3&sv&>$#b%~$r4{-t;Yxs`+J03CuF%5WC0wb=Z*>T6jfERgh%86H*hH=kK^9ra z8HEJQ#AY}Waa{;-y#@3Fh--BKBsnY$^aQVEWqXvfXAqYGx5o{-kTnM=wXz?oxvuzA3^C0&0S=3A^;j5 z$VwIHZil|df#t`(6nZULZ9j`o#@=8?XH7=?h>-{(3V$JZiAhg~et-&pa2Y))(jd@R zL>h`rHI;^B=^+c)Zw*;VNd}N)CWk|iM=azp0~reJPl*^vk1Q)WM}t!{2|-CM#{!Dt zalu)HMx~2E(ot}x8sJ2T2q!JzZ1BO9qzOC~0z7R2@!3JuxHA@RfsbK^h&q(xSqq78 zN3dzZjQLzh%;zm!f#8^R-bl-Z5MY@FEEK@eCNSe-2=bDJ+#rzm#7##K=!IlQo2@GF zacWfIJA+K!y>B z2)jRlB%_+(L(-KIdJa8CSTarwmT{6P<0O*NWIb817NLzUxtaQJe2h)p6vAbQn<;dB zw}SmtCNMVyIMre}OXzc#37i%JoNfWV0(jH}&hP>ANarIdIirj;WsoYr4NlZ5Gf^`s zQNil{PQ)O%tOrWg%Mb%;EzcJN-BzTJp~qMw28!VO;0QLE5&YoPp2Ut$!qM%yxZVrg z2tUiI&%QTr=ZMG!9CMbke%p+DuG6@>d!9uXvzGm^`I_=R-zVFTlzL9ljk9E%A1vDe zQ?><^co6_w@4$!>xzLH5=n-3q0MU4Y6ICG_d`U11QLzQwDL7_fUp?j3Pa(jc0esK6yjDLgkU1uDV+eAS z#qyQ_jx&LqLx8_nz_IHoxw$5Ai;>(9ODw>20mw4}TSGYgY60f}XxH-rq~vZ30dBW| zO9XI*3H;5}@D2;GRzz8BM!7SD(=H2GEI5^zoOb(w+u@Dj2fWDy_c-;vPOZDR5n7)@ zR+DR)&OV>%R5w-wk0U5m-TPrX;?w&_=pt$TJiNuXag;#^C?4@fW%MAfr`2M_r@;pH z#sjhRfuMoS-0&d2^o3xWkYULEu)JG=Qp4am`hGYeD}AbGV84AJmcG?9u*)8Z6(8#f zS=T)X>uYj6)SVF}Lej-=5q#?dgVQzN`ZRh>w=%O7nVA9G^DXM`0~^ZBLsSun5I9I5 zRzVf@VW)oNo{B&}Dr`$YjqB5|m_~TaXIp0JJ#GPw>(g(WMwoFT1bNaz8uzE?Tr$S6 zr$T_IEnx3rQ78cp5n7l3$FEizrgqR}qA|Ym>DduG%W`<_wCwku&a+N?9o5-ua z1eq+aS-?#KSYiUN`+&RPjeXhhrn;rvso$Uy{R0U;iypK6Nl4Le2B+aDf|5RN`Af72 zMq{es)T)w(Z&N(tjY{+#t3;;?EQVE8LPf#L5U`7gNwmAf@-DFyZ^W`fu+-;}m~-hd z&o8i^iGy+jjP{x-Z|^YZTm--(?Ipu#`{2vLFl#Gszc4C2z~Bp2G3R*_I8spmu;4~% zfDecs;ZI}?nU@V?7#IS~vVarr3mjwtXZ(b|VAU)KTgdP4%W{YXTm&Gd535K`wgp@x zfH_Vi2g{{zcrh#!D%)cC3vY}QLQ*;0Vt{_GtWN@t@+`-PTR^!ppB@XXd>Rp)Px}xB z+0{tOC)1Eeg|(#nEJW}NpgZ+^u%-!y(LUCTh~Z*-EU{RR31)r6WIdKx2X|w+5M3}C z^fTpT2_m4$xN&9#{Aqm6kv!gljROoHX8}fQ!xO?pk286q1(+oOCruqpG5{HqEx?Ze zU|InHTAcaDml8A0Q!L=G0(cuhGQwOR&`Sv|pvO`x$y0-qd;~#Bo6}5fX3(9;(*5SBk!z%>A3 z`)(CN&a!~pLx4t}%(eh01R&4kG{?-7xfbAp0OXs1c_A|8TfjR4SYQI@hX5B?z>%9s z_(Bu7Fa)>=z<6x3pbY$0Ad5}pVnetmmRPJ73qXkp@P@D|uz;A1My(DU<<(NtG?!WQ zBEjgW$!NI=SYZK51i(^*p~xRCzWI^BVKPtTtX3x0O*f^5#{yPF#XqnhHRUNQDAl>lwHpU?o|SA z_r++I^xrJxc|Wo;;0_De{}-w#3&E25KRXTWChf8SSh2xgA5*m5ruO$(^od}A88ZN= zE#K=CX$>WPEj@}XCF~1ULLP#W_V<$#L;$RIn35a_(+>tHp;SaDFe`sCn$&AXPw|j1 zMpFrgE#xmkv>X6Q2}eSJM=jt10i0w4kA(n_TfnmhFw&1S%G3!9aSI5nO#wjPmYg*8 zb;<(dY#~5C0Aw_$eQ~WLEv=`=21{ROg7uY)pro&}q_1Lv{X~zStpMkO1AK1=$T;s0 zfyM?=Qz!pIm|k|TeP0xk3g!g}jZy(Psqd0c(v1||CVFhPBEB3P@ftJYD-`d>GaUiO z{02DD{KnNV{o1_|Ul$Pz=35XN`ymK^9UWRjhsifAz!3njr3*yrncOr1w=BQ~0B~6Z z04wl!JB;_3ti&Z*^qZhVg`knq-ZdFiSb%{gl>i>g45vP&ka1)P!01yd>GjYqfbPd_`)8c-Jt>Ay?XJXmLHnD86S()ht~}l1+Zf!( zGXs|!Y18R3Ee7X}irYA=gEO(!Mnojxq)WO2IUJo?WC4Hv4JA!2jjARCqSKvi3UAa^ z`H*K9DPKzyxw1~__W0R~v2@HR9h6Exbup)2M!!7TQrZoo$enTfwg9EcxTi=5k>{*a zn!RiW_1JJ#tq6=*q|ZqcB0N378J>>MwJn0L$p`1gL(-=ZC3$%0+c{id3bxhOD=|tD z4n7rrx{WV*PRZiV4GNAi03(k$Jest(%IWQ1ti(GbBH*pfa3=9jHY*2s+7_j{exp`wBf&PRa!RBUoeJlKhveuYWhO_rt3De zUaBogUt+vT;>8BClv-V%zks*@RcYOgmiRrfo@&}KTG`kLsJ?~pPTkWh&7Q2UC7%uC zV^2ofrN1QOG>l<%H;^Y1@~3KYXBjsEgA}PZ!cpPgqF!a=w^p753Z7a#^Z$K5Y7*k_Cl@0 zc*0(s_Aere_Gq5y_ravwUL3;xo%bJm6^A6}F5n;SQ|2`j5SPboBr#YPN_~Zl1#OnETp+kudb6@KqONaln2bBi6wB?@%mG9mei^F)4;kbqA zIXcGoSKRQB4tFcuI&gQug$Q~HT&7Pl%o=Rqg+lc_1?hKP*gEd@@%^OxzL7p`$A3(L zAI~Vo#T(c8{8FW1ILarj_wv1^$|vx9{*dwvL>Y4kpL(x#B;!!G%uLUx$W<(YLSnw* zkn%YH<*@RNw3UB&M5&LvzWEV^+{z=4g6S6C_9!ZfpS)9#Dq|&f(}fF1Jhm=24J+bF zXK-lz7XHC;9Ob{27aYf-*<1Mj<2dC1j`trYl9o=wPUIQfB)o+`aYlJX+Txvf2KN@ITkJUh7*?vF z&}`w4ol`o3^w~KD2kUR)8RwM_(ry0ZdF8#BvTLYkQmFWMv8Cc9SrVGJy`ZE@efjGb zlvcR$YxD)BuC$vkyP%{P@FGlm+iiQ3rZ~jTxCj4IQ7ev8o@YRi6C&@ z%LMLA!doJrL&9|Ttt%2 z^4%A4jQTPjdr4`SAmI79@WVyef?0m-tCxV?&Hr;r`KO#Y+go-?`JF76%;N2?D*uH4 z{Hw~_Ny~7JhF<9G>52Blc*5)3OK=5Jefut_w%gnA8nocRvPfUv?YfeH+jQQ$uGFhR z9&}GqE&|0Gfw0<%Kv{&Gb6rWnvFkryS9(K(&zCFD!x>+$`~l9na$G#nmp8egJPYSP zHdH9C%ib!#Ndk)fF-#*UX1()B_zk))WcAEe3rt-%`kxfGHbfXilVG&WQ+Fic- zrqTm>TKksrcgpo}E7$og%5}cumNL2xk{O08NRUc*7n{ky@J=TUx(lQ7A6DP)NsA^Y zJ@%-nJ?qtR49$23_atc zDy;>HFEVzv-v8{)=rkjrDCO9#DFL?AGkrrJIl!$NGX#eQqdqav`5gjpS`qe z&QzO%8!$wBN->V%hkj9XzH|%PqJbi)_ii}Lmtylrp>Q-rGmHzcJdWIH2wyUauZ?8S zkvN(QIvLKJxma>+Zy>3zJx9t5r=Anj;`!SymJoY*q(M4MBy>FkNLO+U(itLQCeb1# z?=VTHiG+4XkWjxu=&@UsU3`YZwAjPLjPOSZ1SzfXuFFFW(%{qljKXTW&YADHIxd0X z{h;}d%eCe)7SC_)S01Y~+yT9bK3Z$z_AlccctpF$gy)~(i7Knb$1tY3Hk+O~f=8-m zLoWmiTc+>u(*$kmT4uhNp60(-S$)?c^Zm#*-d|-6T{F%1@u&GRm8H8TnD2+L@mg+{ z$Xlz3YK-Z5NO*RxwheVJB-KVoq@t6hm)Ur#gN^6I4=bIbFS}${hV!f1HociR#$GSH z#s|4sy0$MC$va84aJpRX(3bMmZnjJY^{XiMCAl}EP)xkMvBn<36?%Wv*fY3VX0pcq zgudq$jWs7sy=v?;awk<2*pg~237|981gJ}O_7@_~tj=~zmw9Hiz zrBK*phHD4P`DgL09U`9>&mNO@@}u$WC+QbH7Z;MjS(m_SHJO=BT`^MB4YZE5Wb#W? zwQ9ChrawaQb<#H4QzP_x=5Jm-kxfC+1&ORbQrtR;O|552r|m}J#&@RT&c#sm; zu)PlEQ?89oW{*(xi##liV%+6n9UHEo3(#y&Q_U{pSBAD$Npp&;IO&~o zrX?-`wWZm#6u7ZtE1z0%I!6}HW zo#LbFuuiHOdn#^D#YMLV>#&;8ytkqbTO`TH2l2&^uy5qDLHvK}v7Yj`gZb)uXmCyp z=I(U%xYipwKn9fI61RR%Mccvukj~nuLAvJS(^>tr83r&jv(VN{kNHBo;Y`Lb(uuBm zrt~Q|XJ^!kwzz4QbVDN5ex`s~q| z$*~xyYyw7`jq)gd^!4tk&)$p53V z9<{@n&Odgr!TjyUEQX577mb;x18Q-)sB#xNNmRF5b$ECKSS+sd3n$A>jl{l`u@dUK zR0gvFZ4+9oGQO=b`>z|dx~LKksH6ZV*>oBc#dTh325VNau;Z`PEh zMN_>@qjt0)+Gxd4-<*z8T|T%eYn{50GJ14Fs$caeEfX~;mXJ`R72>o<=)GVyKhl)V zQmInM4hm7Jci~YTBGUL*PKL{m-#~Y0LNnGn{`y)bLg2zxiLQc?Xp*5{5kJ+8)#fqH zA;_9d42h>o&m?Q3`0tvtCrC-dnzMnZ9^)Qmf0cga|9zCzmHK(7J<3WXqJI7ut4(%4 z{xQ}`a#G$!;tp_otV{Pig(@9Y)sNoWkFz%g`1Mw3llt+)t=I=(^-^oW>YuII7D0Wg ztzgC9Z_Bnx+}o)gdtLZXZqG&_RMQSZfH55?6kpzfy+iSOI>J}l;qBEG6&RnWEVpK@SMpPKEZx8_?Am?Lu1iH zA?u{hkuqJzEz@M`8Bej~R$lb^wBBKuBiV*IU!x+#e2YULIRF(Ma_R}!&f4u!<=XL) z-AG9*ccwZi@YbhTO6M{(j?}(}*-@iX4GP05YoL|d{h>W!J=5-G;c=pVB`%GhX7wp) zuRhJ%MNAf#bxOVXx^UJaax?WcNMt_oY1V*18=hv*liTBY_7Cq@&#+7h*>LxF?2&|0 zRBdEvXy(w5@aQPj5$`Y1_VAn+(I0>FS$1C9!C!a|b@h+@ljqoX#3k{0_7q$%xRnv3 z-@o_(Mhhj*yS~J}=FfLy9^&v(H>1JqvDe<7pY6t;bpI-fmWDDW>807;PA{{^4XX<0 zFF(g(y~BRb+6$xD^oRQgQ_5|KWy$S(l@RC(if6oxIi? zEG~hnk0J?IV$=QBSuh*CqnaJV*`HZGWr*R?`F(hF{4?vyOb@!Ma||E$XZ8vv9FPB* zwQXz?FzyuBvp=I!)c{_&1+}I833!_TYInx)7hY$RnhZ0TqfclCK^M~>1S3~$&@~X4 z&_I~@H`qwT_QM!?Jw^;PM z)ISh?N!&$89S{dqLjsC^B7hMz!-yF}(O--ZF5P|VpoRvmH$pg{0v$~RH8tq+(3A{C z;>4V;X7(nF-x5a2wYORGaO$8_A$jI)*2FQ^flm0BZ?o~wqPoVJhBQF~7dO?Te@C54 z@mu(D&}3a4aHbWZmx!61IOHVUBR95jDH(-?I^O(^9;kMf^Z)i>Jyg*Rx0w|0 z=^ku`gwgi!cTmUA=Ud-lehri(1mG66W|&t!w(_e$)n1lO}gI zJhfl>+;>@g;#PDaG3rIC(L}YBM?+Dv4ujah54_9T#SVa2q$NyrimR;2coy&`e`Rf@ zRs6lbik$I|{wu@HU`0Ib@2pT-={@pymMCG|apxZ_0Z!a|Y&l=gSR20eJ)<{!{5|%5 z0(!pSiAfZavKDEjCQg0RiuijySsh9-ghW{hgRl*Y=PQVi1k$M%49x`iQmUV?SblmX8kQmp@{4<+DS1 z(#PnwmJa1@K4y=~Cx`M6KW253%7%^>b?KUf-dP{B&m^hLTdNnt z#6Kih^%+ZX6&w9nz33Q!=2JGk3jc2WozGbJDv6JO&OYO#QZbfVLxWOL?|=6>n@0gI zPG?CBJrpaRum8zrR!({T3-&2r{{@>Uee3?e*eZO`r~al7s`07(U?287;`QPH zDTze{q=9$q%Rcn%LYh3{4w_B$3xh4JmHPckuJQeS*$R2rH9oN)`!~6<{gL-@+xN#5 z9Ng~x(esDz$m%K9}876&N_yFR90e8yC}uu-y>_lxRB=9huE) zChVg(N3ymcmIey9v7YuA>Pg(z+$kHfLl3+ivjDg3`U|T4dJ`{P0TVVYRz3y)@i{gumioc&ECNQc=wp6l{ zln+qR_#_HUly}xlHdsQ`E%VUHneBZok3|W7TX#DXRlQjNL!R?Ja{k`*^X=cWGtw+x z_ycPS126l5?K4qHxYaUHB=5CZYzIZQc@8?nv-uz9qW|y>|KGW2RcG_Db6Iv}?4O;- zZt-FHtU7-spS6;H;KTD-r^w5{|1%$5UxD8+pWUhi=smpviIl$QHy5&NmC+Lx zvu1uJMCnC~gQ|c}m$2r73Oh)=hq~FzK1oHr&~Z1q+u!qlel}43*Es@BlsgGY<37GkMY;OyZrp<@7kObUF1!tUgxA=INxo^k>pl!V z7J2*aV^<_^<^lFC)v=G1vPUK9Xa3qDRzis*n-8|*mk+Z{qJ-2?-W!LR3=aJE5%vZc zbw5g$ae*H@#=7AG`Ig7o80j1DrsM2cJ74n>`)|88)I?}>gOv@F9}zvNDMrbpC5J)% zFm&(K3gsJ%Z;o~n^=k*u9Zn}_V0K2i!+Sp`KT9&8hy+>sxYKO1>7T^H0<^;4IAc&m zog7#O_*XB;AM+7s*%y#K;v6!+%X6*-d19D1=N$W0UT6D){6gY&rz>k(9-?%dBhU*Rqu1_=Lu*X%N3XG$A~2ViYNxkB*U(GaSfQsSK6vc8o10lHJf2=Id!H5>wGD`RwaP#qjfW);iKRKV%!5rq{#gWV+{icMB8+wOL3|pj#39lx1G5K3C zh?m}Ff9D(Tq7P`id`a%>6>O>UgEI+>Yoa$a#-lz%Q5lsZjyUkwwmdaXZ5S@Djs@M5 zq9(^!l}7O~qfFaud~2jb%v4swp)5{qM$9QN3k=ME7q5EwB1w(*&8DV7`zu;tJ{4|3 zi>G0*d-)+rt(~+ZmU3F(*MIs!(_ zfqB6%%IYTaUu9Plq=9^w-4M{_P?I|i45tC47(mz?+rFf@;P#fR$#XKu2tDx&6e(Oc z+*8kM(-X#oaGr2ne*CUO?U0-sOH8o2sI4V$X6V^Q7XEFxT3ar{ z&G6xB3)03Rk0Yh2PkUC@A{iK>6u+)0lasK96Hc9d%wlPIS|8Z!$zVhF_3QznaaTWol~l zc-SR+ywbC@gn$~0iu2b@Z3M&h&SvU1QSEH~c7Sf#I7>CWra^7TSqec%N-SS(k=d@_Az-ulW*p zVl~}HBcwnZ`?R`YV<_**%<2@NG;Xb~wjxmwFe%DT>-s+Bq7b);HiNw-B{Pd5f{lz; z-<6i|>(Q#{(NnZ)aFpv}stQ{tR@HrFNvuqW3iH2|@u<*x^Nd*aUnCMrX;PFUL?o1S ztDIU*6h!(mPJPh~7Anhq3wJ6*M+tGGx760=;QxwO#k5t~FKD?vf!g>fJ|JpqV1uaB z5>zpA2x-$fLNpAg?Kxx}s9A!_cSVBQ0zHKmiK>`Odoxj`CXA0uRNu!ut|LkPM__&W zMUr9v_tsCpCaF(Q!1!eKZJzdxIx^yiaETdHg~@7J;RCe~7|ZUoe^x|Z6lgIVOM zSZ2SDz;HE#$BznD6Y!k?m}=u9h#y7~f**zp`!MB#wYL{N>R%{Pl^E78k72RZQiJu` zI#tc1Acs@cGg2Y{B~5+d(R}oGXf0iEUOh&If&ur6Y7g1JDz<~UC8=kV4p5O zk3x>*Mn0u}AT9QO@suih&ECAH)!sthhQCwqgpuG4x~VN9=*L^Hs_9N&$wMB*dZI^) zd6bc6G*jPDA9uKq#cC&G<*($VeSgI`+OQR>dpH;f^0v9%S+dDh(vPMIWGn3Do!D4-I|ydP@o_Vm&lR zOa%0p-;xs2{Uh~lsdZMk$0csD*AEOKtHxTGUWQ-jl;W4Ee$?!a&#@=6VNdOwShIG& z^s(A0g&URgHfIuS8T&+R%C-oZ8Qn_n7oVuzNK?G{bG0M65&u*tBrHc~7R{dYqzbEV zY>PmPtcu>>vVW?j(S50}+t_x97CU_!pYw(KPszPFLQ&>8v8v#texJA5zty=CtmNQ- z)N3B_P=TZNfhe;auxm~s_@@hg@3jG zTKt>%S`e#wMyswD?ZE`_G$jc?Z+8flwRYuU${rSY^kIQT4+|`~2iT}`8Ao^MsjZ*{ z=G_w_Fb58PrN&p512w<4{2#A82GmyCQd(C>Z_@a&LUb|Hs>tlQ0W1SWIQO;sC!Yva zC_KOAL*~qkhXsy%SYY$)R?e^m}W*La0cAM zZ^s&AQ1AiecWdxfyOhluPWx>LTiw#Rrq)9r#7vO&%}O}^Eus5eW@~hkN%b8 z^Q-W$sKWon0hRNaT!sJH0Y*QN();4QS%T7thGj(?QL~{~_Q6a(bt{Y?{yM>`MQEFH zD>=UdWk9G7^9EKf+x3Ae21EDapU$e>pJ!Pz2j<R8ei^hl;ZPP;j+F(_TwnI}peXyGTxUZqLC8HyDCKk#wedtpO`bp}gg*IA#(oV;w z;&U?59gOBpQyr0kse5FI`gUbnnma`OrTQ{ zRgy4z8kVCrCVxzU1ocXe=BUrg(}wb9Bha0hJ(Ryfu6HQ^dW0IUuBF(V+E6U6VgKv2 z5f~KA9KiRDP`ityv>9ns;h0CL<<|k?S~k+?6o>TedD1AgeY-W-%%6hUo3(Hg;1Q=^QbleI~5g5Qnj8ao#FqWrNAeDhJ*xU(~Vawf6@6u7~ zO3C#-6@a77u?NrFdyG2Ij%DiRdWy`M7|EtB@z$B3-jUQI^t@Wi zWo^J@>kw~~N$OCcS?UzF(M!uK3!5fsSFkg}XD^sA6hDnmYhWvvV)^`U)FjgU=5N&Q zJnJeO#OqB_>yQu4Ut&xt1r2k*m|_g98a}Gx}0UFmfNThGDTM~6x?H~A#SMuoGScpRN?>RG>cCqZ6CCbyx(V6lx0p? z&ai*QxBgj5fUwlSWfiyG^rIJ4;CK7-!sQlgO zYS$DW?6WkP>?bHZ|MLtrS;Y4r^T*g3=xYDpf^Z%j2HoS(XqJ9!Mx)_JoR7UJPR3`L zMM1Xd->R<&Stk0>4;!orZ#h$qsx0e2oT)Z+&%<|F>GHqR97YEnW9B4m*YOpNz^*c2 z@21(!etbyl9R8h}7Dau*bongiGEESgC{JaafGT|`)IMR6lzy_fs(6(=6sqWQwBx!0Lf^&7q98%b3X* z-36j~x@T>BzyhNg3a#DtEl@iPYYkZouL?h5A^0GkpBAbcC>$oclA=+$T=!WH~1zUu#(O+R-!m433Z1Kaa{nyrpa?yMJqfSuAbU4W6_RjwARiP1x` zyjPZ2ad2ElD>UIat^*R)U8|bne*D%bKDby-mwNLXV=srH=M(;iA=rZx}o@8mubfgJT&Z_!nqB0Om2m}mqDTg<^#bfA11-2 z^3~T46TNAe>K)U)ZMwHi_onIIFx_&~y>7bKO!unkUNPOvH%DcNGH}WCxM;d%rhCD3 z&ztT!(>-gtXH56B>7Fv(lcsyZbdQ_vG1EP2x<_t$jFcTVJr0>}sp%fPNm=(L&+KGp z@k*T8E@9IpzHJe8aW%!p-`uEvF7+R^bz+?N;zsouyL6Mc-J*8J;^Y5rQP)T-dB+m9 z4K_FZyF~pmEjJE(=A7D;xKyVn0+l&-&!Xc(`xa>*7)CEQdCXSzCw$6yV5_=M<__;$ z+tp-=@7$&ikZyY4+^(ib(bfD-B#ELOvnvxuO?ka71@``?{t+7=*ba3%_GRbqP(QYd zFZgJ4x0Bc0qs9e^_c))m2aWDZ-exak{GNZdSN#lt6MIn^Z{h#gr#9tN_o>6cs@Z;Z zrX=6AdzWcAC=`@r}&{` zYJ0R&HIHM0{U*;nu1>%f%XTN!DV`a}6=*=8b9ofTy-2<`#F?ZUp6FE`yv%Q&fKVc6 zUH;lh^>rhBUB36ETC3|#Y9ZLdlgG1 z=tofu9Z#uCXw8)_DBzb*sa<)e)9NSD-Z-(OicScvv5=0J@HMB^1JZWy)H9exm$vgI zXVLrl{xXj_r+Q*$fj4#{j>I}~7;Sf;%O1R)&#BR}G?f4G0v3g#h$$D;SNPov>dVqV zZ?`h_H+!wc7}wB1OiH!WaxQJM#Uq6t_~2#{?|KExo+OFodJCw9p8 zzM_63t>B)kY9c;uYI_weIO2KpDpnUaM)H-No$un^`@uD}NWw1C=H=>JvQ*?9aZ{}; zVX4P^OC66rr!U`DA60jqGFJP;Z8oJN&;1=vNAM)c;e7f3IN~w18G0K%jWxXH9rZiz zxQqPU$@ROal6HD~-la9LNtgMK3biJ=*DBQS-W_%k`q+m1F380w!%jXFPsmhPkN!%ayh%_~XnF-|0ahq=Gya+2Iujp{+^}uOv6eQ9e+WK9KD`IrXQOi zKmDnSb$)zkLiUb1qkZ9el$bQq(Tl>%mO-)x10-v8VRfV`0I|Yn!=g`lLkYS?`n!d1_%{$DcG@u&7P|mQP+V91l3nUdqSo;aF-;?J~k>QqBch{FraaXjv zhMei*^`qVIq{JXb5Ayj5TVaE)qdoS~+NemSBfRvyBYbzXyA}UA8qpdrZ6ni+i5q%t< z<&1I+yDmnfSu>`V6zV2}gdtuA47!Ugil)9Y8O`5AtynLtZ+}~9WP!+}g8^ws8O^m} zUpuDS6vh8BJMw0lLt^|$f;&IhHHOBIi16MC%Ie3lna?K*rjx8(3}I(Y)o>$ zM3n|s-%)9#CA&MY+wtHGUXoT3$KOwOe=Va}o=JuoZ|1Qn?&p2>&I;ornaVOmY7W&Pz4i2@x9{V#iu0|G0*`P@|d% z@{5`XmeGs9)YcK-)K~G~Q@6m12Mr}vJjjAz0PkNDW|Y8Z)pXaanV=|7pwNgW4WlP* z11eV-2HG|l1FXv9P8?ecyJFyP*E5XjEt5Y|%iT&IeVo5l3r6=!C6#wPF9#{EGp*`M zdJM4*2tKNoyJ6RKDyuL!(2OJ+CMb&~Yr}HI0=M$AC0}|a^0mr%vuZ#9PbCd!G~gpz z9Mym>d1gtbvlUGvlOK$o9FO5(@>qAYwV|_a#7|pP;l+XzVQ{7ec7EIAu1gAn;+}R8 zG}GH8)tx83cr=_!6*U`_Sx>?g{LKbzs-=81+^Asog^NN)C1W4F^uj^-A{kAGk%MMc z@dfWu$DL9;p9a|4AJ8nWqqWp5)mV5-l|<`EbwM_NrndWc5&aW%RBzf7{G+4Q68N$) z)v6~vO}idp57{bhUBL{lic?=;-Z=h2ZP);}bgKA3rLD~dCgbR*s6IpqmXHQXyG!<- zE^p_}>bT=GLwVn#@CMty^uG9!LqGcA zNA~~2-kX3&Rb>6ceQ$R*x^r(`5=ck_bix(_VHXf^;L0M33%Khz4!9zqfTH7qcC#8J zK!896h!_x+B`gZsfDytX1_TL;5)d^&Sj8DoR1}o&ck0&dC4f5L-+AA8{@+J<`kdOg zQ>RW3N=N~a z5<+GH@vSCoHn3HM%mK23kU}8EguD!7At7^tEFk0+AVq`}0VyP89*_b;<^#zmM)c@UptcC|3XqsyPI|8l+ zYzO!*AU&xn0c;NV9w1q0S_jw=a6OD?{ipDz~#jzM-jqb^Q+N*m!v5#-n@e4D#V{ zUG25B@xgRVFMAP7Hadm&&j4l(zBW_y3|K`;ix2^IJ&WZNnac{wn%Q-NuX8m;E{&%i z6Ll*Kq2(d8BE*&o;|KADhm5AYZ&S^cSuE-S4ufGvImAB~QjRM~w8M?4@XdA%;3J!A zO|wuK7V0E~gR%J`kvK@@DBCgE)eWQ!yb7R7)}ZUkJ)FNpIE) zP0rHNnyrdw$MD*XRL+FCO6W4khz@rrM+K@u)!7~IUa8EyDylYrGE1wUH~{;m$}h3c z!gb=_udMwRUznw3d4=y`*k*(;swsA8W@Wr!pJ1!g__tYF>!b=daeI5Qh-JQl8mdYoA_3XQyD{3gkT(Jxic^nXbp%!^@nS%u)ls=8z^y za4*Q#n$?2vis)DZ$-IRbgUhjA?v;FVws!S3;4{`Th3PZWTsRB!gn4L@LV~BQ5RCWJ z<|2eRDa0xl3%YoGiCOjBa1_h?wa_xvo^C#+h1M?S7#fhN7V>Q^w5;0Xpn*6JGXc1J z!HsCtQVmN{jIRKQCTK=sL}(>(DIlLy8jYh;#lvR|OI0!-WT55@SN%T%j&5N<$(^AWh&Y;Sz;$~|tgEw!bHT8hvFaWqc z1d;Ipt+Zr!aXirlc`W2(TWK#QuArfh#x@Dd0HKh27xMb8F+d`t*6uRs&Y|YmcQoM7 zx7NBtqTkS3o31qDx3$r3hHGIP?GD91vn~DdJ1wxHt!66s@o(FT9YAtBZ6Lx%wbOb7 zY-^|8bOT8Ptjg`?3giRywO11VeQ0G3^Xy>|+t{GQEXGD`fYH9<_zagAKCn)lf{7MC zbcJ?>2C*@12+VL{*GA*E=nAdg&DO36Mj0s{{q(0pRj%@#2aeRd+|zpep`F3SK!WT^!9%OFPJePb(c0+Bwou$FlYo8zjfs<$@J z>a3M0`vXTiYZ*#{m%{5`rL{>ZD7W5|;4zjXoz`F> z6{FsMKKLrFMc-B`6?Br$45*LBDiEfT1EvPnZg`w@vnFr@JLArPZ#fQ~vK>Q7y?Qz- z3yf_Xs*$9(8N!QfaA-->F ze^>6|jjq;O4%mELR+MJ^hS`|4(4L@em)FFx73)Izd!d1VAVQN_I%*zcsyBgR$Pe|x z-X@B5CLTu~ma~&^VAGV&S9bfatJ2$7YmcCp>UY<2Xve&$yY?vhBdLeh1HSk4(6VuU z`BD$eB|qQZLu=NAtOj%$WKM;2iavniwoBkHkdRF#&Q#Wz*XyZe*7lPmf*rD(ChstJ zPa^3&g`d6$hfYI#Y6(ff2(ZwI?o!xj>@Z*tWL8hDCrbRPr#1y+H?$X+fuB$91=acJk^8+_%P3j;qG^0@) zI|mQ|sR&z@_Fg(EHg@96%u%oMsKL6<#^!xtQs zgPo{Y%YL~De9EeIoy!#XiAtT`07LamUoGvPr{xjRNW7iEd?7jUX|r@TQMkv-wK^$#TEKlat0m({6#DWbv9f$AFK6bAGwShb(;?}t-3NobcM8=if$ zmWjc(M%k{7IEqGh6!XV!)|%geKBI|Y%;X zz@AkNC|xp`FuIip5q&_DjGw+)OQKUrcxPf0M(iq6?T<{X;PhJ{$K~@YZ_zHEB;fsd zeCRD&^8_MPNuw(6w}@zYzgx8{WXj~~1Ba9#a`!x<6gmX=^X|7oWRc}m?<2&{;qTol zCgZ-#@j zKV4$|L^ommv~XcR1?qw1C2PR!8bA+lD~=^mL+e!#F#hNrT1^&wQPmOs?Qnm})34G} z_{rO}cvN%Y9aIAZ2On8bYmYeO0@l%G|C3k|&Y4m9xgJ26B2{E0iY zE&wa;#9{L$?!F60z8iUyyR@#D$@bWQ0wCsKfys8Xz}h~@%;BT&(i*}((HnPZbuV}1 z7Y*^@l1F~u-KC|cVt?(8>g32K`bjh28x5D4Ji<(Vk|pz&ccV3ae)rwlz`C1+H5rtR zCnj+?F^wTHz)NO09Bd>1>TYc&Vm|d(trKeh=3j9FxRICtRqNF@SbH=*8E1MJ-C*tA zgVLQ=r=(%`jAO7~B=rpE*WPpa)?lB1>DJ7+M{AaXmDO$rF0Hef7OE zjioN6siXZ(OHITX040IPKr*o-cs{@CZ(0V!wk)!%hyD%wzu|lmK)1-l)8MrZxZou# zXGgFOrRiGd#NV{mJq8dd;0TlquRDa0jouQ^bLdJeOo$Bf7OHDvhEs0Y&=qs|-|y9u zYR^u>i9Ll$@+BVap2l}_qSvGd0y>oyq1)Gd#4E4ZWFaa*od zmaEiqWm>M)mdk6oR#>iN;i3Xq2Pd6r(8?*Pmbd@Amfr4Zxl~}k*h}zrI!1k(I+*s2 zVDD%Pc89PqJUrb6ngAU<&ZqocYjqoTsnvIjVv`z2!jwzsWGaw5yh<}?w|A%ydb3&L z2%gSkus6hJ(F38JD9>f;!(qU&lj9gq?5}n5l!E}FJWbUt=XdwlZd6+HMg2j$mAtIK z*6*5ubWktk{jf=o=ARF8GY#v2g~VibsS$mKx^Z{0LyBwbn#yX zXh~Oqaa|29D#5=z*uLRfhfd6({fs>w_>mYN@cbyMCw_gsQqyC2-}`WYi(W(3RUz(V z;6f&}S;5&fHY=!Eve>Ht!FICRMuj|SuOc>8bR;(}(;SoOjmdT(-(IQWSdUJI{E*NX zZIzs~BvJ*PRBE=v7nR|}n9|nMS|!N#4p<$|r4_JkuiD%ZEtm%4#^8d4w)$S$@Ten@ zF#o80){jq5+9)C-8KyXUm^S6V88_PWk&16H#dTtprB<8Hr_A#(HLVOsHL*M)Ka_`n z5gF0L<1tymDRzt%Bfw-6yB zSP?&Yzt*^6`R{EfaM#E?_12n1>?j64Aa)cJAJCqnTU_UZ+J!hFr4Z$D_e0uW8U~%R zPUul0E<|V!@x@(4M;3g?!&;IMFlIiawd#ixSwuh+DdJcKkgS%%1OQQoWGq@fjE$cKe$`ab0 ze}Tpf4qQ~yET9wfG?KvxNBL=(95{MmjfGf&C4fW>h!wr8=)m^#b&qJd^=F2zX2G`U zkBTf6x7{!}2peize|M?a*n)SOC4BcFkl|+j;~?z}jO?8ptbKx=cIgl?<_Csosq7@E z+k8FI%%`I;vfJxjYUzv1$&c7_Tt`j z5yPO?fZwNxW?gcn10Bz0I+w0t_~epop?;U^*T9{AaZLYU9>)*DI^ zc2DQqhiZ@dY%YY$SFk8+nez*l4>}feOJxnwd)Q(M=I&trWMZgTz9OcOSgMc-dfCdv zK320PBr?C`N(E|@2Wi$)Wv#;0G}wAJ)8q+r*s(J``H;uXLbNI5&4z1f9q91cnWZKQ z5dsLy!2MDd?)%62b)q_w3*4lmx`Mxe#5X-aV=Y7*7#PO-K{ME|S|{)U zzsg|BLaYaN6l(}o^TP9VT&|cDM@T?|tWNUOgb_E@re8LEA1|{}BiF3AZ`GZetLn!7a zPilj;FrJ51h+p-TR$o~f_}f!jlA3z7MmqWfjGkmR>%JLzQUksTOnF+nNrh$5ub$QF zxT|ot!p^xIZniz(d=3ZWe8fntftvpvpEXkJl)X^M`5wwls7}#RaE;X0ahb*LLE>9V z=6Z0RMNWR#NG&zHg|!4(<-4HYh*&6^=nh>;$4X?x87Z*nF6J$s$DY(A^2xyL-&~ue zV#u-~W_C04lB6RY4!ThhgV~Upl}SI%>8BNIO(2am6#HSIi7ZXX!ax}lw3bYa#eo%` zR9xT_0^IDI_S9fxxqpc_#n3smBHenec`1!b2cMx-0;^ZA) z(7N_E-GvIq(vo4LAj85^!2anF;DuZeWgfE~(2X%GZ3l*f3U#p-Vkd*m4qyL*mg>u* z2B4bYw=e)^+(1+wuXy_2r6XVDRUu}#Ikll++*Rf ztPy#6EWp?mA{8!an!A(Ms6lyL!Gi#qT@OCYr`_mVxHs4?e5t~23Y{LlIa6g<(#0=b zA}gQ|s9if)M=BHWV-KFbt*- zw&|asd)S7oKDZ_XAY!LjU0rNal2|q|p>pCg;%Kstc8{g5q?j*O@C~E2gc>La z%Dc8ZDKF5%jOkhwHvw&MOsI1w2m~zo$N7+hRYtO87;(U2=F5@@5L#RwLXEPi}fjrH4F?G zhoiMS9<^1O4}K;ZWwqRa76sb~Y9fL%oH$;HVpj;pp6$@$aUX;<=2FG{7#)Z)E+JFF zW}XWioOhgn9)4)FRx52dnUVvoF?>!96i8<#&TeQt^6bq|j@P_RdK11Pc!RXsO(dN! zZjjo7^IOMWERDB)5&8%Vg!&P7b_$8NE?OC!L?H|CDi?KVL6QLa03s;$fqSJBOc2#< z?r@k(BwQ@vA_*5t_=be9OZb|E3nY9M&_@}~mmc#ZERygQ3Fk`qvV?^a&XI7ogtH_p zkdR9_Q^FY%=1VyJv*|a9mQ0f#QzgukaEgSJC7dK-u7ndMd`ZFyp9P;Dr1{(*qOZRE z)at7*B-}6I=MwIdaIb_F67G@kGYLPHaJPh?NcgdYyCf`^aObB!tKg5M#|{a%OZcIL z+a%m7VVQ&Ahw622zk0tsK0 zaK41|BrKBf6$$4`__BnB63&ruwuG}JENChbF5yfGXGoYY;q*|Sd42A$Ael^+A$bx` zk#MqvlO)WQaH51SNjO2m90^~PaJ+=$BpfT@7zsyzI?$rGQPRUN;f39n|F07MBH?)n z&q?^Rgg;4mR>B`8{6WI+cN3XB$FH2A_3%vrm3;V#Rlqh0w@O$h;Rh0Kk??&9H%qul z!i^Gckg!z3^%Aa=@I47jK9LWh-jyC}C0rxnY6$}pz9Zq=60VYPrG#%u_@;y_BwQ}x zG6|PTSo}$>)$%2u1ZNK8=cj0?o+XHavpABnCh`V(T8r2WEUq}#Z@}-$)4b}APxy0r zT6$e*TATHun}~?!VUcEqjY64uO&)d!jd&HM7`K~8Pu0@vG)ByNSWPI}EDQ(hSj0YMq5MO{PHqbCy3oTUzwbqGB~Uhj8`HGR zcdel0w&r&{7J0kxxY^)MVC9)9R^}pYnavu$5@Z zewBvcd=~|PzEf9)MftsnyTqZ*OHi}M}fhbBV z{@!%t_t9tki|JaLuQirmoCuQSpbBe_SeRj8FO!z)n`6=SR$k-2MzmUXAKQ*)TB$xDQW+PVVUA9EoBP@nTp zSV_G&SOAd6Pb~bI(Yxn7n!E5 z<$cET1sN#j`7nGmrWR@>{By$ayfA!v7(OQqelya0;Iy&90bhdpWsh=ms>sNPt1 z0+*B%Ikd4e*jH$Dwxcy<>3Os8@a}c!His#PQFh{z5Eqw;v$U?tw!p2ka5IkgenV$# zrFi$)YL522s^kThy{sjw?Ml%hf{Mjk5>y%=2bM~aMgJ5*=vf?onq7pUXZA8`YKgr` zMOrQ1xd>NRR9QA720H~hd=R?i!sR~g!sbBKWrnq8$2Luybfnu!CBv;Juft*#~^8=7Gg!~BPl;ZW_`53U1G-D<;_mt{~)BAiD{<0HmA{KOXjPCu9_mGD1cJ*-Xe7dh<`nSRl|OSIluh zRs->w8;3B|Gz{P+K0ha)J0gD0C0G9$L11t$Jp+q=NPo3!~bMxJqCKd zuJu$y@2T?R_=JTx1>5|Q^+*oz>_Y7UCld097eN~!hvzQR+5(g=((2K>*{|u{>=%o0 z4fGyQU97G3eXBt0>-0=|-vWWEG>EMZVk?5!!XQ=@#Lfn>Q$g%l5UUJg6+x^#h%Nkf zrcV}J^sQZmf*_U`#Bzd|KZsQXvGO2R7Q{+}*y4*9*wcwpjFlX$_~rdT^{h;Q6<#7gP4zRq@*XD)@};D`M7rReNE z{H3K@L9L}VFkqBNSFZw2?J$?sFuc6OGA+~km`(7Tl0%khSGz>uTg$YW33KR{lTIGI zG2-L_1j_%qT&vSuWEhqgUKckO`QxiBDZx)vLZ_8d6fM{KsQ8N6H-K@nLHMX5-g9_s zOABO8)vDGVKQ@uFo1GI~s+_XhfNIkwMzDGNT|Fi^#~16(l4p76r*z z+r#qO3|z`6s8~~z!eq4Ku*?eGDxO6?9JC0O-J8(`Zh z3K;`Sx26|WPbC2b#6t~%8@Gz$t0c0GsE6C6oavC+N<><@5T|5mSUpQm^FbeLjbg}) z$~HD*oh>=d2b5~Ue)#`f9n#p2Su4*!XV;G^^YPnI;Qybm%(8d>D>~$VeNg@z`r+PB zv_|QYI4v3%FR0XRCQVB*Ma{x*iCmL;tM|3k-<~)2w6^Ds%)_2HGFZ%;LS%2v8}ha0 zjf{?uTAM}R@_F0wgRxnF}Q2vnujCWA%S!9nxh#L=F*&z19#d_``F`7MtxMl6lxeB!k5e zEeOsj^0kIYMyDZKDCg8y?_*ApKg4kUulFHPS+)6{ar#p$LW_8?4nJ=BU#WwTa_xQ) zQttnJKL{olF(Cg-75VS%j2+vw439s^*v9^0#%6CL?O7x9uxE`77PDq-kg<`kHEU#a znl(8>tZNiQUZ!6%Hmf4PGhzO7b=a{T6Xt)u4v-lByZS-QmH%({1C2$xq{+xdrZ~9B ztoXx=jD4PBPZyboJzZq5m@af?XYGQ>*P1ReI!%{V)*{1>Y@c<`i7ObB!ti75gsd9< z&b;|kDkvo`xw%N{G4hdov@Sd0}Nb6R6XzSdaD=rmUO zQf4DBGgq=Ut0KQMME|pOc<_=ZUVmO4paObPU)=SXR<|ylCl5+@;f%F{Fky)=LlIYi zyHE4!pK0mFZV`Y-5Dq+af%TEo{Qb|Yb274p9r@v6?;fpZH##aFlumJ16K3UUT`R64 z4{<_>gI3y^;qVlf=t6PIA)fV^tG?y0?a?~XnZ|)VTExc^Vk)%0KAgiJ!#TYBGu^5A z5}#K_T6e<=)D`8~tXY%=-7ecDz8(ivtWFLng45UI@KIMOGD0PkZAhkjNtu%3HpQ)y zuwBJILAOAa^sSj0i5=-O#0%i9X`VST4J1d8N>@Z%hPW#$v_@3ln7vwd%eUP){jEeh zy^f|T-QSwWq$8FbXW=00E%fbU+y;Nk@81hm+cV$toV~EjhfLnst36%!3}R)W!)tnL z<|C5jU|yC#4H@t*`?MF7IsDyyTJyN^?sw8_dmG^X{?tCLRkJD?*YFzoq84^8(?m7M zWo2{n+d!YswSTBBsV~GUoH$a^vxY34^w|YLkdZfWVm&Bb1GeyV;Pe+-E!8LJ1|DLp zy>YBG*$cxPxL!A1^5C8Hr@b}Y*TI+y>Lm6AL{?(fmS5zv`63^porqMFRk8H+;fP)4 zRa8A52)$a$@FRCC73Fmv4UZ_mJav&z)kQwkE1Bx;;*dX-*Y=Czm0sjyGyPE2?fpj3 zhgTec#ekoA{6SoWe9p~-Ac-Gby#GP%`q-){D3wM-TYA+&Eu+?=C{pUilLXk3Azgpc z0NumCK8WP|DP2Mw=nsZc@GU#u<&ZWSnXW&iJ?<8{;3Ex#kWrT^EuAtFWbXAwK}VD_ zf+b}Bcoj_0ff$!mY0tY?*FsikbS&E%XnR;2tSDvtl_T28`r~w(Q7oed1_L&hDRCSo zC#DA}u1?{Lk7^U#CG-(Ym(Wn=cOTGv+0d63Z~pMG1{2L8@*t+{fTA3CmO*Q}!Vb1pJc;uJcYY(CF8p|ydI@NFlwN9~W| zp$PB^yjFr~3;c8hAK?2>XjfzuSVL~9DMPtu2%f9ZEh$+-QmJAKc-yZv^Qu>&`-%=@ zdvM)^%5)=EhzR(k%z84Ig?_}n5)`z})%Xsz=uQz!WHE)m`87LXOl2CEnz1f5|TG#VG#npbJ_q! z`HCMnuXW))ege-tfyc{HwE}H_(R79Ka!@~01#kEjq5JvvU(qGI_=#U}w|tOm7qoVf zu`Xy$YVL}q*PI{|>w%Vw9pK|HXyet&Wd4eiCC_NAw|sk(e!HrC6G(CD>y#O{=?^4M zi9;Q`4TeI~9c1s2y7~e?=+g1EgFt$eewUIA1#~nZ7PDF`hESx(q*B={d|I^L76iH_ zT2GJbX}uaLJi$lB=_<%2zXHmont^62;V z-EeH0($eAR>>ve#HE=X_I662;d*Dsm;e}(7?I68@dA5U;24>j~(ioU}jGMaNl0O@- zU)^*+LPXY-X15)U(rmXKlxFiW{+Om`^O~C8w&{=IY5rwLqclft2c`K+r0Ju6pUmIY z^uFz9AD^aVJ7AcR>N*V$(F!W}CEG!HjJ6$=$Iqg!_cdKlqf8~V-4$9$!sH*WMXOpd75bCLE$3Xs7vY4DLm&<0)8x@I1aPU5v{>Xlqc z&|&BLC{It&7pr5B@*N3!D#+`2f_^nvNApB|9kcAyf*nkbbAPNVvE2JvLNbr8rQZtM zPk*hYPf*nJ$$=xa^;R*k4wO_6Wc6!uV0t}$j>_Ao>*f4FBfTxZGDC05J2lqpaes#1 zBYOMcX$m_S*p{JRqj=6#QRToB&Eg}xe8u$ ztTjhD+_L2uLoouP<(8vy99g5qIG?GqM#+xTwY44x+w#}8*7wDWwPv!1I{h6d_f1Qv zHT~$Ec>dLA@gMV6ZS{>I1)s6?`02L#w`$Shz~Od!nWF6G%i8NhqgR8T*s(x^4!Y`; z4&JPj-pR%XchXzgk>+*MpQnWNyXcdYDS@S3^uta#r+3o_DPIJB?WW%pqfFyB_SRp- zczo7dzaKX4I$f(D0I8>42io7yU%yVTfXmlMuMhA_AN{WY=lXz+ZsSd_*Bc~{_s}Xt zoFB^q^|{6QUk*HQz5bS>B1M_0zoojr*Yrqj|4>dMBljkLsu20`O@+y^)f~&-K&O z)Xi0aIydX>qU^@sa)uqCr)<8WU z4O~A^wEC-oqSc)r5v_jYk!r1u32*g+N32%gF<7+PIYdvtM60v-Jwx<;%52`@QT;KD z!0V6do$)1zgO6Ixe@uTG&ENBwXudL3_of%bfEfzeE>_5PUfR$`dE+2FKsOhkWaL*5 z75(!3P|+{DhU$&#<-r;r9;Zf$rQ7S&-3-snZ@d(ZHa4n#reaJze%CO)7bZf{Fnc~U zQ$FM8hJkX9@P~%$%@Rt)B*Pw<*f4}86EkYTaJ`&n)>Dt`U66R?<9bVgLyzl?w8eEm zAwooVQq0;<=>2KZKK+D#s|ud<(Gz-`7|DS6_ThR%-fV>4l^D;E5nx~?eBKCAk@69G zqeh?M4I4yPk~vz@Pdkd^x~H0FJKo?K9i~((_&v|)4I7@UApSyPFPcs!X$$uX z4-d3=T9F>B!anBKO|Q`*djO2*p65@ zP96&EdRF%+$~XMW=k(^v&VYNQext(GB4+|@HS#;3*H0;L^J`xKE$j)5eL>%^U`7w{ z>klb&17&_4YP$2d_M*NXl>X6+`WXr>7_0ZIL&I+tAGBH}v}{Sm5kCBxaeA@!#fB&c z|H-c(S6;nT4)t7k%;^@{R2-Wa z7d&nYzhaW!QS~3qW4UO}i3Oy2qP#K6$c!7*hI(Df$|K7J2&ZX&=>b*8$TKRzc{&pf~uXn4S(kJ`epn zhp)`julE#*A)<_qeZ}2VNvPP%jk7R*34-W+HaaEk75WweG4+uaf&Fd@)Zx@rJqeu| zJ56t_&iC+f)Aa86wB*)l`pvxcH2t9iJu8Nn zT1$jQb+rf!hhBF5DUVFZ99}$sOLjN4>WVfkpRU&x54#(Od)4Dl%>*G8@i%9J4;JxV zGxcUlQQ()Em@9n8biGdElwA(y&4^|OjLSqbGLqpx!GE5vk1@-4(fJV$tI8}S)-1J< zICHgy)G$|A2rfP?#A6m&NW59Fi?7Sq2dl`g{%SobdNc$IuZyqCWXA2{TYVsjg4i*Pl_81HAAJFz*BW zlmLMq3-zB=uh z$U7|~5E!*gpBo!D)Jj;6J?R>~M=-x37kP`SeZNL;8by)3>-8mS!54hTdcCnHUyv5P zStUXG^AEBOY;BG!A@&sGQZtAn0L z4(ksS(cE-IZ=;^6!yh}OUmwh&V(%q#K(#N<0i8lQK!AJnkeKLRQ8% zdyit7E9EEsYe}xCDp=dWSvT}$XSni=0GXmp{Pw4eKR*B;X$d5SH zLI%R(oQcyJd~@Oy<|s{3=)tSu^OMd~4)W(uKqx%G=bpfx{}o<(0<82EUU5Pn3WfLH zU+eX$sgHcE&sA4^#p6!uBa}&j7YHct1|GS?^^g*{>tFh#Ay@XdL^XEUFK6_DA=maF z^@l^Q**}N72L7V=Q54S8eVy~$+gKMhz8VD_X zVy#tP33N?hEtQ%T$r)q{hTdr57z|W#iu)5;N4`0cH6t#X$g)Gbsr+c3R*PLNWxRI0 zs21yhub{m-+nKTj*583aOY2Mk-Lfj4pPrx4$c{HSDHspm#2!|gHL*jw zHVTET4xCEDb1Jnsg%2o?uER^4vx>lu6c+DPmxa9E5A3hUzEsua!mBp#+K`p;zg)rM z0B0&6o_4<#_BHTzsu*NEDE89;yGW7=yi7hlqW1$*m@j=>i40au24 z>*Xth{`iny*bw5|WZfFELFiQ?1ALS$qZ2!$s2jujLAjFeoLVD^kLk!V0zY(N^_=Ra zu;9R%Zfu{bZkDxK)`QiSi(V8uh)jRNxCC`jMGsb9-%kRK%4%j%??qd^M>izqC=tNB ztk$#m>7HzJ+_)HL4Ln#;p6931Vx|ZBU&CS)wba8$HH)bo@bzYKO7uc(M{wRW`C6ta z^|z;Zuq`AWTN&%Yc^P3}#d;tP6ZR#4_d1sD+UoJd^4fh^eSYCOR<}N!GQ7;=iMC>X z;PFIR*cRTo57NAkAU>1Q`1&9XoHBf~$3x;Ta^Do>`5XDWNK=19FbI{A%K<7QmxC{H zlEBitAd(D1BpHNAa;5k(7KSWfKgslo57LC}q=~aXe(m+_6{S3I{Cc)kiOTWdvwM8+ zjqG~$%pSh)CWg-kh~qyWUwtEPdX~|r;vl0$20q7qeOZCBoG15V*^oGT^<#I}7%QV% z>7V1*+{~_wJ_!?F>?=P0W;T)+^}`HRZ(;p#pnU5s?AEj;d$3?R9PJ?z`>&G-}fAtb5aQpUHaAsqA-fh+9GICtiyNc9MzxXkdpndCZcXy!`L%IrUs3 zzo9>C&|$+)vWSB_rQ`G#30yf{K@KpW(h=7IWLSPf6b&n31t2qIO?>+tf1^M1*4Qc% zcST~pt3R8p?%Bx)3}A`sH#_-12C%mG{F|9WZnv`E7DHEJz|lnU<%-zhFyq+C(basZ zoT@8IjJ}V(qW+Y~-?)!8_0Z$HwxDOTV5f%{>9Ee5az9IQhP!I;zu(W?J^q>Eu0;{g ze1sRCK*Umn(-3!>5U0T;VUi5(Z*2Ywi;@aHS=u9t0tCKzfPJp0TYK?c53!MI!A^eD!|VyV+uZyxYnJvFwpIA#GKzuSvGkf$ zdQJ?OF{uP__drG_OtS{EHc>0w=9&$Bz(Cf}SERvIwz+YGhZRDrft{v%E!;v@I8CKj zCx_os7&N^j0*mF`S?pbGQCq&wd zP`aj(v_L6)QVHE0g)Z|8k+d+ph(Z+6(>y3rt;8p;P_}tgxPG);YB%#6sxU$6I3xy>d(a!z2m(FpSheU!eWsOb=*XmI6tw`=P&k64m+uPyrn&drk6BSk( z@-DlYybFc*=8(6D?K77M|J@;fzsUR@;aySP`vZ7`Mc_6J+8lOccZ;}XsO?XJBZD5$ zulrRu8&AyIJR3DAJ)WknJ^1EvEBEL@KC4F@eK%c$N+Rz5=s|2;EpyUlYD7sidaQ5v zYq~o|*6dAg?n=EGgO_Ek^n~5#8!gm))V~;iVh5@zfWDU0&OPh+#pSd9M-P3#^Kvlw4rH zBr+d}%=~Cer~$i0ywkG7DuwF|Tua3wlL%F#)57nR6$8x3ydXSIUffNBgw31}g1Hk7 zP!>}@poaQm26adK{U$28il!MYGoXyOVe-r3Yx6|BN|Cd_EA@()jf;hMmGFMH2fXF1 z6W+&!cNt|`)|1G7t?*tYhh&{_EwpsH%E*wvdRyh|dz=?q!;gXXDy)*EE1_5$I(nZG!c-HiK^eM8xBt+dP| z#1*pmwWbW`{mfLp=W~X!PO(_*V`)zCFNU#MQDk}T2mah}RtMMXGlsMIP!8z$IQvLZ ze@x`DBiKmanNwjOl_v-Lm_9OLo&*YGAEmit{r;!t`z3Ylb&Kt+E!3vEXrc+*yL#Q2;w?$ zE-6N{l)SsK(YQm)Qv0VH=s~RV!=Ga9J0AUrYFyw-v$MtoG!K3~;`9QFVqzWKd*hP*g30c_ITCy16KW5#bs1&a*Sf3uX|} zo|;{$J_6m&qu0H4Cws=^0&i^u>5 zt1oJgUkS^h9SoRA3b8T}2eIy9Xvq%@x%m!D|&FjOW{)Wy5d;*7-ShCBT!{Fo;KKr?v}^-bU>kvu3gogr*==s!ZnehzLX=)^l}9WPlcp%vJS4pL zTi*0hW=B`@J|Vo1g~#^6-))|<^E)qMYz~h>EOp!tYI|9A@5#b@do^#jIcrC#vyb9y zHJVu@VitfXAWfh?{;tR`M;(;GmyN{9-9El`B+CLgV}bh5vn~nwFG69`xsqz%IX}bj zCb50|vFBN8%Y5YNHN17$KBqS&-&+@W;`DrP;xt13PT!vP)-dzmKx)HV3yD@g&pOpx zh8nmiFX|<~U@b1_*xIDSUSRFpS%iZjj-b5vkW#f%T1-g|O9`gbwnLsxb)cb$#M_WK z%1&$*8&xfFn%_aNaGcv~O4_tq^m__S0=vdE#049MbXuV(H=2?zv>{}E+tH}t_Bg@Asaz30*w7sI6tU$NH5$%2% zX`}75R=cCC)%}WAGHENj>K2PzjHI+6g;AKhTGAA+OzO3hhFZOEG`lxOwwiYx!)mo5 z5;oU}X2Pu1kI^_zFxSEP8)STH42ZGZrYG=)h{k=0#J@qwNNmr6(rPI`L(1PEV=7i# zVHXSb$A02-#ph@F~PFS2c zVS#M&QxuL^VC@S>EZ!LWA9`3#>@!jAG|Ln+ zwX*^?*GEuOVCje4`+0+xSa(l;D)O>6mKFSQ_+-%84|@|oDGrLxu)zpvDC3CprP^GX z$m-A$%(pMG%=V!`Y{WY`&MR(rZIKeYI+L_^Vy?w`NF$v3TpyMpzj7iQ675gL@oza_ zGLfZGep@H9r*%6&yaK_+^Az4UmnGNQ0i$TB3#yLYBAKd+qI09?5d`J(nYrxxv`q*= z4Dt9yVIL)vE&{m1G3+9~9MV=T6>Y$SH5xLK! z6Y_1`hsdH^3#E_f%~I53q3|f0v~I!5Bf03_5#VFG zAB-K&I~?Zhl}FA%wR{!f(EME>!~CRw@zSy>=Y$G=6z?{TW%;&8(?=1a*heBV_AlTJ zq$iaFNPRIDkg87qPHjNt&Lbjq))`9Rhe5{=3?9w*do$l^AcXp8p7;Z+h%NN^^>p}?4G zNX7)k3?gb`OrU?_OT(tKqPqEUDPS++`GI76h=idghPQ!d=d+2pCtZ`z>eoHL9;dS1 zP?Oz+5c!{74us^kW9zwhCac?{z(rJw1#bazphNh-LkO;zc^E7Xv3}vKmT_0|tG+ivD=N0+zy43Rqor<9dE&0qde}UeEtg!1@#1 zTfl}YXZW?VSl7gy4H%ogUe!EP3WPrJj;<}7#TulEexwjF1Xc*5;C_QaOLP`X!`;o< zS?q?orRzOdGneDon%-1o;G*Ih@wr~`cy^fIH=8wyLKJqMPoB-5z53#81$m^2l12Xb z%+xie?|NEsGSx1Er$#Z+N#bOC0l#hzd&&tLYy4DmPd$EM4(pl<7wBM_6G~~g6~*~9 zOkQG0@nj+;(76ztJ}_@CdsRV|hZeDvSU~{DncqH_^@(Xr9e&md$`(QHTPbxUL98Gu z?ueL$gvcZ}&0}@tK;Qyq0so?ir6yc1ViS=!-P91>yL(X{m(4XRA~N+t_uq`)IU>IM zNE5~NJmtT_W2zV&Gxu$esRNg>UnI^I3ggz+*-ug18JcXJAl;i!KDs zF$jx87|f*Esg@$Y7|J+U!r66p30bO(1)QO{ImpZ-%Fco)6&^Bowa0W*E)$mfJm&nj zu!F#tXEGeAxYz(6N~NI5%Psmct57x(S}5bUQ3*yq!AgW>7|ah}kqpl-*o3+7T7{=W zj=`K+T+BTD*;iTo^=NGraupY><|epe$tBkI?Ge5730%|(;@b35y;N4hKY5j9`<9?@ zL?(3OYp#MTo|2IaWp0E^bhWrF*lNe5+gC_bsa{+^0;GvozjNNQ=Q|cPq$OVdGW>|l z=<3ROu^%3@NzbBC;?OXjN0~$)R++7=GMigvX8yk|GrUNA#KEdusLToP*@I6l>tdDJ z(JHgupHXIbk?pKGI3uFW>#Z_-TV?h@ne^u}3>fU>-V(+wyy_Jg1Qv3edWiCURT5w2*SY-~h%6z~ov;Uu6=6fhJM7krb zGM~1}9AT9?>=I@A{!jY0O!h5xqF;%aNuP!Vjg1UCD0_!e<@h4QP9uzXtu-0)6{{I} ziq(!>1q~tU__ycaWog7G)`xQ_Hq?1Vve-gdY{8#jtSI%DwI0(KYHhJBcA+eG!GEaO z@nD_7Qt=i+7Q0FoyW&4o>^E30LKAVbEY(*ki!J#N6`L2{TA0MPC~CVbwd|q)P_eU7 ztXP~UU;&^179X&L)%IO}E#HE*oR*}}TK+AFgGiEQNk!x&A-bUfq@ewgK`&xex0klc z$e@?jUTJY9N>&vamWO1tCR5O{$RHsn@Oj0o*4-x+&E>!c-o)bk9)|Nzk`orc%jXue z#w3INNjY9h5c-#L8A)gj8ebcY$0w+=V0=A-jg`y(42{dBvYxG8ChNUOPEhJMR-{l0D z%Q8>F#oj=%Htpm^*63|nBWg!}WKg(7UVtwIMwyc@o*us;{O-hrp*av5m|xa}Tw7uNEVWW%yi9aZyzjZm{xfG?XjEw9HHKbf-O?|yewBt8=Z|_C>m+!F`v3Dt} zBfDWVI@YGtlE@(6420QSsx&gJ2tkG<@Xe7y`6w*70^wsTk|#?_E&E+c4HBxay7*1y zkl!UG?YB@P+HX-8K@UEB?yN&lEg4i18MGTgi85$^WYF=Z2ul!Q*^Wvm?Sv6lwbA1% z-u%r4;J`&AvKXCY_g__Hxg}wPbu2PyD}s__ZBIr9&0URMrrd7^sqa)IL51k)05Y;f zBHAC)AMH+0tD4iHDuUWS2fq&OnNK3V*yL5C{ctL@b|RrNj-$~;bfHOX3kfttXCkZr zGm5kM%-P7G9F%Pj?D@!`2vW;XbDfeaIweqL0pRNLJD zfUdcpnrrRP?f%bqYATjs+5ty)|3UN)4cBG&!(-pE$SKsVFw91HhXTsv0 zbaA7UwMN8sr7VlLTFYFi=Obe0MTK(B;jEOkiHKZ)OI~~Un&R3l6nO#94d&eX%4&mU zPad00o$PQd1aCZxk1;=8)ezYo(xq+=z;=}yDTopLBv6|mMR|OVsW*<^K zdMBZ@0{Q#j4*0jQlS=&CmLFXTjD0)sOd0%YT{OK^I#Yjk8>{Q1qiIYYRUCYWiR;_t zgbmI)b0N+(XvGg_7^|W(oYwiRQ=A6}CD65qOj22RETshwc@^br}%*-26;b1i!10LtyR)Qny+~PKGMti>&s~h;0dz*^UyC zW3WY&K#;^Qan%(%;c-tveF z?{60SGK#e~srk_n9kC2Sa(AQ_h@jtCfA@l*NdyTI^bz>@?5#s#WY#|+%+9(fGHAk^ zAxUpRWDrMCGRmNFSQr_!0ztHm51$al(HXu=PoEDEyZT&P8hx3$wil5}Xt4%nwH%mL za$r{c=D_&m)xaMo+8{lAgJNw8g+5LAeq{_O)E4tgMbO0qW08D3-AjnY+^gY6GIb~G z4R!1XcCt))RR?oh#Jxy)1T5>7o$^jk5m$A5%TAVFgTgx^9KyuuoveY^cFTk+8$;F# z=nlW3l}o#F)~-#-dJnFX>2qkf^jYr_#yxSXZWc=%-&;2qNSq{`!u5gK<*c?EH^FHc zJj~-&ndB6`yd_M3w^eh&_8jR-!-xbfmWg9&KOJ+-X zpO!|Qz^%L4WQAY&l-;Hr3EcJ>d*2zeADWHk*YkM#KGw`~jF}&}Wgn|jEZ3Cz{4e{N z*K*96A9!#-o1nH5sot1R6y(uR2(*`~dEr^y<00Qby{{Oa!EX=bRx;fMSXjlX;*|M; zQU7G)NRub#G#-(?8fbi)>9S7cuLioDVar^~M}e=;vhk`_gYtR&>2s`!<=8(j@cKD+ zdo=R-MKQ*y8S_2DMr*X`dt!Kou$%)uE^i#35)-N8W9P317PyRu?Yv$M)QmC8RlM{* z6lZjFBAc{$<3p;>G2OTV-u0OA06E9hG%``U;+n>@h{X}BVW3ZK<1GsNHQ8v9C>p=q z>W?J6IRMLc1P=Vl9#QzZSR*>HJjH0BAj3~mjdQZ}<@5Qc^^CUgjH_>y1w8{5>Bb9g ze(+P4qBeH$+p>)_Fobkn3*%{}oNsDj+?*iFs+>!GA2b;{prtXhy%n%X3<@@js_7kW zkHD#*uglbjo3Xv{5<*13uqcq-%9yVzi+On)BL(2=Hbx@=qpi^?ai@!(#F}g8dEDs^ zsNTgQ5&wHz;|}%)jHsxrB)Vt3%j+?rl(VI+k%L?UH?=pqx~$>(aB*NpCu5r=q@|1b zLtTtE36v*H3d`I;d~4_NC0&d@kO+V5Vx%j@fjUVO=x7nICkYJu3l|?o$0TE#~Uzc8f%UMmM5^$z;X!_Cbbcyup_)ycO&!0KM)%o zN*29v>wlBz4!1QTn?(6AQ&vp3@gSvGRv4Jr-S|{V9aF;`Tf-bz11i>PuT=ahy;9RP zXfK%K`Exyuy2`k~te!^WSY;b<2#YAKBX%{x^Bl3l6b3Q3Gq(pO5ykQHxg?>p%MI) z^j!~2%maJ66Z;$2t3`A9-u}imb@N>Q+5lrV9`bj)&&W!}bG|6{9<0++Q9?Zo59-Bh z5<49Qy3Z=BXLUl*jzr|Na zp@l}d2xG)2?=$MFuqON9{l+uK))-4c&BgMgvEs54{;&Iue{?1d(ytYCChU^Y4_-af zJt>F^K>Ec7{XnA9kF?k3JzykUWk<)7EQ1n*(P8jO`XvYbgmS1TDh*kj4$lIsy^P*4 z7`w`w;dJB)ZNk?rJ_pp_)X^S6oVgcd! zZ1s|t`KkwvJMB1=h5yBIvK}(7j9m$3W^~=heDFiY6>3!hpZ}22Uj43s?<07jfY*E& zaONz2-NQx)-`rWy^d|Gb>oL||rKJKT!{Kau966v%gr{^^VN7*+Cr1tqVE$Z7=E($} zJ6Fg&PA~AW5>Ezx{$2qX@u*$po=FzV)Rlc&f)zZF*-MxGbfmQ zIibPi8-p&s?hzxc#@>*->Jg)z@1HWE>2TxJ)kXA(PePmiLa0NM89kW1#(hKn!xIxeMFz0OKaFR4kfSF!u0uLMJ7l)o|9xEi)SP7F3K zIMu4j{Oh5{bIQ8F!^4chN~~Z>XJ&eM|MhVVorK`&e;wZ9aU(8yX^i#GzkH@(o#0F) z0jn;)Yq(JhAKiv9=ds@Nm(S$)K5n#74h1GXZak%`#WVQ}PZ{lb=O>M%a7PVrB6kmA zPT549q9=_mab~!)BX9GR(Y;<`_%sw#u!h4ejDO)#l*qfgYQgqlIl?DAN6XnUF!~=x zZx`S99G0YQfwRvUilTfF_<1C1#&>Kobl&ZzxI0oSjth$dMhrgHt%t1%Y->zlw9oia z$y{Jf{``Dv@)L6>qwHR1b4P;d=$%SzKrxT!^Le9;HF4X;dj)iV;QrA@2RcXXKh8+R z8`2eHj0Y9vQ(k+Vac$6-KRM2LEa?~wLODQ7F0u|E>y5MM{22dv9CA3u+l)8<(qNZ| z#1&bWrJ^okMMTQ*3M2$xA8!m$m7_d%f-w;we}b_cV8BbpHO(hYr$gu!PSBatY|b{h zG8CdY9LNsNsA0zRCftk}j1L1$pU!u`WIU<-%CDPfysdmVGuLPW6Tz9e#%iVYE)S$J zS(8t!UJ(U6T!PB*&8kvVpl$_H`ZKi$Z=*tcUoB-EY!&3t23a*m*0EOKN^@}oGm+nEuK zPLAd+3XD2@<_yF4+ff3&W*X&+RvgMkGk5Za1xCBLU<>$w0;8^KjeP>2USRaqav?c* zvAE(p;||pGbb;|KY={k+W&8u6YL+n^;P%p(}u z@SvG%e#mz%FdERR|HA@fmvWAmy=F{|J_m`4O$yxgI&Caa@Is@P1{Q$6MR(zQ%;t7p za}jEq8yLIDctt_7hD(fT0D&c__)?x#Y#c%+uzN5mkg(Lyl$vsd+%iL~ilMRWwaf?v zqLv$ZPJH=$=3B<+YFR4Jd(D;1C$2Q=B!tgC7!Ugb=70jrR~mJlcnP@U9iu0V!6gKY z3{XS+fRXJ~zTgk6HEyo^B_^4ON4}7xL@JE3q-CAlq<5a%n zA8j%oR4a}LuGoyl74p-NEyj~khjBC!%kP;}GnxOo#mEBB!>nV2(012|L6*Wk-hr7P z1iF1-M5!?9-fOGTS2@f1R?LJlzJ9CmS9qpwGkR4^8tnQH_%qv#Sxywh|FPYu%iDZt zv`?a9ND;tvj=&25pv7uBO5wf_jjxg4;O$1=+Gk@k;@BEcD~P~72p{Z#dbL@`cWpNY zB1)$n#x($=cNpye0z1%2Tlp{KdXKmH$Y@*Z2dpSiQX7=vu|BNrhG4rV@a#v%{i?D& z@MXENUr`PR-u>9P9VSYT^Mu_XrRBW)ZsQ3Uj126?x4XaEZB#1TcjSZoICRpK0Xd7x{hQ9}8hKVURe@Zoh3{aTIJKVd znPA5}WaZPr&Zm-v@y|g-yx(CXOZkqEJZx}fB~LtJqzAelp_U)wX~(dcJ;9CR#uk8z z;_qw#0IHm0cGrv}_7joV;MGce#AV*nY|-1JXls`6dnwtpE* z6y=?Oa@sgTJsCLutzjtt4{2`#9Yyi{f$z-bULc#9*$t3`O}N6HY&I7lFro-5hX;y+ z0s_h)zyEvx z@S3UauCA`GuCA``>FrUMVafNUu1AtjV*n{9#OQxgI*^<<{gd*$@?oU>Ov*@=;`RPb zsb@>$d0QIC7+`5&_Nyd~&#%R?r2%&v(h&cmk>CEC;#SaiThFI_ARl>=#r18q`Ot&k+G_o(IS1}ORVZJ^8<9RSS|>%v6iyR2W|As{@y(6quGoNhKUS-S zW#Q&n?J4@!!Yv8f_t}wPBdtw*%^kSc&e7*frdxV3eTJM2UI}V?$g(a=r%@*TI>GQx zjx{$juKA-(#cf})<_=lhZK8PZS236T8`K_BmWtl_T61M-WPZMus3=p#8zJo&?kJyG zp#2SFI<#2xi_=jtPiyt+b1{3vx_r zZIL=YU7YHJ7PV}n`AE_3Xrn!kn~@H-(XwGb6HV=vYR7PKIkpW+k|FO0Vuh*wrOXs> zU9Y9%TF3R*YXdM^bK7d~;f4(AZKBfd2Ccp_J2K=3?WtJh&&bgZT3_5fcDt4=?z=_1 zn=n?~qP1536r=CZnuuMuBIDCLw0p&rTeX_%p9v!KsgyL)=}yfbL0*EQtQ7k?YTa;S zZHrFY<1wpa)OcL-oKgd~gqvNp#$xqn@i!=QBX@V!yeb9}s%sRPd7IWwQO=4#ztmDi zht7$ek}9-NEbXMFD%-`{TQr~OeFxMHBkvBaTs=`y^r{4R?Z| z-Rtky4kU~8Y}h3DhV9^`0r%scT2)1PLwwy!yDbhzY3I>7k<{K=yrLWvwI0wGVxMX4 z16mm#o%=uxe~86>Fg8%IZeJ}yt#Z=35H8;PXBF{&f9;XT+Yf4PRXHi%>#vO#vj?EN zUlPv`)Rse#?FVVS)%o1(HN}^Mv=riM=OFaPyQ2DFZINSm|kCao9X^&~2tI7&-`;!`81s{n#{iODZ(r6pDi1Ce_op|u#m#$Hvh;@w$W%DWz ziIG14)7q-2J+k;2&9ADPriwMCT2T2*{9URoK@AH=YfF_{RD|4T>@P)2dsZq+44uh9 znPJar8mo0si05?CV!YNodDB#0BgNtuSZ2Wcml!)Z6QQkv>IB zR6kD_W?QXHENK(#RWDW%tJ}o(&2g%#1|tiHR`DLGLK`yprIN>*ytbu_T4S~9F?fC9 z5<|+gmZ=vKDpn6m{_xO}!DTL*N;WndLu!AS)(9KV-l6@m|UTWgO|q1p?y;ZY|3byQ)?%O}<@)Y^jQ zrmsQ?vKDDI0k>QP)(?nLi?o$iPO3F&%{W!TrJF>Kc_|bRuh3Mo5=AQ%w=v)N4@{rf z_bLqAr;+ooYI)?mHhx2^PwsrzH?-!qAYT73E;F)Jx-P)#rvF4qr#mK-X!p>AAL9q; z_ITAZx|Z968#t?q#5c9|>dsSdk7&{Y zxZh%NLRLC$teWMV*w*E0)5iN{Y@E@Sk0amfFI(U;-W2hd}h zDLJtL+-;J;J1bPfHsmX~e64gjdamtzS}4yK&@Ddv3=!5|CU}uT zi_EGnhhLa5t*=0RLnWJ=?>N7W?=BSOaktsKzh@;3QkJ!Fco7`X>A<}*wp=8AphuA|?qw?HN z`8jI2Dt0f`>WT6Xw4T|=t|~(%N@Jo$CS3N2ybrZ;$@4Bt+8$K+0TRFbP-|N4D^BFT z+=(=0nU>~04xrXDtu*~Yv;=ykz`^g-D<1L5GHqP?f-4qHTL6+(v1=#O75nu@@p|R%zG` z`d9Q=tu@55e!^;y`B!XQt&O$^^@cy$ZqQ~kmZPv6eLmCL*nAx3OmrI3mwyHuy-74! zqh%@|i1uq>c{hqdYqT|37dBoC=i=SSxV3QUY%}w=G^|Y6Hb}at{sm^n3*yT!wBPXg zk=NH@68~HLvQ8U}yMk~2QhQbUUBloJ_FS)xgiEn)J?!K^;-;@)HvbWyeWi`4`!jtl z5TfUWTsFU7vuBCp6=ox_K})sU@wX$r!v?KRwuS$iY#*6ixjdwky#ab0Xw%I-?}*PgX!9z~c#9p?V8%-mQ@?>Lc2>;!Mq8z+S6bZ)?%gUzy?790S)#e(T0CSO~y7cXDjw0(fB7XVcTdYu#Q z;cF+{!cE%$MDS~EgZN;RHWruT7JaLA#$M2bZ?!s#a#1Y#PMd}9FgI(%)Fo5JhnuyV zYvA)88zVQc_u|wciJe*H5o0x^C6l z#?C}yoY>P^ZxC6(Rl|byr7Qx7UY$Bx zbRGnjOLk(4Iyy!uyR?bwjxl2LF0DotrVf3HH9vV)lp`m0*=QWk5o>SMePVh)JxTQV zN$aVue^z|@lhy=VI)D76Js5MYN>+@xWw2f^^3>08cw^rs&R7rvf-vU%qFu%Y%avcW zY!zJ8{#Bb5yBsL6QG2nb`Tkd}p-OBiH|W`sz+UYYMV(g~S-Vfe$1H3Cf0?K^6TS9p zEmbh~@_y|Rb@Q_#<$yLU>8EGu)Da6g^B4^2hqvqX#m)m-jheHj@nHfFy-tfW)qz=Y zba!>EdH7l3IjFTu`Wq#AOE*SzKB09Lub*wmeNP7zco_<)XrM@{dHedbwS&?}Z zQd>Vp%s7fTq?mU}yC0vV)M9ItE0y@(3=v4>W4X*ZrWxu_&kFxBZAfN?Ojkw=K^w8- zI?zPlzEZ4biZ#cyfzkf#bX@DBcs@X5;?PNul$dcut0}hssST;bgm~+OmTYxuPf_Ef zrjf2Ny<1K?=Pk5>b<>M zoVa)vp6^FvMW1upC}IF|=_SI~>s4Z6%r#?W^zDDOYU;+Zq;dV@@vRaPx*VAjM%f>CgNuQvo<)x7=ir&0JB2C@;AY$r8w>~U(%{ZK`rg7{S z&otB%MY9-vK(xUtWAtc)BR9nAknhUU$j@>5dNt`KjBXx8Ni>A8uujx_tLw&zoFx6N zB>1H`?~ef+BLYqI+o7pVJzxp`X=jh#9np6@dd*n4sb;cxr6cUlZytRpk~>$?bL#&) zfet;A^<=|{JKM-GR`nT43?L=fsj)-1G4PJwy3Q?5(H!3hP?EXer}PyQ?ed zLp_N^C%?#^{`H&~7PwkOcdL8Gi^ME_n0jD>cq&Vu7Yn~1eZ(WBSvHT9SF-h-oCWBf z6k@*8NNF7HT&{u^3MaDld(iR@we^e|AE1!$8re0GvYRUdWKBi}mzC_#Dg;3mm5^E5=7=N9pzDgqwvIFzvU!BjZ7RC7hecW4P;aLG`>Z(8P;afiHbvw%f@Lh9B5rG> z2Pi(Gk^ZXs=@e1DvECbf_GDu{Q{6B{r0440)15M>?*XzSg6mmg%G-16x)NqQjx-6)K*sx}Ws2Tb*7d2TGSK`jFxwCb_X6MyBeSdTcdNYX0%61$J^Yv+p z`g5sRGeWOEXSiN7@^47jcxJ0wsF%f-qV~87r&N4hsGn3POqtVOuOZU>kp1o=y^A`1 z3KmZXg#-<==1QMh0@63=FtCG?o2uQo^A;L_=c94BezZ#@3+)P#qPpz ziW9$_)4J2tUrl-rwp;VR`}9WQv$n8CC$7`;qx9RgqN()z(#S8Z_3Q14xlG+NS(Kal z5cTL}5x8C-9(x+3V@1b*wLwYe3FHwZeTE?ipr?b|>IoL_9jKNzG@Zf2{sf<@DUGbY zQE#bO^E-xOEs=Q>LShQ19M2pV)NcGGV zv9z;3T)i|!)a{~Ag`zL(qSsM>ohW{i(E+#V_0A`OLjfgElOxAL%bSgG>t8glM+@s$pGh0e?vGyLepy%(= zpHffYD8Y?-F!I*Ddcw6@^<#Gk{77k}O%FZ2!o`IKRp`Ixel%V^Q!3u+sXwh=ETvT* zjRPZcS1*i%YZP@#Zxn`_{o7mbp~Swz&HMF7t*7{?kFKk)mx=HC=p&MrAe}9xDo%{V z670#ox>x_2j?8KUMuy*6n>>w%~ZYS4?G z=>O4p*5TEroU?EMfv+FMiA>xyD*ZvMsvUea5>*Guu>j_ps>E{mVcj0xbtBD&=*wBa z2Z!p@X-x83dEPL6LlSEQ)nn}lOn5}^slGd!x~*}<7_O(Wn&*ws%hVlZWQE8XY(Em3 z`b(L3WF(u`O(S6`Vc!pp)NfJ`m5JO@Xvp7X;x;_9{IRFUu)VMY2p2KNIjjDDOobl2nhZ`Z8mcR!)` zjNJ%TPoUA-ATr=dJ!<3*ik^?@Y*>CfuXO^HbJu{u6; z_oy%H#_VIcF9#tmjjqxa%py%L2d=E^}V`G)|k^WQk zkdiW{Dy{HwqaSv!`9?pXPu06%SFZ0=y%8SMr|KJ(F`~ybeT?Y6LhDxLisLn0WcM_E zNQ`T$SxE`kcA2?@vg7Kw)Hdd4N8p*@N4({@S=N3zu;U2t&f)gnqc}RH zzli;(j@!aFXE<>=27);|p!8#8Jw7J4=W`kv6wdatVGW3l`NxD|LIvf~B4QNvX@&YXjLHgV90 zuG_@H_&@+ZTQP~R03B*RgKd-?H7DCG9+`tKZao*evPiU>tKXgS6{Ij3Hw@GMFb>FJ zr}4eH`s0Pxj^ukst?gL6!~aae@pK4bi-fBYe1Kv6h7fY>F;DN3B4Vo`-Kqo|vas$D6-|7xm>e@HI)ti<+sDhTRug892;CZ)hASCn|SWR-|CQ{&6g* zo?OUO6Bp?tluP32MVO$zTBLWjKAxves4C35_%Vp})wcdQkkb9P5W6 zZ(wQgS9;{i8~SWFUX#v#TOX*XvyViSCHf_dlk^qu>ATgOFAsaniwJ+a%!NmI!!!oJ zP_R=^xXeq)#5QUqW~u(GqMl0^`#;ccRm%^FrA9(yasP*UoLXu{p8pWz9XaoQsP~Os zaL9w(DqAeq@5iCEdCT>-V&yXU&cOZe?5fpxM-;wobC)Y1ZfmU6j@y0EW9~f&uTpuc zu7qKM($JktaWb90Nyo3bT=tvNJd~2oNQNga@*^l75l!@ja z>-DRZk%P%4J&P4Z4C`Rrh~s-*PFAfhzUyEZ!v7UE?GkP_s)VOk^?Z+W+WSx7ZSv5hh>P#XP&Nak9lXHhEMv}w+F zlvw~cOof(FB2JQ8*;b+QXrYykLaP8%nJtt?zfUqb*DABgF5{u~y!Uw={O4<9Jra!) z@H;Q&Lc(6jsGYI@gveT@H%eOa-fVu;J~~N+S79AKc$J=zRQ^sh@tIXn)t6W4h3e@; zV*4sgH>VFpuB_4@RC3ns_n6Q9?lE7FF%JWTT9LBZsc*!XWe23Pm95qfsp2d#;fY0GomWjGw==IX=?3ppR4JMkJS`y2fsyquZzjsBB+R&1HLv;nix zvm5n>Szqn*?Kobhz0&T70(=3x~@oB4ZO=o`a(2COy;l z63(^KJ6l*;LQa51HD4CbZ_@Agj63M@UZAdlJT7d~w_un=HhqV-iL5R9DwtGnq1d}c zPYpwmKR}SUwpXFf@eaz4Md!p)Q|Z*J8)xC^KYaJEnc^j=Dt*ol)zP)b_>bNmlk@o*pf?bbDVFUAOBU zW6v`9=61}Klf}kedWJU+M^avNdj`pq?NjE7t^4%GqU9kyU*!I-$9Ntfeibt`&^t*S z{ax>@u6j`{-=TL&+ddCe>DVq_Aw?ncH%b+Oov7*WA^L zl%-gl_*risX}en=;r4{C4~)-(a^<-S#M!Sv7PO4g9>lYcT|xr}!+M&r zat=)k;F(@J((qS2--w1s^eoZ!h~84&?-G|&V^hW3N8lT77n_e@arcEdc0|7kUpL0D z=-3~m6Zl(Zind3w1iGk*{zqZy&naTTQGFA|hy0-r!nenN`a?gBLAm*uUYs@`KWH{_ z^*H)gUTRIFJAl0ys8jZFEIH>#x*ylK;a9UF_axlRZ$#&l`mNOtW)Pd{I12^)dtAJA zQeP&XKBZ@=pUo5tPGNa_D01+WK2fRm#%#B_)NP)a4K>D3+5Y#p-Z90QhT4$))8BB` z7YOfZy}P*Y6jp~P62-vN@XEWChz@7gMak_N(TKXjy^FD z`xY3K&67_6mYojdL#*$g*Zu1E8KT!AwLly{tj7!Y1+2U#h*}p=#l%E0?}FZ`>x+NU zF=skL19QBnD%~u0dIom|+d|ADxDz{|@(97_(+Nr_Qg4uuw@AHJLe-1ZJ0%n-QhSK& zF2cE*Ag;Th-!Dop>S?(X6FpVfDm8JXdj;K+thS+_gcs6`PbSv|`J--342pMbqDS0% z2}_oj#HdSp1Du6^<&r*J9KDD|aLQ%9IJtZpbI2Atw@?+`F6-I#U(A3lce%2lLgcj+ zf*qxW62ijJ^2J~_7ff?U-np#rRFrkg#~Onb`xy4A_{a&xc$Lm=FQu zo+@rhG=|)WSHl1QNku?vvQp(t2D_Z}S%V(pe43Fheor!*sb9s5sy`&w5KTPBefV|K zWRLNk3P0rDYDN?Iq7$nbF>Wz0#TcXhlM%_(j1LuML*#qiXh=V&xa2n;t+5_m<~G-; z^pkt)DCi8vjCZa#@=U7X1Fguc8b*C3EG5CW2UxjQ9I6E~V~4X{K)*9PFy1}nWf zU@4d)H(B75FC0Jnjkq*&3&FCtAY-V)DA&24V z#$>m8DMMVTWelc?cW`7-z-X&_|Dj!RnC&Xr&>-*SjL7P2BS%qQ5HA)cI;gfRmaE?r|KGkme$d`H>T1d7f`~Q?aCB}Ra&P_ zEo0d2{S4nVldubLw#!_K!}0i?i7tB8Ge)Urf-E zhGe8T@?vA7xjT|lY{2nKPbV>pM!Cj`%yqJ8EV)Tu9HZ`8~9G(gVz}_6UBxfXU&`E7)Qm1>x}2bK@;vfx*|)CLTd zi9>CSrqF)BX=J-0jFKCS{y6nw3{5PsPsxY{Hy8`x9-B8B<2~p2Te#3;?>X`PjmC9Y z0eagR_6iX6o@!@g>Sz)?oCNtpGWs2^_Z6|Eol&dG3HuGC_k4!f(atDC`F=MUA@O#5 zXz)34f18B5;#_-UL}czwMv5W^buezmNLbOqFjXklxm%1+@b!>ow;I#&xUr+Lw94Ul zPZG5Z2IH_e+tIjAZSN9hCnFetG9K&7WAS1}CnLSletgm-;Kq9@90Q`aRjua~t9vL- z#YaqUZDl>~$2ZY-i=CZ}dVYMbhfM@cE!ZM~s=88|y2PbU#_i!LxL%PaE&A>~%~~#V zkB2@i0VOyV1M839h5`Q~wpA!^KYpC#GD|%J%{?yqjS`0b;Ynn8iG0*afh#v)p3dcbuo&RUn9%97{A4a zQ$VXiRNj+`9&GDbOBMyfQLev&zvLn}t)WgQ(zi>X5HwrkTRoLBaY4#|CDZqkENl!p z*i4u@i#~)u=Wat&{uKJ%M$;;wP8(#5Ejr$96r@lJ?PkdGSb~e0cN>Elk$%8W$->jk z$cF7|iU(HdvN7IunWA$yBV9b!&FBGD+t$svMVTT3_ZY3hJ2E}5`P|-c{4P))49*SH5CwW;3Ss09mH+}(H!v!2-3!>FwY5qF=FS#5kZhz^REorneK z4iUW1sEZBJZuc2Y)AnTI_p@>4EOnrFCbSzJn1CxP=;L_%BMa{{nk&j&vHN~ZBy&Zb zp8Ocx(|ET#f2(U#m4N|XN@9y}H-9JI+>In&?ZS1z7sK$=Y;zluuns1H0(nanl@3lN zjLc5pBUJCwBEyf}IwV6ea@0LyWG|z!vPUfJg$6t>*7q{%D7oT~UPh);ERuQ~_tYGX z%WI;l=KVbrUhcb4r3UU7#M8ZvboAl8-o|L``xsBCClztH zk8!73T1~X-Yoz;Dq}-6te}A`L^eT>qv;oWW#n8U!=OyBkzQ!=H(zqY&`C`$#pOF?I zO(HK7ADE+WOa&70b!J*${%a1LVSlOm%BW3w{6tE&8= z>{yHmvU&88FEX8nF;&o$rV;+A*Qi_y4y;}Sci$1UqRbOI4HZx!aaxPtg~T! z|BF7JwuDFh%`;o<71neVneCYyPU3Yfe_oHOB~yPKVczMgy?+qE5m*L(M52CZo~020tyL zAN9)AbpX-lguersUTEqL&Gr4-j2U;4FYvmE~laWa?so7U2Z| zEy6DVwCGL;XwjVr(4t!kP|}Sv&kG5}7_BR(%o}0k;pcaoMqG^=KhkK~VY-syhI&B_D`yMyCVcKu;gwYSNg-;mWv1xPZ31bHFF#Sox zjDK??ere;laAVCHi-*Q8x0_{y3ZKltc%a_E`ytmF7A{|kGhxiY%S2kK@l+yqqqp*IwAivW(TKcLYP_c4wt+5V;G|dsM+E`4E>^y zJcxuW1)~FP#Vmw*6d!ksX2sZ97)=#f;*pqmKW5^cWf*S<#Q8EKJ=rc}p2SZi&Si?a zQ;j@(-{g&C(RHfP^q!p)q2MsjG>`1DU~Dqc1a#PnVicGsEtuw}a~9kMaOrchIL&7h zEw~rp>CcJXQ;j{~BxSnc7e7ohbQ``Dg&WvOw@t6eehP5d;@oW>p5XRwteOo$;HMXK z*BSjXBa`0ra$cbtkk%(aI~8nwvN2?(E!ine5VXadFwyP(Ha?rLTETKolBp%hAkRq# ztqpj{g6)#UBh_aZ_r<^&eRQ_*7%ngTbGFeg?yfx(WV=aJJ1v+*xW$5LBL3Qf1Ay09 zaCN{dE!YdV+=6McTRb5$X+C6DXc2KQR~xv-0@8Gg_v{Rrwg71c8Yi}VY}Bi}n8lD?3s-LXL1c-4pt%i6Dio85 zE<=3xgh<*aSlpmxtyUR}8p zK-Fj;x&ppv7rFw5tqN#Pa-e`5Rh9#O2UZ~oFQg#KzBkgTo8S4~ID*P%|6r)7RJ`z` zam*gvZze~c-EK^XjSSt5mg1DaL%$k>-D}3V<;_n7(9KT~|8GVc)z}=LMe|t$F93Wp zIZy{cWZ+)op%|sFIMqG2wrINBFvHVpxy-$|ISC((r2`$_1R0x{09cW58QnvunEMC| zp18!~n1#i#6YHe}+*fOrC{MttWySoRN`GmW=Gc#@BW!2=Dl6fPL$Wx-#~sB_CEy&E zMe3gfoHDfFF^M>{Yr)eJ;V)V+u1H9<;a3uI=*LQbGZ7zpkZ{<1KM_}8Ss9T;951ur z&l2(8(SpB9#8F=h-t4GgkE4Q9jta&kMJq68CRNaXEvbV3@+6`kmV#NI#1-r(A?--A zM9i_jlDH!nK8qZ%!SE&A*=WPh;((S7Kj&c?G0rp(%ZTAQ9+nZqFL`k2P0|U&7iEEQ z#@iki7{g0FEHH*wdbm9df9B!#FudNw?P2&kI-hJYw;jKhu;E{E9^8iU(mTb558((t zwVw;)*Lu30aoU3e^A;f-x%b&Hj&1pE7{9wnwPBo7t8T-%7OMu}10=_}xH^XwnqwB* z3|nj*1Qz<=Mx&^?whD`z;VBRbYQOc12dn@Wf=U@&sYcOt!E%_Iffi#_&>! zb&{|mfSG+6ld@pgk|e_t6+FJvQQnvpLn?nhClam6%4PJRWSUGtm1DX zyV)kovEL+BhL1{044;>jPE(2SnY3#!|wqLOfmdn3NylRB!%0` z@R}5EE5l!=a9bJPn8MbE;Vmg_Y#82_0%H@li2jptZA3steI&xyj?TXZFskaZyZ=m{GpkdfWut)lxEhlGtO&f zz=p@`W|j??>1MVK&(Y1=HvF<~*0JH&bsP({DtJ#f>)G&Ux>?_bx9Vn&4e!*$W&=C2 zM>iYV@FCr7WW&dG+%RYnJ*}HfZ1}uxHnrg~hS|)9CmUw24bL>pJR6>8m_Zv}WSIF3 zhoOUS8D_}NSZbIBHvF++7TWOVhFN68-xy}G4ev6{5*yxUn9XhYFT-qM!xs&+r43K; znb+CyET7qm#y@w#BA?mXhL`%xH8kWoW3A6z8;yM9qt_2s&NiRfzG&q0 z8s_iO$WJxQ{S^6!jM!f_ENjZK(waO%8J>u{S!}GiHQ9!7`r9?xZvAtF>i@JR8zs*8 zx+dEXhJUEZBk>GXu@{8cOmgg>nrtQ+E=}Vq7@nNQRWLj!jm;#(3-R$4u)*+>G&YlG ziE1P*jOmP=ZjQq5r8Y6VO_DuFXg>jFERG$;VJu)Ve9VD$Mpn-0|H{f49-GdUGdwY! zD`$9CI&3uTFGuF4vyo=_jdb<`8D5djcA4RI>1>z(C6>NPw^-sBoK9kiVK}TLa)#k_ z(X_!Z{7mwi7={Bz@&Jtb;UJPH&l&LX$dhLn4kCG}4DXaIF??LIbe`Bamu}5o9D|V{ zHW-GHAT}6=ksvl0hLIpP7>1Du6CWIbl^`}4hLs>T7>1P~HW-GHpv48lFcP%5U>G)n z78eY|M9|`bVOR)STQCd*L2C|f88!-%{kU{;=5f}xUju?hXpxKCFScHHL z!ywRX#ObgHG#fDtb3n5Z!>|T48!-%HK(i6Uumv<5F$_~cvk}8#m;#!PI08dJvk}9v z12h{k3^PEp5yP+oG#fDtBS5p!1=57+8J0qFY;Fc?0>f`2$HsaugEiqIl~_$B!Zi3e z`n4>=u(g(Dc#EURp$t|YPQR4FI?V9QOxB%CM0Rne#R$hNstj9HFB8@W7FKJMqn209 z@M>g%UxwFZGQSLO$fU|Wp7)o{QO@FccWHuWeuqfYD!#jw$h%d2%{`I3YWUh$6G!U% z8i|}7U!EA0<7*q!b40(9kvDUEPsg|iJlQXj-Nd&j#&~b5%cGXIcA1~s!1k?TXP&Q( zfByF_Pq)w9F4r1_wFsXhd?A_!eI3GMey~bC58(dN*26}P=-=~!-hBqShW8r*;;sP$ zT#w>yTVQ!zS2hAYYa`H~9d}u2j}E{eWgwn~PzRwF0>wGYEZyev)b}}(!$gbns9Zh3 zM3bI52xd9ZYuhPAg;MERAAzXXwc_R;V74W~b_!uOM4;02Z0vxE0>$wRyBYx?QVnDR zD*e$SWv38oQv@PK&s+ygq$p0$W(Y*7i4`|Xx4S&As>GF@M5sXoB1O+f!)SQOiWFGS zLhD&%J#A!)7hjb|@sg|3DBk?4G>W&d(nvHm%`in;S{c_lGAPYPYUO}iJK#1BIMxB1 z4)}Tp+|~i#AmK2#r~@Kq`A(N-rkm=dMp0v_A$HsVOp>(o>~wnC4Ypxws14h^6VB0P zGEjBZ5bz8~5h;QG?1D8Ar(nmaavSzL;8X`(-2vBhz-bQn2$-NiOk^()OYV;$fr3nw zY0k=RiBdP(-A6EKJ27_aRq59wPRtTcM+8z&!s(2lB2XT~VE_pTT@d~P14N86Gz1%_ zd~?gsF3+7*jD&jvm`Qm4S0E$Mm;ay(+S0hWrzRWWb zBmQk1Sy@FziB>-0RYABN!EHTl`c&TT=oZxect;?DWQ!<`3U{)e(E^AQK|28d!3Q6# zV1UwzIVx*2NzcA$EYYCKDRf03)ePT-|AGkgq;L|VvEfsI%`LyWJU%o zXDN+Z*A0Qn^gtkbgwJpo03q8M=9WD!PwM?hp+IVT2pD86$ncmak=y70$|Yhz90V%-fCcw)!1n%vyK2h6 znl$lFESuB!yF7O|OS+Nj3^bxJL@-8N%+LeKXNq_}K=zL!P69-h=1KD;NcSb7JBwV6 z=~NFYNkI-`QiIC!pgh8N;6eWh&D?Xq<Q-lH)9Ew0J4s*bR03U?dC{RA-*|-Fo<%eCK0^+W~%C$|A zjcsd>olmu~Ubw>MNfiE2ahA6Ek(%RT-fT(_a;M5}wW(1fo#lx)vKS)~NI3LIFooaI z2GaHYcv7c^DZ)Bn5w;PNk#56O$O%&gBM{8;qb|=)R5evcRS`AvqKLGmg>1Nh=8Pv?6>p1pDS}yk%o;6rReR9{Ds67LI%gkph>m#@IiIn6M}>$N3Smfz zZG&B}lSyX-E`tvJjYgr1fG;6jKp2NOl^u(aXTij$-5cWpQ+$GzMo$XVLwJTcQo~B5 zjK4wDMmi0664I!GHVDKV1#+qEv<$!$D4!~#XFLK~NNPAeDNgB=5r{E*QW#72&yEli zglxyDA{(X(rXf(J*CP;Ns*GR?(-DX;Jt5wP>@Clw+B6i;!$#P7>idTqy(7$O0Xa9%{9dKMwL5MD(H6K9k_h0N)H z!TBIj*eRr{wXC>Vj@-6yB1XiBiG>I`2$Xh%^`xOo@wX8Oha~WxBT&U=>EAH*oJ#U9 zM{uH1d?^AUnB_p_iHTAuhX|1MGPfW{u-Cl8N_OK(+%LD{lul`OKDE)#s|$D~>AwZA z0H`rYjKUuQw$o?{OL+~fCy9mPIs)Mlaf%Z@RYEWcit>mlic?*U5eVlKgyp3Fl&}hc zkO}cqgf&*2(y1WDNt*QMjFZ@?Jmph5l_!`gHBbKI^4$FeAfikiPk}Hfjo1anFelmx zgg`KnawDumunTMeOoizAC4#x-40>i0AR)SPGZaFI~zCyAPy<`sR_>H zp11aP7TLgx^WxqceajmCb-~IRbJ68l`ngit`df_N?+`X4Y(dzH@IAs0k&<@4>wAfb zZ}@iL^JKl=^z~M1tW~X@CL7oe;Lo_y*1}xu!zX**_1zdLddsJ|!(XeOn!7>f7ldCC zenZ%Uuoq#U8>dQbgx`^{AK?JPL4-pHhk@|I28+TGBpgNf1K}9LafCmCunGuc6RD09 z2qzIvA^e5#x7!utI_-9eHj8~VBvTFF^;L_h`n|>euK?CXZd~e1b|xpvC>yJ`GvizCv@4u zyy6zqSNa-P+l55oj*-Qc$i|hv8A`Q_`&G|Ps+H &h)skZ5W>ggS0rNxSsAN%g@ zxbmRt84zcs#pBs$=-{El@qeE#y@&UHc!X=zqa*tC9^B8>cj$wG2Zs*t_t5a6qlWYi z3>`Ic*r<`5N*j4HRowoGuXcFJA=UFhf<-bB&x&HM3S6q9-9y(ue1S(*3<*eYL(TI-Igo+QIc^TmJy5_Q1wv}HS)tyE{^*UBU zT|95^H)81ENBaf3^d2z+L+gac#q%|98=MK-Vkz!_La z*+niFnVDNa_f~|C2%Qi*BXki1zVZE7WAy}!!1p$A5Wu6bi_Pj(uO%Mc=)1e&pA#*d zG0$1R902!K)NwoL-GOkYIJ?nzYc(9F_SEi*I9Z^(#BG~==~?eha(m)fVZiKqM40QJ zY~asHk*S+}Tb1zVQ?0D+HgMDiF5AGAX>L#2y`bM6p$Ec!2=^n58Zv0e(8q>AJiut! z6DhqAdLul5&g5!oK(GhyK_C#N(r?m6}On7rH+Z)yuj^QTP(7^_4^_%cles7$Gy1A?fI#hOd0pL@2gbx@35bu6q=%9Z6%^?qA z;;|EB+=1&m+|lz+vtuuDU$MVtbH}veQWeK6bL)U1{dy0_KB(fHZzyWbIih}vzma>! zff#O3{JeuPo^4;^ni{ky?)beBmMX&jtOjDwPH@<&xj!@Y(SChGfj%u<5BKXkVAR9I z0uK%z+IwW6Z)CcX`h{C9C=^}J`bH~-V(%;d25~(L3Y$Lugh+WY)lm9~g@^qiF?fML zp}H*eKns^m&7vaK{_1O#RM8yqNW;`7u{=9+R&qraH%%;E;BPE0ANJoanl1F#6ARn; zb235&g%;tSp-@3l3(SDBo}PK3VzKqT)J(BDJ~b;W>+G3Vn41^4EVEF{*@ z2p~5UYhP|sGYq&GX%C~${HD2$1AY1p7)(@v*@y}^a7e9)>!8eHFjI+gQ4uu-QVBEz zeIQm;T2xqstieMc3R-j<5=K!T2=^aQ^`ZX5SOUZqy7s(3RlNVOKRy$pX&A`i65tiN z1-S(c7@(rK*DqBU_g(NOB|+YhG>Kj8xxt?qzDmD_bEg#-(gU2JQdU?*Ld4_H;ei}W zT|%KyiEKlQ0LUTIl9(zi=4e4K^0*Wzac(1SZ-c0|6%|ttR4;}Mz%QXVWKdinrr+q# z4quf@l963sR9xVcbTP3a6+z}a+e0<^#&Xj7jfH)OQ1TO)`SvEWMYxC z|B7?N)c-jT5AB=73^on~p|oI^I$8?180sP=1c?S2M!kTM&JPgaS|r=WxrI@UC77t# zy=G|w6DDz>eX&F$D7Fmsr{#wVNM&f8F#S9hH-y+C&;W|z(2Jrx)>`UeGb`1Qrh$Y} z6r|zW$jttHI#j4-d<+j8$R2 zX#I#kJzShm-OZz*7?S1QYC^*-+DUmOq$!dzL@!4m3Q$QJHh4~xMSc-FfXpI<0khkZdaz;;6cXdv<&Ei7Ut z^C;K0JH^G+{a4$aVqjivcY?Wj)X!)Oid42c!Q3DT$g(?x7_Af$GHjOJA-ZTL;j;;7 z)rUt@NdXfsh*}%w5LMaM#wt)rAB#&$#3Nn(HQjl|C9IL+{tN!Zm|$)wD9oGvfkIje zl3D-}4`QTZXakE?fv{<=l2S#iK}8Rj&XZ4}f{MlG`xBC`<+-XFBa zc&M1;teF^5p#m9Yt`H@2jV8hnRGvVBd29#l`2!eH_K{U0=a0&%`9zZqF=03qAupeJ z;rYYLk@H6|FGNf`=8s@rejXUYBfnz)pqNa|bIc#Xyn--^!IQDaaaq(hw!Ws*7IKu)nT9TWXkCCJoLi2^$Zjk8OH z9r^<;LlvY05}(`;=@VEoN9$QH<%Gx%6U}XM;$sgQQD^6s@VJvRU}ZPJ?!~^r5)z;_ z|L5f821D$O%f$=T2bQQ_s|yh&X@D?Gqa@cc(DO=oO<>IguvO%X6SA1`YIR?Yypkf~ zz9O4F4Lds-_-HqK2vk($J>>VdKw6YL8l9L7`VAh@58{+Lyj-%4bub7!Y!e7FfiTi4 z5#SLk6P;z@&Jb@T22w9Hgt`De3lcGDp*Efgsa7^MgwcRToXnIR2eMXXQIQ3NOK9o9 zo=}uLJRqvg^18S>;7c^FkfxRBvJgHLN;-K3TM(2r_vDvA-)*-lKhUa@TNTW&!G2j~ zZ;3syd~w5_{(A2G!aVWto&Gv8WCw(~*OwN4!l6K+ken0qLFOtCiWWMy-t-Itv0~Pd z_K`g(=nASpTQPO?8$O`-V7a5-^Z}L+iaBSW{2~nccBEgjjKiJc^^Y{!LD?(FWbX^e zMG!$HtC(M$OP*Gm8>nPX{bKqv{)Da});|>B*3j&1&-1~8e765wF-<9z+EWmsVPs9P zK~Qm&3yEp8KD#=Vv{p{A1tIbr?cr9yGl`sFWsWt$7H~H^C)k2eh)fYmI3`%cWMarM z?t%qjxr*ln8nJTi1dGb-IWJgHMC~DI%Kd|2K_N}z7FU3&bI=PU6dJ%F=xhS@lAKm) zRwZJM;($f6p7Bvo4`b-a-iVINLew4YAa>pgr3Uj1OoJL$57vTaQP87ku#iMpX(R*- zt=W|G3#h~7u&CsD<+D3Q839m%KSNV4dhqHgH(0<+Vy?Ji%FQe&;fXj16{0DZukur;FXp91*q-K#f;|0K=C>%H zhH_8Bc5H(Mi&(^xU!XYnEh;1jNN#|DUn(yR57b4PcS=QZi}?m3tFOOKb50`ek!5jT zspl~SkV~3Sp#fxj3qzuOj6XBG@GRH4kO**}1EWI42mvjj#XDihs)95|IEh4IHAzy<&%gQVX&X~4^{;Jsc$IIBjeNNf zwQUO!qgsKi5IOHzVJh!Trb&s73!zkW3t}`Tco)h z`!SCC!tCx!@10n=#<);rwsFbNWskJNxS;X^+qf`%m2m+)Ou(@oq@St8Mrb&H(K~Yj)8D&Q`OnN8d?75S2an#<^bsA_h zgk_IB+tTFcVyBWeF>Fgy87Zpm*al+}6&E-xO@3Z3^*UP`5OVZ1dWQ$8Wf>{+T1&&l zp(GG|0b827g+vgel5(Pk#^xc9R}8k9vI~<=iM>7j=>ziM*%Oacb%l?HXeGYnzOIEt z$W8@;Qsf7@L!p{Hk&tDE%%Q{5G9$Z)H*RWI7A;C$BU)a@WQF-%2#wE5ICiVZ*(R>B zPH{>$$gYc&EKn-OP(EgL6tHbL%H{osWU06%S($KwqP^D z#jNmLu|uvX<>acEm(~^%>M4-UfjzWf$asp7BTf!6SZD&s9792PQIStu2GT;4q?zS# zkhjVSnZ0@mV2)>G6i02ei%sd)%s>E>1v#bxeTtF=r05C5=ws>JPA;&#ULNEY~06mllQZzxf1%v=VGK-$Il)r-6VBj7n zw?P;OdvSS{sjJvyuyiYwpAWHAwto3gce&C6CDMR(Z=KnHl~WKbrjc| z8zvVYh4Z5w&JHaS@HPy>q`r~}?9XsDBsvFzrD(i8L)`?8sDuEiS5!gyR+QDa7V#~! zrMX4%s09cW6te}mYJURu!mksS$@IQb}$`?VGl=T_FU`~qISQh&(TCwTe8J(!P|K`Ec+=-2ax1Lb3H z1@uADrVv%$0!+V^m6u-cu%ZG#-%?(B8EB>9eIo5Wg!9?PS5{ux1c<>hbEFc`4IX#Y z97{f|%hpR3aD}}BR$hpT1Y;ussK6nYvXUByNpqP6Yu1M}sM|mTQeh>8k&{(dh(+!- za5Sgv2io`fGTI78oI#LV3uaT@7WU<^o8T#A%?C#Cgn9&k+eqv}I7j`+`U$>r2v? zvY=|EK`r8zP@D@hKFzrm8!C*!^yFL|$}fQxfWF*=;|!o!0vV7h(AEy^zF1?UUOibK zz29X+6R=W<9y8dW;(b;@5ltbyiAFR;t^WQ7a*t)ko&F4Q-3-#N5_S-=Z7dza5}v_% z(}|i!>6RR5?Zu3NCi5htQGDB`VCBSiN45x4LS8||yF06~Gy^e}Fzp->PEiGpHE8k* zcp8?fZ%G7huH1a&N=V_UDD^2}GlSMkK$0MNuoD{H&6V4tvJr66#De(L*3p9;)~X%p zB@PpqSHSP-*aQN0ER_%=rNYSx6mT5mD5!WvMkrvK6hZEVf*5Qsk}*MB2RRx+C?V3f zN(u(1k;DpS%QI9GvQBX1$rBv8)Cnk6ae^acFOqPYgEx0r1*tyTdZQ;DAfZ7`EI3ba z@c7_lHiDAFt50z7_7YyN(r}5M;2;I6yf;V~*S<;3E8;qkiM_na`+ztcK?1PGEFne> z2(oBFWS`)Wt9!zSSo;sCR`C`iuds;UjMm7eRzNgRe?ZJDwLBNIHR%}@tvJEqft;}u zhc3vMuC!y_?|AWEBu_N(D$~-QBJy6~cUw~+hE#|>1T=!*(;y;`aPa#&kVh*}dp^If zBUE@!WC845J)BA*ZK^oJ!Sv-jaO4$RM>r~_VpU)*;t2y1u~nsr-DF{!I(v<7(tcm$z4tW11_gU=fw&#{O{;V{3gv5s(1Q?5C}L7t415abbk9R~$x^CaJ8 zIaIc&gielFi~{C$z13|n-=qrMZ6sW@FNUNnHV^fu<7qEnS@gv$ZOG8EOyyN-UJ<`y zqCpnqRVuoT7$D+o#pno!lRKnCNMv#BWb91+zaHV>V*@CbYikJ~;iy%yD66DN(yA5Z ziG>SsjOgSre_RLXxO6$GQMN}7f~-)~WPay}Cj@GDaWTIgmQ$oOPEd6|xY4~B4l$2$ z8flf^*ifTrsKM|O)u`_Pky9xeAb3hQnn1ZHAx{lZRBXM)pW24rb+eyC1_gqLnX1s^ z;zCjqC=v1;?DAX&lE}4fM=?*LSKE$aU|xF)gKZs(qex}jfwzs+TFZ6>b8{UV>$$v~ zik`xduZn;VO?tGSbqa&sSf|Bc4j~8IVo(KaY#g?xxFpD@Fk)~l1P3^8_Gh?r^X1-! z;{b;B7SORY4d%)&#gq3gHSdcFj$DP4tyHN_W29PiU>J0k;oS@d3@wZ8h;3u zMyA8~6A|!3B`SR$(k~h1 zog}G^RF)lK;`=Hs2n9)MFmdwy1!D9v2;FtfOjE*VXqZ-XKa|d2a78#>!EXrifMqXt zNIakwlt)1<3_gDmtRw^2n5)iT*oNV%^A~*F2L>yz!Byukhy`ggAUTJ4al{Nc)}bvJ z13C&qqZeYg&R_7_8wths+m=ek1IgDK4-k>(FLK#G#%>~6-sobNXxZK<+m1|o5ECNR zj^k7Iu*8-kzc0ILg9Ab(9Ysrdu61~AlnjAdxoE1?3(Tt2JU%o*70A^P#v{$Ql!F0l zAE%%a`F47=1esdOK`&Y*$gGkB^#8PWE^szg@BiO>&()l9pE+mTM~qy@jJa^mH!-tjk{OS+{4e`IjLE7;Xcilj+HW(r}u$<7gNrg#daXVQ+g%hB^gcg6*=m`XsUlY5Mpy*NC@Z!2$-Ry|fg(2s~V_}}t_at2zOG*?cPn#pUhoeaG@@dQXx?#>S zN(9Sd&9S`5k;$K1HF%Px7 z8eYQ-{rLjT#XBV0+c!eb$4AAlK40%++GD6}-*{s5HnqDG4qr=mw=X*Aaq17d3~hOQ z+f;``u=YAcUJo&jR`yi0bc2?*5wBAiIsBtIq$|}b(K*>A4oihz8du5EwA4oYn%Y~M zmih(RrGdm#8rxtaS{mU$Z(kqV3wvKbFF(K7EW>VXL`93ksOYu}`Uiz|n~QzQC#p9u zyG*l;;uoWvFqSG8Fw2M*S<{huiX!bxZ&cV1(hx*|ZV^z}1k!vY17c7qI!g>|oYz4I z(m_%c5=4<~sV%a~Fw4*rR97vPG|SM#l&g7ydBqEloGeam9kYy*!IE#sEF;^~$T)zP zL0M}aVJ1Je=E=#@I^Lssh!!Oy9L1A*@#(;9_E@4#HzzBscTrrkj6BC4h*G8 zyI5Y3iDJz|;?Zx$^s_Uua5WD__9mvyqg~CTh1q5q`ChZ2pgla$>7_l%V8XlPb+~33 zRl{OfQ{uRQQ_JWO64hF*yt8brwPZ`aBwvoKL`wz9>Y#+S<7C&Z0J>Jof9WF?ThB-t z^z1;tXx*A^ud~t+&B-jpSqswCbkoy2_9bmDp#>!bYXuEQrci6Uyoh3da-p7q_%08 zYZ)$b9UY{$j;Wi{tEJZ%jEay^LTepZJ#XDH-f*>!M4qp8G&?$!T5n|=5{NuHs6<3{ zj?(~;sJoJ$rE-QPq@sUmUfM!qShhB5(AFK&&YYQ}uz8v+3so}g5{VmaFwzT%;e!yN z@F;1j5(!QPv3ijY1M3&>1xhc3$*H9hl=5w<$1boWnOiQtqR?4l(&|y@7%WOo?W%>u zQwA}iK-Fn}DuNtg7ntG`25)6nmH??tT)Q$=W}k}#6@0+|GigA_3irq+94tg9?@h(YMm@bPnw80Uac}J~~r+ds}Fwn3_qC z@Hs*YH<@(K(0T1)n}R1TLtdiON*v8D#I{&IJSpyzG91uMO65hCOQrH6qcF6(T*AbI zWPv87^AbkB-PLth7789T1+7azP*+-nZ377b4^C$70@Gfj={nWIYp~O$x4TQqQp!t= z9)}ID=Im68*5l|e$5{3#C%w(jVwy`V(Ied^hQ!l_#Wcdxg@ymTIa!Xdi-u!8W!qY`ln`n7 zxaXKSSAVIs7>MpQk*=E+xHw&+-wNL-q|ckpCErYWQu z+U;9DQk6Wxil7qBms5BtCUvhZro_x3JF0G-x?^Rho4B`y%i)b~%?QnR&4_3WP8c62 z*meQ>2(Dxc*ID+oW@$GxAl(zCa8B*%248Gt!PY_462rDgkSf-59}!P4kerli>w4Ot zv)~NvIeG<-+LJocEj345Z4pvjN%p1_g_idZsXovllQyYNN4Hvgk5NR~UR{ww9-Zr9 ziJ?bC8i-zvEicqf=z=(Vu3*+WJgOANbriA={5Lk`&;odS_v<9hUT zs>FVCWL*ckb)Xxz1j_P2YTwq?lC0KsVl_gO5Wg;%rY|vfvMIDYd(7or3spgTaV#-f zQYDfxZHd8VOi4=&0!mq8NQ&oKV(4oG97~K`R&ZrmVlZbRtJ!(^c2>1X9VKFcEk%=X z+Y*CsF?3mMdWx(MF37dr_+;p=M@8vT&g-xy#F zGzJ-5o-!>EP{;NJ{mmv3f2VPmakp`g5jG}6H3i&j+-FQRrWyAe(>3P|;{oGA_=;}L z3zFx`T?2J+x*p4}(S4(_Nwak{-Z9=a-ZM5E?;9T&A0qZ61bvLV1@{wUD^J^;kWX>9 z8#|289RKIW7d-7WzBIlfkv*HUtExBV`0JCzH?fTZ>bsG7NwJbO^;DmrU!5ygv$|E= zRMx1BOLHZ-wRx%8#%ya+cjjgM-_EoXZjal+>}Ym!{GH9q%`13TtLFOC!q-FD%k0hn zeVq6kaBnnka(sQwLZ14W{mlX9K&S>e;e&C9m_r@kFmpIhBg~u4k?jxuj`Vn&-| zc)HEJ-5hIWp9xKe#WNV6buXSH%$fi0G({S&% zraQhF)&o2}Xgy@jgyv!E5$jPWW|s9BPqVGZtvQx7kGa-7tD{;|IZ#dAxWIpf*;;M= zg}Z(>F7Q`T`xp2J$DCLZuk>w4lV6DUtxeH)1I0B+)VE{3>F+4F0+o*y&8^n|?)OJ- zebQePqxx>}-&sfRwKgo&`jh>Q5?}twwLo$WOYDHmN#oVwxIkM~X_0?uOm6xBx%7uy zK6VBgsjN|fIJN4rz*Ta+Pc`-0>D1(;;*0atl)lXZ0q)<^I~vYCaE0#8Mr+mutEqKu z{pDh?EK-%<3DgmB3F_N5+!C{Xu|F@#ogZRIRrHMi7IoxMApY{gAll!)(@+0l4(A3w z1_n=rlLk84o`6w&_Hyl|s-FKzl37dqDGk^|ZkEHQQqy$#U#1kAwpo5&UKZcjI)0V@ zxj)4`rYctpq&9kkyPr(csIMJUe3ziWJL3{gkCb~B z+p6ju6ynL8ASKReSv;}hw50#5{y?XEzS)Qh%W{Nel@g{G9*AKcfhl6t_kcLVC<|*f9Ji~H)q*p z!=uZ_YaKgI%{<|+5$$hvq@v?h)*63OB|eALuUu|;K|qcg6Y*b@=E~E>BUH!bWlmCi ziv0RbB&NB!%C{|v^0Oq{cvSjYe=jVHg_S8HpG|7Jta)qw&BJ=`%QZFF>P*!9?D%kL zjbuOq?S?4ZKpa;RD93a}$hi+xyh5i^*(Hz0%9k|~k2}$R$->S?vuo(Ui`s*t6MUZH4DA^hT#JlhJxK9$kB#HN+C3k`zlrIY1c`93$S zC3}{re8a2D-jd80liHu;kcZ4kp1>%j?ydTD+h%Dp5zn!&1fUr^dn*`u%34c4VYgRb zqV-8XM~l^18|BoXFS8 zjjnML*4sz97)ZJ#Iw!fZogq_udx0auq}F7!!pVuSXunWOYirR`z3{F-J%%h5Prd`i zBNCPC9J>ptJ3UX*y9v=a-f79fLJnb^MNE1dF;qzp@iOx{Rq_rU+^*&sV04qP7d{@I zmYflId7R;;dBalUO+$D1iK?l5v39U~AsVv#D*qK)Im-F;nv_~v_u1M}O?jq{_U5a} zyBM8CL8_z4O|$~dQ(8T;MQf`^wnw5GE!R;(xh0j5{-TjNf~bSMRv2ze1Lfd2+7eNZ zl{*Cdm*?0$NB1Im*2)&Qq_WkkP2`BQV799tQ58}BXshml@|jFDZxCwLon1PV|I zt?%UKLR5~{hO(NEsx!}GS}u6h>WtAZ+L&@ZH-JdhlvZclq-U!$=hmPLsk7qOmMa>x z9i`3po=4=```8jleYl!W8&zvcuR7Bs3oHLNl>*gAI-0}Yt>*N~))UTGMJ=OW_t~2@ ztj?o~!`_dBqm<$hn+UDKFhCI(7VSc*etpK@I9!H~@MePYmB<7oi>9gf+j7N{+s-Dt z$Fdc`Mqa5*NF{0QWoJTIv>!^zM6-WXLukA6R7ySvv|g1`N)5@YJfElRS#PD%YDiCe zt+m`Yni)tbHSfKYwdythH1BPF{=D~#a$IBlkMrK{2Arx=lK)E8_NVluW*rO#U+^FK z?$UgVKTEGsxeq%O4;eGr>v-6B#CX&gsQPbAPgRqD3?`c$)ShZgq_@8A-xV|OcW2)G z)F1J_Z))3j!*+SoU%z5pf4QJrWe5Frt!Z;r|GobE;vSio;9IZKKlc0Mnv$a%Bh0PK z$EsUb`0t9e`G!S;!&EsxFtQ?FU9vT1>jBJd)wkdJ+d1)LuC1Huv(=IqzP46lk^*(r ztlj=tpH7uND;!6+`>V&w*VV=Gx~Z|EV=hRsVR6m0STS|DAVt;>fs}9y zZOEY20ZF&iY6B}w$94QI@JH1Mn}%rEVh+*K!eP5DZ5NJW#lxu#99pxHoRH_r$-mSP za}jRPh{onJG-)|JOd4ODq-~X=E0(iH=8aK~JSU5|-UMYbsmG+!36h>xgLY(YYlb#E z!C=V*^=y=+Q2i~qWl?7IHjAh_DS~J>z3CT2yc)g7-`G5P3z{#7kcj z%3L0#sfV4JL!Q2GMz=K*aAHzH!@@ki zaInXE{T+~O1F8Sc3HZVTF0_&<9?10-LrliKA2ho|K7pPg-`RR6&^zSod6uw8S1|TM zj)8Zq`r(YfPRYAu+!nxIjn=6RdB|43HVtH?mOTA;U*?%6fvkTJ!F)VR6*LPpXkVs? z;-u^|*{sYKq6f%k@zycEb4-%2y|`Frs$wVp(kz1VW5E1Z4U(-nK!M~Usl7PS#wN+p!J*b>s{ zV(T*L&?r&Q&YbQCbP2ot;!dRT>85#s?YO_*4Wy|~0|PbG&!_yE=j##DbM(lV_v+eu zq*7Fm$f0r$6qV1_PgC6&TrfU+O7j$D^$16jw9Y zgDIy>jxMq1=3EX}LYK%8SqSTG(0RV|h0r*#*%yP0{yOhAv@(s<%P(S#4C8-2A`MCAKoi zr)thqFa&yaiL8AjFJ4{Z9QCoVZCi<*@-1}(<<;Rcet+ri@4Wl-G>E@c_jlXK*(QPJ z{~#l(LOfSW>lRiztwzdMFVIAPLG9fn|NM-WrK+bw+7w zkIu-~4A+*@8KoFpoq>hfg_bz>7Evx2LfK0md!5zn!kwRnOReRx>*sX-;?HH>%@A7| z*o%^WdQozbm29f!NBob({lI}oW0ieXpl)1OBgEQa(J!gZ6WSU}2yfsG&t8+xAJF-Q zKQgfGoPV1&^SC`xn)`c#@4JiaIoD-opi5=ztWvY81n!H!e?g*eX+=9Gvufb+1nZUM zcFbGPCHhuZwPX6%2rMjT{qcs5i97dZqHnrhB}D$65g40fJ-XdynZF~^_f%_}WldIK zX6=~ukCn5JZ{D9>&Ue<4_RZCSpUcI3veb^Ub}n1iwNIde_4P*8Z5UblVN*HZxe97q zuSThnBf|nC6XFkTFXwwUPw`hPhN{y(e|gnlZLqWImh5jG={+W}s#?qw4Ou6@<&;HXh^W2B$52_DO2kKk<4@Q1H9XM{4YkJn=tf%0} zF?HmxKn-iq)ZTu&Msfc#DRx2cPdh=|`vz$QGq@I0094!(CI z!E$K}W5P4$CHtyxC14x)6l@1Oz-QodSXK(b7kGApFTq#fYp@G^Bb6-#@`rrBCEz=- z8|(q!gS`+OcL{zV;770z`~>#L8vN~UDCVnV-|qOI2|5T4fy3Yk_yrt|jZ7?`);Z?d z`~Q>dR1XjJCrAH^&@qU91INMd;16&DoJ8~{NN@iW&na*koB?OSU*KG9srGm*TiX%kFysalniHrZSjX`Y()m1(X}NrAKpu`82(SE-}>g6S&j zr(h-3S^i@(QOSHkeGy2z%Uq>;q@~?#u2$>Q(gFikC;OTuu*s1KHlI6pP9S>_)BrUj zL#m~YfPHa*4|3ub_Ypa}E>UBDUQ_XFgI*RD_YW!HnLKJX@xfxiLpCU7zS zh5*Ln@YQO>bK_DpP4G7bRM)}{$-Ym@|4n_-J8!xutxim2aYowQm^R0^P`z33W`hZ%eEnszZ_nXMYWJ4x z2CCJ`>>H-nX`TkEf$E?}q)zji1M(Bzd9Rl5{qL&Sbd`Qf%~eNy{)-jFk4#rXYJysz zHmDO(L(<<^m7tbo`QAUKIi?6*;`F_#b-_iT9;hGLo0{?V+Qb73HX6P~vnv#5L2d2b zEK&9A)#(1|Z+wyg8i0!I`f4%IVv#Zv+~HCZK6#+x5-vFcTkG%^&D~=@DI& zDbo=FGC^~Y71`Q5`{nqAci#Nf@O?X~IH^c-|LpJbt(7YyhgJ5WeCvrPB42OGZr;fH z@X+++li8pJ$cZGM%@nRBR8#YRr7Fo?H996UyIgM?xmm&Xba>| zLKWa%2HJu4pabX#IsxJfjtl3g&iF0|!g&R_5_mbg;J*rV1y_S^fVQj~GwnHSbSFSI zBCiEKKu>TTxE}NZy@6z>5AF>#kV893cEFAJZUTKlA?OGCg8^V57z8}Y7=!T-0Yib8 zJ~WH~VHgfZfSbWca0^N8{F047FG6&yWFb^m& zpO{V2m<5DL4M~jD#%_tx75xMuPXbA5AtuG9X;brRtvp&w~}ft&NpDzX02M&9(~P zYET4(Z4G!4yaZkbF4rqOzY5n$;i?kBw-)>tyarw;X3lqR%o~Kvj1AjSQm!J2(v|oo zQEvfBY8@!6TvCba5x8G-ZNT?7*a$X(cfh;gJ+K+P4?X}Nf{)-@w41a-AItmSLeM9m z5cC6Efwxm_!|!&gPkG)Bb|B&h5s~>BzR$rIU?=zzdQ1#5+8 z{Qz^HY6MgVH9$>J3)BX6Ksu-kE&^WNSr31GkO3Nii$O!s2s8#wKvS}JTvAAChA$H| zCuGKt5|V{4JM084k)ZNoD9N1FAiJ2p7Q7*W4O&2w19Cwg@a7>Oe@oB`sfV=GAij_j zGI<~T75;_q63`l43f+7OO=^R$Z9ENCSXXMo0)j3B?Ld1%H%q7<13M7XhD@~u9eFOm zy$rMi?Li075p)v3IrS$=xHFWOgDb$5gf5iOMKP@*>O#;}plu2s(M(K&H@TM(~oA&Bp0MrA)ATSsV0Yk~^exaCa4Z}Mei~y3$n{h`v&*J~T;rjn8<3I4J z@PXin@QiI_eUwgJ0?ywgzKY$;>KJXLR4-W8_mV6`c z@n?Jo!69%M909+8qfl%Xik^Gb-9HCwsLA_TAB{K~tPxuNEx~$WdIG|eKo+Kd!mvqV zzA{e{bQ+uiXTe|K95B?nqrr{g<-4IeVRcTRfdi@ID{$R9zLMuI;407+Tn)N`?%*15 zE$9Jyg6qKbpcm*3`hXk2jo>EG7Zieipg$M@@&@wXATSsV0YkwsFdU2kH-nMj7BC9j z3P!7Lzfu0a$AT;4m+vM2wbhzmgEf7!Ww2HJ_gd;>0@Ss?1^3t8^&=t8WdR+AcQTj) z?gjUOsR@QEs+F2ruVBtT=yXj^Bm90KH8~ySRU|Pi!Ike=uv&|P9gdf&5=4)JS>Q1+ z8$1rfNuii$Nt$yAQk8xSrl@-lkmm)zvz*oc9pA^(g9n0X>bc*8!_=|k!KQVWAAs+0 ztTr--*97q(0azd=CQ|W_U{5Q&=m>NND?WkjC&5DSZ?K1#_aEG+z#_01JPn=!OTe>W zDOd)UgXh5WUsDlVsk&ee~#&^DtibT>u`aL2?a+as$y{zB{OKR4^CH`VndCRU!6|0{sX~p zPgj4&h8osCA|chCzaOmSiKNMGzOMMbEx%y)4AmhnG}kJ6AhIhibg`AP?_pSy+O|b6 z7ce(1FbYmRtOALl=d87ls<#tE&8(x3Mt)5U-R!e=FOBp~2?d*n6We7N0;&G?9Wyj6 zp51VHcEiz_(QtWo!`aL9TD=PtMcq46PGAmQRx02zafj3GwG$RSjyzkR4y*R}+< z2c1C|P_JGu&>Qpt*Bg@w^I|Ig2f-{b4=e;vgXP+W$lT4d7yIxZ0e^tMKzw^L z1N`8xc9A{pL!08PqQ}*;D?+2JrE^r^%22xX;haeD$`F5_dHeI~((6L~t*tL|@lYtm z+PWeV!Ee^=_fm#&+xY%QvnJ{3=~=z9CKwGzjTcF4n^TCXL~dc>?Zf)>XOl6CA2(`j2g%Dv4`vu!`=~Ga zgs!!=zN(tu5K3#>?S>44!+WD$X3riSo3U#$KSC-og9t7tlE?Ti?FtLJbYZy=QKN4N z^-D;W1!6!fkY7L2h)XmsGvWylh6LP1P!1#kACTWv z2$Oj(4}`7)ZbeWDR0dTdI|hU5p^uv{(SIk0>n6%M$#u_^rYl7PpGy|ESImiOpYU$w6 z#aD^Qf(&^^fdFU{4bEOJJEfTGbgEYEWGYJrckCO4g$)92%+}7WyLMOsCr*Xbfos%jQdI863XA&se?;#+kmz}eu>Z)@O&ANDsG3{9&`ZmTXMVo3Oed| zbz)Gcj`WeMK{wD{y*(^6zP~iR5l~8&d*I4X2CAvfvxHZ2p1oB$ldyu#Khd8)G$)L; zQ@Tc{#N-XP2j~f|Q-9G6)rR4r9>YaeXK2exBi0G`rqPeEf`tc2<2$q8I6IBLP8x-{ z{Xl;(01O0!z+f;$-7_LIJ}gCR0GloXuA6LI=UKu(DkIs>#1~9GNV4n9hIiP>4n?d~ z@-W=tU<9}sj0CrUQQ%hKwx&_zZc$@z4s{PpA}249_{&bXx6GADu;8OZB>tqY;rI+= zG(yJ!N&Gh4+rd~c4%`98g9$*k{)K)b&y&EN;I2ewu6Ofr4+yKSBSSaDOQr0&L#-Ye zYS2NR&yb$vaUrh!WYXknuj7PC-qMjPI$C}y6PPFPJOxOe?p1w9glg24f*%AA zftlc8@CbNRU3W|9W}V^zq)CcPL@K|sQcOmao8nrYXCdM-ASupP@uNb8ttImdh!Rmf zgq)wZB8xmCT20I_9*2F7BVw+4dQ|Ajp2B+cA6P$vRTSAghgIRu2MfRx;7PC${2TlS zJf+?m9SW%4w}#Shk}R%-U(%U{TRMxI2$L+!uk9o|okhryQZB}Q8axB!DEnEk6f6VF z!E<&xhi?rf{!8T7hhKi)D)7pG*^&P|ydr-E?#e_%U2;pPzS=xGRH;u^2Q-_An*R@? z8s2GV^<_uYE4Z(M2v`gL3tj`SgEzpNlGQpv5uFU{-{tZnNAz2;NiNsnu2=psp@9Wb zna>j~Vg{8ZhOmO8C#2(;qwlhFxWN(gHtt6Cnk%L&(IO@hw{&iX5mqqgPc0_pZd=SI zN6b68@2bAHIk`FJh*?>Nm}FQB)}GR0);eO|bHr@MeP3C(hX(5YFpp@-O*h=qxhWDc zyG|o!dDX0Y?A(0di1`rrBk-}RJ2sS}-n>0jN6RY@oya>`hP;Nvxh-ynBX5f%?-Sgu zV4KLRp~ukCkd)3+!+RpvjSVf0EfB3xO4}4G8|27O`tgNTLhFg4Yr_+!Wf-4Az8zGK zW3C2v@cbD_<=GDc;B)-daKFH9Ta!YWdTx+ReC#y!$D~lcj%z!=s8 zEU8UqwwXpY369=l8e?lvLuW{^76PhU#t=#`+`LW Date: Thu, 1 Apr 2021 20:31:16 -0700 Subject: [PATCH 22/39] Add JSON unit test, fix ring count output. Shockingly there were no unit tests that did a simple write-then-read. This is important because it's easy to forget details such as trailing commas and the fact that uint8_t is a char. --- docs/remote/filament.wasm | Bin 3844375 -> 3844305 bytes libs/viewer/src/AutomationEngine.cpp | 6 +++++- libs/viewer/src/Settings.cpp | 8 +++----- libs/viewer/tests/test_settings.cpp | 17 +++++++++++++++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/docs/remote/filament.wasm b/docs/remote/filament.wasm index f890818b5496d77d41c1286c30f1e356b1efc43f..32680cc8f099f619a057ee1c212763ca5f5c3df4 100755 GIT binary patch delta 6593 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 diff --git a/libs/viewer/src/AutomationEngine.cpp b/libs/viewer/src/AutomationEngine.cpp index 359b884eb2..da117a2e51 100644 --- a/libs/viewer/src/AutomationEngine.cpp +++ b/libs/viewer/src/AutomationEngine.cpp @@ -140,7 +140,11 @@ void AutomationEngine::applySettings(const char* json, size_t jsonLength, View* MaterialInstance* const* materials, size_t materialCount, IndirectLight* ibl, utils::Entity sunlight, LightManager* lm, Scene* scene, Renderer* renderer) { JsonSerializer serializer; - serializer.readJson(json, jsonLength, mSettings); + if (!serializer.readJson(json, jsonLength, mSettings)) { + std::string jsonWithTerminator(json, json + jsonLength); + slog.e << "Badly formed JSON:\n" << jsonWithTerminator.c_str() << io::endl; + return; + } viewer::applySettings(mSettings->view, view); for (size_t i = 0; i < materialCount; i++) { viewer::applySettings(mSettings->material, materials[i]); diff --git a/libs/viewer/src/Settings.cpp b/libs/viewer/src/Settings.cpp index 61393afd1f..3d33d7ac17 100644 --- a/libs/viewer/src/Settings.cpp +++ b/libs/viewer/src/Settings.cpp @@ -1205,9 +1205,9 @@ static std::ostream& operator<<(std::ostream& out, const DepthOfFieldOptions& in << "\"enabled\": " << to_string(in.enabled) << ",\n" << "\"filter\": " << (in.filter) << ",\n" << "\"nativeResolution\": " << (in.nativeResolution) << ",\n" - << "\"foregroundRingCount\": " << (in.foregroundRingCount) << ",\n" - << "\"backgroundRingCount\": " << (in.backgroundRingCount) << ",\n" - << "\"fastGatherRingCount\": " << (in.fastGatherRingCount) << ",\n" + << "\"foregroundRingCount\": " << int(in.foregroundRingCount) << ",\n" + << "\"backgroundRingCount\": " << int(in.backgroundRingCount) << ",\n" + << "\"fastGatherRingCount\": " << int(in.fastGatherRingCount) << ",\n" << "\"maxForegroundCOC\": " << (in.maxForegroundCOC) << ",\n" << "\"maxBackgroundCOC\": " << (in.maxBackgroundCOC) << "\n" << "}"; @@ -1330,7 +1330,6 @@ bool JsonSerializer::readJson(const char* jsonChunk, size_t size, Settings* out) int tokenCount = jsmn_parse(&parser, jsonChunk, size, nullptr, 0); if (tokenCount <= 0) { - slog.e << "Badly formed JSON." << io::endl; return false; } @@ -1342,7 +1341,6 @@ bool JsonSerializer::readJson(const char* jsonChunk, size_t size, Settings* out) if (tokenCount <= 0) { free(tokens); - slog.e << "Badly formed JSON." << io::endl; return false; } diff --git a/libs/viewer/tests/test_settings.cpp b/libs/viewer/tests/test_settings.cpp index 1273839a5d..6eadab3de4 100644 --- a/libs/viewer/tests/test_settings.cpp +++ b/libs/viewer/tests/test_settings.cpp @@ -162,6 +162,23 @@ TEST_F(ViewSettingsTest, JsonTestDefaults) { ASSERT_EQ(serializer.writeJson(settings2), serializer.writeJson(settings3)); } +TEST_F(ViewSettingsTest, JsonTestSerialization) { + auto canParse = [](bool parseResult, std::string json) { + if (parseResult) { + return testing::AssertionSuccess() << "Settings can be serialized."; + } else { + return testing::AssertionFailure() << "JSON has errors:\n" << json.c_str() << std::endl; + } + }; + + JsonSerializer serializer; + Settings outSettings = {}; + std::string jsonstr = serializer.writeJson(outSettings); + Settings inSettings = {}; + bool result = serializer.readJson(jsonstr.c_str(), jsonstr.size(), &inSettings); + ASSERT_TRUE(canParse(result, jsonstr)); +} + TEST_F(ViewSettingsTest, JsonTestMaterial) { JsonSerializer serializer; Settings settings = {0}; From bd4a207b372c59aa994da2ab55d7b595238d6055 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Fri, 2 Apr 2021 09:54:51 -0700 Subject: [PATCH 23/39] Switch specular-color to CIE 1931 10 degree observer --- tools/specular-color/src/main.cpp | 946 +++++++++++++++--------------- 1 file changed, 473 insertions(+), 473 deletions(-) diff --git a/tools/specular-color/src/main.cpp b/tools/specular-color/src/main.cpp index b4d0ea365b..d60121ba03 100644 --- a/tools/specular-color/src/main.cpp +++ b/tools/specular-color/src/main.cpp @@ -99,485 +99,485 @@ static int handleArguments(int argc, char* argv[]) { return optind; } -// CIE 1931 2-deg color matching functions (CMFs), from 360nm to 830nm, at 1nm intervals +// CIE 1931 10-deg color matching functions (CMFs), from 360nm to 830nm, at 1nm intervals // // Data source: // http://cvrl.ioo.ucl.ac.uk/cmfs.htm -// http://cvrl.ioo.ucl.ac.uk/database/text/cmfs/ciexyz31.htm +// http://cvrl.ioo.ucl.ac.uk/database/text/cmfs/ciexyz64.htm const size_t CIE_XYZ_START = 360; const size_t CIE_XYZ_COUNT = 471; const float3 CIE_XYZ[CIE_XYZ_COUNT] = { // NOLINT - { 0.0001299f, 0.000003917f, 0.0006061f }, - { 0.000145847f, 0.000004393581f, 0.0006808792f }, - { 0.0001638021f, 0.000004929604f, 0.0007651456f }, - { 0.0001840037f, 0.000005532136f, 0.0008600124f }, - { 0.0002066902f, 0.000006208245f, 0.0009665928f }, - { 0.0002321f, 0.000006965f, 0.001086f }, - { 0.000260728f, 0.000007813219f, 0.001220586f }, - { 0.000293075f, 0.000008767336f, 0.001372729f }, - { 0.000329388f, 0.000009839844f, 0.001543579f }, - { 0.000369914f, 0.00001104323f, 0.001734286f }, - { 0.0004149f, 0.00001239f, 0.001946f }, - { 0.0004641587f, 0.00001388641f, 0.002177777f }, - { 0.000518986f, 0.00001555728f, 0.002435809f }, - { 0.000581854f, 0.00001744296f, 0.002731953f }, - { 0.0006552347f, 0.00001958375f, 0.003078064f }, - { 0.0007416f, 0.00002202f, 0.003486f }, - { 0.0008450296f, 0.00002483965f, 0.003975227f }, - { 0.0009645268f, 0.00002804126f, 0.00454088f }, - { 0.001094949f, 0.00003153104f, 0.00515832f }, - { 0.001231154f, 0.00003521521f, 0.005802907f }, - { 0.001368f, 0.000039f, 0.006450001f }, - { 0.00150205f, 0.0000428264f, 0.007083216f }, - { 0.001642328f, 0.0000469146f, 0.007745488f }, - { 0.001802382f, 0.0000515896f, 0.008501152f }, - { 0.001995757f, 0.0000571764f, 0.009414544f }, - { 0.002236f, 0.000064f, 0.01054999f }, - { 0.002535385f, 0.00007234421f, 0.0119658f }, - { 0.002892603f, 0.00008221224f, 0.01365587f }, - { 0.003300829f, 0.00009350816f, 0.01558805f }, - { 0.003753236f, 0.0001061361f, 0.01773015f }, - { 0.004243f, 0.00012f, 0.02005001f }, - { 0.004762389f, 0.000134984f, 0.02251136f }, - { 0.005330048f, 0.000151492f, 0.02520288f }, - { 0.005978712f, 0.000170208f, 0.02827972f }, - { 0.006741117f, 0.000191816f, 0.03189704f }, - { 0.00765f, 0.000217f, 0.03621f }, - { 0.008751373f, 0.0002469067f, 0.04143771f }, - { 0.01002888f, 0.00028124f, 0.04750372f }, - { 0.0114217f, 0.00031852f, 0.05411988f }, - { 0.01286901f, 0.0003572667f, 0.06099803f }, - { 0.01431f, 0.000396f, 0.06785001f }, - { 0.01570443f, 0.0004337147f, 0.07448632f }, - { 0.01714744f, 0.000473024f, 0.08136156f }, - { 0.01878122f, 0.000517876f, 0.08915364f }, - { 0.02074801f, 0.0005722187f, 0.09854048f }, - { 0.02319f, 0.00064f, 0.1102f }, - { 0.02620736f, 0.00072456f, 0.1246133f }, - { 0.02978248f, 0.0008255f, 0.1417017f }, - { 0.03388092f, 0.00094116f, 0.1613035f }, - { 0.03846824f, 0.00106988f, 0.1832568f }, - { 0.04351f, 0.00121f, 0.2074f }, - { 0.0489956f, 0.001362091f, 0.2336921f }, - { 0.0550226f, 0.001530752f, 0.2626114f }, - { 0.0617188f, 0.001720368f, 0.2947746f }, - { 0.069212f, 0.001935323f, 0.3307985f }, - { 0.07763f, 0.00218f, 0.3713f }, - { 0.08695811f, 0.0024548f, 0.4162091f }, - { 0.09717672f, 0.002764f, 0.4654642f }, - { 0.1084063f, 0.0031178f, 0.5196948f }, - { 0.1207672f, 0.0035264f, 0.5795303f }, - { 0.13438f, 0.004f, 0.6456f }, - { 0.1493582f, 0.00454624f, 0.7184838f }, - { 0.1653957f, 0.00515932f, 0.7967133f }, - { 0.1819831f, 0.00582928f, 0.8778459f }, - { 0.198611f, 0.00654616f, 0.959439f }, - { 0.21477f, 0.0073f, 1.0390501f }, - { 0.2301868f, 0.008086507f, 1.1153673f }, - { 0.2448797f, 0.00890872f, 1.1884971f }, - { 0.2587773f, 0.00976768f, 1.2581233f }, - { 0.2718079f, 0.01066443f, 1.3239296f }, - { 0.2839f, 0.0116f, 1.3856f }, - { 0.2949438f, 0.01257317f, 1.4426352f }, - { 0.3048965f, 0.01358272f, 1.4948035f }, - { 0.3137873f, 0.01462968f, 1.5421903f }, - { 0.3216454f, 0.01571509f, 1.5848807f }, - { 0.3285f, 0.01684f, 1.62296f }, - { 0.3343513f, 0.01800736f, 1.6564048f }, - { 0.3392101f, 0.01921448f, 1.6852959f }, - { 0.3431213f, 0.02045392f, 1.7098745f }, - { 0.3461296f, 0.02171824f, 1.7303821f }, - { 0.34828f, 0.023f, 1.74706f }, - { 0.3495999f, 0.02429461f, 1.7600446f }, - { 0.3501474f, 0.02561024f, 1.7696233f }, - { 0.350013f, 0.02695857f, 1.7762637f }, - { 0.349287f, 0.02835125f, 1.7804334f }, - { 0.34806f, 0.0298f, 1.7826f }, - { 0.3463733f, 0.03131083f, 1.7829682f }, - { 0.3442624f, 0.03288368f, 1.7816998f }, - { 0.3418088f, 0.03452112f, 1.7791982f }, - { 0.3390941f, 0.03622571f, 1.7758671f }, - { 0.3362f, 0.038f, 1.77211f }, - { 0.3331977f, 0.03984667f, 1.7682589f }, - { 0.3300411f, 0.041768f, 1.764039f }, - { 0.3266357f, 0.043766f, 1.7589438f }, - { 0.3228868f, 0.04584267f, 1.7524663f }, - { 0.3187f, 0.048f, 1.7441f }, - { 0.3140251f, 0.05024368f, 1.7335595f }, - { 0.308884f, 0.05257304f, 1.7208581f }, - { 0.3032904f, 0.05498056f, 1.7059369f }, - { 0.2972579f, 0.05745872f, 1.6887372f }, - { 0.2908f, 0.06f, 1.6692f }, - { 0.2839701f, 0.06260197f, 1.6475287f }, - { 0.2767214f, 0.06527752f, 1.6234127f }, - { 0.2689178f, 0.06804208f, 1.5960223f }, - { 0.2604227f, 0.07091109f, 1.564528f }, - { 0.2511f, 0.0739f, 1.5281f }, - { 0.2408475f, 0.077016f, 1.4861114f }, - { 0.2298512f, 0.0802664f, 1.4395215f }, - { 0.2184072f, 0.0836668f, 1.3898799f }, - { 0.2068115f, 0.0872328f, 1.3387362f }, - { 0.19536f, 0.09098f, 1.28764f }, - { 0.1842136f, 0.09491755f, 1.2374223f }, - { 0.1733273f, 0.09904584f, 1.1878243f }, - { 0.1626881f, 0.1033674f, 1.1387611f }, - { 0.1522833f, 0.1078846f, 1.090148f }, - { 0.1421f, 0.1126f, 1.0419f }, - { 0.1321786f, 0.117532f, 0.9941976f }, - { 0.1225696f, 0.1226744f, 0.9473473f }, - { 0.1132752f, 0.1279928f, 0.9014531f }, - { 0.1042979f, 0.1334528f, 0.8566193f }, - { 0.09564f, 0.13902f, 0.8129501f }, - { 0.08729955f, 0.1446764f, 0.7705173f }, - { 0.07930804f, 0.1504693f, 0.7294448f }, - { 0.07171776f, 0.1564619f, 0.6899136f }, - { 0.06458099f, 0.1627177f, 0.6521049f }, - { 0.05795001f, 0.1693f, 0.6162f }, - { 0.05186211f, 0.1762431f, 0.5823286f }, - { 0.04628152f, 0.1835581f, 0.5504162f }, - { 0.04115088f, 0.1912735f, 0.5203376f }, - { 0.03641283f, 0.199418f, 0.4919673f }, - { 0.03201f, 0.20802f, 0.46518f }, - { 0.0279172f, 0.2171199f, 0.4399246f }, - { 0.0241444f, 0.2267345f, 0.4161836f }, - { 0.020687f, 0.2368571f, 0.3938822f }, - { 0.0175404f, 0.2474812f, 0.3729459f }, - { 0.0147f, 0.2586f, 0.3533f }, - { 0.01216179f, 0.2701849f, 0.3348578f }, - { 0.00991996f, 0.2822939f, 0.3175521f }, - { 0.00796724f, 0.2950505f, 0.3013375f }, - { 0.006296346f, 0.308578f, 0.2861686f }, - { 0.0049f, 0.323f, 0.272f }, - { 0.003777173f, 0.3384021f, 0.2588171f }, - { 0.00294532f, 0.3546858f, 0.2464838f }, - { 0.00242488f, 0.3716986f, 0.2347718f }, - { 0.002236293f, 0.3892875f, 0.2234533f }, - { 0.0024f, 0.4073f, 0.2123f }, - { 0.00292552f, 0.4256299f, 0.2011692f }, - { 0.00383656f, 0.4443096f, 0.1901196f }, - { 0.00517484f, 0.4633944f, 0.1792254f }, - { 0.00698208f, 0.4829395f, 0.1685608f }, - { 0.0093f, 0.503f, 0.1582f }, - { 0.01214949f, 0.5235693f, 0.1481383f }, - { 0.01553588f, 0.544512f, 0.1383758f }, - { 0.01947752f, 0.56569f, 0.1289942f }, - { 0.02399277f, 0.5869653f, 0.1200751f }, - { 0.0291f, 0.6082f, 0.1117f }, - { 0.03481485f, 0.6293456f, 0.1039048f }, - { 0.04112016f, 0.6503068f, 0.09666748f }, - { 0.04798504f, 0.6708752f, 0.08998272f }, - { 0.05537861f, 0.6908424f, 0.08384531f }, - { 0.06327f, 0.71f, 0.07824999f }, - { 0.07163501f, 0.7281852f, 0.07320899f }, - { 0.08046224f, 0.7454636f, 0.06867816f }, - { 0.08973996f, 0.7619694f, 0.06456784f }, - { 0.09945645f, 0.7778368f, 0.06078835f }, - { 0.1096f, 0.7932f, 0.05725001f }, - { 0.1201674f, 0.8081104f, 0.05390435f }, - { 0.1311145f, 0.8224962f, 0.05074664f }, - { 0.1423679f, 0.8363068f, 0.04775276f }, - { 0.1538542f, 0.8494916f, 0.04489859f }, - { 0.1655f, 0.862f, 0.04216f }, - { 0.1772571f, 0.8738108f, 0.03950728f }, - { 0.18914f, 0.8849624f, 0.03693564f }, - { 0.2011694f, 0.8954936f, 0.03445836f }, - { 0.2133658f, 0.9054432f, 0.03208872f }, - { 0.2257499f, 0.9148501f, 0.02984f }, - { 0.2383209f, 0.9237348f, 0.02771181f }, - { 0.2510668f, 0.9320924f, 0.02569444f }, - { 0.2639922f, 0.9399226f, 0.02378716f }, - { 0.2771017f, 0.9472252f, 0.02198925f }, - { 0.2904f, 0.954f, 0.0203f }, - { 0.3038912f, 0.9602561f, 0.01871805f }, - { 0.3175726f, 0.9660074f, 0.01724036f }, - { 0.3314384f, 0.9712606f, 0.01586364f }, - { 0.3454828f, 0.9760225f, 0.01458461f }, - { 0.3597f, 0.9803f, 0.0134f }, - { 0.3740839f, 0.9840924f, 0.01230723f }, - { 0.3886396f, 0.9874182f, 0.01130188f }, - { 0.4033784f, 0.9903128f, 0.01037792f }, - { 0.4183115f, 0.9928116f, 0.009529306f }, - { 0.4334499f, 0.9949501f, 0.008749999f }, - { 0.4487953f, 0.9967108f, 0.0080352f }, - { 0.464336f, 0.9980983f, 0.0073816f }, - { 0.480064f, 0.999112f, 0.0067854f }, - { 0.4959713f, 0.9997482f, 0.0062428f }, - { 0.5120501f, 1.0f, 0.005749999f }, - { 0.5282959f, 0.9998567f, 0.0053036f }, - { 0.5446916f, 0.9993046f, 0.0048998f }, - { 0.5612094f, 0.9983255f, 0.0045342f }, - { 0.5778215f, 0.9968987f, 0.0042024f }, - { 0.5945f, 0.995f, 0.0039f }, - { 0.6112209f, 0.9926005f, 0.0036232f }, - { 0.6279758f, 0.9897426f, 0.0033706f }, - { 0.6447602f, 0.9864444f, 0.0031414f }, - { 0.6615697f, 0.9827241f, 0.0029348f }, - { 0.6784f, 0.9786f, 0.002749999f }, - { 0.6952392f, 0.9740837f, 0.0025852f }, - { 0.7120586f, 0.9691712f, 0.0024386f }, - { 0.7288284f, 0.9638568f, 0.0023094f }, - { 0.7455188f, 0.9581349f, 0.0021968f }, - { 0.7621f, 0.952f, 0.0021f }, - { 0.7785432f, 0.9454504f, 0.002017733f }, - { 0.7948256f, 0.9384992f, 0.0019482f }, - { 0.8109264f, 0.9311628f, 0.0018898f }, - { 0.8268248f, 0.9234576f, 0.001840933f }, - { 0.8425f, 0.9154f, 0.0018f }, - { 0.8579325f, 0.9070064f, 0.001766267f }, - { 0.8730816f, 0.8982772f, 0.0017378f }, - { 0.8878944f, 0.8892048f, 0.0017112f }, - { 0.9023181f, 0.8797816f, 0.001683067f }, - { 0.9163f, 0.87f, 0.001650001f }, - { 0.9297995f, 0.8598613f, 0.001610133f }, - { 0.9427984f, 0.849392f, 0.0015644f }, - { 0.9552776f, 0.838622f, 0.0015136f }, - { 0.9672179f, 0.8275813f, 0.001458533f }, - { 0.9786f, 0.8163f, 0.0014f }, - { 0.9893856f, 0.8047947f, 0.001336667f }, - { 0.9995488f, 0.793082f, 0.00127f }, - { 1.0090892f, 0.781192f, 0.001205f }, - { 1.0180064f, 0.7691547f, 0.001146667f }, - { 1.0263f, 0.757f, 0.0011f }, - { 1.0339827f, 0.7447541f, 0.0010688f }, - { 1.040986f, 0.7324224f, 0.0010494f }, - { 1.047188f, 0.7200036f, 0.0010356f }, - { 1.0524667f, 0.7074965f, 0.0010212f }, - { 1.0567f, 0.6949f, 0.001f }, - { 1.0597944f, 0.6822192f, 0.00096864f }, - { 1.0617992f, 0.6694716f, 0.00092992f }, - { 1.0628068f, 0.6566744f, 0.00088688f }, - { 1.0629096f, 0.6438448f, 0.00084256f }, - { 1.0622f, 0.631f, 0.0008f }, - { 1.0607352f, 0.6181555f, 0.00076096f }, - { 1.0584436f, 0.6053144f, 0.00072368f }, - { 1.0552244f, 0.5924756f, 0.00068592f }, - { 1.0509768f, 0.5796379f, 0.00064544f }, - { 1.0456f, 0.5668f, 0.0006f }, - { 1.0390369f, 0.5539611f, 0.0005478667f }, - { 1.0313608f, 0.5411372f, 0.0004916f }, - { 1.0226662f, 0.5283528f, 0.0004354f }, - { 1.0130477f, 0.5156323f, 0.0003834667f }, - { 1.0026f, 0.503f, 0.00034f }, - { 0.9913675f, 0.4904688f, 0.0003072533f }, - { 0.9793314f, 0.4780304f, 0.00028316f }, - { 0.9664916f, 0.4656776f, 0.00026544f }, - { 0.9528479f, 0.4534032f, 0.0002518133f }, - { 0.9384f, 0.4412f, 0.00024f }, - { 0.923194f, 0.42908f, 0.0002295467f }, - { 0.907244f, 0.417036f, 0.00022064f }, - { 0.890502f, 0.405032f, 0.00021196f }, - { 0.87292f, 0.393032f, 0.0002021867f }, - { 0.8544499f, 0.381f, 0.00019f }, - { 0.835084f, 0.3689184f, 0.0001742133f }, - { 0.814946f, 0.3568272f, 0.00015564f }, - { 0.794186f, 0.3447768f, 0.00013596f }, - { 0.772954f, 0.3328176f, 0.0001168533f }, - { 0.7514f, 0.321f, 0.0001f }, - { 0.7295836f, 0.3093381f, 0.00008613333f }, - { 0.7075888f, 0.2978504f, 0.0000746f }, - { 0.6856022f, 0.2865936f, 0.000065f }, - { 0.6638104f, 0.2756245f, 0.00005693333f }, - { 0.6424f, 0.265f, 0.00004999999f }, - { 0.6215149f, 0.2547632f, 0.00004416f }, - { 0.6011138f, 0.2448896f, 0.00003948f }, - { 0.5811052f, 0.2353344f, 0.00003572f }, - { 0.5613977f, 0.2260528f, 0.00003264f }, - { 0.5419f, 0.217f, 0.00003f }, - { 0.5225995f, 0.2081616f, 0.00002765333f }, - { 0.5035464f, 0.1995488f, 0.00002556f }, - { 0.4847436f, 0.1911552f, 0.00002364f }, - { 0.4661939f, 0.1829744f, 0.00002181333f }, - { 0.4479f, 0.175f, 0.00002f }, - { 0.4298613f, 0.1672235f, 0.00001813333f }, - { 0.412098f, 0.1596464f, 0.0000162f }, - { 0.394644f, 0.1522776f, 0.0000142f }, - { 0.3775333f, 0.1451259f, 0.00001213333f }, - { 0.3608f, 0.1382f, 0.00001f }, - { 0.3444563f, 0.1315003f, 0.000007733333f }, - { 0.3285168f, 0.1250248f, 0.0000054f }, - { 0.3130192f, 0.1187792f, 0.0000032f }, - { 0.2980011f, 0.1127691f, 0.000001333333f }, - { 0.2835f, 0.107f, 0.0f }, - { 0.2695448f, 0.1014762f, 0.0f }, - { 0.2561184f, 0.09618864f, 0.0f }, - { 0.2431896f, 0.09112296f, 0.0f }, - { 0.2307272f, 0.08626485f, 0.0f }, - { 0.2187f, 0.0816f, 0.0f }, - { 0.2070971f, 0.07712064f, 0.0f }, - { 0.1959232f, 0.07282552f, 0.0f }, - { 0.1851708f, 0.06871008f, 0.0f }, - { 0.1748323f, 0.06476976f, 0.0f }, - { 0.1649f, 0.061f, 0.0f }, - { 0.1553667f, 0.05739621f, 0.0f }, - { 0.14623f, 0.05395504f, 0.0f }, - { 0.13749f, 0.05067376f, 0.0f }, - { 0.1291467f, 0.04754965f, 0.0f }, - { 0.1212f, 0.04458f, 0.0f }, - { 0.1136397f, 0.04175872f, 0.0f }, - { 0.106465f, 0.03908496f, 0.0f }, - { 0.09969044f, 0.03656384f, 0.0f }, - { 0.09333061f, 0.03420048f, 0.0f }, - { 0.0874f, 0.032f, 0.0f }, - { 0.08190096f, 0.02996261f, 0.0f }, - { 0.07680428f, 0.02807664f, 0.0f }, - { 0.07207712f, 0.02632936f, 0.0f }, - { 0.06768664f, 0.02470805f, 0.0f }, - { 0.0636f, 0.0232f, 0.0f }, - { 0.05980685f, 0.02180077f, 0.0f }, - { 0.05628216f, 0.02050112f, 0.0f }, - { 0.05297104f, 0.01928108f, 0.0f }, - { 0.04981861f, 0.01812069f, 0.0f }, - { 0.04677f, 0.017f, 0.0f }, - { 0.04378405f, 0.01590379f, 0.0f }, - { 0.04087536f, 0.01483718f, 0.0f }, - { 0.03807264f, 0.01381068f, 0.0f }, - { 0.03540461f, 0.01283478f, 0.0f }, - { 0.0329f, 0.01192f, 0.0f }, - { 0.03056419f, 0.01106831f, 0.0f }, - { 0.02838056f, 0.01027339f, 0.0f }, - { 0.02634484f, 0.009533311f, 0.0f }, - { 0.02445275f, 0.008846157f, 0.0f }, - { 0.0227f, 0.00821f, 0.0f }, - { 0.02108429f, 0.007623781f, 0.0f }, - { 0.01959988f, 0.007085424f, 0.0f }, - { 0.01823732f, 0.006591476f, 0.0f }, - { 0.01698717f, 0.006138485f, 0.0f }, - { 0.01584f, 0.005723f, 0.0f }, - { 0.01479064f, 0.005343059f, 0.0f }, - { 0.01383132f, 0.004995796f, 0.0f }, - { 0.01294868f, 0.004676404f, 0.0f }, - { 0.0121292f, 0.004380075f, 0.0f }, - { 0.01135916f, 0.004102f, 0.0f }, - { 0.01062935f, 0.003838453f, 0.0f }, - { 0.009938846f, 0.003589099f, 0.0f }, - { 0.009288422f, 0.003354219f, 0.0f }, - { 0.008678854f, 0.003134093f, 0.0f }, - { 0.008110916f, 0.002929f, 0.0f }, - { 0.007582388f, 0.002738139f, 0.0f }, - { 0.007088746f, 0.002559876f, 0.0f }, - { 0.006627313f, 0.002393244f, 0.0f }, - { 0.006195408f, 0.002237275f, 0.0f }, - { 0.005790346f, 0.002091f, 0.0f }, - { 0.005409826f, 0.001953587f, 0.0f }, - { 0.005052583f, 0.00182458f, 0.0f }, - { 0.004717512f, 0.00170358f, 0.0f }, - { 0.004403507f, 0.001590187f, 0.0f }, - { 0.004109457f, 0.001484f, 0.0f }, - { 0.003833913f, 0.001384496f, 0.0f }, - { 0.003575748f, 0.001291268f, 0.0f }, - { 0.003334342f, 0.001204092f, 0.0f }, - { 0.003109075f, 0.001122744f, 0.0f }, - { 0.002899327f, 0.001047f, 0.0f }, - { 0.002704348f, 0.0009765896f, 0.0f }, - { 0.00252302f, 0.0009111088f, 0.0f }, - { 0.002354168f, 0.0008501332f, 0.0f }, - { 0.002196616f, 0.0007932384f, 0.0f }, - { 0.00204919f, 0.00074f, 0.0f }, - { 0.00191096f, 0.0006900827f, 0.0f }, - { 0.001781438f, 0.00064331f, 0.0f }, - { 0.00166011f, 0.000599496f, 0.0f }, - { 0.001546459f, 0.0005584547f, 0.0f }, - { 0.001439971f, 0.00052f, 0.0f }, - { 0.001340042f, 0.0004839136f, 0.0f }, - { 0.001246275f, 0.0004500528f, 0.0f }, - { 0.001158471f, 0.0004183452f, 0.0f }, - { 0.00107643f, 0.0003887184f, 0.0f }, - { 0.0009999493f, 0.0003611f, 0.0f }, - { 0.0009287358f, 0.0003353835f, 0.0f }, - { 0.0008624332f, 0.0003114404f, 0.0f }, - { 0.0008007503f, 0.0002891656f, 0.0f }, - { 0.000743396f, 0.0002684539f, 0.0f }, - { 0.0006900786f, 0.0002492f, 0.0f }, - { 0.0006405156f, 0.0002313019f, 0.0f }, - { 0.0005945021f, 0.0002146856f, 0.0f }, - { 0.0005518646f, 0.0001992884f, 0.0f }, - { 0.000512429f, 0.0001850475f, 0.0f }, - { 0.0004760213f, 0.0001719f, 0.0f }, - { 0.0004424536f, 0.0001597781f, 0.0f }, - { 0.0004115117f, 0.0001486044f, 0.0f }, - { 0.0003829814f, 0.0001383016f, 0.0f }, - { 0.0003566491f, 0.0001287925f, 0.0f }, - { 0.0003323011f, 0.00012f, 0.0f }, - { 0.0003097586f, 0.0001118595f, 0.0f }, - { 0.0002888871f, 0.0001043224f, 0.0f }, - { 0.0002695394f, 0.0000973356f, 0.0f }, - { 0.0002515682f, 0.00009084587f, 0.0f }, - { 0.0002348261f, 0.0000848f, 0.0f }, - { 0.000219171f, 0.00007914667f, 0.0f }, - { 0.0002045258f, 0.000073858f, 0.0f }, - { 0.0001908405f, 0.000068916f, 0.0f }, - { 0.0001780654f, 0.00006430267f, 0.0f }, - { 0.0001661505f, 0.00006f, 0.0f }, - { 0.0001550236f, 0.00005598187f, 0.0f }, - { 0.0001446219f, 0.0000522256f, 0.0f }, - { 0.0001349098f, 0.0000487184f, 0.0f }, - { 0.000125852f, 0.00004544747f, 0.0f }, - { 0.000117413f, 0.0000424f, 0.0f }, - { 0.0001095515f, 0.00003956104f, 0.0f }, - { 0.0001022245f, 0.00003691512f, 0.0f }, - { 0.00009539445f, 0.00003444868f, 0.0f }, - { 0.0000890239f, 0.00003214816f, 0.0f }, - { 0.00008307527f, 0.00003f, 0.0f }, - { 0.00007751269f, 0.00002799125f, 0.0f }, - { 0.00007231304f, 0.00002611356f, 0.0f }, - { 0.00006745778f, 0.00002436024f, 0.0f }, - { 0.00006292844f, 0.00002272461f, 0.0f }, - { 0.00005870652f, 0.0000212f, 0.0f }, - { 0.00005477028f, 0.00001977855f, 0.0f }, - { 0.00005109918f, 0.00001845285f, 0.0f }, - { 0.00004767654f, 0.00001721687f, 0.0f }, - { 0.00004448567f, 0.00001606459f, 0.0f }, - { 0.00004150994f, 0.00001499f, 0.0f }, - { 0.00003873324f, 0.00001398728f, 0.0f }, - { 0.00003614203f, 0.00001305155f, 0.0f }, - { 0.00003372352f, 0.00001217818f, 0.0f }, - { 0.00003146487f, 0.00001136254f, 0.0f }, - { 0.00002935326f, 0.0000106f, 0.0f }, - { 0.00002737573f, 0.000009885877f, 0.0f }, - { 0.00002552433f, 0.000009217304f, 0.0f }, - { 0.00002379376f, 0.000008592362f, 0.0f }, - { 0.0000221787f, 0.000008009133f, 0.0f }, - { 0.00002067383f, 0.0000074657f, 0.0f }, - { 0.00001927226f, 0.000006959567f, 0.0f }, - { 0.0000179664f, 0.000006487995f, 0.0f }, - { 0.00001674991f, 0.000006048699f, 0.0f }, - { 0.00001561648f, 0.000005639396f, 0.0f }, - { 0.00001455977f, 0.0000052578f, 0.0f }, - { 0.00001357387f, 0.000004901771f, 0.0f }, - { 0.00001265436f, 0.00000456972f, 0.0f }, - { 0.00001179723f, 0.000004260194f, 0.0f }, - { 0.00001099844f, 0.000003971739f, 0.0f }, - { 0.00001025398f, 0.0000037029f, 0.0f }, - { 0.000009559646f, 0.000003452163f, 0.0f }, - { 0.000008912044f, 0.000003218302f, 0.0f }, - { 0.000008308358f, 0.0000030003f, 0.0f }, - { 0.000007745769f, 0.000002797139f, 0.0f }, - { 0.000007221456f, 0.0000026078f, 0.0f }, - { 0.000006732475f, 0.00000243122f, 0.0f }, - { 0.000006276423f, 0.000002266531f, 0.0f }, - { 0.000005851304f, 0.000002113013f, 0.0f }, - { 0.000005455118f, 0.000001969943f, 0.0f }, - { 0.000005085868f, 0.0000018366f, 0.0f }, - { 0.000004741466f, 0.00000171223f, 0.0f }, - { 0.000004420236f, 0.000001596228f, 0.0f }, - { 0.000004120783f, 0.00000148809f, 0.0f }, - { 0.000003841716f, 0.000001387314f, 0.0f }, - { 0.000003581652f, 0.0000012934f, 0.0f }, - { 0.000003339127f, 0.00000120582f, 0.0f }, - { 0.000003112949f, 0.000001124143f, 0.0f }, - { 0.000002902121f, 0.000001048009f, 0.0f }, - { 0.000002705645f, 0.000000977058f, 0.0f }, - { 0.000002522525f, 0.00000091093f, 0.0f }, - { 0.000002351726f, 0.000000849251f, 0.0f }, - { 0.000002192415f, 0.000000791721f, 0.0f }, - { 0.000002043902f, 0.00000073809f, 0.0f }, - { 0.000001905497f, 0.00000068811f, 0.0f }, - { 0.000001776509f, 0.00000064153f, 0.0f }, - { 0.000001656215f, 0.00000059809f, 0.0f }, - { 0.000001544022f, 0.000000557575f, 0.0f }, - { 0.00000143944f, 0.000000519808f, 0.0f }, - { 0.000001341977f, 0.000000484612f, 0.0f }, - { 0.000001251141f, 0.00000045181f, 0.0f } + { 0.000000122200f, 0.000000013398f, 0.000000535027f }, + { 0.000000185138f, 0.000000020294f, 0.000000810720f }, + { 0.000000278830f, 0.000000030560f, 0.000001221200f }, + { 0.000000417470f, 0.000000045740f, 0.000001828700f }, + { 0.000000621330f, 0.000000068050f, 0.000002722200f }, + { 0.000000919270f, 0.000000100650f, 0.000004028300f }, + { 0.000001351980f, 0.000000147980f, 0.000005925700f }, + { 0.000001976540f, 0.000000216270f, 0.000008665100f }, + { 0.000002872500f, 0.000000314200f, 0.000012596000f }, + { 0.000004149500f, 0.000000453700f, 0.000018201000f }, + { 0.000005958600f, 0.000000651100f, 0.000026143700f }, + { 0.000008505600f, 0.000000928800f, 0.000037330000f }, + { 0.000012068600f, 0.000001317500f, 0.000052987000f }, + { 0.000017022600f, 0.000001857200f, 0.000074764000f }, + { 0.000023868000f, 0.000002602000f, 0.000104870000f }, + { 0.000033266000f, 0.000003625000f, 0.000146220000f }, + { 0.000046087000f, 0.000005019000f, 0.000202660000f }, + { 0.000063472000f, 0.000006907000f, 0.000279230000f }, + { 0.000086892000f, 0.000009449000f, 0.000382450000f }, + { 0.000118246000f, 0.000012848000f, 0.000520720000f }, + { 0.000159952000f, 0.000017364000f, 0.000704776000f }, + { 0.000215080000f, 0.000023327000f, 0.000948230000f }, + { 0.000287490000f, 0.000031150000f, 0.001268200000f }, + { 0.000381990000f, 0.000041350000f, 0.001686100000f }, + { 0.000504550000f, 0.000054560000f, 0.002228500000f }, + { 0.000662440000f, 0.000071560000f, 0.002927800000f }, + { 0.000864500000f, 0.000093300000f, 0.003823700000f }, + { 0.001121500000f, 0.000120870000f, 0.004964200000f }, + { 0.001446160000f, 0.000155640000f, 0.006406700000f }, + { 0.001853590000f, 0.000199200000f, 0.008219300000f }, + { 0.002361600000f, 0.000253400000f, 0.010482200000f }, + { 0.002990600000f, 0.000320200000f, 0.013289000000f }, + { 0.003764500000f, 0.000402400000f, 0.016747000000f }, + { 0.004710200000f, 0.000502300000f, 0.020980000000f }, + { 0.005858100000f, 0.000623200000f, 0.026127000000f }, + { 0.007242300000f, 0.000768500000f, 0.032344000000f }, + { 0.008899600000f, 0.000941700000f, 0.039802000000f }, + { 0.010870900000f, 0.001147800000f, 0.048691000000f }, + { 0.013198900000f, 0.001390300000f, 0.059210000000f }, + { 0.015929200000f, 0.001674000000f, 0.071576000000f }, + { 0.019109700000f, 0.002004400000f, 0.086010900000f }, + { 0.022788000000f, 0.002386000000f, 0.102740000000f }, + { 0.027011000000f, 0.002822000000f, 0.122000000000f }, + { 0.031829000000f, 0.003319000000f, 0.144020000000f }, + { 0.037278000000f, 0.003880000000f, 0.168990000000f }, + { 0.043400000000f, 0.004509000000f, 0.197120000000f }, + { 0.050223000000f, 0.005209000000f, 0.228570000000f }, + { 0.057764000000f, 0.005985000000f, 0.263470000000f }, + { 0.066038000000f, 0.006833000000f, 0.301900000000f }, + { 0.075033000000f, 0.007757000000f, 0.343870000000f }, + { 0.084736000000f, 0.008756000000f, 0.389366000000f }, + { 0.095041000000f, 0.009816000000f, 0.437970000000f }, + { 0.105836000000f, 0.010918000000f, 0.489220000000f }, + { 0.117066000000f, 0.012058000000f, 0.542900000000f }, + { 0.128682000000f, 0.013237000000f, 0.598810000000f }, + { 0.140638000000f, 0.014456000000f, 0.656760000000f }, + { 0.152893000000f, 0.015717000000f, 0.716580000000f }, + { 0.165416000000f, 0.017025000000f, 0.778120000000f }, + { 0.178191000000f, 0.018399000000f, 0.841310000000f }, + { 0.191214000000f, 0.019848000000f, 0.906110000000f }, + { 0.204492000000f, 0.021391000000f, 0.972542000000f }, + { 0.217650000000f, 0.022992000000f, 1.038900000000f }, + { 0.230267000000f, 0.024598000000f, 1.103100000000f }, + { 0.242311000000f, 0.026213000000f, 1.165100000000f }, + { 0.253793000000f, 0.027841000000f, 1.224900000000f }, + { 0.264737000000f, 0.029497000000f, 1.282500000000f }, + { 0.275195000000f, 0.031195000000f, 1.338200000000f }, + { 0.285301000000f, 0.032927000000f, 1.392600000000f }, + { 0.295143000000f, 0.034738000000f, 1.446100000000f }, + { 0.304869000000f, 0.036654000000f, 1.499400000000f }, + { 0.314679000000f, 0.038676000000f, 1.553480000000f }, + { 0.324355000000f, 0.040792000000f, 1.607200000000f }, + { 0.333570000000f, 0.042946000000f, 1.658900000000f }, + { 0.342243000000f, 0.045114000000f, 1.708200000000f }, + { 0.350312000000f, 0.047333000000f, 1.754800000000f }, + { 0.357719000000f, 0.049602000000f, 1.798500000000f }, + { 0.364482000000f, 0.051934000000f, 1.839200000000f }, + { 0.370493000000f, 0.054337000000f, 1.876600000000f }, + { 0.375727000000f, 0.056822000000f, 1.910500000000f }, + { 0.380158000000f, 0.059399000000f, 1.940800000000f }, + { 0.383734000000f, 0.062077000000f, 1.967280000000f }, + { 0.386327000000f, 0.064737000000f, 1.989100000000f }, + { 0.387858000000f, 0.067285000000f, 2.005700000000f }, + { 0.388396000000f, 0.069764000000f, 2.017400000000f }, + { 0.387978000000f, 0.072218000000f, 2.024400000000f }, + { 0.386726000000f, 0.074704000000f, 2.027300000000f }, + { 0.384696000000f, 0.077272000000f, 2.026400000000f }, + { 0.382006000000f, 0.079979000000f, 2.022300000000f }, + { 0.378709000000f, 0.082874000000f, 2.015300000000f }, + { 0.374915000000f, 0.086000000000f, 2.006000000000f }, + { 0.370702000000f, 0.089456000000f, 1.994800000000f }, + { 0.366089000000f, 0.092947000000f, 1.981400000000f }, + { 0.361045000000f, 0.096275000000f, 1.965300000000f }, + { 0.355518000000f, 0.099535000000f, 1.946400000000f }, + { 0.349486000000f, 0.102829000000f, 1.924800000000f }, + { 0.342957000000f, 0.106256000000f, 1.900700000000f }, + { 0.335893000000f, 0.109901000000f, 1.874100000000f }, + { 0.328284000000f, 0.113835000000f, 1.845100000000f }, + { 0.320150000000f, 0.118167000000f, 1.813900000000f }, + { 0.311475000000f, 0.122932000000f, 1.780600000000f }, + { 0.302273000000f, 0.128201000000f, 1.745370000000f }, + { 0.292858000000f, 0.133457000000f, 1.709100000000f }, + { 0.283502000000f, 0.138323000000f, 1.672300000000f }, + { 0.274044000000f, 0.143042000000f, 1.634700000000f }, + { 0.264263000000f, 0.147787000000f, 1.595600000000f }, + { 0.254085000000f, 0.152761000000f, 1.554900000000f }, + { 0.243392000000f, 0.158102000000f, 1.512200000000f }, + { 0.232187000000f, 0.163941000000f, 1.467300000000f }, + { 0.220488000000f, 0.170362000000f, 1.419900000000f }, + { 0.208198000000f, 0.177425000000f, 1.370000000000f }, + { 0.195618000000f, 0.185190000000f, 1.317560000000f }, + { 0.183034000000f, 0.193025000000f, 1.262400000000f }, + { 0.170222000000f, 0.200313000000f, 1.205000000000f }, + { 0.157348000000f, 0.207156000000f, 1.146600000000f }, + { 0.144650000000f, 0.213644000000f, 1.088000000000f }, + { 0.132349000000f, 0.219940000000f, 1.030200000000f }, + { 0.120584000000f, 0.226170000000f, 0.973830000000f }, + { 0.109456000000f, 0.232467000000f, 0.919430000000f }, + { 0.099042000000f, 0.239025000000f, 0.867460000000f }, + { 0.089388000000f, 0.245997000000f, 0.818280000000f }, + { 0.080507000000f, 0.253589000000f, 0.772125000000f }, + { 0.072034000000f, 0.261876000000f, 0.728290000000f }, + { 0.063710000000f, 0.270643000000f, 0.686040000000f }, + { 0.055694000000f, 0.279645000000f, 0.645530000000f }, + { 0.048117000000f, 0.288694000000f, 0.606850000000f }, + { 0.041072000000f, 0.297665000000f, 0.570060000000f }, + { 0.034642000000f, 0.306469000000f, 0.535220000000f }, + { 0.028896000000f, 0.315035000000f, 0.502340000000f }, + { 0.023876000000f, 0.323335000000f, 0.471400000000f }, + { 0.019628000000f, 0.331366000000f, 0.442390000000f }, + { 0.016172000000f, 0.339133000000f, 0.415254000000f }, + { 0.013300000000f, 0.347860000000f, 0.390024000000f }, + { 0.010759000000f, 0.358326000000f, 0.366399000000f }, + { 0.008542000000f, 0.370001000000f, 0.344015000000f }, + { 0.006661000000f, 0.382464000000f, 0.322689000000f }, + { 0.005132000000f, 0.395379000000f, 0.302356000000f }, + { 0.003982000000f, 0.408482000000f, 0.283036000000f }, + { 0.003239000000f, 0.421588000000f, 0.264816000000f }, + { 0.002934000000f, 0.434619000000f, 0.247848000000f }, + { 0.003114000000f, 0.447601000000f, 0.232318000000f }, + { 0.003816000000f, 0.460777000000f, 0.218502000000f }, + { 0.005095000000f, 0.474340000000f, 0.205851000000f }, + { 0.006936000000f, 0.488200000000f, 0.193596000000f }, + { 0.009299000000f, 0.502340000000f, 0.181736000000f }, + { 0.012147000000f, 0.516740000000f, 0.170281000000f }, + { 0.015444000000f, 0.531360000000f, 0.159249000000f }, + { 0.019156000000f, 0.546190000000f, 0.148673000000f }, + { 0.023250000000f, 0.561180000000f, 0.138609000000f }, + { 0.027690000000f, 0.576290000000f, 0.129096000000f }, + { 0.032444000000f, 0.591500000000f, 0.120215000000f }, + { 0.037465000000f, 0.606741000000f, 0.112044000000f }, + { 0.042956000000f, 0.622150000000f, 0.104710000000f }, + { 0.049114000000f, 0.637830000000f, 0.098196000000f }, + { 0.055920000000f, 0.653710000000f, 0.092361000000f }, + { 0.063349000000f, 0.669680000000f, 0.087088000000f }, + { 0.071358000000f, 0.685660000000f, 0.082248000000f }, + { 0.079901000000f, 0.701550000000f, 0.077744000000f }, + { 0.088909000000f, 0.717230000000f, 0.073456000000f }, + { 0.098293000000f, 0.732570000000f, 0.069268000000f }, + { 0.107949000000f, 0.747460000000f, 0.065060000000f }, + { 0.117749000000f, 0.761757000000f, 0.060709000000f }, + { 0.127839000000f, 0.775340000000f, 0.056457000000f }, + { 0.138450000000f, 0.788220000000f, 0.052609000000f }, + { 0.149516000000f, 0.800460000000f, 0.049122000000f }, + { 0.161041000000f, 0.812140000000f, 0.045954000000f }, + { 0.172953000000f, 0.823330000000f, 0.043050000000f }, + { 0.185209000000f, 0.834120000000f, 0.040368000000f }, + { 0.197755000000f, 0.844600000000f, 0.037839000000f }, + { 0.210538000000f, 0.854870000000f, 0.035384000000f }, + { 0.223460000000f, 0.865040000000f, 0.032949000000f }, + { 0.236491000000f, 0.875211000000f, 0.030451000000f }, + { 0.249633000000f, 0.885370000000f, 0.028029000000f }, + { 0.262972000000f, 0.895370000000f, 0.025862000000f }, + { 0.276515000000f, 0.905150000000f, 0.023920000000f }, + { 0.290269000000f, 0.914650000000f, 0.022174000000f }, + { 0.304213000000f, 0.923810000000f, 0.020584000000f }, + { 0.318361000000f, 0.932550000000f, 0.019127000000f }, + { 0.332705000000f, 0.940810000000f, 0.017740000000f }, + { 0.347232000000f, 0.948520000000f, 0.016403000000f }, + { 0.361926000000f, 0.955600000000f, 0.015064000000f }, + { 0.376772000000f, 0.961988000000f, 0.013676000000f }, + { 0.391683000000f, 0.967540000000f, 0.012308000000f }, + { 0.406594000000f, 0.972230000000f, 0.011056000000f }, + { 0.421539000000f, 0.976170000000f, 0.009915000000f }, + { 0.436517000000f, 0.979460000000f, 0.008872000000f }, + { 0.451584000000f, 0.982200000000f, 0.007918000000f }, + { 0.466782000000f, 0.984520000000f, 0.007030000000f }, + { 0.482147000000f, 0.986520000000f, 0.006223000000f }, + { 0.497738000000f, 0.988320000000f, 0.005453000000f }, + { 0.513606000000f, 0.990020000000f, 0.004714000000f }, + { 0.529826000000f, 0.991761000000f, 0.003988000000f }, + { 0.546440000000f, 0.993530000000f, 0.003289000000f }, + { 0.563426000000f, 0.995230000000f, 0.002646000000f }, + { 0.580726000000f, 0.996770000000f, 0.002063000000f }, + { 0.598290000000f, 0.998090000000f, 0.001533000000f }, + { 0.616053000000f, 0.999110000000f, 0.001091000000f }, + { 0.633948000000f, 0.999770000000f, 0.000711000000f }, + { 0.651901000000f, 1.000000000000f, 0.000407000000f }, + { 0.669824000000f, 0.999710000000f, 0.000184000000f }, + { 0.687632000000f, 0.998850000000f, 0.000047000000f }, + { 0.705224000000f, 0.997340000000f, 0.000000000000f }, + { 0.722773000000f, 0.995260000000f, 0.000000000000f }, + { 0.740483000000f, 0.992740000000f, 0.000000000000f }, + { 0.758273000000f, 0.989750000000f, 0.000000000000f }, + { 0.776083000000f, 0.986300000000f, 0.000000000000f }, + { 0.793832000000f, 0.982380000000f, 0.000000000000f }, + { 0.811436000000f, 0.977980000000f, 0.000000000000f }, + { 0.828822000000f, 0.973110000000f, 0.000000000000f }, + { 0.845879000000f, 0.967740000000f, 0.000000000000f }, + { 0.862525000000f, 0.961890000000f, 0.000000000000f }, + { 0.878655000000f, 0.955552000000f, 0.000000000000f }, + { 0.894208000000f, 0.948601000000f, 0.000000000000f }, + { 0.909206000000f, 0.940981000000f, 0.000000000000f }, + { 0.923672000000f, 0.932798000000f, 0.000000000000f }, + { 0.937638000000f, 0.924158000000f, 0.000000000000f }, + { 0.951162000000f, 0.915175000000f, 0.000000000000f }, + { 0.964283000000f, 0.905954000000f, 0.000000000000f }, + { 0.977068000000f, 0.896608000000f, 0.000000000000f }, + { 0.989590000000f, 0.887249000000f, 0.000000000000f }, + { 1.001910000000f, 0.877986000000f, 0.000000000000f }, + { 1.014160000000f, 0.868934000000f, 0.000000000000f }, + { 1.026500000000f, 0.860164000000f, 0.000000000000f }, + { 1.038800000000f, 0.851519000000f, 0.000000000000f }, + { 1.051000000000f, 0.842963000000f, 0.000000000000f }, + { 1.062900000000f, 0.834393000000f, 0.000000000000f }, + { 1.074300000000f, 0.825623000000f, 0.000000000000f }, + { 1.085200000000f, 0.816764000000f, 0.000000000000f }, + { 1.095200000000f, 0.807544000000f, 0.000000000000f }, + { 1.104200000000f, 0.797947000000f, 0.000000000000f }, + { 1.112000000000f, 0.787893000000f, 0.000000000000f }, + { 1.118520000000f, 0.777405000000f, 0.000000000000f }, + { 1.123800000000f, 0.766490000000f, 0.000000000000f }, + { 1.128000000000f, 0.755309000000f, 0.000000000000f }, + { 1.131100000000f, 0.743845000000f, 0.000000000000f }, + { 1.133200000000f, 0.732190000000f, 0.000000000000f }, + { 1.134300000000f, 0.720353000000f, 0.000000000000f }, + { 1.134300000000f, 0.708281000000f, 0.000000000000f }, + { 1.133300000000f, 0.696055000000f, 0.000000000000f }, + { 1.131200000000f, 0.683621000000f, 0.000000000000f }, + { 1.128100000000f, 0.671048000000f, 0.000000000000f }, + { 1.123990000000f, 0.658341000000f, 0.000000000000f }, + { 1.118900000000f, 0.645545000000f, 0.000000000000f }, + { 1.112900000000f, 0.632718000000f, 0.000000000000f }, + { 1.105900000000f, 0.619815000000f, 0.000000000000f }, + { 1.098000000000f, 0.606887000000f, 0.000000000000f }, + { 1.089100000000f, 0.593878000000f, 0.000000000000f }, + { 1.079200000000f, 0.580781000000f, 0.000000000000f }, + { 1.068400000000f, 0.567653000000f, 0.000000000000f }, + { 1.056700000000f, 0.554490000000f, 0.000000000000f }, + { 1.044000000000f, 0.541228000000f, 0.000000000000f }, + { 1.030480000000f, 0.527963000000f, 0.000000000000f }, + { 1.016000000000f, 0.514634000000f, 0.000000000000f }, + { 1.000800000000f, 0.501363000000f, 0.000000000000f }, + { 0.984790000000f, 0.488124000000f, 0.000000000000f }, + { 0.968080000000f, 0.474935000000f, 0.000000000000f }, + { 0.950740000000f, 0.461834000000f, 0.000000000000f }, + { 0.932800000000f, 0.448823000000f, 0.000000000000f }, + { 0.914340000000f, 0.435917000000f, 0.000000000000f }, + { 0.895390000000f, 0.423153000000f, 0.000000000000f }, + { 0.876030000000f, 0.410526000000f, 0.000000000000f }, + { 0.856297000000f, 0.398057000000f, 0.000000000000f }, + { 0.836350000000f, 0.385835000000f, 0.000000000000f }, + { 0.816290000000f, 0.373951000000f, 0.000000000000f }, + { 0.796050000000f, 0.362311000000f, 0.000000000000f }, + { 0.775610000000f, 0.350863000000f, 0.000000000000f }, + { 0.754930000000f, 0.339554000000f, 0.000000000000f }, + { 0.733990000000f, 0.328309000000f, 0.000000000000f }, + { 0.712780000000f, 0.317118000000f, 0.000000000000f }, + { 0.691290000000f, 0.305936000000f, 0.000000000000f }, + { 0.669520000000f, 0.294737000000f, 0.000000000000f }, + { 0.647467000000f, 0.283493000000f, 0.000000000000f }, + { 0.625110000000f, 0.272222000000f, 0.000000000000f }, + { 0.602520000000f, 0.260990000000f, 0.000000000000f }, + { 0.579890000000f, 0.249877000000f, 0.000000000000f }, + { 0.557370000000f, 0.238946000000f, 0.000000000000f }, + { 0.535110000000f, 0.228254000000f, 0.000000000000f }, + { 0.513240000000f, 0.217853000000f, 0.000000000000f }, + { 0.491860000000f, 0.207780000000f, 0.000000000000f }, + { 0.471080000000f, 0.198072000000f, 0.000000000000f }, + { 0.450960000000f, 0.188748000000f, 0.000000000000f }, + { 0.431567000000f, 0.179828000000f, 0.000000000000f }, + { 0.412870000000f, 0.171285000000f, 0.000000000000f }, + { 0.394750000000f, 0.163059000000f, 0.000000000000f }, + { 0.377210000000f, 0.155151000000f, 0.000000000000f }, + { 0.360190000000f, 0.147535000000f, 0.000000000000f }, + { 0.343690000000f, 0.140211000000f, 0.000000000000f }, + { 0.327690000000f, 0.133170000000f, 0.000000000000f }, + { 0.312170000000f, 0.126400000000f, 0.000000000000f }, + { 0.297110000000f, 0.119892000000f, 0.000000000000f }, + { 0.282500000000f, 0.113640000000f, 0.000000000000f }, + { 0.268329000000f, 0.107633000000f, 0.000000000000f }, + { 0.254590000000f, 0.101870000000f, 0.000000000000f }, + { 0.241300000000f, 0.096347000000f, 0.000000000000f }, + { 0.228480000000f, 0.091063000000f, 0.000000000000f }, + { 0.216140000000f, 0.086010000000f, 0.000000000000f }, + { 0.204300000000f, 0.081187000000f, 0.000000000000f }, + { 0.192950000000f, 0.076583000000f, 0.000000000000f }, + { 0.182110000000f, 0.072198000000f, 0.000000000000f }, + { 0.171770000000f, 0.068024000000f, 0.000000000000f }, + { 0.161920000000f, 0.064052000000f, 0.000000000000f }, + { 0.152568000000f, 0.060281000000f, 0.000000000000f }, + { 0.143670000000f, 0.056697000000f, 0.000000000000f }, + { 0.135200000000f, 0.053292000000f, 0.000000000000f }, + { 0.127130000000f, 0.050059000000f, 0.000000000000f }, + { 0.119480000000f, 0.046998000000f, 0.000000000000f }, + { 0.112210000000f, 0.044096000000f, 0.000000000000f }, + { 0.105310000000f, 0.041345000000f, 0.000000000000f }, + { 0.098786000000f, 0.038750700000f, 0.000000000000f }, + { 0.092610000000f, 0.036297800000f, 0.000000000000f }, + { 0.086773000000f, 0.033983200000f, 0.000000000000f }, + { 0.081260600000f, 0.031800400000f, 0.000000000000f }, + { 0.076048000000f, 0.029739500000f, 0.000000000000f }, + { 0.071114000000f, 0.027791800000f, 0.000000000000f }, + { 0.066454000000f, 0.025955100000f, 0.000000000000f }, + { 0.062062000000f, 0.024226300000f, 0.000000000000f }, + { 0.057930000000f, 0.022601700000f, 0.000000000000f }, + { 0.054050000000f, 0.021077900000f, 0.000000000000f }, + { 0.050412000000f, 0.019650500000f, 0.000000000000f }, + { 0.047006000000f, 0.018315300000f, 0.000000000000f }, + { 0.043823000000f, 0.017068600000f, 0.000000000000f }, + { 0.040850800000f, 0.015905100000f, 0.000000000000f }, + { 0.038072000000f, 0.014818300000f, 0.000000000000f }, + { 0.035468000000f, 0.013800800000f, 0.000000000000f }, + { 0.033031000000f, 0.012849500000f, 0.000000000000f }, + { 0.030753000000f, 0.011960700000f, 0.000000000000f }, + { 0.028623000000f, 0.011130300000f, 0.000000000000f }, + { 0.026635000000f, 0.010355500000f, 0.000000000000f }, + { 0.024781000000f, 0.009633200000f, 0.000000000000f }, + { 0.023052000000f, 0.008959900000f, 0.000000000000f }, + { 0.021441000000f, 0.008332400000f, 0.000000000000f }, + { 0.019941300000f, 0.007748800000f, 0.000000000000f }, + { 0.018544000000f, 0.007204600000f, 0.000000000000f }, + { 0.017241000000f, 0.006697500000f, 0.000000000000f }, + { 0.016027000000f, 0.006225100000f, 0.000000000000f }, + { 0.014896000000f, 0.005785000000f, 0.000000000000f }, + { 0.013842000000f, 0.005375100000f, 0.000000000000f }, + { 0.012862000000f, 0.004994100000f, 0.000000000000f }, + { 0.011949000000f, 0.004639200000f, 0.000000000000f }, + { 0.011100000000f, 0.004309300000f, 0.000000000000f }, + { 0.010311000000f, 0.004002800000f, 0.000000000000f }, + { 0.009576880000f, 0.003717740000f, 0.000000000000f }, + { 0.008894000000f, 0.003452620000f, 0.000000000000f }, + { 0.008258100000f, 0.003205830000f, 0.000000000000f }, + { 0.007666400000f, 0.002976230000f, 0.000000000000f }, + { 0.007116300000f, 0.002762810000f, 0.000000000000f }, + { 0.006605200000f, 0.002564560000f, 0.000000000000f }, + { 0.006130600000f, 0.002380480000f, 0.000000000000f }, + { 0.005690300000f, 0.002209710000f, 0.000000000000f }, + { 0.005281900000f, 0.002051320000f, 0.000000000000f }, + { 0.004903300000f, 0.001904490000f, 0.000000000000f }, + { 0.004552630000f, 0.001768470000f, 0.000000000000f }, + { 0.004227500000f, 0.001642360000f, 0.000000000000f }, + { 0.003925800000f, 0.001525350000f, 0.000000000000f }, + { 0.003645700000f, 0.001416720000f, 0.000000000000f }, + { 0.003385900000f, 0.001315950000f, 0.000000000000f }, + { 0.003144700000f, 0.001222390000f, 0.000000000000f }, + { 0.002920800000f, 0.001135550000f, 0.000000000000f }, + { 0.002713000000f, 0.001054940000f, 0.000000000000f }, + { 0.002520200000f, 0.000980140000f, 0.000000000000f }, + { 0.002341100000f, 0.000910660000f, 0.000000000000f }, + { 0.002174960000f, 0.000846190000f, 0.000000000000f }, + { 0.002020600000f, 0.000786290000f, 0.000000000000f }, + { 0.001877300000f, 0.000730680000f, 0.000000000000f }, + { 0.001744100000f, 0.000678990000f, 0.000000000000f }, + { 0.001620500000f, 0.000631010000f, 0.000000000000f }, + { 0.001505700000f, 0.000586440000f, 0.000000000000f }, + { 0.001399200000f, 0.000545110000f, 0.000000000000f }, + { 0.001300400000f, 0.000506720000f, 0.000000000000f }, + { 0.001208700000f, 0.000471110000f, 0.000000000000f }, + { 0.001123600000f, 0.000438050000f, 0.000000000000f }, + { 0.001044760000f, 0.000407410000f, 0.000000000000f }, + { 0.000971560000f, 0.000378962000f, 0.000000000000f }, + { 0.000903600000f, 0.000352543000f, 0.000000000000f }, + { 0.000840480000f, 0.000328001000f, 0.000000000000f }, + { 0.000781870000f, 0.000305208000f, 0.000000000000f }, + { 0.000727450000f, 0.000284041000f, 0.000000000000f }, + { 0.000676900000f, 0.000264375000f, 0.000000000000f }, + { 0.000629960000f, 0.000246109000f, 0.000000000000f }, + { 0.000586370000f, 0.000229143000f, 0.000000000000f }, + { 0.000545870000f, 0.000213376000f, 0.000000000000f }, + { 0.000508258000f, 0.000198730000f, 0.000000000000f }, + { 0.000473300000f, 0.000185115000f, 0.000000000000f }, + { 0.000440800000f, 0.000172454000f, 0.000000000000f }, + { 0.000410580000f, 0.000160678000f, 0.000000000000f }, + { 0.000382490000f, 0.000149730000f, 0.000000000000f }, + { 0.000356380000f, 0.000139550000f, 0.000000000000f }, + { 0.000332110000f, 0.000130086000f, 0.000000000000f }, + { 0.000309550000f, 0.000121290000f, 0.000000000000f }, + { 0.000288580000f, 0.000113106000f, 0.000000000000f }, + { 0.000269090000f, 0.000105501000f, 0.000000000000f }, + { 0.000250969000f, 0.000098428000f, 0.000000000000f }, + { 0.000234130000f, 0.000091853000f, 0.000000000000f }, + { 0.000218470000f, 0.000085738000f, 0.000000000000f }, + { 0.000203910000f, 0.000080048000f, 0.000000000000f }, + { 0.000190350000f, 0.000074751000f, 0.000000000000f }, + { 0.000177730000f, 0.000069819000f, 0.000000000000f }, + { 0.000165970000f, 0.000065222000f, 0.000000000000f }, + { 0.000155020000f, 0.000060939000f, 0.000000000000f }, + { 0.000144800000f, 0.000056942000f, 0.000000000000f }, + { 0.000135280000f, 0.000053217000f, 0.000000000000f }, + { 0.000126390000f, 0.000049737000f, 0.000000000000f }, + { 0.000118100000f, 0.000046491000f, 0.000000000000f }, + { 0.000110370000f, 0.000043464000f, 0.000000000000f }, + { 0.000103150000f, 0.000040635000f, 0.000000000000f }, + { 0.000096427000f, 0.000038000000f, 0.000000000000f }, + { 0.000090151000f, 0.000035540500f, 0.000000000000f }, + { 0.000084294000f, 0.000033244800f, 0.000000000000f }, + { 0.000078830000f, 0.000031100600f, 0.000000000000f }, + { 0.000073729000f, 0.000029099000f, 0.000000000000f }, + { 0.000068969000f, 0.000027230700f, 0.000000000000f }, + { 0.000064525800f, 0.000025486000f, 0.000000000000f }, + { 0.000060376000f, 0.000023856100f, 0.000000000000f }, + { 0.000056500000f, 0.000022333200f, 0.000000000000f }, + { 0.000052880000f, 0.000020910400f, 0.000000000000f }, + { 0.000049498000f, 0.000019580800f, 0.000000000000f }, + { 0.000046339000f, 0.000018338400f, 0.000000000000f }, + { 0.000043389000f, 0.000017177700f, 0.000000000000f }, + { 0.000040634000f, 0.000016093400f, 0.000000000000f }, + { 0.000038060000f, 0.000015080000f, 0.000000000000f }, + { 0.000035657000f, 0.000014133600f, 0.000000000000f }, + { 0.000033411700f, 0.000013249000f, 0.000000000000f }, + { 0.000031315000f, 0.000012422600f, 0.000000000000f }, + { 0.000029355000f, 0.000011649900f, 0.000000000000f }, + { 0.000027524000f, 0.000010927700f, 0.000000000000f }, + { 0.000025811000f, 0.000010251900f, 0.000000000000f }, + { 0.000024209000f, 0.000009619600f, 0.000000000000f }, + { 0.000022711000f, 0.000009028100f, 0.000000000000f }, + { 0.000021308000f, 0.000008474000f, 0.000000000000f }, + { 0.000019994000f, 0.000007954800f, 0.000000000000f }, + { 0.000018764000f, 0.000007468600f, 0.000000000000f }, + { 0.000017611500f, 0.000007012800f, 0.000000000000f }, + { 0.000016532000f, 0.000006585800f, 0.000000000000f }, + { 0.000015521000f, 0.000006185700f, 0.000000000000f }, + { 0.000014574000f, 0.000005810700f, 0.000000000000f }, + { 0.000013686000f, 0.000005459000f, 0.000000000000f }, + { 0.000012855000f, 0.000005129800f, 0.000000000000f }, + { 0.000012075000f, 0.000004820600f, 0.000000000000f }, + { 0.000011345000f, 0.000004531200f, 0.000000000000f }, + { 0.000010659000f, 0.000004259100f, 0.000000000000f }, + { 0.000010017000f, 0.000004004200f, 0.000000000000f }, + { 0.000009413630f, 0.000003764730f, 0.000000000000f }, + { 0.000008847900f, 0.000003539950f, 0.000000000000f }, + { 0.000008317100f, 0.000003329140f, 0.000000000000f }, + { 0.000007819000f, 0.000003131150f, 0.000000000000f }, + { 0.000007351600f, 0.000002945290f, 0.000000000000f }, + { 0.000006913000f, 0.000002770810f, 0.000000000000f }, + { 0.000006501500f, 0.000002607050f, 0.000000000000f }, + { 0.000006115300f, 0.000002453290f, 0.000000000000f }, + { 0.000005752900f, 0.000002308940f, 0.000000000000f }, + { 0.000005412700f, 0.000002173380f, 0.000000000000f }, + { 0.000005093470f, 0.000002046130f, 0.000000000000f }, + { 0.000004793800f, 0.000001926620f, 0.000000000000f }, + { 0.000004512500f, 0.000001814400f, 0.000000000000f }, + { 0.000004248300f, 0.000001708950f, 0.000000000000f }, + { 0.000004000200f, 0.000001609880f, 0.000000000000f }, + { 0.000003767100f, 0.000001516770f, 0.000000000000f }, + { 0.000003548000f, 0.000001429210f, 0.000000000000f }, + { 0.000003342100f, 0.000001346860f, 0.000000000000f }, + { 0.000003148500f, 0.000001269450f, 0.000000000000f }, + { 0.000002966500f, 0.000001196620f, 0.000000000000f }, + { 0.000002795310f, 0.000001128090f, 0.000000000000f }, + { 0.000002634500f, 0.000001063680f, 0.000000000000f }, + { 0.000002483400f, 0.000001003130f, 0.000000000000f }, + { 0.000002341400f, 0.000000946220f, 0.000000000000f }, + { 0.000002207800f, 0.000000892630f, 0.000000000000f }, + { 0.000002082000f, 0.000000842160f, 0.000000000000f }, + { 0.000001963600f, 0.000000794640f, 0.000000000000f }, + { 0.000001851900f, 0.000000749780f, 0.000000000000f }, + { 0.000001746500f, 0.000000707440f, 0.000000000000f }, + { 0.000001647100f, 0.000000667480f, 0.000000000000f }, + { 0.000001553140f, 0.000000629700f, 0.000000000000f } }; // CIE Standard Illuminant D65 relative spectral power distribution, From f35be05e762ed5a39d1fbdca8f61b43f4148492c Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 1 Apr 2021 18:14:45 -0700 Subject: [PATCH 24/39] DoF: fix anamorphism of the Bokeh when dynamic scaling is used --- filament/src/PostProcessManager.cpp | 17 ++++++++++++----- filament/src/PostProcessManager.h | 8 +++----- filament/src/Renderer.cpp | 2 +- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index e79cf27a9e..d2d982310e 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -817,10 +817,8 @@ FrameGraphId PostProcessManager::gaussianBlurPass(FrameGraph& } FrameGraphId PostProcessManager::dof(FrameGraph& fg, - FrameGraphId input, - const View::DepthOfFieldOptions& dofOptions, - bool translucent, - const CameraInfo& cameraInfo) noexcept { + FrameGraphId input, const View::DepthOfFieldOptions& dofOptions, + bool translucent, const CameraInfo& cameraInfo, float2 scale) noexcept { FEngine& engine = mEngine; Handle const& fullScreenRenderPrimitive = engine.getFullScreenRenderPrimitive(); @@ -1205,7 +1203,16 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); mi->setParameter("tiles", tilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); - mi->setParameter("cocToTexelScale", (1.0f / dofResolution) / float2{ inputDesc.width, inputDesc.height }); + + // The bokeh height is always correct regardless of the dynamic resolution scaling. + // (because the CoC is calculated w.r.t. the height), so we only need to adjust + // the width. + const float aspectRatio = scale.x / scale.y; + mi->setParameter("cocToTexelScale", float2{ + aspectRatio / (inputDesc.width * dofResolution), + 1.0 / (inputDesc.height * dofResolution) + }); + mi->setParameter("cocToPixelScale", (1.0f / dofResolution)); mi->setParameter("uvscale", float4{ outputDesc.width / float(inputDesc.width), diff --git a/filament/src/PostProcessManager.h b/filament/src/PostProcessManager.h index 24aa894af1..2e109e00bd 100644 --- a/filament/src/PostProcessManager.h +++ b/filament/src/PostProcessManager.h @@ -79,11 +79,9 @@ public: size_t kernelWidth, float sigmaRatio = 6.0f) noexcept; // Depth-of-field - FrameGraphId dof(FrameGraph& fg, - FrameGraphId input, - const View::DepthOfFieldOptions& dofOptions, - bool translucent, - const CameraInfo& cameraInfo) noexcept; + FrameGraphId dof(FrameGraph& fg, FrameGraphId input, + const View::DepthOfFieldOptions& dofOptions, bool translucent, + const CameraInfo& cameraInfo, math::float2 scale) noexcept; // Color grading, tone mapping, etc. void colorGradingPrepareSubpass(backend::DriverApi& driver, const FColorGrading* colorGrading, diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index 491429eab6..2e46ec0260 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -466,7 +466,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { if (hasPostProcess) { if (dofOptions.enabled) { - input = ppm.dof(fg, input, dofOptions, needsAlphaChannel, cameraInfo); + input = ppm.dof(fg, input, dofOptions, needsAlphaChannel, cameraInfo, scale); } if (colorGrading) { if (!colorGradingConfig.asSubpass) { From 891fb65daaa25e28c6d7f4b87aaf68a338666aaa Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 1 Apr 2021 18:30:12 -0700 Subject: [PATCH 25/39] added a slider to debug dynamic scaling issues This is a big hackish, but is intended to help us debug scaling issues, this adds a couple of sliders under [Debug] to control dynamic scaling manually. --- samples/gltf_viewer.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/samples/gltf_viewer.cpp b/samples/gltf_viewer.cpp index 6d48bae093..d70c99848f 100644 --- a/samples/gltf_viewer.cpp +++ b/samples/gltf_viewer.cpp @@ -341,6 +341,9 @@ static LinearColor inverseTonemapSRGB(sRGBColor x) { return (x * -0.155) / (x - 1.019); } +static float sGlobalScale = 1.0f; +static float sGlobalScaleAnamorphism = 0.0f; + int main(int argc, char** argv) { App app; @@ -567,6 +570,8 @@ int main(int argc, char** argv) { debug.getPropertyAddress("d.renderer.doFrameCapture"); *captureFrame = true; } + ImGui::SliderFloat("scale", &sGlobalScale, 0.25f, 1.0f); + ImGui::SliderFloat("anamorphism", &sGlobalScaleAnamorphism, -1.0f, 1.0f); } if (ImGui::BeginPopupModal("MessageBox", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { @@ -679,6 +684,22 @@ int main(int argc, char** argv) { } else { view->setColorGrading(nullptr); } + + view->setDynamicResolutionOptions({ + .minScale = { + lerp(sGlobalScale, 1.0f, + sGlobalScaleAnamorphism >= 0.0f ? sGlobalScaleAnamorphism : 0.0f), + lerp(sGlobalScale, 1.0f, + sGlobalScaleAnamorphism <= 0.0f ? -sGlobalScaleAnamorphism : 0.0f), + }, + .maxScale = { + lerp(sGlobalScale, 1.0f, + sGlobalScaleAnamorphism >= 0.0f ? sGlobalScaleAnamorphism : 0.0f), + lerp(sGlobalScale, 1.0f, + sGlobalScaleAnamorphism <= 0.0f ? -sGlobalScaleAnamorphism : 0.0f), + }, + .enabled = sGlobalScale != 1.0f, + }); }; auto postRender = [&app](Engine* engine, View* view, Scene* scene, Renderer* renderer) { From 57f19327448fed488eebff586f39f386f9a70bc1 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Fri, 2 Apr 2021 09:08:34 -0700 Subject: [PATCH 26/39] Vulkan: add swizzle support. --- filament/backend/src/vulkan/VulkanDriver.cpp | 7 ++--- filament/backend/src/vulkan/VulkanHandles.cpp | 14 +++++----- filament/backend/src/vulkan/VulkanHandles.h | 5 ++-- filament/backend/src/vulkan/VulkanUtility.cpp | 27 +++++++++++++++++++ filament/backend/src/vulkan/VulkanUtility.h | 1 + 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index b12846f489..e7706bfaaf 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -508,12 +508,13 @@ void VulkanDriver::createTextureSwizzledR(Handle th, SamplerType targ TextureFormat format, uint8_t samples, uint32_t w, uint32_t h, uint32_t depth, TextureUsage usage, TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a) { + TextureSwizzle swizzleArray[] = {r, g, b, a}; + const VkComponentMapping swizzleMap = getSwizzleMap(swizzleArray); auto vktexture = construct_handle(mHandleMap, th, mContext, target, levels, - format, samples, w, h, depth, usage, mStagePool); + format, samples, w, h, depth, usage, mStagePool, swizzleMap); mDisposer.createDisposable(vktexture, [this, th] () { destruct_handle(mHandleMap, th); }); - // TODO: implement texture swizzling } void VulkanDriver::importTextureR(Handle th, intptr_t id, @@ -816,7 +817,7 @@ bool VulkanDriver::isTextureFormatSupported(TextureFormat format) { } bool VulkanDriver::isTextureSwizzleSupported() { - return false; // TODO: implement texture swizzling + return true; } bool VulkanDriver::isTextureFormatMipmappable(backend::TextureFormat format) { diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index e266ce1c47..b1a3fc4fd9 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -479,14 +479,14 @@ VulkanUniformBuffer::~VulkanUniformBuffer() { VulkanTexture::VulkanTexture(VulkanContext& context, SamplerType target, uint8_t levels, TextureFormat tformat, uint8_t samples, uint32_t w, uint32_t h, uint32_t depth, - TextureUsage usage, VulkanStagePool& stagePool) : + TextureUsage usage, VulkanStagePool& stagePool, VkComponentMapping swizzle) : HwTexture(target, levels, samples, w, h, depth, tformat, usage), - mVkFormat(backend::getVkFormat(tformat)), mContext(context), mStagePool(stagePool) { - // Vulkan does not support 24-bit depth, use the official fallback format. - if (tformat == TextureFormat::DEPTH24) { - mVkFormat = mContext.finalDepthFormat; - } + // Vulkan does not support 24-bit depth, use the official fallback format. + mVkFormat(tformat == TextureFormat::DEPTH24 ? context.finalDepthFormat : + backend::getVkFormat(tformat)), + + mSwizzle(swizzle), mContext(context), mStagePool(stagePool) { // Create an appropriately-sized device-only VkImage, but do not fill it yet. VkImageCreateInfo imageInfo { @@ -752,7 +752,7 @@ VkImageView VulkanTexture::getImageView(VkImageSubresourceRange range) { .image = mTextureImage, .viewType = mViewType, .format = mVkFormat, - .components = {}, + .components = mSwizzle, .subresourceRange = range }; VkImageView imageView; diff --git a/filament/backend/src/vulkan/VulkanHandles.h b/filament/backend/src/vulkan/VulkanHandles.h index e1c3509e5a..d0a47bd31c 100644 --- a/filament/backend/src/vulkan/VulkanHandles.h +++ b/filament/backend/src/vulkan/VulkanHandles.h @@ -127,7 +127,7 @@ struct VulkanSamplerGroup : public HwSamplerGroup { struct VulkanTexture : public HwTexture { VulkanTexture(VulkanContext& context, SamplerType target, uint8_t levels, TextureFormat format, uint8_t samples, uint32_t w, uint32_t h, uint32_t depth, - TextureUsage usage, VulkanStagePool& stagePool); + TextureUsage usage, VulkanStagePool& stagePool, VkComponentMapping swizzle = {}); ~VulkanTexture(); void update2DImage(const PixelBufferDescriptor& data, uint32_t width, uint32_t height, int miplevel); @@ -172,7 +172,8 @@ private: uint32_t width, uint32_t height, uint32_t depth, FaceOffsets const* faceOffsets, uint32_t miplevel); - VkFormat mVkFormat; + const VkFormat mVkFormat; + const VkComponentMapping mSwizzle; VkImageViewType mViewType; VkImage mTextureImage = VK_NULL_HANDLE; VkDeviceMemory mTextureImageMemory = VK_NULL_HANDLE; diff --git a/filament/backend/src/vulkan/VulkanUtility.cpp b/filament/backend/src/vulkan/VulkanUtility.cpp index 6981875292..173370855c 100644 --- a/filament/backend/src/vulkan/VulkanUtility.cpp +++ b/filament/backend/src/vulkan/VulkanUtility.cpp @@ -380,6 +380,33 @@ PixelDataType getComponentType(VkFormat format) { return {}; } +VkComponentMapping getSwizzleMap(TextureSwizzle swizzle[4]) { + VkComponentMapping map; + VkComponentSwizzle* dst = &map.r; + for (int i = 0; i < 4; ++i, ++dst) { + switch (swizzle[i]) { + case TextureSwizzle::SUBSTITUTE_ZERO: *dst = VK_COMPONENT_SWIZZLE_ZERO; break; + case TextureSwizzle::SUBSTITUTE_ONE: *dst = VK_COMPONENT_SWIZZLE_ONE; break; + // NOTE: In some cases, IDENTITY is equivalent to one of the other enums, in which + // case we choose IDENTITY under the premise that it could be more efficient, or + // allow for more state sharing. In practice this probably has no impact. + case TextureSwizzle::CHANNEL_0: + *dst = i == 0 ? VK_COMPONENT_SWIZZLE_IDENTITY : VK_COMPONENT_SWIZZLE_R; + break; + case TextureSwizzle::CHANNEL_1: + *dst = i == 1 ? VK_COMPONENT_SWIZZLE_IDENTITY : VK_COMPONENT_SWIZZLE_G; + break; + case TextureSwizzle::CHANNEL_2: + *dst = i == 2 ? VK_COMPONENT_SWIZZLE_IDENTITY : VK_COMPONENT_SWIZZLE_B; + break; + case TextureSwizzle::CHANNEL_3: + *dst = i == 3 ? VK_COMPONENT_SWIZZLE_IDENTITY : VK_COMPONENT_SWIZZLE_A; + break; + } + } + return map; +} + } // namespace filament } // namespace backend diff --git a/filament/backend/src/vulkan/VulkanUtility.h b/filament/backend/src/vulkan/VulkanUtility.h index c57e8a37cc..189b48533c 100644 --- a/filament/backend/src/vulkan/VulkanUtility.h +++ b/filament/backend/src/vulkan/VulkanUtility.h @@ -33,6 +33,7 @@ VkBlendFactor getBlendFactor(BlendFunction mode); VkCullModeFlags getCullMode(CullingMode mode); VkFrontFace getFrontFace(bool inverseFrontFaces); PixelDataType getComponentType(VkFormat format); +VkComponentMapping getSwizzleMap(TextureSwizzle swizzle[4]); } // namespace filament } // namespace backend From 7d604cd05bbea697145c9536e4774bc1a995ca88 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Fri, 2 Apr 2021 10:01:25 -0700 Subject: [PATCH 27/39] Add script that updates remote UI. This script makes it easy to update the web page at https://google.github.io/filament/remote/ even if you do not have the emscripten SDK. It works by downloadinug the latest continuous web build, then placing the wasm file in the right place. After running the script, the user must make a git commit to finish the operation. --- docs/remote/update.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 docs/remote/update.sh diff --git a/docs/remote/update.sh b/docs/remote/update.sh new file mode 100755 index 0000000000..f3c3cb9fad --- /dev/null +++ b/docs/remote/update.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +pushd "$(dirname "$0")" > /dev/null + +curl -OL https://nightly.link/google/filament/workflows/web-continuous/main/filament-web.zip +unzip -q filament-web.zip +tar -xvzf filament-release-web.tgz +rm filament-release-web.tgz +rm filament-web.zip +rm filament.d.ts +cp ../../web/samples/remote.html index.html + +popd + +git status +echo "" +echo "All done! Next, make a git commit that updates docs/remote." From c2fabbf9d91e271e5a87eabfb28f9a65eff7d410 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Fri, 2 Apr 2021 12:26:56 -0700 Subject: [PATCH 28/39] WebGL: support for multiple elements. We now annotate the JS wrapper for Engine with a GL context handle. This is fairly hacky because emscripten hides its internal GL object from JavaScript, and it does not provide a mechanism to pass JS objects into inline assembly. --- web/filament-js/extensions.js | 25 ++++++++++++++++++++++--- web/filament-js/jsbindings.cpp | 15 +++++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/web/filament-js/extensions.js b/web/filament-js/extensions.js index 32d6938812..baaf47c7fc 100644 --- a/web/filament-js/extensions.js +++ b/web/filament-js/extensions.js @@ -73,16 +73,35 @@ Filament.loadClassExtensions = function() { // Create the WebGL 2.0 context. const ctx = canvas.getContext("webgl2", options); - Filament.glOptions = options; - Filament.glContext = ctx; // Enable all desired extensions by calling getExtension on each one. ctx.getExtension('WEBGL_compressed_texture_s3tc'); ctx.getExtension('WEBGL_compressed_texture_astc'); ctx.getExtension('WEBGL_compressed_texture_etc'); + // These transient globals are used temporarily during Engine construction. + window.filament_glOptions = options; + window.filament_glContext = ctx; + // Register the GL context with emscripten and create the Engine. - return Filament.Engine._create(); + const engine = Filament.Engine._create(); + + // Annotate the engine with the GL context to support multiple canvases. + engine.context = window.filament_glContext; + engine.handle = window.filament_contextHandle; + + // Ensure that we do not pollute the global namespace. + delete window.filament_glOptions; + delete window.filament_glContext; + delete window.filament_contextHandle; + + return engine; + }; + + Filament.Engine.prototype.execute = function() { + window.filament_contextHandle = this.handle; + this._execute(); + delete window.filament_contextHandle; }; /// createMaterial ::method:: diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index 33a7c27cc9..7ddcf6a781 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -472,16 +472,27 @@ register_vector("MaterialInstanceVector"); class_("Engine") .class_function("_create", (Engine* (*)()) [] { EM_ASM_INT({ - const handle = GL.registerContext(Filament.glContext, Filament.glOptions); + const options = window.filament_glOptions; + const context = window.filament_glContext; + const handle = GL.registerContext(context, options); + window.filament_contextHandle = handle; GL.makeContextCurrent(handle); }); return Engine::create(); }, allow_raw_pointers()) + + .function("_execute", EMBIND_LAMBDA(void, (Engine* engine), { + EM_ASM_INT({ + const handle = window.filament_contextHandle; + GL.makeContextCurrent(handle); + }); + engine->execute(); + }), allow_raw_pointers()) + /// destroy ::static method:: Destroys an engine instance and cleans up resources. /// engine ::argument:: the instance to destroy .class_function("destroy", (void (*)(Engine*)) [] (Engine* engine) { Engine::destroy(&engine); }, allow_raw_pointers()) - .function("execute", &Engine::execute) /// getTransformManager ::method:: /// ::retval:: an instance of [TransformManager] From 6b529bb2311e9a55d5c3293cc2b7b1dab738a25f Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Fri, 2 Apr 2021 15:15:45 -0700 Subject: [PATCH 29/39] Fix typo --- tools/cso-lut/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cso-lut/src/main.cpp b/tools/cso-lut/src/main.cpp index fbe21a87ed..b45a60702f 100644 --- a/tools/cso-lut/src/main.cpp +++ b/tools/cso-lut/src/main.cpp @@ -70,7 +70,7 @@ static void printUsage(const char* name) { " DDS: 8, 16 (default), 32\n\n" ); - const std::string from("ROUGHNESSPREFILTER"); + const std::string from("CSO-LUT"); for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) { usage.replace(pos, from.length(), execName); } From fe94f935f106a7a8a899a3a44830be8d76e161ce Mon Sep 17 00:00:00 2001 From: Thomas Gorisse Date: Sun, 4 Apr 2021 00:45:46 +0200 Subject: [PATCH 30/39] Expose TransformManager.getParent(int) (#3751) It will be nice to have access to TransformManager EntityInstance parent. --- .../src/main/cpp/TransformManager.cpp | 7 +++++++ .../google/android/filament/TransformManager.java | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/android/filament-android/src/main/cpp/TransformManager.cpp b/android/filament-android/src/main/cpp/TransformManager.cpp index b329776289..c4b2d3895d 100644 --- a/android/filament-android/src/main/cpp/TransformManager.cpp +++ b/android/filament-android/src/main/cpp/TransformManager.cpp @@ -86,6 +86,13 @@ Java_com_google_android_filament_TransformManager_nSetParent(JNIEnv*, jclass, (TransformManager::Instance) newParent); } +extern "C" JNIEXPORT jint JNICALL +Java_com_google_android_filament_TransformManager_nGetParent(JNIEnv*, jclass, + jlong nativeTransformManager, jint i) { + TransformManager* tm = (TransformManager*) nativeTransformManager; + return tm->getParent((TransformManager::Instance) i).getId(); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_TransformManager_nSetTransform(JNIEnv* env, jclass, jlong nativeTransformManager, jint i, diff --git a/android/filament-android/src/main/java/com/google/android/filament/TransformManager.java b/android/filament-android/src/main/java/com/google/android/filament/TransformManager.java index 3611ee6c1e..e67f882e80 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/TransformManager.java +++ b/android/filament-android/src/main/java/com/google/android/filament/TransformManager.java @@ -140,6 +140,19 @@ import androidx.annotation.Size; nSetParent(mNativeObject, i, newParent); } + /** + * Returns the actual parent entity of an {@link EntityInstance} originally defined + * by {@link #setParent(int, int)}. + * + * @param i the {@link EntityInstance} of the transform component to get the parent from. + * @return the parent {@link Entity}. + * @see #getInstance + */ + @Entity + public int getParent(@EntityInstance int i) { + return nGetParent(mNativeObject, i); + } + /** * Sets a local transform of a transform component. *

This operation can be slow if the hierarchy of transform is too deep, and this @@ -241,6 +254,7 @@ import androidx.annotation.Size; private static native int nCreateArray(long mNativeObject, int entity, int parent, float[] localTransform); private static native void nDestroy(long nativeTransformManager, int entity); private static native void nSetParent(long nativeTransformManager, int i, int newParent); + private static native int nGetParent(long nativeTransformManager, int i); private static native void nSetTransform(long nativeTransformManager, int i, float[] localTransform); private static native void nGetTransform(long nativeTransformManager, int i, float[] outLocalTransform); private static native void nGetWorldTransform(long nativeTransformManager, int i, float[] outWorldTransform); From b95d91a65ef4ab223458bb9e25ba4aea2fe614a6 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Fri, 2 Apr 2021 14:27:53 -0700 Subject: [PATCH 31/39] WebGL: expose fitIntoUnitCube to JS. --- libs/viewer/include/viewer/SimpleViewer.h | 3 ++- libs/viewer/src/SimpleViewer.cpp | 6 +++--- samples/gltf_viewer.cpp | 2 +- web/filament-js/filament.d.ts | 3 +++ web/filament-js/jsbindings.cpp | 8 ++++++++ 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libs/viewer/include/viewer/SimpleViewer.h b/libs/viewer/include/viewer/SimpleViewer.h index 6573034321..a8c534f675 100644 --- a/libs/viewer/include/viewer/SimpleViewer.h +++ b/libs/viewer/include/viewer/SimpleViewer.h @@ -31,6 +31,7 @@ #include +#include #include namespace filagui { @@ -243,7 +244,7 @@ private: float mCurvePlot[1024 * 3]; }; -filament::math::mat4f fitIntoUnitCube(const filament::Aabb& bounds); +filament::math::mat4f fitIntoUnitCube(const filament::Aabb& bounds, float zoffset); } // namespace viewer } // namespace filament diff --git a/libs/viewer/src/SimpleViewer.cpp b/libs/viewer/src/SimpleViewer.cpp index aadd51b8c9..b82091f19c 100644 --- a/libs/viewer/src/SimpleViewer.cpp +++ b/libs/viewer/src/SimpleViewer.cpp @@ -42,7 +42,7 @@ using namespace filament::math; namespace filament { namespace viewer { -filament::math::mat4f fitIntoUnitCube(const filament::Aabb& bounds) { +filament::math::mat4f fitIntoUnitCube(const filament::Aabb& bounds, float zoffset) { using namespace filament::math; auto minpt = bounds.min; auto maxpt = bounds.max; @@ -51,7 +51,7 @@ filament::math::mat4f fitIntoUnitCube(const filament::Aabb& bounds) { maxExtent = std::max(maxExtent, maxpt.z - minpt.z); float scaleFactor = 2.0f / maxExtent; float3 center = (minpt + maxpt) / 2.0f; - center.z += 4.0f / scaleFactor; + center.z += zoffset / scaleFactor; return mat4f::scaling(float3(scaleFactor)) * mat4f::translation(-center); } @@ -348,7 +348,7 @@ void SimpleViewer::populateScene(FilamentAsset* asset, bool scale, if (scale) { auto& tcm = mEngine->getTransformManager(); auto root = tcm.getInstance(mAsset->getRoot()); - filament::math::mat4f transform = fitIntoUnitCube(mAsset->getBoundingBox()); + filament::math::mat4f transform = fitIntoUnitCube(mAsset->getBoundingBox(), 4); tcm.setTransform(root, transform); } diff --git a/samples/gltf_viewer.cpp b/samples/gltf_viewer.cpp index d70c99848f..207751ffb0 100644 --- a/samples/gltf_viewer.cpp +++ b/samples/gltf_viewer.cpp @@ -261,7 +261,7 @@ static void createGroundPlane(Engine* engine, Scene* scene, App& app) { Aabb aabb = app.asset->getBoundingBox(); if (!app.actualSize) { - mat4f transform = fitIntoUnitCube(aabb); + mat4f transform = fitIntoUnitCube(aabb, 4); aabb = aabb.transform(transform); } diff --git a/web/filament-js/filament.d.ts b/web/filament-js/filament.d.ts index a3231463ff..ee4304b1e0 100644 --- a/web/filament-js/filament.d.ts +++ b/web/filament-js/filament.d.ts @@ -143,6 +143,9 @@ export interface View$VignetteOptions { enabled?: boolean; } +export function fitIntoUnitCube(box: Aabb): mat4; +export function multiplyMatrices(a: mat4, b: mat4): mat4; + // Clients should use the [PixelBuffer/CompressedPixelBuffer] helper function to contruct PixelBufferDescriptor objects. export class driver$PixelBufferDescriptor { constructor(byteLength: number, format: PixelDataFormat, datatype: PixelDataType); diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index 7ddcf6a781..3e02d3e47b 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -1903,6 +1903,14 @@ class_("SimpleViewer") .function("keyUpEvent", &SimpleViewer::keyUpEvent) .function("keyPressEvent", &SimpleViewer::keyPressEvent); +function("fitIntoUnitCube", EMBIND_LAMBDA(flatmat4, (Aabb box, float zoffset), { + return flatmat4 { fitIntoUnitCube(box, zoffset) }; +})); + +function("multiplyMatrices", EMBIND_LAMBDA(flatmat4, (flatmat4 a, flatmat4 b), { + return flatmat4 { a.m * b.m }; +})); + } // EMSCRIPTEN_BINDINGS #pragma clang diagnostic pop From 951802dd73bd4acc24d82cae59c02d1d1e0f280b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 2 Apr 2021 15:46:11 -0700 Subject: [PATCH 32/39] SSAO: fix high-quality upsampling Another mediump issue. --- shaders/src/ambient_occlusion.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shaders/src/ambient_occlusion.fs b/shaders/src/ambient_occlusion.fs index 6b8f2d1a9c..59ac2b3ee5 100644 --- a/shaders/src/ambient_occlusion.fs +++ b/shaders/src/ambient_occlusion.fs @@ -58,9 +58,9 @@ float evaluateSSAO() { depths.z = unpack(vec2(dg.z, db.z)); depths.w = unpack(vec2(dg.w, db.w)); depths *= -frameUniforms.cameraFar; - mat4 m = getViewFromWorldMatrix(); - float d = dot(vec3(m[0].z, m[1].z, m[2].z), shading_position) + m[3].z; - vec4 w = (vec4(d) - depths) * frameUniforms.aoSamplingQualityAndEdgeDistance; + highp mat4 m = getViewFromWorldMatrix(); + highp float d = dot(vec3(m[0].z, m[1].z, m[2].z), shading_position) + m[3].z; + highp vec4 w = (vec4(d) - depths) * frameUniforms.aoSamplingQualityAndEdgeDistance; w = max(vec4(MEDIUMP_FLT_MIN), 1.0 - w * w) * b; return dot(ao, w) * (1.0 / (w.x + w.y + w.z + w.w)); } else { From 8a34f3c289e753f4fb8fd5afb0de3748d8619454 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Sun, 4 Apr 2021 23:15:18 -0700 Subject: [PATCH 33/39] revive somewhat the importance sampling mode --- shaders/src/light_indirect.fs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shaders/src/light_indirect.fs b/shaders/src/light_indirect.fs index 91a6328d9a..f95b11bd97 100644 --- a/shaders/src/light_indirect.fs +++ b/shaders/src/light_indirect.fs @@ -224,9 +224,9 @@ float prefilteredImportanceSampling(float ipdf, float iblRoughnessOneLevel) { // Prefiltering doesn't work with anisotropy const float numSamples = float(IBL_INTEGRATION_IMPORTANCE_SAMPLING_COUNT); const float invNumSamples = 1.0 / float(numSamples); - const float dim = float(textureSize(light_iblSpecular, 0).x); - const float omegaP = (4.0 * PI) / (6.0 * dim * dim); - const float invOmegaP = 1.0 / omegaP; + float dim = float(textureSize(light_iblSpecular, 0).x); + float omegaP = (4.0 * PI) / (6.0 * dim * dim); + float invOmegaP = 1.0 / omegaP; const float K = 4.0; float omegaS = invNumSamples * ipdf; float mipLevel = clamp(log2(K * omegaS * invOmegaP) * 0.5, 0.0, iblRoughnessOneLevel); @@ -304,7 +304,9 @@ void isEvaluateClearCoatIBL(const PixelParams pixel, float specularAO, inout vec p.perceptualRoughness = pixel.clearCoatPerceptualRoughness; p.f0 = vec3(0.04); p.roughness = perceptualRoughnessToRoughness(p.perceptualRoughness); +#if defined(MATERIAL_HAS_ANISOTROPY) p.anisotropy = 0.0; +#endif vec3 clearCoatLobe = isEvaluateIBL(p, clearCoatNormal, shading_view, clearCoatNoV); Fr += clearCoatLobe * (specularAO * pixel.clearCoat); From e29bfc2c86149e41e438b16ae1e19e9add04f0a7 Mon Sep 17 00:00:00 2001 From: Adrian Perez Date: Mon, 5 Apr 2021 10:42:57 -0700 Subject: [PATCH 34/39] ImGuiHelper can construct with a context (#3753) * ImGuiHelper supports client-provided context this lets impress load >1 embedded font into the font table * ImGuiHelper supports client-provided context this lets impress load >1 embedded font into the font table Co-authored-by: Philip Rideout --- libs/filagui/include/filagui/ImGuiHelper.h | 3 ++- libs/filagui/src/ImGuiHelper.cpp | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libs/filagui/include/filagui/ImGuiHelper.h b/libs/filagui/include/filagui/ImGuiHelper.h index e6ffe2386e..8313974c7e 100644 --- a/libs/filagui/include/filagui/ImGuiHelper.h +++ b/libs/filagui/include/filagui/ImGuiHelper.h @@ -47,7 +47,8 @@ public: using Callback = std::function; // The constructor creates its own Scene and places it in the given View. - ImGuiHelper(filament::Engine* engine, filament::View* view, const utils::Path& fontPath); + ImGuiHelper(filament::Engine* engine, filament::View* view, const utils::Path& fontPath, + ImGuiContext* imGuiContext = nullptr); ~ImGuiHelper(); // Informs ImGui of the current display size, as well as a scaling factor when scissoring. diff --git a/libs/filagui/src/ImGuiHelper.cpp b/libs/filagui/src/ImGuiHelper.cpp index 74f750559c..91b2a4e156 100644 --- a/libs/filagui/src/ImGuiHelper.cpp +++ b/libs/filagui/src/ImGuiHelper.cpp @@ -45,9 +45,10 @@ namespace filagui { #include "generated/resources/filagui_resources.h" -ImGuiHelper::ImGuiHelper(Engine* engine, filament::View* view, const Path& fontPath) : - mEngine(engine), mView(view), mScene(engine->createScene()), - mImGuiContext(ImGui::CreateContext()) { +ImGuiHelper::ImGuiHelper(Engine* engine, filament::View* view, const Path& fontPath, + ImGuiContext *imGuiContext) + : mEngine(engine), mView(view), mScene(engine->createScene()), + mImGuiContext(imGuiContext ? imGuiContext : ImGui::CreateContext()) { ImGuiIO& io = ImGui::GetIO(); // Create a simple alpha-blended 2D blitting material. @@ -63,7 +64,7 @@ ImGuiHelper::ImGuiHelper(Engine* engine, filament::View* view, const Path& fontP createAtlasTexture(engine); // For proggy, switch to NEAREST for pixel-perfect text. - if (fontPath.isEmpty()) { + if (fontPath.isEmpty() && !imGuiContext) { TextureSampler sampler(MinFilter::NEAREST, MagFilter::NEAREST); mMaterial->setDefaultParameter("albedo", mTexture, sampler); } From bcb5b2d790c52216d3258be56a9d7cf8bf35b7ea Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Fri, 2 Apr 2021 16:27:23 -0700 Subject: [PATCH 35/39] Implement Metal BufferObjects --- filament/backend/src/metal/MetalDriver.mm | 40 +++++++++++++++++----- filament/backend/src/metal/MetalHandles.h | 19 +++++++--- filament/backend/src/metal/MetalHandles.mm | 33 +++++++++--------- 3 files changed, 63 insertions(+), 29 deletions(-) diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index 39f38578b6..84d326750e 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -174,7 +174,7 @@ void MetalDriver::createIndexBufferR(Handle ibh, ElementType elem void MetalDriver::createBufferObjectR(Handle boh, uint32_t byteCount, BufferObjectBinding bindingType) { - // TODO + construct_handle(mHandleMap, boh, *mContext, byteCount); } void MetalDriver::createTextureR(Handle th, SamplerType target, uint8_t levels, @@ -327,8 +327,7 @@ Handle MetalDriver::createIndexBufferS() noexcept { } Handle MetalDriver::createBufferObjectS() noexcept { - // TODO - return {}; + return alloc_handle(); } Handle MetalDriver::createTextureS() noexcept { @@ -411,7 +410,7 @@ void MetalDriver::destroyIndexBuffer(Handle ibh) { void MetalDriver::destroyBufferObject(Handle boh) { if (boh) { - // TODO + destruct_handle(mHandleMap, boh); } } @@ -668,12 +667,18 @@ void MetalDriver::updateIndexBuffer(Handle ibh, BufferDescriptor& void MetalDriver::updateBufferObject(Handle boh, BufferDescriptor&& data, uint32_t byteOffset) { - // TODO + auto* bo = handle_cast(mHandleMap, boh); + bo->updateBuffer(data.buffer, data.size, byteOffset); + scheduleDestroy(std::move(data)); } void MetalDriver::setVertexBufferObject(Handle vbh, size_t index, Handle boh) { - // TODO + auto* vertexBuffer = handle_cast(mHandleMap, vbh); + auto* bufferObject = handle_cast(mHandleMap, boh); + assert_invariant(index < vertexBuffer->buffers.size()); + assert_invariant(bufferObject->getBuffer()); + vertexBuffer->buffers[index] = bufferObject->getBuffer(); } void MetalDriver::update2DImage(Handle th, uint32_t level, uint32_t xoffset, @@ -1289,9 +1294,28 @@ void MetalDriver::draw(backend::PipelineState ps, Handle rph) withRange:samplerRange]; // Bind the vertex buffers. + + MetalBuffer* buffers[MAX_VERTEX_ATTRIBUTE_COUNT]; + size_t vertexBufferOffsets[MAX_VERTEX_ATTRIBUTE_COUNT]; + size_t bufferIndex = 0; + + auto vb = primitive->vertexBuffer; + for (uint32_t attributeIndex = 0; attributeIndex < vb->attributes.size(); attributeIndex++) { + const auto& attribute = vb->attributes[attributeIndex]; + if (attribute.buffer == Attribute::BUFFER_UNUSED) { + continue; + } + + assert_invariant(vb->buffers[attribute.buffer]); + buffers[bufferIndex] = vb->buffers[attribute.buffer].get(); + vertexBufferOffsets[bufferIndex] = attribute.offset; + bufferIndex++; + } + + const auto bufferCount = bufferIndex; MetalBuffer::bindBuffers(getPendingCommandBuffer(mContext), mContext->currentRenderPassEncoder, - VERTEX_BUFFER_START, MetalBuffer::Stage::VERTEX, primitive->buffers.data(), - primitive->offsets.data(), primitive->buffers.size()); + VERTEX_BUFFER_START, MetalBuffer::Stage::VERTEX, buffers, + vertexBufferOffsets, bufferCount); // Bind the zero buffer, used for missing vertex attributes. static const char bytes[16] = { 0 }; diff --git a/filament/backend/src/metal/MetalHandles.h b/filament/backend/src/metal/MetalHandles.h index 7d021b6c80..cfc1be1e8e 100644 --- a/filament/backend/src/metal/MetalHandles.h +++ b/filament/backend/src/metal/MetalHandles.h @@ -112,12 +112,24 @@ private: void* frameCompletedUserData = nullptr; }; +class MetalBufferObject : public HwBufferObject { +public: + MetalBufferObject(MetalContext& context, uint32_t byteCount); + + void updateBuffer(void* data, size_t size, uint32_t byteOffset); + const std::shared_ptr& getBuffer() const { return buffer; } + +private: + uint32_t byteCount; + std::shared_ptr buffer = nullptr; + +}; + struct MetalVertexBuffer : public HwVertexBuffer { MetalVertexBuffer(MetalContext& context, uint8_t bufferCount, uint8_t attributeCount, uint32_t vertexCount, AttributeArray const& attributes, bool bufferObjectsEnabled); - ~MetalVertexBuffer(); - std::vector buffers; + std::vector> buffers; }; struct MetalIndexBuffer : public HwIndexBuffer { @@ -142,9 +154,6 @@ struct MetalRenderPrimitive : public HwRenderPrimitive { // This struct is used to create the pipeline description to describe vertex assembly. VertexDescription vertexDescription = {}; - - std::vector buffers; - std::vector offsets; }; struct MetalProgram : public HwProgram { diff --git a/filament/backend/src/metal/MetalHandles.mm b/filament/backend/src/metal/MetalHandles.mm index a7186e0c88..0a374762f7 100644 --- a/filament/backend/src/metal/MetalHandles.mm +++ b/filament/backend/src/metal/MetalHandles.mm @@ -266,12 +266,27 @@ void MetalSwapChain::scheduleFrameCompletedCallback() { }]; } +MetalBufferObject::MetalBufferObject(MetalContext& context, uint32_t byteCount) + : byteCount(byteCount), buffer(std::make_shared(context, byteCount)) {} + +void MetalBufferObject::updateBuffer(void* data, size_t size, uint32_t byteOffset) { + assert_invariant(byteOffset + size <= byteCount); + buffer->copyIntoBuffer(data, size); +} + MetalVertexBuffer::MetalVertexBuffer(MetalContext& context, uint8_t bufferCount, uint8_t attributeCount, uint32_t vertexCount, AttributeArray const& attributes, bool bufferObjectsEnabled) : HwVertexBuffer(bufferCount, attributeCount, vertexCount, attributes, bufferObjectsEnabled) { buffers.reserve(bufferCount); + if (bufferObjectsEnabled) { + // If BufferObjects are used, we don't need to make any allocations. Simply reserve enough + // "slots" for future calls to setVertexBufferObject. + buffers.resize(bufferCount); + return; + } + for (uint8_t bufferIndex = 0; bufferIndex < bufferCount; ++bufferIndex) { // Calculate buffer size. uint32_t size = 0; @@ -282,21 +297,14 @@ MetalVertexBuffer::MetalVertexBuffer(MetalContext& context, uint8_t bufferCount, } } - MetalBuffer* buffer = nullptr; + std::shared_ptr buffer = nullptr; if (size > 0) { - buffer = new MetalBuffer(context, size); + buffer = std::make_shared(context, size); } buffers.push_back(buffer); } } -MetalVertexBuffer::~MetalVertexBuffer() { - for (auto* b : buffers) { - delete b; - } - buffers.clear(); -} - MetalIndexBuffer::MetalIndexBuffer(MetalContext& context, uint8_t elementSize, uint32_t indexCount) : HwIndexBuffer(elementSize, indexCount), buffer(context, elementSize * indexCount, true) { } @@ -310,10 +318,6 @@ void MetalRenderPrimitive::setBuffers(MetalVertexBuffer* vertexBuffer, MetalInde const size_t attributeCount = vertexBuffer->attributes.size(); - buffers.clear(); - buffers.reserve(attributeCount); - offsets.clear(); - offsets.reserve(attributeCount); vertexDescription = {}; // Each attribute gets its own vertex buffer. @@ -340,9 +344,6 @@ void MetalRenderPrimitive::setBuffers(MetalVertexBuffer* vertexBuffer, MetalInde continue; } - buffers.push_back(vertexBuffer->buffers[attribute.buffer]); - offsets.push_back(attribute.offset); - vertexDescription.attributes[attributeIndex] = { .format = getMetalFormat(attribute.type, attribute.flags & Attribute::FLAG_NORMALIZED), From 491e8032e696122aeeb50f209718f5501eefc5c2 Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Mon, 5 Apr 2021 11:10:20 -0700 Subject: [PATCH 36/39] Release Filament 1.9.19 --- README.md | 4 ++-- android/gradle.properties | 2 +- ios/CocoaPods/Filament.podspec | 4 ++-- web/filament-js/package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8ee2c9ee91..6985714aa9 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ repositories { } dependencies { - implementation 'com.google.android.filament:filament-android:1.9.18' + implementation 'com.google.android.filament:filament-android:1.9.19' } ``` @@ -63,7 +63,7 @@ A much smaller alternative to `filamat-android` that can only generate OpenGL sh iOS projects can use CocoaPods to install the latest release: ``` -pod 'Filament', '~> 1.9.18' +pod 'Filament', '~> 1.9.19' ``` ### Snapshots diff --git a/android/gradle.properties b/android/gradle.properties index 4b9ecbc900..8d3b35e378 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ GROUP=com.google.android.filament -VERSION_NAME=1.9.18 +VERSION_NAME=1.9.19 POM_DESCRIPTION=Real-time physically based rendering engine for Android. diff --git a/ios/CocoaPods/Filament.podspec b/ios/CocoaPods/Filament.podspec index a916590857..c87c07532f 100644 --- a/ios/CocoaPods/Filament.podspec +++ b/ios/CocoaPods/Filament.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |spec| spec.name = "Filament" - spec.version = "1.9.18" + spec.version = "1.9.19" spec.license = { :type => "Apache 2.0", :file => "LICENSE" } spec.homepage = "https://google.github.io/filament" spec.authors = "Google LLC." spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL." spec.platform = :ios, "11.0" - spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.18/filament-v1.9.18-ios.tgz" } + spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.19/filament-v1.9.19-ios.tgz" } # Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon. spec.pod_target_xcconfig = { diff --git a/web/filament-js/package.json b/web/filament-js/package.json index 9437e36336..4ab5468503 100644 --- a/web/filament-js/package.json +++ b/web/filament-js/package.json @@ -1,6 +1,6 @@ { "name": "filament", - "version": "1.9.18", + "version": "1.9.19", "description": "Real-time physically based rendering engine", "main": "filament.js", "module": "filament.js", From 2786d0a9f7161133a15f8386c7379a825788359b Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Mon, 5 Apr 2021 11:09:38 -0700 Subject: [PATCH 37/39] Update RELEASE_NOTES for 1.9.19 --- RELEASE_NOTES.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6fbcf16c0c..a4a1fcd842 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,9 +5,18 @@ A new header is inserted each time a *tag* is created. ## Next release (main branch) +## v1.9.20 + ## v1.9.19 +- engine: Fix Metal bug when setGeometryAt is called multiple times. +- engine: Improvements to DoF. +- engine: Fix RenderTarget NPE when depth is not present. +- engine: Improvements to Camera APIs. Move focus distance from DofOptions to Camera. - engine: VSM shadows now support `shadowMultiplier`. +- java: Expose severla MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that + should have been public. +- java: fix bug with Texture::setImage buffer size calculation. ## v1.9.18 From d9f800454ccab4e49693237a75fdf6ab67f3dd76 Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Mon, 5 Apr 2021 11:14:17 -0700 Subject: [PATCH 38/39] Bump version to 1.9.20 --- README.md | 4 ++-- android/gradle.properties | 2 +- ios/CocoaPods/Filament.podspec | 4 ++-- web/filament-js/package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6985714aa9..7acd6e06c0 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ repositories { } dependencies { - implementation 'com.google.android.filament:filament-android:1.9.19' + implementation 'com.google.android.filament:filament-android:1.9.20' } ``` @@ -63,7 +63,7 @@ A much smaller alternative to `filamat-android` that can only generate OpenGL sh iOS projects can use CocoaPods to install the latest release: ``` -pod 'Filament', '~> 1.9.19' +pod 'Filament', '~> 1.9.20' ``` ### Snapshots diff --git a/android/gradle.properties b/android/gradle.properties index 8d3b35e378..d42fab15b8 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ GROUP=com.google.android.filament -VERSION_NAME=1.9.19 +VERSION_NAME=1.9.20 POM_DESCRIPTION=Real-time physically based rendering engine for Android. diff --git a/ios/CocoaPods/Filament.podspec b/ios/CocoaPods/Filament.podspec index c87c07532f..c09aa7ee5e 100644 --- a/ios/CocoaPods/Filament.podspec +++ b/ios/CocoaPods/Filament.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |spec| spec.name = "Filament" - spec.version = "1.9.19" + spec.version = "1.9.20" spec.license = { :type => "Apache 2.0", :file => "LICENSE" } spec.homepage = "https://google.github.io/filament" spec.authors = "Google LLC." spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL." spec.platform = :ios, "11.0" - spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.19/filament-v1.9.19-ios.tgz" } + spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.20/filament-v1.9.20-ios.tgz" } # Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon. spec.pod_target_xcconfig = { diff --git a/web/filament-js/package.json b/web/filament-js/package.json index 4ab5468503..265de588c8 100644 --- a/web/filament-js/package.json +++ b/web/filament-js/package.json @@ -1,6 +1,6 @@ { "name": "filament", - "version": "1.9.19", + "version": "1.9.20", "description": "Real-time physically based rendering engine", "main": "filament.js", "module": "filament.js", From baea54a3fc3946381ccde8666ab175c0dcd5bc61 Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Mon, 12 Apr 2021 09:20:31 -0700 Subject: [PATCH 39/39] Update RELEASE_NOTES for 1.9.20 --- RELEASE_NOTES.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a4a1fcd842..60ed56fc22 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -7,6 +7,18 @@ A new header is inserted each time a *tag* is created. ## v1.9.20 +Android: Fix VSM. +engine: Introduce BufferObject API. +engine: Add new isTextureSwizzleSupported API on Texture. +engine: Add support to Metal and Vulkan backends for texture swizzling. +engine: Add new DoF settings (native/half res, gather kernel ring counts, CoC radius clamp). +engine: DoF quality and performance improvements. +engine: Fix high-quality upsampling issue with SSAO. +Java: Expose `TransformManager.getParent(int)`. +samples: Add Metal and Vulkan backend support to Suzanne sample. +WebGL: expose fitIntoUnitCube to JS. +WebGL: support for multiple elements. + ## v1.9.19 - engine: Fix Metal bug when setGeometryAt is called multiple times.