From 00a46c13908363064933ca072996d35948cf8bc2 Mon Sep 17 00:00:00 2001 From: chris bell Date: Mon, 5 Oct 2026 18:03:52 -0500 Subject: [PATCH] added test spacegame --- dev/spacegame/index.data | Bin 0 -> 3871 bytes dev/spacegame/index.html | 40 + dev/spacegame/index.js | 10625 +++++++++++++++++++++++++++++++++++++ dev/spacegame/index.wasm | Bin 0 -> 541105 bytes 4 files changed, 10665 insertions(+) create mode 100644 dev/spacegame/index.data create mode 100644 dev/spacegame/index.html create mode 100644 dev/spacegame/index.js create mode 100755 dev/spacegame/index.wasm diff --git a/dev/spacegame/index.data b/dev/spacegame/index.data new file mode 100644 index 0000000000000000000000000000000000000000..abf3597ad341232f8786469d5e17c8914571fff5 GIT binary patch literal 3871 zcmeAS@N?(olHy`uVBq!ia0y~yU{GUVV36QoV_;yI=G$M)z`(#*9OUlAc=M!AJp%&+ zOS+@4BLl<6e(pbstPBhc3dtTpz6=aiY77hwEes657#J8DUNA6}8Za=tN?>5Hn!&&z zUNC1@pbY~916z`}y94*ZG!|AcFz_XNx;Tb-@G?g5E&s^KKpgmwri@s9XxfP9G7+Klzr4IWgMonogOTe) zm~wQ7!o;aY6XP%x%a9z0B2H}%Ne=t>+8^0|nuZ$8VIWIzVX$M~zkd&=K?FTQjfH`M z0puX$^aHXRj=6utfZ2~8Jp$99P-7C^2xdd|(j+5*317lE&200977Tkd_0c6_N)|LU}IFQ3Y;#eF95(Z(InYhe@$%EA5 z#Gt5zNn+E0VK^wQJ$wi%HsGNJ(+{KJdO)6m34-XuhYy1&xIBmh#Ta&D2tXBrC~O9R z#2G;48kj)^0^&&&gTQVA6DYzE4%kuXJ_bp_qVvLq3m`6Dj4jRL(|~LyHiw}&>MO?* zuvwtoiR>t1iVRTZAVwY70we;Y4_1yL2@eh?wh#lk3?QW$wflS0_0XV90gce9IO)yCXEWJVt z2xV3X$ywM<}?A + + + + + Spacegame + + + + + + + + + diff --git a/dev/spacegame/index.js b/dev/spacegame/index.js new file mode 100644 index 0000000..c348943 --- /dev/null +++ b/dev/spacegame/index.js @@ -0,0 +1,10625 @@ +// include: shell.js +// include: minimum_runtime_check.js +(function() { + // "30.0.0" -> 300000 + function humanReadableVersionToPacked(str) { + str = str.split('-')[0]; // Remove any trailing part from e.g. "12.53.3-alpha" + var vers = str.split('.').slice(0, 3); + while(vers.length < 3) vers.push('00'); + vers = vers.map((n, i, arr) => n.padStart(2, '0')); + return vers.join(''); + } + // 300000 -> "30.0.0" + var packedVersionToHumanReadable = n => [n / 10000 | 0, (n / 100 | 0) % 100, n % 100].join('.'); + + var TARGET_NOT_SUPPORTED = 2147483647; + + // Note: We use a typeof check here instead of optional chaining using + // globalThis because older browsers might not have globalThis defined. + + // We skip the node version checking when running on Bun/Deno since the node + // version they report doesn't seem to be useful. + if (typeof process !== 'undefined' && !process.versions?.bun && typeof Deno == "undefined") { + var currentNodeVersion = process.versions?.node ? humanReadableVersionToPacked(process.versions.node) : TARGET_NOT_SUPPORTED; + if (currentNodeVersion < 180300) { + throw new Error(`This emscripten-generated code requires node v${ packedVersionToHumanReadable(180300) } (detected v${packedVersionToHumanReadable(currentNodeVersion)})`); + } + } + + var userAgent = typeof navigator !== 'undefined' && navigator.userAgent; + if (!userAgent) { + return; + } + + var currentSafariVersion = userAgent.includes("Safari/") && !userAgent.includes("Chrome/") && userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/) ? humanReadableVersionToPacked(userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/)[1]) : TARGET_NOT_SUPPORTED; + if (currentSafariVersion < 150000) { + throw new Error(`This emscripten-generated code requires Safari v${ packedVersionToHumanReadable(150000) } (detected v${currentSafariVersion})`); + } + + var currentFirefoxVersion = userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/) ? parseFloat(userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED; + if (currentFirefoxVersion < 79) { + throw new Error(`This emscripten-generated code requires Firefox v79 (detected v${currentFirefoxVersion})`); + } + + var currentChromeVersion = userAgent.match(/Chrome\/(\d+(?:\.\d+)?)/) ? parseFloat(userAgent.match(/Chrome\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED; + if (currentChromeVersion < 85) { + throw new Error(`This emscripten-generated code requires Chrome v85 (detected v${currentChromeVersion})`); + } +})(); + +// end include: minimum_runtime_check.js +// The Module object: Our interface to the outside world. We import +// and export values on it. There are various ways Module can be used: +// 1. Not defined. We create it here +// 2. A function parameter, function(moduleArg) => Promise +// 3. pre-run appended it, var Module = {}; ..generated code.. +// 4. External script tag defines var Module. +// We need to check if Module already exists (e.g. case 3 above). +// Substitution will be replaced with actual code on later stage of the build, +// this way Closure Compiler will not mangle it (e.g. case 4. above). +// Note that if you want to run closure, and also to use Module +// after the generated code, you will need to define var Module = {}; +// before the code. Then that object will be used in the code, and you +// can continue to use Module afterwards as well. +var Module = typeof Module != 'undefined' ? Module : {}; + +// Determine the runtime environment we are in. You can customize this by +// setting the ENVIRONMENT setting at compile time (see settings.js). + +// Attempt to auto-detect the environment +var ENVIRONMENT_IS_WEB = !!globalThis.window; +var ENVIRONMENT_IS_WORKER = !!globalThis.WorkerGlobalScope; +// N.b. Electron.js environment is simultaneously a NODE-environment, but +// also a web environment. +var ENVIRONMENT_IS_NODE = globalThis.process?.versions?.node && globalThis.process?.type != 'renderer'; +var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; + +// --pre-jses are emitted after the Module integration code, so that they can +// refer to Module (if they choose; they can also define Module) +// include: /tmp/tmpyzenctb4.js + + if (!Module['expectedDataFileDownloads']) Module['expectedDataFileDownloads'] = 0; + Module['expectedDataFileDownloads']++; + (() => { + // Do not attempt to redownload the virtual filesystem data when in a pthread or a Wasm Worker context. + var isPthread = typeof ENVIRONMENT_IS_PTHREAD != 'undefined' && ENVIRONMENT_IS_PTHREAD; + var isWasmWorker = typeof ENVIRONMENT_IS_WASM_WORKER != 'undefined' && ENVIRONMENT_IS_WASM_WORKER; + if (isPthread || isWasmWorker) return; + var isNode = globalThis.process && globalThis.process.versions && globalThis.process.versions.node && globalThis.process.type != 'renderer'; + async function loadPackage(metadata) { + + var PACKAGE_PATH = ''; + if (typeof window === 'object') { + PACKAGE_PATH = window['encodeURIComponent'](window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/'); + } else if (typeof process === 'undefined' && typeof location !== 'undefined') { + // web worker + PACKAGE_PATH = encodeURIComponent(location.pathname.substring(0, location.pathname.lastIndexOf('/')) + '/'); + } + var PACKAGE_NAME = 'index.data'; + var REMOTE_PACKAGE_BASE = 'index.data'; + var REMOTE_PACKAGE_NAME = Module['locateFile'] ? Module['locateFile'](REMOTE_PACKAGE_BASE, '') : REMOTE_PACKAGE_BASE; + var REMOTE_PACKAGE_SIZE = metadata['remote_package_size']; + + async function fetchRemotePackage(packageName, packageSize) { + if (isNode) { + var contents = require('fs').readFileSync(packageName); + return new Uint8Array(contents).buffer; + } + if (!Module['dataFileDownloads']) Module['dataFileDownloads'] = {}; + try { + var response = await fetch(packageName); + } catch (e) { + throw new Error(`Network Error: ${packageName}`, {e}); + } + if (!response.ok) { + throw new Error(`${response.status}: ${response.url}`); + } + + const chunks = []; + const headers = response.headers; + const total = Number(headers.get('Content-Length') || packageSize); + let loaded = 0; + + Module['setStatus'] && Module['setStatus']('Downloading data...'); + const reader = response.body.getReader(); + + while (1) { + var {done, value} = await reader.read(); + if (done) break; + chunks.push(value); + loaded += value.length; + Module['dataFileDownloads'][packageName] = {loaded, total}; + + let totalLoaded = 0; + let totalSize = 0; + + for (const download of Object.values(Module['dataFileDownloads'])) { + totalLoaded += download.loaded; + totalSize += download.total; + } + + Module['setStatus'] && Module['setStatus'](`Downloading data... (${totalLoaded}/${totalSize})`); + } + + const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0)); + let offset = 0; + for (const chunk of chunks) { + packageData.set(chunk, offset); + offset += chunk.length; + } + return packageData.buffer; + } + + var fetchPromise; + var fetched = Module['getPreloadedPackage'] && Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE); + + if (!fetched) { + // Note that we don't use await here because we want to execute the + // the rest of this function immediately. + fetchPromise = fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE); + } + + async function runWithFS(Module) { + + function assert(check, msg) { + if (!check) throw new Error(msg); + } +Module['FS_createPath']("/", "assets", true, true); + + async function processPackageData(arrayBuffer) { + assert(arrayBuffer, 'Loading data file failed.'); + assert(arrayBuffer.constructor.name === ArrayBuffer.name, 'bad input to processPackageData ' + arrayBuffer.constructor.name); + var byteArray = new Uint8Array(arrayBuffer); + var curr; + // Reuse the bytearray from the XHR as the source for file reads. + for (var file of metadata['files']) { + var name = file['filename']; + var data = byteArray.subarray(file['start'], file['end']); + // canOwn this data in the filesystem, it is a slice into the heap that will never change + Module['FS_createDataFile'](name, null, data, true, true, true); + } + Module['removeRunDependency']('datafile_index.data'); + } + Module['addRunDependency']('datafile_index.data'); + + if (!Module['preloadResults']) Module['preloadResults'] = {}; + + Module['preloadResults'][PACKAGE_NAME] = {fromCache: false}; + if (!fetched) { + fetched = await fetchPromise; + } + await processPackageData(fetched); + + } + // Detect whether the module JS file has already been loaded. + if (Module['FS_createPath']) { + runWithFS(Module); + } else { + if (!Module['preRun']) Module['preRun'] = []; + Module['preRun'].push(runWithFS); // FS is not initialized yet, wait for it + } + + } + loadPackage({"files": [{"filename": "/assets/ship.png", "start": 0, "end": 3871}], "remote_package_size": 3871}); + + })(); + +// end include: /tmp/tmpyzenctb4.js +// include: /tmp/tmpa4qxu_6j.js + + // All the pre-js content up to here must remain later on, we need to run + // it. + if ((typeof ENVIRONMENT_IS_WASM_WORKER != 'undefined' && ENVIRONMENT_IS_WASM_WORKER) || (typeof ENVIRONMENT_IS_PTHREAD != 'undefined' && ENVIRONMENT_IS_PTHREAD) || (typeof ENVIRONMENT_IS_AUDIO_WORKLET != 'undefined' && ENVIRONMENT_IS_AUDIO_WORKLET)) Module['preRun'] = []; + var necessaryPreJSTasks = Module['preRun'].slice(); + // end include: /tmp/tmpa4qxu_6j.js +// include: /tmp/tmpldy8u63b.js + + if (!Module['preRun']) throw 'Module.preRun should exist because file support used it; did a pre-js delete it?'; + necessaryPreJSTasks.forEach((task) => { + if (Module['preRun'].indexOf(task) < 0) throw 'All preRun tasks that exist before user pre-js code should remain after; did you replace Module or modify Module.preRun?'; + }); + // end include: /tmp/tmpldy8u63b.js + + +var programArgs = []; +var thisProgram = './this.program'; +var quit_ = (status, toThrow) => { + throw toThrow; +}; + +// In MODULARIZE mode _scriptName needs to be captured already at the very top of the page immediately when the page is parsed, so it is generated there +// before the page load. In non-MODULARIZE modes generate it here. +var _scriptName = globalThis.document?.currentScript?.src; + +if (typeof __filename != 'undefined') { // Node + _scriptName = __filename; +} else +if (ENVIRONMENT_IS_WORKER) { + _scriptName = self.location.href; +} + +// `/` should be present at the end if `scriptDirectory` is not empty +var scriptDirectory = ''; +function locateFile(path) { + if (Module['locateFile']) { + return Module['locateFile'](path, scriptDirectory); + } + return scriptDirectory + path; +} + +// Hooks that are implemented differently in different runtime environments. +var readAsync, readBinary; + +if (ENVIRONMENT_IS_NODE) { + const isNode = globalThis.process?.versions?.node && globalThis.process?.type != 'renderer'; + if (!isNode) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)'); + + // These modules will usually be used on Node.js. Load them eagerly to avoid + // the complexity of lazy-loading. + var fs = require('node:fs'); + + scriptDirectory = __dirname + '/'; + +// include: node_shell_read.js +readBinary = (filename) => { + // We need to re-wrap `file://` strings to URLs. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename); + assert(Buffer.isBuffer(ret)); + return ret; +}; + +readAsync = async (filename, binary = true) => { + // See the comment in the `readBinary` function. + filename = isFileURI(filename) ? new URL(filename) : filename; + var ret = fs.readFileSync(filename, binary ? undefined : 'utf8'); + assert(binary ? Buffer.isBuffer(ret) : typeof ret == 'string'); + return ret; +}; +// end include: node_shell_read.js + if (process.argv.length > 1) { + thisProgram = process.argv[1].replace(/\\/g, '/'); + } + + programArgs = process.argv.slice(2); + + // MODULARIZE will export the module in the proper place outside, we don't need to export here + if (typeof module != 'undefined') { + module['exports'] = Module; + } + + quit_ = (status, toThrow) => { + process.exitCode = status; + throw toThrow; + }; + +} else +if (ENVIRONMENT_IS_SHELL) { + +} else + +// Note that this includes Node.js workers when relevant (pthreads is enabled). +// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and +// ENVIRONMENT_IS_NODE. +if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + try { + scriptDirectory = new URL('.', _scriptName).href; // includes trailing slash + } catch { + // Must be a `blob:` or `data:` URL (e.g. `blob:http://site.com/etc/etc`), we cannot + // infer anything from them. + } + + if (!(globalThis.window || globalThis.WorkerGlobalScope)) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)'); + + { +// include: web_or_worker_shell_read.js +if (ENVIRONMENT_IS_WORKER) { + readBinary = (url) => { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.responseType = 'arraybuffer'; + xhr.send(null); + return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response)); + }; + } + + readAsync = async (url) => { + // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url. + // See https://github.com/github/fetch/pull/92#issuecomment-140665932 + // Cordova or Electron apps are typically loaded from a file:// url. + // So use XHR on webview if URL is a file URL. + if (isFileURI(url)) { + return new Promise((resolve, reject) => { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = 'arraybuffer'; + xhr.onload = () => { + if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 + resolve(xhr.response); + return; + } + reject(xhr.status); + }; + xhr.onerror = reject; + xhr.send(null); + }); + } + var response = await fetch(url, { credentials: 'same-origin' }); + if (response.ok) { + return response.arrayBuffer(); + } + throw new Error(response.status + ' : ' + response.url); + }; +// end include: web_or_worker_shell_read.js + } +} else +{ + throw new Error('environment detection error'); +} + +var out = console.log.bind(console); +var err = console.error.bind(console); + +var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js'; +var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js'; +var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js'; +var FETCHFS = 'FETCHFS is no longer included by default; build with -lfetchfs.js'; +var ICASEFS = 'ICASEFS is no longer included by default; build with -licasefs.js'; +var JSFILEFS = 'JSFILEFS is no longer included by default; build with -ljsfilefs.js'; +var OPFS = 'OPFS is no longer included by default; build with -lopfs.js'; + +var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js'; + +// perform assertions in shell.js after we set up out() and err(), as otherwise +// if an assertion fails it cannot print the message + +assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time (add `shell` to `-sENVIRONMENT` to enable)'); + +// end include: shell.js + +// include: preamble.js +// === Preamble library stuff === + +// Documentation for the public APIs defined in this file must be updated in: +// site/source/docs/api_reference/preamble.js.rst +// A prebuilt local version of the documentation is available at: +// site/build/text/docs/api_reference/preamble.js.txt +// You can also build docs locally as HTML or other formats in site/ +// An online HTML version (which may be of a different version of Emscripten) +// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html + +var wasmBinary; + +if (!globalThis.WebAssembly) { + err('no native wasm support detected'); +} + +// Wasm globals + +//======================================== +// Runtime essentials +//======================================== + +// whether we are quitting the application. no code should run after this. +// set in exit() and abort() +var ABORT = false; + +// set by exit() and abort(). Passed to 'onExit' handler. +// NOTE: This is also used as the process return code in shell environments +// but only when noExitRuntime is false. +var EXITSTATUS; + +// In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we +// don't define it at all in release modes. This matches the behaviour of +// MINIMAL_RUNTIME. +// TODO(sbc): Make this the default even without STRICT enabled. +/** @type {function(*, string=)} */ +function assert(condition, text) { + if (!condition) { + abort('Assertion failed' + (text ? ': ' + text : '')); + } +} + +// We used to include malloc/free by default in the past. Show a helpful error in +// builds with assertions. + +/** + * Indicates whether filename is delivered via file protocol (as opposed to http/https) + * @noinline + */ +var isFileURI = (filename) => filename.startsWith('file://'); + +// include: runtime_common.js +// include: runtime_exceptions.js +// Base Emscripten EH error class +class EmscriptenEH {} + +class EmscriptenSjLj extends EmscriptenEH {} + +// end include: runtime_exceptions.js +// include: runtime_debug.js +var runtimeDebug = true; // Switch to false at runtime to disable logging at the right times + +// Used by XXXXX_DEBUG settings to output debug messages. +function dbg(...args) { + if (!runtimeDebug && typeof runtimeDebug != 'undefined') return; + // TODO(sbc): Make this configurable somehow. Its not always convenient for + // logging to show up as warnings. + console.warn(...args); +} + +// Endianness check +(() => { + var h16 = new Int16Array(1); + var h8 = new Int8Array(h16.buffer); + h16[0] = 0x6373; + if (h8[0] !== 0x73 || h8[1] !== 0x63) abort('Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)'); +})(); + +function consumedModuleProp(prop) { + var value = Module[prop]; + var msg = `Attempt to modify \`Module.${prop}\` after it has already been processed. This can happen, for example, when code is injected via '--post-js' rather than '--pre-js'`; + if (Array.isArray(value)) { + value = new Proxy(value, { + set(target, key, val) { + abort(msg); + return false; + }, + defineProperty(target, key, descriptor) { + abort(msg); + return false; + }, + deleteProperty(target, key) { + abort(msg); + return false; + } + }); + } + Object.defineProperty(Module, prop, { + configurable: true, + get() { return value; }, + set() { + abort(msg); + } + }); +} + +function makeInvalidEarlyAccess(name) { + return () => assert(false, `call to '${name}' via reference taken before Wasm module initialization`); + +} + +function ignoredModuleProp(prop) { + if (Object.getOwnPropertyDescriptor(Module, prop)) { + abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`); + } +} + +// forcing the filesystem exports a few things by default +function isExportedByForceFilesystem(name) { + return name === 'FS_createPath' || + name === 'FS_createDataFile' || + name === 'FS_createPreloadedFile' || + name === 'FS_preloadFile' || + name === 'FS_unlink' || + name === 'addRunDependency' || + // The old FS has some functionality that WasmFS lacks. + name === 'FS_createLazyFile' || + name === 'FS_createDevice' || + name === 'removeRunDependency'; +} + +/** + * Intercept access to a symbols in the global symbol. This enables us to give + * informative warnings/errors when folks attempt to use symbols they did not + * include in their build, or no symbols that no longer exist. + * + * We don't define this in MODULARIZE mode since in that mode emscripten symbols + * are never placed in the global scope. + */ +function hookGlobalSymbolAccess(sym, func) { + if (!Object.getOwnPropertyDescriptor(globalThis, sym)) { + Object.defineProperty(globalThis, sym, { + configurable: true, + get() { + func(); + return undefined; + } + }); + } +} + +function missingGlobal(sym, msg) { + hookGlobalSymbolAccess(sym, () => { + warnOnce(`\`${sym}\` is no longer defined by emscripten. ${msg}`); + }); +} + +missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer'); +missingGlobal('asm', 'Please use wasmExports instead'); + +function missingLibrarySymbol(sym) { + hookGlobalSymbolAccess(sym, () => { + // Can't `abort()` here because it would break code that does runtime + // checks. e.g. `if (typeof SDL === 'undefined')`. + var msg = `\`${sym}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`; + // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in + // library.js, which means $name for a JS name with no prefix, or name + // for a JS name like _name. + var librarySymbol = sym; + if (!librarySymbol.startsWith('_')) { + librarySymbol = '$' + sym; + } + msg += ` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`; + if (isExportedByForceFilesystem(sym)) { + msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; + } + warnOnce(msg); + }); + + // Any symbol that is not included from the JS library is also (by definition) + // not exported on the Module object. + unexportedRuntimeSymbol(sym); +} + +function unexportedRuntimeSymbol(sym) { + if (!Object.getOwnPropertyDescriptor(Module, sym)) { + Object.defineProperty(Module, sym, { + configurable: true, + get() { + var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`; + if (isExportedByForceFilesystem(sym)) { + msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; + } + abort(msg); + }, + }); + } +} + +// end include: runtime_debug.js +// include: runtime_stack_check.js +const stackCookie1 = 0x02135467; +const stackCookie2 = 0x89BACDFE; + +// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode. +function writeStackCookie() { + var max = _emscripten_stack_get_end(); + assert((max & 3) == 0); + // If the stack ends at address zero we write our cookies 4 bytes into the + // stack. This prevents interference with SAFE_HEAP and ASAN which also + // monitor writes to address zero. + if (max == 0) { + max += 4; + } + // The stack grow downwards towards _emscripten_stack_get_end. + // We write cookies to the final two words in the stack and detect if they are + // ever overwritten. + HEAPU32[((max)>>2)] = stackCookie1; + HEAPU32[(((max)+(4))>>2)] = stackCookie2; + // Also test the global address 0 for integrity. + HEAPU32[((0)>>2)] = 1668509029; +} + +function u32ToHexString(num) { + return '0x' + (num >>> 0).toString(16).padStart(8, '0'); +} + +function checkStackCookie() { + if (ABORT) return; + var max = _emscripten_stack_get_end(); + // See writeStackCookie(). + if (max == 0) { + max += 4; + } + var val1 = HEAPU32[((max)>>2)]; + var val2 = HEAPU32[(((max)+(4))>>2)]; + if (val1 != stackCookie1 || val2 != stackCookie2) { + abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords ${u32ToHexString(stackCookie2)} and ${u32ToHexString(stackCookie1)}, but received ${u32ToHexString(val2)} ${u32ToHexString(val1)}`); + } + // Also test the global address 0 for integrity. + if (HEAPU32[((0)>>2)] != 0x63736d65 /* 'emsc' */) { + abort('Runtime error: The application has corrupted its heap memory area (address zero)!'); + } +} +// end include: runtime_stack_check.js +// Memory management + +var runtimeInitialized = false; + + + +function updateMemoryViews() { + // When memory growth is disabled this function should be called exactly once. + assert(!HEAP8, 'updateMemoryViews should only be called once when ALLOW_MEMORY_GROWTH=0'); + var b = wasmMemory.buffer; + HEAP8 = new Int8Array(b); + HEAP16 = new Int16Array(b); + HEAPU8 = new Uint8Array(b); + HEAPU16 = new Uint16Array(b); + HEAP32 = new Int32Array(b); + HEAPU32 = new Uint32Array(b); + HEAPF32 = new Float32Array(b); + HEAPF64 = new Float64Array(b); + HEAP64 = new BigInt64Array(b); + +} + +// include: memoryprofiler.js +// end include: memoryprofiler.js +// end include: runtime_common.js +assert(globalThis.Int32Array && globalThis.Float64Array && Int32Array.prototype.subarray && Int32Array.prototype.set, + 'JS engine does not provide full typed array support'); + +function preRun() { + var preRun = Module['preRun']; + if (preRun) { + if (typeof preRun == 'function') preRun = [preRun]; + onPreRuns.push(...preRun); + } + consumedModuleProp('preRun'); + // Begin ATPRERUNS hooks + callRuntimeCallbacks(onPreRuns); + // End ATPRERUNS hooks +} + +function initRuntime() { + assert(!runtimeInitialized); + runtimeInitialized = true; + + checkStackCookie(); + + // Begin ATINITS hooks + if (!Module['noFSInit'] && !FS.initialized) FS.init(); +TTY.init(); + // End ATINITS hooks + + wasmExports['__wasm_call_ctors'](); + + // Begin ATPOSTCTORS hooks + FS.ignorePermissions = false; + // End ATPOSTCTORS hooks + + checkStackCookie(); +} + +function postRun() { + checkStackCookie(); + + var postRun = Module['postRun']; + if (postRun) { + if (typeof postRun == 'function') postRun = [postRun]; + onPostRuns.push(...postRun); + } + consumedModuleProp('postRun'); + + // Begin ATPOSTRUNS hooks + callRuntimeCallbacks(onPostRuns); + // End ATPOSTRUNS hooks +} + +/** + * @param {string|number=} what + */ +function abort(what) { + Module['onAbort']?.(what); + + what = `Aborted(${what})`; + // TODO(sbc): Should we remove printing and leave it up to whoever + // catches the exception? + err(what); + + ABORT = true; + + if (what.search(/RuntimeError: [Uu]nreachable/) >= 0) { + what += '. "unreachable" may be due to ASYNCIFY_STACK_SIZE not being large enough (try increasing it)'; + } + + // Use a wasm runtime error, because a JS error might be seen as a foreign + // exception, which means we'd run destructors on it. We need the error to + // simply make the program stop. + // FIXME This approach does not work in Wasm EH because it currently does not assume + // all RuntimeErrors are from traps; it decides whether a RuntimeError is from + // a trap or not based on a hidden field within the object. So at the moment + // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that + // allows this in the wasm spec. + + // Suppress closure compiler warning here. Closure compiler's builtin extern + // definition for WebAssembly.RuntimeError claims it takes no arguments even + // though it can. + // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed. + /** @suppress {checkTypes} */ + var e = new WebAssembly.RuntimeError(what); + + // Throw the error whether or not MODULARIZE is set because abort is used + // in code paths apart from instantiation where an exception is expected + // to be thrown when abort is called. + throw e; +} + +function createExportWrapper(name, func, nargs) { + assert(func); + return (...args) => { + assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`); + // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled. + assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`); + return func(...args); + }; +} + +var wasmBinaryFile; + +function findWasmBinary() { + return locateFile('index.wasm'); +} + +function getBinarySync(file) { + if (readBinary) { + return readBinary(file); + } + // Throwing a plain string here, even though it not normally advisable since + // this gets turning into an `abort` in instantiateArrayBuffer. + throw 'both async and sync fetching of the wasm failed'; +} + +async function getWasmBinary(binaryFile) { + // If we don't have the binary yet, load it asynchronously using readAsync. + if (!wasmBinary) { + // Fetch the binary using readAsync + try { + var response = await readAsync(binaryFile); + return new Uint8Array(response); + } catch { + // Fall back to getBinarySync below; + } + } + + // Otherwise, getBinarySync should be able to get it synchronously + return getBinarySync(binaryFile); +} + +async function instantiateArrayBuffer(binaryFile, imports) { + try { + var binary = await getWasmBinary(binaryFile); + var instance = await WebAssembly.instantiate(binary, imports); + return instance; + } catch (reason) { + err(`failed to asynchronously prepare wasm: ${reason}`); + + // Warn on some common problems. + if (isFileURI(binaryFile)) { + err(`warning: Loading from a file URI (${binaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`); + } + abort(reason); + } +} + +async function instantiateAsync(binary, binaryFile, imports) { + if (!binary + // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. + && !isFileURI(binaryFile) + // Avoid using instantiateStreaming() on Node.js since the `fetch()` API + // does not support `file://` URLs. + // See: https://github.com/emscripten-core/emscripten/pull/16917 + && !ENVIRONMENT_IS_NODE + ) { + try { + var response = fetch(binaryFile, { credentials: 'same-origin' }); + var instantiationResult = await WebAssembly.instantiateStreaming(response, imports); + return instantiationResult; + } catch (reason) { + // We expect the most common failure cause to be a bad MIME type for the binary, + // in which case falling back to ArrayBuffer instantiation should work. + err(`wasm streaming compile failed: ${reason}`); + err('falling back to ArrayBuffer instantiation'); + // fall back of instantiateArrayBuffer below + }; + } + return instantiateArrayBuffer(binaryFile, imports); +} + +function getWasmImports() { + // instrumenting imports is used in asyncify in two ways: to add assertions + // that check for proper import use, and for JSPI we use them to set up + // the Promise API on the import side. + Asyncify.instrumentWasmImports(wasmImports); + // prepare imports + var imports = { + 'env': wasmImports, + 'wasi_snapshot_preview1': wasmImports, + }; + return imports; +} + +// Create the wasm instance. +// Receives the wasm imports, returns the exports. +async function createWasm() { + // Load the wasm module and create an instance of using native support in the JS engine. + // handle a generated wasm instance, receiving its exports and + // performing other necessary setup + function receiveInstance(instance) { + wasmExports = instance.exports; + + wasmExports = Asyncify.instrumentWasmExports(wasmExports); + + assignWasmExports(wasmExports); + + updateMemoryViews(); + + return wasmExports; + } + + // Prefer streaming instantiation if available. + // Async compilation can be confusing when an error on the page overwrites Module + // (for example, if the order of elements is wrong, and the one defining Module is + // later), so we save Module and check it later. + var trueModule = Module; + function receiveInstantiationResult(result) { + // 'result' is a ResultObject object which has both the module and instance. + // receiveInstance() will swap in the exports (to Module.asm) so they can be called + assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?'); + trueModule = null; + // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line. + // When the regression is fixed, can restore the above PTHREADS-enabled path. + return receiveInstance(result['instance']); + } + + var info = getWasmImports(); + + // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback + // to manually instantiate the Wasm module themselves. This allows pages to + // run the instantiation parallel to any other async startup actions they are + // performing. + // Also pthreads and wasm workers initialize the wasm instance through this + // path. + var instantiateWasm = Module['instantiateWasm']; + if (instantiateWasm) { + return new Promise((resolve) => { + try { + instantiateWasm(info, (inst) => resolve(receiveInstance(inst))); + } catch(e) { + err(`Module.instantiateWasm callback failed with error: ${e}`); + throw e; + } + }); + } + + wasmBinaryFile ??= findWasmBinary(); + var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info); + var exports = receiveInstantiationResult(result); + return exports; +} + +// end include: preamble.js + +// Begin JS library code + + + class ExitStatus { + name = 'ExitStatus'; + constructor(status) { + this.message = `Program terminated with exit(${status})`; + this.status = status; + } + } + + /** @type {!Int32Array} */ + var HEAP32; + + /** @type {!Int8Array} */ + var HEAP8; + + /** @type {!Uint32Array} */ + var HEAPU32; + + var callRuntimeCallbacks = (callbacks) => { + while (callbacks.length > 0) { + // Pass the module as the first argument. + callbacks.shift()(Module); + } + }; + var onPostRuns = []; + var addOnPostRun = (cb) => onPostRuns.push(cb); + + var onPreRuns = []; + var addOnPreRun = (cb) => onPreRuns.push(cb); + + + var dynCalls = { + }; + var dynCallLegacy = (sig, ptr, args) => { + sig = sig.replace(/p/g, 'i') + assert(sig in dynCalls, `bad function pointer type - sig is not in dynCalls: '${sig}'`); + if (args?.length) { + // j (64-bit integer) is fine, and is implemented as a BigInt. Without + // legalization, the number of parameters should match (j is not expanded + // into two i's). + assert(args.length === sig.length - 1); + } else { + assert(sig.length == 1); + } + var f = dynCalls[sig]; + return f(ptr, ...args); + }; + var dynCall = (sig, ptr, args = [], promising = false) => { + assert(ptr, `null function pointer in dynCall`); + assert(!promising, 'async dynCall is not supported in this mode') + var rtn = dynCallLegacy(sig, ptr, args); + + function convert(rtn) { + return rtn; + } + + return convert(rtn); + }; + + var noExitRuntime = true; + + function ptrToString(ptr) { + assert(typeof ptr === 'number', `ptrToString expects a number, got ${typeof ptr}`); + // Convert to 32-bit unsigned value + ptr >>>= 0; + return '0x' + ptr.toString(16).padStart(8, '0'); + } + + var stackRestore = (val) => __emscripten_stack_restore(val); + + var stackSave = () => _emscripten_stack_get_current(); + + var warnOnce = (text) => { + warnOnce.shown ||= {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text; + err(text); + } + }; + + + + var UTF8Decoder = globalThis.TextDecoder && new TextDecoder(); + + + /** + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number} idx + * @param {number=} maxBytesToRead + * @param {boolean=} ignoreNul + * @return {number} + */ + var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => { + var maxIdx = idx + maxBytesToRead; + if (ignoreNul) return maxIdx; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. + // As a tiny code save trick, compare idx against maxIdx using a negation, + // so that maxBytesToRead=undefined/NaN means Infinity. + while (heapOrArray[idx] && !(idx >= maxIdx)) ++idx; + return idx; + }; + + + /** + * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given + * array that contains uint8 values, returns a copy of that string as a + * Javascript String object. + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number=} idx + * @param {number=} maxBytesToRead + * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character. + * @return {string} + */ + var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => { + + var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul); + + // When using conditional TextDecoder, skip it for short strings as the overhead of the native call is not worth it. + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr)); + } + var str = ''; + while (idx < endPtr) { + // For UTF8 byte structure, see: + // http://en.wikipedia.org/wiki/UTF-8#Description + // https://www.ietf.org/rfc/rfc2279.txt + // https://tools.ietf.org/html/rfc3629 + var u0 = heapOrArray[idx++]; + if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } + var u1 = heapOrArray[idx++] & 63; + if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } + var u2 = heapOrArray[idx++] & 63; + if ((u0 & 0xF0) == 0xE0) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { + if ((u0 & 0xF8) != 0xF0) warnOnce(`Invalid UTF-8 leading byte ${ptrToString(u0)} encountered when deserializing a UTF-8 string in wasm memory to a JS string!`); + u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63); + } + + if (u0 < 0x10000) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } + } + return str; + }; + + /** @type {!Uint8Array} */ + var HEAPU8; + + /** + * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the + * emscripten HEAP, returns a copy of that string as a Javascript String object. + * + * @param {number} ptr + * @param {number=} maxBytesToRead - An optional length that specifies the + * maximum number of bytes to read. You can omit this parameter to scan the + * string until the first 0 byte. If maxBytesToRead is passed, and the string + * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the + * string will cut short at that byte index. + * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character. + * @return {string} + */ + var UTF8ToString = (ptr, maxBytesToRead, ignoreNul) => { + assert(typeof ptr == 'number', `UTF8ToString expects a number (got ${typeof ptr})`); + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead, ignoreNul) : ''; + }; + var ___assert_fail = (condition, filename, line, func) => + abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']); + + var PATH = { + isAbs:(path) => path.charAt(0) === '/', + splitPath:(filename) => { + var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + return splitPathRe.exec(filename).slice(1); + }, + normalizeArray:(parts, allowAboveRoot) => { + // if the path tries to go above the root, `up` ends up > 0 + 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 the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up; up--) { + parts.unshift('..'); + } + } + return parts; + }, + normalize:(path) => { + var isAbsolute = PATH.isAbs(path), + trailingSlash = path.slice(-1) === '/'; + // Normalize the path + path = PATH.normalizeArray(path.split('/').filter((p) => !!p), !isAbsolute).join('/'); + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + return (isAbsolute ? '/' : '') + path; + }, + dirname:(path) => { + var result = PATH.splitPath(path), + root = result[0], + dir = result[1]; + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.slice(0, -1); + } + return root + dir; + }, + basename:(path) => path && path.match(/([^\/]+|\/)\/*$/)[1], +join:(...paths) => PATH.normalize(paths.join('/')), +join2:(l, r) => PATH.normalize(l + '/' + r), +}; + +var initRandomFill = () => { + // This block is not needed on v19+ since crypto.getRandomValues is builtin + if (ENVIRONMENT_IS_NODE) { + var nodeCrypto = require('node:crypto'); + return (view) => (nodeCrypto.randomFillSync(view), 0); + } + + return (view) => (crypto.getRandomValues(view), 0); + }; +var randomFill = (view) => (randomFill = initRandomFill())(view); + + + +var PATH_FS = { +resolve:(...args) => { + var resolvedPath = '', + resolvedAbsolute = false; + for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? args[i] : FS.cwd(); + // Skip empty and invalid entries + if (typeof path != 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + return ''; // an invalid portion invalidates the whole thing + } + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = PATH.isAbs(path); + } + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter((p) => !!p), !resolvedAbsolute).join('/'); + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; + }, +relative:(from, to) => { + from = PATH_FS.resolve(from).slice(1); + to = PATH_FS.resolve(to).slice(1); + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + var end = arr.length - 1; + for (; end >= 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; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + return outputParts.join('/'); + }, +}; + + + +var FS_stdin_getChar_buffer = []; + +var lengthBytesUTF8 = (str) => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code + // unit, not a Unicode code point of the character! So decode + // UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var c = str.charCodeAt(i); // possibly a lead surrogate + if (c <= 0x7F) { + len++; + } else if (c <= 0x7FF) { + len += 2; + } else if (c >= 0xD800 && c <= 0xDFFF) { + len += 4; ++i; + } else { + len += 3; + } + } + return len; + }; + +var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + assert(typeof str === 'string', `stringToUTF8Array expects a string (got ${typeof str})`); + // Parameter maxBytesToWrite is not optional. Negative values, 0, null, + // undefined and false each don't write out any bytes. + if (!(maxBytesToWrite > 0)) + return 0; + + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator. + for (var i = 0; i < str.length; ++i) { + // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description + // and https://www.ietf.org/rfc/rfc2279.txt + // and https://tools.ietf.org/html/rfc3629 + var u = str.codePointAt(i); + if (u <= 0x7F) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 0x7FF) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 0xC0 | (u >> 6); + heap[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0xFFFF) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 0xE0 | (u >> 12); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + if (u > 0x10FFFF) warnOnce(`Invalid Unicode code point ${ptrToString(u)} encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).`); + heap[outIdx++] = 0xF0 | (u >> 18); + heap[outIdx++] = 0x80 | ((u >> 12) & 63); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16. + // We need to manually skip over the second code unit for correct iteration. + i++; + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx] = 0; + return outIdx - startIdx; + }; +/** @type {function(string, boolean=, number=)} */ + var 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 FS_stdin_getChar = () => { + if (!FS_stdin_getChar_buffer.length) { + var result = null; + if (ENVIRONMENT_IS_NODE) { + // we will read data by chunks of BUFSIZE + var BUFSIZE = 256; + var buf = Buffer.alloc(BUFSIZE); + var bytesRead = 0; + + // For some reason we must suppress a closure warning here, even though + // fd definitely exists on process.stdin, and is even the proper way to + // get the fd of stdin, + // https://github.com/nodejs/help/issues/2136#issuecomment-523649904 + // This started to happen after moving this logic out of library_tty.js, + // so it is related to the surrounding code in some unclear manner. + /** @suppress {missingProperties} */ + var fd = process.stdin.fd; + + try { + bytesRead = fs.readSync(fd, buf, 0, BUFSIZE); + } catch(e) { + // Cross-platform differences: on Windows, reading EOF throws an + // exception, but on other OSes, reading EOF returns 0. Uniformize + // behavior by treating the EOF exception to return 0. + if (e.toString().includes('EOF')) bytesRead = 0; + else throw e; + } + + if (bytesRead > 0) { + result = buf.slice(0, bytesRead).toString('utf-8'); + } + } else + if (globalThis.window?.prompt) { + // Browser. + result = window.prompt('Input: '); // returns null on cancel + if (result !== null) { + result += '\n'; + } + } else + {} + if (!result) { + return null; + } + FS_stdin_getChar_buffer = intArrayFromString(result, true); + } + return FS_stdin_getChar_buffer.shift(); + }; + var TTY = { + ttys:[], + init() { + // https://github.com/emscripten-core/emscripten/pull/1555 + // if (ENVIRONMENT_IS_NODE) { + // // currently, FS.init does not distinguish if process.stdin is a file or TTY + // // device, it always assumes it's a TTY device. because of this, we're forcing + // // process.stdin to UTF8 encoding to at least make stdin reading compatible + // // with text files until FS.init can be refactored. + // process.stdin.setEncoding('utf8'); + // } + }, + shutdown() { + // https://github.com/emscripten-core/emscripten/pull/1555 + // if (ENVIRONMENT_IS_NODE) { + // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)? + // // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation + // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists? + // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle + // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call + // process.stdin.pause(); + // } + }, + register(dev, ops) { + TTY.ttys[dev] = { input: [], output: [], ops: ops }; + FS.registerDevice(dev, TTY.stream_ops); + }, + stream_ops:{ + open(stream) { + var tty = TTY.ttys[stream.node.rdev]; + if (!tty) { + throw new FS.ErrnoError(43); + } + stream.tty = tty; + stream.seekable = false; + }, + close(stream) { + // flush any pending line data + stream.tty.ops.fsync(stream.tty); + }, + fsync(stream) { + stream.tty.ops.fsync(stream.tty); + }, + read(stream, buffer, offset, length, pos /* ignored */) { + if (!stream.tty || !stream.tty.ops.get_char) { + throw new FS.ErrnoError(60); + } + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = stream.tty.ops.get_char(stream.tty); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && !bytesRead) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset+i] = result; + // We currently only support canonical mode (ICANON), where + // read(2) returns as soon as a line delimiter is read. + if (result === 10) break; + } + if (bytesRead) { + stream.node.atime = Date.now(); + } + return bytesRead; + }, + write(stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.put_char) { + throw new FS.ErrnoError(60); + } + try { + for (var i = 0; i < length; i++) { + stream.tty.ops.put_char(stream.tty, buffer[offset+i]); + } + } catch (e) { + throw new FS.ErrnoError(29); + } + if (length) { + stream.node.mtime = stream.node.ctime = Date.now(); + } + return i; + }, + }, + default_tty_ops:{ + get_char(tty) { + return FS_stdin_getChar(); + }, + put_char(tty, val) { + if (val === null || val === 10) { + out(UTF8ArrayToString(tty.output)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle. + } + }, + fsync(tty) { + if (tty.output?.length > 0) { + out(UTF8ArrayToString(tty.output)); + tty.output = []; + } + }, + ioctl_tcgets(tty) { + // typical setting + return { + c_iflag: 25856, + c_oflag: 5, + c_cflag: 191, + c_lflag: 35387, + c_cc: [ + 0x03, 0x1c, 0x7f, 0x15, 0x04, 0x00, 0x01, 0x00, 0x11, 0x13, 0x1a, 0x00, + 0x12, 0x0f, 0x17, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ] + }; + }, + ioctl_tcsets(tty, optional_actions, data) { + // currently just ignore + return 0; + }, + ioctl_tiocgwinsz(tty) { + return [24, 80]; + }, + }, + default_tty1_ops:{ + put_char(tty, val) { + if (val === null || val === 10) { + err(UTF8ArrayToString(tty.output)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync(tty) { + if (tty.output?.length > 0) { + err(UTF8ArrayToString(tty.output)); + tty.output = []; + } + }, + }, + }; + + + var mmapAlloc = (size) => { + abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported'); + }; + + var MEMFS = { + ops_table:null, + mount(mount) { + return MEMFS.createNode(null, '/', 16895, 0); + }, + createNode(parent, name, mode, dev) { + if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { + // not supported + throw new FS.ErrnoError(63); + } + MEMFS.ops_table ||= { + dir: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + lookup: MEMFS.node_ops.lookup, + mknod: MEMFS.node_ops.mknod, + rename: MEMFS.node_ops.rename, + unlink: MEMFS.node_ops.unlink, + rmdir: MEMFS.node_ops.rmdir, + readdir: MEMFS.node_ops.readdir, + symlink: MEMFS.node_ops.symlink + }, + stream: { + llseek: MEMFS.stream_ops.llseek + } + }, + file: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: { + llseek: MEMFS.stream_ops.llseek, + read: MEMFS.stream_ops.read, + write: MEMFS.stream_ops.write, + mmap: MEMFS.stream_ops.mmap, + msync: MEMFS.stream_ops.msync + } + }, + link: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + readlink: MEMFS.node_ops.readlink + }, + stream: {} + }, + chrdev: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: FS.chrdev_stream_ops + } + }; + var node = FS.createNode(parent, name, mode, dev); + if (FS.isDir(node.mode)) { + node.node_ops = MEMFS.ops_table.dir.node; + node.stream_ops = MEMFS.ops_table.dir.stream; + node.contents = {}; + } else if (FS.isFile(node.mode)) { + node.node_ops = MEMFS.ops_table.file.node; + node.stream_ops = MEMFS.ops_table.file.stream; + // The actual number of bytes used in the typed array, as opposed to + // contents.length which gives the whole capacity. + node.usedBytes = 0; + // The byte data of the file is stored in a typed array. + // Note: typed arrays are not resizable like normal JS arrays are, so + // there is a small penalty involved for appending file writes that + // continuously grow a file similar to std::vector capacity vs used. + node.contents = MEMFS.emptyFileContents ??= new Uint8Array(0); + } else if (FS.isLink(node.mode)) { + node.node_ops = MEMFS.ops_table.link.node; + node.stream_ops = MEMFS.ops_table.link.stream; + } else if (FS.isChrdev(node.mode)) { + node.node_ops = MEMFS.ops_table.chrdev.node; + node.stream_ops = MEMFS.ops_table.chrdev.stream; + } + node.atime = node.mtime = node.ctime = Date.now(); + // add the new node to the parent + if (parent) { + parent.contents[name] = node; + parent.atime = parent.mtime = parent.ctime = node.atime; + } + return node; + }, + getFileDataAsTypedArray(node) { + assert(FS.isFile(node.mode), 'getFileDataAsTypedArray called on non-file'); + return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes. + }, + expandFileStorage(node, newCapacity) { + var prevCapacity = node.contents.length; + if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough. + // Don't expand strictly to the given requested limit if it's only a very + // small increase, but instead geometrically grow capacity. + // For small filesizes (<1MB), perform size*2 geometric increase, but for + // large sizes, do a much more conservative size*1.125 increase to avoid + // overshooting the allocation cap by a very large margin. + var CAPACITY_DOUBLING_MAX = 1024 * 1024; + newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0); + if (prevCapacity) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding. + var oldContents = MEMFS.getFileDataAsTypedArray(node); + node.contents = new Uint8Array(newCapacity); // Allocate new storage. + node.contents.set(oldContents); + }, + resizeFileStorage(node, newSize) { + if (node.usedBytes == newSize) return; + var oldContents = node.contents; + node.contents = new Uint8Array(newSize); // Allocate new storage. + node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage. + node.usedBytes = newSize; + }, + node_ops:{ + getattr(node) { + var attr = {}; + // device numbers reuse inode numbers. + attr.dev = FS.isChrdev(node.mode) ? node.id : 1; + attr.ino = node.id; + attr.mode = node.mode; + attr.nlink = 1; + attr.uid = 0; + attr.gid = 0; + attr.rdev = node.rdev; + if (FS.isDir(node.mode)) { + attr.size = 4096; + } else if (FS.isFile(node.mode)) { + attr.size = node.usedBytes; + } else if (FS.isLink(node.mode)) { + attr.size = node.link.length; + } else { + attr.size = 0; + } + attr.atime = new Date(node.atime); + attr.mtime = new Date(node.mtime); + attr.ctime = new Date(node.ctime); + // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize), + // but this is not required by the standard. + attr.blksize = 4096; + attr.blocks = Math.ceil(attr.size / attr.blksize); + return attr; + }, + setattr(node, attr) { + for (const key of ['mode', 'atime', 'mtime', 'ctime']) { + if (attr[key] != null) { + node[key] = attr[key]; + } + } + if (attr.size !== undefined) { + MEMFS.resizeFileStorage(node, attr.size); + } + }, + lookup(parent, name) { + throw new FS.ErrnoError(44); + }, + mknod(parent, name, mode, dev) { + return MEMFS.createNode(parent, name, mode, dev); + }, + rename(old_node, new_dir, new_name) { + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (new_node) { + if (FS.isDir(old_node.mode)) { + // if we're overwriting a directory at new_name, make sure it's empty. + for (var i in new_node.contents) { + throw new FS.ErrnoError(55); + } + } + FS.hashRemoveNode(new_node); + } + // do the internal rewiring + delete old_node.parent.contents[old_node.name]; + new_dir.contents[new_name] = old_node; + old_node.name = new_name; + new_dir.ctime = new_dir.mtime = old_node.parent.ctime = old_node.parent.mtime = Date.now(); + }, + unlink(parent, name) { + delete parent.contents[name]; + parent.ctime = parent.mtime = Date.now(); + }, + rmdir(parent, name) { + var node = FS.lookupNode(parent, name); + for (var i in node.contents) { + throw new FS.ErrnoError(55); + } + delete parent.contents[name]; + parent.ctime = parent.mtime = Date.now(); + }, + readdir(node) { + return ['.', '..', ...Object.keys(node.contents)]; + }, + symlink(parent, newname, oldpath) { + var node = MEMFS.createNode(parent, newname, 0o777 | 40960, 0); + node.link = oldpath; + return node; + }, + readlink(node) { + if (!FS.isLink(node.mode)) { + throw new FS.ErrnoError(28); + } + return node.link; + }, + }, + stream_ops:{ + read(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= stream.node.usedBytes) return 0; + var size = Math.min(stream.node.usedBytes - position, length); + assert(size >= 0); + buffer.set(contents.subarray(position, position + size), offset); + return size; + }, + write(stream, buffer, offset, length, position, canOwn) { + assert(buffer.subarray, 'FS.write expects a TypedArray'); + + if (!length) return 0; + var node = stream.node; + node.mtime = node.ctime = Date.now(); + + if (canOwn) { + assert(!position, 'canOwn must imply no weird position inside the file'); + node.contents = buffer.subarray(offset, offset + length); + node.usedBytes = length; + } else if (!node.usedBytes && !position) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data. + node.contents = buffer.slice(offset, offset + length); + node.usedBytes = length; + } else { + MEMFS.expandFileStorage(node, position+length); + // Use typed array write which is available. + node.contents.set(buffer.subarray(offset, offset + length), position); + node.usedBytes = Math.max(node.usedBytes, position + length); + } + return length; + }, + llseek(stream, offset, whence) { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + position += stream.node.usedBytes; + } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + mmap(stream, length, position, prot, flags) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr; + var allocated; + var contents = stream.node.contents; + // Only make a new copy when MAP_PRIVATE is specified. + if (!(flags & 2) && contents.buffer === HEAP8.buffer) { + // We can't emulate MAP_SHARED when the file is not backed by the + // buffer we're mapping to (e.g. the HEAP buffer). + allocated = false; + ptr = contents.byteOffset; + } else { + allocated = true; + ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + if (contents) { + // Try to avoid unnecessary slices. + if (position > 0 || position + length < contents.length) { + if (contents.subarray) { + contents = contents.subarray(position, position + length); + } else { + contents = Array.prototype.slice.call(contents, position, position + length); + } + } + HEAP8.set(contents, ptr); + } + } + return { ptr, allocated }; + }, + msync(stream, buffer, offset, length, mmapFlags) { + MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); + // should we check if bytesWritten and length are the same? + return 0; + }, + }, + }; + + var FS_modeStringToFlags = (str) => { + if (typeof str != 'string') return str; + var flagModes = { + 'r': 0, + 'r+': 2, + 'w': 512 | 64 | 1, + 'w+': 512 | 64 | 2, + 'a': 1024 | 64 | 1, + 'a+': 1024 | 64 | 2, + }; + var flags = flagModes[str]; + if (typeof flags == 'undefined') { + throw new Error(`Unknown file open mode: ${str}`); + } + return flags; + }; + + var FS_fileDataToTypedArray = (data) => { + if (typeof data == 'string') { + data = intArrayFromString(data, true); + } + if (!data.subarray) { + data = new Uint8Array(data); + } + return data; + }; + + var FS_getMode = (canRead, canWrite) => { + var mode = 0; + if (canRead) mode |= 292 | 73; + if (canWrite) mode |= 146; + return mode; + }; + + + + + var strError = (errno) => UTF8ToString(_strerror(errno)); + + var ERRNO_CODES = { + 'EPERM': 63, + 'ENOENT': 44, + 'ESRCH': 71, + 'EINTR': 27, + 'EIO': 29, + 'ENXIO': 60, + 'E2BIG': 1, + 'ENOEXEC': 45, + 'EBADF': 8, + 'ECHILD': 12, + 'EAGAIN': 6, + 'EWOULDBLOCK': 6, + 'ENOMEM': 48, + 'EACCES': 2, + 'EFAULT': 21, + 'ENOTBLK': 105, + 'EBUSY': 10, + 'EEXIST': 20, + 'EXDEV': 75, + 'ENODEV': 43, + 'ENOTDIR': 54, + 'EISDIR': 31, + 'EINVAL': 28, + 'ENFILE': 41, + 'EMFILE': 33, + 'ENOTTY': 59, + 'ETXTBSY': 74, + 'EFBIG': 22, + 'ENOSPC': 51, + 'ESPIPE': 70, + 'EROFS': 69, + 'EMLINK': 34, + 'EPIPE': 64, + 'EDOM': 18, + 'ERANGE': 68, + 'ENOMSG': 49, + 'EIDRM': 24, + 'ECHRNG': 106, + 'EL2NSYNC': 156, + 'EL3HLT': 107, + 'EL3RST': 108, + 'ELNRNG': 109, + 'EUNATCH': 110, + 'ENOCSI': 111, + 'EL2HLT': 112, + 'EDEADLK': 16, + 'ENOLCK': 46, + 'EBADE': 113, + 'EBADR': 114, + 'EXFULL': 115, + 'ENOANO': 104, + 'EBADRQC': 103, + 'EBADSLT': 102, + 'EDEADLOCK': 16, + 'EBFONT': 101, + 'ENOSTR': 100, + 'ENODATA': 116, + 'ETIME': 117, + 'ENOSR': 118, + 'ENONET': 119, + 'ENOPKG': 120, + 'EREMOTE': 121, + 'ENOLINK': 47, + 'EADV': 122, + 'ESRMNT': 123, + 'ECOMM': 124, + 'EPROTO': 65, + 'EMULTIHOP': 36, + 'EDOTDOT': 125, + 'EBADMSG': 9, + 'ENOTUNIQ': 126, + 'EBADFD': 127, + 'EREMCHG': 128, + 'ELIBACC': 129, + 'ELIBBAD': 130, + 'ELIBSCN': 131, + 'ELIBMAX': 132, + 'ELIBEXEC': 133, + 'ENOSYS': 52, + 'ENOTEMPTY': 55, + 'ENAMETOOLONG': 37, + 'ELOOP': 32, + 'EOPNOTSUPP': 138, + 'EPFNOSUPPORT': 139, + 'ECONNRESET': 15, + 'ENOBUFS': 42, + 'EAFNOSUPPORT': 5, + 'EPROTOTYPE': 67, + 'ENOTSOCK': 57, + 'ENOPROTOOPT': 50, + 'ESHUTDOWN': 140, + 'ECONNREFUSED': 14, + 'EADDRINUSE': 3, + 'ECONNABORTED': 13, + 'ENETUNREACH': 40, + 'ENETDOWN': 38, + 'ETIMEDOUT': 73, + 'EHOSTDOWN': 142, + 'EHOSTUNREACH': 23, + 'EINPROGRESS': 26, + 'EALREADY': 7, + 'EDESTADDRREQ': 17, + 'EMSGSIZE': 35, + 'EPROTONOSUPPORT': 66, + 'ESOCKTNOSUPPORT': 137, + 'EADDRNOTAVAIL': 4, + 'ENETRESET': 39, + 'EISCONN': 30, + 'ENOTCONN': 53, + 'ETOOMANYREFS': 141, + 'EUSERS': 136, + 'EDQUOT': 19, + 'ESTALE': 72, + 'ENOTSUP': 138, + 'ENOMEDIUM': 148, + 'EILSEQ': 25, + 'EOVERFLOW': 61, + 'ECANCELED': 11, + 'ENOTRECOVERABLE': 56, + 'EOWNERDEAD': 62, + 'ESTRPIPE': 135, + }; + + var asyncLoad = async (url) => { + var arrayBuffer = await readAsync(url); + assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`); + return new Uint8Array(arrayBuffer); + }; + + + var FS_createDataFile = (...args) => FS.createDataFile(...args); + + var getUniqueRunDependency = (id) => { + var orig = id; + while (1) { + if (!runDependencyTracking[id]) return id; + id = orig + Math.random(); + } + }; + + var dependenciesPromise = null; + var resolveRunDependencies = async () => dependenciesPromise; + var runDependencies = 0; + + + var dependenciesPromiseResolve = null; + + var runDependencyTracking = { + }; + + var runDependencyWatcher = null; + var removeRunDependency = (id) => { + runDependencies--; + + Module['monitorRunDependencies']?.(runDependencies); + + assert(id, 'removeRunDependency requires an ID'); + assert(runDependencyTracking[id]); + delete runDependencyTracking[id]; + if (!runDependencies) { + if (runDependencyWatcher !== null) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + } + dependenciesPromiseResolve(); + } + }; + + + + + var addRunDependency = (id) => { + if (!runDependencies) { + dependenciesPromise = new Promise((resolve) => dependenciesPromiseResolve = resolve); + } + runDependencies++; + + Module['monitorRunDependencies']?.(runDependencies); + + assert(id, 'addRunDependency requires an ID') + assert(!runDependencyTracking[id]); + runDependencyTracking[id] = 1; + if (!runDependencyWatcher && globalThis.setInterval) { + // Check for missing dependencies every few seconds + runDependencyWatcher = setInterval(() => { + if (ABORT) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + return; + } + var shown = false; + for (var dep in runDependencyTracking) { + if (!shown) { + shown = true; + err('still waiting on run dependencies:'); + } + err(`dependency: ${dep}`); + } + if (shown) { + err('(end of list)'); + } + }, 10000); + // Prevent this timer from keeping the runtime alive if nothing + // else is. + runDependencyWatcher.unref?.() + } + }; + + + var preloadPlugins = []; + var FS_handledByPreloadPlugin = async (byteArray, fullname) => { + // Ensure plugins are ready. + if (typeof Browser != 'undefined') Browser.init(); + + for (var plugin of preloadPlugins) { + if (plugin['canHandle'](fullname)) { + assert(plugin['handle'].constructor.name === 'AsyncFunction', 'Filesystem plugin handlers must be async functions (See #24914)') + return plugin['handle'](byteArray, fullname); + } + } + // If no plugin handled this file then return the original/unmodified + // byteArray. + return byteArray; + }; + var FS_preloadFile = async (parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish) => { + // TODO we should allow people to just pass in a complete filename instead + // of parent and name being that we just join them anyways + var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; + var dep = getUniqueRunDependency(`cp ${fullname}`); // might have several active requests for the same fullname + addRunDependency(dep); + + try { + var byteArray = url; + if (typeof url == 'string') { + byteArray = await asyncLoad(url); + } + + byteArray = await FS_handledByPreloadPlugin(byteArray, fullname); + preFinish?.(); + if (!dontCreateFile) { + FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn); + } + } finally { + removeRunDependency(dep); + } + }; + var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => { + FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror); + }; + + var FS = { + root:null, + mounts:[], + devices:{ + }, + streams:[], + nextInode:1, + nameTable:null, + currentPath:"/", + initialized:false, + ignorePermissions:true, + filesystems:null, + syncFSRequests:0, + ErrnoError:class extends Error { + name = 'ErrnoError'; + // We set the `name` property to be able to identify `FS.ErrnoError` + // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway. + // - when using PROXYFS, an error can come from an underlying FS + // as different FS objects have their own FS.ErrnoError each, + // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs. + // we'll use the reliable test `err.name == "ErrnoError"` instead + constructor(errno) { + super(runtimeInitialized ? strError(errno) : ''); + this.errno = errno; + for (var key in ERRNO_CODES) { + if (ERRNO_CODES[key] === errno) { + this.code = key; + break; + } + } + } + }, + FSStream:class { + shared = {}; + get object() { + return this.node; + } + set object(val) { + this.node = val; + } + get isRead() { + return (this.flags & 2097155) !== 1; + } + get isWrite() { + return (this.flags & 2097155) !== 0; + } + get isAppend() { + return (this.flags & 1024); + } + get flags() { + return this.shared.flags; + } + set flags(val) { + this.shared.flags = val; + } + get position() { + return this.shared.position; + } + set position(val) { + this.shared.position = val; + } + }, + FSNode:class { + node_ops = {}; + stream_ops = {}; + readMode = 292 | 73; + writeMode = 146; + mounted = null; + constructor(parent, name, mode, rdev) { + if (!parent) { + parent = this; // root node sets parent to itself + } + this.parent = parent; + this.mount = parent.mount; + this.id = FS.nextInode++; + this.name = name; + this.mode = mode; + this.rdev = rdev; + this.atime = this.mtime = this.ctime = Date.now(); + } + get read() { + return (this.mode & this.readMode) === this.readMode; + } + set read(val) { + val ? this.mode |= this.readMode : this.mode &= ~this.readMode; + } + get write() { + return (this.mode & this.writeMode) === this.writeMode; + } + set write(val) { + val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode; + } + get isFolder() { + return FS.isDir(this.mode); + } + get isDevice() { + return FS.isChrdev(this.mode); + } + // The per-inode readiness wait-queue. The node carries a Set of listener + // entries {cb}; producers (SOCKFS, PIPEFS) call notifyListeners on a + // readiness transition, and poll()/epoll consume it. It lives on the node + // (not the fd) so dup'd fds share one queue. Only nodes that derive real + // readiness (sockets, pipes, and an epoll's own node) ever use this - + // always-ready types (regular files, ttys) never register or notify. + addListener(cb, exclusive = false) { + var entry = {cb, exclusive}; + var listeners = (this.listeners ??= new Set()); + listeners.add(entry); + return {listeners, entry}; + } + notifyListeners(flags) { + // Iterates the set without copying, which is safe ONLY under a + // load-bearing contract that every internal listener must honour: + // 1. A listener must not run user code synchronously (a poll waiter only + // resolves a Promise; an epoll registration only re-lists + + // re-notifies; the epoll callback only schedules a tick). User code + // runs on a later tick, never inside this loop. + // 2. A listener may delete entries only from ITS OWN waiter, never from + // a sibling node's set that may be mid-iteration. (Deleting an entry + // of the set being iterated here is fine - a Set tolerates removal of + // a not-yet-visited entry mid-iteration; mutating a *different* node's + // set is fine because that set is not being iterated.) + // Violating either gives silently skipped wakeups that are near-impossible + // to reproduce. Any new producer/listener must preserve it. + if (!this.listeners) return; + // Fire every non-exclusive listener. Among EPOLLEXCLUSIVE registrations + // (one fd watched by several epolls) wake only one, rotating round-robin + // per node, to avoid a thundering herd. (Only epoll registrations are ever + // exclusive; poll waiters and a node's own consumers are not.) + var excl; + for (var entry of this.listeners) { + if (entry.exclusive) (excl ||= []).push(entry); + else entry.cb(flags); + } + if (excl) { + var i = (this.exclTurn || 0) % excl.length; + this.exclTurn = i + 1; + excl[i].cb(flags); + } + } + }, + lookupPath(path, opts = {}) { + if (!path) { + throw new FS.ErrnoError(44); + } + opts.follow_mount ??= true + + if (!PATH.isAbs(path)) { + path = FS.cwd() + '/' + path; + } + + // limit max consecutive symlinks to SYMLOOP_MAX. + linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) { + // split the absolute path + var parts = path.split('/').filter((p) => !!p); + + // start at the root + var current = FS.root; + var current_path = '/'; + + for (var i = 0; i < parts.length; i++) { + var islast = (i === parts.length-1); + if (islast && opts.parent) { + // stop resolving + break; + } + + if (parts[i] === '.') { + continue; + } + + if (parts[i] === '..') { + current_path = PATH.dirname(current_path); + if (FS.isRoot(current)) { + path = current_path + '/' + parts.slice(i + 1).join('/'); + // We're making progress here, don't let many consecutive ..'s + // lead to ELOOP + nlinks--; + continue linkloop; + } else { + current = current.parent; + } + continue; + } + + current_path = PATH.join2(current_path, parts[i]); + try { + current = FS.lookupNode(current, parts[i]); + } catch (e) { + // if noent_okay is true, suppress a ENOENT in the last component + // and return an object with an undefined node. This is needed for + // resolving symlinks in the path when creating a file. + if ((e?.errno === 44) && islast && opts.noent_okay) { + return { path: current_path }; + } + throw e; + } + + // jump to the mount's root node if this is a mountpoint + if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) { + current = current.mounted.root; + } + + // by default, lookupPath will not follow a symlink if it is the final path component. + // setting opts.follow = true will override this behavior. + if (FS.isLink(current.mode) && (!islast || opts.follow)) { + if (!current.node_ops.readlink) { + throw new FS.ErrnoError(52); + } + var link = current.node_ops.readlink(current); + if (!PATH.isAbs(link)) { + link = PATH.dirname(current_path) + '/' + link; + } + path = link + '/' + parts.slice(i + 1).join('/'); + continue linkloop; + } + } + return { path: current_path, node: current }; + } + throw new FS.ErrnoError(32); + }, + getPath(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(parentid, name) { + var hash = 0; + + for (var i = 0; i < name.length; i++) { + hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; + } + return ((parentid + hash) >>> 0) % FS.nameTable.length; + }, + hashAddNode(node) { + var hash = FS.hashName(node.parent.id, node.name); + node.name_next = FS.nameTable[hash]; + FS.nameTable[hash] = node; + }, + hashRemoveNode(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(parent, name) { + var errCode = FS.mayLookup(parent); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + 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; + } + } + // if we failed to find it in the cache, call into the VFS + return FS.lookup(parent, name); + }, + createNode(parent, name, mode, rdev) { + assert(typeof parent == 'object') + var node = new FS.FSNode(parent, name, mode, rdev); + + FS.hashAddNode(node); + + return node; + }, + destroyNode(node) { + FS.hashRemoveNode(node); + }, + isRoot(node) { + return node === node.parent; + }, + isMountpoint(node) { + return !!node.mounted; + }, + isFile(mode) { + return (mode & 61440) === 32768; + }, + isDir(mode) { + return (mode & 61440) === 16384; + }, + isLink(mode) { + return (mode & 61440) === 40960; + }, + isChrdev(mode) { + return (mode & 61440) === 8192; + }, + isBlkdev(mode) { + return (mode & 61440) === 24576; + }, + isFIFO(mode) { + return (mode & 61440) === 4096; + }, + isSocket(mode) { + return (mode & 49152) === 49152; + }, + flagsToPermissionString(flag) { + var perms = ['r', 'w', 'rw'][flag & 3]; + if ((flag & 512)) { + perms += 'w'; + } + return perms; + }, + nodePermissions(node, perms) { + if (FS.ignorePermissions) { + return 0; + } + // return 0 if any user, group or owner bits are set. + if (perms.includes('r') && !(node.mode & 292)) { + return 2; + } + if (perms.includes('w') && !(node.mode & 146)) { + return 2; + } + if (perms.includes('x') && !(node.mode & 73)) { + return 2; + } + return 0; + }, + mayLookup(dir) { + if (!FS.isDir(dir.mode)) return 54; + var errCode = FS.nodePermissions(dir, 'x'); + if (errCode) return errCode; + if (!dir.node_ops.lookup) return 2; + return 0; + }, + mayCreate(dir, name) { + if (!FS.isDir(dir.mode)) { + return 54; + } + try { + var node = FS.lookupNode(dir, name); + return 20; + } catch (e) { + } + return FS.nodePermissions(dir, 'wx'); + }, + mayDelete(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(node, flags) { + if (!node) { + return 44; + } + if (FS.isLink(node.mode)) { + return 32; + } + var mode = FS.flagsToPermissionString(flags); + if (FS.isDir(node.mode)) { + // opening for write + // TODO: check for O_SEARCH? (== search for dir only) + if (mode !== 'r' || (flags & (512 | 64))) { + return 31; + } + } + return FS.nodePermissions(node, mode); + }, + checkOpExists(op, err) { + if (!op) { + throw new FS.ErrnoError(err); + } + return op; + }, + MAX_OPEN_FDS:4096, + nextfd() { + for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) { + if (!FS.streams[fd]) { + return fd; + } + } + throw new FS.ErrnoError(33); + }, + getStreamChecked(fd) { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + return stream; + }, + getStream:(fd) => FS.streams[fd], + createStream(stream, fd = -1) { + assert(fd >= -1); + + // clone it, so we can return an instance of FSStream + stream = Object.assign(new FS.FSStream(), stream); + if (fd == -1) { + fd = FS.nextfd(); + } + stream.fd = fd; + FS.streams[fd] = stream; + return stream; + }, + closeStream(fd) { + FS.streams[fd] = null; + }, + dupStream(origStream, fd = -1) { + var stream = FS.createStream(origStream, fd); + stream.stream_ops?.dup?.(stream); + return stream; + }, + doSetAttr(stream, node, attr) { + var setattr = stream?.stream_ops.setattr; + var arg = setattr ? stream : node; + setattr ??= node.node_ops.setattr; + FS.checkOpExists(setattr, 63) + try { + setattr(arg, attr); + } catch (e) { + if (e instanceof RangeError) { + throw new FS.ErrnoError(22); + } + throw e; + } + }, + chrdev_stream_ops:{ + open(stream) { + var device = FS.getDevice(stream.node.rdev); + // override node's stream ops with the device's + stream.stream_ops = device.stream_ops; + // forward the open call + stream.stream_ops.open?.(stream); + }, + llseek() { + throw new FS.ErrnoError(70); + }, + }, + major:(dev) => ((dev) >> 8), + minor:(dev) => ((dev) & 0xff), + makedev:(ma, mi) => ((ma) << 8 | (mi)), + registerDevice(dev, ops) { + FS.devices[dev] = { stream_ops: ops }; + }, + getDevice:(dev) => FS.devices[dev], + getMounts(mount) { + var mounts = []; + var check = [mount]; + + while (check.length) { + var m = check.pop(); + + mounts.push(m); + + check.push(...m.mounts); + } + + return mounts; + }, + syncfs(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) { + assert(FS.syncFSRequests > 0); + 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); + } + }; + + // sync all mounts + for (var mount of mounts) { + if (mount.type.syncfs) { + mount.type.syncfs(mount, populate, done); + } else { + done(null); + } + } + }, + mount(type, opts, mountpoint) { + if (typeof type == 'string') { + // The filesystem was not included, and instead we have an error + // message stored in the variable. + throw type; + } + 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; // use the absolute 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, + opts, + mountpoint, + mounts: [] + }; + + // create a root node for the fs + var mountRoot = type.mount(mount); + mountRoot.mount = mount; + mount.root = mountRoot; + + if (root) { + FS.root = mountRoot; + } else if (node) { + // set as a mountpoint + node.mounted = mount; + + // add the new mount to the current mount's children + if (node.mount) { + node.mount.mounts.push(mount); + } + } + + return mountRoot; + }, + unmount(mountpoint) { + var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); + + if (!FS.isMountpoint(lookup.node)) { + throw new FS.ErrnoError(28); + } + + // destroy the nodes for this mount, and all its child mounts + var node = lookup.node; + var mount = node.mounted; + var mounts = FS.getMounts(mount); + + for (var [hash, current] of Object.entries(FS.nameTable)) { + while (current) { + var next = current.name_next; + + if (mounts.includes(current.mount)) { + FS.destroyNode(current); + } + + current = next; + } + } + + // no longer a mountpoint + node.mounted = null; + + // remove this mount from the child mounts + var idx = node.mount.mounts.indexOf(mount); + assert(idx !== -1); + node.mount.mounts.splice(idx, 1); + }, + lookup(parent, name) { + return parent.node_ops.lookup(parent, name); + }, + mknod(path, mode, dev) { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + var name = PATH.basename(path); + if (!name) { + throw new FS.ErrnoError(28); + } + if (name === '.' || name === '..') { + throw new FS.ErrnoError(20); + } + 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); + }, + statfs(path) { + return FS.statfsNode(FS.lookupPath(path, {follow: true}).node); + }, + statfsStream(stream) { + // We keep a separate statfsStream function because noderawfs overrides + // it. In noderawfs, stream.node is sometimes null. Instead, we need to + // look at stream.path. + return FS.statfsNode(stream.node); + }, + statfsNode(node) { + // NOTE: None of the defaults here are true. We're just returning safe and + // sane values. Currently nodefs and rawfs replace these defaults, + // other file systems leave them alone. + var rtn = { + bsize: 4096, + frsize: 4096, + blocks: 1e6, + bfree: 5e5, + bavail: 5e5, + files: FS.nextInode, + ffree: FS.nextInode - 1, + fsid: 42, + flags: 2, + namelen: 255, + }; + + if (node.node_ops.statfs) { + Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root)); + } + return rtn; + }, + create(path, mode = 0o666) { + mode &= 4095; + mode |= 32768; + return FS.mknod(path, mode, 0); + }, + mkdir(path, mode = 0o777) { + mode &= 511 | 512; + mode |= 16384; + return FS.mknod(path, mode, 0); + }, + mkdirTree(path, mode) { + var dirs = path.split('/'); + var d = ''; + for (var dir of dirs) { + if (!dir) continue; + if (d || PATH.isAbs(path)) d += '/'; + d += dir; + try { + FS.mkdir(d, mode); + } catch(e) { + if (e.errno != 20) throw e; + } + } + }, + mkdev(path, mode, dev) { + if (typeof dev == 'undefined') { + dev = mode; + mode = 0o666; + } + mode |= 8192; + return FS.mknod(path, mode, dev); + }, + symlink(oldpath, newpath) { + if (!PATH_FS.resolve(oldpath)) { + throw new FS.ErrnoError(44); + } + var lookup = FS.lookupPath(newpath, { parent: true }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var newname = PATH.basename(newpath); + var errCode = FS.mayCreate(parent, newname); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.symlink) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.symlink(parent, newname, oldpath); + }, + link(oldpath, newpath, flags) { + var lookup = FS.lookupPath(newpath, { parent: true }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var newname = PATH.basename(newpath); + var errCode = FS.mayCreate(parent, newname); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + // Hardlinks are only supported by filesystem backends that provide a + // `link` node op (e.g. NODERAWFS backed by the host). NODEFS omits it: + // a host hardlink cannot be confined to the mount root. + if (!parent.node_ops.link) { + throw new FS.ErrnoError(34); + } + return parent.node_ops.link(parent, newname, oldpath, flags); + }, + rename(old_path, new_path) { + var old_dirname = PATH.dirname(old_path); + var new_dirname = PATH.dirname(new_path); + var old_name = PATH.basename(old_path); + var new_name = PATH.basename(new_path); + // parents must exist + var lookup, old_dir, new_dir; + + // let the errors from non existent directories percolate up + lookup = FS.lookupPath(old_path, { parent: true }); + old_dir = lookup.node; + lookup = FS.lookupPath(new_path, { parent: true }); + new_dir = lookup.node; + + if (!old_dir || !new_dir) throw new FS.ErrnoError(44); + // need to be part of the same mount + if (old_dir.mount !== new_dir.mount) { + throw new FS.ErrnoError(75); + } + // source must exist + var old_node = FS.lookupNode(old_dir, old_name); + // old path should not be an ancestor of the new path + var relative = PATH_FS.relative(old_path, new_dirname); + if (relative.charAt(0) !== '.') { + throw new FS.ErrnoError(28); + } + // new path should not be an ancestor of the old path + relative = PATH_FS.relative(new_path, old_dirname); + if (relative.charAt(0) !== '.') { + throw new FS.ErrnoError(55); + } + // see if the new path already exists + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) { + // not fatal + } + // early out if nothing needs to change + if (old_node === new_node) { + return; + } + // we'll need to delete the old entry + var isdir = FS.isDir(old_node.mode); + var errCode = FS.mayDelete(old_dir, old_name, isdir); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + // need delete permissions if we'll be overwriting. + // need create permissions if new doesn't already exist. + errCode = new_node ? + FS.mayDelete(new_dir, new_name, isdir) : + FS.mayCreate(new_dir, new_name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!old_dir.node_ops.rename) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) { + throw new FS.ErrnoError(10); + } + // if we are going to change the parent, check write permissions + if (new_dir !== old_dir) { + errCode = FS.nodePermissions(old_dir, 'w'); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + // remove the node from the lookup hash + FS.hashRemoveNode(old_node); + // do the underlying fs rename + try { + old_dir.node_ops.rename(old_node, new_dir, new_name); + // update old node (we do this here to avoid each backend + // needing to) + old_node.parent = new_dir; + } catch (e) { + throw e; + } finally { + // add the node back to the hash (in case node_ops.rename + // changed its name) + FS.hashAddNode(old_node); + } + }, + rmdir(path) { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, true); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.rmdir) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.rmdir(parent, name); + FS.destroyNode(node); + }, + readdir(path) { + var lookup = FS.lookupPath(path, { follow: true }); + var node = lookup.node; + var readdir = FS.checkOpExists(node.node_ops.readdir, 54); + return readdir(node); + }, + unlink(path) { + var lookup = FS.lookupPath(path, { parent: true }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, false); + if (errCode) { + // According to POSIX, we should map EISDIR to EPERM, but + // we instead do what Linux does (and we must, as we use + // the musl linux libc). + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.unlink) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.unlink(parent, name); + FS.destroyNode(node); + }, + readlink(path) { + var lookup = FS.lookupPath(path); + var link = lookup.node; + if (!link) { + throw new FS.ErrnoError(44); + } + if (!link.node_ops.readlink) { + throw new FS.ErrnoError(28); + } + return link.node_ops.readlink(link); + }, + stat(path, dontFollow) { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + var node = lookup.node; + var getattr = FS.checkOpExists(node.node_ops.getattr, 63); + return getattr(node); + }, + fstat(fd) { + var stream = FS.getStreamChecked(fd); + var node = stream.node; + var getattr = stream.stream_ops.getattr; + var arg = getattr ? stream : node; + getattr ??= node.node_ops.getattr; + FS.checkOpExists(getattr, 63) + return getattr(arg); + }, + lstat(path) { + return FS.stat(path, true); + }, + doChmod(stream, node, mode, dontFollow) { + FS.doSetAttr(stream, node, { + mode: (mode & 4095) | (node.mode & ~4095), + ctime: Date.now(), + dontFollow + }); + }, + chmod(path, mode, dontFollow) { + var node; + if (typeof path == 'string') { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + node = lookup.node; + } else { + node = path; + } + FS.doChmod(null, node, mode, dontFollow); + }, + lchmod(path, mode) { + FS.chmod(path, mode, true); + }, + fchmod(fd, mode) { + var stream = FS.getStreamChecked(fd); + FS.doChmod(stream, stream.node, mode, false); + }, + doChown(stream, node, dontFollow) { + FS.doSetAttr(stream, node, { + timestamp: Date.now(), + dontFollow + // we ignore the uid / gid for now + }); + }, + chown(path, uid, gid, dontFollow) { + var node; + if (typeof path == 'string') { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + node = lookup.node; + } else { + node = path; + } + FS.doChown(null, node, dontFollow); + }, + lchown(path, uid, gid) { + FS.chown(path, uid, gid, true); + }, + fchown(fd, uid, gid) { + var stream = FS.getStreamChecked(fd); + FS.doChown(stream, stream.node, false); + }, + doTruncate(stream, node, len) { + if (FS.isDir(node.mode)) { + throw new FS.ErrnoError(31); + } + if (!FS.isFile(node.mode)) { + throw new FS.ErrnoError(28); + } + var errCode = FS.nodePermissions(node, 'w'); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.doSetAttr(stream, node, { + size: len, + timestamp: Date.now() + }); + }, + truncate(path, len) { + if (len < 0) { + throw new FS.ErrnoError(28); + } + var node; + if (typeof path == 'string') { + var lookup = FS.lookupPath(path, { follow: true }); + node = lookup.node; + } else { + node = path; + } + FS.doTruncate(null, node, len); + }, + ftruncate(fd, len) { + var stream = FS.getStreamChecked(fd); + if (len < 0 || (stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(28); + } + FS.doTruncate(stream, stream.node, len); + }, + utime(path, atime, mtime, dontFollow) { + var lookup = FS.lookupPath(path, { follow: !dontFollow }); + FS.doSetAttr(null, lookup.node, { + atime: atime, + mtime: mtime, + dontFollow + }); + }, + open(path, flags, mode = 0o666) { + if (path === '') { + throw new FS.ErrnoError(44); + } + flags = FS_modeStringToFlags(flags); + if ((flags & 64)) { + mode = (mode & 4095) | 32768; + } else { + mode = 0; + } + var node; + var isDirPath; + if (typeof path == 'object') { + node = path; + } else { + isDirPath = path.endsWith('/'); + // noent_okay makes it so that if the final component of the path + // doesn't exist, lookupPath returns `node: undefined`. `path` will be + // updated to point to the target of all symlinks. + var lookup = FS.lookupPath(path, { + follow: !(flags & 131072), + noent_okay: true + }); + node = lookup.node; + path = lookup.path; + } + // perhaps we need to create the node + var created = false; + if ((flags & 64)) { + if (node) { + // if O_CREAT and O_EXCL are set, error out if the node already exists + if ((flags & 128)) { + throw new FS.ErrnoError(20); + } + } else if (isDirPath) { + throw new FS.ErrnoError(31); + } else { + // node doesn't exist, try to create it + // Ignore the permission bits here to ensure we can `open` this new + // file below. We use chmod below to apply the permissions once the + // file is open. + node = FS.mknod(path, mode | 0o777, 0); + created = true; + } + } + if (!node) { + throw new FS.ErrnoError(44); + } + // can't truncate a device + if (FS.isChrdev(node.mode)) { + flags &= ~512; + } + // if asked only for a directory, then this must be one + if ((flags & 65536) && !FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + // check permissions, if this is not a file we just created now (it is ok to + // create and write to a file with read-only permissions; it is read-only + // for later use) + if (!created) { + var errCode = FS.mayOpen(node, flags); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + // do truncation if necessary + if ((flags & 512) && !created) { + FS.truncate(node, 0); + } + // we've already handled these, don't pass down to the underlying vfs + flags &= ~(128 | 512 | 131072); + + // register the stream with the filesystem + var stream = FS.createStream({ + node, + path: FS.getPath(node), // we want the absolute path to the node + flags, + seekable: true, + position: 0, + stream_ops: node.stream_ops, + // used by the file family libc calls (fopen, fwrite, ferror, etc.) + ungotten: [], + error: false + }); + // call the new stream's open function + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + if (created) { + FS.chmod(node, mode & 0o777); + } + return stream; + }, + close(stream) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (stream.getdents) stream.getdents = null; // free readdir state + // The fd is going away: wake anything waiting on it (poll/epoll) with + // POLLNVAL so a blocking wait unblocks and an epoll registration is evicted + // on its next derive. Only sockets/pipes/epoll ever carry a wait-queue, so + // for every other stream (incl. nodeless noderawfs stdio) this is a no-op. + stream.node?.notifyListeners(32); + try { + if (stream.stream_ops.close) { + stream.stream_ops.close(stream); + } + } catch (e) { + throw e; + } finally { + FS.closeStream(stream.fd); + } + stream.fd = null; + }, + isClosed(stream) { + return stream.fd === null; + }, + llseek(stream, offset, whence) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (!stream.seekable || !stream.stream_ops.llseek) { + throw new FS.ErrnoError(70); + } + if (whence != 0 && whence != 1 && whence != 2) { + throw new FS.ErrnoError(28); + } + stream.position = stream.stream_ops.llseek(stream, offset, whence); + stream.ungotten = []; + return stream.position; + }, + read(stream, buffer, offset, length, position) { + assert(offset >= 0); + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.read) { + throw new FS.ErrnoError(28); + } + var seeking = typeof position != 'undefined'; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); + if (!seeking) stream.position += bytesRead; + return bytesRead; + }, + write(stream, buffer, offset, length, position, canOwn) { + assert(offset >= 0); + assert(buffer.subarray, 'FS.write expects a TypedArray'); + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.write) { + throw new FS.ErrnoError(28); + } + if (stream.seekable && stream.flags & 1024) { + // seek to the end before writing in append mode + FS.llseek(stream, 0, 2); + } + var seeking = typeof position != 'undefined'; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); + if (!seeking) stream.position += bytesWritten; + return bytesWritten; + }, + mmap(stream, length, position, prot, flags) { + // User requests writing to file (prot & PROT_WRITE != 0). + // Checking if we have permissions to write to the file unless + // MAP_PRIVATE flag is set. According to POSIX spec it is possible + // to write to file opened in read-only mode with MAP_PRIVATE flag, + // as all modifications will be visible only in the memory of + // the current process. + if ((prot & 2) + && !(flags & 2) + && (stream.flags & 2097155) !== 2) { + throw new FS.ErrnoError(2); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(2); + } + if (!stream.stream_ops.mmap) { + throw new FS.ErrnoError(43); + } + if (!length) { + throw new FS.ErrnoError(28); + } + return stream.stream_ops.mmap(stream, length, position, prot, flags); + }, + msync(stream, buffer, offset, length, mmapFlags) { + assert(offset >= 0); + if (!stream.stream_ops.msync) { + return 0; + } + return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags); + }, + ioctl(stream, cmd, arg) { + if (!stream.stream_ops.ioctl) { + throw new FS.ErrnoError(59); + } + return stream.stream_ops.ioctl(stream, cmd, arg); + }, + readFile(path, opts = {}) { + opts.flags = opts.flags ?? 0; + opts.encoding = opts.encoding ?? 'binary'; + if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') { + abort(`Invalid encoding type "${opts.encoding}"`); + } + var stream = FS.open(path, opts.flags); + var stat = FS.stat(path); + var length = stat.size; + var buf = new Uint8Array(length); + FS.read(stream, buf, 0, length, 0); + if (opts.encoding === 'utf8') { + buf = UTF8ArrayToString(buf); + } + FS.close(stream); + return buf; + }, + writeFile(path, data, opts = {}) { + opts.flags = opts.flags ?? 577; + var stream = FS.open(path, opts.flags, opts.mode); + data = FS_fileDataToTypedArray(data); + FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn); + FS.close(stream); + }, + cwd:() => FS.currentPath, + chdir(path) { + var lookup = FS.lookupPath(path, { follow: true }); + if (lookup.node === null) { + throw new FS.ErrnoError(44); + } + if (!FS.isDir(lookup.node.mode)) { + throw new FS.ErrnoError(54); + } + var errCode = FS.nodePermissions(lookup.node, 'x'); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.currentPath = lookup.path; + }, + createDefaultDirectories() { + FS.mkdir('/tmp'); + FS.mkdir('/home'); + FS.mkdir('/home/web_user'); + }, + createDefaultDevices() { + // create /dev + FS.mkdir('/dev'); + // setup /dev/null + FS.registerDevice(FS.makedev(1, 3), { + read: () => 0, + write: (stream, buffer, offset, length, pos) => length, + llseek: () => 0, + }); + FS.mkdev('/dev/null', FS.makedev(1, 3)); + // setup /dev/tty and /dev/tty1 + // stderr needs to print output using err() rather than out() + // so we register a second tty just for it. + TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); + TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); + FS.mkdev('/dev/tty', FS.makedev(5, 0)); + FS.mkdev('/dev/tty1', FS.makedev(6, 0)); + // setup /dev/[u]random + // use a buffer to avoid overhead of individual crypto calls per byte + var randomBuffer = new Uint8Array(1024), randomLeft = 0; + var randomByte = () => { + if (!randomLeft) { + randomFill(randomBuffer); + randomLeft = randomBuffer.byteLength; + } + return randomBuffer[--randomLeft]; + }; + FS.createDevice('/dev', 'random', randomByte); + FS.createDevice('/dev', 'urandom', randomByte); + // we're not going to emulate the actual shm device, + // just create the tmp dirs that reside in it commonly + FS.mkdir('/dev/shm'); + FS.mkdir('/dev/shm/tmp'); + }, + createSpecialDirectories() { + // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the + // name of the stream for fd 6 (see test_unistd_ttyname) + FS.mkdir('/proc'); + var proc_self = FS.mkdir('/proc/self'); + FS.mkdir('/proc/self/fd'); + FS.mount({ + mount() { + var node = FS.createNode(proc_self, 'fd', 16895, 73); + node.stream_ops = { + llseek: MEMFS.stream_ops.llseek, + }; + node.node_ops = { + lookup(parent, name) { + var fd = +name; + var stream = FS.getStreamChecked(fd); + var ret = { + parent: null, + mount: { mountpoint: 'fake' }, + node_ops: { readlink: () => stream.path }, + id: fd + 1, + }; + ret.parent = ret; // make it look like a simple root node + return ret; + }, + readdir() { + return Array.from(FS.streams.entries()) + .filter(([k, v]) => v) + .map(([k, v]) => k.toString()); + } + }; + return node; + } + }, {}, '/proc/self/fd'); + }, + createStandardStreams(input, output, error) { + // TODO deprecate the old functionality of a single + // input / output callback and that utilizes FS.createDevice + // and instead require a unique set of stream ops + + // by default, we symlink the standard streams to the + // default tty devices. however, if the standard streams + // have been overwritten we create a unique device for + // them instead. + if (input) { + FS.createDevice('/dev', 'stdin', input); + } else { + FS.symlink('/dev/tty', '/dev/stdin'); + } + if (output) { + FS.createDevice('/dev', 'stdout', null, output); + } else { + FS.symlink('/dev/tty', '/dev/stdout'); + } + if (error) { + FS.createDevice('/dev', 'stderr', null, error); + } else { + FS.symlink('/dev/tty1', '/dev/stderr'); + } + + // open default streams for the stdin, stdout and stderr devices + var stdin = FS.open('/dev/stdin', 0); + var stdout = FS.open('/dev/stdout', 1); + var stderr = FS.open('/dev/stderr', 1); + assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`); + assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`); + assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`); + }, + staticInit() { + FS.nameTable = new Array(4096); + + FS.mount(MEMFS, {}, '/'); + + FS.createDefaultDirectories(); + FS.createDefaultDevices(); + FS.createSpecialDirectories(); + + FS.filesystems = { + 'MEMFS': MEMFS, + }; + }, + init(input, output, error) { + assert(!FS.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)'); + FS.initialized = true; + + // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here + input ??= Module['stdin']; + output ??= Module['stdout']; + error ??= Module['stderr']; + + FS.createStandardStreams(input, output, error); + }, + quit() { + FS.initialized = false; + // force-flush all streams, so we get musl std streams printed out + _fflush(0); + // close all of our streams + for (var stream of FS.streams) { + if (stream) { + FS.close(stream); + } + } + }, + findObject(path, dontResolveLastLink) { + var ret = FS.analyzePath(path, dontResolveLastLink); + if (!ret.exists) { + return null; + } + return ret.object; + }, + analyzePath(path, dontResolveLastLink) { + // operate from within the context of the symlink's target + try { + var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); + path = lookup.path; + } catch (e) { + } + var ret = { + isRoot: false, exists: false, error: 0, name: null, path: null, object: null, + parentExists: false, parentPath: null, parentObject: null + }; + try { + var lookup = FS.lookupPath(path, { parent: true }); + ret.parentExists = true; + ret.parentPath = lookup.path; + ret.parentObject = lookup.node; + ret.name = PATH.basename(path); + lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); + ret.exists = true; + ret.path = lookup.path; + ret.object = lookup.node; + ret.name = lookup.node.name; + ret.isRoot = lookup.path === '/'; + } catch (e) { + ret.error = e.errno; + }; + return ret; + }, + createPath(parent, path, canRead, canWrite) { + parent = typeof parent == 'string' ? parent : FS.getPath(parent); + var parts = path.split('/').reverse(); + while (parts.length) { + var part = parts.pop(); + if (!part) continue; + var current = PATH.join2(parent, part); + try { + FS.mkdir(current); + } catch (e) { + if (e.errno != 20) throw e; + } + parent = current; + } + return current; + }, + createFile(parent, name, properties, canRead, canWrite) { + var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name); + var mode = FS_getMode(canRead, canWrite); + return FS.create(path, mode); + }, + createDataFile(parent, name, data, canRead, canWrite, canOwn) { + var path = name; + if (parent) { + parent = typeof parent == 'string' ? parent : FS.getPath(parent); + path = name ? PATH.join2(parent, name) : parent; + } + var mode = FS_getMode(canRead, canWrite); + var node = FS.create(path, mode); + if (data) { + data = FS_fileDataToTypedArray(data); + // make sure we can write to the file + FS.chmod(node, mode | 146); + var stream = FS.open(node, 577); + FS.write(stream, data, 0, data.length, 0, canOwn); + FS.close(stream); + FS.chmod(node, mode); + } + }, + createDevice(parent, name, input, output) { + var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name); + var mode = FS_getMode(!!input, !!output); + FS.createDevice.major ??= 64; + var dev = FS.makedev(FS.createDevice.major++, 0); + // Create a fake device that a set of stream ops to emulate + // the old behavior. + FS.registerDevice(dev, { + open(stream) { + stream.seekable = false; + }, + close(stream) { + // flush any pending line data + if (output?.buffer?.length) { + output(10); + } + }, + read(stream, buffer, offset, length, pos /* ignored */) { + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = input(); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && !bytesRead) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset+i] = result; + } + if (bytesRead) { + stream.node.atime = Date.now(); + } + return bytesRead; + }, + write(stream, buffer, offset, length, pos) { + for (var i = 0; i < length; i++) { + try { + output(buffer[offset+i]); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + if (length) { + stream.node.mtime = stream.node.ctime = Date.now(); + } + return i; + } + }); + return FS.mkdev(path, mode, dev); + }, + forceLoadFile(obj) { + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; + if (globalThis.XMLHttpRequest) { + abort('Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.'); + } else { // Command-line. + try { + obj.contents = readBinary(obj.url); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + }, + createLazyFile(parent, name, url, canRead, canWrite) { + // Lazy chunked Uint8Array (implements get and length from Uint8Array). + // Actual getting is abstracted away for eventual reuse. + class LazyUint8Array { + lengthKnown = false; + chunks = []; // Loaded chunks. Index is the chunk number + get(idx) { + if (idx > this.length-1 || idx < 0) { + return undefined; + } + var chunkOffset = idx % this.chunkSize; + var chunkNum = (idx / this.chunkSize)|0; + return this.getter(chunkNum)[chunkOffset]; + } + setDataGetter(getter) { + this.getter = getter; + } + cacheLength() { + // Find length + var xhr = new XMLHttpRequest(); + xhr.open('HEAD', url, false); + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort(`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; // Chunk size in bytes + + if (!hasByteServing) chunkSize = datalength; + + // Function to get a range from the remote URL. + var doXHR = (from, to) => { + if (from > to) abort(`invalid range (${from}, ${to}) or no bytes requested!`); + if (to > datalength-1) abort(`only ${datalength} bytes available! programmer error!`); + + // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + if (datalength !== chunkSize) xhr.setRequestHeader('Range', `bytes=${from}-${to}`); + + // Some hints to the browser that we want binary data. + 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)) abort(`Couldn't load ${url}. Status: ${xhr.status}`); + if (xhr.response !== undefined) { + return new Uint8Array(/** @type{Array} */(xhr.response || [])); + } + return intArrayFromString(xhr.responseText ?? '', true); + }; + var lazyArray = this; + lazyArray.setDataGetter((chunkNum) => { + var start = chunkNum * chunkSize; + var end = (chunkNum+1) * chunkSize - 1; // including this byte + end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block + if (typeof lazyArray.chunks[chunkNum] == 'undefined') { + lazyArray.chunks[chunkNum] = doXHR(start, end); + } + if (typeof lazyArray.chunks[chunkNum] == 'undefined') abort('doXHR failed!'); + return lazyArray.chunks[chunkNum]; + }); + + if (usesGzip || !datalength) { + // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length + chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file + 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; + } + get length() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._length; + } + get chunkSize() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._chunkSize; + } + } + + if (globalThis.XMLHttpRequest) { + if (!ENVIRONMENT_IS_WORKER) abort('Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'); + var lazyArray = new LazyUint8Array(); + var properties = { isDevice: false, contents: lazyArray }; + } else { + var properties = { isDevice: false, url: url }; + } + + var node = FS.createFile(parent, name, properties, canRead, canWrite); + // This is a total hack, but I want to get this lazy file code out of the + // core of MEMFS. If we want to keep this lazy file concept I feel it should + // be its own thin LAZYFS proxying calls to MEMFS. + if (properties.contents) { + node.contents = properties.contents; + } else if (properties.url) { + node.contents = null; + node.url = properties.url; + } + // Add a function that defers querying the file size until it is asked the first time. + Object.defineProperties(node, { + usedBytes: { + get: function() { return this.contents.length; } + } + }); + // override each stream op with one that tries to force load the lazy file first + var stream_ops = {}; + for (const [key, fn] of Object.entries(node.stream_ops)) { + stream_ops[key] = (...args) => { + FS.forceLoadFile(node); + return fn(...args); + }; + } + function writeChunks(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= contents.length) + return 0; + var size = Math.min(contents.length - position, length); + assert(size >= 0); + if (contents.slice) { // normal array + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents[position + i]; + } + } else { + for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR + buffer[offset + i] = contents.get(position + i); + } + } + return size; + } + // use a custom read function + stream_ops.read = (stream, buffer, offset, length, position) => { + FS.forceLoadFile(node); + return writeChunks(stream, buffer, offset, length, position) + }; + // use a custom mmap function + stream_ops.mmap = (stream, length, position, prot, flags) => { + FS.forceLoadFile(node); + var ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + writeChunks(stream, HEAP8, ptr, length, position); + return { ptr, allocated: true }; + }; + node.stream_ops = stream_ops; + return node; + }, + }; + + + + + + /** not-@type {!BigInt64Array} */ + var HEAP64; + var SYSCALLS = { + currentUmask:18, + calculateAt(dirfd, path, allowEmpty) { + if (PATH.isAbs(path)) { + return path; + } + // relative path + var dir; + if (dirfd === -100) { + dir = FS.cwd(); + } else { + var dirstream = SYSCALLS.getStreamFromFD(dirfd); + dir = dirstream.path; + } + if (path.length == 0) { + if (!allowEmpty) { + throw new FS.ErrnoError(44);; + } + return dir; + } + return dir + '/' + path; + }, + writeStat(buf, stat) { + HEAPU32[((buf)>>2)] = stat.dev; + HEAPU32[(((buf)+(4))>>2)] = stat.mode; + HEAPU32[(((buf)+(8))>>2)] = stat.nlink; + HEAPU32[(((buf)+(12))>>2)] = stat.uid; + HEAPU32[(((buf)+(16))>>2)] = stat.gid; + HEAPU32[(((buf)+(20))>>2)] = stat.rdev; + HEAP64[(((buf)+(24))>>3)] = BigInt(stat.size); + HEAP32[(((buf)+(32))>>2)] = 4096; + HEAP32[(((buf)+(36))>>2)] = stat.blocks; + var atime = stat.atime.getTime(); + var mtime = stat.mtime.getTime(); + var ctime = stat.ctime.getTime(); + HEAP64[(((buf)+(40))>>3)] = BigInt(Math.floor(atime / 1000)); + HEAPU32[(((buf)+(48))>>2)] = (atime % 1000) * 1000 * 1000; + HEAP64[(((buf)+(56))>>3)] = BigInt(Math.floor(mtime / 1000)); + HEAPU32[(((buf)+(64))>>2)] = (mtime % 1000) * 1000 * 1000; + HEAP64[(((buf)+(72))>>3)] = BigInt(Math.floor(ctime / 1000)); + HEAPU32[(((buf)+(80))>>2)] = (ctime % 1000) * 1000 * 1000; + HEAP64[(((buf)+(88))>>3)] = BigInt(stat.ino); + return 0; + }, + writeStatFs(buf, stats) { + HEAPU32[(((buf)+(4))>>2)] = stats.bsize; + HEAPU32[(((buf)+(60))>>2)] = stats.bsize; + HEAP64[(((buf)+(8))>>3)] = BigInt(stats.blocks); + HEAP64[(((buf)+(16))>>3)] = BigInt(stats.bfree); + HEAP64[(((buf)+(24))>>3)] = BigInt(stats.bavail); + HEAP64[(((buf)+(32))>>3)] = BigInt(stats.files); + HEAP64[(((buf)+(40))>>3)] = BigInt(stats.ffree); + HEAPU32[(((buf)+(48))>>2)] = stats.fsid; + HEAPU32[(((buf)+(64))>>2)] = stats.flags; // ST_NOSUID + HEAPU32[(((buf)+(56))>>2)] = stats.namelen; + }, + doMsync(addr, stream, len, flags, offset) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (flags & 2) { + // MAP_PRIVATE calls need not to be synced back to underlying fs + return 0; + } + var buffer = HEAPU8.subarray(addr, addr + len); + FS.msync(stream, buffer, offset, len, flags); + }, + getStreamFromFD(fd) { + var stream = FS.getStreamChecked(fd); + return stream; + }, + varargs:undefined, + getStr(ptr) { + var ret = UTF8ToString(ptr); + return ret; + }, + }; + function ___syscall_faccessat(dirfd, path, amode, flags) { + try { + + path = SYSCALLS.getStr(path); + assert(!flags || flags == 512); + path = SYSCALLS.calculateAt(dirfd, path); + if (amode & ~7) { + // need a valid mode + return -28; + } + var lookup = FS.lookupPath(path, { follow: true }); + var 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 /* otherwise, they've just passed F_OK */ && FS.nodePermissions(node, perms)) { + return -2; + } + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return -e.errno; + } + } + + + var syscallGetVarargI = () => { + assert(SYSCALLS.varargs != undefined); + // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number. + var ret = HEAP32[((+SYSCALLS.varargs)>>2)]; + SYSCALLS.varargs += 4; + return ret; + }; + var syscallGetVarargP = syscallGetVarargI; + + + + /** @type {!Int16Array} */ + var HEAP16; + function ___syscall_fcntl64(fd, cmd, varargs) { + SYSCALLS.varargs = varargs; + try { + + var stream = SYSCALLS.getStreamFromFD(fd); + switch (cmd) { + case 0: { + var arg = syscallGetVarargI(); + if (arg < 0) { + return -28; + } + while (FS.streams[arg]) { + arg++; + } + var newStream; + newStream = FS.dupStream(stream, arg); + return newStream.fd; + } + case 1: + case 2: + return 0; // FD_CLOEXEC makes no sense for a single process. + case 3: + return stream.flags; + case 4: { + var arg = syscallGetVarargI(); + var mask = 289792; + stream.flags = (stream.flags & ~mask) | (arg & mask); + return 0; + } + case 12: { + var arg = syscallGetVarargP(); + var offset = 0; + // We're always unlocked. + HEAP16[(((arg)+(offset))>>1)] = 2; + return 0; + } + case 13: + case 14: + // Pretend that the locking is successful. These are process-level locks, + // and Emscripten programs are a single process. If we supported linking a + // filesystem between programs, we'd need to do more here. + // See https://github.com/emscripten-core/emscripten/issues/23697 + return 0; + } + return -28; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return -e.errno; + } + } + + + + + var stringToUTF8 = (str, outPtr, maxBytesToWrite) => { + assert(typeof maxBytesToWrite == 'number', 'stringToUTF8 requires a third parameter that specifies the length of the output buffer'); + return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); + }; + function ___syscall_getcwd(buf, size) { + try { + + if (!size) return -28; + var cwd = FS.cwd(); + var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1; + if (size < cwdLengthInBytes) return -68; + stringToUTF8(cwd, buf, size); + return cwdLengthInBytes; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return -e.errno; + } + } + + + + + + + function ___syscall_ioctl(fd, op, varargs) { + SYSCALLS.varargs = varargs; + try { + + var stream = SYSCALLS.getStreamFromFD(fd); + switch (op) { + case 21509: { + if (!stream.tty) return -59; + return 0; + } + case 21505: { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tcgets) { + var termios = stream.tty.ops.ioctl_tcgets(stream); + var argp = syscallGetVarargP(); + HEAP32[((argp)>>2)] = termios.c_iflag || 0; + HEAP32[(((argp)+(4))>>2)] = termios.c_oflag || 0; + HEAP32[(((argp)+(8))>>2)] = termios.c_cflag || 0; + HEAP32[(((argp)+(12))>>2)] = termios.c_lflag || 0; + for (var i = 0; i < 32; i++) { + HEAP8[(argp + i)+(17)] = termios.c_cc[i] || 0; + } + return 0; + } + return 0; + } + case 21510: + case 21511: + case 21512: { + if (!stream.tty) return -59; + return 0; // no-op, not actually adjusting terminal settings + } + case 21506: + case 21507: + case 21508: { + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tcsets) { + var argp = syscallGetVarargP(); + var c_iflag = HEAP32[((argp)>>2)]; + var c_oflag = HEAP32[(((argp)+(4))>>2)]; + var c_cflag = HEAP32[(((argp)+(8))>>2)]; + var c_lflag = HEAP32[(((argp)+(12))>>2)]; + var c_cc = [] + for (var i = 0; i < 32; i++) { + c_cc.push(HEAP8[(argp + i)+(17)]); + } + return stream.tty.ops.ioctl_tcsets(stream.tty, op, { c_iflag, c_oflag, c_cflag, c_lflag, c_cc }); + } + return 0; // no-op, not actually adjusting terminal settings + } + case 21519: { + if (!stream.tty) return -59; + var argp = syscallGetVarargP(); + HEAP32[((argp)>>2)] = 0; + return 0; + } + case 21520: { + if (!stream.tty) return -59; + return -28; // not supported + } + case 21537: + case 21531: { + var argp = syscallGetVarargP(); + return FS.ioctl(stream, op, argp); + } + case 21523: { + // TODO: in theory we should write to the winsize struct that gets + // passed in, but for now musl doesn't read anything on it + if (!stream.tty) return -59; + if (stream.tty.ops.ioctl_tiocgwinsz) { + var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty); + var argp = syscallGetVarargP(); + HEAP16[((argp)>>1)] = winsize[0]; + HEAP16[(((argp)+(2))>>1)] = winsize[1]; + } + return 0; + } + case 21524: { + // TODO: technically, this ioctl call should change the window size. + // but, since emscripten doesn't have any concept of a terminal window + // yet, we'll just silently throw it away as we do TIOCGWINSZ + if (!stream.tty) return -59; + return 0; + } + case 21515: { + if (!stream.tty) return -59; + return 0; + } + default: return -28; // not supported + } + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return -e.errno; + } + } + + + + function ___syscall_openat(dirfd, path, flags, varargs) { + SYSCALLS.varargs = varargs; + try { + + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + var mode = varargs ? syscallGetVarargI() : 0; + if (flags & 64) { + mode &= ~SYSCALLS.currentUmask; + } + return FS.open(path, flags, mode).fd; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return -e.errno; + } + } + + + var __abort_js = () => + abort('native code called abort()'); + + var _emscripten_get_now = () => performance.now(); + + var _emscripten_date_now = () => Date.now(); + + var nowIsMonotonic = 1; + + var checkWasiClock = (clock_id) => clock_id >= 0 && clock_id <= 3; + + var INT53_MAX = 9007199254740992; + + var INT53_MIN = -9007199254740992; + var bigintToI53Checked = (num) => (num < INT53_MIN || num > INT53_MAX) ? NaN : Number(num); + + function _clock_time_get(clk_id, ignored_precision, ptime) { + ignored_precision = bigintToI53Checked(ignored_precision); + + + if (!checkWasiClock(clk_id)) { + return 28; + } + var now; + // all wasi clocks but realtime are monotonic + if (clk_id === 0) { + now = _emscripten_date_now(); + } else if (nowIsMonotonic) { + now = _emscripten_get_now(); + } else { + return 52; + } + // "now" is in ms, and wasi times are in ns. + var nsec = Math.round(now * 1000 * 1000); + HEAP64[((ptime)>>3)] = BigInt(nsec); + return 0; + ; + } + + var readEmAsmArgsArray = []; + + + + + /** @type {!Float64Array} */ + var HEAPF64; + + var readEmAsmArgs = (sigPtr, buf) => { + // Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array. + assert(Array.isArray(readEmAsmArgsArray)); + // The input buffer is allocated on the stack, so it must be stack-aligned. + assert(buf % 16 == 0); + readEmAsmArgsArray.length = 0; + var ch; + // Most arguments are i32s, so shift the buffer pointer so it is a plain + // index into HEAP32. + while (ch = HEAPU8[sigPtr++]) { + var chr = String.fromCharCode(ch); + var validChars = ['d', 'f', 'i', 'p']; + // In WASM_BIGINT mode we support passing i64 values as bigint. + validChars.push('j'); + assert(validChars.includes(chr), `Invalid character ${ch}("${chr}") in readEmAsmArgs! Use only [${validChars}], and do not specify "v" for void return argument.`); + // Floats are always passed as doubles, so all types except for 'i' + // are 8 bytes and require alignment. + var wide = (ch != 105); + wide &= (ch != 112); + buf += wide && (buf % 8) ? 4 : 0; + readEmAsmArgsArray.push( + // Special case for pointers under wasm64 or CAN_ADDRESS_2GB mode. + ch == 112 ? HEAPU32[((buf)>>2)] : + ch == 106 ? HEAP64[((buf)>>3)] : + ch == 105 ? + HEAP32[((buf)>>2)] : + HEAPF64[((buf)>>3)] + ); + buf += wide ? 8 : 4; + } + return readEmAsmArgsArray; + }; + var runEmAsmFunction = (code, sigPtr, argbuf) => { + var args = readEmAsmArgs(sigPtr, argbuf); + assert(ASM_CONSTS.hasOwnProperty(code), `No EM_ASM constant found at address ${code}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`); + return ASM_CONSTS[code](...args); + }; + var _emscripten_asm_const_int = (code, sigPtr, argbuf) => { + return runEmAsmFunction(code, sigPtr, argbuf); + }; + + + var maybeCStringToJsString = (cString) => { + // 'cString > 2' checks if the input is a number, and isn't of the special + // values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2). + // In other words, if cString > 2 then it's a pointer to a valid place in + // memory, and points to a C string. + return cString > 2 ? UTF8ToString(cString) : cString; + }; + + /** @type {Object} */ + var specialHTMLTargets = [0, globalThis.document ?? 0, globalThis.window ?? 0]; + var findEventTarget = (target) => { + target = maybeCStringToJsString(target); + var domElement = specialHTMLTargets[target] || globalThis.document?.querySelector(target); + return domElement; + }; + + var getBoundingClientRect = (e) => specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0}; + + var _emscripten_get_element_css_size = (target, width, height) => { + target = findEventTarget(target); + if (!target) return -4; + + var rect = getBoundingClientRect(target); + HEAPF64[((width)>>3)] = rect.width; + HEAPF64[((height)>>3)] = rect.height; + + return 0; + }; + + var onExits = []; + var addOnExit = (cb) => onExits.push(cb); + var JSEvents = { + removeAllEventListeners() { + while (JSEvents.eventHandlers.length) { + JSEvents._removeHandler(JSEvents.eventHandlers.length - 1); + } + JSEvents.deferredCalls = []; + }, + inEventHandler:0, + deferredCalls:[], + deferCall(targetFunction, precedence, argsList) { + function arraysHaveEqualContent(arrA, arrB) { + if (arrA.length != arrB.length) return false; + + for (var i = 0; i < arrA.length; i++) { + if (arrA[i] != arrB[i]) return false; + } + return true; + } + // Test if the given call was already queued, and if so, don't add it again. + for (var call of JSEvents.deferredCalls) { + if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) { + return; + } + } + JSEvents.deferredCalls.push({ + targetFunction, + precedence, + argsList + }); + + JSEvents.deferredCalls.sort((x,y) => x.precedence - y.precedence); + }, + removeDeferredCalls(targetFunction) { + JSEvents.deferredCalls = JSEvents.deferredCalls.filter((call) => call.targetFunction != targetFunction); + }, + canPerformEventHandlerRequests() { + // Browsers that support navigator.userActivation.isActive: https://developer.mozilla.org/en-US/docs/Web/API/UserActivation/isActive + if (navigator.userActivation) { + // Verify against transient activation status from UserActivation API + // whether it is possible to perform a request here without needing to defer. See + // https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation + // and https://caniuse.com/mdn-api_useractivation + return navigator.userActivation.isActive; + } + + return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls; + }, + runDeferredCalls() { + if (!JSEvents.canPerformEventHandlerRequests()) { + return; + } + var deferredCalls = JSEvents.deferredCalls; + JSEvents.deferredCalls = []; + for (var call of deferredCalls) { + call.targetFunction(...call.argsList); + } + }, + eventHandlers:[], + removeAllHandlersOnTarget:(target, eventTypeString) => { + for (var i = 0; i < JSEvents.eventHandlers.length; ++i) { + if (JSEvents.eventHandlers[i].target == target && + (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) { + JSEvents._removeHandler(i--); + } + } + }, + _removeHandler(i) { + var h = JSEvents.eventHandlers[i]; + h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture); + JSEvents.eventHandlers.splice(i, 1); + }, + registerOrRemoveHandler(eventHandler) { + if (!eventHandler.target) { + err('registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:'); + console.dir(eventHandler); + return -4; + } + if (eventHandler.callbackfunc) { + eventHandler.eventListenerFunc = function(event) { + // Increment nesting count for the event handler. + ++JSEvents.inEventHandler; + JSEvents.currentEventHandler = eventHandler; + // Process any old deferred calls the user has placed. + JSEvents.runDeferredCalls(); + // Process the actual event, calls back to user C code handler. + eventHandler.handlerFunc(event); + // Process any new deferred calls that were placed right now from this event handler. + JSEvents.runDeferredCalls(); + // Out of event handler - restore nesting count. + --JSEvents.inEventHandler; + }; + + eventHandler.target.addEventListener(eventHandler.eventTypeString, + eventHandler.eventListenerFunc, + eventHandler.useCapture); + JSEvents.eventHandlers.push(eventHandler); + } else { + for (var i = 0; i < JSEvents.eventHandlers.length; ++i) { + if (JSEvents.eventHandlers[i].target == eventHandler.target + && JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) { + JSEvents._removeHandler(i--); + } + } + } + return 0; + }, + removeSingleHandler(eventHandler) { + let success = false; + for (let i = 0; i < JSEvents.eventHandlers.length; ++i) { + const handler = JSEvents.eventHandlers[i]; + if (handler.target === eventHandler.target + && handler.eventTypeId === eventHandler.eventTypeId + && handler.callbackfunc === eventHandler.callbackfunc + && handler.userData === eventHandler.userData) { + // in some very rare cases (ex: Safari / fullscreen events), there is more than 1 handler (eventTypeString is different) + JSEvents._removeHandler(i--); + success = true; + } + } + return success ? 0 : -5; + }, + getNodeNameForTarget(target) { + if (target == window) return '#window'; + if (target == screen) return '#screen'; + return target?.nodeName ?? ''; + }, + fullscreenEnabled() { + return document.fullscreenEnabled + // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled. + // TODO: If Safari at some point ships with unprefixed version, update the version check above. + ?? document.webkitFullscreenEnabled + ; + }, + }; + + + + + var fillGamepadEventData = (eventStruct, e) => { + HEAPF64[((eventStruct)>>3)] = e.timestamp; + for (var i = 0; i < e.axes.length; ++i) { + HEAPF64[(((eventStruct+i*8)+(16))>>3)] = e.axes[i]; + } + for (var i = 0; i < e.buttons.length; ++i) { + HEAP8[(eventStruct+i)+(1040)] = e.buttons[i].pressed; + HEAPF64[(((eventStruct+i*8)+(528))>>3)] = e.buttons[i].value; + } + HEAP8[(eventStruct)+(1104)] = e.connected; + HEAP32[(((eventStruct)+(1108))>>2)] = e.index; + HEAP32[(((eventStruct)+(8))>>2)] = e.axes.length; + HEAP32[(((eventStruct)+(12))>>2)] = e.buttons.length; + stringToUTF8(e.id, eventStruct + 1112, 64); + stringToUTF8(e.mapping, eventStruct + 1176, 64); + }; + var _emscripten_get_gamepad_status = (index, gamepadState) => { + assert(JSEvents.lastGamepadState, 'emscripten_get_gamepad_status() called before emscripten_sample_gamepad_data()'); + // INVALID_PARAM is returned on a Gamepad index that never was there. + if (index < 0 || index >= JSEvents.lastGamepadState.length) return -5; + + // NO_DATA is returned on a Gamepad index that was removed. + // For previously disconnected gamepads there should be an empty slot (null/undefined/false) at the index. + // This is because gamepads must keep their original position in the array. + // For example, removing the first of two gamepads produces [null/undefined/false, gamepad]. + if (!JSEvents.lastGamepadState[index]) return -7; + + fillGamepadEventData(gamepadState, JSEvents.lastGamepadState[index]); + return 0; + }; + + + var _emscripten_get_num_gamepads = () => { + assert(JSEvents.lastGamepadState, 'emscripten_get_num_gamepads() called before emscripten_sample_gamepad_data()'); + // N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS. + // Otherwise the following line will throw an exception. + return JSEvents.lastGamepadState.length; + }; + + var GLctx; + + var webgl_enable_ANGLE_instanced_arrays = (ctx) => { + // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension('ANGLE_instanced_arrays'); + // Because this extension is a core function in WebGL 2, assign the extension entry points in place of + // where the core functions will reside in WebGL 2. This way the calling code can call these without + // having to dynamically branch depending if running against WebGL 1 or WebGL 2. + if (ext) { + ctx['vertexAttribDivisor'] = (index, divisor) => ext['vertexAttribDivisorANGLE'](index, divisor); + ctx['drawArraysInstanced'] = (mode, first, count, primcount) => ext['drawArraysInstancedANGLE'](mode, first, count, primcount); + ctx['drawElementsInstanced'] = (mode, count, type, indices, primcount) => ext['drawElementsInstancedANGLE'](mode, count, type, indices, primcount); + return 1; + } + }; + + var webgl_enable_OES_vertex_array_object = (ctx) => { + // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension('OES_vertex_array_object'); + if (ext) { + ctx['createVertexArray'] = () => ext['createVertexArrayOES'](); + ctx['deleteVertexArray'] = (vao) => ext['deleteVertexArrayOES'](vao); + ctx['bindVertexArray'] = (vao) => ext['bindVertexArrayOES'](vao); + ctx['isVertexArray'] = (vao) => ext['isVertexArrayOES'](vao); + return 1; + } + }; + + var webgl_enable_WEBGL_draw_buffers = (ctx) => { + // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2. + var ext = ctx.getExtension('WEBGL_draw_buffers'); + if (ext) { + ctx['drawBuffers'] = (n, bufs) => ext['drawBuffersWEBGL'](n, bufs); + return 1; + } + }; + + var webgl_enable_EXT_polygon_offset_clamp = (ctx) => + !!(ctx.extPolygonOffsetClamp = ctx.getExtension('EXT_polygon_offset_clamp')); + + var webgl_enable_EXT_clip_control = (ctx) => + !!(ctx.extClipControl = ctx.getExtension('EXT_clip_control')); + + var webgl_enable_WEBGL_polygon_mode = (ctx) => + !!(ctx.webglPolygonMode = ctx.getExtension('WEBGL_polygon_mode')); + + var webgl_enable_WEBGL_multi_draw = (ctx) => + // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted. + !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw')); + + var getEmscriptenSupportedExtensions = (ctx) => { + // Restrict the list of advertised extensions to those that we actually + // support. + var supportedExtensions = [ + // WebGL 1 extensions + 'ANGLE_instanced_arrays', + 'EXT_blend_minmax', + 'EXT_disjoint_timer_query', + 'EXT_frag_depth', + 'EXT_shader_texture_lod', + 'EXT_sRGB', + 'OES_element_index_uint', + 'OES_fbo_render_mipmap', + 'OES_standard_derivatives', + 'OES_texture_float', + 'OES_texture_half_float', + 'OES_texture_half_float_linear', + 'OES_vertex_array_object', + 'WEBGL_color_buffer_float', + 'WEBGL_depth_texture', + 'WEBGL_draw_buffers', + // WebGL 1 and WebGL 2 extensions + 'EXT_clip_control', + 'EXT_color_buffer_half_float', + 'EXT_depth_clamp', + 'EXT_float_blend', + 'EXT_polygon_offset_clamp', + 'EXT_texture_compression_bptc', + 'EXT_texture_compression_rgtc', + 'EXT_texture_filter_anisotropic', + 'KHR_parallel_shader_compile', + 'OES_texture_float_linear', + 'WEBGL_blend_func_extended', + 'WEBGL_compressed_texture_astc', + 'WEBGL_compressed_texture_etc', + 'WEBGL_compressed_texture_etc1', + 'WEBGL_compressed_texture_s3tc', + 'WEBGL_compressed_texture_s3tc_srgb', + 'WEBGL_debug_renderer_info', + 'WEBGL_debug_shaders', + 'WEBGL_lose_context', + 'WEBGL_multi_draw', + 'WEBGL_polygon_mode' + ]; + // .getSupportedExtensions() can return null if context is lost, so coerce to empty array. + return ctx.getSupportedExtensions()?.filter(ext => supportedExtensions.includes(ext)) ?? []; + }; + + + + + var GL = { + counter:1, + buffers:[], + programs:[], + framebuffers:[], + renderbuffers:[], + textures:[], + shaders:[], + vaos:[], + contexts:[], + offscreenCanvases:{ + }, + queries:[], + stringCache:{ + }, + unpackAlignment:4, + unpackRowLength:0, + recordError:(errorCode) => { + if (!GL.lastError) { + GL.lastError = errorCode; + } + }, + getNewId:(table) => { + var ret = GL.counter++; + for (var i = table.length; i < ret; i++) { + table[i] = null; + } + return ret; + }, + genObject:(n, buffers, createFunction, objectTable + ) => { + for (var i = 0; i < n; i++) { + var buffer = GLctx[createFunction](); + var id = buffer && GL.getNewId(objectTable); + if (buffer) { + buffer.name = id; + objectTable[id] = buffer; + } else { + GL.recordError(0x502 /* GL_INVALID_OPERATION */); + } + HEAP32[(((buffers)+(i*4))>>2)] = id; + } + }, + getSource:(shader, count, string, length) => { + var source = ''; + for (var i = 0; i < count; ++i) { + var len = length ? HEAPU32[(((length)+(i*4))>>2)] : undefined; + source += UTF8ToString(HEAPU32[(((string)+(i*4))>>2)], len); + } + return source; + }, + createContext:(/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) => { + + // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL + // context on a canvas, calling .getContext() will always return that + // context independent of which 'webgl' or 'webgl2' + // context version was passed. See: + // https://webkit.org/b/222758 + // and: + // https://github.com/emscripten-core/emscripten/issues/13295. + // TODO: Once the bug is fixed and shipped in Safari, adjust the Safari + // version field in above check. + if (!canvas.getContextSafariWebGL2Fixed) { + canvas.getContextSafariWebGL2Fixed = canvas.getContext; + /** @type {function(this:HTMLCanvasElement, string, (Object|null)=): (Object|null)} */ + function fixedGetContext(ver, attrs) { + var gl = canvas.getContextSafariWebGL2Fixed(ver, attrs); + return ((ver == 'webgl') == (gl instanceof WebGLRenderingContext)) ? gl : null; + } + canvas.getContext = fixedGetContext; + } + + var ctx = + canvas.getContext('webgl', webGLContextAttributes); + + if (!ctx) return 0; + + var handle = GL.registerContext(ctx, webGLContextAttributes); + + return handle; + }, + registerContext:(ctx, webGLContextAttributes) => { + // without pthreads a context is just an integer ID + var handle = GL.getNewId(GL.contexts); + + var context = { + handle, + attributes: webGLContextAttributes, + version: webGLContextAttributes.majorVersion, + GLctx: ctx + }; + + // Store the created context object so that we can access the context + // given a canvas without having to pass the parameters again. + if (ctx.canvas) ctx.canvas.GLctxObject = context; + GL.contexts[handle] = context; + if (typeof webGLContextAttributes.enableExtensionsByDefault == 'undefined' || webGLContextAttributes.enableExtensionsByDefault) { + GL.initExtensions(context); + } + + return handle; + }, + makeContextCurrent:(contextHandle) => { + + // Active Emscripten GL layer context object. + GL.currentContext = GL.contexts[contextHandle]; + // Active WebGL context object. + Module['ctx'] = GLctx = GL.currentContext?.GLctx; + return !(contextHandle && !GLctx); + }, + getContext:(contextHandle) => { + return GL.contexts[contextHandle]; + }, + deleteContext:(contextHandle) => { + if (GL.currentContext === GL.contexts[contextHandle]) { + GL.currentContext = null; + } + if (typeof JSEvents == 'object') { + // Release all JS event handlers on the DOM element that the GL context is + // associated with since the context is now deleted. + JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas); + } + // Make sure the canvas object no longer refers to the context object so + // there are no GC surprises. + if (GL.contexts[contextHandle]?.GLctx.canvas) { + GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined; + } + GL.contexts[contextHandle] = null; + }, + initExtensions:(context) => { + // If this function is called without a specific context object, init the + // extensions of the currently active context. + context ||= GL.currentContext; + + if (context.initExtensionsDone) return; + context.initExtensionsDone = true; + + var GLctx = context.GLctx; + + // Detect the presence of a few extensions manually, since the GL interop + // layer itself will need to know if they exist. + + // Extensions that are available in both WebGL 1 and WebGL 2 + webgl_enable_WEBGL_multi_draw(GLctx); + webgl_enable_EXT_polygon_offset_clamp(GLctx); + webgl_enable_EXT_clip_control(GLctx); + webgl_enable_WEBGL_polygon_mode(GLctx); + // Extensions that are only available in WebGL 1 (the calls will be no-ops + // if called on a WebGL 2 context active) + webgl_enable_ANGLE_instanced_arrays(GLctx); + webgl_enable_OES_vertex_array_object(GLctx); + webgl_enable_WEBGL_draw_buffers(GLctx); + { + GLctx.disjointTimerQueryExt = GLctx.getExtension('EXT_disjoint_timer_query'); + } + + for (var ext of getEmscriptenSupportedExtensions(GLctx)) { + // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders + // are not enabled by default. + if (!ext.includes('lose_context') && !ext.includes('debug')) { + // Call .getExtension() to enable that extension permanently. + GLctx.getExtension(ext); + } + } + }, + }; + var _emscripten_glActiveTexture = (x0) => GLctx.activeTexture(x0); + + var _emscripten_glAttachShader = (program, shader) => { + GLctx.attachShader(GL.programs[program], GL.shaders[shader]); + }; + + var _emscripten_glBeginQueryEXT = (target, id) => { + GLctx.disjointTimerQueryExt['beginQueryEXT'](target, GL.queries[id]); + }; + + + var _emscripten_glBindAttribLocation = (program, index, name) => { + GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name)); + }; + + var _emscripten_glBindBuffer = (target, buffer) => { + + GLctx.bindBuffer(target, GL.buffers[buffer]); + }; + + var _emscripten_glBindFramebuffer = (target, framebuffer) => { + + GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]); + + }; + + var _emscripten_glBindRenderbuffer = (target, renderbuffer) => { + GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]); + }; + + var _emscripten_glBindTexture = (target, texture) => { + GLctx.bindTexture(target, GL.textures[texture]); + }; + + + var _emscripten_glBindVertexArray = (vao) => { + GLctx.bindVertexArray(GL.vaos[vao]); + }; + var _glBindVertexArray = _emscripten_glBindVertexArray; + var _emscripten_glBindVertexArrayOES = _glBindVertexArray; + + var _emscripten_glBlendColor = (x0, x1, x2, x3) => GLctx.blendColor(x0, x1, x2, x3); + + var _emscripten_glBlendEquation = (x0) => GLctx.blendEquation(x0); + + var _emscripten_glBlendEquationSeparate = (x0, x1) => GLctx.blendEquationSeparate(x0, x1); + + var _emscripten_glBlendFunc = (x0, x1) => GLctx.blendFunc(x0, x1); + + var _emscripten_glBlendFuncSeparate = (x0, x1, x2, x3) => GLctx.blendFuncSeparate(x0, x1, x2, x3); + + + var _emscripten_glBufferData = (target, size, data, usage) => { + + // N.b. here first form specifies a heap subarray, second form an integer + // size, so the ?: code here is polymorphic. It is advised to avoid + // randomly mixing both uses in calling code, to avoid any potential JS + // engine JIT issues. + GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage); + }; + + + var webglBufferSubData = (target, offset, size, data, src = HEAPU8) => { + GLctx.bufferSubData(target, offset, src.subarray(data, data + size)); + }; + + var _emscripten_glBufferSubData = (target, offset, size, data) => webglBufferSubData(target, offset, size, data); + + var _emscripten_glCheckFramebufferStatus = (x0) => GLctx.checkFramebufferStatus(x0); + + var _emscripten_glClear = (x0) => GLctx.clear(x0); + + var _emscripten_glClearColor = (x0, x1, x2, x3) => GLctx.clearColor(x0, x1, x2, x3); + + var _emscripten_glClearDepthf = (x0) => GLctx.clearDepth(x0); + + var _emscripten_glClearStencil = (x0) => GLctx.clearStencil(x0); + + var _emscripten_glClipControlEXT = (origin, depth) => { + GLctx.extClipControl['clipControlEXT'](origin, depth); + }; + + var _emscripten_glColorMask = (red, green, blue, alpha) => { + GLctx.colorMask(!!red, !!green, !!blue, !!alpha); + }; + + var _emscripten_glCompileShader = (shader) => { + GLctx.compileShader(GL.shaders[shader]); + }; + + + var _emscripten_glCompressedTexImage2D = (target, level, internalFormat, width, height, border, imageSize, data) => { + // `data` may be null here, which means "allocate uninitialized space but + // don't upload" in GLES parlance, but `compressedTexImage2D` requires the + // final data parameter, so we simply pass a heap view starting at zero + // effectively uploading whatever happens to be near address zero. See + // https://github.com/emscripten-core/emscripten/issues/19300. + GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, HEAPU8.subarray(data, data + imageSize)); + }; + + + var _emscripten_glCompressedTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, imageSize, data) => { + GLctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, HEAPU8.subarray(data, data + imageSize)); + }; + + var _emscripten_glCopyTexImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7); + + var _emscripten_glCopyTexSubImage2D = (x0, x1, x2, x3, x4, x5, x6, x7) => GLctx.copyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7); + + var _emscripten_glCreateProgram = () => { + var id = GL.getNewId(GL.programs); + var program = GLctx.createProgram(); + // Store additional information needed for each shader program: + program.name = id; + // Lazy cache results of + // glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH) + program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0; + program.uniformIdCounter = 1; + GL.programs[id] = program; + return id; + }; + + var _emscripten_glCreateShader = (shaderType) => { + var id = GL.getNewId(GL.shaders); + GL.shaders[id] = GLctx.createShader(shaderType); + + return id; + }; + + var _emscripten_glCullFace = (x0) => GLctx.cullFace(x0); + + + var _emscripten_glDeleteBuffers = (n, buffers) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((buffers)+(i*4))>>2)]; + var buffer = GL.buffers[id]; + + // From spec: "glDeleteBuffers silently ignores 0's and names that do not + // correspond to existing buffer objects." + if (!buffer) continue; + + GLctx.deleteBuffer(buffer); + buffer.name = 0; + GL.buffers[id] = null; + + } + }; + + + var _emscripten_glDeleteFramebuffers = (n, framebuffers) => { + for (var i = 0; i < n; ++i) { + var id = HEAP32[(((framebuffers)+(i*4))>>2)]; + var framebuffer = GL.framebuffers[id]; + if (!framebuffer) continue; // GL spec: "glDeleteFramebuffers silently ignores 0s and names that do not correspond to existing framebuffer objects". + GLctx.deleteFramebuffer(framebuffer); + framebuffer.name = 0; + GL.framebuffers[id] = null; + } + }; + + var _emscripten_glDeleteProgram = (id) => { + if (!id) return; + var program = GL.programs[id]; + if (!program) { + // glDeleteProgram actually signals an error when deleting a nonexisting + // object, unlike some other GL delete functions. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + GLctx.deleteProgram(program); + program.name = 0; + GL.programs[id] = null; + }; + + + var _emscripten_glDeleteQueriesEXT = (n, ids) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((ids)+(i*4))>>2)]; + var query = GL.queries[id]; + if (!query) continue; // GL spec: "unused names in ids are ignored, as is the name zero." + GLctx.disjointTimerQueryExt['deleteQueryEXT'](query); + GL.queries[id] = null; + } + }; + + + var _emscripten_glDeleteRenderbuffers = (n, renderbuffers) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((renderbuffers)+(i*4))>>2)]; + var renderbuffer = GL.renderbuffers[id]; + if (!renderbuffer) continue; // GL spec: "glDeleteRenderbuffers silently ignores 0s and names that do not correspond to existing renderbuffer objects". + GLctx.deleteRenderbuffer(renderbuffer); + renderbuffer.name = 0; + GL.renderbuffers[id] = null; + } + }; + + var _emscripten_glDeleteShader = (id) => { + if (!id) return; + var shader = GL.shaders[id]; + if (!shader) { + // glDeleteShader actually signals an error when deleting a nonexisting + // object, unlike some other GL delete functions. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + GLctx.deleteShader(shader); + GL.shaders[id] = null; + }; + + + var _emscripten_glDeleteTextures = (n, textures) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((textures)+(i*4))>>2)]; + var texture = GL.textures[id]; + // GL spec: "glDeleteTextures silently ignores 0s and names that do not + // correspond to existing textures". + if (!texture) continue; + GLctx.deleteTexture(texture); + texture.name = 0; + GL.textures[id] = null; + } + }; + + + + var _emscripten_glDeleteVertexArrays = (n, vaos) => { + for (var i = 0; i < n; i++) { + var id = HEAP32[(((vaos)+(i*4))>>2)]; + GLctx.deleteVertexArray(GL.vaos[id]); + GL.vaos[id] = null; + } + }; + var _glDeleteVertexArrays = _emscripten_glDeleteVertexArrays; + var _emscripten_glDeleteVertexArraysOES = _glDeleteVertexArrays; + + var _emscripten_glDepthFunc = (x0) => GLctx.depthFunc(x0); + + var _emscripten_glDepthMask = (flag) => { + GLctx.depthMask(!!flag); + }; + + var _emscripten_glDepthRangef = (x0, x1) => GLctx.depthRange(x0, x1); + + var _emscripten_glDetachShader = (program, shader) => { + GLctx.detachShader(GL.programs[program], GL.shaders[shader]); + }; + + var _emscripten_glDisable = (x0) => GLctx.disable(x0); + + var _emscripten_glDisableVertexAttribArray = (index) => { + GLctx.disableVertexAttribArray(index); + }; + + var _emscripten_glDrawArrays = (mode, first, count) => { + + GLctx.drawArrays(mode, first, count); + + }; + + + var _emscripten_glDrawArraysInstanced = (mode, first, count, primcount) => { + GLctx.drawArraysInstanced(mode, first, count, primcount); + }; + var _glDrawArraysInstanced = _emscripten_glDrawArraysInstanced; + var _emscripten_glDrawArraysInstancedANGLE = _glDrawArraysInstanced; + + + var tempFixedLengthArray = []; + + + var _emscripten_glDrawBuffers = (n, bufs) => { + + var bufArray = tempFixedLengthArray[n]; + for (var i = 0; i < n; i++) { + bufArray[i] = HEAP32[(((bufs)+(i*4))>>2)]; + } + + GLctx.drawBuffers(bufArray); + }; + var _glDrawBuffers = _emscripten_glDrawBuffers; + var _emscripten_glDrawBuffersWEBGL = _glDrawBuffers; + + + var _emscripten_glDrawElements = (mode, count, type, indices) => { + + GLctx.drawElements(mode, count, type, indices); + + }; + + + var _emscripten_glDrawElementsInstanced = (mode, count, type, indices, primcount) => { + GLctx.drawElementsInstanced(mode, count, type, indices, primcount); + }; + var _glDrawElementsInstanced = _emscripten_glDrawElementsInstanced; + var _emscripten_glDrawElementsInstancedANGLE = _glDrawElementsInstanced; + + var _emscripten_glEnable = (x0) => GLctx.enable(x0); + + var _emscripten_glEnableVertexAttribArray = (index) => { + GLctx.enableVertexAttribArray(index); + }; + + var _emscripten_glEndQueryEXT = (target) => { + GLctx.disjointTimerQueryExt['endQueryEXT'](target); + }; + + var _emscripten_glFinish = () => GLctx.finish(); + + var _emscripten_glFlush = () => GLctx.flush(); + + var _emscripten_glFramebufferRenderbuffer = (target, attachment, renderbuffertarget, renderbuffer) => { + GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget, + GL.renderbuffers[renderbuffer]); + }; + + var _emscripten_glFramebufferTexture2D = (target, attachment, textarget, texture, level) => { + GLctx.framebufferTexture2D(target, attachment, textarget, + GL.textures[texture], level); + }; + + var _emscripten_glFrontFace = (x0) => GLctx.frontFace(x0); + + var _emscripten_glGenBuffers = (n, buffers) => { + GL.genObject(n, buffers, 'createBuffer', GL.buffers + ); + }; + + var _emscripten_glGenFramebuffers = (n, ids) => { + GL.genObject(n, ids, 'createFramebuffer', GL.framebuffers + ); + }; + + + var _emscripten_glGenQueriesEXT = (n, ids) => { + for (var i = 0; i < n; i++) { + var query = GLctx.disjointTimerQueryExt['createQueryEXT'](); + if (!query) { + GL.recordError(0x502 /* GL_INVALID_OPERATION */); + while (i < n) HEAP32[(((ids)+(i++*4))>>2)] = 0; + return; + } + var id = GL.getNewId(GL.queries); + query.name = id; + GL.queries[id] = query; + HEAP32[(((ids)+(i*4))>>2)] = id; + } + }; + + var _emscripten_glGenRenderbuffers = (n, renderbuffers) => { + GL.genObject(n, renderbuffers, 'createRenderbuffer', GL.renderbuffers + ); + }; + + var _emscripten_glGenTextures = (n, textures) => { + GL.genObject(n, textures, 'createTexture', GL.textures + ); + }; + + + var _emscripten_glGenVertexArrays = (n, arrays) => { + GL.genObject(n, arrays, 'createVertexArray', GL.vaos + ); + }; + var _glGenVertexArrays = _emscripten_glGenVertexArrays; + var _emscripten_glGenVertexArraysOES = _glGenVertexArrays; + + var _emscripten_glGenerateMipmap = (x0) => GLctx.generateMipmap(x0); + + + + var __glGetActiveAttribOrUniform = (funcName, program, index, bufSize, length, size, type, name) => { + program = GL.programs[program]; + var info = GLctx[funcName](program, index); + if (info) { + // If an error occurs, nothing will be written to length, size and type and name. + 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; + } + }; + + var _emscripten_glGetActiveAttrib = (program, index, bufSize, length, size, type, name) => + __glGetActiveAttribOrUniform('getActiveAttrib', program, index, bufSize, length, size, type, name); + + + var _emscripten_glGetActiveUniform = (program, index, bufSize, length, size, type, name) => + __glGetActiveAttribOrUniform('getActiveUniform', program, index, bufSize, length, size, type, name); + + + var _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 < len; ++i) { + var id = GL.shaders.indexOf(result[i]); + HEAP32[(((shaders)+(i*4))>>2)] = id; + } + }; + + + var _emscripten_glGetAttribLocation = (program, name) => + GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name)); + + + var readI53FromI64 = (ptr) => { + return HEAPU32[((ptr)>>2)] + HEAP32[(((ptr)+(4))>>2)] * 4294967296; + }; + + var readI53FromU64 = (ptr) => { + return HEAPU32[((ptr)>>2)] + HEAPU32[(((ptr)+(4))>>2)] * 4294967296; + }; + + var writeI53ToI64 = (ptr, num) => { + HEAPU32[((ptr)>>2)] = num; + var lower = HEAPU32[((ptr)>>2)]; + HEAPU32[(((ptr)+(4))>>2)] = (num - lower)/4294967296; + var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr); + var offset = ((ptr)>>2); + if (deserialized != num) warnOnce(`writeI53ToI64() out of range: serialized JS Number ${num} to Wasm heap as bytes lo=${ptrToString(HEAPU32[offset])}, hi=${ptrToString(HEAPU32[offset+1])}, which deserializes back to ${deserialized} instead!`); + }; + + + + + /** @type {!Float32Array} */ + var HEAPF32; + var emscriptenWebGLGet = (name_, p, type) => { + // Guard against user passing a null pointer. + // Note that GLES2 spec does not say anything about how passing a null + // pointer should be treated. Testing on desktop core GL 3, the application + // crashes on glGetIntegerv to a null pointer, but better to report an error + // instead of doing anything random. + if (!p) { + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + var ret = undefined; + switch (name_) { // Handle a few trivial GLES values + case 0x8DFA: // GL_SHADER_COMPILER + ret = 1; + break; + case 0x8DF8: // GL_SHADER_BINARY_FORMATS + if (type != 0 && type != 1) { + GL.recordError(0x500); // GL_INVALID_ENUM + } + // Do not write anything to the out pointer, since no binary formats are + // supported. + return; + case 0x8DF9: // GL_NUM_SHADER_BINARY_FORMATS + ret = 0; + break; + case 0x86A2: // GL_NUM_COMPRESSED_TEXTURE_FORMATS + // WebGL doesn't have GL_NUM_COMPRESSED_TEXTURE_FORMATS (it's obsolete + // since GL_COMPRESSED_TEXTURE_FORMATS returns a JS array that can be + // queried for length), so implement it ourselves to allow C++ GLES2 + // code to get the length. + var formats = GLctx.getParameter(0x86A3 /*GL_COMPRESSED_TEXTURE_FORMATS*/); + ret = formats ? formats.length : 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(0x500); // GL_INVALID_ENUM + return; + case 'object': + if (result === null) { + // null is a valid result for some (e.g., which buffer is bound - + // perhaps nothing is bound), but otherwise can mean an invalid + // name_, which we need to report as an error + switch (name_) { + case 0x8894: // ARRAY_BUFFER_BINDING + case 0x8B8D: // CURRENT_PROGRAM + case 0x8895: // ELEMENT_ARRAY_BUFFER_BINDING + case 0x8CA6: // FRAMEBUFFER_BINDING or DRAW_FRAMEBUFFER_BINDING + case 0x8CA7: // RENDERBUFFER_BINDING + case 0x8069: // TEXTURE_BINDING_2D + case 0x85B5: // WebGL 2 GL_VERTEX_ARRAY_BINDING, or WebGL 1 extension OES_vertex_array_object GL_VERTEX_ARRAY_BINDING_OES + case 0x8514: { // TEXTURE_BINDING_CUBE_MAP + ret = 0; + break; + } + default: { + GL.recordError(0x500); // GL_INVALID_ENUM + return; + } + } + } else if (result instanceof Float32Array || + result instanceof Uint32Array || + result instanceof Int32Array || + result instanceof Array) { + for (var i = 0; i < result.length; ++i) { + switch (type) { + case 0: HEAP32[(((p)+(i*4))>>2)] = result[i]; break; + case 2: HEAPF32[(((p)+(i*4))>>2)] = result[i]; break; + case 4: HEAP8[(p)+(i)] = result[i] ? 1 : 0; break; + } + } + return; + } else { + try { + ret = result.name | 0; + } catch(e) { + GL.recordError(0x500); // GL_INVALID_ENUM + err(`GL_INVALID_ENUM in glGet${type}v: Unknown object returned from WebGL getParameter(${name_})! (error: ${e})`); + return; + } + } + break; + default: + GL.recordError(0x500); // GL_INVALID_ENUM + 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] = ret ? 1 : 0; break; + } + }; + + var _emscripten_glGetBooleanv = (name_, p) => emscriptenWebGLGet(name_, p, 4); + + + var _emscripten_glGetBufferParameteriv = (target, value, data) => { + if (!data) { + // GLES2 specification does not specify how to behave if data is a null + // pointer. Since calling this function does not make sense if data == + // null, issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + HEAP32[((data)>>2)] = GLctx.getBufferParameter(target, value); + }; + + var _emscripten_glGetError = () => { + var error = GLctx.getError() || GL.lastError; + GL.lastError = 0/*GL_NO_ERROR*/; + return error; + }; + + + var _emscripten_glGetFloatv = (name_, p) => emscriptenWebGLGet(name_, p, 2); + + + var _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; + }; + + + var _emscripten_glGetIntegerv = (name_, p) => emscriptenWebGLGet(name_, p, 0); + + + var _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; + }; + + + var _emscripten_glGetProgramiv = (program, pname, p) => { + if (!p) { + // GLES2 specification does not specify how to behave if p is a null + // pointer. Since calling this function does not make sense if p == null, + // issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + + if (program >= GL.counter) { + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + + program = GL.programs[program]; + + if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH + var log = GLctx.getProgramInfoLog(program); + if (log === null) log = '(unknown error)'; + HEAP32[((p)>>2)] = log.length + 1; + } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) { + if (!program.maxUniformLength) { + var numActiveUniforms = GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); + for (var i = 0; i < numActiveUniforms; ++i) { + program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length+1); + } + } + HEAP32[((p)>>2)] = program.maxUniformLength; + } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) { + if (!program.maxAttributeLength) { + var numActiveAttributes = GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/); + for (var i = 0; i < numActiveAttributes; ++i) { + program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length+1); + } + } + HEAP32[((p)>>2)] = program.maxAttributeLength; + } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) { + if (!program.maxUniformBlockNameLength) { + var numActiveUniformBlocks = GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/); + for (var i = 0; i < numActiveUniformBlocks; ++i) { + program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length+1); + } + } + HEAP32[((p)>>2)] = program.maxUniformBlockNameLength; + } else { + HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname); + } + }; + + + var _emscripten_glGetQueryObjecti64vEXT = (id, pname, params) => { + if (!params) { + // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense + // if p == null, issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + var query = GL.queries[id]; + var param; + { + param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname); + } + var ret; + if (typeof param == 'boolean') { + ret = param ? 1 : 0; + } else { + ret = param; + } + writeI53ToI64(params, ret); + }; + + + var _emscripten_glGetQueryObjectivEXT = (id, pname, params) => { + if (!params) { + // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense + // if p == null, issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + var query = GL.queries[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; + }; + + + var _glGetQueryObjecti64vEXT = _emscripten_glGetQueryObjecti64vEXT; + var _emscripten_glGetQueryObjectui64vEXT = _glGetQueryObjecti64vEXT; + + + var _glGetQueryObjectivEXT = _emscripten_glGetQueryObjectivEXT; + var _emscripten_glGetQueryObjectuivEXT = _glGetQueryObjectivEXT; + + + var _emscripten_glGetQueryivEXT = (target, pname, params) => { + if (!params) { + // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense + // if p == null, issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + HEAP32[((params)>>2)] = GLctx.disjointTimerQueryExt['getQueryEXT'](target, pname); + }; + + + var _emscripten_glGetRenderbufferParameteriv = (target, pname, params) => { + if (!params) { + // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense + // if params == null, issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + HEAP32[((params)>>2)] = GLctx.getRenderbufferParameter(target, pname); + }; + + + + var _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; + }; + + + var _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; + }; + + + var _emscripten_glGetShaderSource = (shader, bufSize, length, source) => { + var result = GLctx.getShaderSource(GL.shaders[shader]); + if (!result) return; // If an error occurs, nothing will be written to length or source. + var numBytesWrittenExclNull = (bufSize > 0 && source) ? stringToUTF8(result, source, bufSize) : 0; + if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull; + }; + + + var _emscripten_glGetShaderiv = (shader, pname, p) => { + if (!p) { + // GLES2 specification does not specify how to behave if p is a null + // pointer. Since calling this function does not make sense if p == null, + // issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH + var log = GLctx.getShaderInfoLog(GL.shaders[shader]); + if (log === null) log = '(unknown error)'; + // The GLES2 specification says that if the shader has an empty info log, + // a value of 0 is returned. Otherwise the log has a null char appended. + // (An empty string is falsey, so we can just check that instead of + // looking at log.length.) + var logLength = log ? log.length + 1 : 0; + HEAP32[((p)>>2)] = logLength; + } else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH + var source = GLctx.getShaderSource(GL.shaders[shader]); + // source may be a null, or the empty string, both of which are falsey + // values that we report a 0 length for. + var sourceLength = source ? source.length + 1 : 0; + HEAP32[((p)>>2)] = sourceLength; + } else { + HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname); + } + }; + + + + var stringToNewUTF8 = (str) => { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) stringToUTF8(str, ret, size); + return ret; + }; + + + var webglGetExtensions = () => { + var exts = getEmscriptenSupportedExtensions(GLctx); + exts = exts.concat(exts.map((e) => 'GL_' + e)); + return exts; + }; + + var _emscripten_glGetString = (name_) => { + var ret = GL.stringCache[name_]; + if (!ret) { + switch (name_) { + case 0x1F03 /* GL_EXTENSIONS */: + ret = stringToNewUTF8(webglGetExtensions().join(' ')); + break; + case 0x1F00 /* GL_VENDOR */: + case 0x1F01 /* GL_RENDERER */: + case 0x9245 /* UNMASKED_VENDOR_WEBGL */: + case 0x9246 /* UNMASKED_RENDERER_WEBGL */: + var s = GLctx.getParameter(name_); + if (!s) { + GL.recordError(0x500/*GL_INVALID_ENUM*/); + } + ret = s ? stringToNewUTF8(s) : 0; + break; + + case 0x1F02 /* GL_VERSION */: + var webGLVersion = GLctx.getParameter(0x1F02 /*GL_VERSION*/); + // return GLES version string corresponding to the version of the WebGL context + var glVersion = `OpenGL ES 2.0 (${webGLVersion})`; + ret = stringToNewUTF8(glVersion); + break; + case 0x8B8C /* GL_SHADING_LANGUAGE_VERSION */: + var glslVersion = GLctx.getParameter(0x8B8C /*GL_SHADING_LANGUAGE_VERSION*/); + // extract the version number 'N.M' from the string 'WebGL GLSL ES N.M ...' + 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'; // ensure minor version has 2 digits + glslVersion = `OpenGL ES GLSL ES ${ver_num[1]} (${glslVersion})`; + } + ret = stringToNewUTF8(glslVersion); + break; + default: + GL.recordError(0x500/*GL_INVALID_ENUM*/); + // fall through + } + GL.stringCache[name_] = ret; + } + return ret; + }; + + + var _emscripten_glGetTexParameterfv = (target, pname, params) => { + if (!params) { + // GLES2 specification does not specify how to behave if params is a null + // pointer. Since calling this function does not make sense if p == null, + // issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + HEAPF32[((params)>>2)] = GLctx.getTexParameter(target, pname); + }; + + + var _emscripten_glGetTexParameteriv = (target, pname, params) => { + if (!params) { + // GLES2 specification does not specify how to behave if params is a null + // pointer. Since calling this function does not make sense if p == null, + // issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + HEAP32[((params)>>2)] = GLctx.getTexParameter(target, pname); + }; + + /** @suppress {checkTypes} */ + var jstoi_q = (str) => parseInt(str); + + /** @noinline */ + var webglGetLeftBracePos = (name) => name.slice(-1) == ']' && name.lastIndexOf('['); + + var webglPrepareUniformLocationsBeforeFirstUse = (program) => { + var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation + uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint] + i, j; + + // On the first time invocation of glGetUniformLocation on this shader program: + // initialize cache data structures and discover which uniforms are arrays. + if (!uniformLocsById) { + // maps GLint integer locations to WebGLUniformLocations + program.uniformLocsById = uniformLocsById = {}; + // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations + program.uniformArrayNamesById = {}; + + var numActiveUniforms = GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); + for (i = 0; i < numActiveUniforms; ++i) { + var u = GLctx.getActiveUniform(program, i); + var nm = u.name; + var sz = u.size; + var lb = webglGetLeftBracePos(nm); + var arrayName = lb > 0 ? nm.slice(0, lb) : nm; + + // Assign a new location. + var id = program.uniformIdCounter; + program.uniformIdCounter += sz; + // Eagerly get the location of the uniformArray[0] base element. + // The remaining indices >0 will be left for lazy evaluation to + // improve performance. Those may never be needed to fetch, if the + // application fills arrays always in full starting from the first + // element of the array. + uniformSizeAndIdsByName[arrayName] = [sz, id]; + + // Store placeholder integers in place that highlight that these + // >0 index locations are array indices pending population. + for (j = 0; j < sz; ++j) { + uniformLocsById[id] = j; + program.uniformArrayNamesById[id++] = arrayName; + } + } + } + }; + + + + var _emscripten_glGetUniformLocation = (program, name) => { + + name = UTF8ToString(name); + + if (program = GL.programs[program]) { + webglPrepareUniformLocationsBeforeFirstUse(program); + var uniformLocsById = program.uniformLocsById; // Maps GLuint -> WebGLUniformLocation + var arrayIndex = 0; + var uniformBaseName = name; + + // Invariant: when populating integer IDs for uniform locations, we must + // maintain the precondition that arrays reside in contiguous addresses, + // i.e. for a 'vec4 colors[10];', colors[4] must be at location + // colors[0]+4. However, user might call glGetUniformLocation(program, + // "colors") for an array, so we cannot discover based on the user input + // arguments whether the uniform we are dealing with is an array. The only + // way to discover which uniforms are arrays is to enumerate over all the + // active uniforms in the program. + var leftBrace = webglGetLeftBracePos(name); + + // If user passed an array accessor "[index]", parse the array index off the accessor. + if (leftBrace > 0) { + arrayIndex = jstoi_q(name.slice(leftBrace + 1)) >>> 0; // "index]", coerce parseInt(']') with >>>0 to treat "foo[]" as "foo[0]" and foo[-1] as unsigned out-of-bounds. + uniformBaseName = name.slice(0, leftBrace); + } + + // Have we cached the location of this uniform before? + // A pair [array length, GLint of the uniform location] + var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName]; + + // If a uniform with this name exists, and if its index is within the + // array limits (if it's even an array), query the WebGLlocation, or + // return an existing cached location. + if (sizeAndId && arrayIndex < sizeAndId[0]) { + arrayIndex += sizeAndId[1]; // Add the base location of the uniform to the array index offset. + if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) { + return arrayIndex; + } + } + } + else { + // N.b. we are currently unable to distinguish between GL program IDs that + // never existed vs GL program IDs that have been deleted, so report + // GL_INVALID_VALUE in both cases. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + } + return -1; + }; + + + var webglGetProgramUniformLocation = (program, location) => { + + if (program) { + var webglLoc = program.uniformLocsById[location]; + // program.uniformLocsById[location] stores either an integer, or a + // WebGLUniformLocation. + // If an integer, we have not yet bound the location, so do it now. The + // integer value specifies the array index we should bind to. + if (typeof webglLoc == 'number') { + program.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(program, program.uniformArrayNamesById[location] + (webglLoc > 0 ? `[${webglLoc}]` : '')); + } + // Else an already cached WebGLUniformLocation, return it. + return webglLoc; + } else { + GL.recordError(0x502/*GL_INVALID_OPERATION*/); + } + }; + + + + + /** @suppress{checkTypes} */ + var emscriptenWebGLGetUniform = (program, location, params, type) => { + if (!params) { + // GLES2 specification does not specify how to behave if params is a null + // pointer. Since calling this function does not make sense if params == + // null, issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + program = GL.programs[program]; + webglPrepareUniformLocationsBeforeFirstUse(program); + var data = GLctx.getUniform(program, webglGetProgramUniformLocation(program, location)); + if (typeof data == 'number' || typeof data == 'boolean') { + switch (type) { + case 0: HEAP32[((params)>>2)] = data; break; + case 2: HEAPF32[((params)>>2)] = data; break; + } + } else { + for (var i = 0; i < data.length; i++) { + switch (type) { + case 0: HEAP32[(((params)+(i*4))>>2)] = data[i]; break; + case 2: HEAPF32[(((params)+(i*4))>>2)] = data[i]; break; + } + } + } + }; + + var _emscripten_glGetUniformfv = (program, location, params) => { + emscriptenWebGLGetUniform(program, location, params, 2); + }; + + + var _emscripten_glGetUniformiv = (program, location, params) => { + emscriptenWebGLGetUniform(program, location, params, 0); + }; + + + var _emscripten_glGetVertexAttribPointerv = (index, pname, pointer) => { + if (!pointer) { + // GLES2 specification does not specify how to behave if pointer is a null + // pointer. Since calling this function does not make sense if pointer == + // null, issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + HEAP32[((pointer)>>2)] = GLctx.getVertexAttribOffset(index, pname); + }; + + + + /** @suppress{checkTypes} */ + var emscriptenWebGLGetVertexAttrib = (index, pname, params, type) => { + if (!params) { + // GLES2 specification does not specify how to behave if params is a null + // pointer. Since calling this function does not make sense if params == + // null, issue a GL error to notify user about it. + GL.recordError(0x501 /* GL_INVALID_VALUE */); + return; + } + var data = GLctx.getVertexAttrib(index, pname); + if (pname == 0x889F/*VERTEX_ATTRIB_ARRAY_BUFFER_BINDING*/) { + 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 < data.length; i++) { + switch (type) { + case 0: HEAP32[(((params)+(i*4))>>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; + } + } + } + }; + + var _emscripten_glGetVertexAttribfv = (index, pname, params) => { + // N.B. This function may only be called if the vertex attribute was + // specified using the function glVertexAttrib*f(), otherwise the results + // are undefined. (GLES3 spec 6.1.12) + emscriptenWebGLGetVertexAttrib(index, pname, params, 2); + }; + + + var _emscripten_glGetVertexAttribiv = (index, pname, params) => { + // N.B. This function may only be called if the vertex attribute was + // specified using the function glVertexAttrib*f(), otherwise the results + // are undefined. (GLES3 spec 6.1.12) + emscriptenWebGLGetVertexAttrib(index, pname, params, 5); + }; + + var _emscripten_glHint = (x0, x1) => GLctx.hint(x0, x1); + + var _emscripten_glIsBuffer = (buffer) => { + var b = GL.buffers[buffer]; + if (!b) return 0; + return GLctx.isBuffer(b); + }; + + var _emscripten_glIsEnabled = (x0) => GLctx.isEnabled(x0); + + var _emscripten_glIsFramebuffer = (framebuffer) => { + var fb = GL.framebuffers[framebuffer]; + if (!fb) return 0; + return GLctx.isFramebuffer(fb); + }; + + var _emscripten_glIsProgram = (program) => { + program = GL.programs[program]; + if (!program) return 0; + return GLctx.isProgram(program); + }; + + var _emscripten_glIsQueryEXT = (id) => { + var query = GL.queries[id]; + if (!query) return 0; + return GLctx.disjointTimerQueryExt['isQueryEXT'](query); + }; + + var _emscripten_glIsRenderbuffer = (renderbuffer) => { + var rb = GL.renderbuffers[renderbuffer]; + if (!rb) return 0; + return GLctx.isRenderbuffer(rb); + }; + + var _emscripten_glIsShader = (shader) => { + var s = GL.shaders[shader]; + if (!s) return 0; + return GLctx.isShader(s); + }; + + var _emscripten_glIsTexture = (id) => { + var texture = GL.textures[id]; + if (!texture) return 0; + return GLctx.isTexture(texture); + }; + + + var _emscripten_glIsVertexArray = (array) => { + + var vao = GL.vaos[array]; + if (!vao) return 0; + return GLctx.isVertexArray(vao); + }; + var _glIsVertexArray = _emscripten_glIsVertexArray; + var _emscripten_glIsVertexArrayOES = _glIsVertexArray; + + var _emscripten_glLineWidth = (x0) => GLctx.lineWidth(x0); + + var _emscripten_glLinkProgram = (program) => { + program = GL.programs[program]; + GLctx.linkProgram(program); + // Invalidate earlier computed uniform->ID mappings, those have now become stale + program.uniformLocsById = 0; // Mark as null-like so that glGetUniformLocation() knows to populate this again. + program.uniformSizeAndIdsByName = {}; + + }; + + var _emscripten_glPixelStorei = (pname, param) => { + if (pname == 3317) { + GL.unpackAlignment = param; + } else if (pname == 3314) { + GL.unpackRowLength = param; + } + GLctx.pixelStorei(pname, param); + }; + + var _emscripten_glPolygonModeWEBGL = (face, mode) => { + GLctx.webglPolygonMode['polygonModeWEBGL'](face, mode); + }; + + var _emscripten_glPolygonOffset = (x0, x1) => GLctx.polygonOffset(x0, x1); + + var _emscripten_glPolygonOffsetClampEXT = (factor, units, clamp) => { + GLctx.extPolygonOffsetClamp['polygonOffsetClampEXT'](factor, units, clamp); + }; + + var _emscripten_glQueryCounterEXT = (id, target) => { + GLctx.disjointTimerQueryExt['queryCounterEXT'](GL.queries[id], target); + }; + + var computeUnpackAlignedImageSize = (width, height, sizePerPixel) => { + function roundedToNextMultipleOf(x, y) { + return (x + y - 1) & -y; + } + var plainRowSize = (GL.unpackRowLength || width) * sizePerPixel; + var alignedRowSize = roundedToNextMultipleOf(plainRowSize, GL.unpackAlignment); + return height * alignedRowSize; + }; + + var colorChannelsInGlTextureFormat = (format) => { + // Micro-optimizations for size: map format to size by subtracting smallest + // enum value (0x1902) from all values first. Also omit the most common + // size value (1) from the list, which is assumed by formats not on the + // list. + var colorChannels = { + // 0x1902 /* GL_DEPTH_COMPONENT */ - 0x1902: 1, + // 0x1906 /* GL_ALPHA */ - 0x1902: 1, + 5: 3, + 6: 4, + // 0x1909 /* GL_LUMINANCE */ - 0x1902: 1, + 8: 2, + 29502: 3, + 29504: 4, + }; + return colorChannels[format - 0x1902]||1; + }; + + + + /** @type {!Uint16Array} */ + var HEAPU16; + + + + var heapObjectForWebGLType = (type) => { + // Micro-optimization for size: Subtract lowest GL enum number (0x1400/* GL_BYTE */) from type to compare + // smaller values for the heap, for shorter generated code size. + // Also the type HEAPU16 is not tested for explicitly, but any unrecognized type will return out HEAPU16. + // (since most types are HEAPU16) + type -= 0x1400; + + if (type == 1) return HEAPU8; + + if (type == 4) return HEAP32; + + if (type == 6) return HEAPF32; + + if (type == 5 + || type == 28922 + ) + return HEAPU32; + + return HEAPU16; + }; + + var toTypedArrayIndex = (pointer, heap) => + pointer >>> (31 - Math.clz32(heap.BYTES_PER_ELEMENT)); + + var emscriptenWebGLGetTexPixelData = (type, format, width, height, pixels) => { + var heap = heapObjectForWebGLType(type); + var sizePerPixel = colorChannelsInGlTextureFormat(format) * heap.BYTES_PER_ELEMENT; + var bytes = computeUnpackAlignedImageSize(width, height, sizePerPixel); + return heap.subarray(toTypedArrayIndex(pixels, heap), toTypedArrayIndex(pixels + bytes, heap)); + }; + + var _emscripten_glReadPixels = (x, y, width, height, format, type, pixels) => { + var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels); + if (!pixelData) { + GL.recordError(0x500/*GL_INVALID_ENUM*/); + return; + } + GLctx.readPixels(x, y, width, height, format, type, pixelData); + }; + + var _emscripten_glReleaseShaderCompiler = () => { + // NOP (as allowed by GLES 2.0 spec) + }; + + var _emscripten_glRenderbufferStorage = (x0, x1, x2, x3) => GLctx.renderbufferStorage(x0, x1, x2, x3); + + var _emscripten_glSampleCoverage = (value, invert) => { + GLctx.sampleCoverage(value, !!invert); + }; + + var _emscripten_glScissor = (x0, x1, x2, x3) => GLctx.scissor(x0, x1, x2, x3); + + var _emscripten_glShaderBinary = (count, shaders, binaryformat, binary, length) => { + GL.recordError(0x500/*GL_INVALID_ENUM*/); + }; + + var _emscripten_glShaderSource = (shader, count, string, length) => { + var source = GL.getSource(shader, count, string, length); + + GLctx.shaderSource(GL.shaders[shader], source); + }; + + var _emscripten_glStencilFunc = (x0, x1, x2) => GLctx.stencilFunc(x0, x1, x2); + + var _emscripten_glStencilFuncSeparate = (x0, x1, x2, x3) => GLctx.stencilFuncSeparate(x0, x1, x2, x3); + + var _emscripten_glStencilMask = (x0) => GLctx.stencilMask(x0); + + var _emscripten_glStencilMaskSeparate = (x0, x1) => GLctx.stencilMaskSeparate(x0, x1); + + var _emscripten_glStencilOp = (x0, x1, x2) => GLctx.stencilOp(x0, x1, x2); + + var _emscripten_glStencilOpSeparate = (x0, x1, x2, x3) => GLctx.stencilOpSeparate(x0, x1, x2, x3); + + + var _emscripten_glTexImage2D = (target, level, internalFormat, width, height, border, format, type, pixels) => { + var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels) : null; + GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixelData); + }; + + var _emscripten_glTexParameterf = (x0, x1, x2) => GLctx.texParameterf(x0, x1, x2); + + + var _emscripten_glTexParameterfv = (target, pname, params) => { + var param = HEAPF32[((params)>>2)]; + GLctx.texParameterf(target, pname, param); + }; + + var _emscripten_glTexParameteri = (x0, x1, x2) => GLctx.texParameteri(x0, x1, x2); + + + var _emscripten_glTexParameteriv = (target, pname, params) => { + var param = HEAP32[((params)>>2)]; + GLctx.texParameteri(target, pname, param); + }; + + + var _emscripten_glTexSubImage2D = (target, level, xoffset, yoffset, width, height, format, type, pixels) => { + var pixelData = pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels) : null; + GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData); + }; + + + var webglGetUniformLocation = (location) => { + + return webglGetProgramUniformLocation(GLctx.currentProgram, location); + }; + + var _emscripten_glUniform1f = (location, v0) => { + GLctx.uniform1f(webglGetUniformLocation(location), v0); + }; + + + var miniTempWebGLFloatBuffers = []; + + + var _emscripten_glUniform1fv = (location, count, value) => { + + if (count <= 288) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; ++i) { + view[i] = HEAPF32[(((value)+(4*i))>>2)]; + } + } else + { + var view = HEAPF32.subarray((((value)>>2)), ((value+count*4)>>2)); + } + GLctx.uniform1fv(webglGetUniformLocation(location), view); + }; + + + var _emscripten_glUniform1i = (location, v0) => { + GLctx.uniform1i(webglGetUniformLocation(location), v0); + }; + + + var miniTempWebGLIntBuffers = []; + + + var _emscripten_glUniform1iv = (location, count, value) => { + + if (count <= 288) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLIntBuffers[count]; + for (var i = 0; i < count; ++i) { + view[i] = HEAP32[(((value)+(4*i))>>2)]; + } + } else + { + var view = HEAP32.subarray((((value)>>2)), ((value+count*4)>>2)); + } + GLctx.uniform1iv(webglGetUniformLocation(location), view); + }; + + + var _emscripten_glUniform2f = (location, v0, v1) => { + GLctx.uniform2f(webglGetUniformLocation(location), v0, v1); + }; + + + + + var _emscripten_glUniform2fv = (location, count, value) => { + + if (count <= 144) { + // avoid allocation when uploading few enough uniforms + count *= 2; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 2) { + view[i] = HEAPF32[(((value)+(4*i))>>2)]; + view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)]; + } + } else + { + var view = HEAPF32.subarray((((value)>>2)), ((value+count*8)>>2)); + } + GLctx.uniform2fv(webglGetUniformLocation(location), view); + }; + + + var _emscripten_glUniform2i = (location, v0, v1) => { + GLctx.uniform2i(webglGetUniformLocation(location), v0, v1); + }; + + + + + var _emscripten_glUniform2iv = (location, count, value) => { + + if (count <= 144) { + // avoid allocation when uploading few enough uniforms + count *= 2; + var view = miniTempWebGLIntBuffers[count]; + for (var i = 0; i < count; i += 2) { + view[i] = HEAP32[(((value)+(4*i))>>2)]; + view[i+1] = HEAP32[(((value)+(4*i+4))>>2)]; + } + } else + { + var view = HEAP32.subarray((((value)>>2)), ((value+count*8)>>2)); + } + GLctx.uniform2iv(webglGetUniformLocation(location), view); + }; + + + var _emscripten_glUniform3f = (location, v0, v1, v2) => { + GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2); + }; + + + + + var _emscripten_glUniform3fv = (location, count, value) => { + + if (count <= 96) { + // avoid allocation when uploading few enough uniforms + count *= 3; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 3) { + view[i] = HEAPF32[(((value)+(4*i))>>2)]; + view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)]; + view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)]; + } + } else + { + var view = HEAPF32.subarray((((value)>>2)), ((value+count*12)>>2)); + } + GLctx.uniform3fv(webglGetUniformLocation(location), view); + }; + + + var _emscripten_glUniform3i = (location, v0, v1, v2) => { + GLctx.uniform3i(webglGetUniformLocation(location), v0, v1, v2); + }; + + + + + var _emscripten_glUniform3iv = (location, count, value) => { + + if (count <= 96) { + // avoid allocation when uploading few enough uniforms + count *= 3; + var view = miniTempWebGLIntBuffers[count]; + for (var i = 0; i < count; i += 3) { + view[i] = HEAP32[(((value)+(4*i))>>2)]; + view[i+1] = HEAP32[(((value)+(4*i+4))>>2)]; + view[i+2] = HEAP32[(((value)+(4*i+8))>>2)]; + } + } else + { + var view = HEAP32.subarray((((value)>>2)), ((value+count*12)>>2)); + } + GLctx.uniform3iv(webglGetUniformLocation(location), view); + }; + + + var _emscripten_glUniform4f = (location, v0, v1, v2, v3) => { + GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3); + }; + + + + + var _emscripten_glUniform4fv = (location, count, value) => { + + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[4*count]; + // hoist the heap out of the loop for size and for pthreads+growth. + var heap = HEAPF32; + value = ((value)>>2); + count *= 4; + for (var i = 0; i < count; i += 4) { + var dst = value + i; + view[i] = heap[dst]; + view[i + 1] = heap[dst + 1]; + view[i + 2] = heap[dst + 2]; + view[i + 3] = heap[dst + 3]; + } + } else + { + var view = HEAPF32.subarray((((value)>>2)), ((value+count*16)>>2)); + } + GLctx.uniform4fv(webglGetUniformLocation(location), view); + }; + + + var _emscripten_glUniform4i = (location, v0, v1, v2, v3) => { + GLctx.uniform4i(webglGetUniformLocation(location), v0, v1, v2, v3); + }; + + + + + var _emscripten_glUniform4iv = (location, count, value) => { + + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + count *= 4; + var view = miniTempWebGLIntBuffers[count]; + for (var i = 0; i < count; i += 4) { + view[i] = HEAP32[(((value)+(4*i))>>2)]; + view[i+1] = HEAP32[(((value)+(4*i+4))>>2)]; + view[i+2] = HEAP32[(((value)+(4*i+8))>>2)]; + view[i+3] = HEAP32[(((value)+(4*i+12))>>2)]; + } + } else + { + var view = HEAP32.subarray((((value)>>2)), ((value+count*16)>>2)); + } + GLctx.uniform4iv(webglGetUniformLocation(location), view); + }; + + + + + var _emscripten_glUniformMatrix2fv = (location, count, transpose, value) => { + + if (count <= 72) { + // avoid allocation when uploading few enough uniforms + count *= 4; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 4) { + view[i] = HEAPF32[(((value)+(4*i))>>2)]; + view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)]; + view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)]; + view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)]; + } + } else + { + var view = HEAPF32.subarray((((value)>>2)), ((value+count*16)>>2)); + } + GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view); + }; + + + + + var _emscripten_glUniformMatrix3fv = (location, count, transpose, value) => { + + if (count <= 32) { + // avoid allocation when uploading few enough uniforms + count *= 9; + var view = miniTempWebGLFloatBuffers[count]; + for (var i = 0; i < count; i += 9) { + view[i] = HEAPF32[(((value)+(4*i))>>2)]; + view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)]; + view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)]; + view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)]; + view[i+4] = HEAPF32[(((value)+(4*i+16))>>2)]; + view[i+5] = HEAPF32[(((value)+(4*i+20))>>2)]; + view[i+6] = HEAPF32[(((value)+(4*i+24))>>2)]; + view[i+7] = HEAPF32[(((value)+(4*i+28))>>2)]; + view[i+8] = HEAPF32[(((value)+(4*i+32))>>2)]; + } + } else + { + var view = HEAPF32.subarray((((value)>>2)), ((value+count*36)>>2)); + } + GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view); + }; + + + + + var _emscripten_glUniformMatrix4fv = (location, count, transpose, value) => { + + if (count <= 18) { + // avoid allocation when uploading few enough uniforms + var view = miniTempWebGLFloatBuffers[16*count]; + // hoist the heap out of the loop for size and for pthreads+growth. + var heap = HEAPF32; + value = ((value)>>2); + count *= 16; + for (var i = 0; i < count; i += 16) { + var dst = value + i; + view[i] = heap[dst]; + view[i + 1] = heap[dst + 1]; + view[i + 2] = heap[dst + 2]; + view[i + 3] = heap[dst + 3]; + view[i + 4] = heap[dst + 4]; + view[i + 5] = heap[dst + 5]; + view[i + 6] = heap[dst + 6]; + view[i + 7] = heap[dst + 7]; + view[i + 8] = heap[dst + 8]; + view[i + 9] = heap[dst + 9]; + view[i + 10] = heap[dst + 10]; + view[i + 11] = heap[dst + 11]; + view[i + 12] = heap[dst + 12]; + view[i + 13] = heap[dst + 13]; + view[i + 14] = heap[dst + 14]; + view[i + 15] = heap[dst + 15]; + } + } else + { + var view = HEAPF32.subarray((((value)>>2)), ((value+count*64)>>2)); + } + GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view); + }; + + var _emscripten_glUseProgram = (program) => { + program = GL.programs[program]; + GLctx.useProgram(program); + // Record the currently active program so that we can access the uniform + // mapping table of that program. + GLctx.currentProgram = program; + }; + + var _emscripten_glValidateProgram = (program) => { + GLctx.validateProgram(GL.programs[program]); + }; + + var _emscripten_glVertexAttrib1f = (x0, x1) => GLctx.vertexAttrib1f(x0, x1); + + + var _emscripten_glVertexAttrib1fv = (index, v) => { + + GLctx.vertexAttrib1f(index, HEAPF32[v>>2]); + }; + + var _emscripten_glVertexAttrib2f = (x0, x1, x2) => GLctx.vertexAttrib2f(x0, x1, x2); + + + var _emscripten_glVertexAttrib2fv = (index, v) => { + + GLctx.vertexAttrib2f(index, HEAPF32[v>>2], HEAPF32[v+4>>2]); + }; + + var _emscripten_glVertexAttrib3f = (x0, x1, x2, x3) => GLctx.vertexAttrib3f(x0, x1, x2, x3); + + + var _emscripten_glVertexAttrib3fv = (index, v) => { + + GLctx.vertexAttrib3f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2]); + }; + + var _emscripten_glVertexAttrib4f = (x0, x1, x2, x3, x4) => GLctx.vertexAttrib4f(x0, x1, x2, x3, x4); + + + var _emscripten_glVertexAttrib4fv = (index, v) => { + + GLctx.vertexAttrib4f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2], HEAPF32[v+12>>2]); + }; + + + var _emscripten_glVertexAttribDivisor = (index, divisor) => { + GLctx.vertexAttribDivisor(index, divisor); + }; + var _glVertexAttribDivisor = _emscripten_glVertexAttribDivisor; + var _emscripten_glVertexAttribDivisorANGLE = _glVertexAttribDivisor; + + var _emscripten_glVertexAttribPointer = (index, size, type, normalized, stride, ptr) => { + GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); + }; + + var _emscripten_glViewport = (x0, x1, x2, x3) => GLctx.viewport(x0, x1, x2, x3); + + var abortOnCannotGrowMemory = (requestedSize) => { + abort(`Cannot enlarge memory arrays to size ${requestedSize} bytes (OOM). Either (1) compile with -sINITIAL_MEMORY=X with X higher than the current value ${HEAP8.length}, (2) compile with -sALLOW_MEMORY_GROWTH which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -sABORTING_MALLOC=0`); + }; + + var _emscripten_resize_heap = (requestedSize) => { + var oldSize = HEAPU8.length; + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + requestedSize >>>= 0; + abortOnCannotGrowMemory(requestedSize); + }; + + /** @suppress {checkTypes} */ + var _emscripten_sample_gamepad_data = () => { + try { + if (navigator.getGamepads) return (JSEvents.lastGamepadState = navigator.getGamepads()) + ? 0 : -1; + } catch(e) { + err(`navigator.getGamepads() exists, but failed to execute with exception ${e}. Disabling Gamepad access.`); + navigator.getGamepads = null; // Disable getGamepads() so that it won't be attempted to be used again. + } + return -1; + }; + + var findCanvasEventTarget = findEventTarget; + var _emscripten_set_canvas_element_size = (target, width, height) => { + var canvas = findCanvasEventTarget(target); + if (!canvas) return -4; + canvas.width = width; + canvas.height = height; + return 0; + }; + + + + + + + var fillMouseEventData = (eventStruct, e, target) => { + assert(eventStruct % 4 == 0); + HEAPF64[((eventStruct)>>3)] = e.timeStamp; + var idx = ((eventStruct)>>2); + HEAP32[idx + 2] = e.screenX; + HEAP32[idx + 3] = e.screenY; + HEAP32[idx + 4] = e.clientX; + HEAP32[idx + 5] = e.clientY; + HEAP8[eventStruct + 24] = e.ctrlKey; + HEAP8[eventStruct + 25] = e.shiftKey; + HEAP8[eventStruct + 26] = e.altKey; + HEAP8[eventStruct + 27] = e.metaKey; + HEAP16[idx*2 + 14] = e.button; + HEAP16[idx*2 + 15] = e.buttons; + HEAP32[idx + 8] = e.movementX; + HEAP32[idx + 9] = e.movementY; + + // Note: rect contains doubles (truncated to placate SAFE_HEAP, which is the same behaviour when writing to HEAP32 anyway) + var rect = getBoundingClientRect(target); + HEAP32[idx + 10] = e.clientX - (rect.left | 0); + HEAP32[idx + 11] = e.clientY - (rect.top | 0); + }; + + + var registerMouseEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => { + var eventSize = 64; + JSEvents.mouseEvent ||= _malloc(eventSize); + target = findEventTarget(target); + + var mouseEventHandlerFunc = (e) => { + // TODO: Make this access thread safe, or this could update live while app is reading it. + fillMouseEventData(JSEvents.mouseEvent, e, target); + + if (((a1, a2, a3) => dynCall_iiii(callbackfunc, a1, a2, a3))(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault(); + }; + + var eventHandler = { + target, + allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them! + eventTypeString, + eventTypeId, + userData, + callbackfunc, + handlerFunc: mouseEventHandlerFunc, + useCapture + }; + return JSEvents.registerOrRemoveHandler(eventHandler); + }; + var _emscripten_set_click_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => + registerMouseEventCallback(target, userData, useCapture, callbackfunc, 4, 'click', targetThread); + + + + + + function getFullscreenElement() { + return document.fullscreenElement + ?? document.webkitFullscreenElement + ; + } + + + var fillFullscreenChangeEventData = (eventStruct) => { + var fullscreenElement = getFullscreenElement(); + var isFullscreen = !!fullscreenElement; + // Assigning a boolean to HEAP32 with expected type coercion. + /** @suppress{checkTypes} */ + HEAP8[eventStruct] = isFullscreen; + HEAP8[(eventStruct)+(1)] = JSEvents.fullscreenEnabled(); + // If transitioning to fullscreen, report info about the element that is now fullscreen. + // If transitioning to windowed mode, report info about the element that just was fullscreen. + var reportedElement = isFullscreen ? fullscreenElement : JSEvents.previousFullscreenElement; + var nodeName = JSEvents.getNodeNameForTarget(reportedElement); + var id = reportedElement?.id ?? ''; + stringToUTF8(nodeName, eventStruct + 2, 128); + stringToUTF8(id, eventStruct + 130, 128); + HEAP32[(((eventStruct)+(260))>>2)] = reportedElement?.clientWidth ?? 0; + HEAP32[(((eventStruct)+(264))>>2)] = reportedElement?.clientHeight ?? 0; + HEAP32[(((eventStruct)+(268))>>2)] = screen.width; + HEAP32[(((eventStruct)+(272))>>2)] = screen.height; + if (isFullscreen) { + JSEvents.previousFullscreenElement = fullscreenElement; + } + }; + + var registerFullscreenChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => { + var eventSize = 276; + JSEvents.fullscreenChangeEvent ||= _malloc(eventSize); + + var fullscreenChangeEventHandlerFunc = (e) => { + var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent; + fillFullscreenChangeEventData(fullscreenChangeEvent); + + if (((a1, a2, a3) => dynCall_iiii(callbackfunc, a1, a2, a3))(eventTypeId, fullscreenChangeEvent, userData)) e.preventDefault(); + }; + + var eventHandler = { + target, + eventTypeString, + eventTypeId, + userData, + callbackfunc, + handlerFunc: fullscreenChangeEventHandlerFunc, + useCapture + }; + return JSEvents.registerOrRemoveHandler(eventHandler); + }; + + var _emscripten_set_fullscreenchange_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => { + if (!JSEvents.fullscreenEnabled()) return -1; + target = findEventTarget(target); + if (!target) return -4; + + // TODO: When this block is removed, also change test/test_html5_remove_event_listener.c test expectation on emscripten_set_fullscreenchange_callback(). + registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, 'webkitfullscreenchange', targetThread); + + return registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, 'fullscreenchange', targetThread); + }; + + + + + var registerGamepadEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => { + var eventSize = 1240; + JSEvents.gamepadEvent ||= _malloc(eventSize); + + var gamepadEventHandlerFunc = (e) => { + var gamepadEvent = JSEvents.gamepadEvent; + fillGamepadEventData(gamepadEvent, e['gamepad']); + + if (((a1, a2, a3) => dynCall_iiii(callbackfunc, a1, a2, a3))(eventTypeId, gamepadEvent, userData)) e.preventDefault(); + }; + + var eventHandler = { + target: findEventTarget(target), + allowsDeferredCalls: true, + eventTypeString, + eventTypeId, + userData, + callbackfunc, + handlerFunc: gamepadEventHandlerFunc, + useCapture + }; + return JSEvents.registerOrRemoveHandler(eventHandler); + }; + + var _emscripten_set_gamepadconnected_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => { + if (_emscripten_sample_gamepad_data()) return -1; + return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, 'gamepadconnected', targetThread); + }; + + + var _emscripten_set_gamepaddisconnected_callback_on_thread = (userData, useCapture, callbackfunc, targetThread) => { + if (_emscripten_sample_gamepad_data()) return -1; + return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, 'gamepaddisconnected', targetThread); + }; + + var _emscripten_set_mousemove_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => + registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, 'mousemove', targetThread); + + + + + + var fillPointerlockChangeEventData = (eventStruct) => { + var pointerLockElement = document.pointerLockElement; + var isPointerlocked = !!pointerLockElement; + // Assigning a boolean to HEAP32 with expected type coercion. + /** @suppress{checkTypes} */ + HEAP8[eventStruct] = isPointerlocked; + var nodeName = JSEvents.getNodeNameForTarget(pointerLockElement); + var id = pointerLockElement?.id ?? ''; + stringToUTF8(nodeName, eventStruct + 1, 128); + stringToUTF8(id, eventStruct + 129, 128); + }; + + var registerPointerlockChangeEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => { + var eventSize = 257; + JSEvents.pointerlockChangeEvent ||= _malloc(eventSize); + + var pointerlockChangeEventHandlerFunc = (e) => { + var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent; + fillPointerlockChangeEventData(pointerlockChangeEvent); + + if (((a1, a2, a3) => dynCall_iiii(callbackfunc, a1, a2, a3))(eventTypeId, pointerlockChangeEvent, userData)) e.preventDefault(); + }; + + var eventHandler = { + target, + eventTypeString, + eventTypeId, + userData, + callbackfunc, + handlerFunc: pointerlockChangeEventHandlerFunc, + useCapture + }; + return JSEvents.registerOrRemoveHandler(eventHandler); + }; + + var _emscripten_set_pointerlockchange_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => { + if (!document.body?.requestPointerLock) { + return -1; + } + + target = findEventTarget(target); + if (!target) return -4; + return registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, 'pointerlockchange', targetThread); + }; + + + + + var registerUiEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => { + var eventSize = 36; + JSEvents.uiEvent ||= _malloc(eventSize); + + target = findEventTarget(target); + + var uiEventHandlerFunc = (e) => { + if (e.target != target) { + // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that + // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log + // message box could cause to scroll, generating a new (bubbled) scroll message, causing a new log print, + // causing a new scroll, etc.. + return; + } + var b = document.body; // Take document.body to a variable, Closure compiler does not outline access to it on its own. + if (!b) { + // During a page unload 'body' can be null, with "Cannot read property 'clientWidth' of null" being thrown + return; + } + var uiEvent = JSEvents.uiEvent; + HEAP32[((uiEvent)>>2)] = 0; // always zero for resize and scroll + HEAP32[(((uiEvent)+(4))>>2)] = b.clientWidth; + HEAP32[(((uiEvent)+(8))>>2)] = b.clientHeight; + HEAP32[(((uiEvent)+(12))>>2)] = innerWidth; + HEAP32[(((uiEvent)+(16))>>2)] = innerHeight; + HEAP32[(((uiEvent)+(20))>>2)] = outerWidth; + HEAP32[(((uiEvent)+(24))>>2)] = outerHeight; + HEAP32[(((uiEvent)+(28))>>2)] = pageXOffset | 0; // scroll offsets are float + HEAP32[(((uiEvent)+(32))>>2)] = pageYOffset | 0; + if (((a1, a2, a3) => dynCall_iiii(callbackfunc, a1, a2, a3))(eventTypeId, uiEvent, userData)) e.preventDefault(); + }; + + var eventHandler = { + target, + eventTypeString, + eventTypeId, + userData, + callbackfunc, + handlerFunc: uiEventHandlerFunc, + useCapture + }; + return JSEvents.registerOrRemoveHandler(eventHandler); + }; + var _emscripten_set_resize_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => + registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, 'resize', targetThread); + + + + + + + + var registerTouchEventCallback = (target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) => { + var eventSize = 1552; + JSEvents.touchEvent ||= _malloc(eventSize); + + target = findEventTarget(target); + + var touchEventHandlerFunc = (e) => { + assert(e); + var t, touches = {}, et = e.touches; + // To ease marshalling different kinds of touches that browser reports (all touches are listed in e.touches, + // only changed touches in e.changedTouches, and touches on target at a.targetTouches), mark a boolean in + // each Touch object so that we can later loop only once over all touches we see to marshall over to Wasm. + + for (let t of et) { + // Browser might recycle the generated Touch objects between each frame (Firefox on Android), so reset any + // changed/target states we may have set from previous frame. + t.isChanged = t.onTarget = 0; + touches[t.identifier] = t; + } + // Mark which touches are part of the changedTouches list. + for (let t of e.changedTouches) { + t.isChanged = 1; + touches[t.identifier] = t; + } + // Mark which touches are part of the targetTouches list. + for (let t of e.targetTouches) { + touches[t.identifier].onTarget = 1; + } + + var touchEvent = JSEvents.touchEvent; + HEAPF64[((touchEvent)>>3)] = e.timeStamp; + HEAP8[touchEvent + 12] = e.ctrlKey; + HEAP8[touchEvent + 13] = e.shiftKey; + HEAP8[touchEvent + 14] = e.altKey; + HEAP8[touchEvent + 15] = e.metaKey; + var idx = touchEvent + 16; + var targetRect = getBoundingClientRect(target); + var numTouches = 0; + for (let t of Object.values(touches)) { + var idx32 = ((idx)>>2); // Pre-shift the ptr to index to HEAP32 to save code size + HEAP32[idx32 + 0] = t.identifier; + HEAP32[idx32 + 1] = t.screenX; + HEAP32[idx32 + 2] = t.screenY; + HEAP32[idx32 + 3] = t.clientX; + HEAP32[idx32 + 4] = t.clientY; + HEAP32[idx32 + 5] = t.pageX; + HEAP32[idx32 + 6] = t.pageY; + HEAP8[idx + 28] = t.isChanged; + HEAP8[idx + 29] = t.onTarget; + HEAP32[idx32 + 8] = t.clientX - (targetRect.left | 0); + HEAP32[idx32 + 9] = t.clientY - (targetRect.top | 0); + + idx += 48; + + if (++numTouches > 31) { + break; + } + } + HEAP32[(((touchEvent)+(8))>>2)] = numTouches; + + if (((a1, a2, a3) => dynCall_iiii(callbackfunc, a1, a2, a3))(eventTypeId, touchEvent, userData)) e.preventDefault(); + }; + + var eventHandler = { + target, + allowsDeferredCalls: eventTypeString == 'touchstart' || eventTypeString == 'touchend', + eventTypeString, + eventTypeId, + userData, + callbackfunc, + handlerFunc: touchEventHandlerFunc, + useCapture + }; + return JSEvents.registerOrRemoveHandler(eventHandler); + }; + var _emscripten_set_touchcancel_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => + registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, 'touchcancel', targetThread); + + var _emscripten_set_touchend_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => + registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, 'touchend', targetThread); + + var _emscripten_set_touchmove_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => + registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, 'touchmove', targetThread); + + var _emscripten_set_touchstart_callback_on_thread = (target, userData, useCapture, callbackfunc, targetThread) => + registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, 'touchstart', targetThread); + + var handleException = (e) => { + // Certain exception types we do not treat as errors since they are used for + // internal control flow. + // 1. ExitStatus, which is thrown by exit() + // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others + // that wish to return to JS event loop. + if (e instanceof ExitStatus || e == 'unwind') { + return EXITSTATUS; + } + checkStackCookie(); + if (e instanceof WebAssembly.RuntimeError) { + if (_emscripten_stack_get_current() <= 0) { + err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)'); + } + } + quit_(1, e); + }; + + + var runtimeKeepaliveCounter = 0; + var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0; + var _proc_exit = (code) => { + EXITSTATUS = code; + if (!keepRuntimeAlive()) { + Module['onExit']?.(code); + ABORT = true; + } + quit_(code, new ExitStatus(code)); + }; + + + /** @param {boolean|number=} implicit */ + var exitJS = (status, implicit) => { + EXITSTATUS = status; + + checkUnflushedContent(); + + // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down + if (keepRuntimeAlive() && !implicit) { + var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`; + err(msg); + } + + _proc_exit(status); + }; + var _exit = exitJS; + + + var maybeExit = () => { + if (!keepRuntimeAlive()) { + try { + _exit(EXITSTATUS); + } catch (e) { + handleException(e); + } + } + }; + var callUserCallback = (func) => { + if (ABORT) { + err('user callback triggered after runtime exited or application aborted. Ignoring.'); + return; + } + try { + return func(); + } catch (e) { + handleException(e); + } finally { + maybeExit(); + } + }; + + + /** @param {number=} timeout */ + var safeSetTimeout = (func, timeout) => { + + return setTimeout(() => { + + callUserCallback(func); + }, timeout); + }; + + + + + + var Browser = { + useWebGL:false, + isFullscreen:false, + pointerLock:false, + moduleContextCreatedCallbacks:[], + preloadedImages:{ + }, + preloadedAudios:{ + }, + getCanvas:() => Module['canvas'], + init() { + if (Browser.initted) return; + Browser.initted = true; + + // Support for plugins that can process preloaded files. You can add more of these to + // your app by creating and appending to preloadPlugins. + // + // Each plugin is asked if it can handle a file based on the file's name. If it can, + // it is given the file's raw data. When it is done, it calls a callback with the file's + // (possibly modified) data. For example, a plugin might decompress a file, or it + // might create some side data structure for use later (like an Image element, etc.). + + var imagePlugin = {}; + imagePlugin['canHandle'] = (name) => { + return !Module['noImageDecoding'] && /\.(jpg|jpeg|png|bmp|webp)$/i.test(name); + }; + imagePlugin['handle'] = async (byteArray, name) => { + var b = new Blob([byteArray], { type: Browser.getMimetype(name) }); + if (b.size !== byteArray.length) { // Safari bug #118630 + // Safari's Blob can only take an ArrayBuffer + b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) }); + } + var url = URL.createObjectURL(b); + return new Promise((resolve, reject) => { + var img = new Image(); + img.onload = () => { + assert(img.complete, `Image ${name} could not be decoded`); + var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement('canvas')); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + Browser.preloadedImages[name] = canvas; + URL.revokeObjectURL(url); + resolve(byteArray); + }; + img.onerror = (event) => { + err(`Image ${url} could not be decoded`); + reject(); + }; + img.src = url; + }); + }; + preloadPlugins.push(imagePlugin); + + var audioPlugin = {}; + audioPlugin['canHandle'] = (name) => { + return !Module['noAudioDecoding'] && name.slice(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 }; + }; + audioPlugin['handle'] = async (byteArray, name) => { + return new Promise((resolve, reject) => { + var done = false; + function finish(audio) { + if (done) return; + done = true; + Browser.preloadedAudios[name] = audio; + resolve(byteArray); + } + var b = new Blob([byteArray], { type: Browser.getMimetype(name) }); + var url = URL.createObjectURL(b); // XXX we never revoke this! + var audio = new Audio(); + audio.addEventListener('canplaythrough', () => finish(audio)); // use addEventListener due to chromium bug 124926 + audio.onerror = (event) => { + if (done) return; + err(`warning: browser could not fully decode audio ${name}, trying slower base64 approach`); + function encode64(data) { + var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + var PAD = '='; + var ret = ''; + var leftchar = 0; + var leftbits = 0; + for (var byte of data) { + leftchar = (leftchar << 8) | byte; + leftbits += 8; + while (leftbits >= 6) { + var curr = (leftchar >> (leftbits-6)) & 0x3f; + leftbits -= 6; + ret += BASE[curr]; + } + } + if (leftbits == 2) { + ret += BASE[(leftchar&3) << 4]; + ret += PAD + PAD; + } else if (leftbits == 4) { + ret += BASE[(leftchar&0xf) << 2]; + ret += PAD; + } + return ret; + } + audio.src = 'data:audio/x-' + name.slice(-3) + ';base64,' + encode64(byteArray); + finish(audio); // we don't wait for confirmation this worked - but it's worth trying + }; + audio.src = url; + // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror + safeSetTimeout(() => { + finish(audio); // try to use it even though it is not necessarily ready to play + }, 10000); + }); + }; + preloadPlugins.push(audioPlugin); + + // Canvas event setup + + function pointerLockChange() { + var canvas = Browser.getCanvas(); + Browser.pointerLock = document.pointerLockElement === canvas; + } + var canvas = Browser.getCanvas(); + if (canvas) { + // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module + // Module['forcedAspectRatio'] = 4 / 3; + + document.addEventListener('pointerlockchange', pointerLockChange); + + if (Module['elementPointerLock']) { + canvas.addEventListener('click', (ev) => { + if (!Browser.pointerLock && Browser.getCanvas().requestPointerLock) { + Browser.getCanvas().requestPointerLock(); + ev.preventDefault(); + } + }); + } + } + }, + createContext(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) { + if (useWebGL && Module['ctx'] && canvas == Browser.getCanvas()) return Module['ctx']; // no need to recreate GL context if it's already been created for this canvas. + + var ctx; + var contextHandle; + if (useWebGL) { + // For GLES2/desktop GL compatibility, adjust a few defaults to be different to WebGL defaults, so that they align better with the desktop defaults. + var contextAttributes = { + antialias: false, + alpha: false, + majorVersion: 1, + }; + + if (webGLContextAttributes) { + for (var attribute in webGLContextAttributes) { + contextAttributes[attribute] = webGLContextAttributes[attribute]; + } + } + + // This check of existence of GL is here to satisfy Closure compiler, which yells if variable GL is referenced below but GL object is not + // actually compiled in because application is not doing any GL operations. TODO: Ideally if GL is not being used, this function + // Browser.createContext() should not even be emitted. + if (typeof GL != 'undefined') { + contextHandle = GL.createContext(canvas, contextAttributes); + if (contextHandle) { + ctx = GL.getContext(contextHandle).GLctx; + } + } + } else { + ctx = canvas.getContext('2d'); + } + + if (!ctx) return null; + + if (setInModule) { + if (!useWebGL) assert(typeof GLctx == 'undefined', 'cannot set in module if GLctx is used, but we are a non-GL context that would replace it'); + Module['ctx'] = ctx; + if (useWebGL) GL.makeContextCurrent(contextHandle); + Browser.useWebGL = useWebGL; + Browser.moduleContextCreatedCallbacks.forEach((callback) => callback()); + Browser.init(); + } + return ctx; + }, + fullscreenHandlersInstalled:false, + lockPointer:undefined, + resizeCanvas:undefined, + requestFullscreen(lockPointer, resizeCanvas) { + Browser.lockPointer = lockPointer; + Browser.resizeCanvas = resizeCanvas; + if (typeof Browser.lockPointer == 'undefined') Browser.lockPointer = true; + if (typeof Browser.resizeCanvas == 'undefined') Browser.resizeCanvas = false; + + var canvas = Browser.getCanvas(); + function fullscreenChange() { + Browser.isFullscreen = false; + var canvasContainer = canvas.parentNode; + if (getFullscreenElement() === canvasContainer) { + canvas.exitFullscreen = Browser.exitFullscreen; + if (Browser.lockPointer) canvas.requestPointerLock(); + Browser.isFullscreen = true; + if (Browser.resizeCanvas) { + Browser.setFullscreenCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + } + } else { + // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen + canvasContainer.parentNode.insertBefore(canvas, canvasContainer); + canvasContainer.parentNode.removeChild(canvasContainer); + + if (Browser.resizeCanvas) { + Browser.setWindowedCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + } + } + } + + if (!Browser.fullscreenHandlersInstalled) { + Browser.fullscreenHandlersInstalled = true; + document.addEventListener('fullscreenchange', fullscreenChange); + document.addEventListener('webkitfullscreenchange', fullscreenChange); + } + + // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root + var canvasContainer = document.createElement('div'); + canvas.parentNode.insertBefore(canvasContainer, canvas); + canvasContainer.appendChild(canvas); + + // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) + // Safari didn't support Element.requestFullscreen until 16.4 + // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen + /** @suppress {checkTypes} */ + canvasContainer.requestFullscreen ??= (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element.ALLOW_KEYBOARD_INPUT) : null) ?? + (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element.ALLOW_KEYBOARD_INPUT) : null); + + canvasContainer.requestFullscreen(); + }, + exitFullscreen() { + // This is workaround for chrome. Trying to exit from fullscreen + // not in fullscreen state will cause 'TypeError: Document not active' + // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236 + if (!Browser.isFullscreen) { + return false; + } + + var CFS = document.exitFullscreen ?? document['webkitCancelFullScreen']; + CFS.apply(document, []); + return true; + }, + safeSetTimeout(func, timeout) { + // Legacy function, this is used by the SDL2 port so we need to keep it + // around at least until that is updated. + // See https://github.com/libsdl-org/SDL/pull/6304 + return safeSetTimeout(func, timeout); + }, + getMimetype(name) { + return { + 'jpg': 'image/jpeg', + 'jpeg': 'image/jpeg', + 'png': 'image/png', + 'bmp': 'image/bmp', + 'ogg': 'audio/ogg', + 'wav': 'audio/wav', + 'mp3': 'audio/mpeg' + }[name.slice(name.lastIndexOf('.')+1)]; + }, + getUserMedia(func) { + return navigator.mediaDevices.getUserMedia(func); + }, + getMouseWheelDelta(event) { + var delta = 0; + switch (event.type) { + case 'DOMMouseScroll': + // 3 lines make up a step + delta = event.detail / 3; + break; + case 'mousewheel': + // 120 units make up a step + delta = event.wheelDelta / 120; + break; + case 'wheel': + delta = event.deltaY + switch (event.deltaMode) { + case 0: + // DOM_DELTA_PIXEL: 100 pixels make up a step + delta /= 100; + break; + case 1: + // DOM_DELTA_LINE: 3 lines make up a step + delta /= 3; + break; + case 2: + // DOM_DELTA_PAGE: A page makes up 80 steps + delta *= 80; + break; + default: + abort('unrecognized mouse wheel delta mode: ' + event.deltaMode); + } + break; + default: + abort('unrecognized mouse wheel event: ' + event.type); + } + return delta; + }, + mouseX:0, + mouseY:0, + mouseMovementX:0, + mouseMovementY:0, + touches:{ + }, + lastTouches:{ + }, + calculateMouseCoords(pageX, pageY) { + // Calculate the movement based on the changes + // in the coordinates. + var canvas = Browser.getCanvas(); + var rect = canvas.getBoundingClientRect(); + + var adjustedX = pageX - (window.scrollX + rect.left); + var adjustedY = pageY - (window.scrollY + rect.top); + + // the canvas might be CSS-scaled compared to its backbuffer; + // SDL-using content will want mouse coordinates in terms + // of backbuffer units. + adjustedX = adjustedX * (canvas.width / rect.width); + adjustedY = adjustedY * (canvas.height / rect.height); + + return { x: adjustedX, y: adjustedY }; + }, + setMouseCoords(pageX, pageY) { + const {x, y} = Browser.calculateMouseCoords(pageX, pageY); + Browser.mouseMovementX = x - Browser.mouseX; + Browser.mouseMovementY = y - Browser.mouseY; + Browser.mouseX = x; + Browser.mouseY = y; + }, + calculateMouseEvent(event) { // event should be mousemove, mousedown or mouseup + if (Browser.pointerLock) { + // When the pointer is locked, calculate the coordinates + // based on the movement of the mouse. + Browser.mouseMovementX = event.movementX; + Browser.mouseMovementY = event.movementY; + + // add the mouse delta to the current absolute mouse position + Browser.mouseX += Browser.mouseMovementX; + Browser.mouseY += Browser.mouseMovementY; + } else { + if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') { + var touch = event.touch; + if (touch === undefined) { + return; // the 'touch' property is only defined in SDL + + } + var coords = Browser.calculateMouseCoords(touch.pageX, touch.pageY); + + if (event.type === 'touchstart') { + Browser.lastTouches[touch.identifier] = coords; + Browser.touches[touch.identifier] = coords; + } else if (event.type === 'touchend' || event.type === 'touchmove') { + var last = Browser.touches[touch.identifier]; + last ||= coords; + Browser.lastTouches[touch.identifier] = last; + Browser.touches[touch.identifier] = coords; + } + return; + } + + Browser.setMouseCoords(event.pageX, event.pageY); + } + }, + resizeListeners:[], + updateResizeListeners() { + var canvas = Browser.getCanvas(); + Browser.resizeListeners.forEach((listener) => listener(canvas.width, canvas.height)); + }, + setCanvasSize(width, height, noUpdates) { + var canvas = Browser.getCanvas(); + Browser.updateCanvasDimensions(canvas, width, height); + if (!noUpdates) Browser.updateResizeListeners(); + }, + windowedWidth:0, + windowedHeight:0, + setFullscreenCanvasSize() { + // check if SDL is available + if (typeof SDL != 'undefined') { + var flags = HEAPU32[((SDL.screen)>>2)]; + flags = flags | 0x00800000; // set SDL_FULLSCREEN flag + HEAP32[((SDL.screen)>>2)] = flags; + } + Browser.updateCanvasDimensions(Browser.getCanvas()); + Browser.updateResizeListeners(); + }, + setWindowedCanvasSize() { + // check if SDL is available + if (typeof SDL != 'undefined') { + var flags = HEAPU32[((SDL.screen)>>2)]; + flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag + HEAP32[((SDL.screen)>>2)] = flags; + } + Browser.updateCanvasDimensions(Browser.getCanvas()); + Browser.updateResizeListeners(); + }, + updateCanvasDimensions(canvas, wNative, hNative) { + if (wNative && hNative) { + canvas.widthNative = wNative; + canvas.heightNative = hNative; + } else { + wNative = canvas.widthNative; + hNative = canvas.heightNative; + } + var w = wNative; + var h = hNative; + if ((getFullscreenElement() === canvas.parentNode) && (typeof screen != 'undefined')) { + var factor = Math.min(screen.width / w, screen.height / h); + w = Math.round(w * factor); + h = Math.round(h * factor); + } + if (Browser.resizeCanvas) { + if (canvas.width != w) canvas.width = w; + if (canvas.height != h) canvas.height = h; + if (typeof canvas.style != 'undefined') { + canvas.style.removeProperty( 'width'); + canvas.style.removeProperty('height'); + } + } else { + if (canvas.width != wNative) canvas.width = wNative; + if (canvas.height != hNative) canvas.height = hNative; + if (typeof canvas.style != 'undefined') { + if (w != wNative || h != hNative) { + canvas.style.setProperty( 'width', w + 'px', 'important'); + canvas.style.setProperty('height', h + 'px', 'important'); + } else { + canvas.style.removeProperty( 'width'); + canvas.style.removeProperty('height'); + } + } + } + }, + }; + + var _emscripten_set_window_title = (title) => document.title = UTF8ToString(title); + + var _emscripten_sleep = function(ms) { + let innerFunc = () => new Promise((resolve) => setTimeout(resolve, ms)); + return Asyncify.handleAsync(innerFunc); + } + ; + _emscripten_sleep.isAsync = true; + + + function _fd_close(fd) { + try { + + var stream = SYSCALLS.getStreamFromFD(fd); + FS.close(stream); + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return e.errno; + } + } + + + + /** @param {number=} offset */ + var doReadv = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[((iov)>>2)]; + var len = HEAPU32[(((iov)+(4))>>2)]; + iov += 8; + try { + var curr = FS.read(stream, HEAP8, ptr, len, offset); + } catch (e) { + // On a non-blocking stream a subsequent read may would-block after we + // already gathered data. POSIX readv is a single gather-read: return + // what we have rather than failing the whole call. + if (ret > 0 && e instanceof FS.ErrnoError && + (e.errno == 6 || e.errno == 6)) { + break; + } + throw e; + } + if (curr < 0) return -1; + ret += curr; + if (curr < len) break; // nothing more to read + if (typeof offset != 'undefined') { + offset += curr; + } + } + return ret; + }; + + + function _fd_read(fd, iov, iovcnt, pnum) { + try { + + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doReadv(stream, iov, iovcnt); + HEAPU32[((pnum)>>2)] = num; + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return e.errno; + } + } + + + + + function _fd_seek(fd, offset, whence, newOffset) { + offset = bigintToI53Checked(offset); + + + try { + + if (isNaN(offset)) return 22; + var stream = SYSCALLS.getStreamFromFD(fd); + FS.llseek(stream, offset, whence); + HEAP64[((newOffset)>>3)] = BigInt(stream.position); + if (stream.getdents && !offset && whence === 0) stream.getdents = null; // reset readdir state + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return e.errno; + } + ; + } + + + + /** @param {number=} offset */ + var doWritev = (stream, iov, iovcnt, offset) => { + // Gather all iovecs into one contiguous buffer and issue a single + // FS.write, matching POSIX writev's single gather-write semantics (as + // __syscall_sendmsg already does). Per-iovec writes fragment a stream + // socket send into multiple segments, breaking stream byte semantics. + if (iovcnt == 1) { + // Single iovec: write directly from HEAP8, no gather buffer needed. + return FS.write(stream, HEAP8, HEAPU32[((iov)>>2)], HEAPU32[(((iov)+(4))>>2)], offset); + } + var total = 0; + for (var i = 0, p = iov; i < iovcnt; i++, p += 8) { + total += HEAPU32[(((p)+(4))>>2)]; + } + var view = new Uint8Array(total); + var voff = 0; + for (var i = 0; i < iovcnt; i++, iov += 8) { + var ptr = HEAPU32[((iov)>>2)]; + var len = HEAPU32[(((iov)+(4))>>2)]; + view.set(HEAPU8.subarray(ptr, ptr + len), voff); + voff += len; + } + return FS.write(stream, view, 0, total, offset); + }; + + + function _fd_write(fd, iov, iovcnt, pnum) { + try { + + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doWritev(stream, iov, iovcnt); + HEAPU32[((pnum)>>2)] = num; + return 0; + } catch (e) { + if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e; + return e.errno; + } + } + + + var _glActiveTexture = _emscripten_glActiveTexture; + + var _glAttachShader = _emscripten_glAttachShader; + + var _glBindAttribLocation = _emscripten_glBindAttribLocation; + + var _glBindBuffer = _emscripten_glBindBuffer; + + var _glBindTexture = _emscripten_glBindTexture; + + var _glBlendFunc = _emscripten_glBlendFunc; + + var _glBufferData = _emscripten_glBufferData; + + var _glBufferSubData = _emscripten_glBufferSubData; + + var _glClear = _emscripten_glClear; + + var _glClearColor = _emscripten_glClearColor; + + var _glClearDepthf = _emscripten_glClearDepthf; + + var _glCompileShader = _emscripten_glCompileShader; + + var _glCompressedTexImage2D = _emscripten_glCompressedTexImage2D; + + var _glCreateProgram = _emscripten_glCreateProgram; + + var _glCreateShader = _emscripten_glCreateShader; + + var _glCullFace = _emscripten_glCullFace; + + var _glDeleteBuffers = _emscripten_glDeleteBuffers; + + var _glDeleteProgram = _emscripten_glDeleteProgram; + + var _glDeleteShader = _emscripten_glDeleteShader; + + var _glDeleteTextures = _emscripten_glDeleteTextures; + + var _glDepthFunc = _emscripten_glDepthFunc; + + var _glDetachShader = _emscripten_glDetachShader; + + var _glDisable = _emscripten_glDisable; + + var _glDisableVertexAttribArray = _emscripten_glDisableVertexAttribArray; + + var _glDrawArrays = _emscripten_glDrawArrays; + + var _glDrawElements = _emscripten_glDrawElements; + + var _glEnable = _emscripten_glEnable; + + var _glEnableVertexAttribArray = _emscripten_glEnableVertexAttribArray; + + var _glFrontFace = _emscripten_glFrontFace; + + var _glGenBuffers = _emscripten_glGenBuffers; + + var _glGenTextures = _emscripten_glGenTextures; + + var _glGetAttribLocation = _emscripten_glGetAttribLocation; + + var _glGetFloatv = _emscripten_glGetFloatv; + + var _glGetProgramInfoLog = _emscripten_glGetProgramInfoLog; + + var _glGetProgramiv = _emscripten_glGetProgramiv; + + var _glGetShaderInfoLog = _emscripten_glGetShaderInfoLog; + + var _glGetShaderiv = _emscripten_glGetShaderiv; + + var _glGetString = _emscripten_glGetString; + + var _glGetUniformLocation = _emscripten_glGetUniformLocation; + + var _glLinkProgram = _emscripten_glLinkProgram; + + var _glPixelStorei = _emscripten_glPixelStorei; + + var _glReadPixels = _emscripten_glReadPixels; + + var _glShaderSource = _emscripten_glShaderSource; + + var _glTexImage2D = _emscripten_glTexImage2D; + + var _glTexParameteri = _emscripten_glTexParameteri; + + var _glUniform1i = _emscripten_glUniform1i; + + var _glUniform4f = _emscripten_glUniform4f; + + var _glUniformMatrix4fv = _emscripten_glUniformMatrix4fv; + + var _glUseProgram = _emscripten_glUseProgram; + + var _glVertexAttribPointer = _emscripten_glVertexAttribPointer; + + var _glViewport = _emscripten_glViewport; + + + + + /** @constructor */ + function GLFW_Window(id, width, height, framebufferWidth, framebufferHeight, title, monitor, share) { + this.id = id; + this.x = 0; + this.y = 0; + this.fullscreen = false; // Used to determine if app is in fullscreen mode + this.storedX = 0; // Used to store X before fullscreen + this.storedY = 0; // Used to store Y before fullscreen + this.width = width; + this.height = height; + this.framebufferWidth = framebufferWidth; + this.framebufferHeight = framebufferHeight; + this.storedWidth = width; // Used to store width before fullscreen + this.storedHeight = height; // Used to store height before fullscreen + this.title = title; + this.monitor = monitor; + this.share = share; + this.attributes = {...GLFW.hints}; + this.inputModes = { + 0x00033001:0x00034001, // GLFW_CURSOR (GLFW_CURSOR_NORMAL) + 0x00033002:0, // GLFW_STICKY_KEYS + 0x00033003:0, // GLFW_STICKY_MOUSE_BUTTONS + }; + this.buttons = 0; + this.keys = new Array(); + this.domKeys = new Array(); + this.shouldClose = 0; + this.title = null; + this.windowPosFunc = 0; // GLFWwindowposfun + this.windowSizeFunc = 0; // GLFWwindowsizefun + this.windowCloseFunc = 0; // GLFWwindowclosefun + this.windowRefreshFunc = 0; // GLFWwindowrefreshfun + this.windowFocusFunc = 0; // GLFWwindowfocusfun + this.windowIconifyFunc = 0; // GLFWwindowiconifyfun + this.windowMaximizeFunc = 0; // GLFWwindowmaximizefun + this.framebufferSizeFunc = 0; // GLFWframebuffersizefun + this.windowContentScaleFunc = 0; // GLFWwindowcontentscalefun + this.mouseButtonFunc = 0; // GLFWmousebuttonfun + this.cursorPosFunc = 0; // GLFWcursorposfun + this.cursorEnterFunc = 0; // GLFWcursorenterfun + this.scrollFunc = 0; // GLFWscrollfun + this.dropFunc = 0; // GLFWdropfun + this.keyFunc = 0; // GLFWkeyfun + this.charFunc = 0; // GLFWcharfun + this.userptr = 0; + } + + + + + var _emscripten_set_main_loop_timing = (mode, value) => { + MainLoop.timingMode = mode; + MainLoop.timingValue = value; + + if (!MainLoop.func) { + err('emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.'); + return 1; // Return non-zero on failure, can't set timing mode when there is no main loop. + } + + if (mode == 0) { + MainLoop.scheduler = function MainLoop_scheduler_setTimeout() { + var timeUntilNextTick = Math.max(0, MainLoop.tickStartTime + value - _emscripten_get_now())|0; + setTimeout(MainLoop.runner, timeUntilNextTick); // doing this each time means that on exception, we stop + }; + } else if (mode == 1) { + MainLoop.scheduler = function MainLoop_scheduler_rAF() { + MainLoop.requestAnimationFrame(MainLoop.runner); + }; + } else { + assert(mode == 2); + if (!MainLoop.setImmediate) { + if (globalThis.scheduler) { + // Some modern browsers implement scheduler.postTask, but not all. + MainLoop.setImmediate = scheduler.postTask.bind(scheduler); + } else if (globalThis.setImmediate) { + MainLoop.setImmediate = setImmediate; + } else { + // Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed) + var setImmediates = []; + var emscriptenMainLoopMessageId = 'setimmediate'; + /** @param {Event} event */ + var MainLoop_setImmediate_messageHandler = (event) => { + if (event.data === emscriptenMainLoopMessageId) { + event.stopPropagation(); + setImmediates.shift()(); + } + }; + addEventListener('message', MainLoop_setImmediate_messageHandler, true); + MainLoop.setImmediate = /** @type{function(function(): ?, ...?): number} */((func) => { + setImmediates.push(func); + if (ENVIRONMENT_IS_WORKER) { + // The postMessge API in a Worker, sends message to the main + // thread and does not support the `targetOrigin` (*) argument. + postMessage(emscriptenMainLoopMessageId); + } else { + postMessage(emscriptenMainLoopMessageId, '*'); + } + }); + } + } + MainLoop.scheduler = function MainLoop_scheduler_setImmediate() { + MainLoop.setImmediate(MainLoop.runner); + }; + } + return 0; + }; + + + + /** + * @param {number=} arg + * @param {boolean=} noSetTiming + */ + var setMainLoop = (iterFunc, fps, simulateInfiniteLoop, arg, noSetTiming) => { + assert(!MainLoop.func, 'emscripten_set_main_loop: there can only be one main loop function at once') + MainLoop.func = iterFunc; + MainLoop.arg = arg; + + var thisMainLoopId = MainLoop.currentlyRunningMainloop; + function checkIsRunning() { + if (thisMainLoopId < MainLoop.currentlyRunningMainloop) { + maybeExit(); + return false; + } + return true; + } + + // We create the loop runner here but it is not actually running until + // _emscripten_set_main_loop_timing is called (which might happen at a + // later time). + MainLoop.runner = function MainLoop_runner() { + if (ABORT) return; + if (MainLoop.queue.length > 0) { + var start = Date.now(); + var blocker = MainLoop.queue.shift(); + blocker.func(blocker.arg); + if (MainLoop.remainingBlockers) { + var remaining = MainLoop.remainingBlockers; + var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining); + if (blocker.counted) { + MainLoop.remainingBlockers = next; + } else { + // not counted, but move the progress along a tiny bit + next = next + 0.5; // do not steal all the next one's progress + MainLoop.remainingBlockers = (8*remaining + next)/9; + } + } + MainLoop.updateStatus(); + + // catches pause/resume main loop from blocker execution + if (!checkIsRunning()) return; + + setTimeout(MainLoop.runner, 0); + return; + } + + // catch pauses from non-main loop sources + if (!checkIsRunning()) return; + + // Implement very basic swap interval control + MainLoop.currentFrameNumber = MainLoop.currentFrameNumber + 1 | 0; + if (MainLoop.timingMode == 1 && MainLoop.timingValue > 1 && MainLoop.currentFrameNumber % MainLoop.timingValue != 0) { + // Not the scheduled time to render this frame - skip. + MainLoop.scheduler(); + return; + } else if (MainLoop.timingMode == 0) { + MainLoop.tickStartTime = _emscripten_get_now(); + if (Module['ctx']) { + warnOnce('Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!'); + } + } + + MainLoop.runIter(iterFunc); + + // catch pauses from the main loop itself + if (!checkIsRunning()) return; + + MainLoop.scheduler(); + } + + if (!noSetTiming) { + if (fps > 0) { + _emscripten_set_main_loop_timing(0, 1000.0 / fps); + } else { + // Do rAF by rendering each frame (no decimating) + _emscripten_set_main_loop_timing(1, 1); + } + + MainLoop.scheduler(); + } + + if (simulateInfiniteLoop) { + throw 'unwind'; + } + }; + + + var MainLoop = { + func:null, + scheduler:null, + currentlyRunningMainloop:0, + arg:0, + timingMode:0, + timingValue:0, + currentFrameNumber:0, + queue:[], + preMainLoop:[], + postMainLoop:[], + pause() { + if (MainLoop.scheduler) { + MainLoop.scheduler = null; + // Incrementing this signals the previous main loop that it's now become old, and it must return. + MainLoop.currentlyRunningMainloop++; + + } + }, + resume() { + MainLoop.currentlyRunningMainloop++; + var timingMode = MainLoop.timingMode; + var timingValue = MainLoop.timingValue; + var func = MainLoop.func; + MainLoop.func = null; + // do not set timing and call scheduler, we will do it on the next lines + setMainLoop(func, 0, false, MainLoop.arg, true); + _emscripten_set_main_loop_timing(timingMode, timingValue); + MainLoop.scheduler(); + }, + updateStatus() { + if (Module['setStatus']) { + var message = Module['statusMessage'] || 'Please wait...'; + var remaining = MainLoop.remainingBlockers ?? 0; + var expected = MainLoop.expectedBlockers ?? 0; + if (remaining) { + if (remaining < expected) { + Module['setStatus'](`{message} ({expected - remaining}/{expected})`); + } else { + Module['setStatus'](message); + } + } else { + Module['setStatus'](''); + } + } + }, + init() { + }, + runIter(func) { + if (ABORT) return; + for (var pre of MainLoop.preMainLoop) { + if (pre() === false) { + return; // |return false| skips a frame + } + } + callUserCallback(func); + for (var post of MainLoop.postMainLoop) { + post(); + } + checkStackCookie(); + }, + nextRAF:0, + fakeRequestAnimationFrame(func) { + // try to keep 60fps between calls to here + var now = Date.now(); + if (!MainLoop.nextRAF) { + MainLoop.nextRAF = now + 1000/60; + } else { + while (now + 2 >= MainLoop.nextRAF) { // fudge a little, to avoid timer jitter causing us to do lots of delay:0 + MainLoop.nextRAF += 1000/60; + } + } + var delay = Math.max(MainLoop.nextRAF - now, 0); + setTimeout(func, delay); + }, + requestAnimationFrame(func) { + if (globalThis.requestAnimationFrame) { + requestAnimationFrame(func); + } else { + MainLoop.fakeRequestAnimationFrame(func); + } + }, + }; + + + + + + + + + + + var GLFW = { + WindowFromId:(id) => { + if (id <= 0 || !GLFW.windows) return null; + return GLFW.windows[id - 1]; + }, + joystickFunc:0, + errorFunc:0, + monitorFunc:0, + active:null, + scale:null, + windows:null, + monitors:null, + monitorString:null, + versionString:null, + initialTime:null, + extensions:null, + devicePixelRatioMQL:null, + hints:null, + primaryTouchId:null, + defaultHints:{ + 131073:0, + 131074:0, + 131075:1, + 131076:1, + 131077:1, + 131082:0, + 135169:8, + 135170:8, + 135171:8, + 135172:8, + 135173:24, + 135174:8, + 135175:0, + 135176:0, + 135177:0, + 135178:0, + 135179:0, + 135180:0, + 135181:0, + 135182:0, + 135183:0, + 139265:196609, + 139266:1, + 139267:0, + 139268:0, + 139269:0, + 139270:0, + 139271:0, + 139272:0, + 139276:0, + }, + DOMToGLFWKeyCode:(keycode) => { + switch (keycode) { + // these keycodes are only defined for GLFW3, assume they are the same for GLFW2 + case 0x20:return 32; // DOM_VK_SPACE -> GLFW_KEY_SPACE + case 0xDE:return 39; // DOM_VK_QUOTE -> GLFW_KEY_APOSTROPHE + case 0xBC:return 44; // DOM_VK_COMMA -> GLFW_KEY_COMMA + case 0xAD:return 45; // DOM_VK_HYPHEN_MINUS -> GLFW_KEY_MINUS + case 0xBD:return 45; // DOM_VK_MINUS -> GLFW_KEY_MINUS + case 0xBE:return 46; // DOM_VK_PERIOD -> GLFW_KEY_PERIOD + case 0xBF:return 47; // DOM_VK_SLASH -> GLFW_KEY_SLASH + case 0x30:return 48; // DOM_VK_0 -> GLFW_KEY_0 + case 0x31:return 49; // DOM_VK_1 -> GLFW_KEY_1 + case 0x32:return 50; // DOM_VK_2 -> GLFW_KEY_2 + case 0x33:return 51; // DOM_VK_3 -> GLFW_KEY_3 + case 0x34:return 52; // DOM_VK_4 -> GLFW_KEY_4 + case 0x35:return 53; // DOM_VK_5 -> GLFW_KEY_5 + case 0x36:return 54; // DOM_VK_6 -> GLFW_KEY_6 + case 0x37:return 55; // DOM_VK_7 -> GLFW_KEY_7 + case 0x38:return 56; // DOM_VK_8 -> GLFW_KEY_8 + case 0x39:return 57; // DOM_VK_9 -> GLFW_KEY_9 + case 0x3B:return 59; // DOM_VK_SEMICOLON -> GLFW_KEY_SEMICOLON + case 0x3D:return 61; // DOM_VK_EQUALS -> GLFW_KEY_EQUAL + case 0xBB:return 61; // DOM_VK_EQUALS -> GLFW_KEY_EQUAL + case 0x41:return 65; // DOM_VK_A -> GLFW_KEY_A + case 0x42:return 66; // DOM_VK_B -> GLFW_KEY_B + case 0x43:return 67; // DOM_VK_C -> GLFW_KEY_C + case 0x44:return 68; // DOM_VK_D -> GLFW_KEY_D + case 0x45:return 69; // DOM_VK_E -> GLFW_KEY_E + case 0x46:return 70; // DOM_VK_F -> GLFW_KEY_F + case 0x47:return 71; // DOM_VK_G -> GLFW_KEY_G + case 0x48:return 72; // DOM_VK_H -> GLFW_KEY_H + case 0x49:return 73; // DOM_VK_I -> GLFW_KEY_I + case 0x4A:return 74; // DOM_VK_J -> GLFW_KEY_J + case 0x4B:return 75; // DOM_VK_K -> GLFW_KEY_K + case 0x4C:return 76; // DOM_VK_L -> GLFW_KEY_L + case 0x4D:return 77; // DOM_VK_M -> GLFW_KEY_M + case 0x4E:return 78; // DOM_VK_N -> GLFW_KEY_N + case 0x4F:return 79; // DOM_VK_O -> GLFW_KEY_O + case 0x50:return 80; // DOM_VK_P -> GLFW_KEY_P + case 0x51:return 81; // DOM_VK_Q -> GLFW_KEY_Q + case 0x52:return 82; // DOM_VK_R -> GLFW_KEY_R + case 0x53:return 83; // DOM_VK_S -> GLFW_KEY_S + case 0x54:return 84; // DOM_VK_T -> GLFW_KEY_T + case 0x55:return 85; // DOM_VK_U -> GLFW_KEY_U + case 0x56:return 86; // DOM_VK_V -> GLFW_KEY_V + case 0x57:return 87; // DOM_VK_W -> GLFW_KEY_W + case 0x58:return 88; // DOM_VK_X -> GLFW_KEY_X + case 0x59:return 89; // DOM_VK_Y -> GLFW_KEY_Y + case 0x5a:return 90; // DOM_VK_Z -> GLFW_KEY_Z + case 0xDB:return 91; // DOM_VK_OPEN_BRACKET -> GLFW_KEY_LEFT_BRACKET + case 0xDC:return 92; // DOM_VK_BACKSLASH -> GLFW_KEY_BACKSLASH + case 0xDD:return 93; // DOM_VK_CLOSE_BRACKET -> GLFW_KEY_RIGHT_BRACKET + case 0xC0:return 96; // DOM_VK_BACK_QUOTE -> GLFW_KEY_GRAVE_ACCENT + + case 0x1B:return 256; // DOM_VK_ESCAPE -> GLFW_KEY_ESCAPE + case 0x0D:return 257; // DOM_VK_RETURN -> GLFW_KEY_ENTER + case 0x09:return 258; // DOM_VK_TAB -> GLFW_KEY_TAB + case 0x08:return 259; // DOM_VK_BACK -> GLFW_KEY_BACKSPACE + case 0x2D:return 260; // DOM_VK_INSERT -> GLFW_KEY_INSERT + case 0x2E:return 261; // DOM_VK_DELETE -> GLFW_KEY_DELETE + case 0x27:return 262; // DOM_VK_RIGHT -> GLFW_KEY_RIGHT + case 0x25:return 263; // DOM_VK_LEFT -> GLFW_KEY_LEFT + case 0x28:return 264; // DOM_VK_DOWN -> GLFW_KEY_DOWN + case 0x26:return 265; // DOM_VK_UP -> GLFW_KEY_UP + case 0x21:return 266; // DOM_VK_PAGE_UP -> GLFW_KEY_PAGE_UP + case 0x22:return 267; // DOM_VK_PAGE_DOWN -> GLFW_KEY_PAGE_DOWN + case 0x24:return 268; // DOM_VK_HOME -> GLFW_KEY_HOME + case 0x23:return 269; // DOM_VK_END -> GLFW_KEY_END + case 0x14:return 280; // DOM_VK_CAPS_LOCK -> GLFW_KEY_CAPS_LOCK + case 0x91:return 281; // DOM_VK_SCROLL_LOCK -> GLFW_KEY_SCROLL_LOCK + case 0x90:return 282; // DOM_VK_NUM_LOCK -> GLFW_KEY_NUM_LOCK + case 0x2C:return 283; // DOM_VK_SNAPSHOT -> GLFW_KEY_PRINT_SCREEN + case 0x13:return 284; // DOM_VK_PAUSE -> GLFW_KEY_PAUSE + case 0x70:return 290; // DOM_VK_F1 -> GLFW_KEY_F1 + case 0x71:return 291; // DOM_VK_F2 -> GLFW_KEY_F2 + case 0x72:return 292; // DOM_VK_F3 -> GLFW_KEY_F3 + case 0x73:return 293; // DOM_VK_F4 -> GLFW_KEY_F4 + case 0x74:return 294; // DOM_VK_F5 -> GLFW_KEY_F5 + case 0x75:return 295; // DOM_VK_F6 -> GLFW_KEY_F6 + case 0x76:return 296; // DOM_VK_F7 -> GLFW_KEY_F7 + case 0x77:return 297; // DOM_VK_F8 -> GLFW_KEY_F8 + case 0x78:return 298; // DOM_VK_F9 -> GLFW_KEY_F9 + case 0x79:return 299; // DOM_VK_F10 -> GLFW_KEY_F10 + case 0x7A:return 300; // DOM_VK_F11 -> GLFW_KEY_F11 + case 0x7B:return 301; // DOM_VK_F12 -> GLFW_KEY_F12 + case 0x7C:return 302; // DOM_VK_F13 -> GLFW_KEY_F13 + case 0x7D:return 303; // DOM_VK_F14 -> GLFW_KEY_F14 + case 0x7E:return 304; // DOM_VK_F15 -> GLFW_KEY_F15 + case 0x7F:return 305; // DOM_VK_F16 -> GLFW_KEY_F16 + case 0x80:return 306; // DOM_VK_F17 -> GLFW_KEY_F17 + case 0x81:return 307; // DOM_VK_F18 -> GLFW_KEY_F18 + case 0x82:return 308; // DOM_VK_F19 -> GLFW_KEY_F19 + case 0x83:return 309; // DOM_VK_F20 -> GLFW_KEY_F20 + case 0x84:return 310; // DOM_VK_F21 -> GLFW_KEY_F21 + case 0x85:return 311; // DOM_VK_F22 -> GLFW_KEY_F22 + case 0x86:return 312; // DOM_VK_F23 -> GLFW_KEY_F23 + case 0x87:return 313; // DOM_VK_F24 -> GLFW_KEY_F24 + case 0x88:return 314; // 0x88 (not used?) -> GLFW_KEY_F25 + case 0x60:return 320; // DOM_VK_NUMPAD0 -> GLFW_KEY_KP_0 + case 0x61:return 321; // DOM_VK_NUMPAD1 -> GLFW_KEY_KP_1 + case 0x62:return 322; // DOM_VK_NUMPAD2 -> GLFW_KEY_KP_2 + case 0x63:return 323; // DOM_VK_NUMPAD3 -> GLFW_KEY_KP_3 + case 0x64:return 324; // DOM_VK_NUMPAD4 -> GLFW_KEY_KP_4 + case 0x65:return 325; // DOM_VK_NUMPAD5 -> GLFW_KEY_KP_5 + case 0x66:return 326; // DOM_VK_NUMPAD6 -> GLFW_KEY_KP_6 + case 0x67:return 327; // DOM_VK_NUMPAD7 -> GLFW_KEY_KP_7 + case 0x68:return 328; // DOM_VK_NUMPAD8 -> GLFW_KEY_KP_8 + case 0x69:return 329; // DOM_VK_NUMPAD9 -> GLFW_KEY_KP_9 + case 0x6E:return 330; // DOM_VK_DECIMAL -> GLFW_KEY_KP_DECIMAL + case 0x6F:return 331; // DOM_VK_DIVIDE -> GLFW_KEY_KP_DIVIDE + case 0x6A:return 332; // DOM_VK_MULTIPLY -> GLFW_KEY_KP_MULTIPLY + case 0x6D:return 333; // DOM_VK_SUBTRACT -> GLFW_KEY_KP_SUBTRACT + case 0x6B:return 334; // DOM_VK_ADD -> GLFW_KEY_KP_ADD + // case 0x0D:return 335; // DOM_VK_RETURN -> GLFW_KEY_KP_ENTER (DOM_KEY_LOCATION_RIGHT) + // case 0x61:return 336; // DOM_VK_EQUALS -> GLFW_KEY_KP_EQUAL (DOM_KEY_LOCATION_RIGHT) + case 0x10:return 340; // DOM_VK_SHIFT -> GLFW_KEY_LEFT_SHIFT + case 0x11:return 341; // DOM_VK_CONTROL -> GLFW_KEY_LEFT_CONTROL + case 0x12:return 342; // DOM_VK_ALT -> GLFW_KEY_LEFT_ALT + case 0x5B:return 343; // DOM_VK_WIN -> GLFW_KEY_LEFT_SUPER + case 0xE0:return 343; // DOM_VK_META -> GLFW_KEY_LEFT_SUPER + // case 0x10:return 344; // DOM_VK_SHIFT -> GLFW_KEY_RIGHT_SHIFT (DOM_KEY_LOCATION_RIGHT) + // case 0x11:return 345; // DOM_VK_CONTROL -> GLFW_KEY_RIGHT_CONTROL (DOM_KEY_LOCATION_RIGHT) + // case 0x12:return 346; // DOM_VK_ALT -> GLFW_KEY_RIGHT_ALT (DOM_KEY_LOCATION_RIGHT) + // case 0x5B:return 347; // DOM_VK_WIN -> GLFW_KEY_RIGHT_SUPER (DOM_KEY_LOCATION_RIGHT) + case 0x5D:return 348; // DOM_VK_CONTEXT_MENU -> GLFW_KEY_MENU + // XXX: GLFW_KEY_WORLD_1, GLFW_KEY_WORLD_2 what are these? + default:return -1; // GLFW_KEY_UNKNOWN + }; + }, + getModBits:(win) => { + var mod = 0; + if (win.keys[340]) mod |= 0x0001; // GLFW_MOD_SHIFT + if (win.keys[341]) mod |= 0x0002; // GLFW_MOD_CONTROL + if (win.keys[342]) mod |= 0x0004; // GLFW_MOD_ALT + if (win.keys[343] || win.keys[348]) mod |= 0x0008; // GLFW_MOD_SUPER + // add caps and num lock keys? only if lock_key_mod is set + return mod; + }, + onKeyPress:(event) => { + if (!GLFW.active || !GLFW.active.charFunc) return; + if (event.ctrlKey || event.metaKey) return; + + // correct unicode charCode is only available with onKeyPress event + var charCode = event.charCode; + if (charCode == 0 || (charCode >= 0x00 && charCode <= 0x1F)) return; + + ((a1, a2) => dynCall_vii(GLFW.active.charFunc, a1, a2))(GLFW.active.id, charCode); + }, + onKeyChanged:(keyCode, status) => { + if (!GLFW.active) return; + + var key = GLFW.DOMToGLFWKeyCode(keyCode); + if (key == -1) return; + + var repeat = status && GLFW.active.keys[key]; + GLFW.active.keys[key] = status; + GLFW.active.domKeys[keyCode] = status; + + if (GLFW.active.keyFunc) { + if (repeat) status = 2; // GLFW_REPEAT + ((a1, a2, a3, a4, a5) => dynCall_viiiii(GLFW.active.keyFunc, a1, a2, a3, a4, a5))(GLFW.active.id, key, keyCode, status, GLFW.getModBits(GLFW.active)); + } + }, + onGamepadConnected:(event) => { + GLFW.refreshJoysticks(); + }, + onGamepadDisconnected:(event) => { + GLFW.refreshJoysticks(); + }, + onKeydown:(event) => { + GLFW.onKeyChanged(event.keyCode, 1); // GLFW_PRESS or GLFW_REPEAT + + // This logic comes directly from the sdl implementation. We cannot + // call preventDefault on all keydown events otherwise onKeyPress will + // not get called + if (event.key == 'Backspace' || event.key == 'Tab') { + event.preventDefault(); + } + }, + onKeyup:(event) => { + GLFW.onKeyChanged(event.keyCode, 0); // GLFW_RELEASE + }, + onBlur:(event) => { + if (!GLFW.active) return; + + for (var i = 0; i < GLFW.active.domKeys.length; ++i) { + if (GLFW.active.domKeys[i]) { + GLFW.onKeyChanged(i, 0); // GLFW_RELEASE + } + } + }, + onMousemove:(event) => { + if (!GLFW.active) return; + + if (event.type === 'touchmove') { + // Handling for touch events that are being converted to mouse input. + + // Don't let the browser fire a duplicate mouse event. + event.preventDefault(); + + let primaryChanged = false; + for (let i of event.changedTouches) { + // If our chosen primary touch moved, update Browser mouse coords + if (GLFW.primaryTouchId === i.identifier) { + Browser.setMouseCoords(i.pageX, i.pageY); + primaryChanged = true; + break; + } + } + + if (!primaryChanged) { + // Do not send mouse events if some touch other than the primary triggered this. + return; + } + + } else { + // Handling for non-touch mouse input events. + Browser.calculateMouseEvent(event); + } + + if (event.target != Browser.getCanvas() || !GLFW.active.cursorPosFunc) return; + + if (GLFW.active.cursorPosFunc) { + ((a1, a2, a3) => dynCall_vidd(GLFW.active.cursorPosFunc, a1, a2, a3))(GLFW.active.id, Browser.mouseX, Browser.mouseY); + } + }, + DOMToGLFWMouseButton:(event) => { + // DOM and glfw have different button codes. + // See http://www.w3schools.com/jsref/event_button.asp. + var eventButton = event['button']; + if (eventButton > 0) { + if (eventButton == 1) { + eventButton = 2; + } else { + eventButton = 1; + } + } + return eventButton; + }, + onMouseenter:(event) => { + if (!GLFW.active) return; + + if (event.target != Browser.getCanvas()) return; + + if (GLFW.active.cursorEnterFunc) { + ((a1, a2) => dynCall_vii(GLFW.active.cursorEnterFunc, a1, a2))(GLFW.active.id, 1); + } + }, + onMouseleave:(event) => { + if (!GLFW.active) return; + + if (event.target != Browser.getCanvas()) return; + + if (GLFW.active.cursorEnterFunc) { + ((a1, a2) => dynCall_vii(GLFW.active.cursorEnterFunc, a1, a2))(GLFW.active.id, 0); + } + }, + onMouseButtonChanged:(event, status) => { + if (!GLFW.active) return; + + if (event.target != Browser.getCanvas()) return; + + // Is this from a touch event? + const isTouchType = event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchcancel'; + + // Only emulating mouse left-click behavior for touches. + let eventButton = 0; + if (isTouchType) { + // Handling for touch events that are being converted to mouse input. + + // Don't let the browser fire a duplicate mouse event. + event.preventDefault(); + + let primaryChanged = false; + + // Set a primary touch if we have none. + if (GLFW.primaryTouchId === null && event.type === 'touchstart' && event.targetTouches.length > 0) { + // Pick the first touch that started in the canvas and treat it as primary. + const chosenTouch = event.targetTouches[0]; + GLFW.primaryTouchId = chosenTouch.identifier; + + Browser.setMouseCoords(chosenTouch.pageX, chosenTouch.pageY); + primaryChanged = true; + } else if (event.type === 'touchend' || event.type === 'touchcancel') { + // Clear the primary touch if it ended. + for (let i of event.changedTouches) { + // If our chosen primary touch ended, remove it. + if (GLFW.primaryTouchId === i.identifier) { + GLFW.primaryTouchId = null; + primaryChanged = true; + break; + } + } + } + + if (!primaryChanged) { + // Do not send mouse events if some touch other than the primary triggered this. + return; + } + + } else { + // Handling for non-touch mouse input events. + Browser.calculateMouseEvent(event); + eventButton = GLFW.DOMToGLFWMouseButton(event); + } + + if (status == 1) { // GLFW_PRESS + GLFW.active.buttons |= (1 << eventButton); + try { + event.target.setCapture(); + } catch (e) {} + } else { // GLFW_RELEASE + GLFW.active.buttons &= ~(1 << eventButton); + } + + // Send mouse event to GLFW. + if (GLFW.active.mouseButtonFunc) { + ((a1, a2, a3, a4) => dynCall_viiii(GLFW.active.mouseButtonFunc, a1, a2, a3, a4))(GLFW.active.id, eventButton, status, GLFW.getModBits(GLFW.active)); + } + }, + onMouseButtonDown:(event) => { + if (!GLFW.active) return; + GLFW.onMouseButtonChanged(event, 1); // GLFW_PRESS + }, + onMouseButtonUp:(event) => { + if (!GLFW.active) return; + GLFW.onMouseButtonChanged(event, 0); // GLFW_RELEASE + }, + onMouseWheel:(event) => { + // Note the minus sign that flips browser wheel direction (positive direction scrolls page down) to native wheel direction (positive direction is mouse wheel up) + var delta = -Browser.getMouseWheelDelta(event); + delta = (delta == 0) ? 0 : (delta > 0 ? Math.max(delta, 1) : Math.min(delta, -1)); // Quantize to integer so that minimum scroll is at least +/- 1. + GLFW.wheelPos += delta; + + if (!GLFW.active || !GLFW.active.scrollFunc || event.target != Browser.getCanvas()) return; + var sx = 0; + var sy = delta; + if (event.type == 'mousewheel') { + sx = event.wheelDeltaX; + } else { + sx = event.deltaX; + } + + ((a1, a2, a3) => dynCall_vidd(GLFW.active.scrollFunc, a1, a2, a3))(GLFW.active.id, sx, sy); + + event.preventDefault(); + }, + onCanvasResize:(width, height, framebufferWidth, framebufferHeight) => { + if (!GLFW.active) return; + + var resizeNeeded = false; + + // If the client is requesting fullscreen mode + if (getFullscreenElement()) { + if (!GLFW.active.fullscreen) { + resizeNeeded = width != screen.width || height != screen.height; + GLFW.active.storedX = GLFW.active.x; + GLFW.active.storedY = GLFW.active.y; + GLFW.active.storedWidth = GLFW.active.width; + GLFW.active.storedHeight = GLFW.active.height; + GLFW.active.x = GLFW.active.y = 0; + GLFW.active.width = screen.width; + GLFW.active.height = screen.height; + GLFW.active.fullscreen = true; + } + // If the client is reverting from fullscreen mode + } else if (GLFW.active.fullscreen == true) { + resizeNeeded = width != GLFW.active.storedWidth || height != GLFW.active.storedHeight; + GLFW.active.x = GLFW.active.storedX; + GLFW.active.y = GLFW.active.storedY; + GLFW.active.width = GLFW.active.storedWidth; + GLFW.active.height = GLFW.active.storedHeight; + GLFW.active.fullscreen = false; + } + + if (resizeNeeded) { + // width or height is changed (fullscreen / exit fullscreen) which will call this listener back + // with proper framebufferWidth/framebufferHeight + Browser.setCanvasSize(GLFW.active.width, GLFW.active.height); + } else if (GLFW.active.width != width || + GLFW.active.height != height || + GLFW.active.framebufferWidth != framebufferWidth || + GLFW.active.framebufferHeight != framebufferHeight) { + GLFW.active.width = width; + GLFW.active.height = height; + GLFW.active.framebufferWidth = framebufferWidth; + GLFW.active.framebufferHeight = framebufferHeight; + GLFW.onWindowSizeChanged(); + GLFW.onFramebufferSizeChanged(); + } + }, + onWindowSizeChanged:() => { + if (!GLFW.active) return; + + if (GLFW.active.windowSizeFunc) { + ((a1, a2, a3) => dynCall_viii(GLFW.active.windowSizeFunc, a1, a2, a3))(GLFW.active.id, GLFW.active.width, GLFW.active.height); + } + }, + onFramebufferSizeChanged:() => { + if (!GLFW.active) return; + + if (GLFW.active.framebufferSizeFunc) { + ((a1, a2, a3) => dynCall_viii(GLFW.active.framebufferSizeFunc, a1, a2, a3))(GLFW.active.id, GLFW.active.framebufferWidth, GLFW.active.framebufferHeight); + } + }, + onWindowContentScaleChanged:(scale) => { + GLFW.scale = scale; + if (!GLFW.active) return; + + if (GLFW.active.windowContentScaleFunc) { + ((a1, a2, a3) => dynCall_viff(GLFW.active.windowContentScaleFunc, a1, a2, a3))(GLFW.active.id, GLFW.scale, GLFW.scale); + } + }, + getTime:() => _emscripten_get_now() / 1000, + setWindowTitle:(winid, title) => { + var win = GLFW.WindowFromId(winid); + if (!win) return; + + win.title = title; + if (GLFW.active.id == win.id) { + _emscripten_set_window_title(title); + } + }, + setJoystickCallback:(cbfun) => { + var prevcbfun = GLFW.joystickFunc; + GLFW.joystickFunc = cbfun; + GLFW.refreshJoysticks(); + return prevcbfun; + }, + joys:{ + }, + lastGamepadState:[], + lastGamepadStateFrame:null, + refreshJoysticks:() => { + // Produce a new Gamepad API sample if we are ticking a new game frame, or if not using emscripten_set_main_loop() at all to drive animation. + if (MainLoop.currentFrameNumber !== GLFW.lastGamepadStateFrame || !MainLoop.currentFrameNumber) { + GLFW.lastGamepadState = navigator.getGamepads?.() ?? []; + GLFW.lastGamepadStateFrame = MainLoop.currentFrameNumber; + + for (var joy = 0; joy < GLFW.lastGamepadState.length; ++joy) { + var gamepad = GLFW.lastGamepadState[joy]; + + if (gamepad) { + if (!GLFW.joys[joy]) { + out('glfw joystick connected:',joy); + GLFW.joys[joy] = { + id: stringToNewUTF8(gamepad.id), + buttonsCount: gamepad.buttons.length, + axesCount: gamepad.axes.length, + buttons: _malloc(gamepad.buttons.length), + axes: _malloc(gamepad.axes.length*4), + }; + + if (GLFW.joystickFunc) { + ((a1, a2) => dynCall_vii(GLFW.joystickFunc, a1, a2))(joy, 0x00040001); // GLFW_CONNECTED + } + } + + var data = GLFW.joys[joy]; + + for (var i = 0; i < gamepad.buttons.length; ++i) { + HEAP8[data.buttons + i] = gamepad.buttons[i].pressed; + } + + for (var i = 0; i < gamepad.axes.length; ++i) { + HEAPF32[((data.axes + i*4)>>2)] = gamepad.axes[i]; + } + } else { + if (GLFW.joys[joy]) { + out('glfw joystick disconnected',joy); + + if (GLFW.joystickFunc) { + ((a1, a2) => dynCall_vii(GLFW.joystickFunc, a1, a2))(joy, 0x00040002); // GLFW_DISCONNECTED + } + + _free(GLFW.joys[joy].id); + _free(GLFW.joys[joy].buttons); + _free(GLFW.joys[joy].axes); + + delete GLFW.joys[joy]; + } + } + } + } + }, + setKeyCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.keyFunc; + win.keyFunc = cbfun; + return prevcbfun; + }, + setCharCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.charFunc; + win.charFunc = cbfun; + return prevcbfun; + }, + setMouseButtonCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.mouseButtonFunc; + win.mouseButtonFunc = cbfun; + return prevcbfun; + }, + setCursorPosCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.cursorPosFunc; + win.cursorPosFunc = cbfun; + return prevcbfun; + }, + setScrollCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.scrollFunc; + win.scrollFunc = cbfun; + return prevcbfun; + }, + setDropCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.dropFunc; + win.dropFunc = cbfun; + return prevcbfun; + }, + onDrop:(event) => { + if (!GLFW.active || !GLFW.active.dropFunc) return; + if (!event.dataTransfer || !event.dataTransfer.files || event.dataTransfer.files.length == 0) return; + + event.preventDefault(); + + var drop_dir = '.glfw_dropped_files'; + var filenames = _malloc(event.dataTransfer.files.length * 4); + var filenamesArray = []; + for (var i = 0; i < event.dataTransfer.files.length; ++i) { + var path = `/${drop_dir}/${event.dataTransfer.files[i].name.replace(/\//g, '_')}`; + var filename = stringToNewUTF8(path); + filenamesArray.push(filename); + HEAPU32[(((filenames)+(i*4))>>2)] = filename; + } + + // Read and save the files to emscripten's FS + var written = 0; + FS.createPath('/', drop_dir); + + function save(file, in_path, numfiles) { + var path = '/' + drop_dir + in_path + '/' + file.name.replace(/\//g, '_'); + var reader = new FileReader(); + reader.onloadend = (e) => { + if (reader.readyState != 2) { // not DONE + ++written; + err(`failed to read dropped file: ${in_path}/${file.name}: ${reader.error}`); + return; + } + + var data = e.target.result; + FS.writeFile(path, new Uint8Array(data)); + if (++written === numfiles) { + ((a1, a2, a3) => dynCall_viii(GLFW.active.dropFunc, a1, a2, a3))(GLFW.active.id, filenamesArray.length, filenames); + + for (var i = 0; i < filenamesArray.length; ++i) { + _free(filenamesArray[i]); + } + _free(filenames); + } + }; + reader.readAsArrayBuffer(file); + } + + let filesQ = []; + function finalize() { + var count = filesQ.length; + for (var i = 0; i < count; ++i) { + save(filesQ[i].file, filesQ[i].path, count); + } + } + + if (DataTransferItem.prototype.webkitGetAsEntry) { + let entriesTree = {}; + function markDone(fullpath, recursive) { + if (entriesTree[fullpath].subpaths.length != 0) return; + delete entriesTree[fullpath]; + let parentpath = fullpath.substring(0, fullpath.lastIndexOf('/')); + if (!entriesTree.hasOwnProperty(parentpath)) { + if (Object.keys(entriesTree).length == 0) finalize(); + return; + } + const fpIndex = entriesTree[parentpath].subpaths.indexOf(fullpath); + if (fpIndex > -1) entriesTree[parentpath].subpaths.splice(fpIndex, 1); + if (recursive) markDone(parentpath, true); + if (Object.keys(entriesTree).length == 0) finalize(); + } + function processEntry(entry) { + let fp = entry.fullPath; + let pp = fp.substring(0, fp.lastIndexOf('/')); + entriesTree[fp] = { subpaths: [] }; + if (entry.isFile) { + entry.file((f) => { filesQ.push({ file: f, path: pp }); markDone(fp, false); }) + } else if (entry.isDirectory) { + if (entriesTree.hasOwnProperty(pp)) entriesTree[pp].subpaths.push(fp); + FS.createPath('/' + drop_dir + pp, entry.name); + var reader = entry.createReader(); + var rRead = function (dirEntries) { + if (dirEntries.length == 0) { + markDone(fp, true); + return; + } + for (const ent of dirEntries) processEntry(ent); + reader.readEntries(rRead); + }; + reader.readEntries(rRead); + } + } + for (const item of event.dataTransfer.items) { + processEntry(item.webkitGetAsEntry()); + } + } else { + // fallback for browsers that does not support webkitGetAsEntry + for (const file of event.dataTransfer.files) { + filesQ.push({ file: file, path: '' }); + } + finalize(); + } + + return false; + }, + onDragover:(event) => { + if (!GLFW.active || !GLFW.active.dropFunc) return; + + event.preventDefault(); + return false; + }, + setWindowSizeCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.windowSizeFunc; + win.windowSizeFunc = cbfun; + + return prevcbfun; + }, + setWindowCloseCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.windowCloseFunc; + win.windowCloseFunc = cbfun; + return prevcbfun; + }, + setWindowRefreshCallback:(winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.windowRefreshFunc; + win.windowRefreshFunc = cbfun; + return prevcbfun; + }, + onClickRequestPointerLock:(e) => { + var canvas = Browser.getCanvas(); + if (!Browser.pointerLock && canvas.requestPointerLock) { + canvas.requestPointerLock(); + e.preventDefault(); + } + }, + setInputMode:(winid, mode, value) => { + var win = GLFW.WindowFromId(winid); + if (!win) return; + + switch (mode) { + case 0x00033001: { // GLFW_CURSOR + var canvas = Browser.getCanvas(); + switch (value) { + case 0x00034001: { // GLFW_CURSOR_NORMAL + win.inputModes[mode] = value; + canvas.removeEventListener('click', GLFW.onClickRequestPointerLock, true); + document.exitPointerLock(); + break; + } + case 0x00034002: { // GLFW_CURSOR_HIDDEN + err('glfwSetInputMode called with GLFW_CURSOR_HIDDEN value not implemented'); + break; + } + case 0x00034003: { // GLFW_CURSOR_DISABLED + win.inputModes[mode] = value; + canvas.addEventListener('click', GLFW.onClickRequestPointerLock, true); + canvas.requestPointerLock(); + break; + } + default: { + err(`glfwSetInputMode called with unknown value parameter value: ${value}`); + break; + } + } + break; + } + case 0x00033002: { // GLFW_STICKY_KEYS + err('glfwSetInputMode called with GLFW_STICKY_KEYS mode not implemented'); + break; + } + case 0x00033003: { // GLFW_STICKY_MOUSE_BUTTONS + err('glfwSetInputMode called with GLFW_STICKY_MOUSE_BUTTONS mode not implemented'); + break; + } + case 0x00033004: { // GLFW_LOCK_KEY_MODS + err('glfwSetInputMode called with GLFW_LOCK_KEY_MODS mode not implemented'); + break; + } + case 0x00033005: { // GLFW_RAW_MOUSE_MOTION + err('glfwSetInputMode called with GLFW_RAW_MOUSE_MOTION mode not implemented'); + break; + } + default: { + err(`glfwSetInputMode called with unknown mode parameter value: ${mode}`); + break; + } + } + }, + getKey:(winid, key) => { + var win = GLFW.WindowFromId(winid); + if (!win) return 0; + return win.keys[key]; + }, + getMouseButton:(winid, button) => { + var win = GLFW.WindowFromId(winid); + if (!win) return 0; + return (win.buttons & (1 << button)) > 0; + }, + getCursorPos:(winid, x, y) => { + HEAPF64[((x)>>3)] = Browser.mouseX; + HEAPF64[((y)>>3)] = Browser.mouseY; + }, + getMousePos:(winid, x, y) => { + HEAP32[((x)>>2)] = Browser.mouseX; + HEAP32[((y)>>2)] = Browser.mouseY; + }, + setCursorPos:(winid, x, y) => { + }, + getWindowPos:(winid, x, y) => { + var wx = 0; + var wy = 0; + + var win = GLFW.WindowFromId(winid); + if (win) { + wx = win.x; + wy = win.y; + } + + if (x) { + HEAP32[((x)>>2)] = wx; + } + + if (y) { + HEAP32[((y)>>2)] = wy; + } + }, + setWindowPos:(winid, x, y) => { + var win = GLFW.WindowFromId(winid); + if (!win) return; + win.x = x; + win.y = y; + }, + getWindowSize:(winid, width, height) => { + var ww = 0; + var wh = 0; + + var win = GLFW.WindowFromId(winid); + if (win) { + ww = win.width; + wh = win.height; + } + + if (width) { + HEAP32[((width)>>2)] = ww; + } + + if (height) { + HEAP32[((height)>>2)] = wh; + } + }, + setWindowSize:(winid, width, height) => { + var win = GLFW.WindowFromId(winid); + if (!win) return; + + if (GLFW.active.id == win.id) { + Browser.setCanvasSize(width, height); // triggers the listener (onCanvasResize) + windowSizeFunc + } + }, + defaultWindowHints:() => { + GLFW.hints = {...GLFW.defaultHints}; + }, + createWindow:(width, height, title, monitor, share) => { + var i, id; + for (i = 0; i < GLFW.windows.length && GLFW.windows[i] !== null; i++) { + // no-op + } + if (i > 0) abort('glfwCreateWindow only supports one window at time currently'); + + // id for window + id = i + 1; + + // not valid + if (width <= 0 || height <= 0) return 0; + + if (monitor) { + Browser.requestFullscreen(); + } else { + Browser.setCanvasSize(width, height); + } + + // Create context when there are no existing alive windows + for (i = 0; i < GLFW.windows.length && GLFW.windows[i] == null; i++) { + // no-op + } + + const canvas = Browser.getCanvas(); + + var useWebGL = GLFW.hints[0x00022001] > 0; // Use WebGL when we are told to based on GLFW_CLIENT_API + if (i == GLFW.windows.length) { + if (useWebGL) { + var contextAttributes = { + antialias: (GLFW.hints[0x0002100D] > 1), // GLFW_SAMPLES + depth: (GLFW.hints[0x00021005] > 0), // GLFW_DEPTH_BITS + stencil: (GLFW.hints[0x00021006] > 0), // GLFW_STENCIL_BITS + alpha: (GLFW.hints[0x00021004] > 0) // GLFW_ALPHA_BITS + } + Browser.createContext(canvas, /*useWebGL=*/true, /*setInModule=*/true, contextAttributes); + } else { + Browser.init(); + } + } + + // If context creation failed, do not return a valid window + if (!Module['ctx'] && useWebGL) return 0; + + // Initializes the framebuffer size from the canvas + var win = new GLFW_Window(id, width, height, canvas.width, canvas.height, title, monitor, share); + + // Set window to array + if (id - 1 == GLFW.windows.length) { + GLFW.windows.push(win); + } else { + GLFW.windows[id - 1] = win; + } + + GLFW.active = win; + GLFW.adjustCanvasDimensions(); + return win.id; + }, + destroyWindow:(winid) => { + var win = GLFW.WindowFromId(winid); + if (!win) return; + + if (win.windowCloseFunc) { + ((a1) => dynCall_vi(win.windowCloseFunc, a1))(win.id); + } + + GLFW.windows[win.id - 1] = null; + if (GLFW.active.id == win.id) { + GLFW.active = null; + } + + // Destroy context when no alive windows + for (win of GLFW.windows) { + if (win !== null) return; + } + + delete Module['ctx']; + }, + swapBuffers:(winid) => { + }, + requestFullscreen(lockPointer, resizeCanvas) { + Browser.lockPointer = lockPointer; + Browser.resizeCanvas = resizeCanvas; + if (typeof Browser.lockPointer == 'undefined') Browser.lockPointer = true; + if (typeof Browser.resizeCanvas == 'undefined') Browser.resizeCanvas = false; + + var canvas = Browser.getCanvas(); + function fullscreenChange() { + Browser.isFullscreen = false; + var canvasContainer = canvas.parentNode; + if (getFullscreenElement() === canvasContainer) { + canvas.exitFullscreen = Browser.exitFullscreen; + if (Browser.lockPointer) canvas.requestPointerLock(); + Browser.isFullscreen = true; + if (Browser.resizeCanvas) { + Browser.setFullscreenCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + Browser.updateResizeListeners(); + } + } else { + // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen + canvasContainer.parentNode.insertBefore(canvas, canvasContainer); + canvasContainer.parentNode.removeChild(canvasContainer); + + if (Browser.resizeCanvas) { + Browser.setWindowedCanvasSize(); + } else { + Browser.updateCanvasDimensions(canvas); + Browser.updateResizeListeners(); + } + } + } + + if (!Browser.fullscreenHandlersInstalled) { + Browser.fullscreenHandlersInstalled = true; + document.addEventListener('fullscreenchange', fullscreenChange); + document.addEventListener('webkitfullscreenchange', fullscreenChange); + } + + // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root + var canvasContainer = document.createElement('div'); + canvas.parentNode.insertBefore(canvasContainer, canvas); + canvasContainer.appendChild(canvas); + + // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) + // Safari didn't Element.requestFullscreen support until 16.4 + // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen + /** @suppress {checkTypes} */ + canvasContainer.requestFullscreen ??= (canvasContainer.webkitRequestFullscreen ? () => canvasContainer.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT) : null) ?? + (canvasContainer.webkitRequestFullScreen ? () => canvasContainer.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) : null); + + canvasContainer.requestFullscreen(); + }, + updateCanvasDimensions(canvas, wNative, hNative) { + const scale = GLFW.getHiDPIScale(); + + if (wNative && hNative) { + canvas.widthNative = wNative; + canvas.heightNative = hNative; + } else { + wNative = canvas.widthNative; + hNative = canvas.heightNative; + } + var w = wNative; + var h = hNative; + if ((getFullscreenElement() === canvas.parentNode) && (typeof screen != 'undefined')) { + var factor = Math.min(screen.width / w, screen.height / h); + w = Math.round(w * factor); + h = Math.round(h * factor); + } + if (Browser.resizeCanvas) { + wNative = w; + hNative = h; + } + const wNativeScaled = Math.floor(wNative * scale); + const hNativeScaled = Math.floor(hNative * scale); + if (canvas.width != wNativeScaled) canvas.width = wNativeScaled; + if (canvas.height != hNativeScaled) canvas.height = hNativeScaled; + if (typeof canvas.style != 'undefined') { + if (!GLFW.isCSSScalingEnabled()) { + canvas.style.setProperty( 'width', wNative + 'px', 'important'); + canvas.style.setProperty('height', hNative + 'px', 'important'); + } else { + canvas.style.removeProperty( 'width'); + canvas.style.removeProperty('height'); + } + } + }, + calculateMouseCoords(pageX, pageY) { + // Calculate the movement based on the changes + // in the coordinates. + const rect = Browser.getCanvas().getBoundingClientRect(); + + var adjustedX = pageX - (window.scrollX + rect.left); + var adjustedY = pageY - (window.scrollY + rect.top); + + // getBoundingClientRect() returns dimension affected by CSS, so as a result: + // - when CSS scaling is enabled, this will fix the mouse coordinates to match the width/height of the window + // - otherwise the CSS width/height are forced to the width/height of the GLFW window (see updateCanvasDimensions), + // so there is no need to adjust the position + if (GLFW.isCSSScalingEnabled() && GLFW.active) { + adjustedX = adjustedX * (GLFW.active.width / rect.width); + adjustedY = adjustedY * (GLFW.active.height / rect.height); + } + + return { x: adjustedX, y: adjustedY }; + }, + setWindowAttrib:(winid, attrib, value) => { + var win = GLFW.WindowFromId(winid); + if (!win) return; + const isHiDPIAware = GLFW.isHiDPIAware(); + win.attributes[attrib] = value; + if (isHiDPIAware !== GLFW.isHiDPIAware()) + GLFW.adjustCanvasDimensions(); + }, + getDevicePixelRatio() { + return (typeof devicePixelRatio == 'number' && devicePixelRatio) || 1.0; + }, + isHiDPIAware() { + if (GLFW.active) + return GLFW.active.attributes[0x0002200C] > 0; // GLFW_SCALE_TO_MONITOR + else + return false; + }, + isCSSScalingEnabled() { + return !GLFW.isHiDPIAware(); + }, + adjustCanvasDimensions() { + if (GLFW.active) { + Browser.updateCanvasDimensions(Browser.getCanvas(), GLFW.active.width, GLFW.active.height); + Browser.updateResizeListeners(); + } + }, + getHiDPIScale() { + return GLFW.isHiDPIAware() ? GLFW.scale : 1.0; + }, + onDevicePixelRatioChange() { + GLFW.onWindowContentScaleChanged(GLFW.getDevicePixelRatio()); + GLFW.adjustCanvasDimensions(); + }, + GLFW2ParamToGLFW3Param:(param) => { + var table = { + 0x00030001:0, // GLFW_MOUSE_CURSOR + 0x00030002:0, // GLFW_STICKY_KEYS + 0x00030003:0, // GLFW_STICKY_MOUSE_BUTTONS + 0x00030004:0, // GLFW_SYSTEM_KEYS + 0x00030005:0, // GLFW_KEY_REPEAT + 0x00030006:0, // GLFW_AUTO_POLL_EVENTS + 0x00020001:0, // GLFW_OPENED + 0x00020002:0, // GLFW_ACTIVE + 0x00020003:0, // GLFW_ICONIFIED + 0x00020004:0, // GLFW_ACCELERATED + 0x00020005:0x00021001, // GLFW_RED_BITS + 0x00020006:0x00021002, // GLFW_GREEN_BITS + 0x00020007:0x00021003, // GLFW_BLUE_BITS + 0x00020008:0x00021004, // GLFW_ALPHA_BITS + 0x00020009:0x00021005, // GLFW_DEPTH_BITS + 0x0002000A:0x00021006, // GLFW_STENCIL_BITS + 0x0002000B:0x0002100F, // GLFW_REFRESH_RATE + 0x0002000C:0x00021007, // GLFW_ACCUM_RED_BITS + 0x0002000D:0x00021008, // GLFW_ACCUM_GREEN_BITS + 0x0002000E:0x00021009, // GLFW_ACCUM_BLUE_BITS + 0x0002000F:0x0002100A, // GLFW_ACCUM_ALPHA_BITS + 0x00020010:0x0002100B, // GLFW_AUX_BUFFERS + 0x00020011:0x0002100C, // GLFW_STEREO + 0x00020012:0, // GLFW_WINDOW_NO_RESIZE + 0x00020013:0x0002100D, // GLFW_FSAA_SAMPLES + 0x00020014:0x00022002, // GLFW_OPENGL_VERSION_MAJOR + 0x00020015:0x00022003, // GLFW_OPENGL_VERSION_MINOR + 0x00020016:0x00022006, // GLFW_OPENGL_FORWARD_COMPAT + 0x00020017:0x00022007, // GLFW_OPENGL_DEBUG_CONTEXT + 0x00020018:0x00022008, // GLFW_OPENGL_PROFILE + }; + return table[param]; + }, + }; + var _glfwCreateWindow = (width, height, title, monitor, share) => GLFW.createWindow(width, height, title, monitor, share); + + var _glfwDefaultWindowHints = () => GLFW.defaultWindowHints(); + + var _glfwDestroyWindow = (winid) => GLFW.destroyWindow(winid); + + var _glfwGetPrimaryMonitor = () => 1; + + var _glfwGetTime = () => GLFW.getTime() - GLFW.initialTime; + + + var _glfwGetVideoModes = (monitor, count) => { + HEAP32[((count)>>2)] = 0; + return 0; + }; + + var _glfwInit = () => { + if (GLFW.windows) return 1; // GL_TRUE + + GLFW.initialTime = GLFW.getTime(); + GLFW.defaultWindowHints(); + GLFW.windows = new Array() + GLFW.active = null; + GLFW.scale = GLFW.getDevicePixelRatio(); + + window.addEventListener('gamepadconnected', GLFW.onGamepadConnected, true); + window.addEventListener('gamepaddisconnected', GLFW.onGamepadDisconnected, true); + window.addEventListener('keydown', GLFW.onKeydown, true); + window.addEventListener('keypress', GLFW.onKeyPress, true); + window.addEventListener('keyup', GLFW.onKeyup, true); + window.addEventListener('blur', GLFW.onBlur, true); + + // watch for devicePixelRatio changes + GLFW.devicePixelRatioMQL = window.matchMedia('(resolution: ' + GLFW.getDevicePixelRatio() + 'dppx)'); + GLFW.devicePixelRatioMQL.addEventListener('change', GLFW.onDevicePixelRatioChange); + + var canvas = Browser.getCanvas(); + canvas.addEventListener('touchmove', GLFW.onMousemove, true); + canvas.addEventListener('touchstart', GLFW.onMouseButtonDown, true); + canvas.addEventListener('touchcancel', GLFW.onMouseButtonUp, true); + canvas.addEventListener('touchend', GLFW.onMouseButtonUp, true); + canvas.addEventListener('mousemove', GLFW.onMousemove, true); + canvas.addEventListener('mousedown', GLFW.onMouseButtonDown, true); + canvas.addEventListener('mouseup', GLFW.onMouseButtonUp, true); + canvas.addEventListener('wheel', GLFW.onMouseWheel, true); + canvas.addEventListener('mousewheel', GLFW.onMouseWheel, true); + canvas.addEventListener('mouseenter', GLFW.onMouseenter, true); + canvas.addEventListener('mouseleave', GLFW.onMouseleave, true); + canvas.addEventListener('drop', GLFW.onDrop, true); + canvas.addEventListener('dragover', GLFW.onDragover, true); + + // Overriding implementation to account for HiDPI + Browser.requestFullscreen = GLFW.requestFullscreen; + Browser.calculateMouseCoords = GLFW.calculateMouseCoords; + Browser.updateCanvasDimensions = GLFW.updateCanvasDimensions; + + Browser.resizeListeners.push((width, height) => { + if (GLFW.isHiDPIAware()) { + var canvas = Browser.getCanvas(); + GLFW.onCanvasResize(canvas.clientWidth, canvas.clientHeight, width, height); + } else { + GLFW.onCanvasResize(width, height, width, height); + } + }); + + return 1; // GL_TRUE + }; + + var _glfwMakeContextCurrent = (winid) => 0; + + var _glfwSetCharCallback = (winid, cbfun) => GLFW.setCharCallback(winid, cbfun); + + var _glfwSetCursorEnterCallback = (winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.cursorEnterFunc; + win.cursorEnterFunc = cbfun; + return prevcbfun; + }; + + var _glfwSetCursorPosCallback = (winid, cbfun) => GLFW.setCursorPosCallback(winid, cbfun); + + var _glfwSetDropCallback = (winid, cbfun) => GLFW.setDropCallback(winid, cbfun); + + var _glfwSetErrorCallback = (cbfun) => { + var prevcbfun = GLFW.errorFunc; + GLFW.errorFunc = cbfun; + return prevcbfun; + }; + + var _glfwSetKeyCallback = (winid, cbfun) => GLFW.setKeyCallback(winid, cbfun); + + var _glfwSetMouseButtonCallback = (winid, cbfun) => GLFW.setMouseButtonCallback(winid, cbfun); + + var _glfwSetScrollCallback = (winid, cbfun) => GLFW.setScrollCallback(winid, cbfun); + + var _glfwSetWindowContentScaleCallback = (winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.windowContentScaleFunc; + win.windowContentScaleFunc = cbfun; + return prevcbfun; + }; + + var _glfwSetWindowFocusCallback = (winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.windowFocusFunc; + win.windowFocusFunc = cbfun; + return prevcbfun; + }; + + var _glfwSetWindowIconifyCallback = (winid, cbfun) => { + var win = GLFW.WindowFromId(winid); + if (!win) return null; + var prevcbfun = win.windowIconifyFunc; + win.windowIconifyFunc = cbfun; + return prevcbfun; + }; + + var _glfwSetWindowShouldClose = (winid, value) => { + var win = GLFW.WindowFromId(winid); + if (!win) return; + win.shouldClose = value; + }; + + var _glfwSetWindowSizeCallback = (winid, cbfun) => GLFW.setWindowSizeCallback(winid, cbfun); + + var _glfwSwapBuffers = (winid) => GLFW.swapBuffers(winid); + + var _glfwTerminate = () => { + window.removeEventListener('gamepadconnected', GLFW.onGamepadConnected, true); + window.removeEventListener('gamepaddisconnected', GLFW.onGamepadDisconnected, true); + window.removeEventListener('keydown', GLFW.onKeydown, true); + window.removeEventListener('keypress', GLFW.onKeyPress, true); + window.removeEventListener('keyup', GLFW.onKeyup, true); + window.removeEventListener('blur', GLFW.onBlur, true); + var canvas = Browser.getCanvas(); + canvas.removeEventListener('touchmove', GLFW.onMousemove, true); + canvas.removeEventListener('touchstart', GLFW.onMouseButtonDown, true); + canvas.removeEventListener('touchcancel', GLFW.onMouseButtonUp, true); + canvas.removeEventListener('touchend', GLFW.onMouseButtonUp, true); + canvas.removeEventListener('mousemove', GLFW.onMousemove, true); + canvas.removeEventListener('mousedown', GLFW.onMouseButtonDown, true); + canvas.removeEventListener('mouseup', GLFW.onMouseButtonUp, true); + canvas.removeEventListener('wheel', GLFW.onMouseWheel, true); + canvas.removeEventListener('mousewheel', GLFW.onMouseWheel, true); + canvas.removeEventListener('mouseenter', GLFW.onMouseenter, true); + canvas.removeEventListener('mouseleave', GLFW.onMouseleave, true); + canvas.removeEventListener('drop', GLFW.onDrop, true); + canvas.removeEventListener('dragover', GLFW.onDragover, true); + + if (GLFW.devicePixelRatioMQL) + GLFW.devicePixelRatioMQL.removeEventListener('change', GLFW.onDevicePixelRatioChange); + + canvas.width = canvas.height = 1; + GLFW.windows = null; + GLFW.active = null; + }; + + var _glfwWindowHint = (target, hint) => { + GLFW.hints[target] = hint; + }; + + + + + var runAndAbortIfError = (func) => { + try { + return func(); + } catch (e) { + abort(e); + } + }; + + + var createNamedFunction = (name, func) => Object.defineProperty(func, 'name', { value: name }); + + var runtimeKeepalivePush = () => { + runtimeKeepaliveCounter += 1; + }; + + var runtimeKeepalivePop = () => { + assert(runtimeKeepaliveCounter > 0); + runtimeKeepaliveCounter -= 1; + }; + + + + + var Asyncify = { + instrumentWasmImports(imports) { + var importPattern = /^(invoke_.*|__asyncjs__.*)$/; + + for (let [x, original] of Object.entries(imports)) { + if (typeof original == 'function') { + let isAsyncifyImport = original.isAsync || importPattern.test(x); + imports[x] = (...args) => { + var originalAsyncifyState = Asyncify.state; + try { + return original(...args); + } finally { + // Only asyncify-declared imports are allowed to change the + // state. + // Changing the state from normal to disabled is allowed (in any + // function) as that is what shutdown does (and we don't have an + // explicit list of shutdown imports). + var changedToDisabled = + originalAsyncifyState === Asyncify.State.Normal && + Asyncify.state === Asyncify.State.Disabled; + // invoke_* functions are allowed to change the state if we do + // not ignore indirect calls. + var ignoredInvoke = x.startsWith('invoke_') && + true; + if (Asyncify.state !== originalAsyncifyState && + !isAsyncifyImport && + !changedToDisabled && + !ignoredInvoke) { + abort(`import ${x} was not in ASYNCIFY_IMPORTS, but changed the state`); + } + } + }; + } + } + }, + instrumentFunction(original) { + var wrapper = (...args) => { + Asyncify.exportCallStack.push(original); + try { + return original(...args); + } finally { + if (!ABORT) { + var top = Asyncify.exportCallStack.pop(); + assert(top === original); + Asyncify.maybeStopUnwind(); + } + } + }; + Asyncify.funcWrappers.set(original, wrapper); + wrapper = createNamedFunction(`__asyncify_wrapper_${original.name}`, wrapper); + return wrapper; + }, + instrumentWasmExports(exports) { + var ret = {}; + for (let [x, original] of Object.entries(exports)) { + if (typeof original == 'function') { + var wrapper = Asyncify.instrumentFunction(original); + ret[x] = wrapper; + } else { + ret[x] = original; + } + } + return ret; + }, + State:{ + Normal:0, + Unwinding:1, + Rewinding:2, + Disabled:3, + }, + state:0, + StackSize:4096, + currData:null, + handleSleepReturnValue:0, + exportCallStack:[], + callstackFuncToId:new Map, + callStackIdToFunc:new Map, + funcWrappers:new Map, + callStackId:0, + asyncPromiseHandlers:null, + sleepCallbacks:[], + getCallStackId(func) { + assert(func); + if (!Asyncify.callstackFuncToId.has(func)) { + var id = Asyncify.callStackId++; + Asyncify.callstackFuncToId.set(func, id); + Asyncify.callStackIdToFunc.set(id, func); + } + return Asyncify.callstackFuncToId.get(func); + }, + maybeStopUnwind() { + if (Asyncify.currData && + Asyncify.state === Asyncify.State.Unwinding && + !Asyncify.exportCallStack.length) { + // We just finished unwinding. + // Be sure to set the state before calling any other functions to avoid + // possible infinite recursion here (For example in debug pthread builds + // the dbg() function itself can call back into WebAssembly to get the + // current pthread_self() pointer). + Asyncify.state = Asyncify.State.Normal; + + // Keep the runtime alive so that a re-wind can be done later. + runAndAbortIfError(_asyncify_stop_unwind); + if (typeof Fibers != 'undefined') { + Fibers.trampoline(); + } + } + }, + whenDone() { + assert(Asyncify.currData, 'tried to wait for an async operation when none is in progress'); + assert(!Asyncify.asyncPromiseHandlers, 'cannot have multiple async operations in flight at once'); + return new Promise((resolve, reject) => { + Asyncify.asyncPromiseHandlers = { resolve, reject }; + }); + }, + allocateData() { + // An asyncify data structure has three fields: + // 0 current stack pos + // 4 max stack pos + // 8 id of function at bottom of the call stack (callStackIdToFunc[id] == wasm func) + // + // The Asyncify ABI only interprets the first two fields, the rest is for the runtime. + // We also embed a stack in the same memory region here, right next to the structure. + // This struct is also defined as asyncify_data_t in emscripten/fiber.h + var ptr = _malloc(12 + Asyncify.StackSize); + Asyncify.setDataHeader(ptr, ptr + 12, Asyncify.StackSize); + Asyncify.setDataRewindFunc(ptr); + return ptr; + }, + setDataHeader(ptr, stack, stackSize) { + HEAPU32[((ptr)>>2)] = stack; + HEAPU32[(((ptr)+(4))>>2)] = stack + stackSize; + }, + setDataRewindFunc(ptr) { + var bottomOfCallStack = Asyncify.exportCallStack[0]; + assert(bottomOfCallStack, 'exportCallStack is empty'); + var rewindId = Asyncify.getCallStackId(bottomOfCallStack); + HEAP32[(((ptr)+(8))>>2)] = rewindId; + }, + getDataRewindFunc(ptr) { + var id = HEAP32[(((ptr)+(8))>>2)]; + var func = Asyncify.callStackIdToFunc.get(id); + assert(func, `id ${id} not found in callStackIdToFunc`); + return func; + }, + doRewind(ptr) { + var original = Asyncify.getDataRewindFunc(ptr); + var func = Asyncify.funcWrappers.get(original); + assert(original); + assert(func); + // Once we have rewound and the stack we no longer need to artificially + // keep the runtime alive. + + return callUserCallback(func); + }, + handleSleep(startAsync) { + assert(Asyncify.state !== Asyncify.State.Disabled, 'handleSleep called after Asyncify was shut down'); + if (ABORT) return; + if (Asyncify.state === Asyncify.State.Normal) { + // Prepare to sleep. Call startAsync, and see what happens: + // if the code decided to call our callback synchronously, + // then no async operation was in fact begun, and we don't + // need to do anything. + var reachedCallback = false; + var reachedAfterCallback = false; + startAsync((handleSleepReturnValue = 0) => { + // old emterpretify API supported other stuff + assert(['undefined', 'number', 'boolean', 'bigint'].includes(typeof handleSleepReturnValue), `invalid type for handleSleepReturnValue: '${typeof handleSleepReturnValue}'`); + if (ABORT) return; + Asyncify.handleSleepReturnValue = handleSleepReturnValue; + reachedCallback = true; + if (!reachedAfterCallback) { + // We are happening synchronously, so no need for async. + return; + } + // This async operation did not happen synchronously, so we did + // unwind. In that case there can be no compiled code on the stack, + // as it might break later operations (we can rewind ok now, but if + // we unwind again, we would unwind through the extra compiled code + // too). + assert(!Asyncify.exportCallStack.length, 'waking up (starting to rewind) must be done from JS, without compiled code on the stack'); + Asyncify.state = Asyncify.State.Rewinding; + runAndAbortIfError(() => _asyncify_start_rewind(Asyncify.currData)); + if (typeof MainLoop != 'undefined' && MainLoop.func) { + MainLoop.resume(); + } + var asyncWasmReturnValue, isError = false; + try { + asyncWasmReturnValue = Asyncify.doRewind(Asyncify.currData); + } catch (err) { + asyncWasmReturnValue = err; + isError = true; + } + // Track whether the return value was handled by any promise handlers. + var handled = false; + if (!Asyncify.currData) { + // All asynchronous execution has finished. + // `asyncWasmReturnValue` now contains the final + // return value of the exported async WASM function. + // + // Note: `asyncWasmReturnValue` is distinct from + // `Asyncify.handleSleepReturnValue`. + // `Asyncify.handleSleepReturnValue` contains the return + // value of the last C function to have executed + // `Asyncify.handleSleep()`, whereas `asyncWasmReturnValue` + // contains the return value of the exported WASM function + // that may have called C functions that + // call `Asyncify.handleSleep()`. + var asyncPromiseHandlers = Asyncify.asyncPromiseHandlers; + if (asyncPromiseHandlers) { + Asyncify.asyncPromiseHandlers = null; + (isError ? asyncPromiseHandlers.reject : asyncPromiseHandlers.resolve)(asyncWasmReturnValue); + handled = true; + } + } + if (isError && !handled) { + // If there was an error and it was not handled by now, we have no choice but to + // rethrow that error into the global scope where it can be caught only by + // `onerror` or `onunhandledpromiserejection`. + throw asyncWasmReturnValue; + } + }); + reachedAfterCallback = true; + if (!reachedCallback) { + // A true async operation was begun; start a sleep. + Asyncify.state = Asyncify.State.Unwinding; + // TODO: reuse, don't alloc/free every sleep + Asyncify.currData = Asyncify.allocateData(); + if (typeof MainLoop != 'undefined' && MainLoop.func) { + MainLoop.pause(); + } + runAndAbortIfError(() => _asyncify_start_unwind(Asyncify.currData)); + } + } else if (Asyncify.state === Asyncify.State.Rewinding) { + // Stop a resume. + Asyncify.state = Asyncify.State.Normal; + runAndAbortIfError(_asyncify_stop_rewind); + _free(Asyncify.currData); + Asyncify.currData = null; + // Call all sleep callbacks now that the sleep-resume is all done. + Asyncify.sleepCallbacks.forEach(callUserCallback); + } else { + abort(`invalid state: ${Asyncify.state}`); + } + return Asyncify.handleSleepReturnValue; + }, + handleAsync:(startAsync) => Asyncify.handleSleep(async (wakeUp) => { + // TODO: add error handling as a second param when handleSleep implements it. + wakeUp(await startAsync()); + }), + }; + + + + + var FS_createPath = (...args) => FS.createPath(...args); + + + + var FS_unlink = (...args) => FS.unlink(...args); + + var FS_createLazyFile = (...args) => FS.createLazyFile(...args); + + var FS_createDevice = (...args) => FS.createDevice(...args); + + + + FS.createPreloadedFile = FS_createPreloadedFile; + FS.preloadFile = FS_preloadFile; + FS.staticInit();; +for (let i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i));; +var miniTempWebGLFloatBuffersStorage = new Float32Array(288); + // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive + for (/**@suppress{duplicate}*/var i = 0; i <= 288; ++i) { + miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i); + }; +var miniTempWebGLIntBuffersStorage = new Int32Array(288); + // Create GL_POOL_TEMP_BUFFERS_SIZE+1 temporary buffers, for uploads of size 0 through GL_POOL_TEMP_BUFFERS_SIZE inclusive + for (/**@suppress{duplicate}*/var i = 0; i <= 288; ++i) { + miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i); + }; + + Module['requestAnimationFrame'] = MainLoop.requestAnimationFrame; + Module['pauseMainLoop'] = MainLoop.pause; + Module['resumeMainLoop'] = MainLoop.resume; + MainLoop.init();; +// End JS library code + +// include: postlibrary.js +// This file is included after the automatically-generated JS library code +// but before the wasm module is created. + +{ + + // Begin ATMODULES hooks + if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime']; + +if (Module['print']) out = Module['print']; +if (Module['printErr']) err = Module['printErr']; + // End ATMODULES hooks + + checkIncomingModuleAPI(); + + if (Module['arguments']) programArgs = Module['arguments']; + if (Module['thisProgram']) thisProgram = Module['thisProgram']; + + // Assertions on removed incoming Module JS APIs. + assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead'); + assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead'); + assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead'); + assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead'); + assert(typeof Module['read'] == 'undefined', 'Module.read option was removed'); + assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)'); + assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)'); + assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)'); + assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY'); + assert(typeof Module['ENVIRONMENT'] == 'undefined', 'Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)'); + assert(typeof Module['STACK_SIZE'] == 'undefined', 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time') + // If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY + assert(typeof Module['wasmMemory'] == 'undefined', 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally'); + assert(typeof Module['INITIAL_MEMORY'] == 'undefined', 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically'); + + var preInit = Module['preInit']; + if (preInit) { + if (typeof preInit == 'function') Module['preInit'] = preInit = [preInit]; + // Written as a loop so that preInit functions that themselves add more + // preInit functions. Is this actually needed? + while (preInit.length > 0) { + preInit.shift()(); + } + } + consumedModuleProp('preInit'); +} + +// Begin runtime exports + Module['addRunDependency'] = addRunDependency; + Module['removeRunDependency'] = removeRunDependency; + Module['FS_preloadFile'] = FS_preloadFile; + Module['FS_unlink'] = FS_unlink; + Module['FS_createPath'] = FS_createPath; + Module['FS_createDevice'] = FS_createDevice; + Module['FS_createDataFile'] = FS_createDataFile; + Module['FS_createLazyFile'] = FS_createLazyFile; + var missingLibrarySymbols = [ + 'writeI53ToI64Clamped', + 'writeI53ToI64Signaling', + 'writeI53ToU64Clamped', + 'writeI53ToU64Signaling', + 'convertI32PairToI53', + 'convertI32PairToI53Checked', + 'convertU32PairToI53', + 'stackAlloc', + 'getTempRet0', + 'setTempRet0', + 'zeroMemory', + 'getHeapMax', + 'growMemory', + 'withStackSave', + 'inetPton4', + 'inetNtop4', + 'inetPton6', + 'inetNtop6', + 'readSockaddr', + 'writeSockaddr', + 'runMainThreadEmAsm', + 'getExecutableName', + 'autoResumeAudioContext', + 'getDynCaller', + 'asmjsMangle', + 'alignMemory', + 'HandleAllocator', + 'addOnInit', + 'addOnPostCtor', + 'addOnPreMain', + 'STACK_SIZE', + 'STACK_ALIGN', + 'POINTER_SIZE', + 'ASSERTIONS', + 'ccall', + 'cwrap', + 'convertJsFunctionToWasm', + 'getEmptyTableSlot', + 'updateTableMap', + 'getFunctionAddress', + 'addFunction', + 'removeFunction', + 'setValue', + 'getValue', + 'intArrayToString', + 'AsciiToString', + 'stringToAscii', + 'UTF16ToString', + 'stringToUTF16', + 'lengthBytesUTF16', + 'UTF32ToString', + 'stringToUTF32', + 'lengthBytesUTF32', + 'stringToUTF8OnStack', + 'writeArrayToMemory', + 'registerKeyEventCallback', + 'registerWheelEventCallback', + 'registerFocusEventCallback', + 'fillDeviceOrientationEventData', + 'registerDeviceOrientationEventCallback', + 'fillDeviceMotionEventData', + 'registerDeviceMotionEventCallback', + 'screenOrientation', + 'fillOrientationChangeEventData', + 'registerOrientationChangeEventCallback', + 'callCanvasResizedCallback', + 'JSEvents_requestFullscreen', + 'JSEvents_resizeCanvasForFullscreen', + 'registerRestoreOldStyle', + 'hideEverythingExceptGivenElement', + 'restoreHiddenElements', + 'setLetterbox', + 'currentFullscreenStrategy', + 'softFullscreenResizeWebGLRenderTarget', + 'doRequestFullscreen', + 'registerPointerlockErrorEventCallback', + 'requestPointerLock', + 'fillVisibilityChangeEventData', + 'registerVisibilityChangeEventCallback', + 'registerBeforeUnloadEventCallback', + 'fillBatteryEventData', + 'registerBatteryEventCallback', + 'setCanvasElementSize', + 'getCanvasElementSize', + 'jsStackTrace', + 'getCallstack', + 'convertPCtoSourceLocation', + 'getEnvStrings', + 'wasiRightsToMuslOFlags', + 'wasiOFlagsToMuslOFlags', + 'setImmediateWrapped', + 'safeRequestAnimationFrame', + 'clearImmediateWrapped', + 'registerPostMainLoop', + 'registerPreMainLoop', + 'getPromise', + 'makePromise', + 'addPromise', + 'idsToPromises', + 'makePromiseCallback', + 'Browser_asyncPrepareDataCounter', + 'isLeapYear', + 'ydayFromDate', + 'arraySum', + 'addDays', + 'getSocketFromFD', + 'getSocketAddress', + 'FS_mkdirTree', + '_setNetworkCallback', + 'writeGLArray', + 'registerWebGlEventCallback', + 'writeStringToMemory', + 'writeAsciiToMemory', + 'allocateUTF8', + 'allocateUTF8OnStack', + 'stackTrace', + 'getNativeTypeSize', +]; +missingLibrarySymbols.forEach(missingLibrarySymbol) + + var unexportedSymbols = [ + 'run', + 'out', + 'err', + 'callMain', + 'abort', + 'wasmExports', + 'writeStackCookie', + 'checkStackCookie', + 'writeI53ToI64', + 'readI53FromI64', + 'readI53FromU64', + 'INT53_MAX', + 'INT53_MIN', + 'bigintToI53Checked', + 'HEAP8', + 'HEAPU8', + 'HEAP16', + 'HEAPU16', + 'HEAP32', + 'HEAPU32', + 'HEAPF32', + 'HEAPF64', + 'HEAP64', + 'HEAPU64', + 'stackSave', + 'stackRestore', + 'createNamedFunction', + 'ptrToString', + 'exitJS', + 'abortOnCannotGrowMemory', + 'ENV', + 'ERRNO_CODES', + 'strError', + 'DNS', + 'Protocols', + 'Sockets', + 'timers', + 'warnOnce', + 'readEmAsmArgsArray', + 'readEmAsmArgs', + 'runEmAsmFunction', + 'jstoi_q', + 'dynCallLegacy', + 'dynCall', + 'handleException', + 'keepRuntimeAlive', + 'runtimeKeepalivePush', + 'runtimeKeepalivePop', + 'callUserCallback', + 'maybeExit', + 'asyncLoad', + 'mmapAlloc', + 'wasmTable', + 'wasmMemory', + 'getUniqueRunDependency', + 'noExitRuntime', + 'addOnPreRun', + 'addOnExit', + 'addOnPostRun', + 'freeTableIndexes', + 'functionsInTableMap', + 'PATH', + 'PATH_FS', + 'UTF8Decoder', + 'UTF8ArrayToString', + 'UTF8ToString', + 'stringToUTF8Array', + 'stringToUTF8', + 'lengthBytesUTF8', + 'intArrayFromString', + 'UTF16Decoder', + 'stringToNewUTF8', + 'JSEvents', + 'specialHTMLTargets', + 'maybeCStringToJsString', + 'findEventTarget', + 'findCanvasEventTarget', + 'getBoundingClientRect', + 'fillMouseEventData', + 'registerMouseEventCallback', + 'registerUiEventCallback', + 'fillFullscreenChangeEventData', + 'registerFullscreenChangeEventCallback', + 'restoreOldWindowedStyle', + 'fillPointerlockChangeEventData', + 'registerPointerlockChangeEventCallback', + 'registerTouchEventCallback', + 'fillGamepadEventData', + 'registerGamepadEventCallback', + 'UNWIND_CACHE', + 'ExitStatus', + 'checkWasiClock', + 'doReadv', + 'doWritev', + 'initRandomFill', + 'randomFill', + 'safeSetTimeout', + 'emSetImmediate', + 'emClearImmediate_deps', + 'emClearImmediate', + 'promiseMap', + 'Browser', + 'requestFullscreen', + 'setCanvasSize', + 'getUserMedia', + 'createContext', + 'getPreloadedImageData__data', + 'wget', + 'MONTH_DAYS_REGULAR', + 'MONTH_DAYS_LEAP', + 'MONTH_DAYS_REGULAR_CUMULATIVE', + 'MONTH_DAYS_LEAP_CUMULATIVE', + 'SYSCALLS', + 'preloadPlugins', + 'FS_createPreloadedFile', + 'FS_modeStringToFlags', + 'FS_getMode', + 'FS_fileDataToTypedArray', + 'FS_stdin_getChar_buffer', + 'FS_stdin_getChar', + 'FS_readFile', + 'FS', + 'FS_root', + 'FS_mounts', + 'FS_devices', + 'FS_streams', + 'FS_nextInode', + 'FS_nameTable', + 'FS_currentPath', + 'FS_initialized', + 'FS_ignorePermissions', + 'FS_filesystems', + 'FS_syncFSRequests', + 'FS_lookupPath', + 'FS_getPath', + 'FS_hashName', + 'FS_hashAddNode', + 'FS_hashRemoveNode', + 'FS_lookupNode', + 'FS_createNode', + 'FS_destroyNode', + 'FS_isRoot', + 'FS_isMountpoint', + 'FS_isFile', + 'FS_isDir', + 'FS_isLink', + 'FS_isChrdev', + 'FS_isBlkdev', + 'FS_isFIFO', + 'FS_isSocket', + 'FS_flagsToPermissionString', + 'FS_nodePermissions', + 'FS_mayLookup', + 'FS_mayCreate', + 'FS_mayDelete', + 'FS_mayOpen', + 'FS_checkOpExists', + 'FS_nextfd', + 'FS_getStreamChecked', + 'FS_getStream', + 'FS_createStream', + 'FS_closeStream', + 'FS_dupStream', + 'FS_doSetAttr', + 'FS_chrdev_stream_ops', + 'FS_major', + 'FS_minor', + 'FS_makedev', + 'FS_registerDevice', + 'FS_getDevice', + 'FS_getMounts', + 'FS_syncfs', + 'FS_mount', + 'FS_unmount', + 'FS_lookup', + 'FS_mknod', + 'FS_statfs', + 'FS_statfsStream', + 'FS_statfsNode', + 'FS_create', + 'FS_mkdir', + 'FS_mkdev', + 'FS_symlink', + 'FS_link', + 'FS_rename', + 'FS_rmdir', + 'FS_readdir', + 'FS_readlink', + 'FS_stat', + 'FS_fstat', + 'FS_lstat', + 'FS_doChmod', + 'FS_chmod', + 'FS_lchmod', + 'FS_fchmod', + 'FS_doChown', + 'FS_chown', + 'FS_lchown', + 'FS_fchown', + 'FS_doTruncate', + 'FS_truncate', + 'FS_ftruncate', + 'FS_utime', + 'FS_open', + 'FS_close', + 'FS_isClosed', + 'FS_llseek', + 'FS_read', + 'FS_write', + 'FS_mmap', + 'FS_msync', + 'FS_ioctl', + 'FS_writeFile', + 'FS_cwd', + 'FS_chdir', + 'FS_createDefaultDirectories', + 'FS_createDefaultDevices', + 'FS_createSpecialDirectories', + 'FS_createStandardStreams', + 'FS_staticInit', + 'FS_init', + 'FS_quit', + 'FS_findObject', + 'FS_analyzePath', + 'FS_createFile', + 'FS_forceLoadFile', + 'MEMFS', + 'TTY', + 'PIPEFS', + 'SOCKFS', + 'tempFixedLengthArray', + 'miniTempWebGLFloatBuffers', + 'miniTempWebGLIntBuffers', + 'heapObjectForWebGLType', + 'toTypedArrayIndex', + 'webgl_enable_ANGLE_instanced_arrays', + 'webgl_enable_OES_vertex_array_object', + 'webgl_enable_WEBGL_draw_buffers', + 'webgl_enable_WEBGL_multi_draw', + 'webgl_enable_EXT_polygon_offset_clamp', + 'webgl_enable_EXT_clip_control', + 'webgl_enable_WEBGL_polygon_mode', + 'GL', + 'emscriptenWebGLGet', + 'computeUnpackAlignedImageSize', + 'colorChannelsInGlTextureFormat', + 'emscriptenWebGLGetTexPixelData', + 'emscriptenWebGLGetUniform', + 'webglGetProgramUniformLocation', + 'webglGetUniformLocation', + 'webglPrepareUniformLocationsBeforeFirstUse', + 'webglGetLeftBracePos', + 'emscriptenWebGLGetVertexAttrib', + '__glGetActiveAttribOrUniform', + 'AL', + 'GLUT', + 'EGL', + 'GLEW', + 'IDBStore', + 'runAndAbortIfError', + 'Asyncify', + 'Fibers', + 'SDL', + 'SDL_gfx', + 'GLFW_Window', + 'GLFW', + 'print', + 'printErr', + 'jstoi_s', +]; +unexportedSymbols.forEach(unexportedRuntimeSymbol); + + // End runtime exports + // Begin JS library exports + // End JS library exports + +// end include: postlibrary.js + +function checkIncomingModuleAPI() { + ignoredModuleProp('fetchSettings'); + ignoredModuleProp('logReadFiles'); + ignoredModuleProp('loadSplitModule'); + ignoredModuleProp('onMalloc'); + ignoredModuleProp('onRealloc'); + ignoredModuleProp('onFree'); + ignoredModuleProp('onSbrkGrow'); + ignoredModuleProp('onCOSCacheHit'); + ignoredModuleProp('onCOSCacheMiss'); + ignoredModuleProp('onCOSStore'); + ignoredModuleProp('GL_MAX_TEXTURE_IMAGE_UNITS'); + ignoredModuleProp('SDL_canPlayWithWebAudio'); + ignoredModuleProp('SDL_numSimultaneouslyQueuedBuffers'); + ignoredModuleProp('freePreloadedMediaOnUse'); + ignoredModuleProp('preinitializedWebGLContext'); + ignoredModuleProp('keyboardListeningElement'); + ignoredModuleProp('doNotCaptureKeyboard'); + ignoredModuleProp('extraStackTrace'); + ignoredModuleProp('preloadPlugins'); + ignoredModuleProp('preMainLoop'); + ignoredModuleProp('postMainLoop'); + ignoredModuleProp('forcedAspectRatio'); + ignoredModuleProp('mainScriptUrlOrBlob'); + ignoredModuleProp('onFullScreen'); + ignoredModuleProp('INITIAL_MEMORY'); + ignoredModuleProp('wasmMemory'); + ignoredModuleProp('wasmBinary'); +} +var ASM_CONSTS = { + 97272: () => { if (document.fullscreenElement) return 1; }, + 97318: () => { return document.getElementById('canvas').width; }, + 97370: () => { return parseInt(document.getElementById('canvas').style.width); }, + 97438: () => { document.exitFullscreen(); }, + 97465: () => { setTimeout(function() { Module.requestFullscreen(false, false); }, 100); }, + 97538: () => { if (document.fullscreenElement) return 1; }, + 97584: () => { return document.getElementById('canvas').width; }, + 97636: () => { return screen.width; }, + 97661: () => { document.exitFullscreen(); }, + 97688: () => { setTimeout(function() { Module.requestFullscreen(false, true); setTimeout(function() { canvas.style.width="unset"; }, 100); }, 100); }, + 97821: () => { return window.innerWidth; }, + 97847: () => { return window.innerHeight; }, + 97874: () => { if (document.fullscreenElement) return 1; }, + 97920: () => { return document.getElementById('canvas').width; }, + 97972: () => { return parseInt(document.getElementById('canvas').style.width); }, + 98040: () => { if (document.fullscreenElement) return 1; }, + 98086: () => { return document.getElementById('canvas').width; }, + 98138: () => { return screen.width; }, + 98163: () => { return window.innerWidth; }, + 98189: () => { return window.innerHeight; }, + 98216: () => { if (document.fullscreenElement) return 1; }, + 98262: () => { return document.getElementById('canvas').width; }, + 98314: () => { return screen.width; }, + 98339: () => { document.exitFullscreen(); }, + 98366: () => { if (document.fullscreenElement) return 1; }, + 98412: () => { return document.getElementById('canvas').width; }, + 98464: () => { return parseInt(document.getElementById('canvas').style.width); }, + 98532: () => { document.exitFullscreen(); }, + 98559: ($0) => { document.getElementById('canvas').style.opacity = $0; }, + 98617: () => { return screen.width; }, + 98642: () => { return screen.height; }, + 98668: () => { return window.screenX; }, + 98695: () => { return window.screenY; }, + 98722: ($0) => { navigator.clipboard.writeText(UTF8ToString($0)); }, + 98775: ($0) => { document.getElementById("canvas").style.cursor = UTF8ToString($0); }, + 98846: () => { document.getElementById('canvas').style.cursor = 'none'; }, + 98903: ($0, $1, $2, $3) => { try { navigator.getGamepads()[$0].vibrationActuator.playEffect('dual-rumble', { startDelay: 0, duration: $3, weakMagnitude: $1, strongMagnitude: $2 }); } catch (e) { try { navigator.getGamepads()[$0].hapticActuators[0].pulse($2, $3); } catch (e) { } } }, + 99159: ($0) => { document.getElementById('canvas').style.cursor = UTF8ToString($0); }, + 99230: () => { if (document.fullscreenElement) return 1; }, + 99276: () => { return window.innerWidth; }, + 99302: () => { return window.innerHeight; }, + 99329: () => { if (document.pointerLockElement) return 1; } +}; + +// Imports from the Wasm binary. +var _main = Module['_main'] = makeInvalidEarlyAccess('_main'); +var _malloc = makeInvalidEarlyAccess('_malloc'); +var _free = makeInvalidEarlyAccess('_free'); +var _fflush = makeInvalidEarlyAccess('_fflush'); +var _emscripten_stack_get_end = makeInvalidEarlyAccess('_emscripten_stack_get_end'); +var _emscripten_stack_get_base = makeInvalidEarlyAccess('_emscripten_stack_get_base'); +var _strerror = makeInvalidEarlyAccess('_strerror'); +var _emscripten_stack_init = makeInvalidEarlyAccess('_emscripten_stack_init'); +var _emscripten_stack_get_free = makeInvalidEarlyAccess('_emscripten_stack_get_free'); +var __emscripten_stack_restore = makeInvalidEarlyAccess('__emscripten_stack_restore'); +var __emscripten_stack_alloc = makeInvalidEarlyAccess('__emscripten_stack_alloc'); +var _emscripten_stack_get_current = makeInvalidEarlyAccess('_emscripten_stack_get_current'); +var dynCall_vii = makeInvalidEarlyAccess('dynCall_vii'); +var dynCall_viii = makeInvalidEarlyAccess('dynCall_viii'); +var dynCall_viff = makeInvalidEarlyAccess('dynCall_viff'); +var dynCall_viiiii = makeInvalidEarlyAccess('dynCall_viiiii'); +var dynCall_viiii = makeInvalidEarlyAccess('dynCall_viiii'); +var dynCall_vidd = makeInvalidEarlyAccess('dynCall_vidd'); +var dynCall_ii = makeInvalidEarlyAccess('dynCall_ii'); +var dynCall_iiii = makeInvalidEarlyAccess('dynCall_iiii'); +var dynCall_viiiiii = makeInvalidEarlyAccess('dynCall_viiiiii'); +var dynCall_iiiiii = makeInvalidEarlyAccess('dynCall_iiiiii'); +var dynCall_vi = makeInvalidEarlyAccess('dynCall_vi'); +var dynCall_vffff = makeInvalidEarlyAccess('dynCall_vffff'); +var dynCall_vf = makeInvalidEarlyAccess('dynCall_vf'); +var dynCall_viiiiiiii = makeInvalidEarlyAccess('dynCall_viiiiiiii'); +var dynCall_viiiiiiiii = makeInvalidEarlyAccess('dynCall_viiiiiiiii'); +var dynCall_i = makeInvalidEarlyAccess('dynCall_i'); +var dynCall_vff = makeInvalidEarlyAccess('dynCall_vff'); +var dynCall_v = makeInvalidEarlyAccess('dynCall_v'); +var dynCall_viiiiiii = makeInvalidEarlyAccess('dynCall_viiiiiii'); +var dynCall_iii = makeInvalidEarlyAccess('dynCall_iii'); +var dynCall_vfi = makeInvalidEarlyAccess('dynCall_vfi'); +var dynCall_viif = makeInvalidEarlyAccess('dynCall_viif'); +var dynCall_vif = makeInvalidEarlyAccess('dynCall_vif'); +var dynCall_vifff = makeInvalidEarlyAccess('dynCall_vifff'); +var dynCall_viffff = makeInvalidEarlyAccess('dynCall_viffff'); +var dynCall_vfff = makeInvalidEarlyAccess('dynCall_vfff'); +var dynCall_jiji = makeInvalidEarlyAccess('dynCall_jiji'); +var dynCall_iidiiiii = makeInvalidEarlyAccess('dynCall_iidiiiii'); +var _asyncify_start_unwind = makeInvalidEarlyAccess('_asyncify_start_unwind'); +var _asyncify_stop_unwind = makeInvalidEarlyAccess('_asyncify_stop_unwind'); +var _asyncify_start_rewind = makeInvalidEarlyAccess('_asyncify_start_rewind'); +var _asyncify_stop_rewind = makeInvalidEarlyAccess('_asyncify_stop_rewind'); +var memory = makeInvalidEarlyAccess('memory'); +var __indirect_function_table = makeInvalidEarlyAccess('__indirect_function_table'); +var wasmMemory = makeInvalidEarlyAccess('wasmMemory'); + +function assignWasmExports(wasmExports) { + assert(typeof wasmExports['main'] != 'undefined', 'missing Wasm export: main'); + assert(typeof wasmExports['malloc'] != 'undefined', 'missing Wasm export: malloc'); + assert(typeof wasmExports['free'] != 'undefined', 'missing Wasm export: free'); + assert(typeof wasmExports['fflush'] != 'undefined', 'missing Wasm export: fflush'); + assert(typeof wasmExports['emscripten_stack_get_end'] != 'undefined', 'missing Wasm export: emscripten_stack_get_end'); + assert(typeof wasmExports['emscripten_stack_get_base'] != 'undefined', 'missing Wasm export: emscripten_stack_get_base'); + assert(typeof wasmExports['strerror'] != 'undefined', 'missing Wasm export: strerror'); + assert(typeof wasmExports['emscripten_stack_init'] != 'undefined', 'missing Wasm export: emscripten_stack_init'); + assert(typeof wasmExports['emscripten_stack_get_free'] != 'undefined', 'missing Wasm export: emscripten_stack_get_free'); + assert(typeof wasmExports['_emscripten_stack_restore'] != 'undefined', 'missing Wasm export: _emscripten_stack_restore'); + assert(typeof wasmExports['_emscripten_stack_alloc'] != 'undefined', 'missing Wasm export: _emscripten_stack_alloc'); + assert(typeof wasmExports['emscripten_stack_get_current'] != 'undefined', 'missing Wasm export: emscripten_stack_get_current'); + assert(typeof wasmExports['dynCall_vii'] != 'undefined', 'missing Wasm export: dynCall_vii'); + assert(typeof wasmExports['dynCall_viii'] != 'undefined', 'missing Wasm export: dynCall_viii'); + assert(typeof wasmExports['dynCall_viff'] != 'undefined', 'missing Wasm export: dynCall_viff'); + assert(typeof wasmExports['dynCall_viiiii'] != 'undefined', 'missing Wasm export: dynCall_viiiii'); + assert(typeof wasmExports['dynCall_viiii'] != 'undefined', 'missing Wasm export: dynCall_viiii'); + assert(typeof wasmExports['dynCall_vidd'] != 'undefined', 'missing Wasm export: dynCall_vidd'); + assert(typeof wasmExports['dynCall_ii'] != 'undefined', 'missing Wasm export: dynCall_ii'); + assert(typeof wasmExports['dynCall_iiii'] != 'undefined', 'missing Wasm export: dynCall_iiii'); + assert(typeof wasmExports['dynCall_viiiiii'] != 'undefined', 'missing Wasm export: dynCall_viiiiii'); + assert(typeof wasmExports['dynCall_iiiiii'] != 'undefined', 'missing Wasm export: dynCall_iiiiii'); + assert(typeof wasmExports['dynCall_vi'] != 'undefined', 'missing Wasm export: dynCall_vi'); + assert(typeof wasmExports['dynCall_vffff'] != 'undefined', 'missing Wasm export: dynCall_vffff'); + assert(typeof wasmExports['dynCall_vf'] != 'undefined', 'missing Wasm export: dynCall_vf'); + assert(typeof wasmExports['dynCall_viiiiiiii'] != 'undefined', 'missing Wasm export: dynCall_viiiiiiii'); + assert(typeof wasmExports['dynCall_viiiiiiiii'] != 'undefined', 'missing Wasm export: dynCall_viiiiiiiii'); + assert(typeof wasmExports['dynCall_i'] != 'undefined', 'missing Wasm export: dynCall_i'); + assert(typeof wasmExports['dynCall_vff'] != 'undefined', 'missing Wasm export: dynCall_vff'); + assert(typeof wasmExports['dynCall_v'] != 'undefined', 'missing Wasm export: dynCall_v'); + assert(typeof wasmExports['dynCall_viiiiiii'] != 'undefined', 'missing Wasm export: dynCall_viiiiiii'); + assert(typeof wasmExports['dynCall_iii'] != 'undefined', 'missing Wasm export: dynCall_iii'); + assert(typeof wasmExports['dynCall_vfi'] != 'undefined', 'missing Wasm export: dynCall_vfi'); + assert(typeof wasmExports['dynCall_viif'] != 'undefined', 'missing Wasm export: dynCall_viif'); + assert(typeof wasmExports['dynCall_vif'] != 'undefined', 'missing Wasm export: dynCall_vif'); + assert(typeof wasmExports['dynCall_vifff'] != 'undefined', 'missing Wasm export: dynCall_vifff'); + assert(typeof wasmExports['dynCall_viffff'] != 'undefined', 'missing Wasm export: dynCall_viffff'); + assert(typeof wasmExports['dynCall_vfff'] != 'undefined', 'missing Wasm export: dynCall_vfff'); + assert(typeof wasmExports['dynCall_jiji'] != 'undefined', 'missing Wasm export: dynCall_jiji'); + assert(typeof wasmExports['dynCall_iidiiiii'] != 'undefined', 'missing Wasm export: dynCall_iidiiiii'); + assert(typeof wasmExports['asyncify_start_unwind'] != 'undefined', 'missing Wasm export: asyncify_start_unwind'); + assert(typeof wasmExports['asyncify_stop_unwind'] != 'undefined', 'missing Wasm export: asyncify_stop_unwind'); + assert(typeof wasmExports['asyncify_start_rewind'] != 'undefined', 'missing Wasm export: asyncify_start_rewind'); + assert(typeof wasmExports['asyncify_stop_rewind'] != 'undefined', 'missing Wasm export: asyncify_stop_rewind'); + assert(typeof wasmExports['memory'] != 'undefined', 'missing Wasm export: memory'); + assert(typeof wasmExports['__indirect_function_table'] != 'undefined', 'missing Wasm export: __indirect_function_table'); + _main = Module['_main'] = createExportWrapper('main', wasmExports['main'], 2); + _malloc = createExportWrapper('malloc', wasmExports['malloc'], 1); + _free = createExportWrapper('free', wasmExports['free'], 1); + _fflush = createExportWrapper('fflush', wasmExports['fflush'], 1); + _emscripten_stack_get_end = wasmExports['emscripten_stack_get_end']; + _emscripten_stack_get_base = wasmExports['emscripten_stack_get_base']; + _strerror = createExportWrapper('strerror', wasmExports['strerror'], 1); + _emscripten_stack_init = wasmExports['emscripten_stack_init']; + _emscripten_stack_get_free = wasmExports['emscripten_stack_get_free']; + __emscripten_stack_restore = wasmExports['_emscripten_stack_restore']; + __emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc']; + _emscripten_stack_get_current = wasmExports['emscripten_stack_get_current']; + dynCall_vii = dynCalls['vii'] = createExportWrapper('dynCall_vii', wasmExports['dynCall_vii'], 3); + dynCall_viii = dynCalls['viii'] = createExportWrapper('dynCall_viii', wasmExports['dynCall_viii'], 4); + dynCall_viff = dynCalls['viff'] = createExportWrapper('dynCall_viff', wasmExports['dynCall_viff'], 4); + dynCall_viiiii = dynCalls['viiiii'] = createExportWrapper('dynCall_viiiii', wasmExports['dynCall_viiiii'], 6); + dynCall_viiii = dynCalls['viiii'] = createExportWrapper('dynCall_viiii', wasmExports['dynCall_viiii'], 5); + dynCall_vidd = dynCalls['vidd'] = createExportWrapper('dynCall_vidd', wasmExports['dynCall_vidd'], 4); + dynCall_ii = dynCalls['ii'] = createExportWrapper('dynCall_ii', wasmExports['dynCall_ii'], 2); + dynCall_iiii = dynCalls['iiii'] = createExportWrapper('dynCall_iiii', wasmExports['dynCall_iiii'], 4); + dynCall_viiiiii = dynCalls['viiiiii'] = createExportWrapper('dynCall_viiiiii', wasmExports['dynCall_viiiiii'], 7); + dynCall_iiiiii = dynCalls['iiiiii'] = createExportWrapper('dynCall_iiiiii', wasmExports['dynCall_iiiiii'], 6); + dynCall_vi = dynCalls['vi'] = createExportWrapper('dynCall_vi', wasmExports['dynCall_vi'], 2); + dynCall_vffff = dynCalls['vffff'] = createExportWrapper('dynCall_vffff', wasmExports['dynCall_vffff'], 5); + dynCall_vf = dynCalls['vf'] = createExportWrapper('dynCall_vf', wasmExports['dynCall_vf'], 2); + dynCall_viiiiiiii = dynCalls['viiiiiiii'] = createExportWrapper('dynCall_viiiiiiii', wasmExports['dynCall_viiiiiiii'], 9); + dynCall_viiiiiiiii = dynCalls['viiiiiiiii'] = createExportWrapper('dynCall_viiiiiiiii', wasmExports['dynCall_viiiiiiiii'], 10); + dynCall_i = dynCalls['i'] = createExportWrapper('dynCall_i', wasmExports['dynCall_i'], 1); + dynCall_vff = dynCalls['vff'] = createExportWrapper('dynCall_vff', wasmExports['dynCall_vff'], 3); + dynCall_v = dynCalls['v'] = createExportWrapper('dynCall_v', wasmExports['dynCall_v'], 1); + dynCall_viiiiiii = dynCalls['viiiiiii'] = createExportWrapper('dynCall_viiiiiii', wasmExports['dynCall_viiiiiii'], 8); + dynCall_iii = dynCalls['iii'] = createExportWrapper('dynCall_iii', wasmExports['dynCall_iii'], 3); + dynCall_vfi = dynCalls['vfi'] = createExportWrapper('dynCall_vfi', wasmExports['dynCall_vfi'], 3); + dynCall_viif = dynCalls['viif'] = createExportWrapper('dynCall_viif', wasmExports['dynCall_viif'], 4); + dynCall_vif = dynCalls['vif'] = createExportWrapper('dynCall_vif', wasmExports['dynCall_vif'], 3); + dynCall_vifff = dynCalls['vifff'] = createExportWrapper('dynCall_vifff', wasmExports['dynCall_vifff'], 5); + dynCall_viffff = dynCalls['viffff'] = createExportWrapper('dynCall_viffff', wasmExports['dynCall_viffff'], 6); + dynCall_vfff = dynCalls['vfff'] = createExportWrapper('dynCall_vfff', wasmExports['dynCall_vfff'], 4); + dynCall_jiji = dynCalls['jiji'] = createExportWrapper('dynCall_jiji', wasmExports['dynCall_jiji'], 4); + dynCall_iidiiiii = dynCalls['iidiiiii'] = createExportWrapper('dynCall_iidiiiii', wasmExports['dynCall_iidiiiii'], 8); + _asyncify_start_unwind = createExportWrapper('asyncify_start_unwind', wasmExports['asyncify_start_unwind'], 1); + _asyncify_stop_unwind = createExportWrapper('asyncify_stop_unwind', wasmExports['asyncify_stop_unwind'], 0); + _asyncify_start_rewind = createExportWrapper('asyncify_start_rewind', wasmExports['asyncify_start_rewind'], 1); + _asyncify_stop_rewind = createExportWrapper('asyncify_stop_rewind', wasmExports['asyncify_stop_rewind'], 0); + memory = wasmMemory = wasmExports['memory']; + __indirect_function_table = wasmExports['__indirect_function_table']; +} + +var wasmImports = { + /** @export */ + __assert_fail: ___assert_fail, + /** @export */ + __syscall_faccessat: ___syscall_faccessat, + /** @export */ + __syscall_fcntl64: ___syscall_fcntl64, + /** @export */ + __syscall_getcwd: ___syscall_getcwd, + /** @export */ + __syscall_ioctl: ___syscall_ioctl, + /** @export */ + __syscall_openat: ___syscall_openat, + /** @export */ + _abort_js: __abort_js, + /** @export */ + clock_time_get: _clock_time_get, + /** @export */ + emscripten_asm_const_int: _emscripten_asm_const_int, + /** @export */ + emscripten_date_now: _emscripten_date_now, + /** @export */ + emscripten_get_element_css_size: _emscripten_get_element_css_size, + /** @export */ + emscripten_get_gamepad_status: _emscripten_get_gamepad_status, + /** @export */ + emscripten_get_now: _emscripten_get_now, + /** @export */ + emscripten_get_num_gamepads: _emscripten_get_num_gamepads, + /** @export */ + emscripten_glActiveTexture: _emscripten_glActiveTexture, + /** @export */ + emscripten_glAttachShader: _emscripten_glAttachShader, + /** @export */ + emscripten_glBeginQueryEXT: _emscripten_glBeginQueryEXT, + /** @export */ + emscripten_glBindAttribLocation: _emscripten_glBindAttribLocation, + /** @export */ + emscripten_glBindBuffer: _emscripten_glBindBuffer, + /** @export */ + emscripten_glBindFramebuffer: _emscripten_glBindFramebuffer, + /** @export */ + emscripten_glBindRenderbuffer: _emscripten_glBindRenderbuffer, + /** @export */ + emscripten_glBindTexture: _emscripten_glBindTexture, + /** @export */ + emscripten_glBindVertexArrayOES: _emscripten_glBindVertexArrayOES, + /** @export */ + emscripten_glBlendColor: _emscripten_glBlendColor, + /** @export */ + emscripten_glBlendEquation: _emscripten_glBlendEquation, + /** @export */ + emscripten_glBlendEquationSeparate: _emscripten_glBlendEquationSeparate, + /** @export */ + emscripten_glBlendFunc: _emscripten_glBlendFunc, + /** @export */ + emscripten_glBlendFuncSeparate: _emscripten_glBlendFuncSeparate, + /** @export */ + emscripten_glBufferData: _emscripten_glBufferData, + /** @export */ + emscripten_glBufferSubData: _emscripten_glBufferSubData, + /** @export */ + emscripten_glCheckFramebufferStatus: _emscripten_glCheckFramebufferStatus, + /** @export */ + emscripten_glClear: _emscripten_glClear, + /** @export */ + emscripten_glClearColor: _emscripten_glClearColor, + /** @export */ + emscripten_glClearDepthf: _emscripten_glClearDepthf, + /** @export */ + emscripten_glClearStencil: _emscripten_glClearStencil, + /** @export */ + emscripten_glClipControlEXT: _emscripten_glClipControlEXT, + /** @export */ + emscripten_glColorMask: _emscripten_glColorMask, + /** @export */ + emscripten_glCompileShader: _emscripten_glCompileShader, + /** @export */ + emscripten_glCompressedTexImage2D: _emscripten_glCompressedTexImage2D, + /** @export */ + emscripten_glCompressedTexSubImage2D: _emscripten_glCompressedTexSubImage2D, + /** @export */ + emscripten_glCopyTexImage2D: _emscripten_glCopyTexImage2D, + /** @export */ + emscripten_glCopyTexSubImage2D: _emscripten_glCopyTexSubImage2D, + /** @export */ + emscripten_glCreateProgram: _emscripten_glCreateProgram, + /** @export */ + emscripten_glCreateShader: _emscripten_glCreateShader, + /** @export */ + emscripten_glCullFace: _emscripten_glCullFace, + /** @export */ + emscripten_glDeleteBuffers: _emscripten_glDeleteBuffers, + /** @export */ + emscripten_glDeleteFramebuffers: _emscripten_glDeleteFramebuffers, + /** @export */ + emscripten_glDeleteProgram: _emscripten_glDeleteProgram, + /** @export */ + emscripten_glDeleteQueriesEXT: _emscripten_glDeleteQueriesEXT, + /** @export */ + emscripten_glDeleteRenderbuffers: _emscripten_glDeleteRenderbuffers, + /** @export */ + emscripten_glDeleteShader: _emscripten_glDeleteShader, + /** @export */ + emscripten_glDeleteTextures: _emscripten_glDeleteTextures, + /** @export */ + emscripten_glDeleteVertexArraysOES: _emscripten_glDeleteVertexArraysOES, + /** @export */ + emscripten_glDepthFunc: _emscripten_glDepthFunc, + /** @export */ + emscripten_glDepthMask: _emscripten_glDepthMask, + /** @export */ + emscripten_glDepthRangef: _emscripten_glDepthRangef, + /** @export */ + emscripten_glDetachShader: _emscripten_glDetachShader, + /** @export */ + emscripten_glDisable: _emscripten_glDisable, + /** @export */ + emscripten_glDisableVertexAttribArray: _emscripten_glDisableVertexAttribArray, + /** @export */ + emscripten_glDrawArrays: _emscripten_glDrawArrays, + /** @export */ + emscripten_glDrawArraysInstancedANGLE: _emscripten_glDrawArraysInstancedANGLE, + /** @export */ + emscripten_glDrawBuffersWEBGL: _emscripten_glDrawBuffersWEBGL, + /** @export */ + emscripten_glDrawElements: _emscripten_glDrawElements, + /** @export */ + emscripten_glDrawElementsInstancedANGLE: _emscripten_glDrawElementsInstancedANGLE, + /** @export */ + emscripten_glEnable: _emscripten_glEnable, + /** @export */ + emscripten_glEnableVertexAttribArray: _emscripten_glEnableVertexAttribArray, + /** @export */ + emscripten_glEndQueryEXT: _emscripten_glEndQueryEXT, + /** @export */ + emscripten_glFinish: _emscripten_glFinish, + /** @export */ + emscripten_glFlush: _emscripten_glFlush, + /** @export */ + emscripten_glFramebufferRenderbuffer: _emscripten_glFramebufferRenderbuffer, + /** @export */ + emscripten_glFramebufferTexture2D: _emscripten_glFramebufferTexture2D, + /** @export */ + emscripten_glFrontFace: _emscripten_glFrontFace, + /** @export */ + emscripten_glGenBuffers: _emscripten_glGenBuffers, + /** @export */ + emscripten_glGenFramebuffers: _emscripten_glGenFramebuffers, + /** @export */ + emscripten_glGenQueriesEXT: _emscripten_glGenQueriesEXT, + /** @export */ + emscripten_glGenRenderbuffers: _emscripten_glGenRenderbuffers, + /** @export */ + emscripten_glGenTextures: _emscripten_glGenTextures, + /** @export */ + emscripten_glGenVertexArraysOES: _emscripten_glGenVertexArraysOES, + /** @export */ + emscripten_glGenerateMipmap: _emscripten_glGenerateMipmap, + /** @export */ + emscripten_glGetActiveAttrib: _emscripten_glGetActiveAttrib, + /** @export */ + emscripten_glGetActiveUniform: _emscripten_glGetActiveUniform, + /** @export */ + emscripten_glGetAttachedShaders: _emscripten_glGetAttachedShaders, + /** @export */ + emscripten_glGetAttribLocation: _emscripten_glGetAttribLocation, + /** @export */ + emscripten_glGetBooleanv: _emscripten_glGetBooleanv, + /** @export */ + emscripten_glGetBufferParameteriv: _emscripten_glGetBufferParameteriv, + /** @export */ + emscripten_glGetError: _emscripten_glGetError, + /** @export */ + emscripten_glGetFloatv: _emscripten_glGetFloatv, + /** @export */ + emscripten_glGetFramebufferAttachmentParameteriv: _emscripten_glGetFramebufferAttachmentParameteriv, + /** @export */ + emscripten_glGetIntegerv: _emscripten_glGetIntegerv, + /** @export */ + emscripten_glGetProgramInfoLog: _emscripten_glGetProgramInfoLog, + /** @export */ + emscripten_glGetProgramiv: _emscripten_glGetProgramiv, + /** @export */ + emscripten_glGetQueryObjecti64vEXT: _emscripten_glGetQueryObjecti64vEXT, + /** @export */ + emscripten_glGetQueryObjectivEXT: _emscripten_glGetQueryObjectivEXT, + /** @export */ + emscripten_glGetQueryObjectui64vEXT: _emscripten_glGetQueryObjectui64vEXT, + /** @export */ + emscripten_glGetQueryObjectuivEXT: _emscripten_glGetQueryObjectuivEXT, + /** @export */ + emscripten_glGetQueryivEXT: _emscripten_glGetQueryivEXT, + /** @export */ + emscripten_glGetRenderbufferParameteriv: _emscripten_glGetRenderbufferParameteriv, + /** @export */ + emscripten_glGetShaderInfoLog: _emscripten_glGetShaderInfoLog, + /** @export */ + emscripten_glGetShaderPrecisionFormat: _emscripten_glGetShaderPrecisionFormat, + /** @export */ + emscripten_glGetShaderSource: _emscripten_glGetShaderSource, + /** @export */ + emscripten_glGetShaderiv: _emscripten_glGetShaderiv, + /** @export */ + emscripten_glGetString: _emscripten_glGetString, + /** @export */ + emscripten_glGetTexParameterfv: _emscripten_glGetTexParameterfv, + /** @export */ + emscripten_glGetTexParameteriv: _emscripten_glGetTexParameteriv, + /** @export */ + emscripten_glGetUniformLocation: _emscripten_glGetUniformLocation, + /** @export */ + emscripten_glGetUniformfv: _emscripten_glGetUniformfv, + /** @export */ + emscripten_glGetUniformiv: _emscripten_glGetUniformiv, + /** @export */ + emscripten_glGetVertexAttribPointerv: _emscripten_glGetVertexAttribPointerv, + /** @export */ + emscripten_glGetVertexAttribfv: _emscripten_glGetVertexAttribfv, + /** @export */ + emscripten_glGetVertexAttribiv: _emscripten_glGetVertexAttribiv, + /** @export */ + emscripten_glHint: _emscripten_glHint, + /** @export */ + emscripten_glIsBuffer: _emscripten_glIsBuffer, + /** @export */ + emscripten_glIsEnabled: _emscripten_glIsEnabled, + /** @export */ + emscripten_glIsFramebuffer: _emscripten_glIsFramebuffer, + /** @export */ + emscripten_glIsProgram: _emscripten_glIsProgram, + /** @export */ + emscripten_glIsQueryEXT: _emscripten_glIsQueryEXT, + /** @export */ + emscripten_glIsRenderbuffer: _emscripten_glIsRenderbuffer, + /** @export */ + emscripten_glIsShader: _emscripten_glIsShader, + /** @export */ + emscripten_glIsTexture: _emscripten_glIsTexture, + /** @export */ + emscripten_glIsVertexArrayOES: _emscripten_glIsVertexArrayOES, + /** @export */ + emscripten_glLineWidth: _emscripten_glLineWidth, + /** @export */ + emscripten_glLinkProgram: _emscripten_glLinkProgram, + /** @export */ + emscripten_glPixelStorei: _emscripten_glPixelStorei, + /** @export */ + emscripten_glPolygonModeWEBGL: _emscripten_glPolygonModeWEBGL, + /** @export */ + emscripten_glPolygonOffset: _emscripten_glPolygonOffset, + /** @export */ + emscripten_glPolygonOffsetClampEXT: _emscripten_glPolygonOffsetClampEXT, + /** @export */ + emscripten_glQueryCounterEXT: _emscripten_glQueryCounterEXT, + /** @export */ + emscripten_glReadPixels: _emscripten_glReadPixels, + /** @export */ + emscripten_glReleaseShaderCompiler: _emscripten_glReleaseShaderCompiler, + /** @export */ + emscripten_glRenderbufferStorage: _emscripten_glRenderbufferStorage, + /** @export */ + emscripten_glSampleCoverage: _emscripten_glSampleCoverage, + /** @export */ + emscripten_glScissor: _emscripten_glScissor, + /** @export */ + emscripten_glShaderBinary: _emscripten_glShaderBinary, + /** @export */ + emscripten_glShaderSource: _emscripten_glShaderSource, + /** @export */ + emscripten_glStencilFunc: _emscripten_glStencilFunc, + /** @export */ + emscripten_glStencilFuncSeparate: _emscripten_glStencilFuncSeparate, + /** @export */ + emscripten_glStencilMask: _emscripten_glStencilMask, + /** @export */ + emscripten_glStencilMaskSeparate: _emscripten_glStencilMaskSeparate, + /** @export */ + emscripten_glStencilOp: _emscripten_glStencilOp, + /** @export */ + emscripten_glStencilOpSeparate: _emscripten_glStencilOpSeparate, + /** @export */ + emscripten_glTexImage2D: _emscripten_glTexImage2D, + /** @export */ + emscripten_glTexParameterf: _emscripten_glTexParameterf, + /** @export */ + emscripten_glTexParameterfv: _emscripten_glTexParameterfv, + /** @export */ + emscripten_glTexParameteri: _emscripten_glTexParameteri, + /** @export */ + emscripten_glTexParameteriv: _emscripten_glTexParameteriv, + /** @export */ + emscripten_glTexSubImage2D: _emscripten_glTexSubImage2D, + /** @export */ + emscripten_glUniform1f: _emscripten_glUniform1f, + /** @export */ + emscripten_glUniform1fv: _emscripten_glUniform1fv, + /** @export */ + emscripten_glUniform1i: _emscripten_glUniform1i, + /** @export */ + emscripten_glUniform1iv: _emscripten_glUniform1iv, + /** @export */ + emscripten_glUniform2f: _emscripten_glUniform2f, + /** @export */ + emscripten_glUniform2fv: _emscripten_glUniform2fv, + /** @export */ + emscripten_glUniform2i: _emscripten_glUniform2i, + /** @export */ + emscripten_glUniform2iv: _emscripten_glUniform2iv, + /** @export */ + emscripten_glUniform3f: _emscripten_glUniform3f, + /** @export */ + emscripten_glUniform3fv: _emscripten_glUniform3fv, + /** @export */ + emscripten_glUniform3i: _emscripten_glUniform3i, + /** @export */ + emscripten_glUniform3iv: _emscripten_glUniform3iv, + /** @export */ + emscripten_glUniform4f: _emscripten_glUniform4f, + /** @export */ + emscripten_glUniform4fv: _emscripten_glUniform4fv, + /** @export */ + emscripten_glUniform4i: _emscripten_glUniform4i, + /** @export */ + emscripten_glUniform4iv: _emscripten_glUniform4iv, + /** @export */ + emscripten_glUniformMatrix2fv: _emscripten_glUniformMatrix2fv, + /** @export */ + emscripten_glUniformMatrix3fv: _emscripten_glUniformMatrix3fv, + /** @export */ + emscripten_glUniformMatrix4fv: _emscripten_glUniformMatrix4fv, + /** @export */ + emscripten_glUseProgram: _emscripten_glUseProgram, + /** @export */ + emscripten_glValidateProgram: _emscripten_glValidateProgram, + /** @export */ + emscripten_glVertexAttrib1f: _emscripten_glVertexAttrib1f, + /** @export */ + emscripten_glVertexAttrib1fv: _emscripten_glVertexAttrib1fv, + /** @export */ + emscripten_glVertexAttrib2f: _emscripten_glVertexAttrib2f, + /** @export */ + emscripten_glVertexAttrib2fv: _emscripten_glVertexAttrib2fv, + /** @export */ + emscripten_glVertexAttrib3f: _emscripten_glVertexAttrib3f, + /** @export */ + emscripten_glVertexAttrib3fv: _emscripten_glVertexAttrib3fv, + /** @export */ + emscripten_glVertexAttrib4f: _emscripten_glVertexAttrib4f, + /** @export */ + emscripten_glVertexAttrib4fv: _emscripten_glVertexAttrib4fv, + /** @export */ + emscripten_glVertexAttribDivisorANGLE: _emscripten_glVertexAttribDivisorANGLE, + /** @export */ + emscripten_glVertexAttribPointer: _emscripten_glVertexAttribPointer, + /** @export */ + emscripten_glViewport: _emscripten_glViewport, + /** @export */ + emscripten_resize_heap: _emscripten_resize_heap, + /** @export */ + emscripten_sample_gamepad_data: _emscripten_sample_gamepad_data, + /** @export */ + emscripten_set_canvas_element_size: _emscripten_set_canvas_element_size, + /** @export */ + emscripten_set_click_callback_on_thread: _emscripten_set_click_callback_on_thread, + /** @export */ + emscripten_set_fullscreenchange_callback_on_thread: _emscripten_set_fullscreenchange_callback_on_thread, + /** @export */ + emscripten_set_gamepadconnected_callback_on_thread: _emscripten_set_gamepadconnected_callback_on_thread, + /** @export */ + emscripten_set_gamepaddisconnected_callback_on_thread: _emscripten_set_gamepaddisconnected_callback_on_thread, + /** @export */ + emscripten_set_mousemove_callback_on_thread: _emscripten_set_mousemove_callback_on_thread, + /** @export */ + emscripten_set_pointerlockchange_callback_on_thread: _emscripten_set_pointerlockchange_callback_on_thread, + /** @export */ + emscripten_set_resize_callback_on_thread: _emscripten_set_resize_callback_on_thread, + /** @export */ + emscripten_set_touchcancel_callback_on_thread: _emscripten_set_touchcancel_callback_on_thread, + /** @export */ + emscripten_set_touchend_callback_on_thread: _emscripten_set_touchend_callback_on_thread, + /** @export */ + emscripten_set_touchmove_callback_on_thread: _emscripten_set_touchmove_callback_on_thread, + /** @export */ + emscripten_set_touchstart_callback_on_thread: _emscripten_set_touchstart_callback_on_thread, + /** @export */ + emscripten_set_window_title: _emscripten_set_window_title, + /** @export */ + emscripten_sleep: _emscripten_sleep, + /** @export */ + exit: _exit, + /** @export */ + fd_close: _fd_close, + /** @export */ + fd_read: _fd_read, + /** @export */ + fd_seek: _fd_seek, + /** @export */ + fd_write: _fd_write, + /** @export */ + glActiveTexture: _glActiveTexture, + /** @export */ + glAttachShader: _glAttachShader, + /** @export */ + glBindAttribLocation: _glBindAttribLocation, + /** @export */ + glBindBuffer: _glBindBuffer, + /** @export */ + glBindTexture: _glBindTexture, + /** @export */ + glBlendFunc: _glBlendFunc, + /** @export */ + glBufferData: _glBufferData, + /** @export */ + glBufferSubData: _glBufferSubData, + /** @export */ + glClear: _glClear, + /** @export */ + glClearColor: _glClearColor, + /** @export */ + glClearDepthf: _glClearDepthf, + /** @export */ + glCompileShader: _glCompileShader, + /** @export */ + glCompressedTexImage2D: _glCompressedTexImage2D, + /** @export */ + glCreateProgram: _glCreateProgram, + /** @export */ + glCreateShader: _glCreateShader, + /** @export */ + glCullFace: _glCullFace, + /** @export */ + glDeleteBuffers: _glDeleteBuffers, + /** @export */ + glDeleteProgram: _glDeleteProgram, + /** @export */ + glDeleteShader: _glDeleteShader, + /** @export */ + glDeleteTextures: _glDeleteTextures, + /** @export */ + glDepthFunc: _glDepthFunc, + /** @export */ + glDetachShader: _glDetachShader, + /** @export */ + glDisable: _glDisable, + /** @export */ + glDisableVertexAttribArray: _glDisableVertexAttribArray, + /** @export */ + glDrawArrays: _glDrawArrays, + /** @export */ + glDrawElements: _glDrawElements, + /** @export */ + glEnable: _glEnable, + /** @export */ + glEnableVertexAttribArray: _glEnableVertexAttribArray, + /** @export */ + glFrontFace: _glFrontFace, + /** @export */ + glGenBuffers: _glGenBuffers, + /** @export */ + glGenTextures: _glGenTextures, + /** @export */ + glGetAttribLocation: _glGetAttribLocation, + /** @export */ + glGetFloatv: _glGetFloatv, + /** @export */ + glGetProgramInfoLog: _glGetProgramInfoLog, + /** @export */ + glGetProgramiv: _glGetProgramiv, + /** @export */ + glGetShaderInfoLog: _glGetShaderInfoLog, + /** @export */ + glGetShaderiv: _glGetShaderiv, + /** @export */ + glGetString: _glGetString, + /** @export */ + glGetUniformLocation: _glGetUniformLocation, + /** @export */ + glLinkProgram: _glLinkProgram, + /** @export */ + glPixelStorei: _glPixelStorei, + /** @export */ + glReadPixels: _glReadPixels, + /** @export */ + glShaderSource: _glShaderSource, + /** @export */ + glTexImage2D: _glTexImage2D, + /** @export */ + glTexParameteri: _glTexParameteri, + /** @export */ + glUniform1i: _glUniform1i, + /** @export */ + glUniform4f: _glUniform4f, + /** @export */ + glUniformMatrix4fv: _glUniformMatrix4fv, + /** @export */ + glUseProgram: _glUseProgram, + /** @export */ + glVertexAttribPointer: _glVertexAttribPointer, + /** @export */ + glViewport: _glViewport, + /** @export */ + glfwCreateWindow: _glfwCreateWindow, + /** @export */ + glfwDefaultWindowHints: _glfwDefaultWindowHints, + /** @export */ + glfwDestroyWindow: _glfwDestroyWindow, + /** @export */ + glfwGetPrimaryMonitor: _glfwGetPrimaryMonitor, + /** @export */ + glfwGetTime: _glfwGetTime, + /** @export */ + glfwGetVideoModes: _glfwGetVideoModes, + /** @export */ + glfwInit: _glfwInit, + /** @export */ + glfwMakeContextCurrent: _glfwMakeContextCurrent, + /** @export */ + glfwSetCharCallback: _glfwSetCharCallback, + /** @export */ + glfwSetCursorEnterCallback: _glfwSetCursorEnterCallback, + /** @export */ + glfwSetCursorPosCallback: _glfwSetCursorPosCallback, + /** @export */ + glfwSetDropCallback: _glfwSetDropCallback, + /** @export */ + glfwSetErrorCallback: _glfwSetErrorCallback, + /** @export */ + glfwSetKeyCallback: _glfwSetKeyCallback, + /** @export */ + glfwSetMouseButtonCallback: _glfwSetMouseButtonCallback, + /** @export */ + glfwSetScrollCallback: _glfwSetScrollCallback, + /** @export */ + glfwSetWindowContentScaleCallback: _glfwSetWindowContentScaleCallback, + /** @export */ + glfwSetWindowFocusCallback: _glfwSetWindowFocusCallback, + /** @export */ + glfwSetWindowIconifyCallback: _glfwSetWindowIconifyCallback, + /** @export */ + glfwSetWindowShouldClose: _glfwSetWindowShouldClose, + /** @export */ + glfwSetWindowSizeCallback: _glfwSetWindowSizeCallback, + /** @export */ + glfwSwapBuffers: _glfwSwapBuffers, + /** @export */ + glfwTerminate: _glfwTerminate, + /** @export */ + glfwWindowHint: _glfwWindowHint +}; + + +// include: postamble.js +// === Auto-generated postamble setup entry stuff === + +var calledRun; + +function callMain() { + assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])'); + assert(typeof onPreRuns === 'undefined' || onPreRuns.length == 0, 'cannot call main when preRun functions remain to be called'); + + var entryFunction = _main; + + var argc = 0; + var argv = 0; + + try { + + var ret = entryFunction(argc, argv); + + // if we're not running an evented main loop, it's time to exit + exitJS(ret, /* implicit = */ true); + return ret; + } catch (e) { + return handleException(e); + } +} + +function stackCheckInit() { + // This is normally called automatically during __wasm_call_ctors but need to + // get these values before even running any of the ctors so we call it redundantly + // here. + _emscripten_stack_init(); + // TODO(sbc): Move writeStackCookie to native to to avoid this. + writeStackCookie(); +} + +async function run() { + assert(!calledRun); + calledRun = true; + + stackCheckInit(); + + preRun(); + + if (runDependencies) { + await resolveRunDependencies(); + } + + var setStatus = Module['setStatus']; + if (setStatus) { + setStatus('Running...'); + // Yield to the event loop to allow the browser to paint "Running..." + await new Promise((resolve) => setTimeout(resolve, 1)); + // Then we want to clear the status text, but only after the rest of this function runs. + setTimeout(setStatus, 1, ''); + } + + if (ABORT) return; + + initRuntime(); + + // No ATMAINS hooks + + Module['onRuntimeInitialized']?.(); + consumedModuleProp('onRuntimeInitialized'); + + var noInitialRun = Module['noInitialRun'] || false; + if (!noInitialRun) callMain(); + + postRun(); +} + +function checkUnflushedContent() { + // Compiler settings do not allow exiting the runtime, so flushing + // the streams is not possible. but in ASSERTIONS mode we check + // if there was something to flush, and if so tell the user they + // should request that the runtime be exitable. + // Normally we would not even include flush() at all, but in ASSERTIONS + // builds we do so just for this check, and here we see if there is any + // content to flush, that is, we check if there would have been + // something a non-ASSERTIONS build would have not seen. + // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0 + // mode (which has its own special function for this; otherwise, all + // the code is inside libc) + var oldOut = out; + var oldErr = err; + var has = false; + out = err = (x) => { + has = true; + } + try { // it doesn't matter if it fails + _fflush(0); + // also flush in the JS FS layer + for (var name of ['stdout', 'stderr']) { + var info = FS.analyzePath('/dev/' + name); + if (!info) return; + var stream = info.object; + var rdev = stream.rdev; + var tty = TTY.ttys[rdev]; + if (tty?.output?.length) { + has = true; + } + } + } catch(e) {} + out = oldOut; + err = oldErr; + if (has) { + warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the Emscripten FAQ), or make sure to emit a newline when you printf etc.'); + } +} + +var wasmExports; + +// With async instantation wasmExports is assigned asynchronously when the +// instance is received. +createWasm().then(() => run()); + +// end include: postamble.js + diff --git a/dev/spacegame/index.wasm b/dev/spacegame/index.wasm new file mode 100755 index 0000000000000000000000000000000000000000..18b1b41a7a8ee78cfe34846edc18454e8cacc23f GIT binary patch literal 541105 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 z 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 literal 0 HcmV?d00001

lw9}G88+(H$ikVPgU#!sowy) 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 W;M+5tIOA)!ZlF+ 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