diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
index 15d09343b05035..f6cdff8b24e98b 100644
--- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
+++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
@@ -217,6 +217,7 @@
+
diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile
index 7d48a7e6f98aa8..c4aebc3327c48a 100644
--- a/src/mono/wasm/Makefile
+++ b/src/mono/wasm/Makefile
@@ -101,7 +101,7 @@ $(NATIVE_BIN_DIR)/include/wasm:
$(BUILDS_OBJ_DIR):
mkdir -p $$@
-$(NATIVE_BIN_DIR)/dotnet.js: runtime/library_mono.js runtime/binding_support.js runtime/dotnet_support.js $(SYSTEM_NATIVE_LIBDIR)/pal_random.js $(2) $(EMCC_DEFAULT_RSP) | $(NATIVE_BIN_DIR)
+$(NATIVE_BIN_DIR)/dotnet.js: $(NATIVE_BIN_DIR)/src/runtime.iffe.js runtime/library_mono.js runtime/binding_support.js runtime/dotnet_support.js $(SYSTEM_NATIVE_LIBDIR)/pal_random.js $(2) $(EMCC_DEFAULT_RSP) | $(NATIVE_BIN_DIR)
$(DOTNET) build $(CURDIR)/wasm.proj _MSBUILD_WASM_BUILD_ARGS /t:BuildWasmRuntimes
$(EMCC_DEFAULT_RSP): $(CURDIR)/wasm.proj | $(NATIVE_BIN_DIR)/src Makefile
diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets
index 19737849bdaeef..e4bb5ffb278368 100644
--- a/src/mono/wasm/build/WasmApp.Native.targets
+++ b/src/mono/wasm/build/WasmApp.Native.targets
@@ -217,7 +217,8 @@
<_WasmRuntimePackSrcFile ObjectFile="$(_WasmIntermediateOutputPath)%(FileName).o" />
- <_DotnetJSSrcFile Include="$(_WasmRuntimePackSrcDir)\*.js" />
+ <_DotnetJSSrcFile Include="$(_WasmRuntimePackSrcDir)\*.js" Exclude="$(_WasmRuntimePackSrcDir)\*.iffe.js"/>
+ <_WasmExtraJSFile Include="$(_WasmRuntimePackSrcDir)\*.iffe.js" Kind="pre-js" />
<_WasmNativeFileForLinking Include="@(NativeFileReference)" />
diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js
index 76c02dfe63f85b..8d8b89bd0bd5a4 100644
--- a/src/mono/wasm/runtime-test.js
+++ b/src/mono/wasm/runtime-test.js
@@ -274,6 +274,7 @@ var Module = {
try {
bytes = read (asset, 'binary');
} catch (exc) {
+ console.log('v8 file read failed ' + asset + ' ' + exc)
error = exc;
}
var response = { ok: (bytes && !error), url: asset,
diff --git a/src/mono/wasm/runtime/.eslintrc.js b/src/mono/wasm/runtime/.eslintrc.js
new file mode 100644
index 00000000000000..2a571451d5dc8e
--- /dev/null
+++ b/src/mono/wasm/runtime/.eslintrc.js
@@ -0,0 +1,38 @@
+module.exports = {
+ 'env': {
+ 'browser': true,
+ 'es2021': true,
+ 'node': true
+ },
+ 'extends': [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended'
+ ],
+ 'parser': '@typescript-eslint/parser',
+ 'parserOptions': {
+ 'ecmaVersion': 12,
+ 'sourceType': 'module'
+ },
+ 'plugins': [
+ '@typescript-eslint'
+ ],
+ 'rules': {
+ 'indent': [
+ 'error',
+ 4,
+ {SwitchCase: 1}
+ ],
+ 'linebreak-style': [
+ 'error',
+ 'windows'
+ ],
+ 'quotes': [
+ 'error',
+ 'single'
+ ],
+ 'semi': [
+ 'error',
+ 'always'
+ ]
+ }
+};
diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt
index ee2cf5f608308e..8e20ff644a19d4 100644
--- a/src/mono/wasm/runtime/CMakeLists.txt
+++ b/src/mono/wasm/runtime/CMakeLists.txt
@@ -21,8 +21,8 @@ target_link_libraries(dotnet
set_target_properties(dotnet PROPERTIES
CMAKE_EXECUTABLE_SUFFIX ".js"
- LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${SOURCE_DIR}/library_mono.js;${SOURCE_DIR}/binding_support.js;${SOURCE_DIR}/dotnet_support.js;${SYSTEM_NATIVE_DIR}/pal_random.js"
- LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp ${CONFIGURATION_EMCC_FLAGS} -DENABLE_NETCORE=1 --js-library ${SOURCE_DIR}/library_mono.js --js-library ${SOURCE_DIR}/binding_support.js --js-library ${SOURCE_DIR}/dotnet_support.js --js-library ${SYSTEM_NATIVE_DIR}/pal_random.js"
+ LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${NATIVE_BIN_DIR}/src/runtime.iffe.js;${SOURCE_DIR}/library_mono.js;${SOURCE_DIR}/binding_support.js;${SOURCE_DIR}/dotnet_support.js;${SYSTEM_NATIVE_DIR}/pal_random.js"
+ LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp ${CONFIGURATION_EMCC_FLAGS} -DENABLE_NETCORE=1 --pre-js ${NATIVE_BIN_DIR}/src/runtime.iffe.js --js-library ${SOURCE_DIR}/library_mono.js --js-library ${SOURCE_DIR}/binding_support.js --js-library ${SOURCE_DIR}/dotnet_support.js --js-library ${SYSTEM_NATIVE_DIR}/pal_random.js"
RUNTIME_OUTPUT_DIRECTORY "${NATIVE_BIN_DIR}")
add_custom_command(TARGET dotnet POST_BUILD COMMAND ${EMSDK_PATH}/upstream/bin/wasm-opt --strip-dwarf ${NATIVE_BIN_DIR}/dotnet.wasm -o ${NATIVE_BIN_DIR}/dotnet.wasm)
diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js
index 2f9fe8a5e19c52..462b042fbe711a 100644
--- a/src/mono/wasm/runtime/library_mono.js
+++ b/src/mono/wasm/runtime/library_mono.js
@@ -3,1552 +3,16 @@
"use strict";
-/**
- * @typedef WasmId
- * @type {object}
- * @property {string} idStr - full object id string
- * @property {string} scheme - eg, object, valuetype, array ..
- * @property {string} value - string part after `dotnet:scheme:` of the id string
- * @property {object} o - value parsed as JSON
- */
-
-/**
- * @typedef WasmRoot - a single address in the managed heap, visible to the GC
- * @type {object}
- * @property {ManagedPointer} value - pointer into the managed heap, stored in the root
- * @property {function} get_address - retrieves address of the root in wasm memory
- * @property {function} get - retrieves pointer value
- * @property {function} set - updates the pointer
- * @property {function} release - releases the root storage for future use
- */
-
-/**
- * @typedef WasmRootBuffer - a collection of addresses in the managed heap, visible to the GC
- * @type {object}
- * @property {number} length - number of elements the root buffer can hold
- * @property {function} get_address - retrieves address of an element in wasm memory, by index
- * @property {function} get - retrieves an element by index
- * @property {function} set - sets an element's value by index
- * @property {function} release - releases the root storage for future use
- */
-
-/**
- * @typedef ManagedPointer
- * @type {number} - address in the managed heap
- */
-
-/**
- * @typedef NativePointer
- * @type {number} - address in wasm memory
- */
-
-/**
- * @typedef Event
- * @type {object}
- * @property {string} eventName - name of the event being raised
- * @property {object} eventArgs - arguments for the event itself
- */
-
-var MonoSupportLib = {
- $MONO__postset: 'MONO.export_functions (Module);',
- $MONO: {
- active_frames: [],
- pump_count: 0,
- timeout_queue: [],
- spread_timers_maximum: 0,
- isChromium: false,
- _vt_stack: [],
- mono_wasm_runtime_is_ready : false,
- mono_wasm_ignore_pdb_load_errors: true,
- num_icu_assets_loaded_successfully: 0,
- _async_method_objectId: 0,
- _next_id_var: 0,
- _next_call_function_res_id: 0,
- _scratch_root_buffer: null,
- _scratch_root_free_indices: null,
- _scratch_root_free_indices_count: 0,
- _scratch_root_free_instances: [],
- _vt_stack: [],
-
- /** @type {object.} */
- _id_table: {},
-
- pump_message: function () {
- if (!MONO.mono_background_exec)
- MONO.mono_background_exec = Module.cwrap ("mono_background_exec", null);
- while (MONO.timeout_queue.length > 0) {
- --MONO.pump_count;
- MONO.timeout_queue.shift()();
- }
- while (MONO.pump_count > 0) {
- --MONO.pump_count;
- MONO.mono_background_exec ();
- }
- },
-
- export_functions: function (module) {
- module ["pump_message"] = MONO.pump_message.bind(MONO);
- module ["prevent_timer_throttling"] = MONO.prevent_timer_throttling.bind(MONO);
- module ["mono_wasm_set_timeout_exec"] = MONO.mono_wasm_set_timeout_exec.bind(MONO);
- module ["mono_load_runtime_and_bcl"] = MONO.mono_load_runtime_and_bcl.bind(MONO);
- module ["mono_load_runtime_and_bcl_args"] = MONO.mono_load_runtime_and_bcl_args.bind(MONO);
- module ["mono_wasm_load_bytes_into_heap"] = MONO.mono_wasm_load_bytes_into_heap.bind(MONO);
- module ["mono_wasm_load_icu_data"] = MONO.mono_wasm_load_icu_data.bind(MONO);
- module ["mono_wasm_get_icudt_name"] = MONO.mono_wasm_get_icudt_name.bind(MONO);
- module ["mono_wasm_globalization_init"] = MONO.mono_wasm_globalization_init.bind(MONO);
- module ["mono_wasm_get_loaded_files"] = MONO.mono_wasm_get_loaded_files.bind(MONO);
- module ["mono_wasm_new_root_buffer"] = MONO.mono_wasm_new_root_buffer.bind(MONO);
- module ["mono_wasm_new_root_buffer_from_pointer"] = MONO.mono_wasm_new_root_buffer_from_pointer.bind(MONO);
- module ["mono_wasm_new_root"] = MONO.mono_wasm_new_root.bind(MONO);
- module ["mono_wasm_new_roots"] = MONO.mono_wasm_new_roots.bind(MONO);
- module ["mono_wasm_release_roots"] = MONO.mono_wasm_release_roots.bind(MONO);
- module ["mono_wasm_load_config"] = MONO.mono_wasm_load_config.bind(MONO);
-
- if (globalThis.navigator) {
- const nav = globalThis.navigator;
- if (nav.userAgentData && nav.userAgentData.brands) {
- MONO.isChromium = nav.userAgentData.brands.some((i) => i.brand == 'Chromium');
- }
- else if (nav.userAgent) {
- MONO.isChromium = nav.userAgent.includes("Chrome");
- }
- }
- },
-
- _base64Converter: {
- // Code from JSIL:
- // https://github.com/sq/JSIL/blob/1d57d5427c87ab92ffa3ca4b82429cd7509796ba/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.Convert.js#L149
- // Thanks to Katelyn Gadd @kg
-
- _base64Table: [
- 'A', 'B', 'C', 'D',
- 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L',
- 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X',
- 'Y', 'Z',
- 'a', 'b', 'c', 'd',
- 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x',
- 'y', 'z',
- '0', '1', '2', '3',
- '4', '5', '6', '7',
- '8', '9',
- '+', '/'
- ],
-
- _makeByteReader: function (bytes, index, count) {
- var position = (typeof (index) === "number") ? index : 0;
- var endpoint;
-
- if (typeof (count) === "number")
- endpoint = (position + count);
- else
- endpoint = (bytes.length - position);
-
- var result = {
- read: function () {
- if (position >= endpoint)
- return false;
-
- var nextByte = bytes[position];
- position += 1;
- return nextByte;
- }
- };
-
- Object.defineProperty(result, "eof", {
- get: function () {
- return (position >= endpoint);
- },
- configurable: true,
- enumerable: true
- });
-
- return result;
- },
-
- toBase64StringImpl: function (inArray, offset, length) {
- var reader = this._makeByteReader(inArray, offset, length);
- var result = "";
- var ch1 = 0, ch2 = 0, ch3 = 0, bits = 0, equalsCount = 0, sum = 0;
- var mask1 = (1 << 24) - 1, mask2 = (1 << 18) - 1, mask3 = (1 << 12) - 1, mask4 = (1 << 6) - 1;
- var shift1 = 18, shift2 = 12, shift3 = 6, shift4 = 0;
-
- while (true) {
- ch1 = reader.read();
- ch2 = reader.read();
- ch3 = reader.read();
-
- if (ch1 === false)
- break;
- if (ch2 === false) {
- ch2 = 0;
- equalsCount += 1;
- }
- if (ch3 === false) {
- ch3 = 0;
- equalsCount += 1;
- }
-
- // Seems backwards, but is right!
- sum = (ch1 << 16) | (ch2 << 8) | (ch3 << 0);
-
- bits = (sum & mask1) >> shift1;
- result += this._base64Table[bits];
- bits = (sum & mask2) >> shift2;
- result += this._base64Table[bits];
-
- if (equalsCount < 2) {
- bits = (sum & mask3) >> shift3;
- result += this._base64Table[bits];
- }
-
- if (equalsCount === 2) {
- result += "==";
- } else if (equalsCount === 1) {
- result += "=";
- } else {
- bits = (sum & mask4) >> shift4;
- result += this._base64Table[bits];
- }
- }
-
- return result;
- },
- },
-
- _mono_wasm_root_buffer_prototype: {
- _throw_index_out_of_range: function () {
- throw new Error ("index out of range");
- },
- _check_in_range: function (index) {
- if ((index >= this.__count) || (index < 0))
- this._throw_index_out_of_range();
- },
- /** @returns {NativePointer} */
- get_address: function (index) {
- this._check_in_range (index);
- return this.__offset + (index * 4);
- },
- /** @returns {number} */
- get_address_32: function (index) {
- this._check_in_range (index);
- return this.__offset32 + index;
- },
- /** @returns {ManagedPointer} */
- get: function (index) {
- this._check_in_range (index);
- return Module.HEAP32[this.get_address_32 (index)];
- },
- set: function (index, value) {
- Module.HEAP32[this.get_address_32 (index)] = value;
- return value;
- },
- _unsafe_get: function (index) {
- return Module.HEAP32[this.__offset32 + index];
- },
- _unsafe_set: function (index, value) {
- Module.HEAP32[this.__offset32 + index] = value;
- },
- clear: function () {
- if (this.__offset)
- MONO._zero_region (this.__offset, this.__count * 4);
- },
- release: function () {
- if (this.__offset && this.__ownsAllocation) {
- MONO.mono_wasm_deregister_root (this.__offset);
- MONO._zero_region (this.__offset, this.__count * 4);
- Module._free (this.__offset);
- }
-
- this.__handle = this.__offset = this.__count = this.__offset32 = 0;
- },
- toString: function () {
- return "[root buffer @" + this.get_address (0) + ", size " + this.__count + "]";
- }
- },
-
- _mono_wasm_root_prototype: {
- /** @returns {NativePointer} */
- get_address: function () {
- return this.__buffer.get_address (this.__index);
- },
- /** @returns {number} */
- get_address_32: function () {
- return this.__buffer.get_address_32 (this.__index);
- },
- /** @returns {ManagedPointer} */
- get: function () {
- var result = this.__buffer._unsafe_get (this.__index);
- return result;
- },
- set: function (value) {
- this.__buffer._unsafe_set (this.__index, value);
- return value;
- },
- /** @returns {ManagedPointer} */
- valueOf: function () {
- return this.get ();
- },
- clear: function () {
- this.set (0);
- },
- release: function () {
- const maxPooledInstances = 128;
- if (MONO._scratch_root_free_instances.length > maxPooledInstances) {
- MONO._mono_wasm_release_scratch_index (this.__index);
- this.__buffer = 0;
- this.__index = 0;
- } else {
- this.set (0);
- MONO._scratch_root_free_instances.push (this);
- }
- },
- toString: function () {
- return "[root @" + this.get_address () + "]";
- }
- },
-
- _mono_wasm_release_scratch_index: function (index) {
- if (index === undefined)
- return;
-
- MONO._scratch_root_buffer.set (index, 0);
- MONO._scratch_root_free_indices[MONO._scratch_root_free_indices_count] = index;
- MONO._scratch_root_free_indices_count++;
- },
-
- _mono_wasm_claim_scratch_index: function () {
- if (!MONO._scratch_root_buffer) {
- const maxScratchRoots = 8192;
- MONO._scratch_root_buffer = this.mono_wasm_new_root_buffer (maxScratchRoots, "js roots");
-
- MONO._scratch_root_free_indices = new Int32Array (maxScratchRoots);
- MONO._scratch_root_free_indices_count = maxScratchRoots;
- for (var i = 0; i < maxScratchRoots; i++)
- MONO._scratch_root_free_indices[i] = maxScratchRoots - i - 1;
-
- Object.defineProperty (this._mono_wasm_root_prototype, "value", {
- get: this._mono_wasm_root_prototype.get,
- set: this._mono_wasm_root_prototype.set,
- configurable: false
- });
- }
-
- if (MONO._scratch_root_free_indices_count < 1)
- throw new Error ("Out of scratch root space");
-
- var result = MONO._scratch_root_free_indices[MONO._scratch_root_free_indices_count - 1];
- MONO._scratch_root_free_indices_count--;
- return result;
- },
-
- _zero_region: function (byteOffset, sizeBytes) {
- if (((byteOffset % 4) === 0) && ((sizeBytes % 4) === 0))
- Module.HEAP32.fill(0, byteOffset / 4, sizeBytes / 4);
- else
- Module.HEAP8.fill(0, byteOffset, sizeBytes);
- },
-
- /**
- * Allocates a block of memory that can safely contain pointers into the managed heap.
- * The result object has get(index) and set(index, value) methods that can be used to retrieve and store managed pointers.
- * Once you are done using the root buffer, you must call its release() method.
- * For small numbers of roots, it is preferable to use the mono_wasm_new_root and mono_wasm_new_roots APIs instead.
- * @param {number} capacity - the maximum number of elements the buffer can hold.
- * @param {string} [msg] - a description of the root buffer (for debugging)
- * @returns {WasmRootBuffer}
- */
- mono_wasm_new_root_buffer: function (capacity, msg) {
- if (!this.mono_wasm_register_root || !this.mono_wasm_deregister_root) {
- this.mono_wasm_register_root = Module.cwrap ("mono_wasm_register_root", "number", ["number", "number", "string"]);
- this.mono_wasm_deregister_root = Module.cwrap ("mono_wasm_deregister_root", null, ["number"]);
- }
-
- if (capacity <= 0)
- throw new Error ("capacity >= 1");
-
- capacity = capacity | 0;
-
- var capacityBytes = capacity * 4;
- var offset = Module._malloc (capacityBytes);
- if ((offset % 4) !== 0)
- throw new Error ("Malloc returned an unaligned offset");
-
- this._zero_region (offset, capacityBytes);
-
- var result = Object.create (this._mono_wasm_root_buffer_prototype);
- result.__offset = offset;
- result.__offset32 = (offset / 4) | 0;
- result.__count = capacity;
- result.length = capacity;
- result.__handle = this.mono_wasm_register_root (offset, capacityBytes, msg || 0);
- result.__ownsAllocation = true;
-
- return result;
- },
-
- /**
- * Creates a root buffer object representing an existing allocation in the native heap and registers
- * the allocation with the GC. The caller is responsible for managing the lifetime of the allocation.
- * @param {NativePointer} offset - the offset of the root buffer in the native heap.
- * @param {number} capacity - the maximum number of elements the buffer can hold.
- * @param {string} [msg] - a description of the root buffer (for debugging)
- * @returns {WasmRootBuffer}
- */
- mono_wasm_new_root_buffer_from_pointer: function (offset, capacity, msg) {
- if (!this.mono_wasm_register_root || !this.mono_wasm_deregister_root) {
- this.mono_wasm_register_root = Module.cwrap ("mono_wasm_register_root", "number", ["number", "number", "string"]);
- this.mono_wasm_deregister_root = Module.cwrap ("mono_wasm_deregister_root", null, ["number"]);
- }
-
- if (capacity <= 0)
- throw new Error ("capacity >= 1");
-
- capacity = capacity | 0;
-
- var capacityBytes = capacity * 4;
- if ((offset % 4) !== 0)
- throw new Error ("Unaligned offset");
-
- this._zero_region (offset, capacityBytes);
-
- var result = Object.create (this._mono_wasm_root_buffer_prototype);
- result.__offset = offset;
- result.__offset32 = (offset / 4) | 0;
- result.__count = capacity;
- result.length = capacity;
- result.__handle = this.mono_wasm_register_root (offset, capacityBytes, msg || 0);
- result.__ownsAllocation = false;
-
- return result;
- },
-
- /**
- * Allocates temporary storage for a pointer into the managed heap.
- * Pointers stored here will be visible to the GC, ensuring that the object they point to aren't moved or collected.
- * If you already have a managed pointer you can pass it as an argument to initialize the temporary storage.
- * The result object has get() and set(value) methods, along with a .value property.
- * When you are done using the root you must call its .release() method.
- * @param {ManagedPointer} [value] - an address in the managed heap to initialize the root with (or 0)
- * @returns {WasmRoot}
- */
- mono_wasm_new_root: function (value) {
- var result;
-
- if (MONO._scratch_root_free_instances.length > 0) {
- result = MONO._scratch_root_free_instances.pop ();
- } else {
- var index = this._mono_wasm_claim_scratch_index ();
- var buffer = MONO._scratch_root_buffer;
-
- result = Object.create (this._mono_wasm_root_prototype);
- result.__buffer = buffer;
- result.__index = index;
- }
-
- if (value !== undefined) {
- if (typeof (value) !== "number")
- throw new Error ("value must be an address in the managed heap");
-
- result.set (value);
- } else {
- result.set (0);
- }
-
- return result;
- },
-
- /**
- * Allocates 1 or more temporary roots, accepting either a number of roots or an array of pointers.
- * mono_wasm_new_roots(n): returns an array of N zero-initialized roots.
- * mono_wasm_new_roots([a, b, ...]) returns an array of new roots initialized with each element.
- * Each root must be released with its release method, or using the mono_wasm_release_roots API.
- * @param {(number | ManagedPointer[])} count_or_values - either a number of roots or an array of pointers
- * @returns {WasmRoot[]}
- */
- mono_wasm_new_roots: function (count_or_values) {
- var result;
-
- if (Array.isArray (count_or_values)) {
- result = new Array (count_or_values.length);
- for (var i = 0; i < result.length; i++)
- result[i] = this.mono_wasm_new_root (count_or_values[i]);
- } else if ((count_or_values | 0) > 0) {
- result = new Array (count_or_values);
- for (var i = 0; i < result.length; i++)
- result[i] = this.mono_wasm_new_root ();
- } else {
- throw new Error ("count_or_values must be either an array or a number greater than 0");
- }
-
- return result;
- },
-
- /**
- * Releases 1 or more root or root buffer objects.
- * Multiple objects may be passed on the argument list.
- * 'undefined' may be passed as an argument so it is safe to call this method from finally blocks
- * even if you are not sure all of your roots have been created yet.
- * @param {... WasmRoot} roots
- */
- mono_wasm_release_roots: function () {
- for (var i = 0; i < arguments.length; i++) {
- if (!arguments[i])
- continue;
-
- arguments[i].release ();
- }
- },
-
- string_decoder: {
- copy: function (mono_string) {
- if (mono_string === 0)
- return null;
-
- if (!this.mono_wasm_string_root)
- this.mono_wasm_string_root = MONO.mono_wasm_new_root ();
- this.mono_wasm_string_root.value = mono_string;
-
- if (!this.mono_wasm_string_get_data)
- this.mono_wasm_string_get_data = Module.cwrap ("mono_wasm_string_get_data", null, ['number', 'number', 'number', 'number']);
-
- if (!this.mono_wasm_string_decoder_buffer)
- this.mono_wasm_string_decoder_buffer = Module._malloc(12);
-
- let ppChars = this.mono_wasm_string_decoder_buffer + 0,
- pLengthBytes = this.mono_wasm_string_decoder_buffer + 4,
- pIsInterned = this.mono_wasm_string_decoder_buffer + 8;
-
- this.mono_wasm_string_get_data (mono_string, ppChars, pLengthBytes, pIsInterned);
-
- // TODO: Is this necessary?
- if (!this.mono_wasm_empty_string)
- this.mono_wasm_empty_string = "";
-
- let result = this.mono_wasm_empty_string;
- let lengthBytes = Module.HEAP32[pLengthBytes / 4],
- pChars = Module.HEAP32[ppChars / 4],
- isInterned = Module.HEAP32[pIsInterned / 4];
-
- if (pLengthBytes && pChars) {
- if (
- isInterned &&
- MONO.interned_string_table &&
- MONO.interned_string_table.has(mono_string)
- ) {
- result = MONO.interned_string_table.get(mono_string);
- // console.log("intern table cache hit", mono_string, result.length);
- } else {
- result = this.decode(pChars, pChars + lengthBytes, false);
- if (isInterned) {
- if (!MONO.interned_string_table)
- MONO.interned_string_table = new Map();
- // console.log("interned", mono_string, result.length);
- MONO.interned_string_table.set(mono_string, result);
- }
- }
- }
-
- this.mono_wasm_string_root.value = 0;
- return result;
- },
- decode: function (start, end, save) {
- if (MONO.mono_text_decoder === undefined) {
- MONO.mono_text_decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : null;
- }
-
- var str = "";
- if (MONO.mono_text_decoder) {
- // When threading is enabled, TextDecoder does not accept a view of a
- // SharedArrayBuffer, we must make a copy of the array first.
- // See https://github.com/whatwg/encoding/issues/172
- var subArray = typeof SharedArrayBuffer !== 'undefined' && Module.HEAPU8.buffer instanceof SharedArrayBuffer
- ? Module.HEAPU8.slice(start, end)
- : Module.HEAPU8.subarray(start, end);
-
- str = MONO.mono_text_decoder.decode(subArray);
- } else {
- for (var i = 0; i < end - start; i+=2) {
- var char = Module.getValue (start + i, 'i16');
- str += String.fromCharCode (char);
- }
- }
- if (save)
- this.result = str;
-
- return str;
- },
- },
-
- mono_wasm_add_dbg_command_received: function(res_ok, id, buffer, buffer_len) {
- const assembly_data = new Uint8Array(Module.HEAPU8.buffer, buffer, buffer_len);
- const base64String = MONO._base64Converter.toBase64StringImpl(assembly_data);
- const buffer_obj = {
- res_ok,
- res: {
- id,
- value: base64String
- }
- }
- MONO.commands_received = buffer_obj;
- },
-
- mono_wasm_send_dbg_command_with_parms: function (id, command_set, command, command_parameters, length, valtype, newvalue)
- {
- var dataHeap = this.mono_wasm_load_bytes_into_heap (this._base64_to_uint8 (command_parameters));
- this._c_fn_table.mono_wasm_send_dbg_command_with_parms_wrapper (id, command_set, command, dataHeap, length, valtype, newvalue.toString());
- let { res_ok, res } = MONO.commands_received;
- if (!res_ok)
- throw new Error (`Failed on mono_wasm_invoke_method_debugger_agent_with_parms`);
- return res;
- },
-
- mono_wasm_send_dbg_command: function (id, command_set, command, command_parameters)
- {
- var dataHeap = this.mono_wasm_load_bytes_into_heap (this._base64_to_uint8 (command_parameters));
- this._c_fn_table.mono_wasm_send_dbg_command_wrapper (id, command_set, command, dataHeap, command_parameters.length);
- let { res_ok, res } = MONO.commands_received;
- if (!res_ok)
- throw new Error (`Failed on mono_wasm_send_dbg_command`);
- return res;
-
- },
-
- mono_wasm_get_dbg_command_info: function ()
- {
- let { res_ok, res } = MONO.commands_received;
- if (!res_ok)
- throw new Error (`Failed on mono_wasm_get_dbg_command_info`);
- return res;
- },
-
- _get_cfo_res_details: function (objectId, args) {
- if (!(objectId in this._call_function_res_cache))
- throw new Error(`Could not find any object with id ${objectId}`);
-
- const real_obj = this._call_function_res_cache [objectId];
-
- const descriptors = Object.getOwnPropertyDescriptors (real_obj);
- if (args.accessorPropertiesOnly) {
- Object.keys (descriptors).forEach (k => {
- if (descriptors [k].get === undefined)
- Reflect.deleteProperty (descriptors, k);
- });
- }
-
- let res_details = [];
- Object.keys (descriptors).forEach (k => {
- let new_obj;
- let prop_desc = descriptors [k];
- if (typeof prop_desc.value == "object") {
- // convert `{value: { type='object', ... }}`
- // to `{ name: 'foo', value: { type='object', ... }}
- new_obj = Object.assign ({ name: k }, prop_desc);
- } else if (prop_desc.value !== undefined) {
- // This is needed for values that were not added by us,
- // thus are like { value: 5 }
- // instead of { value: { type = 'number', value: 5 }}
- //
- // This can happen, for eg., when `length` gets added for arrays
- // or `__proto__`.
- new_obj = {
- name: k,
- // merge/add `type` and `description` to `d.value`
- value: Object.assign ({ type: (typeof prop_desc.value), description: '' + prop_desc.value },
- prop_desc)
- };
- } else if (prop_desc.get !== undefined) {
- // The real_obj has the actual getter. We are just returning a placeholder
- // If the caller tries to run function on the cfo_res object,
- // that accesses this property, then it would be run on `real_obj`,
- // which *has* the original getter
- new_obj = {
- name: k,
- get: {
- className: "Function",
- description: `get ${k} () {}`,
- type: "function"
- }
- };
- } else {
- new_obj = { name: k, value: { type: "symbol", value: "", description: ""} };
- }
-
- res_details.push (new_obj);
- });
-
- return { __value_as_json_string__: JSON.stringify (res_details) };
- },
-
- mono_wasm_get_details: function (objectId, args={}) {
- return this._get_cfo_res_details (`dotnet:cfo_res:${objectId}`, args);
- },
-
- _cache_call_function_res: function (obj) {
- const id = `dotnet:cfo_res:${MONO._next_call_function_res_id++}`;
- this._call_function_res_cache[id] = obj;
- return id;
- },
-
- mono_wasm_release_object: function (objectId) {
- if (objectId in this._cache_call_function_res)
- delete this._cache_call_function_res[objectId];
- },
-
- _create_proxy_from_object_id: function (objectId, details) {
- if (objectId.startsWith ('dotnet:array:'))
- {
- let ret = details.map (p => p.value);
- return ret;
- }
-
- let proxy = {};
- Object.keys (details).forEach (p => {
- var prop = details [p];
- if (prop.get !== undefined) {
- Object.defineProperty (proxy,
- prop.name,
- { get () { return MONO.mono_wasm_send_dbg_command(-1, prop.get.commandSet, prop.get.command, prop.get.buffer, prop.get.length); },
- set: function (newValue) { MONO.mono_wasm_send_dbg_command_with_parms(-1, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue); return MONO.commands_received.res_ok;}}
- );
- } else if (prop.set !== undefined ){
- Object.defineProperty (proxy,
- prop.name,
- { get () { return prop.value; },
- set: function (newValue) { MONO.mono_wasm_send_dbg_command_with_parms(-1, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue); return MONO.commands_received.res_ok;}}
- );
- } else {
- proxy [prop.name] = prop.value;
- }
- });
- return proxy;
- },
-
- mono_wasm_call_function_on: function (request) {
- if (request.arguments != undefined && !Array.isArray (request.arguments))
- throw new Error (`"arguments" should be an array, but was ${request.arguments}`);
-
- const objId = request.objectId;
- const details = request.details;
- let proxy;
-
- if (objId.startsWith ('dotnet:cfo_res:')) {
- if (objId in this._call_function_res_cache)
- proxy = this._call_function_res_cache [objId];
- else
- throw new Error (`Unknown object id ${objId}`);
- } else {
- proxy = this._create_proxy_from_object_id (objId, details);
- }
-
- const fn_args = request.arguments != undefined ? request.arguments.map(a => JSON.stringify(a.value)) : [];
- const fn_eval_str = `var fn = ${request.functionDeclaration}; fn.call (proxy, ...[${fn_args}]);`;
-
- const fn_res = eval (fn_eval_str);
- if (fn_res === undefined)
- return { type: "undefined" };
-
- if (Object (fn_res) !== fn_res)
- {
- if (typeof(fn_res) == "object" && fn_res == null)
- return { type: typeof(fn_res), subtype: `${fn_res}`, value: null };
- return { type: typeof(fn_res), description: `${fn_res}`, value: `${fn_res}`};
- }
-
- if (request.returnByValue && fn_res.subtype == undefined)
- return {type: "object", value: fn_res};
- if (Object.getPrototypeOf (fn_res) == Array.prototype) {
-
- const fn_res_id = this._cache_call_function_res (fn_res);
-
- return {
- type: "object",
- subtype: "array",
- className: "Array",
- description: `Array(${fn_res.length})`,
- objectId: fn_res_id
- };
- }
- if (fn_res.value !== undefined || fn_res.subtype !== undefined) {
- return fn_res;
- }
-
- if (fn_res == proxy)
- return { type: "object", className: "Object", description: "Object", objectId: objId };
- const fn_res_id = this._cache_call_function_res (fn_res);
- return { type: "object", className: "Object", description: "Object", objectId: fn_res_id };
- },
-
- _clear_per_step_state: function () {
- MONO._next_id_var = 0;
- MONO._id_table = {};
- },
-
- mono_wasm_debugger_resume: function () {
- this._clear_per_step_state ();
- },
-
- mono_wasm_detach_debugger: function () {
- if (!this.mono_wasm_set_is_debugger_attached)
- this.mono_wasm_set_is_debugger_attached = Module.cwrap ('mono_wasm_set_is_debugger_attached', 'void', ['bool']);
- this.mono_wasm_set_is_debugger_attached(false);
- },
-
- _register_c_fn: function (name, ...args) {
- Object.defineProperty (this._c_fn_table, name + '_wrapper', { value: Module.cwrap (name, ...args) });
- },
-
- /**
- * Calls `Module.cwrap` for the function name,
- * and creates a wrapper around it that returns
- * `{ bool result, object var_info }
- *
- * @param {string} name C function name
- * @param {string} ret_type
- * @param {string[]} params
- *
- * @returns {void}
- */
- _register_c_var_fn: function (name, ret_type, params) {
- if (ret_type !== 'bool')
- throw new Error (`Bug: Expected a C function signature that returns bool`);
-
- this._register_c_fn (name, ret_type, params);
- Object.defineProperty (this, name + '_info', {
- value: function (...args) {
- MONO.var_info = [];
- const res_ok = MONO._c_fn_table [name + '_wrapper'] (...args);
- let res = MONO.var_info;
- MONO.var_info = [];
- if (res_ok) {
- res = this._fixup_name_value_objects (res);
- return { res_ok, res };
- }
-
- return { res_ok, res: undefined };
- }
- });
- },
-
- mono_wasm_runtime_ready: function () {
- MONO.mono_wasm_runtime_is_ready = true;
- this._clear_per_step_state ();
-
- // FIXME: where should this go?
- MONO._next_call_function_res_id = 0;
- this._call_function_res_cache = {};
-
- this._c_fn_table = {};
- this._register_c_fn ('mono_wasm_send_dbg_command', 'bool', [ 'number', 'number', 'number', 'number', 'number' ]);
- this._register_c_fn ('mono_wasm_send_dbg_command_with_parms', 'bool', [ 'number', 'number', 'number', 'number', 'number', 'number', 'string' ]);
-
- // DO NOT REMOVE - magic debugger init function
- if (globalThis.dotnetDebugger)
- debugger;
- else
- console.debug ("mono_wasm_runtime_ready", "fe00e07a-5519-4dfe-b35a-f867dbaf2e28");
- },
-
- // Set environment variable NAME to VALUE
- // Should be called before mono_load_runtime_and_bcl () in most cases
- mono_wasm_setenv: function (name, value) {
- if (!this.wasm_setenv)
- this.wasm_setenv = Module.cwrap ('mono_wasm_setenv', null, ['string', 'string']);
- this.wasm_setenv (name, value);
- },
-
- mono_wasm_set_runtime_options: function (options) {
- if (!this.wasm_parse_runtime_options)
- this.wasm_parse_runtime_options = Module.cwrap ('mono_wasm_parse_runtime_options', null, ['number', 'number']);
- var argv = Module._malloc (options.length * 4);
- var wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string']);
- let aindex = 0;
- for (var i = 0; i < options.length; ++i) {
- Module.setValue (argv + (aindex * 4), wasm_strdup (options [i]), "i32");
- aindex += 1;
- }
- this.wasm_parse_runtime_options (options.length, argv);
- },
-
- //
- // Initialize the AOT profiler with OPTIONS.
- // Requires the AOT profiler to be linked into the app.
- // options = { write_at: "", send_to: "" }
- // should be in the format ::.
- // write_at defaults to 'WebAssembly.Runtime::StopProfile'.
- // send_to defaults to 'WebAssembly.Runtime::DumpAotProfileData'.
- // DumpAotProfileData stores the data into Module.aot_profile_data.
- //
- mono_wasm_init_aot_profiler: function (options) {
- if (options == null)
- options = {}
- if (!('write_at' in options))
- options.write_at = 'Interop/Runtime::StopProfile';
- if (!('send_to' in options))
- options.send_to = 'Interop/Runtime::DumpAotProfileData';
- var arg = "aot:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to;
- Module.ccall ('mono_wasm_load_profiler_aot', null, ['string'], [arg]);
- },
-
- // options = { write_at: "", send_to: "" }
- // should be in the format ::.
- // write_at defaults to 'WebAssembly.Runtime::StopProfile'.
- // send_to defaults to 'WebAssembly.Runtime::DumpCoverageProfileData'.
- // DumpCoverageProfileData stores the data into Module.coverage_profile_data.
- mono_wasm_init_coverage_profiler: function (options) {
- if (options == null)
- options = {}
- if (!('write_at' in options))
- options.write_at = 'WebAssembly.Runtime::StopProfile';
- if (!('send_to' in options))
- options.send_to = 'WebAssembly.Runtime::DumpCoverageProfileData';
- var arg = "coverage:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to;
- Module.ccall ('mono_wasm_load_profiler_coverage', null, ['string'], [arg]);
- },
-
- _apply_configuration_from_args: function (args) {
- for (var k in (args.environment_variables || {}))
- MONO.mono_wasm_setenv (k, args.environment_variables[k]);
-
- if (args.runtime_options)
- MONO.mono_wasm_set_runtime_options (args.runtime_options);
-
- if (args.aot_profiler_options)
- MONO.mono_wasm_init_aot_profiler (args.aot_profiler_options);
-
- if (args.coverage_profiler_options)
- MONO.mono_wasm_init_coverage_profiler (args.coverage_profiler_options);
- },
-
- _get_fetch_file_cb_from_args: function (args) {
- if (typeof (args.fetch_file_cb) === "function")
- return args.fetch_file_cb;
-
- if (ENVIRONMENT_IS_NODE) {
- var fs = require('fs');
- return function (asset) {
- console.debug ("MONO_WASM: Loading... " + asset);
- var binary = fs.readFileSync (asset);
- var resolve_func2 = function (resolve, reject) {
- resolve (new Uint8Array (binary));
- };
-
- var resolve_func1 = function (resolve, reject) {
- var response = {
- ok: true,
- url: asset,
- arrayBuffer: function () {
- return new Promise (resolve_func2);
- }
- };
- resolve (response);
- };
-
- return new Promise (resolve_func1);
- };
- } else if (typeof (fetch) === "function") {
- return function (asset) {
- return fetch (asset, { credentials: 'same-origin' });
- };
- } else {
- throw new Error ("No fetch_file_cb was provided and this environment does not expose 'fetch'.");
- }
- },
-
- _handle_loaded_asset: function (ctx, asset, url, blob) {
- var bytes = new Uint8Array (blob);
- if (ctx.tracing)
- console.log ("MONO_WASM: Loaded:", asset.name, "size", bytes.length, "from", url);
-
- var virtualName = asset.virtual_path || asset.name;
- var offset = null;
-
- switch (asset.behavior) {
- case "resource":
- case "assembly":
- ctx.loaded_files.push ({ url: url, file: virtualName});
- case "heap":
- case "icu":
- offset = this.mono_wasm_load_bytes_into_heap (bytes);
- ctx.loaded_assets[virtualName] = [offset, bytes.length];
- break;
-
- case "vfs":
- // FIXME
- var lastSlash = virtualName.lastIndexOf("/");
- var parentDirectory = (lastSlash > 0)
- ? virtualName.substr(0, lastSlash)
- : null;
- var fileName = (lastSlash > 0)
- ? virtualName.substr(lastSlash + 1)
- : virtualName;
- if (fileName.startsWith("/"))
- fileName = fileName.substr(1);
- if (parentDirectory) {
- if (ctx.tracing)
- console.log ("MONO_WASM: Creating directory '" + parentDirectory + "'");
-
- var pathRet = ctx.createPath(
- "/", parentDirectory, true, true // fixme: should canWrite be false?
- );
- } else {
- parentDirectory = "/";
- }
-
- if (ctx.tracing)
- console.log ("MONO_WASM: Creating file '" + fileName + "' in directory '" + parentDirectory + "'");
-
- if (!this.mono_wasm_load_data_archive (bytes, parentDirectory)) {
- var fileRet = ctx.createDataFile (
- parentDirectory, fileName,
- bytes, true /* canRead */, true /* canWrite */, true /* canOwn */
- );
- }
- break;
-
- default:
- throw new Error ("Unrecognized asset behavior:", asset.behavior, "for asset", asset.name);
- }
-
- if (asset.behavior === "assembly") {
- var hasPpdb = ctx.mono_wasm_add_assembly (virtualName, offset, bytes.length);
-
- if (!hasPpdb) {
- var index = ctx.loaded_files.findIndex(element => element.file == virtualName);
- ctx.loaded_files.splice(index, 1);
- }
- }
- else if (asset.behavior === "icu") {
- if (this.mono_wasm_load_icu_data (offset))
- ctx.num_icu_assets_loaded_successfully += 1;
- else
- console.error ("Error loading ICU asset", asset.name);
- }
- else if (asset.behavior === "resource") {
- ctx.mono_wasm_add_satellite_assembly (virtualName, asset.culture, offset, bytes.length);
- }
- },
-
- // deprecated
- mono_load_runtime_and_bcl: function (
- unused_vfs_prefix, deploy_prefix, debug_level, file_list, loaded_cb, fetch_file_cb
- ) {
- var args = {
- fetch_file_cb: fetch_file_cb,
- loaded_cb: loaded_cb,
- debug_level: debug_level,
- assembly_root: deploy_prefix,
- assets: []
- };
-
- for (var i = 0; i < file_list.length; i++) {
- var file_name = file_list[i];
- var behavior;
- if (file_name.startsWith ("icudt") && file_name.endsWith (".dat")) {
- // ICU data files are expected to be "icudt%FilterName%.dat"
- behavior = "icu";
- } else { // if (file_name.endsWith (".pdb") || file_name.endsWith (".dll"))
- behavior = "assembly";
- }
-
- args.assets.push ({
- name: file_name,
- behavior: behavior
- });
- }
-
- return this.mono_load_runtime_and_bcl_args (args);
- },
-
- // Initializes the runtime and loads assemblies, debug information, and other files.
- // @args is a dictionary-style Object with the following properties:
- // assembly_root: (required) the subfolder containing managed assemblies and pdbs
- // debug_level or enable_debugging: (required)
- // assets: (required) a list of assets to load along with the runtime. each asset
- // is a dictionary-style Object with the following properties:
- // name: (required) the name of the asset, including extension.
- // behavior: (required) determines how the asset will be handled once loaded:
- // "heap": store asset into the native heap
- // "assembly": load asset as a managed assembly (or debugging information)
- // "resource": load asset as a managed resource assembly
- // "icu": load asset as an ICU data archive
- // "vfs": load asset into the virtual filesystem (for fopen, File.Open, etc)
- // load_remote: (optional) if true, an attempt will be made to load the asset
- // from each location in @args.remote_sources.
- // virtual_path: (optional) if specified, overrides the path of the asset in
- // the virtual filesystem and similar data structures once loaded.
- // is_optional: (optional) if true, any failure to load this asset will be ignored.
- // loaded_cb: (required) a function () invoked when loading has completed.
- // fetch_file_cb: (optional) a function (string) invoked to fetch a given file.
- // If no callback is provided a default implementation appropriate for the current
- // environment will be selected (readFileSync in node, fetch elsewhere).
- // If no default implementation is available this call will fail.
- // remote_sources: (optional) additional search locations for assets.
- // sources will be checked in sequential order until the asset is found.
- // the string "./" indicates to load from the application directory (as with the
- // files in assembly_list), and a fully-qualified URL like "https://example.com/" indicates
- // that asset loads can be attempted from a remote server. Sources must end with a "/".
- // environment_variables: (optional) dictionary-style Object containing environment variables
- // runtime_options: (optional) array of runtime options as strings
- // aot_profiler_options: (optional) dictionary-style Object. see the comments for
- // mono_wasm_init_aot_profiler. If omitted, aot profiler will not be initialized.
- // coverage_profiler_options: (optional) dictionary-style Object. see the comments for
- // mono_wasm_init_coverage_profiler. If omitted, coverage profiler will not be initialized.
- // globalization_mode: (optional) configures the runtime's globalization mode:
- // "icu": load ICU globalization data from any runtime assets with behavior "icu".
- // "invariant": operate in invariant globalization mode.
- // "auto" (default): if "icu" behavior assets are present, use ICU, otherwise invariant.
- // diagnostic_tracing: (optional) enables diagnostic log messages during startup
- mono_load_runtime_and_bcl_args: function (args) {
- try {
- return this._load_assets_and_runtime (args);
- } catch (exc) {
- console.error ("error in mono_load_runtime_and_bcl_args:", exc);
- throw exc;
- }
- },
-
- // @bytes must be a typed array. space is allocated for it in the native heap
- // and it is copied to that location. returns the address of the allocation.
- mono_wasm_load_bytes_into_heap: function (bytes) {
- var memoryOffset = Module._malloc (bytes.length);
- var heapBytes = new Uint8Array (Module.HEAPU8.buffer, memoryOffset, bytes.length);
- heapBytes.set (bytes);
- return memoryOffset;
- },
-
- // @offset must be the address of an ICU data archive in the native heap.
- // returns true on success.
- mono_wasm_load_icu_data: function (offset) {
- var fn = Module.cwrap ('mono_wasm_load_icu_data', 'number', ['number']);
- var ok = (fn (offset)) === 1;
- if (ok)
- MONO.num_icu_assets_loaded_successfully++;
- return ok;
- },
-
- // Get icudt.dat exact filename that matches given culture, examples:
- // "ja" -> "icudt_CJK.dat"
- // "en_US" (or "en-US" or just "en") -> "icudt_EFIGS.dat"
- // etc, see "mono_wasm_get_icudt_name" implementation in pal_icushim_static.c
- mono_wasm_get_icudt_name: function (culture) {
- return Module.ccall ('mono_wasm_get_icudt_name', 'string', ['string'], [culture]);
- },
-
- _finalize_startup: function (args, ctx) {
- var loaded_files_with_debug_info = [];
-
- MONO.loaded_assets = ctx.loaded_assets;
- ctx.loaded_files.forEach(value => loaded_files_with_debug_info.push(value.url));
- MONO.loaded_files = loaded_files_with_debug_info;
- if (ctx.tracing) {
- console.log ("MONO_WASM: loaded_assets: " + JSON.stringify(ctx.loaded_assets));
- console.log ("MONO_WASM: loaded_files: " + JSON.stringify(ctx.loaded_files));
- }
-
- var load_runtime = Module.cwrap ('mono_wasm_load_runtime', null, ['string', 'number']);
-
- console.debug ("MONO_WASM: Initializing mono runtime");
-
- this.mono_wasm_globalization_init (args.globalization_mode);
-
- if (ENVIRONMENT_IS_SHELL || ENVIRONMENT_IS_NODE) {
- try {
- load_runtime ("unused", args.debug_level);
- } catch (ex) {
- print ("MONO_WASM: load_runtime () failed: " + ex);
- print ("MONO_WASM: Stacktrace: \n");
- print (ex.stack);
-
- var wasm_exit = Module.cwrap ('mono_wasm_exit', null, ['number']);
- wasm_exit (1);
- }
- } else {
- load_runtime ("unused", args.debug_level);
- }
-
- let tz;
- try {
- tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
- } catch {}
- MONO.mono_wasm_setenv ("TZ", tz || "UTC");
- MONO.mono_wasm_runtime_ready ();
- args.loaded_cb ();
- },
-
- _load_assets_and_runtime: function (args) {
- if (args.enable_debugging)
- args.debug_level = args.enable_debugging;
- if (args.assembly_list)
- throw new Error ("Invalid args (assembly_list was replaced by assets)");
- if (args.runtime_assets)
- throw new Error ("Invalid args (runtime_assets was replaced by assets)");
- if (args.runtime_asset_sources)
- throw new Error ("Invalid args (runtime_asset_sources was replaced by remote_sources)");
- if (!args.loaded_cb)
- throw new Error ("loaded_cb not provided");
-
- var ctx = {
- tracing: args.diagnostic_tracing || false,
- pending_count: args.assets.length,
- mono_wasm_add_assembly: Module.cwrap ('mono_wasm_add_assembly', 'number', ['string', 'number', 'number']),
- mono_wasm_add_satellite_assembly: Module.cwrap ('mono_wasm_add_satellite_assembly', 'void', ['string', 'string', 'number', 'number']),
- loaded_assets: Object.create (null),
- // dlls and pdbs, used by blazor and the debugger
- loaded_files: [],
- createPath: Module['FS_createPath'],
- createDataFile: Module['FS_createDataFile']
- };
-
- if (ctx.tracing)
- console.log ("mono_wasm_load_runtime_with_args", JSON.stringify(args));
-
- this._apply_configuration_from_args (args);
-
- var fetch_file_cb = this._get_fetch_file_cb_from_args (args);
-
- var onPendingRequestComplete = function () {
- --ctx.pending_count;
-
- if (ctx.pending_count === 0) {
- try {
- MONO._finalize_startup (args, ctx);
- } catch (exc) {
- console.error ("Unhandled exception in _finalize_startup", exc);
- throw exc;
- }
- }
- };
-
- var processFetchResponseBuffer = function (asset, url, blob) {
- try {
- MONO._handle_loaded_asset (ctx, asset, url, blob);
- } catch (exc) {
- console.error ("Unhandled exception in processFetchResponseBuffer", exc);
- throw exc;
- } finally {
- onPendingRequestComplete ();
- }
- };
-
- args.assets.forEach (function (asset) {
- var attemptNextSource;
- var sourceIndex = 0;
- var sourcesList = asset.load_remote ? args.remote_sources : [""];
-
- var handleFetchResponse = function (response) {
- if (!response.ok) {
- try {
- attemptNextSource ();
- return;
- } catch (exc) {
- console.error ("MONO_WASM: Unhandled exception in handleFetchResponse attemptNextSource for asset", asset.name, exc);
- throw exc;
- }
- }
-
- try {
- var bufferPromise = response ['arrayBuffer'] ();
- bufferPromise.then (processFetchResponseBuffer.bind (this, asset, response.url));
- } catch (exc) {
- console.error ("MONO_WASM: Unhandled exception in handleFetchResponse for asset", asset.name, exc);
- attemptNextSource ();
- }
- };
-
- attemptNextSource = function () {
- if (sourceIndex >= sourcesList.length) {
- var msg = "MONO_WASM: Failed to load " + asset.name;
- try {
- var isOk = asset.is_optional ||
- (asset.name.match (/\.pdb$/) && MONO.mono_wasm_ignore_pdb_load_errors);
-
- if (isOk)
- console.debug (msg);
- else {
- console.error (msg);
- throw new Error (msg);
- }
- } finally {
- onPendingRequestComplete ();
- }
- }
-
- var sourcePrefix = sourcesList[sourceIndex];
- sourceIndex++;
-
- // HACK: Special-case because MSBuild doesn't allow "" as an attribute
- if (sourcePrefix === "./")
- sourcePrefix = "";
-
- var attemptUrl;
- if (sourcePrefix.trim() === "") {
- if (asset.behavior === "assembly")
- attemptUrl = locateFile (args.assembly_root + "/" + asset.name);
- else if (asset.behavior === "resource") {
- var path = asset.culture !== '' ? `${asset.culture}/${asset.name}` : asset.name;
- attemptUrl = locateFile (args.assembly_root + "/" + path);
- }
- else
- attemptUrl = asset.name;
- } else {
- attemptUrl = sourcePrefix + asset.name;
- }
-
- try {
- if (asset.name === attemptUrl) {
- if (ctx.tracing)
- console.log ("Attempting to fetch '" + attemptUrl + "'");
- } else {
- if (ctx.tracing)
- console.log ("Attempting to fetch '" + attemptUrl + "' for", asset.name);
- }
- var fetch_promise = fetch_file_cb (attemptUrl);
- fetch_promise.then (handleFetchResponse);
- } catch (exc) {
- console.error ("MONO_WASM: Error fetching " + attemptUrl, exc);
- attemptNextSource ();
- }
- };
-
- attemptNextSource ();
- });
- },
-
- // Performs setup for globalization.
- // @globalization_mode is one of "icu", "invariant", or "auto".
- // "auto" will use "icu" if any ICU data archives have been loaded,
- // otherwise "invariant".
- mono_wasm_globalization_init: function (globalization_mode) {
- var invariantMode = false;
-
- if (globalization_mode === "invariant")
- invariantMode = true;
-
- if (!invariantMode) {
- if (MONO.num_icu_assets_loaded_successfully > 0) {
- console.debug ("MONO_WASM: ICU data archive(s) loaded, disabling invariant mode");
- } else if (globalization_mode !== "icu") {
- console.debug ("MONO_WASM: ICU data archive(s) not loaded, using invariant globalization mode");
- invariantMode = true;
- } else {
- var msg = "invariant globalization mode is inactive and no ICU data archives were loaded";
- console.error ("MONO_WASM: ERROR: " + msg);
- throw new Error (msg);
- }
- }
-
- if (invariantMode)
- this.mono_wasm_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1");
-
- // Set globalization mode to PredefinedCulturesOnly
- this.mono_wasm_setenv ("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", "1");
- },
-
- // Used by the debugger to enumerate loaded dlls and pdbs
- mono_wasm_get_loaded_files: function() {
- if (!this.mono_wasm_set_is_debugger_attached)
- this.mono_wasm_set_is_debugger_attached = Module.cwrap ('mono_wasm_set_is_debugger_attached', 'void', ['bool']);
- this.mono_wasm_set_is_debugger_attached (true);
- return MONO.loaded_files;
- },
-
- mono_wasm_get_loaded_asset_table: function() {
- return MONO.loaded_assets;
- },
-
- // FIXME: improve
- _base64_to_uint8: function (base64String) {
- const byteCharacters = atob (base64String);
- const byteNumbers = new Array(byteCharacters.length);
- for (let i = 0; i < byteCharacters.length; i++) {
- byteNumbers[i] = byteCharacters.charCodeAt(i);
- }
-
- return new Uint8Array (byteNumbers);
- },
-
- mono_wasm_load_data_archive: function (data, prefix) {
- if (data.length < 8)
- return false;
-
- var dataview = new DataView(data.buffer);
- var magic = dataview.getUint32(0, true);
- // get magic number
- if (magic != 0x626c6174) {
- return false;
- }
- var manifestSize = dataview.getUint32(4, true);
- if (manifestSize == 0 || data.length < manifestSize + 8)
- return false;
-
- var manifest;
- try {
- var manifestContent = Module.UTF8ArrayToString(data, 8, manifestSize);
- manifest = JSON.parse(manifestContent);
- if (!(manifest instanceof Array))
- return false;
- } catch (exc) {
- return false;
- }
-
- data = data.slice(manifestSize+8);
-
- // Create the folder structure
- // /usr/share/zoneinfo
- // /usr/share/zoneinfo/Africa
- // /usr/share/zoneinfo/Asia
- // ..
-
- var folders = new Set()
- manifest.filter(m => {
- var file = m[0];
- var last = file.lastIndexOf ("/");
- var directory = file.slice (0, last+1);
- folders.add(directory);
- });
- folders.forEach(folder => {
- Module['FS_createPath'](prefix, folder, true, true);
- });
-
- for (var row of manifest) {
- var name = row[0];
- var length = row[1];
- var bytes = data.slice(0, length);
- Module['FS_createDataFile'](prefix, name, bytes, true, true);
- data = data.slice(length);
- }
- return true;
- },
-
- /**
- * Raises an event for the debug proxy
- *
- * @param {Event} event - event to be raised
- * @param {object} args - arguments for raising this event, eg. `{trace: true}`
- */
- mono_wasm_raise_debug_event: function(event, args={}) {
- if (typeof event !== 'object')
- throw new Error(`event must be an object, but got ${JSON.stringify(event)}`);
-
- if (event.eventName === undefined)
- throw new Error(`event.eventName is a required parameter, in event: ${JSON.stringify(event)}`);
-
- if (typeof args !== 'object')
- throw new Error(`args must be an object, but got ${JSON.stringify(args)}`);
-
- console.debug('mono_wasm_debug_event_raised:aef14bca-5519-4dfe-b35a-f867abc123ae', JSON.stringify(event), JSON.stringify(args));
- },
-
- /**
- * Loads the mono config file (typically called mono-config.json) asynchroniously
- * Note: the run dependencies are so emsdk actually awaits it in order.
- *
- * @param {string} configFilePath - relative path to the config file
- * @throws Will throw an error if the config file loading fails
- */
- mono_wasm_load_config: async function (configFilePath) {
- Module.addRunDependency(configFilePath);
- try {
- let config = null;
- // NOTE: when we add nodejs make sure to include the nodejs fetch package
- if (ENVIRONMENT_IS_WEB) {
- const configRaw = await fetch(configFilePath);
- config = await configRaw.json();
- }else if (ENVIRONMENT_IS_NODE) {
- config = require(configFilePath);
- } else { // shell or worker
- config = JSON.parse(read(configFilePath)); // read is a v8 debugger command
- }
- Module.config = config;
- } catch(e) {
- Module.config = {message: "failed to load config file", error: e};
- } finally {
- Module.removeRunDependency(configFilePath);
- }
- },
- mono_wasm_set_timeout_exec: function(id){
- if (!this.mono_set_timeout_exec)
- this.mono_set_timeout_exec = Module.cwrap ("mono_set_timeout_exec", null, [ 'number' ]);
- this.mono_set_timeout_exec (id);
- },
- prevent_timer_throttling: function () {
- if (!MONO.isChromium) {
- return;
- }
-
- // this will schedule timers every second for next 6 minutes, it should be called from WebSocket event, to make it work
- // on next call, it would only extend the timers to cover yet uncovered future
- let now = new Date().valueOf();
- const desired_reach_time = now + (1000 * 60 * 6);
- const next_reach_time = Math.max(now + 1000, this.spread_timers_maximum);
- const light_throttling_frequency = 1000;
- for (var schedule = next_reach_time; schedule < desired_reach_time; schedule += light_throttling_frequency) {
- const delay = schedule - now;
- setTimeout(() => {
- this.mono_wasm_set_timeout_exec(0);
- MONO.pump_count++;
- MONO.pump_message();
- }, delay);
- }
- this.spread_timers_maximum = desired_reach_time;
- }
- },
- schedule_background_exec: function () {
- ++MONO.pump_count;
- if (typeof globalThis.setTimeout === 'function') {
- globalThis.setTimeout (MONO.pump_message, 0);
- }
- },
-
- mono_set_timeout: function (timeout, id) {
-
- if (typeof globalThis.setTimeout === 'function') {
- globalThis.setTimeout (function () {
- MONO.mono_wasm_set_timeout_exec (id);
- }, timeout);
- } else {
- ++MONO.pump_count;
- MONO.timeout_queue.push(function() {
- MONO.mono_wasm_set_timeout_exec (id);
- })
- }
- },
-
- mono_wasm_fire_debugger_agent_message: function () {
- // eslint-disable-next-line no-debugger
- debugger;
- },
-
- mono_wasm_asm_loaded: function (assembly_name, assembly_ptr, assembly_len, pdb_ptr, pdb_len) {
- // Only trigger this codepath for assemblies loaded after app is ready
- if (MONO.mono_wasm_runtime_is_ready !== true)
- return;
-
- const assembly_name_str = assembly_name !== 0 ? Module.UTF8ToString(assembly_name).concat('.dll') : '';
-
- const assembly_data = new Uint8Array(Module.HEAPU8.buffer, assembly_ptr, assembly_len);
- const assembly_b64 = MONO._base64Converter.toBase64StringImpl(assembly_data);
-
- let pdb_b64;
- if (pdb_ptr) {
- const pdb_data = new Uint8Array(Module.HEAPU8.buffer, pdb_ptr, pdb_len);
- pdb_b64 = MONO._base64Converter.toBase64StringImpl(pdb_data);
- }
-
- MONO.mono_wasm_raise_debug_event({
- eventName: 'AssemblyLoaded',
- assembly_name: assembly_name_str,
- assembly_b64,
- pdb_b64
- });
- }
+const MonoSupportLib = {
+ // this line will be executed in mergeInto below
+ $MONO__postset: '__dotnet_runtime.export_functions(MONO, Module);',
+ // this will become globalThis.MONO
+ $MONO: {},
+ // the methods would be visible to EMCC linker
+ mono_set_timeout: function () { return MONO.mono_set_timeout.call(MONO, arguments) },
+ mono_wasm_asm_loaded: function () { return MONO.mono_wasm_asm_loaded.call(MONO, arguments) },
+ mono_wasm_fire_debugger_agent_message: function () { return MONO.mono_wasm_fire_debugger_agent_message.call(MONO, arguments) },
+ schedule_background_exec: function () { return MONO.schedule_background_exec.call(MONO, arguments) },
};
autoAddDeps(MonoSupportLib, '$MONO')
diff --git a/src/mono/wasm/runtime/package-lock.json b/src/mono/wasm/runtime/package-lock.json
new file mode 100644
index 00000000000000..aadc030a45f027
--- /dev/null
+++ b/src/mono/wasm/runtime/package-lock.json
@@ -0,0 +1,1503 @@
+{
+ "name": "dotnet-runtime",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.14.5"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.15.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
+ "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@eslint/eslintrc": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
+ "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.4",
+ "debug": "^4.1.1",
+ "espree": "^7.3.0",
+ "globals": "^13.9.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^3.13.1",
+ "minimatch": "^3.0.4",
+ "strip-json-comments": "^3.1.1"
+ }
+ },
+ "@humanwhocodes/config-array": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
+ "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+ "dev": true,
+ "requires": {
+ "@humanwhocodes/object-schema": "^1.2.0",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "@humanwhocodes/object-schema": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
+ "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
+ "dev": true
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@rollup/plugin-typescript": {
+ "version": "8.2.5",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.2.5.tgz",
+ "integrity": "sha512-QL/LvDol/PAGB2O0S7/+q2HpSUNodpw7z6nGn9BfoVCPOZ0r4EALrojFU29Bkoi2Hr2jgTocTejJ5GGWZfOxbQ==",
+ "dev": true,
+ "requires": {
+ "@rollup/pluginutils": "^3.1.0",
+ "resolve": "^1.17.0"
+ }
+ },
+ "@rollup/pluginutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
+ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
+ "dev": true,
+ "requires": {
+ "@types/estree": "0.0.39",
+ "estree-walker": "^1.0.1",
+ "picomatch": "^2.2.2"
+ },
+ "dependencies": {
+ "@types/estree": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+ "dev": true
+ }
+ }
+ },
+ "@types/json-schema": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
+ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "16.9.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz",
+ "integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA==",
+ "dev": true
+ },
+ "@typescript-eslint/eslint-plugin": {
+ "version": "4.31.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.2.tgz",
+ "integrity": "sha512-w63SCQ4bIwWN/+3FxzpnWrDjQRXVEGiTt9tJTRptRXeFvdZc/wLiz3FQUwNQ2CVoRGI6KUWMNUj/pk63noUfcA==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/experimental-utils": "4.31.2",
+ "@typescript-eslint/scope-manager": "4.31.2",
+ "debug": "^4.3.1",
+ "functional-red-black-tree": "^1.0.1",
+ "regexpp": "^3.1.0",
+ "semver": "^7.3.5",
+ "tsutils": "^3.21.0"
+ }
+ },
+ "@typescript-eslint/experimental-utils": {
+ "version": "4.31.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz",
+ "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.7",
+ "@typescript-eslint/scope-manager": "4.31.2",
+ "@typescript-eslint/types": "4.31.2",
+ "@typescript-eslint/typescript-estree": "4.31.2",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^3.0.0"
+ },
+ "dependencies": {
+ "eslint-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+ "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^2.0.0"
+ }
+ }
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "4.31.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.2.tgz",
+ "integrity": "sha512-EcdO0E7M/sv23S/rLvenHkb58l3XhuSZzKf6DBvLgHqOYdL6YFMYVtreGFWirxaU2mS1GYDby3Lyxco7X5+Vjw==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/scope-manager": "4.31.2",
+ "@typescript-eslint/types": "4.31.2",
+ "@typescript-eslint/typescript-estree": "4.31.2",
+ "debug": "^4.3.1"
+ }
+ },
+ "@typescript-eslint/scope-manager": {
+ "version": "4.31.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz",
+ "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.31.2",
+ "@typescript-eslint/visitor-keys": "4.31.2"
+ }
+ },
+ "@typescript-eslint/types": {
+ "version": "4.31.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz",
+ "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==",
+ "dev": true
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "4.31.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz",
+ "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.31.2",
+ "@typescript-eslint/visitor-keys": "4.31.2",
+ "debug": "^4.3.1",
+ "globby": "^11.0.3",
+ "is-glob": "^4.0.1",
+ "semver": "^7.3.5",
+ "tsutils": "^3.21.0"
+ }
+ },
+ "@typescript-eslint/visitor-keys": {
+ "version": "4.31.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz",
+ "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.31.2",
+ "eslint-visitor-keys": "^2.0.0"
+ }
+ },
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^4.1.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "7.32.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
+ "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "7.12.11",
+ "@eslint/eslintrc": "^0.4.3",
+ "@humanwhocodes/config-array": "^0.5.0",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "enquirer": "^2.3.5",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^2.1.0",
+ "eslint-visitor-keys": "^2.0.0",
+ "espree": "^7.3.1",
+ "esquery": "^1.4.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.1.2",
+ "globals": "^13.6.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.0.4",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "progress": "^2.0.0",
+ "regexpp": "^3.1.0",
+ "semver": "^7.2.1",
+ "strip-ansi": "^6.0.0",
+ "strip-json-comments": "^3.1.0",
+ "table": "^6.0.9",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+ "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "dependencies": {
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true
+ },
+ "espree": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
+ "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.4.0",
+ "acorn-jsx": "^5.3.1",
+ "eslint-visitor-keys": "^1.3.0"
+ },
+ "dependencies": {
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true
+ }
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
+ "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "fastq": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+ "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^3.0.4"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "flat-cache": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+ "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "dev": true,
+ "requires": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ }
+ },
+ "flatted": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz",
+ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
+ "dev": true
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "globals": {
+ "version": "13.11.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz",
+ "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.20.2"
+ }
+ },
+ "globby": {
+ "version": "11.0.4",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz",
+ "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==",
+ "dev": true,
+ "requires": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.1.1",
+ "ignore": "^5.1.4",
+ "merge2": "^1.3.0",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true
+ }
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "is-core-module": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz",
+ "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
+ "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ }
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+ "dev": true
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "lodash.truncate": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "optionator": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+ "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+ "dev": true,
+ "requires": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ }
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "regexpp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+ "dev": true
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+ "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "rollup": {
+ "version": "2.56.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz",
+ "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==",
+ "dev": true,
+ "requires": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "rollup-plugin-terser": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
+ "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "jest-worker": "^26.2.1",
+ "serialize-javascript": "^4.0.0",
+ "terser": "^5.0.0"
+ }
+ },
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.5.20",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz",
+ "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "table": {
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz",
+ "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==",
+ "dev": true,
+ "requires": {
+ "ajv": "^8.0.1",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.truncate": "^4.4.2",
+ "slice-ansi": "^4.0.0",
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "8.6.3",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz",
+ "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ }
+ }
+ },
+ "terser": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.8.0.tgz",
+ "integrity": "sha512-f0JH+6yMpneYcRJN314lZrSwu9eKkUFEHLN/kNy8ceh8gaRiLgFPJqrB9HsXjhEGdv4e/ekjTOFxIlL6xlma8A==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.20.0",
+ "source-map": "~0.7.2",
+ "source-map-support": "~0.5.20"
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ },
+ "tsutils": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+ "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ }
+ }
+ },
+ "type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1"
+ }
+ },
+ "type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz",
+ "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "v8-compile-cache": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ }
+}
diff --git a/src/mono/wasm/runtime/package.json b/src/mono/wasm/runtime/package.json
new file mode 100644
index 00000000000000..dec085458d6d53
--- /dev/null
+++ b/src/mono/wasm/runtime/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "dotnet-runtime",
+ "description": ".NET is a developer platform with tools and libraries for building any type of app, including web, mobile, desktop, games, IoT, cloud, and microservices.",
+ "repository": {
+ "type": "git",
+ "url": "git@github.com:dotnet/runtime.git"
+ },
+ "version": "1.0.0",
+ "scripts": {
+ "rollup": "rollup -c",
+ "lint": "eslint src/**/*.ts"
+ },
+ "keywords": [
+ "dotnet",
+ "runtime",
+ "wasm"
+ ],
+ "author": "Microsoft",
+ "license": "MIT",
+ "devDependencies": {
+ "@rollup/plugin-typescript": "8.2.5",
+ "@typescript-eslint/eslint-plugin": "^4.31.2",
+ "@typescript-eslint/parser": "^4.31.2",
+ "eslint": "^7.32.0",
+ "rollup": "2.56.3",
+ "rollup-plugin-terser": "7.0.2",
+ "tslib": "2.3.1",
+ "typescript": "4.4.3"
+ }
+}
diff --git a/src/mono/wasm/runtime/rollup.config.js b/src/mono/wasm/runtime/rollup.config.js
new file mode 100644
index 00000000000000..7b2777118ae966
--- /dev/null
+++ b/src/mono/wasm/runtime/rollup.config.js
@@ -0,0 +1,69 @@
+import { defineConfig } from 'rollup';
+import typescript from '@rollup/plugin-typescript';
+import { terser } from 'rollup-plugin-terser';
+import { readFile, writeFile, mkdir } from 'fs/promises';
+import * as fs from 'fs';
+import { createHash } from 'crypto';
+
+const outputFileName = 'runtime.iffe.js'
+const isDebug = process.env.Configuration !== 'Release';
+const nativeBinDir = process.env.NativeBinDir ? process.env.NativeBinDir.replace(/\"/g, '') : 'bin';
+const plugins = isDebug ? [writeOnChangePlugin()] : [terser(), writeOnChangePlugin()]
+
+export default defineConfig({
+ treeshake: !isDebug,
+ input: 'src/startup.ts',
+ output: [{
+ banner: '//! Licensed to the .NET Foundation under one or more agreements.\n//! The .NET Foundation licenses this file to you under the MIT license.\n',
+ name: '__dotnet_runtime',
+ file: nativeBinDir + '/src/' + outputFileName,
+
+ // emcc doesn't know how to load ES6 module, that's why we need the whole rollup.js
+ format: 'iife',
+ plugins: plugins
+ }],
+ plugins: [typescript()]
+});
+
+// this would create .md5 file next to the output file, so that we do not touch datetime of the file if it's same -> faster incremental build.
+function writeOnChangePlugin() {
+ return {
+ name: 'writeOnChange',
+ generateBundle: writeWhenChanged
+ }
+}
+
+async function writeWhenChanged(options, bundle) {
+ try {
+ const asset = bundle[outputFileName];
+ const code = asset.code;
+ const hashFileName = options.file + '.sha256';
+ const oldHashExists = await checkFileExists(hashFileName);
+ const oldFileExists = await checkFileExists(options.file)
+
+ var newHash = createHash('sha256').update(code).digest('hex');
+
+ let isOutputChanged = true;
+ if (oldHashExists && oldFileExists) {
+ const oldHash = await readFile(hashFileName, { encoding: 'ascii' });
+ isOutputChanged = oldHash !== newHash
+ }
+ if (isOutputChanged) {
+ if (!await checkFileExists(hashFileName)) {
+ await mkdir(nativeBinDir + '/src', { recursive: true });
+ }
+ await writeFile(hashFileName, newHash);
+ } else {
+ // this.warn('No change in ' + options.file)
+ delete bundle[outputFileName]
+ }
+ } catch (ex) {
+ this.warn(ex.toString());
+ }
+}
+
+function checkFileExists(file) {
+ return fs.promises.access(file, fs.constants.F_OK)
+ .then(() => true)
+ .catch(() => false)
+}
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/binding/types.ts b/src/mono/wasm/runtime/src/binding/types.ts
new file mode 100644
index 00000000000000..c8c38ce13487b1
--- /dev/null
+++ b/src/mono/wasm/runtime/src/binding/types.ts
@@ -0,0 +1,14 @@
+/* TODO this is from ASP
+declare interface BINDING {
+ mono_obj_array_new(length: number): System_Array;
+ mono_obj_array_set(array: System_Array, index: Number, value: System_Object): void;
+ js_string_to_mono_string(jsString: string): System_String;
+ js_typed_array_to_array(array: Uint8Array): System_Object;
+ js_to_mono_obj(jsObject: any) : System_Object;
+ mono_array_to_js_array(array: System_Array) : Array;
+ conv_string(dotnetString: System_String | null): string | null;
+ bind_static_method(fqn: string, signature?: string): Function;
+ call_assembly_entry_point(assemblyName: string, args: any[], signature: any): Promise;
+ unbox_mono_obj(object: System_Object): any;
+ }
+ */
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/mono/base64.ts b/src/mono/wasm/runtime/src/mono/base64.ts
new file mode 100644
index 00000000000000..322b0f72700b7c
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/base64.ts
@@ -0,0 +1,121 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// Code from JSIL:
+// https://github.com/sq/JSIL/blob/1d57d5427c87ab92ffa3ca4b82429cd7509796ba/JSIL.Libraries/Includes/Bootstrap/Core/Classes/System.Convert.js#L149
+// Thanks to Katelyn Gadd @kg
+
+export function toBase64StringImpl(inArray: Uint8Array, offset?: number, length?: number) {
+ var reader = _makeByteReader(inArray, offset, length);
+ var result = "";
+ var ch1: number | null = 0, ch2: number | null = 0, ch3: number | null = 0
+ var bits = 0, equalsCount = 0, sum = 0;
+ var mask1 = (1 << 24) - 1, mask2 = (1 << 18) - 1, mask3 = (1 << 12) - 1, mask4 = (1 << 6) - 1;
+ var shift1 = 18, shift2 = 12, shift3 = 6, shift4 = 0;
+
+ while (true) {
+ ch1 = reader.read();
+ ch2 = reader.read();
+ ch3 = reader.read();
+
+ if (ch1 === null)
+ break;
+ if (ch2 === null) {
+ ch2 = 0;
+ equalsCount += 1;
+ }
+ if (ch3 === null) {
+ ch3 = 0;
+ equalsCount += 1;
+ }
+
+ // Seems backwards, but is right!
+ sum = (ch1 << 16) | (ch2 << 8) | (ch3 << 0);
+
+ bits = (sum & mask1) >> shift1;
+ result += _base64Table[bits];
+ bits = (sum & mask2) >> shift2;
+ result += _base64Table[bits];
+
+ if (equalsCount < 2) {
+ bits = (sum & mask3) >> shift3;
+ result += _base64Table[bits];
+ }
+
+ if (equalsCount === 2) {
+ result += "==";
+ } else if (equalsCount === 1) {
+ result += "=";
+ } else {
+ bits = (sum & mask4) >> shift4;
+ result += _base64Table[bits];
+ }
+ }
+
+ return result;
+}
+
+const _base64Table = [
+ 'A', 'B', 'C', 'D',
+ 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L',
+ 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X',
+ 'Y', 'Z',
+ 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l',
+ 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x',
+ 'y', 'z',
+ '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9',
+ '+', '/'
+]
+
+function _makeByteReader(bytes: Uint8Array, index?: number, count?: number): {
+ read: () => number | null
+} {
+ var position = (typeof (index) === "number") ? index : 0;
+ var endpoint: number;
+
+ if (typeof (count) === "number")
+ endpoint = (position + count);
+ else
+ endpoint = (bytes.length - position);
+
+ var result = {
+ read: function () {
+ if (position >= endpoint)
+ return null;
+
+ var nextByte = bytes[position];
+ position += 1;
+ return nextByte;
+ }
+ };
+
+ Object.defineProperty(result, "eof", {
+ get: function () {
+ return (position >= endpoint);
+ },
+ configurable: true,
+ enumerable: true
+ });
+
+ return result;
+}
+
+// FIXME: improve
+export function _base64_to_uint8(base64String: string) {
+ const byteCharacters = atob(base64String);
+ const byteNumbers = new Array(byteCharacters.length);
+ for (let i = 0; i < byteCharacters.length; i++) {
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
+ }
+
+ return new Uint8Array(byteNumbers);
+}
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/mono/cwraps.ts b/src/mono/wasm/runtime/src/mono/cwraps.ts
new file mode 100644
index 00000000000000..c55a59b2d30be9
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/cwraps.ts
@@ -0,0 +1,57 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import { Module } from '../runtime'
+
+const fn_signatures: [ident: string, returnType: string | null, argTypes?: string[], opts?: any][] = [
+ ["mono_wasm_register_root", "number", ["number", "number", "string"]],
+ ["mono_wasm_deregister_root", null, ["number"]],
+ ["mono_wasm_string_get_data", null, ['number', 'number', 'number', 'number']],
+ ['mono_wasm_set_is_debugger_attached', 'void', ['bool']],
+ ['mono_wasm_send_dbg_command', 'bool', ['number', 'number', 'number', 'number', 'number']],
+ ['mono_wasm_send_dbg_command_with_parms', 'bool', ['number', 'number', 'number', 'number', 'number', 'number', 'string']],
+ ['mono_wasm_setenv', null, ['string', 'string']],
+ ['mono_wasm_parse_runtime_options', null, ['number', 'number']],
+ ['mono_wasm_strdup', 'number', ['string']],
+ ['mono_background_exec', null, []],
+ ["mono_set_timeout_exec", null, ['number']],
+ ['mono_wasm_load_icu_data', 'number', ['number']],
+ ['mono_wasm_get_icudt_name', 'string', ['string']],
+ ['mono_wasm_add_assembly', 'number', ['string', 'number', 'number']],
+ ['mono_wasm_add_satellite_assembly', 'void', ['string', 'string', 'number', 'number']],
+ ['mono_wasm_load_runtime', null, ['string', 'number']],
+ ['mono_wasm_exit', null, ['number']],
+]
+
+export interface t_Cwraps {
+ mono_wasm_register_root(start: CharPtr, size: number, name: CharPtr): number;
+ mono_wasm_deregister_root(addr: CharPtr): void;
+ mono_wasm_string_get_data(string: MonoString, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void;
+ mono_wasm_set_is_debugger_attached(value: boolean): void;
+ mono_wasm_send_dbg_command(id: number, command_set: number, command: number, data: VoidPtr, size: number): boolean;
+ mono_wasm_send_dbg_command_with_parms(id: number, command_set: number, command: number, data: VoidPtr, size: number, valtype: number, newvalue: CharPtr): boolean;
+ mono_wasm_setenv(name: string, value: string): void;
+ mono_wasm_strdup(value: string): number;
+ mono_wasm_parse_runtime_options(length: number, argv: VoidPtr): void;
+ mono_background_exec(): void;
+ mono_set_timeout_exec(id: number): void;
+ mono_wasm_load_icu_data(offset: VoidPtr): number;
+ mono_wasm_get_icudt_name(name: string): string;
+ mono_wasm_add_assembly(name: CharPtr, data: VoidPtr, size: number): number;
+ mono_wasm_add_satellite_assembly(name: CharPtr, culture: CharPtr, data: VoidPtr, size: number): void;
+ mono_wasm_load_runtime(unused: CharPtr, debug_level: number): void;
+ mono_wasm_exit(exit_code: number): number;
+}
+
+const wrapped_c_functions: t_Cwraps = {}
+for (let sig of fn_signatures) {
+ const wf: any = wrapped_c_functions;
+ // lazy init on first run
+ wf[sig[0]] = function () {
+ const fce = Module.cwrap(sig[0], sig[1], sig[2], sig[3])
+ wf[sig[0]] = fce;
+ return fce.apply(undefined, arguments);
+ };
+}
+
+export default wrapped_c_functions;
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/mono/debug.ts b/src/mono/wasm/runtime/src/mono/debug.ts
new file mode 100644
index 00000000000000..9f097b8933cfa8
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/debug.ts
@@ -0,0 +1,291 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import { Module, MONO } from '../runtime'
+import { toBase64StringImpl, _base64_to_uint8 } from './base64'
+import cwraps from './cwraps'
+import { mono_wasm_load_bytes_into_heap } from './init'
+
+var commands_received: any;
+var _call_function_res_cache: any = {}
+var _next_call_function_res_id = 0;
+
+export function mono_wasm_runtime_ready() {
+ MONO.mono_wasm_runtime_is_ready = true;
+
+ // FIXME: where should this go?
+ _next_call_function_res_id = 0;
+ _call_function_res_cache = {};
+
+ // DO NOT REMOVE - magic debugger init function
+ if ((globalThis).dotnetDebugger)
+ debugger;
+ else
+ console.debug("mono_wasm_runtime_ready", "fe00e07a-5519-4dfe-b35a-f867dbaf2e28");
+}
+
+export function mono_wasm_fire_debugger_agent_message() {
+ // eslint-disable-next-line no-debugger
+ debugger;
+}
+
+export function mono_wasm_add_dbg_command_received(res_ok: boolean, id: number, buffer: number, buffer_len: number) {
+ const assembly_data = new Uint8Array(Module.HEAPU8.buffer, buffer, buffer_len);
+ const base64String = toBase64StringImpl(assembly_data);
+ const buffer_obj = {
+ res_ok,
+ res: {
+ id,
+ value: base64String
+ }
+ }
+ commands_received = buffer_obj;
+}
+
+export function mono_wasm_send_dbg_command_with_parms(id: number, command_set: number, command: number, command_parameters: any, length: number, valtype: number, newvalue: number) {
+ const dataHeap = mono_wasm_load_bytes_into_heap(_base64_to_uint8(command_parameters));
+ cwraps.mono_wasm_send_dbg_command_with_parms(id, command_set, command, dataHeap, length, valtype, newvalue.toString());
+
+ const { res_ok, res } = commands_received;
+ if (!res_ok)
+ throw new Error(`Failed on mono_wasm_invoke_method_debugger_agent_with_parms`);
+ return res;
+}
+
+export function mono_wasm_send_dbg_command(id: number, command_set: number, command: number, command_parameters: any) {
+ var dataHeap = mono_wasm_load_bytes_into_heap(_base64_to_uint8(command_parameters));
+ cwraps.mono_wasm_send_dbg_command(id, command_set, command, dataHeap, command_parameters.length);
+
+ const { res_ok, res } = commands_received;
+ if (!res_ok)
+ throw new Error(`Failed on mono_wasm_send_dbg_command`);
+ return res;
+
+}
+
+export function mono_wasm_get_dbg_command_info() {
+ const { res_ok, res } = commands_received;
+ if (!res_ok)
+ throw new Error(`Failed on mono_wasm_get_dbg_command_info`);
+ return res;
+}
+
+export function mono_wasm_debugger_resume() {
+}
+
+export function mono_wasm_detach_debugger() {
+ cwraps.mono_wasm_set_is_debugger_attached(false);
+}
+
+/**
+ * Raises an event for the debug proxy
+ */
+export function mono_wasm_raise_debug_event(event: WasmEvent, args = {}) {
+ if (typeof event !== 'object')
+ throw new Error(`event must be an object, but got ${JSON.stringify(event)}`);
+
+ if (event.eventName === undefined)
+ throw new Error(`event.eventName is a required parameter, in event: ${JSON.stringify(event)}`);
+
+ if (typeof args !== 'object')
+ throw new Error(`args must be an object, but got ${JSON.stringify(args)}`);
+
+ console.debug('mono_wasm_debug_event_raised:aef14bca-5519-4dfe-b35a-f867abc123ae', JSON.stringify(event), JSON.stringify(args));
+}
+
+// Used by the debugger to enumerate loaded dlls and pdbs
+export function mono_wasm_get_loaded_files() {
+ cwraps.mono_wasm_set_is_debugger_attached(true);
+ return MONO.loaded_files;
+}
+
+function _create_proxy_from_object_id(objectId: string, details: any) {
+ if (objectId.startsWith('dotnet:array:')) {
+ const ret = details.map((p: any) => p.value);
+ return ret;
+ }
+
+ const proxy: any = {};
+ Object.keys(details).forEach(p => {
+ var prop = details[p];
+ if (prop.get !== undefined) {
+ Object.defineProperty(proxy,
+ prop.name,
+ {
+ get() {
+ return mono_wasm_send_dbg_command(-1, prop.get.commandSet, prop.get.command, prop.get.buffer);
+ },
+ set: function (newValue) {
+ mono_wasm_send_dbg_command_with_parms(-1, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue); return commands_received.res_ok;
+ }
+ }
+ );
+ } else if (prop.set !== undefined) {
+ Object.defineProperty(proxy,
+ prop.name,
+ {
+ get() {
+ return prop.value;
+ },
+ set: function (newValue) {
+ mono_wasm_send_dbg_command_with_parms(-1, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue); return commands_received.res_ok;
+ }
+ }
+ );
+ } else {
+ proxy[prop.name] = prop.value;
+ }
+ });
+ return proxy;
+}
+
+export function mono_wasm_call_function_on(request: CallRequest) {
+ if (request.arguments != undefined && !Array.isArray(request.arguments))
+ throw new Error(`"arguments" should be an array, but was ${request.arguments}`);
+
+ const objId = request.objectId;
+ const details = request.details;
+ let proxy;
+
+ if (objId.startsWith('dotnet:cfo_res:')) {
+ if (objId in _call_function_res_cache)
+ proxy = _call_function_res_cache[objId];
+ else
+ throw new Error(`Unknown object id ${objId}`);
+ } else {
+ proxy = _create_proxy_from_object_id(objId, details);
+ }
+
+ const fn_args = request.arguments != undefined ? request.arguments.map(a => JSON.stringify(a.value)) : [];
+ const fn_eval_str = `var fn = ${request.functionDeclaration}; fn.call (proxy, ...[${fn_args}]);`;
+
+ const local_eval = eval; // https://rollupjs.org/guide/en/#avoiding-eval
+ const fn_res = local_eval(fn_eval_str);
+ if (fn_res === undefined)
+ return { type: "undefined" };
+
+ if (Object(fn_res) !== fn_res) {
+ if (typeof (fn_res) == "object" && fn_res == null)
+ return { type: typeof (fn_res), subtype: `${fn_res}`, value: null };
+ return { type: typeof (fn_res), description: `${fn_res}`, value: `${fn_res}` };
+ }
+
+ if (request.returnByValue && fn_res.subtype == undefined)
+ return { type: "object", value: fn_res };
+
+ if (Object.getPrototypeOf(fn_res) == Array.prototype) {
+
+ const fn_res_id = _cache_call_function_res(fn_res);
+
+ return {
+ type: "object",
+ subtype: "array",
+ className: "Array",
+ description: `Array(${fn_res.length})`,
+ objectId: fn_res_id
+ };
+ }
+ if (fn_res.value !== undefined || fn_res.subtype !== undefined) {
+ return fn_res;
+ }
+
+ if (fn_res == proxy)
+ return { type: "object", className: "Object", description: "Object", objectId: objId };
+ const fn_res_id = _cache_call_function_res(fn_res);
+ return { type: "object", className: "Object", description: "Object", objectId: fn_res_id };
+}
+
+
+function _get_cfo_res_details(objectId: string, args: any) {
+ if (!(objectId in _call_function_res_cache))
+ throw new Error(`Could not find any object with id ${objectId}`);
+
+ const real_obj = _call_function_res_cache[objectId];
+
+ const descriptors = Object.getOwnPropertyDescriptors(real_obj);
+ if (args.accessorPropertiesOnly) {
+ Object.keys(descriptors).forEach(k => {
+ if (descriptors[k].get === undefined)
+ Reflect.deleteProperty(descriptors, k);
+ });
+ }
+
+ let res_details: any[] = [];
+ Object.keys(descriptors).forEach(k => {
+ let new_obj;
+ let prop_desc = descriptors[k];
+ if (typeof prop_desc.value == "object") {
+ // convert `{value: { type='object', ... }}`
+ // to `{ name: 'foo', value: { type='object', ... }}
+ new_obj = Object.assign({ name: k }, prop_desc);
+ } else if (prop_desc.value !== undefined) {
+ // This is needed for values that were not added by us,
+ // thus are like { value: 5 }
+ // instead of { value: { type = 'number', value: 5 }}
+ //
+ // This can happen, for eg., when `length` gets added for arrays
+ // or `__proto__`.
+ new_obj = {
+ name: k,
+ // merge/add `type` and `description` to `d.value`
+ value: Object.assign({ type: (typeof prop_desc.value), description: '' + prop_desc.value },
+ prop_desc)
+ };
+ } else if (prop_desc.get !== undefined) {
+ // The real_obj has the actual getter. We are just returning a placeholder
+ // If the caller tries to run function on the cfo_res object,
+ // that accesses this property, then it would be run on `real_obj`,
+ // which *has* the original getter
+ new_obj = {
+ name: k,
+ get: {
+ className: "Function",
+ description: `get ${k} () {}`,
+ type: "function"
+ }
+ };
+ } else {
+ new_obj = { name: k, value: { type: "symbol", value: "", description: "" } };
+ }
+
+ res_details.push(new_obj);
+ });
+
+ return { __value_as_json_string__: JSON.stringify(res_details) };
+}
+
+export function mono_wasm_get_details(objectId: string, args = {}) {
+ return _get_cfo_res_details(`dotnet:cfo_res:${objectId}`, args);
+}
+
+function _cache_call_function_res(obj: any) {
+ const id = `dotnet:cfo_res:${_next_call_function_res_id++}`;
+ _call_function_res_cache[id] = obj;
+ return id;
+}
+
+export function mono_wasm_release_object(objectId: string) {
+ if (objectId in _call_function_res_cache)
+ delete _call_function_res_cache[objectId];
+}
+
+type CallDetails = {
+ value: string
+}
+
+type CallArgs = {
+ value: string
+}
+
+type CallRequest = {
+ arguments: undefined | Array,
+ objectId: string,
+ details: CallDetails[],
+ functionDeclaration: string
+ returnByValue: boolean,
+}
+
+type WasmEvent = {
+ eventName: string, // - name of the event being raised
+ [i: string]: any, // - arguments for the event itself
+}
diff --git a/src/mono/wasm/runtime/src/mono/icu.ts b/src/mono/wasm/runtime/src/mono/icu.ts
new file mode 100644
index 00000000000000..041ba2cc5908e6
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/icu.ts
@@ -0,0 +1,60 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import cwraps from './cwraps'
+
+let num_icu_assets_loaded_successfully = 0;
+
+// @offset must be the address of an ICU data archive in the native heap.
+// returns true on success.
+export function mono_wasm_load_icu_data(offset: VoidPtr): boolean {
+ var ok = (cwraps.mono_wasm_load_icu_data(offset)) === 1;
+ if (ok)
+ num_icu_assets_loaded_successfully++;
+ return ok;
+}
+
+// Get icudt.dat exact filename that matches given culture, examples:
+// "ja" -> "icudt_CJK.dat"
+// "en_US" (or "en-US" or just "en") -> "icudt_EFIGS.dat"
+// etc, see "mono_wasm_get_icudt_name" implementation in pal_icushim_static.c
+export function mono_wasm_get_icudt_name(culture: string): string {
+ return cwraps.mono_wasm_get_icudt_name(culture);
+}
+
+
+// Performs setup for globalization.
+// @globalization_mode is one of "icu", "invariant", or "auto".
+// "auto" will use "icu" if any ICU data archives have been loaded,
+// otherwise "invariant".
+export function mono_wasm_globalization_init(globalization_mode: GlobalizationMode) {
+ var invariantMode = false;
+
+ if (globalization_mode === "invariant")
+ invariantMode = true;
+
+ if (!invariantMode) {
+ if (num_icu_assets_loaded_successfully > 0) {
+ console.debug("MONO_WASM: ICU data archive(s) loaded, disabling invariant mode");
+ } else if (globalization_mode !== "icu") {
+ console.debug("MONO_WASM: ICU data archive(s) not loaded, using invariant globalization mode");
+ invariantMode = true;
+ } else {
+ var msg = "invariant globalization mode is inactive and no ICU data archives were loaded";
+ console.error("MONO_WASM: ERROR: " + msg);
+ throw new Error(msg);
+ }
+ }
+
+ if (invariantMode)
+ cwraps.mono_wasm_setenv("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1");
+
+ // Set globalization mode to PredefinedCulturesOnly
+ cwraps.mono_wasm_setenv("DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", "1");
+}
+
+export const enum GlobalizationMode {
+ ICU = "icu", // load ICU globalization data from any runtime assets with behavior "icu".
+ INVARIANT = "invariant", // operate in invariant globalization mode.
+ AUTO = "auto" // (default): if "icu" behavior assets are present, use ICU, otherwise invariant.
+}
diff --git a/src/mono/wasm/runtime/src/mono/init.ts b/src/mono/wasm/runtime/src/mono/init.ts
new file mode 100644
index 00000000000000..fd940352f13bd2
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/init.ts
@@ -0,0 +1,498 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import { Module, MONO } from '../runtime'
+import { AssetEntry, MonoConfig } from './types'
+import cwraps from './cwraps'
+import { mono_wasm_runtime_ready } from './debug';
+import { mono_wasm_globalization_init, mono_wasm_load_icu_data } from './icu';
+import { toBase64StringImpl } from './base64';
+import { mono_wasm_init_aot_profiler, mono_wasm_init_coverage_profiler } from './profiler';
+
+// Set environment variable NAME to VALUE
+// Should be called before mono_load_runtime_and_bcl () in most cases
+export function mono_wasm_setenv(name: string, value: string) {
+ cwraps.mono_wasm_setenv(name, value);
+}
+
+export function mono_wasm_set_runtime_options(options: string[]) {
+ var argv = Module._malloc(options.length * 4);
+ let aindex = 0;
+ for (var i = 0; i < options.length; ++i) {
+ Module.setValue(argv + (aindex * 4), cwraps.mono_wasm_strdup(options[i]), "i32");
+ aindex += 1;
+ }
+ cwraps.mono_wasm_parse_runtime_options(options.length, argv);
+}
+
+function _handle_loaded_asset(ctx: MonoInitContext, asset: AssetEntry, url: string, blob: ArrayBuffer) {
+ var bytes = new Uint8Array(blob);
+ if (ctx.tracing)
+ console.log(`MONO_WASM: Loaded:${asset.name} as ${asset.behavior} size ${bytes.length} from ${url}`);
+
+ var virtualName: string = asset.virtual_path || asset.name;
+ var offset: VoidPtr | null = null;
+
+ switch (asset.behavior) {
+ case "resource":
+ case "assembly":
+ ctx.loaded_files.push({ url: url, file: virtualName });
+ case "heap":
+ case "icu":
+ offset = mono_wasm_load_bytes_into_heap(bytes);
+ ctx.loaded_assets[virtualName] = [offset, bytes.length];
+ break;
+
+ case "vfs":
+ // FIXME
+ var lastSlash = virtualName.lastIndexOf("/");
+ var parentDirectory = (lastSlash > 0)
+ ? virtualName.substr(0, lastSlash)
+ : null;
+ var fileName = (lastSlash > 0)
+ ? virtualName.substr(lastSlash + 1)
+ : virtualName;
+ if (fileName.startsWith("/"))
+ fileName = fileName.substr(1);
+ if (parentDirectory) {
+ if (ctx.tracing)
+ console.log("MONO_WASM: Creating directory '" + parentDirectory + "'");
+
+ var pathRet = ctx.createPath(
+ "/", parentDirectory, true, true // fixme: should canWrite be false?
+ );
+ } else {
+ parentDirectory = "/";
+ }
+
+ if (ctx.tracing)
+ console.log("MONO_WASM: Creating file '" + fileName + "' in directory '" + parentDirectory + "'");
+
+ if (!mono_wasm_load_data_archive(bytes, parentDirectory)) {
+ var fileRet = ctx.createDataFile(
+ parentDirectory, fileName,
+ bytes, true /* canRead */, true /* canWrite */, true /* canOwn */
+ );
+ }
+ break;
+
+ default:
+ throw new Error(`Unrecognized asset behavior:${asset.behavior}, for asset ${asset.name}`);
+ }
+
+ if (asset.behavior === "assembly") {
+ var hasPpdb = cwraps.mono_wasm_add_assembly(virtualName, offset!, bytes.length);
+
+ if (!hasPpdb) {
+ var index = ctx.loaded_files.findIndex(element => element.file == virtualName);
+ ctx.loaded_files.splice(index, 1);
+ }
+ }
+ else if (asset.behavior === "icu") {
+ if (!mono_wasm_load_icu_data(offset!))
+ console.error("Error loading ICU asset", asset.name);
+ }
+ else if (asset.behavior === "resource") {
+ cwraps.mono_wasm_add_satellite_assembly(virtualName, asset.culture!, offset!, bytes.length);
+ }
+}
+
+// Initializes the runtime and loads assemblies, debug information, and other files.
+// @args is a dictionary-style Object with the following properties:
+// assembly_root: (required) the subfolder containing managed assemblies and pdbs
+// debug_level or enable_debugging: (required)
+// assets: (required) a list of assets to load along with the runtime. each asset
+// is a dictionary-style Object with the following properties:
+// name: (required) the name of the asset, including extension.
+// behavior: (required) determines how the asset will be handled once loaded:
+// "heap": store asset into the native heap
+// "assembly": load asset as a managed assembly (or debugging information)
+// "resource": load asset as a managed resource assembly
+// "icu": load asset as an ICU data archive
+// "vfs": load asset into the virtual filesystem (for fopen, File.Open, etc)
+// load_remote: (optional) if true, an attempt will be made to load the asset
+// from each location in @args.remote_sources.
+// virtual_path: (optional) if specified, overrides the path of the asset in
+// the virtual filesystem and similar data structures once loaded.
+// is_optional: (optional) if true, any failure to load this asset will be ignored.
+// loaded_cb: (required) a function () invoked when loading has completed.
+// fetch_file_cb: (optional) a function (string) invoked to fetch a given file.
+// If no callback is provided a default implementation appropriate for the current
+// environment will be selected (readFileSync in node, fetch elsewhere).
+// If no default implementation is available this call will fail.
+// remote_sources: (optional) additional search locations for assets.
+// sources will be checked in sequential order until the asset is found.
+// the string "./" indicates to load from the application directory (as with the
+// files in assembly_list), and a fully-qualified URL like "https://example.com/" indicates
+// that asset loads can be attempted from a remote server. Sources must end with a "/".
+// environment_variables: (optional) dictionary-style Object containing environment variables
+// runtime_options: (optional) array of runtime options as strings
+// aot_profiler_options: (optional) dictionary-style Object. see the comments for
+// mono_wasm_init_aot_profiler. If omitted, aot profiler will not be initialized.
+// coverage_profiler_options: (optional) dictionary-style Object. see the comments for
+// mono_wasm_init_coverage_profiler. If omitted, coverage profiler will not be initialized.
+// globalization_mode: (optional) configures the runtime's globalization mode:
+// "icu": load ICU globalization data from any runtime assets with behavior "icu".
+// "invariant": operate in invariant globalization mode.
+// "auto" (default): if "icu" behavior assets are present, use ICU, otherwise invariant.
+// diagnostic_tracing: (optional) enables diagnostic log messages during startup
+export function mono_load_runtime_and_bcl_args(args: MonoConfig) {
+ try {
+ return _load_assets_and_runtime(args);
+ } catch (exc: any) {
+ console.error("error in mono_load_runtime_and_bcl_args:", exc.toString());
+ throw exc;
+ }
+}
+
+function _apply_configuration_from_args(args: MonoConfig) {
+ for (var k in (args.environment_variables || {}))
+ mono_wasm_setenv(k, args.environment_variables![k]);
+
+ if (args.runtime_options)
+ mono_wasm_set_runtime_options(args.runtime_options);
+
+ if (args.aot_profiler_options)
+ mono_wasm_init_aot_profiler(args.aot_profiler_options);
+
+ if (args.coverage_profiler_options)
+ mono_wasm_init_coverage_profiler(args.coverage_profiler_options);
+}
+
+function _get_fetch_file_cb_from_args(args: MonoConfig): (asset: string) => Promise {
+ if (typeof (args.fetch_file_cb) === "function")
+ return args.fetch_file_cb;
+
+ if (ENVIRONMENT_IS_NODE) {
+ var fs = require('fs');
+ return function (asset) {
+ console.debug("MONO_WASM: Loading... " + asset);
+ var binary = fs.readFileSync(asset);
+ var resolve_func2 = function (resolve: Function, reject: Function) {
+ resolve(new Uint8Array(binary));
+ };
+
+ var resolve_func1 = function (resolve: Function, reject: Function) {
+ var response = {
+ ok: true,
+ url: asset,
+ arrayBuffer: function () {
+ return new Promise(resolve_func2);
+ }
+ };
+ resolve(response);
+ };
+
+ return new Promise(resolve_func1);
+ };
+ } else if (typeof (fetch) === "function") {
+ return function (asset) {
+ return fetch(asset, { credentials: 'same-origin' });
+ };
+ } else {
+ throw new Error("No fetch_file_cb was provided and this environment does not expose 'fetch'.");
+ }
+}
+
+function _finalize_startup(args: MonoConfig, ctx: MonoInitContext) {
+ var loaded_files_with_debug_info: string[] = [];
+ ctx.loaded_files.forEach(value => loaded_files_with_debug_info.push(value.url));
+ MONO.loaded_assets = ctx.loaded_assets;
+ MONO.loaded_files = loaded_files_with_debug_info;
+ if (ctx.tracing) {
+ console.log("MONO_WASM: loaded_assets: " + JSON.stringify(ctx.loaded_assets));
+ console.log("MONO_WASM: loaded_files: " + JSON.stringify(ctx.loaded_files));
+ }
+
+ var load_runtime = cwraps.mono_wasm_load_runtime;
+
+ console.debug("MONO_WASM: Initializing mono runtime");
+
+ mono_wasm_globalization_init(args.globalization_mode!);
+
+ if (ENVIRONMENT_IS_SHELL || ENVIRONMENT_IS_NODE) {
+ try {
+ load_runtime("unused", args.debug_level || 0);
+ } catch (ex: any) {
+ Module.print("MONO_WASM: load_runtime () failed: " + ex);
+ Module.print("MONO_WASM: Stacktrace: \n");
+ Module.print(ex.stack);
+
+ var wasm_exit = cwraps.mono_wasm_exit;
+ wasm_exit(1);
+ }
+ } else {
+ load_runtime("unused", args.debug_level || 0);
+ }
+
+ let tz;
+ try {
+ tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
+ } catch { }
+ mono_wasm_setenv("TZ", tz || "UTC");
+ mono_wasm_runtime_ready();
+ args.loaded_cb();
+}
+
+function _load_assets_and_runtime(args: MonoConfig) {
+ if (args.enable_debugging)
+ args.debug_level = args.enable_debugging;
+ if (args.assembly_list)
+ throw new Error("Invalid args (assembly_list was replaced by assets)");
+ if (args.runtime_assets)
+ throw new Error("Invalid args (runtime_assets was replaced by assets)");
+ if (args.runtime_asset_sources)
+ throw new Error("Invalid args (runtime_asset_sources was replaced by remote_sources)");
+ if (!args.loaded_cb)
+ throw new Error("loaded_cb not provided");
+
+ var ctx: MonoInitContext = {
+ tracing: args.diagnostic_tracing || false,
+ pending_count: args.assets.length,
+ loaded_assets: Object.create(null),
+ // dlls and pdbs, used by blazor and the debugger
+ loaded_files: [],
+ createPath: Module.FS_createPath,
+ createDataFile: Module.FS_createDataFile
+ };
+
+ if (ctx.tracing)
+ console.log("mono_wasm_load_runtime_with_args", JSON.stringify(args));
+
+ _apply_configuration_from_args(args);
+
+ var fetch_file_cb = _get_fetch_file_cb_from_args(args);
+
+ var onPendingRequestComplete = function () {
+ --ctx.pending_count;
+
+ if (ctx.pending_count === 0) {
+ try {
+ _finalize_startup(args, ctx);
+ } catch (exc) {
+ console.error("Unhandled exception in _finalize_startup", exc);
+ throw exc;
+ }
+ }
+ };
+
+ var processFetchResponseBuffer = function (asset: AssetEntry, url: string, buffer: ArrayBuffer) {
+ try {
+ _handle_loaded_asset(ctx, asset, url, buffer);
+ } catch (exc) {
+ console.error(`Unhandled exception in processFetchResponseBuffer ${url}`, exc);
+ throw exc;
+ } finally {
+ onPendingRequestComplete();
+ }
+ };
+
+ args.assets.forEach(function (asset: AssetEntry) {
+ var sourceIndex = 0;
+ var sourcesList = asset.load_remote ? args.remote_sources! : [""];
+
+ var handleFetchResponse = function (response: Response) {
+ if (!response.ok) {
+ try {
+ attemptNextSource();
+ return;
+ } catch (exc) {
+ console.error("MONO_WASM: Unhandled exception in handleFetchResponse attemptNextSource for asset", asset.name, exc);
+ throw exc;
+ }
+ }
+
+ try {
+ var bufferPromise = response.arrayBuffer();
+ bufferPromise.then((data) => processFetchResponseBuffer(asset, response.url, data));
+ } catch (exc) {
+ console.error("MONO_WASM: Unhandled exception in handleFetchResponse for asset", asset.name, exc);
+ attemptNextSource();
+ }
+ };
+
+ const attemptNextSource = function () {
+ if (sourceIndex >= sourcesList.length) {
+ var msg = "MONO_WASM: Failed to load " + asset.name;
+ try {
+ var isOk = asset.is_optional ||
+ (asset.name.match(/\.pdb$/) && args.ignore_pdb_load_errors);
+
+ if (isOk)
+ console.debug(msg);
+ else {
+ console.error(msg);
+ throw new Error(msg);
+ }
+ } finally {
+ onPendingRequestComplete();
+ }
+ }
+
+ var sourcePrefix = sourcesList[sourceIndex];
+ sourceIndex++;
+
+ // HACK: Special-case because MSBuild doesn't allow "" as an attribute
+ if (sourcePrefix === "./")
+ sourcePrefix = "";
+
+ var attemptUrl;
+ if (sourcePrefix.trim() === "") {
+ if (asset.behavior === "assembly")
+ attemptUrl = locateFile(args.assembly_root + "/" + asset.name);
+ else if (asset.behavior === "resource") {
+ var path = asset.culture !== '' ? `${asset.culture}/${asset.name}` : asset.name;
+ attemptUrl = locateFile(args.assembly_root + "/" + path);
+ }
+ else
+ attemptUrl = asset.name;
+ } else {
+ attemptUrl = sourcePrefix + asset.name;
+ }
+
+ try {
+ if (asset.name === attemptUrl) {
+ if (ctx.tracing)
+ console.log("Attempting to fetch '" + attemptUrl + "'");
+ } else {
+ if (ctx.tracing)
+ console.log("Attempting to fetch '" + attemptUrl + "' for", asset.name);
+ }
+ var fetch_promise = fetch_file_cb(attemptUrl);
+ fetch_promise.then(handleFetchResponse);
+ } catch (exc) {
+ console.error("MONO_WASM: Error fetching " + attemptUrl, exc);
+ attemptNextSource();
+ }
+ };
+
+ attemptNextSource();
+ });
+}
+
+// used from ASP.NET
+export function mono_wasm_load_data_archive(data: TypedArray, prefix: string) {
+ if (data.length < 8)
+ return false;
+
+ var dataview = new DataView(data.buffer);
+ var magic = dataview.getUint32(0, true);
+ // get magic number
+ if (magic != 0x626c6174) {
+ return false;
+ }
+ var manifestSize = dataview.getUint32(4, true);
+ if (manifestSize == 0 || data.length < manifestSize + 8)
+ return false;
+
+ var manifest;
+ try {
+ var manifestContent = Module.UTF8ArrayToString(data, 8, manifestSize);
+ manifest = JSON.parse(manifestContent);
+ if (!(manifest instanceof Array))
+ return false;
+ } catch (exc) {
+ return false;
+ }
+
+ data = data.slice(manifestSize + 8);
+
+ // Create the folder structure
+ // /usr/share/zoneinfo
+ // /usr/share/zoneinfo/Africa
+ // /usr/share/zoneinfo/Asia
+ // ..
+
+ var folders = new Set()
+ manifest.filter(m => {
+ var file = m[0];
+ var last = file.lastIndexOf("/");
+ var directory = file.slice(0, last + 1);
+ folders.add(directory);
+ });
+ folders.forEach(folder => {
+ Module['FS_createPath'](prefix, folder, true, true);
+ });
+
+ for (var row of manifest) {
+ var name = row[0];
+ var length = row[1];
+ var bytes = data.slice(0, length);
+ Module['FS_createDataFile'](prefix, name, bytes, true, true);
+ data = data.slice(length);
+ }
+ return true;
+}
+
+/**
+ * Loads the mono config file (typically called mono-config.json) asynchroniously
+ * Note: the run dependencies are so emsdk actually awaits it in order.
+ *
+ * @param {string} configFilePath - relative path to the config file
+ * @throws Will throw an error if the config file loading fails
+ */
+export async function mono_wasm_load_config(configFilePath: string) {
+ Module.addRunDependency(configFilePath);
+ try {
+ let config = null;
+ // NOTE: when we add nodejs make sure to include the nodejs fetch package
+ if (ENVIRONMENT_IS_WEB) {
+ const configRaw = await fetch(configFilePath);
+ config = await configRaw.json();
+ } else if (ENVIRONMENT_IS_NODE) {
+ config = require(configFilePath);
+ } else { // shell or worker
+ config = JSON.parse(read(configFilePath)); // read is a v8 debugger command
+ }
+ MONO.config = config;
+ Module.config = MONO.config;
+ } catch (e) {
+ const errMessage = "failed to load config file " + configFilePath;
+ console.error(errMessage)
+ MONO.config = { message: errMessage, error: e };
+ Module.config = MONO.config;
+ } finally {
+ Module.removeRunDependency(configFilePath);
+ }
+}
+
+export function mono_wasm_asm_loaded(assembly_name: number, assembly_ptr: number, assembly_len: number, pdb_ptr: number, pdb_len: number) {
+ // Only trigger this codepath for assemblies loaded after app is ready
+ if (MONO.mono_wasm_runtime_is_ready !== true)
+ return;
+
+ const assembly_name_str = assembly_name !== 0 ? Module.UTF8ToString(assembly_name).concat('.dll') : '';
+ const assembly_data = new Uint8Array(Module.HEAPU8.buffer, assembly_ptr, assembly_len);
+ const assembly_b64 = toBase64StringImpl(assembly_data);
+
+ let pdb_b64;
+ if (pdb_ptr) {
+ const pdb_data = new Uint8Array(Module.HEAPU8.buffer, pdb_ptr, pdb_len);
+ pdb_b64 = toBase64StringImpl(pdb_data);
+ }
+
+ MONO.mono_wasm_raise_debug_event({
+ eventName: 'AssemblyLoaded',
+ assembly_name: assembly_name_str,
+ assembly_b64,
+ pdb_b64
+ });
+}
+
+// @bytes must be a typed array. space is allocated for it in the native heap
+// and it is copied to that location. returns the address of the allocation.
+export function mono_wasm_load_bytes_into_heap(bytes: Uint8Array): VoidPtr {
+ var memoryOffset = Module._malloc(bytes.length);
+ var heapBytes = new Uint8Array(Module.HEAPU8.buffer, memoryOffset, bytes.length);
+ heapBytes.set(bytes);
+ return memoryOffset;
+}
+
+type MonoInitContext = {
+ tracing: boolean,
+ pending_count: number,
+ loaded_files: { url: string, file: string }[],
+ loaded_assets: { [id: string]: [VoidPtr, number] },
+ createPath: Function,
+ createDataFile: Function
+}
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/mono/profiler.ts b/src/mono/wasm/runtime/src/mono/profiler.ts
new file mode 100644
index 00000000000000..270ef69061345f
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/profiler.ts
@@ -0,0 +1,48 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import { Module } from '../runtime'
+
+// Initialize the AOT profiler with OPTIONS.
+// Requires the AOT profiler to be linked into the app.
+// options = { write_at: "", send_to: "" }
+// should be in the format ::.
+// write_at defaults to 'WebAssembly.Runtime::StopProfile'.
+// send_to defaults to 'WebAssembly.Runtime::DumpAotProfileData'.
+// DumpAotProfileData stores the data into Module.aot_profile_data.
+//
+export function mono_wasm_init_aot_profiler(options: AOTProfilerOptions) {
+ if (options == null)
+ options = {}
+ if (!('write_at' in options))
+ options.write_at = 'Interop/Runtime::StopProfile';
+ if (!('send_to' in options))
+ options.send_to = 'Interop/Runtime::DumpAotProfileData';
+ var arg = "aot:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to;
+ Module.ccall('mono_wasm_load_profiler_aot', null, ['string'], [arg]);
+}
+
+// options = { write_at: "", send_to: "" }
+// should be in the format ::.
+// write_at defaults to 'WebAssembly.Runtime::StopProfile'.
+// send_to defaults to 'WebAssembly.Runtime::DumpCoverageProfileData'.
+// DumpCoverageProfileData stores the data into Module.coverage_profile_data.
+export function mono_wasm_init_coverage_profiler(options: CoverageProfilerOptions) {
+ if (options == null)
+ options = {}
+ if (!('write_at' in options))
+ options.write_at = 'WebAssembly.Runtime::StopProfile';
+ if (!('send_to' in options))
+ options.send_to = 'WebAssembly.Runtime::DumpCoverageProfileData';
+ var arg = "coverage:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to;
+ Module.ccall('mono_wasm_load_profiler_coverage', null, ['string'], [arg]);
+}
+
+export type AOTProfilerOptions = {
+ write_at?: string, // should be in the format ::, default: 'WebAssembly.Runtime::StopProfile'
+ send_to?: string // should be in the format ::, default: 'WebAssembly.Runtime::DumpAotProfileData' (DumpAotProfileData stores the data into Module.aot_profile_data.)
+}
+export type CoverageProfilerOptions = {
+ write_at?: string, // should be in the format ::, default: 'WebAssembly.Runtime::StopProfile'
+ send_to?: string // should be in the format ::, default: 'WebAssembly.Runtime::DumpCoverageProfileData' (DumpCoverageProfileData stores the data into Module.coverage_profile_data.)
+}
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/mono/roots.ts b/src/mono/wasm/runtime/src/mono/roots.ts
new file mode 100644
index 00000000000000..2c6e4230eb7487
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/roots.ts
@@ -0,0 +1,295 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import cwraps from './cwraps'
+import { Module } from '../runtime'
+
+const maxScratchRoots = 8192;
+let _scratch_root_buffer: WasmRootBuffer | null = null;
+let _scratch_root_free_indices: Int32Array | null = null;
+let _scratch_root_free_indices_count = 0;
+const _scratch_root_free_instances: WasmRoot[] = [];
+
+/**
+ * Allocates a block of memory that can safely contain pointers into the managed heap.
+ * The result object has get(index) and set(index, value) methods that can be used to retrieve and store managed pointers.
+ * Once you are done using the root buffer, you must call its release() method.
+ * For small numbers of roots, it is preferable to use the mono_wasm_new_root and mono_wasm_new_roots APIs instead.
+ */
+export function mono_wasm_new_root_buffer(capacity: number, msg: string): WasmRootBuffer {
+ if (capacity <= 0)
+ throw new Error("capacity >= 1");
+
+ capacity = capacity | 0;
+
+ var capacityBytes = capacity * 4;
+ var offset = Module._malloc(capacityBytes);
+ if ((offset % 4) !== 0)
+ throw new Error("Malloc returned an unaligned offset");
+
+ _zero_region(offset, capacityBytes);
+
+ return new WasmRootBuffer(offset, capacity, true, msg);
+}
+
+/**
+ * Creates a root buffer object representing an existing allocation in the native heap and registers
+ * the allocation with the GC. The caller is responsible for managing the lifetime of the allocation.
+ */
+export function mono_wasm_new_root_buffer_from_pointer(offset: number, capacity: number, msg: string): WasmRootBuffer {
+ if (capacity <= 0)
+ throw new Error("capacity >= 1");
+
+ capacity = capacity | 0;
+
+ var capacityBytes = capacity * 4;
+ if ((offset % 4) !== 0)
+ throw new Error("Unaligned offset");
+
+ _zero_region(offset, capacityBytes);
+
+ return new WasmRootBuffer(offset, capacity, false, msg);
+}
+
+/**
+ * Allocates temporary storage for a pointer into the managed heap.
+ * Pointers stored here will be visible to the GC, ensuring that the object they point to aren't moved or collected.
+ * If you already have a managed pointer you can pass it as an argument to initialize the temporary storage.
+ * The result object has get() and set(value) methods, along with a .value property.
+ * When you are done using the root you must call its .release() method.
+ */
+export function mono_wasm_new_root(value: ManagedPointer | undefined = undefined): WasmRoot {
+ var result: WasmRoot;
+
+ if (_scratch_root_free_instances.length > 0) {
+ result = _scratch_root_free_instances.pop()!;
+ } else {
+ var index = _mono_wasm_claim_scratch_index();
+ var buffer = _scratch_root_buffer;
+
+ result = new WasmRoot(buffer!, index);
+ }
+
+ if (value !== undefined) {
+ if (typeof (value) !== "number")
+ throw new Error("value must be an address in the managed heap");
+
+ result.set(value);
+ } else {
+ result.set(0);
+ }
+
+ return result;
+}
+
+/**
+ * Allocates 1 or more temporary roots, accepting either a number of roots or an array of pointers.
+ * mono_wasm_new_roots(n): returns an array of N zero-initialized roots.
+ * mono_wasm_new_roots([a, b, ...]) returns an array of new roots initialized with each element.
+ * Each root must be released with its release method, or using the mono_wasm_release_roots API.
+ */
+export function mono_wasm_new_roots(count_or_values: number | ManagedPointer[]): WasmRoot[] {
+ var result;
+
+ if (Array.isArray(count_or_values)) {
+ result = new Array(count_or_values.length);
+ for (var i = 0; i < result.length; i++)
+ result[i] = mono_wasm_new_root(count_or_values[i]);
+ } else if ((count_or_values | 0) > 0) {
+ result = new Array(count_or_values);
+ for (var i = 0; i < result.length; i++)
+ result[i] = mono_wasm_new_root();
+ } else {
+ throw new Error("count_or_values must be either an array or a number greater than 0");
+ }
+
+ return result;
+}
+
+/**
+ * Releases 1 or more root or root buffer objects.
+ * Multiple objects may be passed on the argument list.
+ * 'undefined' may be passed as an argument so it is safe to call this method from finally blocks
+ * even if you are not sure all of your roots have been created yet.
+ * @param {... WasmRoot} roots
+ */
+export function mono_wasm_release_roots() {
+ for (var i = 0; i < arguments.length; i++) {
+ if (!arguments[i])
+ continue;
+
+ arguments[i].release();
+ }
+}
+
+function _zero_region(byteOffset: number, sizeBytes: number) {
+ if (((byteOffset % 4) === 0) && ((sizeBytes % 4) === 0))
+ Module.HEAP32.fill(0, byteOffset / 4, sizeBytes / 4);
+ else
+ Module.HEAP8.fill(0, byteOffset, sizeBytes);
+}
+
+function _mono_wasm_release_scratch_index(index: number) {
+ if (index === undefined)
+ return;
+
+ _scratch_root_buffer!.set(index, 0);
+ _scratch_root_free_indices![_scratch_root_free_indices_count] = index;
+ _scratch_root_free_indices_count++;
+}
+
+function _mono_wasm_claim_scratch_index() {
+ if (!_scratch_root_buffer || !_scratch_root_free_indices) {
+ _scratch_root_buffer = mono_wasm_new_root_buffer(maxScratchRoots, "js roots");
+
+ _scratch_root_free_indices = new Int32Array(maxScratchRoots);
+ _scratch_root_free_indices_count = maxScratchRoots;
+ for (var i = 0; i < maxScratchRoots; i++)
+ _scratch_root_free_indices[i] = maxScratchRoots - i - 1;
+ }
+
+ if (_scratch_root_free_indices_count < 1)
+ throw new Error("Out of scratch root space");
+
+ var result = _scratch_root_free_indices[_scratch_root_free_indices_count - 1];
+ _scratch_root_free_indices_count--;
+ return result;
+}
+
+
+export class WasmRootBuffer {
+ private __count: number;
+ private length: number;
+ private __offset: number;
+ private __offset32: number;
+ private __handle: number;
+ private __ownsAllocation: boolean;
+
+ constructor(offset: number, capacity: number, ownsAllocation: boolean, msg: string) {
+ const capacityBytes = capacity * 4;
+
+ this.__offset = offset;
+ this.__offset32 = (offset / 4) | 0;
+ this.__count = capacity;
+ this.length = capacity;
+ this.__handle = cwraps.mono_wasm_register_root(offset, capacityBytes, msg || 0);
+ this.__ownsAllocation = ownsAllocation;
+ }
+
+ _throw_index_out_of_range() {
+ throw new Error("index out of range");
+ }
+
+ _check_in_range(index: number) {
+ if ((index >= this.__count) || (index < 0))
+ this._throw_index_out_of_range();
+ }
+
+ get_address(index: number): NativePointer {
+ this._check_in_range(index);
+ return this.__offset + (index * 4);
+ }
+
+ get_address_32(index: number) {
+ this._check_in_range(index);
+ return this.__offset32 + index;
+ }
+
+ get(index: number): ManagedPointer {
+ this._check_in_range(index);
+ return Module.HEAP32[this.get_address_32(index)];
+ }
+
+ set(index: number, value: ManagedPointer) {
+ Module.HEAP32[this.get_address_32(index)] = value;
+ return value;
+ }
+
+ _unsafe_get(index: number) {
+ return Module.HEAP32[this.__offset32 + index];
+ }
+
+ _unsafe_set(index: number, value: ManagedPointer) {
+ Module.HEAP32[this.__offset32 + index] = value;
+ }
+
+ clear() {
+ if (this.__offset)
+ _zero_region(this.__offset, this.__count * 4);
+ }
+
+ release() {
+ if (this.__offset && this.__ownsAllocation) {
+ cwraps.mono_wasm_deregister_root(this.__offset);
+ _zero_region(this.__offset, this.__count * 4);
+ Module._free(this.__offset);
+ }
+
+ this.__handle = this.__offset = this.__count = this.__offset32 = 0;
+ }
+
+ toString() {
+ return "[root buffer @" + this.get_address(0) + ", size " + this.__count + "]";
+ }
+}
+
+export class WasmRoot {
+ private __buffer: WasmRootBuffer;
+ private __index: number;
+
+ constructor(buffer: WasmRootBuffer, index: number) {
+ this.__buffer = buffer;//TODO
+ this.__index = index;
+ }
+
+ get_address(): NativePointer {
+ return this.__buffer.get_address(this.__index);
+ }
+
+ get_address_32(): number {
+ return this.__buffer.get_address_32(this.__index);
+ }
+
+ get(): ManagedPointer {
+ var result = this.__buffer._unsafe_get(this.__index);
+ return result;
+ }
+
+ set(value: ManagedPointer) {
+ this.__buffer._unsafe_set(this.__index, value);
+ return value;
+ }
+
+ get value(): ManagedPointer {
+ return this.get();
+ }
+
+ set value(value: ManagedPointer) {
+ this.set(value);
+ }
+
+ /** @returns {ManagedPointer} */
+ valueOf(): ManagedPointer {
+ return this.get();
+ }
+
+ clear() {
+ this.set(0);
+ }
+
+ release() {
+ const maxPooledInstances = 128;
+ if (_scratch_root_free_instances.length > maxPooledInstances) {
+ _mono_wasm_release_scratch_index(this.__index);
+ (this).__buffer = null;
+ this.__index = 0;
+ } else {
+ this.set(0);
+ _scratch_root_free_instances.push(this);
+ }
+ }
+
+ toString() {
+ return "[root @" + this.get_address() + "]";
+ }
+}
diff --git a/src/mono/wasm/runtime/src/mono/scheduling.ts b/src/mono/wasm/runtime/src/mono/scheduling.ts
new file mode 100644
index 00000000000000..060fc9df99ff5f
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/scheduling.ts
@@ -0,0 +1,78 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import cwraps from './cwraps'
+
+const timeout_queue: Function[] = [];
+let spread_timers_maximum = 0;
+let isChromium = false;
+let pump_count = 0;
+
+if (globalThis.navigator) {
+ const nav: any = globalThis.navigator;
+ if (nav.userAgentData && nav.userAgentData.brands) {
+ isChromium = nav.userAgentData.brands.some((i: any) => i.brand == 'Chromium');
+ }
+ else if (nav.userAgent) {
+ isChromium = nav.userAgent.includes("Chrome");
+ }
+}
+
+function pump_message() {
+ while (timeout_queue.length > 0) {
+ --pump_count;
+ const cb: Function = timeout_queue.shift()!;
+ cb();
+ }
+ while (pump_count > 0) {
+ --pump_count;
+ cwraps.mono_background_exec();
+ }
+}
+
+function mono_wasm_set_timeout_exec(id: number) {
+ cwraps.mono_set_timeout_exec(id);
+}
+
+export function prevent_timer_throttling() {
+ if (isChromium) {
+ return;
+ }
+
+ // this will schedule timers every second for next 6 minutes, it should be called from WebSocket event, to make it work
+ // on next call, it would only extend the timers to cover yet uncovered future
+ let now = new Date().valueOf();
+ const desired_reach_time = now + (1000 * 60 * 6);
+ const next_reach_time = Math.max(now + 1000, spread_timers_maximum);
+ const light_throttling_frequency = 1000;
+ for (var schedule = next_reach_time; schedule < desired_reach_time; schedule += light_throttling_frequency) {
+ const delay = schedule - now;
+ setTimeout(() => {
+ mono_wasm_set_timeout_exec(0);
+ pump_count++;
+ pump_message();
+ }, delay);
+ }
+ spread_timers_maximum = desired_reach_time;
+}
+
+export function schedule_background_exec() {
+ ++pump_count;
+ if (typeof globalThis.setTimeout === 'function') {
+ globalThis.setTimeout(pump_message, 0);
+ }
+}
+
+export function mono_set_timeout(timeout: number, id: number) {
+
+ if (typeof globalThis.setTimeout === 'function') {
+ globalThis.setTimeout(function () {
+ mono_wasm_set_timeout_exec(id);
+ }, timeout);
+ } else {
+ ++pump_count;
+ timeout_queue.push(function () {
+ mono_wasm_set_timeout_exec(id);
+ })
+ }
+}
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/mono/string-decoder.ts b/src/mono/wasm/runtime/src/mono/string-decoder.ts
new file mode 100644
index 00000000000000..cca7fc8f154721
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/string-decoder.ts
@@ -0,0 +1,81 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import { mono_wasm_new_root } from './roots'
+import cwraps from './cwraps'
+import { Module } from '../runtime'
+
+const mono_wasm_empty_string = "";
+
+export class StringDecoder {
+
+ private mono_wasm_string_root: any;
+ private mono_text_decoder: TextDecoder | undefined | null;
+ private mono_wasm_string_decoder_buffer: number | undefined;
+ private interned_string_table: Map | undefined;
+
+ copy(mono_string: MonoString) {
+ if (!this.interned_string_table || !this.mono_wasm_string_decoder_buffer) {
+ this.mono_text_decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : null;
+ this.mono_wasm_string_root = mono_wasm_new_root();
+ this.mono_wasm_string_decoder_buffer = Module._malloc(12);
+ this.interned_string_table = new Map();
+ }
+ if (mono_string === 0)
+ return null;
+
+ this.mono_wasm_string_root.value = mono_string;
+
+ let ppChars = this.mono_wasm_string_decoder_buffer + 0,
+ pLengthBytes = this.mono_wasm_string_decoder_buffer + 4,
+ pIsInterned = this.mono_wasm_string_decoder_buffer + 8;
+
+ cwraps.mono_wasm_string_get_data(mono_string, ppChars, pLengthBytes, pIsInterned);
+
+ let result = mono_wasm_empty_string;
+ let lengthBytes = Module.HEAP32[pLengthBytes / 4],
+ pChars = Module.HEAP32[ppChars / 4],
+ isInterned = Module.HEAP32[pIsInterned / 4];
+
+ if (pLengthBytes && pChars) {
+ if (
+ isInterned &&
+ this.interned_string_table &&
+ this.interned_string_table.has(mono_string) //TODO remove 2x lookup
+ ) {
+ result = this.interned_string_table.get(mono_string)!;
+ // console.log("intern table cache hit", mono_string, result.length);
+ } else {
+ result = this.decode(pChars, pChars + lengthBytes);
+ if (isInterned) {
+ // console.log("interned", mono_string, result.length);
+ this.interned_string_table.set(mono_string, result);
+ }
+ }
+ }
+
+ this.mono_wasm_string_root.value = 0;
+ return result;
+ }
+
+ private decode(start: number, end: number) {
+ var str = "";
+ if (this.mono_text_decoder) {
+ // When threading is enabled, TextDecoder does not accept a view of a
+ // SharedArrayBuffer, we must make a copy of the array first.
+ // See https://github.com/whatwg/encoding/issues/172
+ var subArray = typeof SharedArrayBuffer !== 'undefined' && Module.HEAPU8.buffer instanceof SharedArrayBuffer
+ ? Module.HEAPU8.slice(start, end)
+ : Module.HEAPU8.subarray(start, end);
+
+ str = this.mono_text_decoder.decode(subArray);
+ } else {
+ for (var i = 0; i < end - start; i += 2) {
+ var char = Module.getValue(start + i, 'i16');
+ str += String.fromCharCode(char);
+ }
+ }
+
+ return str;
+ }
+}
diff --git a/src/mono/wasm/runtime/src/mono/types.ts b/src/mono/wasm/runtime/src/mono/types.ts
new file mode 100644
index 00000000000000..81b9334b474ce2
--- /dev/null
+++ b/src/mono/wasm/runtime/src/mono/types.ts
@@ -0,0 +1,158 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import {
+ mono_wasm_new_root, mono_wasm_new_roots, mono_wasm_release_roots,
+ mono_wasm_new_root_buffer, mono_wasm_new_root_buffer_from_pointer
+} from './roots'
+import {
+ mono_wasm_add_dbg_command_received,
+ mono_wasm_send_dbg_command_with_parms,
+ mono_wasm_send_dbg_command,
+ mono_wasm_get_dbg_command_info,
+ mono_wasm_get_details,
+ mono_wasm_release_object,
+ mono_wasm_call_function_on,
+ mono_wasm_debugger_resume,
+ mono_wasm_detach_debugger,
+ mono_wasm_runtime_ready,
+ mono_wasm_get_loaded_files,
+ mono_wasm_raise_debug_event,
+ mono_wasm_fire_debugger_agent_message
+} from './debug'
+import { StringDecoder } from './string-decoder'
+import {
+ mono_load_runtime_and_bcl_args, mono_wasm_load_config,
+ mono_wasm_setenv, mono_wasm_set_runtime_options,
+ mono_wasm_load_data_archive, mono_wasm_asm_loaded,
+ mono_wasm_load_bytes_into_heap
+} from './init'
+import { prevent_timer_throttling, mono_set_timeout, schedule_background_exec } from './scheduling'
+import { mono_wasm_load_icu_data, mono_wasm_get_icudt_name, GlobalizationMode } from './icu'
+import { AOTProfilerOptions, CoverageProfilerOptions } from './profiler'
+
+// this represents visibility for the C code
+export interface t_MonoSupportLib {
+ mono_set_timeout: typeof mono_set_timeout
+ mono_wasm_asm_loaded: typeof mono_wasm_asm_loaded
+ mono_wasm_fire_debugger_agent_message: typeof mono_wasm_fire_debugger_agent_message,
+ schedule_background_exec: typeof schedule_background_exec
+ mono_wasm_setenv: typeof mono_wasm_setenv
+ mono_wasm_new_root_buffer: typeof mono_wasm_new_root_buffer;
+ mono_wasm_new_root_buffer_from_pointer: typeof mono_wasm_new_root_buffer_from_pointer;
+ mono_wasm_new_root: typeof mono_wasm_new_root;
+ mono_wasm_new_roots: typeof mono_wasm_new_roots;
+ mono_wasm_release_roots: typeof mono_wasm_release_roots;
+ mono_wasm_load_bytes_into_heap: typeof mono_wasm_load_bytes_into_heap;
+ mono_wasm_get_loaded_files: typeof mono_wasm_get_loaded_files;
+ mono_wasm_load_icu_data: typeof mono_wasm_load_icu_data;
+ mono_wasm_get_icudt_name: typeof mono_wasm_get_icudt_name;
+}
+
+// this represents visibility in the javascript
+// TODO limit this only to public API methods
+export interface t_MONO {
+ loaded_files: string[];
+ loaded_assets: { [id: string]: [VoidPtr, number] },
+ mono_wasm_runtime_is_ready: boolean;
+ config?: MonoConfig,
+
+ string_decoder: StringDecoder,
+ mono_set_timeout: typeof mono_set_timeout
+ mono_wasm_asm_loaded: typeof mono_wasm_asm_loaded
+ mono_wasm_fire_debugger_agent_message: typeof mono_wasm_fire_debugger_agent_message,
+ schedule_background_exec: typeof schedule_background_exec
+ mono_wasm_new_root: typeof mono_wasm_new_root,
+ mono_wasm_new_roots: typeof mono_wasm_new_roots,
+ mono_wasm_release_roots: typeof mono_wasm_release_roots,
+ mono_wasm_new_root_buffer: typeof mono_wasm_new_root_buffer,
+ mono_wasm_new_root_buffer_from_pointer: typeof mono_wasm_new_root_buffer_from_pointer
+ mono_wasm_load_bytes_into_heap: typeof mono_wasm_load_bytes_into_heap
+ mono_wasm_add_dbg_command_received: typeof mono_wasm_add_dbg_command_received
+ mono_wasm_send_dbg_command_with_parms: typeof mono_wasm_send_dbg_command_with_parms
+ mono_wasm_send_dbg_command: typeof mono_wasm_send_dbg_command
+ mono_wasm_get_dbg_command_info: typeof mono_wasm_get_dbg_command_info
+ mono_wasm_get_details: typeof mono_wasm_get_details
+ mono_wasm_release_object: typeof mono_wasm_release_object
+ mono_wasm_call_function_on: typeof mono_wasm_call_function_on
+ mono_wasm_debugger_resume: typeof mono_wasm_debugger_resume
+ mono_wasm_detach_debugger: typeof mono_wasm_detach_debugger
+ mono_wasm_runtime_ready: typeof mono_wasm_runtime_ready
+ mono_wasm_get_loaded_files: typeof mono_wasm_get_loaded_files
+ mono_wasm_raise_debug_event: typeof mono_wasm_raise_debug_event
+ mono_load_runtime_and_bcl_args: typeof mono_load_runtime_and_bcl_args
+ prevent_timer_throttling: typeof prevent_timer_throttling
+ mono_wasm_load_icu_data: typeof mono_wasm_load_icu_data
+ mono_wasm_get_icudt_name: typeof mono_wasm_get_icudt_name
+ mono_wasm_load_config: typeof mono_wasm_load_config
+ mono_wasm_setenv: typeof mono_wasm_setenv
+ mono_wasm_set_runtime_options: typeof mono_wasm_set_runtime_options
+ mono_wasm_load_data_archive: typeof mono_wasm_load_data_archive
+}
+
+// how we extended wasm Module
+export interface t_ModuleExtension {
+ config?: MonoConfig,
+}
+
+export type MonoConfig = {
+ assembly_root: string, // the subfolder containing managed assemblies and pdbs
+ assets: (AssetEntry | AssetEntry | SatelliteAssemblyEntry | VfsEntry | IcuData)[], // a list of assets to load along with the runtime. each asset is a dictionary-style Object with the following properties:
+ loaded_cb: Function, // a function invoked when loading has completed
+ debug_level?: number, // Either this or the next one needs to be set
+ enable_debugging?: number, // Either this or the previous one needs to be set
+ fetch_file_cb?: Request, // a function (string) invoked to fetch a given file. If no callback is provided a default implementation appropriate for the current environment will be selected (readFileSync in node, fetch elsewhere). If no default implementation is available this call will fail.
+ globalization_mode: GlobalizationMode, // configures the runtime's globalization mode
+ assembly_list?: any, // obsolete but necessary for the check
+ runtime_assets?: any, // obsolete but necessary for the check
+ runtime_asset_sources?: any, // obsolete but necessary for the check
+ diagnostic_tracing?: boolean // enables diagnostic log messages during startup
+ remote_sources?: string[], // additional search locations for assets. Sources will be checked in sequential order until the asset is found. The string "./" indicates to load from the application directory (as with the files in assembly_list), and a fully-qualified URL like "https://example.com/" indicates that asset loads can be attempted from a remote server. Sources must end with a "/".
+ environment_variables?: {
+ [i: string]: string;
+ }, // dictionary-style Object containing environment variables
+ runtime_options?: string[], // array of runtime options as strings
+ aot_profiler_options?: AOTProfilerOptions, // dictionary-style Object. If omitted, aot profiler will not be initialized.
+ coverage_profiler_options?: CoverageProfilerOptions, // dictionary-style Object. If omitted, coverage profiler will not be initialized.
+ ignore_pdb_load_errors?: boolean
+};
+
+export type MonoConfigError = { message: string, error: any }
+
+// Types of assets that can be in the mono-config.js/mono-config.json file (taken from /src/tasks/WasmAppBuilder/WasmAppBuilder.cs)
+export type AssetEntry = {
+ name: string, // the name of the asset, including extension.
+ behavior: AssetBehaviours, // determines how the asset will be handled once loaded
+ virtual_path?: string, // if specified, overrides the path of the asset in the virtual filesystem and similar data structures once loaded.
+ culture?: string,
+ load_remote?: boolean, // if true, an attempt will be made to load the asset from each location in @args.remote_sources.
+ is_optional?: boolean // if true, any failure to load this asset will be ignored.
+}
+
+export interface AssemblyEntry extends AssetEntry {
+ name: "assembly"
+}
+
+export interface SatelliteAssemblyEntry extends AssetEntry {
+ name: "resource",
+ culture: string
+}
+
+export interface VfsEntry extends AssetEntry {
+ name: "vfs",
+ virtual_path: string
+}
+
+export interface IcuData extends AssetEntry {
+ name: "icu",
+ load_remote: boolean
+}
+
+// Note that since these are annoated as `declare const enum` they are replaces by tsc with their raw value during compilation
+export const enum AssetBehaviours {
+ Resource = "resource", // load asset as a managed resource assembly
+ Assembly = "assembly", // load asset as a managed assembly (or debugging information)
+ Heap = "heap", // store asset into the native heap
+ ICU = "icu", // load asset as an ICU data archive
+ VFS = "vfs", // load asset into the virtual filesystem (for fopen, File.Open, etc)
+}
diff --git a/src/mono/wasm/runtime/src/runtime.ts b/src/mono/wasm/runtime/src/runtime.ts
new file mode 100644
index 00000000000000..915a380e8f64fb
--- /dev/null
+++ b/src/mono/wasm/runtime/src/runtime.ts
@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+///
+///
+import { t_MONO, t_ModuleExtension } from './mono/types'
+
+export var Module: t_Module & t_ModuleExtension;
+export var MONO: t_MONO;
+
+export function setMONO(mono: t_MONO, module: t_Module & any) {
+ Module = module;
+ MONO = mono;
+}
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/startup.ts b/src/mono/wasm/runtime/src/startup.ts
new file mode 100644
index 00000000000000..7c60947ae50517
--- /dev/null
+++ b/src/mono/wasm/runtime/src/startup.ts
@@ -0,0 +1,69 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import {
+ mono_wasm_new_root, mono_wasm_new_roots, mono_wasm_release_roots,
+ mono_wasm_new_root_buffer, mono_wasm_new_root_buffer_from_pointer
+} from './mono/roots'
+import {
+ mono_wasm_add_dbg_command_received,
+ mono_wasm_send_dbg_command_with_parms,
+ mono_wasm_send_dbg_command,
+ mono_wasm_get_dbg_command_info,
+ mono_wasm_get_details,
+ mono_wasm_release_object,
+ mono_wasm_call_function_on,
+ mono_wasm_debugger_resume,
+ mono_wasm_detach_debugger,
+ mono_wasm_runtime_ready,
+ mono_wasm_get_loaded_files,
+ mono_wasm_raise_debug_event,
+ mono_wasm_fire_debugger_agent_message,
+} from './mono/debug'
+import { StringDecoder } from './mono/string-decoder'
+import { MONO, setMONO } from './runtime'
+import { t_MONO, t_MonoSupportLib } from './mono/types'
+import {
+ mono_load_runtime_and_bcl_args, mono_wasm_load_config,
+ mono_wasm_setenv, mono_wasm_set_runtime_options,
+ mono_wasm_load_data_archive, mono_wasm_asm_loaded, mono_wasm_load_bytes_into_heap
+} from './mono/init'
+import { prevent_timer_throttling, mono_set_timeout, schedule_background_exec } from './mono/scheduling'
+import { mono_wasm_load_icu_data, mono_wasm_get_icudt_name } from './mono/icu'
+
+export function export_functions(mono: t_MONO, module: t_Module & t_MonoSupportLib) {
+ setMONO(mono, module)
+ MONO.string_decoder = new StringDecoder();
+ MONO.mono_wasm_fire_debugger_agent_message = module.mono_wasm_fire_debugger_agent_message = mono_wasm_fire_debugger_agent_message;
+ MONO.mono_set_timeout = module.mono_set_timeout = mono_set_timeout;
+ MONO.mono_wasm_asm_loaded = module.mono_wasm_asm_loaded = mono_wasm_asm_loaded;
+ MONO.schedule_background_exec = module.schedule_background_exec = schedule_background_exec;
+
+ MONO.mono_wasm_setenv = module.mono_wasm_setenv = mono_wasm_setenv;
+ MONO.mono_wasm_new_root_buffer = module.mono_wasm_new_root_buffer = mono_wasm_new_root_buffer;
+ MONO.mono_wasm_new_root_buffer_from_pointer = module.mono_wasm_new_root_buffer_from_pointer = mono_wasm_new_root_buffer_from_pointer;
+ MONO.mono_wasm_new_root = module.mono_wasm_new_root = mono_wasm_new_root;
+ MONO.mono_wasm_new_roots = module.mono_wasm_new_roots = mono_wasm_new_roots;
+ MONO.mono_wasm_release_roots = module.mono_wasm_release_roots = mono_wasm_release_roots;
+ MONO.mono_wasm_load_bytes_into_heap = module.mono_wasm_load_bytes_into_heap = mono_wasm_load_bytes_into_heap;
+ MONO.mono_wasm_get_loaded_files = module.mono_wasm_get_loaded_files = mono_wasm_get_loaded_files;
+ MONO.mono_wasm_load_icu_data = module.mono_wasm_load_icu_data = mono_wasm_load_icu_data;
+ MONO.mono_wasm_get_icudt_name = module.mono_wasm_get_icudt_name = mono_wasm_get_icudt_name;
+
+ MONO.mono_wasm_set_runtime_options = mono_wasm_set_runtime_options;
+ MONO.mono_wasm_add_dbg_command_received = mono_wasm_add_dbg_command_received;
+ MONO.mono_wasm_send_dbg_command_with_parms = mono_wasm_send_dbg_command_with_parms;
+ MONO.mono_wasm_send_dbg_command = mono_wasm_send_dbg_command;
+ MONO.mono_wasm_get_dbg_command_info = mono_wasm_get_dbg_command_info;
+ MONO.mono_wasm_get_details = mono_wasm_get_details;
+ MONO.mono_wasm_release_object = mono_wasm_release_object;
+ MONO.mono_wasm_call_function_on = mono_wasm_call_function_on;
+ MONO.mono_wasm_debugger_resume = mono_wasm_debugger_resume;
+ MONO.mono_wasm_detach_debugger = mono_wasm_detach_debugger;
+ MONO.mono_wasm_runtime_ready = mono_wasm_runtime_ready;
+ MONO.mono_wasm_raise_debug_event = mono_wasm_raise_debug_event;
+ MONO.mono_load_runtime_and_bcl_args = mono_load_runtime_and_bcl_args;
+ MONO.prevent_timer_throttling = prevent_timer_throttling;
+ MONO.mono_wasm_load_config = mono_wasm_load_config;
+ MONO.mono_wasm_load_data_archive = mono_wasm_load_data_archive;
+}
diff --git a/src/mono/wasm/runtime/src/types/emscripten.d.ts b/src/mono/wasm/runtime/src/types/emscripten.d.ts
new file mode 100644
index 00000000000000..0c30ec740af01e
--- /dev/null
+++ b/src/mono/wasm/runtime/src/types/emscripten.d.ts
@@ -0,0 +1,56 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+declare interface ManagedPointer { }
+declare interface NativePointer { }
+
+declare interface MonoString extends ManagedPointer { }
+declare interface VoidPtr extends NativePointer { }
+declare interface CharPtr extends NativePointer { }
+declare interface Int32Ptr extends NativePointer { }
+declare interface CharPtrPtr extends NativePointer { }
+
+declare var ENVIRONMENT_IS_WEB: boolean;
+declare var ENVIRONMENT_IS_SHELL: boolean;
+declare var ENVIRONMENT_IS_NODE: boolean;
+declare var ENVIRONMENT_IS_WORKER: boolean;
+declare var LibraryManager: any;
+
+declare function autoAddDeps(a: object, b: string): void;
+declare function mergeInto(a: object, b: object): void;
+
+// TODO, what's wrong with EXPORTED_RUNTIME_METHODS ?
+declare function locateFile(path: string, prefix?: string): string;
+
+declare var Module: t_Module;
+
+declare interface t_Module {
+ HEAP8: Int8Array,
+ HEAP16: Int16Array;
+ HEAP32: Int32Array;
+ HEAPU8: Uint8Array;
+ HEAPU16: Uint16Array;
+ HEAPU32: Uint32Array;
+ HEAPF32: Float32Array;
+ HEAPF64: Float64Array;
+
+ // this should match emcc -s EXPORTED_FUNCTIONS
+ _malloc(amnt: number): number;
+ _free(amn: number): void;
+
+ // this should match emcc -s EXPORTED_RUNTIME_METHODS
+ print(message: string): void;
+ ccall(ident: string, returnType?: string | null, argTypes?: string[], args?: any[], opts?: any): T;
+ cwrap(ident: string, returnType: string, argTypes?: string[], opts?: any): T;
+ cwrap(ident: string, ...args: any[]): T;
+ setValue(ptr: number, value: number, type: string, noSafe?: number | boolean): void;
+ getValue(ptr: number, type: string, noSafe?: number | boolean): number;
+ UTF8ToString(arg: CharPtr): string;
+ UTF8ArrayToString(str: TypedArray, heap: number[] | number, outIdx: number, maxBytesToWrite?: number): string;
+ FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string;
+ FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string;
+ removeRunDependency(id: string): void;
+ addRunDependency(id: string): void;
+}
+
+declare type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/src/types/v8.d.ts b/src/mono/wasm/runtime/src/types/v8.d.ts
new file mode 100644
index 00000000000000..9a59e88c408a7b
--- /dev/null
+++ b/src/mono/wasm/runtime/src/types/v8.d.ts
@@ -0,0 +1,5 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// read is a v8 debugger command
+declare function read(name: string): string;
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/tsconfig.json b/src/mono/wasm/runtime/tsconfig.json
new file mode 100644
index 00000000000000..e7242a2ec478ee
--- /dev/null
+++ b/src/mono/wasm/runtime/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "noImplicitAny": true,
+ "noEmitOnError": true,
+ "removeComments": false,
+ "sourceMap": false,
+ "target": "ES2015",
+ "moduleResolution": "Node",
+ "lib": [
+ "esnext",
+ "dom"
+ ],
+ "strict": true,
+ "allowJs": true,
+ "outDir": "bin",
+ },
+ "exclude": [
+ "bin"
+ ]
+}
\ No newline at end of file
diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj
index ec769911a28142..5e65625e0c7e9d 100644
--- a/src/mono/wasm/wasm.proj
+++ b/src/mono/wasm/wasm.proj
@@ -66,8 +66,8 @@
<_EmccCommonFlags Include="-s ALLOW_MEMORY_GROWTH=1" />
<_EmccCommonFlags Include="-s NO_EXIT_RUNTIME=1" />
<_EmccCommonFlags Include="-s FORCE_FILESYSTEM=1" />
- <_EmccCommonFlags Include="-s "EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString', 'UTF8ArrayToString', 'addFunction']"" />
- <_EmccCommonFlags Include="-s "EXPORTED_FUNCTIONS=['_putchar']"" />
+ <_EmccCommonFlags Include="-s EXPORTED_RUNTIME_METHODS="['print','ccall','cwrap','setValue','getValue','UTF8ToString','UTF8ArrayToString','FS_createPath','FS_createDataFile','removeRunDependency','addRunDependency']"" />
+ <_EmccCommonFlags Include="-s EXPORTED_FUNCTIONS="['_free','_malloc']"" />
<_EmccCommonFlags Include="--source-map-base http://example.com" />
<_EmccCommonFlags Include="-s STRICT_JS=1" />
@@ -164,6 +164,15 @@
DestinationFolder="$(MonoObjDir)"
SkipUnchangedFiles="true" />
+
+
+
+
+
+
+
+
+