@datagrok/eda 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"package-test.js","mappings":"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AG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,IAEjDmS,EAASmG,YAAc7kB,UAAUuM,KAAK,EACjC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC9C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,IAEjDmS,EAASqG,WAAa/kB,UAAUuM,KAAK,EAChC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC9C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7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","sources":["webpack://eda/./node_modules/@datagrok-libraries/math/src/dbscan/wasm/wasmDbscan.js","webpack://eda/./node_modules/fast-sha256/sha256.js","webpack://eda/./node_modules/jaro-winkler-typescript/lib/index.js","webpack://eda/webpack/bootstrap","webpack://eda/webpack/runtime/amd options","webpack://eda/webpack/runtime/define property getters","webpack://eda/webpack/runtime/get javascript chunk filename","webpack://eda/webpack/runtime/global","webpack://eda/webpack/runtime/harmony module decorator","webpack://eda/webpack/runtime/hasOwnProperty shorthand","webpack://eda/webpack/runtime/make namespace object","webpack://eda/webpack/runtime/publicPath","webpack://eda/webpack/runtime/jsonp chunk loading","webpack://eda/external var \"DG\"","webpack://eda/external var \"grok\"","webpack://eda/./node_modules/@datagrok-libraries/utils/src/dataframe-utils.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/test.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/types.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/typed-metrics/consts.js","webpack://eda/./node_modules/fastest-levenshtein/esm/mod.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/bit-array.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/hamming.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/needleman-wunsch.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/macromolecule-distance-functions.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/levenstein.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-metrics-methods.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/typed-metrics/typed-metrics.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/vector-operations.js","webpack://eda/external var \"ui\"","webpack://eda/./node_modules/@datagrok-libraries/ml/src/functionEditors/consts.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/dbscan/wasm/dbscan-worker-creator.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/multi-col-distances/webGPU-aggregation.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/multi-col-distances/webGPU-multicol-distances.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/types.js","webpack://eda/./node_modules/is-any-array/lib-esm/index.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/consts.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/types.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/utils.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/reduce-dimensionality.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/embeddings-space.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/multi-dim-red-worker-creator.js","webpack://eda/./src/tests/dim-reduction-tests.ts","webpack://eda/./wasm/callWasm.js","webpack://eda/./wasm/callWasmForWebWorker.js","webpack://eda/./src/utils.ts","webpack://eda/./src/pls/pls-constants.ts","webpack://eda/./src/eda-tools.ts","webpack://eda/./wasm/EDAAPI.js","webpack://eda/./src/pls/pls-tools.ts","webpack://eda/./src/regression.ts","webpack://eda/./src/pls/pls-ml.ts","webpack://eda/./src/tests/utils.ts","webpack://eda/./src/tests/linear-methods-tests.ts","webpack://eda/./src/softmax-classifier.ts","webpack://eda/./src/xgbooster.ts","webpack://eda/./wasm/xgbooster.js","webpack://eda/./src/tests/classifiers-tests.ts","webpack://eda/./src/package-test.ts"],"sourcesContent":["\r\nexport var exportCppDbscanLib = (() => {\r\n var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;\r\n \r\n return (\r\nfunction(exportCppDbscanLib = {}) {\r\n\r\n// include: shell.js\r\n// The Module object: Our interface to the outside world. We import\r\n// and export values on it. There are various ways Module can be used:\r\n// 1. Not defined. We create it here\r\n// 2. A function parameter, function(Module) { ..generated code.. }\r\n// 3. pre-run appended it, var Module = {}; ..generated code..\r\n// 4. External script tag defines var Module.\r\n// We need to check if Module already exists (e.g. case 3 above).\r\n// Substitution will be replaced with actual code on later stage of the build,\r\n// this way Closure Compiler will not mangle it (e.g. case 4. above).\r\n// Note that if you want to run closure, and also to use Module\r\n// after the generated code, you will need to define var Module = {};\r\n// before the code. Then that object will be used in the code, and you\r\n// can continue to use Module afterwards as well.\r\nvar Module = typeof exportCppDbscanLib != 'undefined' ? exportCppDbscanLib : {};\r\n\r\n// Set up the promise that indicates the Module is initialized\r\nvar readyPromiseResolve, readyPromiseReject;\r\nModule['ready'] = new Promise(function(resolve, reject) {\r\n readyPromiseResolve = resolve;\r\n readyPromiseReject = reject;\r\n});\r\n\r\n// --pre-jses are emitted after the Module integration code, so that they can\r\n// refer to Module (if they choose; they can also define Module)\r\n\r\n\r\n// Sometimes an existing Module object exists with properties\r\n// meant to overwrite the default module functionality. Here\r\n// we collect those properties and reapply _after_ we configure\r\n// the current environment's defaults to avoid having to be so\r\n// defensive during initialization.\r\nvar moduleOverrides = Object.assign({}, Module);\r\n\r\nvar arguments_ = [];\r\nvar thisProgram = './this.program';\r\nvar quit_ = (status, toThrow) => {\r\n throw toThrow;\r\n};\r\n\r\n// Determine the runtime environment we are in. You can customize this by\r\n// setting the ENVIRONMENT setting at compile time (see settings.js).\r\n\r\n// Attempt to auto-detect the environment\r\nvar ENVIRONMENT_IS_WEB = typeof window == 'object';\r\nvar ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';\r\n// N.b. Electron.js environment is simultaneously a NODE-environment, but\r\n// also a web environment.\r\nvar ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';\r\nvar ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;\r\n\r\n// `/` should be present at the end if `scriptDirectory` is not empty\r\nvar scriptDirectory = '';\r\nfunction locateFile(path) {\r\n if (Module['locateFile']) {\r\n return Module['locateFile'](path, scriptDirectory);\r\n }\r\n return scriptDirectory + path;\r\n}\r\n\r\n// Hooks that are implemented differently in different runtime environments.\r\nvar read_,\r\n readAsync,\r\n readBinary,\r\n setWindowTitle;\r\n\r\n// Note that this includes Node.js workers when relevant (pthreads is enabled).\r\n// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and\r\n// ENVIRONMENT_IS_NODE.\r\nif (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {\r\n if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled\r\n scriptDirectory = self.location.href;\r\n } else if (typeof document != 'undefined' && document.currentScript) { // web\r\n scriptDirectory = document.currentScript.src;\r\n }\r\n // When MODULARIZE, this JS may be executed later, after document.currentScript\r\n // is gone, so we saved it, and we use it here instead of any other info.\r\n if (_scriptDir) {\r\n scriptDirectory = _scriptDir;\r\n }\r\n // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.\r\n // otherwise, slice off the final part of the url to find the script directory.\r\n // if scriptDirectory does not contain a slash, lastIndexOf will return -1,\r\n // and scriptDirectory will correctly be replaced with an empty string.\r\n // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),\r\n // they are removed because they could contain a slash.\r\n if (scriptDirectory.indexOf('blob:') !== 0) {\r\n scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, \"\").lastIndexOf('/')+1);\r\n } else {\r\n scriptDirectory = '';\r\n }\r\n\r\n // Differentiate the Web Worker from the Node Worker case, as reading must\r\n // be done differently.\r\n {\r\n// include: web_or_worker_shell_read.js\r\nread_ = (url) => {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('GET', url, false);\r\n xhr.send(null);\r\n return xhr.responseText;\r\n }\r\n\r\n if (ENVIRONMENT_IS_WORKER) {\r\n readBinary = (url) => {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('GET', url, false);\r\n xhr.responseType = 'arraybuffer';\r\n xhr.send(null);\r\n return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));\r\n };\r\n }\r\n\r\n readAsync = (url, onload, onerror) => {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('GET', url, true);\r\n xhr.responseType = 'arraybuffer';\r\n xhr.onload = () => {\r\n if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0\r\n onload(xhr.response);\r\n return;\r\n }\r\n onerror();\r\n };\r\n xhr.onerror = onerror;\r\n xhr.send(null);\r\n }\r\n\r\n// end include: web_or_worker_shell_read.js\r\n }\r\n\r\n setWindowTitle = (title) => document.title = title;\r\n} else\r\n{\r\n}\r\n\r\nvar out = Module['print'] || console.log.bind(console);\r\nvar err = Module['printErr'] || console.warn.bind(console);\r\n\r\n// Merge back in the overrides\r\nObject.assign(Module, moduleOverrides);\r\n// Free the object hierarchy contained in the overrides, this lets the GC\r\n// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.\r\nmoduleOverrides = null;\r\n\r\n// Emit code to handle expected values on the Module object. This applies Module.x\r\n// to the proper local x. This has two benefits: first, we only emit it if it is\r\n// expected to arrive, and second, by using a local everywhere else that can be\r\n// minified.\r\n\r\nif (Module['arguments']) arguments_ = Module['arguments'];\r\n\r\nif (Module['thisProgram']) thisProgram = Module['thisProgram'];\r\n\r\nif (Module['quit']) quit_ = Module['quit'];\r\n\r\n// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message\r\n\r\n\r\n// end include: shell.js\r\n// include: preamble.js\r\n// === Preamble library stuff ===\r\n\r\n// Documentation for the public APIs defined in this file must be updated in:\r\n// site/source/docs/api_reference/preamble.js.rst\r\n// A prebuilt local version of the documentation is available at:\r\n// site/build/text/docs/api_reference/preamble.js.txt\r\n// You can also build docs locally as HTML or other formats in site/\r\n// An online HTML version (which may be of a different version of Emscripten)\r\n// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html\r\n\r\nvar wasmBinary;\r\nif (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];\r\nvar noExitRuntime = Module['noExitRuntime'] || true;\r\n\r\nif (typeof WebAssembly != 'object') {\r\n abort('no native wasm support detected');\r\n}\r\n\r\n// Wasm globals\r\n\r\nvar wasmMemory;\r\n\r\n//========================================\r\n// Runtime essentials\r\n//========================================\r\n\r\n// whether we are quitting the application. no code should run after this.\r\n// set in exit() and abort()\r\nvar ABORT = false;\r\n\r\n// set by exit() and abort(). Passed to 'onExit' handler.\r\n// NOTE: This is also used as the process return code code in shell environments\r\n// but only when noExitRuntime is false.\r\nvar EXITSTATUS;\r\n\r\n/** @type {function(*, string=)} */\r\nfunction assert(condition, text) {\r\n if (!condition) {\r\n // This build was created without ASSERTIONS defined. `assert()` should not\r\n // ever be called in this configuration but in case there are callers in\r\n // the wild leave this simple abort() implemenation here for now.\r\n abort(text);\r\n }\r\n}\r\n\r\n// Memory management\r\n\r\nvar HEAP,\r\n/** @type {!Int8Array} */\r\n HEAP8,\r\n/** @type {!Uint8Array} */\r\n HEAPU8,\r\n/** @type {!Int16Array} */\r\n HEAP16,\r\n/** @type {!Uint16Array} */\r\n HEAPU16,\r\n/** @type {!Int32Array} */\r\n HEAP32,\r\n/** @type {!Uint32Array} */\r\n HEAPU32,\r\n/** @type {!Float32Array} */\r\n HEAPF32,\r\n/** @type {!Float64Array} */\r\n HEAPF64;\r\n\r\nfunction updateMemoryViews() {\r\n var b = wasmMemory.buffer;\r\n Module['HEAP8'] = HEAP8 = new Int8Array(b);\r\n Module['HEAP16'] = HEAP16 = new Int16Array(b);\r\n Module['HEAP32'] = HEAP32 = new Int32Array(b);\r\n Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);\r\n Module['HEAPU16'] = HEAPU16 = new Uint16Array(b);\r\n Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);\r\n Module['HEAPF32'] = HEAPF32 = new Float32Array(b);\r\n Module['HEAPF64'] = HEAPF64 = new Float64Array(b);\r\n}\r\n\r\n// include: runtime_init_table.js\r\n// In regular non-RELOCATABLE mode the table is exported\r\n// from the wasm module and this will be assigned once\r\n// the exports are available.\r\nvar wasmTable;\r\n\r\n// end include: runtime_init_table.js\r\n// include: runtime_stack_check.js\r\n// end include: runtime_stack_check.js\r\n// include: runtime_assertions.js\r\n// end include: runtime_assertions.js\r\nvar __ATPRERUN__ = []; // functions called before the runtime is initialized\r\nvar __ATINIT__ = []; // functions called during startup\r\nvar __ATEXIT__ = []; // functions called during shutdown\r\nvar __ATPOSTRUN__ = []; // functions called after the main() is called\r\n\r\nvar runtimeInitialized = false;\r\n\r\nvar runtimeKeepaliveCounter = 0;\r\n\r\nfunction keepRuntimeAlive() {\r\n return noExitRuntime || runtimeKeepaliveCounter > 0;\r\n}\r\n\r\nfunction preRun() {\r\n if (Module['preRun']) {\r\n if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];\r\n while (Module['preRun'].length) {\r\n addOnPreRun(Module['preRun'].shift());\r\n }\r\n }\r\n callRuntimeCallbacks(__ATPRERUN__);\r\n}\r\n\r\nfunction initRuntime() {\r\n runtimeInitialized = true;\r\n\r\n \r\n callRuntimeCallbacks(__ATINIT__);\r\n}\r\n\r\nfunction postRun() {\r\n\r\n if (Module['postRun']) {\r\n if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];\r\n while (Module['postRun'].length) {\r\n addOnPostRun(Module['postRun'].shift());\r\n }\r\n }\r\n\r\n callRuntimeCallbacks(__ATPOSTRUN__);\r\n}\r\n\r\nfunction addOnPreRun(cb) {\r\n __ATPRERUN__.unshift(cb);\r\n}\r\n\r\nfunction addOnInit(cb) {\r\n __ATINIT__.unshift(cb);\r\n}\r\n\r\nfunction addOnExit(cb) {\r\n}\r\n\r\nfunction addOnPostRun(cb) {\r\n __ATPOSTRUN__.unshift(cb);\r\n}\r\n\r\n// include: runtime_math.js\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul\r\n\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround\r\n\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32\r\n\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc\r\n\r\n// end include: runtime_math.js\r\n// A counter of dependencies for calling run(). If we need to\r\n// do asynchronous work before running, increment this and\r\n// decrement it. Incrementing must happen in a place like\r\n// Module.preRun (used by emcc to add file preloading).\r\n// Note that you can add dependencies in preRun, even though\r\n// it happens right before run - run will be postponed until\r\n// the dependencies are met.\r\nvar runDependencies = 0;\r\nvar runDependencyWatcher = null;\r\nvar dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled\r\n\r\nfunction getUniqueRunDependency(id) {\r\n return id;\r\n}\r\n\r\nfunction addRunDependency(id) {\r\n runDependencies++;\r\n\r\n if (Module['monitorRunDependencies']) {\r\n Module['monitorRunDependencies'](runDependencies);\r\n }\r\n\r\n}\r\n\r\nfunction removeRunDependency(id) {\r\n runDependencies--;\r\n\r\n if (Module['monitorRunDependencies']) {\r\n Module['monitorRunDependencies'](runDependencies);\r\n }\r\n\r\n if (runDependencies == 0) {\r\n if (runDependencyWatcher !== null) {\r\n clearInterval(runDependencyWatcher);\r\n runDependencyWatcher = null;\r\n }\r\n if (dependenciesFulfilled) {\r\n var callback = dependenciesFulfilled;\r\n dependenciesFulfilled = null;\r\n callback(); // can add another dependenciesFulfilled\r\n }\r\n }\r\n}\r\n\r\n/** @param {string|number=} what */\r\nfunction abort(what) {\r\n if (Module['onAbort']) {\r\n Module['onAbort'](what);\r\n }\r\n\r\n what = 'Aborted(' + what + ')';\r\n // TODO(sbc): Should we remove printing and leave it up to whoever\r\n // catches the exception?\r\n err(what);\r\n\r\n ABORT = true;\r\n EXITSTATUS = 1;\r\n\r\n what += '. Build with -sASSERTIONS for more info.';\r\n\r\n // Use a wasm runtime error, because a JS error might be seen as a foreign\r\n // exception, which means we'd run destructors on it. We need the error to\r\n // simply make the program stop.\r\n // FIXME This approach does not work in Wasm EH because it currently does not assume\r\n // all RuntimeErrors are from traps; it decides whether a RuntimeError is from\r\n // a trap or not based on a hidden field within the object. So at the moment\r\n // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that\r\n // allows this in the wasm spec.\r\n\r\n // Suppress closure compiler warning here. Closure compiler's builtin extern\r\n // defintion for WebAssembly.RuntimeError claims it takes no arguments even\r\n // though it can.\r\n // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.\r\n /** @suppress {checkTypes} */\r\n var e = new WebAssembly.RuntimeError(what);\r\n\r\n readyPromiseReject(e);\r\n // Throw the error whether or not MODULARIZE is set because abort is used\r\n // in code paths apart from instantiation where an exception is expected\r\n // to be thrown when abort is called.\r\n throw e;\r\n}\r\n\r\n// include: memoryprofiler.js\r\n// end include: memoryprofiler.js\r\n// include: URIUtils.js\r\n// Prefix of data URIs emitted by SINGLE_FILE and related options.\r\nvar dataURIPrefix = 'data:application/octet-stream;base64,';\r\n\r\n// Indicates whether filename is a base64 data URI.\r\nfunction isDataURI(filename) {\r\n // Prefix of data URIs emitted by SINGLE_FILE and related options.\r\n return filename.startsWith(dataURIPrefix);\r\n}\r\n\r\n// Indicates whether filename is delivered via file protocol (as opposed to http/https)\r\nfunction isFileURI(filename) {\r\n return filename.startsWith('file://');\r\n}\r\n\r\n// end include: URIUtils.js\r\n// include: runtime_exceptions.js\r\n// end include: runtime_exceptions.js\r\nvar wasmBinaryFile;\r\n wasmBinaryFile = 'wasmDbscan.wasm';\r\n if (!isDataURI(wasmBinaryFile)) {\r\n wasmBinaryFile = locateFile(wasmBinaryFile);\r\n }\r\n\r\nfunction getBinary(file) {\r\n try {\r\n if (file == wasmBinaryFile && wasmBinary) {\r\n return new Uint8Array(wasmBinary);\r\n }\r\n if (readBinary) {\r\n return readBinary(file);\r\n }\r\n throw \"both async and sync fetching of the wasm failed\";\r\n }\r\n catch (err) {\r\n abort(err);\r\n }\r\n}\r\n\r\nfunction getBinaryPromise(binaryFile) {\r\n // If we don't have the binary yet, try to load it asynchronously.\r\n // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.\r\n // See https://github.com/github/fetch/pull/92#issuecomment-140665932\r\n // Cordova or Electron apps are typically loaded from a file:// url.\r\n // So use fetch if it is available and the url is not a file, otherwise fall back to XHR.\r\n if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {\r\n if (typeof fetch == 'function'\r\n ) {\r\n return fetch(binaryFile, { credentials: 'same-origin' }).then(function(response) {\r\n if (!response['ok']) {\r\n throw \"failed to load wasm binary file at '\" + binaryFile + \"'\";\r\n }\r\n return response['arrayBuffer']();\r\n }).catch(function () {\r\n return getBinary(binaryFile);\r\n });\r\n }\r\n }\r\n\r\n // Otherwise, getBinary should be able to get it synchronously\r\n return Promise.resolve().then(function() { return getBinary(binaryFile); });\r\n}\r\n\r\nfunction instantiateArrayBuffer(binaryFile, imports, receiver) {\r\n return getBinaryPromise(binaryFile).then(function(binary) {\r\n return WebAssembly.instantiate(binary, imports);\r\n }).then(function (instance) {\r\n return instance;\r\n }).then(receiver, function(reason) {\r\n err('failed to asynchronously prepare wasm: ' + reason);\r\n\r\n abort(reason);\r\n });\r\n}\r\n\r\nfunction instantiateAsync(binary, binaryFile, imports, callback) {\r\n if (!binary &&\r\n typeof WebAssembly.instantiateStreaming == 'function' &&\r\n !isDataURI(binaryFile) &&\r\n typeof fetch == 'function') {\r\n return fetch(binaryFile, { credentials: 'same-origin' }).then(function(response) {\r\n // Suppress closure warning here since the upstream definition for\r\n // instantiateStreaming only allows Promise<Repsponse> rather than\r\n // an actual Response.\r\n // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.\r\n /** @suppress {checkTypes} */\r\n var result = WebAssembly.instantiateStreaming(response, imports);\r\n\r\n return result.then(\r\n callback,\r\n function(reason) {\r\n // We expect the most common failure cause to be a bad MIME type for the binary,\r\n // in which case falling back to ArrayBuffer instantiation should work.\r\n err('wasm streaming compile failed: ' + reason);\r\n err('falling back to ArrayBuffer instantiation');\r\n return instantiateArrayBuffer(binaryFile, imports, callback);\r\n });\r\n });\r\n } else {\r\n return instantiateArrayBuffer(binaryFile, imports, callback);\r\n }\r\n}\r\n\r\n// Create the wasm instance.\r\n// Receives the wasm imports, returns the exports.\r\nfunction createWasm() {\r\n // prepare imports\r\n var info = {\r\n 'env': wasmImports,\r\n 'wasi_snapshot_preview1': wasmImports,\r\n };\r\n // Load the wasm module and create an instance of using native support in the JS engine.\r\n // handle a generated wasm instance, receiving its exports and\r\n // performing other necessary setup\r\n /** @param {WebAssembly.Module=} module*/\r\n function receiveInstance(instance, module) {\r\n var exports = instance.exports;\r\n\r\n Module['asm'] = exports;\r\n\r\n wasmMemory = Module['asm']['memory'];\r\n updateMemoryViews();\r\n\r\n wasmTable = Module['asm']['__indirect_function_table'];\r\n\r\n addOnInit(Module['asm']['__wasm_call_ctors']);\r\n\r\n removeRunDependency('wasm-instantiate');\r\n\r\n return exports;\r\n }\r\n // wait for the pthread pool (if any)\r\n addRunDependency('wasm-instantiate');\r\n\r\n // Prefer streaming instantiation if available.\r\n function receiveInstantiationResult(result) {\r\n // 'result' is a ResultObject object which has both the module and instance.\r\n // receiveInstance() will swap in the exports (to Module.asm) so they can be called\r\n // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.\r\n // When the regression is fixed, can restore the above PTHREADS-enabled path.\r\n receiveInstance(result['instance']);\r\n }\r\n\r\n // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback\r\n // to manually instantiate the Wasm module themselves. This allows pages to\r\n // run the instantiation parallel to any other async startup actions they are\r\n // performing.\r\n // Also pthreads and wasm workers initialize the wasm instance through this\r\n // path.\r\n if (Module['instantiateWasm']) {\r\n\r\n try {\r\n return Module['instantiateWasm'](info, receiveInstance);\r\n } catch(e) {\r\n err('Module.instantiateWasm callback failed with error: ' + e);\r\n // If instantiation fails, reject the module ready promise.\r\n readyPromiseReject(e);\r\n }\r\n }\r\n\r\n // If instantiation fails, reject the module ready promise.\r\n instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult).catch(readyPromiseReject);\r\n return {}; // no exports yet; we'll fill them in later\r\n}\r\n\r\n// Globals used by JS i64 conversions (see makeSetValue)\r\nvar tempDouble;\r\nvar tempI64;\r\n\r\n// include: runtime_debug.js\r\n// end include: runtime_debug.js\r\n// === Body ===\r\n\r\n\r\n// end include: preamble.js\r\n\r\n /** @constructor */\r\n function ExitStatus(status) {\r\n this.name = 'ExitStatus';\r\n this.message = 'Program terminated with exit(' + status + ')';\r\n this.status = status;\r\n }\r\n\r\n function callRuntimeCallbacks(callbacks) {\r\n while (callbacks.length > 0) {\r\n // Pass the module as the first argument.\r\n callbacks.shift()(Module);\r\n }\r\n }\r\n\r\n \r\n /**\r\n * @param {number} ptr\r\n * @param {string} type\r\n */\r\n function getValue(ptr, type = 'i8') {\r\n if (type.endsWith('*')) type = '*';\r\n switch (type) {\r\n case 'i1': return HEAP8[((ptr)>>0)];\r\n case 'i8': return HEAP8[((ptr)>>0)];\r\n case 'i16': return HEAP16[((ptr)>>1)];\r\n case 'i32': return HEAP32[((ptr)>>2)];\r\n case 'i64': return HEAP32[((ptr)>>2)];\r\n case 'float': return HEAPF32[((ptr)>>2)];\r\n case 'double': return HEAPF64[((ptr)>>3)];\r\n case '*': return HEAPU32[((ptr)>>2)];\r\n default: abort('invalid type for getValue: ' + type);\r\n }\r\n }\r\n\r\n \r\n /**\r\n * @param {number} ptr\r\n * @param {number} value\r\n * @param {string} type\r\n */\r\n function setValue(ptr, value, type = 'i8') {\r\n if (type.endsWith('*')) type = '*';\r\n switch (type) {\r\n case 'i1': HEAP8[((ptr)>>0)] = value; break;\r\n case 'i8': HEAP8[((ptr)>>0)] = value; break;\r\n case 'i16': HEAP16[((ptr)>>1)] = value; break;\r\n case 'i32': HEAP32[((ptr)>>2)] = value; break;\r\n case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break;\r\n case 'float': HEAPF32[((ptr)>>2)] = value; break;\r\n case 'double': HEAPF64[((ptr)>>3)] = value; break;\r\n case '*': HEAPU32[((ptr)>>2)] = value; break;\r\n default: abort('invalid type for setValue: ' + type);\r\n }\r\n }\r\n\r\n /** @constructor */\r\n function ExceptionInfo(excPtr) {\r\n this.excPtr = excPtr;\r\n this.ptr = excPtr - 24;\r\n \r\n this.set_type = function(type) {\r\n HEAPU32[(((this.ptr)+(4))>>2)] = type;\r\n };\r\n \r\n this.get_type = function() {\r\n return HEAPU32[(((this.ptr)+(4))>>2)];\r\n };\r\n \r\n this.set_destructor = function(destructor) {\r\n HEAPU32[(((this.ptr)+(8))>>2)] = destructor;\r\n };\r\n \r\n this.get_destructor = function() {\r\n return HEAPU32[(((this.ptr)+(8))>>2)];\r\n };\r\n \r\n this.set_caught = function (caught) {\r\n caught = caught ? 1 : 0;\r\n HEAP8[(((this.ptr)+(12))>>0)] = caught;\r\n };\r\n \r\n this.get_caught = function () {\r\n return HEAP8[(((this.ptr)+(12))>>0)] != 0;\r\n };\r\n \r\n this.set_rethrown = function (rethrown) {\r\n rethrown = rethrown ? 1 : 0;\r\n HEAP8[(((this.ptr)+(13))>>0)] = rethrown;\r\n };\r\n \r\n this.get_rethrown = function () {\r\n return HEAP8[(((this.ptr)+(13))>>0)] != 0;\r\n };\r\n \r\n // Initialize native structure fields. Should be called once after allocated.\r\n this.init = function(type, destructor) {\r\n this.set_adjusted_ptr(0);\r\n this.set_type(type);\r\n this.set_destructor(destructor);\r\n }\r\n \r\n this.set_adjusted_ptr = function(adjustedPtr) {\r\n HEAPU32[(((this.ptr)+(16))>>2)] = adjustedPtr;\r\n };\r\n \r\n this.get_adjusted_ptr = function() {\r\n return HEAPU32[(((this.ptr)+(16))>>2)];\r\n };\r\n \r\n // Get pointer which is expected to be received by catch clause in C++ code. It may be adjusted\r\n // when the pointer is casted to some of the exception object base classes (e.g. when virtual\r\n // inheritance is used). When a pointer is thrown this method should return the thrown pointer\r\n // itself.\r\n this.get_exception_ptr = function() {\r\n // Work around a fastcomp bug, this code is still included for some reason in a build without\r\n // exceptions support.\r\n var isPointer = ___cxa_is_pointer_type(this.get_type());\r\n if (isPointer) {\r\n return HEAPU32[((this.excPtr)>>2)];\r\n }\r\n var adjusted = this.get_adjusted_ptr();\r\n if (adjusted !== 0) return adjusted;\r\n return this.excPtr;\r\n };\r\n }\r\n \r\n var exceptionLast = 0;\r\n \r\n var uncaughtExceptionCount = 0;\r\n function ___cxa_throw(ptr, type, destructor) {\r\n var info = new ExceptionInfo(ptr);\r\n // Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception.\r\n info.init(type, destructor);\r\n exceptionLast = ptr;\r\n uncaughtExceptionCount++;\r\n throw exceptionLast;\r\n }\r\n\r\n function _abort() {\r\n abort('');\r\n }\r\n\r\n function _emscripten_memcpy_big(dest, src, num) {\r\n HEAPU8.copyWithin(dest, src, src + num);\r\n }\r\n\r\n function getHeapMax() {\r\n // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate\r\n // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side\r\n // for any code that deals with heap sizes, which would require special\r\n // casing all heap size related code to treat 0 specially.\r\n return 2147483648;\r\n }\r\n \r\n function emscripten_realloc_buffer(size) {\r\n var b = wasmMemory.buffer;\r\n try {\r\n // round size grow request up to wasm page size (fixed 64KB per spec)\r\n wasmMemory.grow((size - b.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size\r\n updateMemoryViews();\r\n return 1 /*success*/;\r\n } catch(e) {\r\n }\r\n // implicit 0 return to save code size (caller will cast \"undefined\" into 0\r\n // anyhow)\r\n }\r\n function _emscripten_resize_heap(requestedSize) {\r\n var oldSize = HEAPU8.length;\r\n requestedSize = requestedSize >>> 0;\r\n // With multithreaded builds, races can happen (another thread might increase the size\r\n // in between), so return a failure, and let the caller retry.\r\n \r\n // Memory resize rules:\r\n // 1. Always increase heap size to at least the requested size, rounded up\r\n // to next page multiple.\r\n // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap\r\n // geometrically: increase the heap size according to\r\n // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most\r\n // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).\r\n // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap\r\n // linearly: increase the heap size by at least\r\n // MEMORY_GROWTH_LINEAR_STEP bytes.\r\n // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by\r\n // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest\r\n // 4. If we were unable to allocate as much memory, it may be due to\r\n // over-eager decision to excessively reserve due to (3) above.\r\n // Hence if an allocation fails, cut down on the amount of excess\r\n // growth, in an attempt to succeed to perform a smaller allocation.\r\n \r\n // A limit is set for how much we can grow. We should not exceed that\r\n // (the wasm binary specifies it, so if we tried, we'd fail anyhow).\r\n var maxHeapSize = getHeapMax();\r\n if (requestedSize > maxHeapSize) {\r\n return false;\r\n }\r\n \r\n let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;\r\n \r\n // Loop through potential heap size increases. If we attempt a too eager\r\n // reservation that fails, cut down on the attempted size and reserve a\r\n // smaller bump instead. (max 3 times, chosen somewhat arbitrarily)\r\n for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {\r\n var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth\r\n // but limit overreserving (default to capping at +96MB overgrowth at most)\r\n overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );\r\n \r\n var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));\r\n \r\n var replacement = emscripten_realloc_buffer(newSize);\r\n if (replacement) {\r\n \r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n function getCFunc(ident) {\r\n var func = Module['_' + ident]; // closure exported function\r\n return func;\r\n }\r\n \r\n \r\n function writeArrayToMemory(array, buffer) {\r\n HEAP8.set(array, buffer);\r\n }\r\n \r\n function lengthBytesUTF8(str) {\r\n var len = 0;\r\n for (var i = 0; i < str.length; ++i) {\r\n // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code\r\n // unit, not a Unicode code point of the character! So decode\r\n // UTF16->UTF32->UTF8.\r\n // See http://unicode.org/faq/utf_bom.html#utf16-3\r\n var c = str.charCodeAt(i); // possibly a lead surrogate\r\n if (c <= 0x7F) {\r\n len++;\r\n } else if (c <= 0x7FF) {\r\n len += 2;\r\n } else if (c >= 0xD800 && c <= 0xDFFF) {\r\n len += 4; ++i;\r\n } else {\r\n len += 3;\r\n }\r\n }\r\n return len;\r\n }\r\n \r\n function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {\r\n // Parameter maxBytesToWrite is not optional. Negative values, 0, null,\r\n // undefined and false each don't write out any bytes.\r\n if (!(maxBytesToWrite > 0))\r\n return 0;\r\n \r\n var startIdx = outIdx;\r\n var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.\r\n for (var i = 0; i < str.length; ++i) {\r\n // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code\r\n // unit, not a Unicode code point of the character! So decode\r\n // UTF16->UTF32->UTF8.\r\n // See http://unicode.org/faq/utf_bom.html#utf16-3\r\n // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description\r\n // and https://www.ietf.org/rfc/rfc2279.txt\r\n // and https://tools.ietf.org/html/rfc3629\r\n var u = str.charCodeAt(i); // possibly a lead surrogate\r\n if (u >= 0xD800 && u <= 0xDFFF) {\r\n var u1 = str.charCodeAt(++i);\r\n u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);\r\n }\r\n if (u <= 0x7F) {\r\n if (outIdx >= endIdx) break;\r\n heap[outIdx++] = u;\r\n } else if (u <= 0x7FF) {\r\n if (outIdx + 1 >= endIdx) break;\r\n heap[outIdx++] = 0xC0 | (u >> 6);\r\n heap[outIdx++] = 0x80 | (u & 63);\r\n } else if (u <= 0xFFFF) {\r\n if (outIdx + 2 >= endIdx) break;\r\n heap[outIdx++] = 0xE0 | (u >> 12);\r\n heap[outIdx++] = 0x80 | ((u >> 6) & 63);\r\n heap[outIdx++] = 0x80 | (u & 63);\r\n } else {\r\n if (outIdx + 3 >= endIdx) break;\r\n heap[outIdx++] = 0xF0 | (u >> 18);\r\n heap[outIdx++] = 0x80 | ((u >> 12) & 63);\r\n heap[outIdx++] = 0x80 | ((u >> 6) & 63);\r\n heap[outIdx++] = 0x80 | (u & 63);\r\n }\r\n }\r\n // Null-terminate the pointer to the buffer.\r\n heap[outIdx] = 0;\r\n return outIdx - startIdx;\r\n }\r\n function stringToUTF8(str, outPtr, maxBytesToWrite) {\r\n return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);\r\n }\r\n function stringToUTF8OnStack(str) {\r\n var size = lengthBytesUTF8(str) + 1;\r\n var ret = stackAlloc(size);\r\n stringToUTF8(str, ret, size);\r\n return ret;\r\n }\r\n \r\n var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;\r\n \r\n /**\r\n * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given\r\n * array that contains uint8 values, returns a copy of that string as a\r\n * Javascript String object.\r\n * heapOrArray is either a regular array, or a JavaScript typed array view.\r\n * @param {number} idx\r\n * @param {number=} maxBytesToRead\r\n * @return {string}\r\n */\r\n function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) {\r\n var endIdx = idx + maxBytesToRead;\r\n var endPtr = idx;\r\n // TextDecoder needs to know the byte length in advance, it doesn't stop on\r\n // null terminator by itself. Also, use the length info to avoid running tiny\r\n // strings through TextDecoder, since .subarray() allocates garbage.\r\n // (As a tiny code save trick, compare endPtr against endIdx using a negation,\r\n // so that undefined means Infinity)\r\n while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;\r\n \r\n if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {\r\n return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));\r\n }\r\n var str = '';\r\n // If building with TextDecoder, we have already computed the string length\r\n // above, so test loop end condition against that\r\n while (idx < endPtr) {\r\n // For UTF8 byte structure, see:\r\n // http://en.wikipedia.org/wiki/UTF-8#Description\r\n // https://www.ietf.org/rfc/rfc2279.txt\r\n // https://tools.ietf.org/html/rfc3629\r\n var u0 = heapOrArray[idx++];\r\n if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }\r\n var u1 = heapOrArray[idx++] & 63;\r\n if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }\r\n var u2 = heapOrArray[idx++] & 63;\r\n if ((u0 & 0xF0) == 0xE0) {\r\n u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;\r\n } else {\r\n u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);\r\n }\r\n \r\n if (u0 < 0x10000) {\r\n str += String.fromCharCode(u0);\r\n } else {\r\n var ch = u0 - 0x10000;\r\n str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));\r\n }\r\n }\r\n return str;\r\n }\r\n \r\n \r\n /**\r\n * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the\r\n * emscripten HEAP, returns a copy of that string as a Javascript String object.\r\n *\r\n * @param {number} ptr\r\n * @param {number=} maxBytesToRead - An optional length that specifies the\r\n * maximum number of bytes to read. You can omit this parameter to scan the\r\n * string until the first \u0000 byte. If maxBytesToRead is passed, and the string\r\n * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the\r\n * string will cut short at that byte index (i.e. maxBytesToRead will not\r\n * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing\r\n * frequent uses of UTF8ToString() with and without maxBytesToRead may throw\r\n * JS JIT optimizations off, so it is worth to consider consistently using one\r\n * @return {string}\r\n */\r\n function UTF8ToString(ptr, maxBytesToRead) {\r\n return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';\r\n }\r\n \r\n /**\r\n * @param {string|null=} returnType\r\n * @param {Array=} argTypes\r\n * @param {Arguments|Array=} args\r\n * @param {Object=} opts\r\n */\r\n function ccall(ident, returnType, argTypes, args, opts) {\r\n // For fast lookup of conversion functions\r\n var toC = {\r\n 'string': (str) => {\r\n var ret = 0;\r\n if (str !== null && str !== undefined && str !== 0) { // null string\r\n // at most 4 bytes per UTF-8 code point, +1 for the trailing '\\0'\r\n ret = stringToUTF8OnStack(str);\r\n }\r\n return ret;\r\n },\r\n 'array': (arr) => {\r\n var ret = stackAlloc(arr.length);\r\n writeArrayToMemory(arr, ret);\r\n return ret;\r\n }\r\n };\r\n \r\n function convertReturnValue(ret) {\r\n if (returnType === 'string') {\r\n \r\n return UTF8ToString(ret);\r\n }\r\n if (returnType === 'boolean') return Boolean(ret);\r\n return ret;\r\n }\r\n \r\n var func = getCFunc(ident);\r\n var cArgs = [];\r\n var stack = 0;\r\n if (args) {\r\n for (var i = 0; i < args.length; i++) {\r\n var converter = toC[argTypes[i]];\r\n if (converter) {\r\n if (stack === 0) stack = stackSave();\r\n cArgs[i] = converter(args[i]);\r\n } else {\r\n cArgs[i] = args[i];\r\n }\r\n }\r\n }\r\n var ret = func.apply(null, cArgs);\r\n function onDone(ret) {\r\n if (stack !== 0) stackRestore(stack);\r\n return convertReturnValue(ret);\r\n }\r\n \r\n ret = onDone(ret);\r\n return ret;\r\n }\r\n \r\n /**\r\n * @param {string=} returnType\r\n * @param {Array=} argTypes\r\n * @param {Object=} opts\r\n */\r\n function cwrap(ident, returnType, argTypes, opts) {\r\n // When the function takes numbers and returns a number, we can just return\r\n // the original function\r\n var numericArgs = !argTypes || argTypes.every((type) => type === 'number' || type === 'boolean');\r\n var numericRet = returnType !== 'string';\r\n if (numericRet && numericArgs && !opts) {\r\n return getCFunc(ident);\r\n }\r\n return function() {\r\n return ccall(ident, returnType, argTypes, arguments, opts);\r\n }\r\n }\r\n\r\nvar wasmImports = {\r\n \"__cxa_throw\": ___cxa_throw,\r\n \"abort\": _abort,\r\n \"emscripten_memcpy_big\": _emscripten_memcpy_big,\r\n \"emscripten_resize_heap\": _emscripten_resize_heap\r\n};\r\nvar asm = createWasm();\r\n/** @type {function(...*):?} */\r\nvar ___wasm_call_ctors = function() {\r\n return (___wasm_call_ctors = Module[\"asm\"][\"__wasm_call_ctors\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar _dbscan = Module[\"_dbscan\"] = function() {\r\n return (_dbscan = Module[\"_dbscan\"] = Module[\"asm\"][\"dbscan\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar ___errno_location = function() {\r\n return (___errno_location = Module[\"asm\"][\"__errno_location\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar _malloc = Module[\"_malloc\"] = function() {\r\n return (_malloc = Module[\"_malloc\"] = Module[\"asm\"][\"malloc\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar _free = Module[\"_free\"] = function() {\r\n return (_free = Module[\"_free\"] = Module[\"asm\"][\"free\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar stackSave = function() {\r\n return (stackSave = Module[\"asm\"][\"stackSave\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar stackRestore = function() {\r\n return (stackRestore = Module[\"asm\"][\"stackRestore\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar stackAlloc = function() {\r\n return (stackAlloc = Module[\"asm\"][\"stackAlloc\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar ___cxa_is_pointer_type = function() {\r\n return (___cxa_is_pointer_type = Module[\"asm\"][\"__cxa_is_pointer_type\"]).apply(null, arguments);\r\n};\r\n\r\n\r\n\r\n// include: postamble.js\r\n// === Auto-generated postamble setup entry stuff ===\r\n\r\nModule[\"ccall\"] = ccall;\r\nModule[\"cwrap\"] = cwrap;\r\n\r\n\r\nvar calledRun;\r\n\r\ndependenciesFulfilled = function runCaller() {\r\n // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)\r\n if (!calledRun) run();\r\n if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled\r\n};\r\n\r\nfunction run() {\r\n\r\n if (runDependencies > 0) {\r\n return;\r\n }\r\n\r\n preRun();\r\n\r\n // a preRun added a dependency, run will be called later\r\n if (runDependencies > 0) {\r\n return;\r\n }\r\n\r\n function doRun() {\r\n // run may have just been called through dependencies being fulfilled just in this very frame,\r\n // or while the async setStatus time below was happening\r\n if (calledRun) return;\r\n calledRun = true;\r\n Module['calledRun'] = true;\r\n\r\n if (ABORT) return;\r\n\r\n initRuntime();\r\n\r\n readyPromiseResolve(Module);\r\n if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();\r\n\r\n postRun();\r\n }\r\n\r\n if (Module['setStatus']) {\r\n Module['setStatus']('Running...');\r\n setTimeout(function() {\r\n setTimeout(function() {\r\n Module['setStatus']('');\r\n }, 1);\r\n doRun();\r\n }, 1);\r\n } else\r\n {\r\n doRun();\r\n }\r\n}\r\n\r\nif (Module['preInit']) {\r\n if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];\r\n while (Module['preInit'].length > 0) {\r\n Module['preInit'].pop()();\r\n }\r\n}\r\n\r\nrun();\r\n\r\n\r\n// end include: postamble.js\r\n\r\n\r\n return exportCppDbscanLib.ready\r\n}\r\n\r\n);\r\n})();\r\nif (typeof exports === 'object' && typeof module === 'object')\r\n module.exports = exportCppDbscanLib;\r\nelse if (typeof define === 'function' && define['amd'])\r\n define([], function() { return exportCppDbscanLib; });\r\nelse if (typeof exports === 'object')\r\n exports[\"exportCppDbscanLib\"] = exportCppDbscanLib;\r\n","(function (root, factory) {\n // Hack to make all exports of this module sha256 function object properties.\n var exports = {};\n factory(exports);\n var sha256 = exports[\"default\"];\n for (var k in exports) {\n sha256[k] = exports[k];\n }\n \n if (typeof module === 'object' && typeof module.exports === 'object') {\n module.exports = sha256;\n } else if (typeof define === 'function' && define.amd) {\n define(function() { return sha256; }); \n } else {\n root.sha256 = sha256;\n }\n})(this, function(exports) {\n\"use strict\";\nexports.__esModule = true;\n// SHA-256 (+ HMAC and PBKDF2) for JavaScript.\n//\n// Written in 2014-2016 by Dmitry Chestnykh.\n// Public domain, no warranty.\n//\n// Functions (accept and return Uint8Arrays):\n//\n// sha256(message) -> hash\n// sha256.hmac(key, message) -> mac\n// sha256.pbkdf2(password, salt, rounds, dkLen) -> dk\n//\n// Classes:\n//\n// new sha256.Hash()\n// new sha256.HMAC(key)\n//\nexports.digestLength = 32;\nexports.blockSize = 64;\n// SHA-256 constants\nvar K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,\n 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,\n 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,\n 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,\n 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,\n 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,\n 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,\n 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,\n 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\nfunction hashBlocks(w, v, p, pos, len) {\n var a, b, c, d, e, f, g, h, u, i, j, t1, t2;\n while (len >= 64) {\n a = v[0];\n b = v[1];\n c = v[2];\n d = v[3];\n e = v[4];\n f = v[5];\n g = v[6];\n h = v[7];\n for (i = 0; i < 16; i++) {\n j = pos + i * 4;\n w[i] = (((p[j] & 0xff) << 24) | ((p[j + 1] & 0xff) << 16) |\n ((p[j + 2] & 0xff) << 8) | (p[j + 3] & 0xff));\n }\n for (i = 16; i < 64; i++) {\n u = w[i - 2];\n t1 = (u >>> 17 | u << (32 - 17)) ^ (u >>> 19 | u << (32 - 19)) ^ (u >>> 10);\n u = w[i - 15];\n t2 = (u >>> 7 | u << (32 - 7)) ^ (u >>> 18 | u << (32 - 18)) ^ (u >>> 3);\n w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0);\n }\n for (i = 0; i < 64; i++) {\n t1 = (((((e >>> 6 | e << (32 - 6)) ^ (e >>> 11 | e << (32 - 11)) ^\n (e >>> 25 | e << (32 - 25))) + ((e & f) ^ (~e & g))) | 0) +\n ((h + ((K[i] + w[i]) | 0)) | 0)) | 0;\n t2 = (((a >>> 2 | a << (32 - 2)) ^ (a >>> 13 | a << (32 - 13)) ^\n (a >>> 22 | a << (32 - 22))) + ((a & b) ^ (a & c) ^ (b & c))) | 0;\n h = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n v[0] += a;\n v[1] += b;\n v[2] += c;\n v[3] += d;\n v[4] += e;\n v[5] += f;\n v[6] += g;\n v[7] += h;\n pos += 64;\n len -= 64;\n }\n return pos;\n}\n// Hash implements SHA256 hash algorithm.\nvar Hash = /** @class */ (function () {\n function Hash() {\n this.digestLength = exports.digestLength;\n this.blockSize = exports.blockSize;\n // Note: Int32Array is used instead of Uint32Array for performance reasons.\n this.state = new Int32Array(8); // hash state\n this.temp = new Int32Array(64); // temporary state\n this.buffer = new Uint8Array(128); // buffer for data to hash\n this.bufferLength = 0; // number of bytes in buffer\n this.bytesHashed = 0; // number of total bytes hashed\n this.finished = false; // indicates whether the hash was finalized\n this.reset();\n }\n // Resets hash state making it possible\n // to re-use this instance to hash other data.\n Hash.prototype.reset = function () {\n this.state[0] = 0x6a09e667;\n this.state[1] = 0xbb67ae85;\n this.state[2] = 0x3c6ef372;\n this.state[3] = 0xa54ff53a;\n this.state[4] = 0x510e527f;\n this.state[5] = 0x9b05688c;\n this.state[6] = 0x1f83d9ab;\n this.state[7] = 0x5be0cd19;\n this.bufferLength = 0;\n this.bytesHashed = 0;\n this.finished = false;\n return this;\n };\n // Cleans internal buffers and re-initializes hash state.\n Hash.prototype.clean = function () {\n for (var i = 0; i < this.buffer.length; i++) {\n this.buffer[i] = 0;\n }\n for (var i = 0; i < this.temp.length; i++) {\n this.temp[i] = 0;\n }\n this.reset();\n };\n // Updates hash state with the given data.\n //\n // Optionally, length of the data can be specified to hash\n // fewer bytes than data.length.\n //\n // Throws error when trying to update already finalized hash:\n // instance must be reset to use it again.\n Hash.prototype.update = function (data, dataLength) {\n if (dataLength === void 0) { dataLength = data.length; }\n if (this.finished) {\n throw new Error(\"SHA256: can't update because hash was finished.\");\n }\n var dataPos = 0;\n this.bytesHashed += dataLength;\n if (this.bufferLength > 0) {\n while (this.bufferLength < 64 && dataLength > 0) {\n this.buffer[this.bufferLength++] = data[dataPos++];\n dataLength--;\n }\n if (this.bufferLength === 64) {\n hashBlocks(this.temp, this.state, this.buffer, 0, 64);\n this.bufferLength = 0;\n }\n }\n if (dataLength >= 64) {\n dataPos = hashBlocks(this.temp, this.state, data, dataPos, dataLength);\n dataLength %= 64;\n }\n while (dataLength > 0) {\n this.buffer[this.bufferLength++] = data[dataPos++];\n dataLength--;\n }\n return this;\n };\n // Finalizes hash state and puts hash into out.\n //\n // If hash was already finalized, puts the same value.\n Hash.prototype.finish = function (out) {\n if (!this.finished) {\n var bytesHashed = this.bytesHashed;\n var left = this.bufferLength;\n var bitLenHi = (bytesHashed / 0x20000000) | 0;\n var bitLenLo = bytesHashed << 3;\n var padLength = (bytesHashed % 64 < 56) ? 64 : 128;\n this.buffer[left] = 0x80;\n for (var i = left + 1; i < padLength - 8; i++) {\n this.buffer[i] = 0;\n }\n this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff;\n this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff;\n this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff;\n this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff;\n this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff;\n this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff;\n this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff;\n this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff;\n hashBlocks(this.temp, this.state, this.buffer, 0, padLength);\n this.finished = true;\n }\n for (var i = 0; i < 8; i++) {\n out[i * 4 + 0] = (this.state[i] >>> 24) & 0xff;\n out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;\n out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;\n out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;\n }\n return this;\n };\n // Returns the final hash digest.\n Hash.prototype.digest = function () {\n var out = new Uint8Array(this.digestLength);\n this.finish(out);\n return out;\n };\n // Internal function for use in HMAC for optimization.\n Hash.prototype._saveState = function (out) {\n for (var i = 0; i < this.state.length; i++) {\n out[i] = this.state[i];\n }\n };\n // Internal function for use in HMAC for optimization.\n Hash.prototype._restoreState = function (from, bytesHashed) {\n for (var i = 0; i < this.state.length; i++) {\n this.state[i] = from[i];\n }\n this.bytesHashed = bytesHashed;\n this.finished = false;\n this.bufferLength = 0;\n };\n return Hash;\n}());\nexports.Hash = Hash;\n// HMAC implements HMAC-SHA256 message authentication algorithm.\nvar HMAC = /** @class */ (function () {\n function HMAC(key) {\n this.inner = new Hash();\n this.outer = new Hash();\n this.blockSize = this.inner.blockSize;\n this.digestLength = this.inner.digestLength;\n var pad = new Uint8Array(this.blockSize);\n if (key.length > this.blockSize) {\n (new Hash()).update(key).finish(pad).clean();\n }\n else {\n for (var i = 0; i < key.length; i++) {\n pad[i] = key[i];\n }\n }\n for (var i = 0; i < pad.length; i++) {\n pad[i] ^= 0x36;\n }\n this.inner.update(pad);\n for (var i = 0; i < pad.length; i++) {\n pad[i] ^= 0x36 ^ 0x5c;\n }\n this.outer.update(pad);\n this.istate = new Uint32Array(8);\n this.ostate = new Uint32Array(8);\n this.inner._saveState(this.istate);\n this.outer._saveState(this.ostate);\n for (var i = 0; i < pad.length; i++) {\n pad[i] = 0;\n }\n }\n // Returns HMAC state to the state initialized with key\n // to make it possible to run HMAC over the other data with the same\n // key without creating a new instance.\n HMAC.prototype.reset = function () {\n this.inner._restoreState(this.istate, this.inner.blockSize);\n this.outer._restoreState(this.ostate, this.outer.blockSize);\n return this;\n };\n // Cleans HMAC state.\n HMAC.prototype.clean = function () {\n for (var i = 0; i < this.istate.length; i++) {\n this.ostate[i] = this.istate[i] = 0;\n }\n this.inner.clean();\n this.outer.clean();\n };\n // Updates state with provided data.\n HMAC.prototype.update = function (data) {\n this.inner.update(data);\n return this;\n };\n // Finalizes HMAC and puts the result in out.\n HMAC.prototype.finish = function (out) {\n if (this.outer.finished) {\n this.outer.finish(out);\n }\n else {\n this.inner.finish(out);\n this.outer.update(out, this.digestLength).finish(out);\n }\n return this;\n };\n // Returns message authentication code.\n HMAC.prototype.digest = function () {\n var out = new Uint8Array(this.digestLength);\n this.finish(out);\n return out;\n };\n return HMAC;\n}());\nexports.HMAC = HMAC;\n// Returns SHA256 hash of data.\nfunction hash(data) {\n var h = (new Hash()).update(data);\n var digest = h.digest();\n h.clean();\n return digest;\n}\nexports.hash = hash;\n// Function hash is both available as module.hash and as default export.\nexports[\"default\"] = hash;\n// Returns HMAC-SHA256 of data under the key.\nfunction hmac(key, data) {\n var h = (new HMAC(key)).update(data);\n var digest = h.digest();\n h.clean();\n return digest;\n}\nexports.hmac = hmac;\n// Fills hkdf buffer like this:\n// T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)\nfunction fillBuffer(buffer, hmac, info, counter) {\n // Counter is a byte value: check if it overflowed.\n var num = counter[0];\n if (num === 0) {\n throw new Error(\"hkdf: cannot expand more\");\n }\n // Prepare HMAC instance for new data with old key.\n hmac.reset();\n // Hash in previous output if it was generated\n // (i.e. counter is greater than 1).\n if (num > 1) {\n hmac.update(buffer);\n }\n // Hash in info if it exists.\n if (info) {\n hmac.update(info);\n }\n // Hash in the counter.\n hmac.update(counter);\n // Output result to buffer and clean HMAC instance.\n hmac.finish(buffer);\n // Increment counter inside typed array, this works properly.\n counter[0]++;\n}\nvar hkdfSalt = new Uint8Array(exports.digestLength); // Filled with zeroes.\nfunction hkdf(key, salt, info, length) {\n if (salt === void 0) { salt = hkdfSalt; }\n if (length === void 0) { length = 32; }\n var counter = new Uint8Array([1]);\n // HKDF-Extract uses salt as HMAC key, and key as data.\n var okm = hmac(salt, key);\n // Initialize HMAC for expanding with extracted key.\n // Ensure no collisions with `hmac` function.\n var hmac_ = new HMAC(okm);\n // Allocate buffer.\n var buffer = new Uint8Array(hmac_.digestLength);\n var bufpos = buffer.length;\n var out = new Uint8Array(length);\n for (var i = 0; i < length; i++) {\n if (bufpos === buffer.length) {\n fillBuffer(buffer, hmac_, info, counter);\n bufpos = 0;\n }\n out[i] = buffer[bufpos++];\n }\n hmac_.clean();\n buffer.fill(0);\n counter.fill(0);\n return out;\n}\nexports.hkdf = hkdf;\n// Derives a key from password and salt using PBKDF2-HMAC-SHA256\n// with the given number of iterations.\n//\n// The number of bytes returned is equal to dkLen.\n//\n// (For better security, avoid dkLen greater than hash length - 32 bytes).\nfunction pbkdf2(password, salt, iterations, dkLen) {\n var prf = new HMAC(password);\n var len = prf.digestLength;\n var ctr = new Uint8Array(4);\n var t = new Uint8Array(len);\n var u = new Uint8Array(len);\n var dk = new Uint8Array(dkLen);\n for (var i = 0; i * len < dkLen; i++) {\n var c = i + 1;\n ctr[0] = (c >>> 24) & 0xff;\n ctr[1] = (c >>> 16) & 0xff;\n ctr[2] = (c >>> 8) & 0xff;\n ctr[3] = (c >>> 0) & 0xff;\n prf.reset();\n prf.update(salt);\n prf.update(ctr);\n prf.finish(u);\n for (var j = 0; j < len; j++) {\n t[j] = u[j];\n }\n for (var j = 2; j <= iterations; j++) {\n prf.reset();\n prf.update(u).finish(u);\n for (var k = 0; k < len; k++) {\n t[k] ^= u[k];\n }\n }\n for (var j = 0; j < len && i * len + j < dkLen; j++) {\n dk[i * len + j] = t[j];\n }\n }\n for (var i = 0; i < len; i++) {\n t[i] = u[i] = 0;\n }\n for (var i = 0; i < 4; i++) {\n ctr[i] = 0;\n }\n prf.clean();\n return dk;\n}\nexports.pbkdf2 = pbkdf2;\n});\n","\"use strict\";\n// Reference: https://www.geeksforgeeks.org/jaro-and-jaro-winkler-similarity/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.jaroWinkler = exports.jaro = void 0;\n/**\n *\n * @param str1 String 1 for compare\n * @param str2 String 2 for compare\n * @param options to control case sensitive or not\n */\nfunction jaro(str1, str2, options) {\n // Exit early if either are empty.\n if (str1.length === 0 || str2.length === 0) {\n return 0;\n }\n // Convert to upper if case-sensitive is false.\n if (options && !options.caseSensitive) {\n str1 = str1.toUpperCase();\n str2 = str2.toUpperCase();\n }\n // Exact match\n if (str1 === str2) {\n return 1;\n }\n // Number of matches\n var m = 0;\n // Length of two Strings\n var len1 = str1.length;\n var len2 = str2.length;\n // Maximum distance\n var window = Math.floor(Math.max(len1, len2) / 2) - 1;\n // Hash for matches\n var str1Hash = new Array(len1);\n var str2Hash = new Array(len2);\n for (var i = 0; i < len1; i++) {\n for (var j = Math.max(0, i - window); j <= Math.min(len2, i + window + 1); j++) {\n if (!str1Hash[i] && !str2Hash[j] && str1[i] === str2[j]) {\n ++m;\n str1Hash[i] = str2Hash[j] = true;\n break;\n }\n }\n }\n // Exit early if no matches were found.\n if (m === 0) {\n return 0;\n }\n // Count the transpositions.\n var t = 0;\n var point = 0;\n for (var i = 0; i < len1; i++) {\n if (str1Hash[i]) {\n while (!str2Hash[point]) {\n point++;\n }\n if (str1.charAt(i) !== str2.charAt(point++)) {\n t++;\n }\n }\n }\n t /= 2;\n return (m / len1 + m / len2 + (m - t) / m) / 3;\n}\nexports.jaro = jaro;\n/**\n *\n * @param str1 String 1 for compare\n * @param str2 String 2 for compare\n * @param options to control case sensitive or not\n */\nfunction jaroWinkler(str1, str2, options) {\n // Jaro Distance\n var jaroDist = jaro(str1, str2, options);\n // Same prefix length, maxium is 4\n var prefix = 0;\n if (jaroDist > 0.7) {\n var minIndex = Math.min(str1.length, str2.length);\n var i = 0;\n while (str1[i] === str2[i] && i < 4 && i < minIndex) {\n ++prefix;\n i++;\n }\n jaroDist += 0.1 * prefix * (1 - jaroDist);\n }\n return jaroDist;\n}\nexports.jaroWinkler = jaroWinkler;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdO = {};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","// This function allow to reference async chunks\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.hmd = (module) => {\n\tmodule = Object.create(module);\n\tif (!module.children) module.children = [];\n\tObject.defineProperty(module, 'exports', {\n\t\tenumerable: true,\n\t\tset: () => {\n\t\t\tthrow new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);\n\t\t}\n\t});\n\treturn module;\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t255: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n// no on chunks loaded\n\n// no jsonp function","const __WEBPACK_NAMESPACE_OBJECT__ = DG;","const __WEBPACK_NAMESPACE_OBJECT__ = grok;","/* eslint-disable max-len */\nimport * as DG from 'datagrok-api/dg';\nimport * as sha256 from 'fast-sha256';\n/**\n * For columns of string type. Checks whether column contains empty values and removes corresponding rows in case user selects to remove.\n *\n */\nexport function removeEmptyStringRows(table, col) {\n const cats = col.categories;\n const emptyRawInd = cats.map((val, ind) => !val ? ind : null).filter((it) => it !== null);\n const rawData = [...col.getRawData()];\n const emptyRawsIndexes = [];\n let removedRowsCounter = 0;\n for (let i = 0; i < table.rowCount; i++) {\n if (emptyRawInd.includes(rawData[i])) {\n table.rows.removeAt(i - removedRowsCounter);\n emptyRawsIndexes.push(i);\n removedRowsCounter += 1;\n }\n }\n return emptyRawsIndexes;\n}\nexport function hashDataFrame(table, names) {\n names !== null && names !== void 0 ? names : (names = table.columns.names());\n const hasher = new sha256.Hash();\n const order = table.getSortedOrder(names);\n const encoder = new TextEncoder();\n for (const name of names) {\n const column = table.columns.byName(name);\n const dataArray = column.getRawData();\n const isString = column.type == DG.TYPE.STRING;\n const cats = column.categories;\n for (let i = 0; i < dataArray.length; i++) {\n if (isString) {\n const data = cats[dataArray[order[i]]];\n hasher.update(encoder.encode(data));\n }\n else {\n const data = dataArray[order[i]];\n hasher.update(Uint8Array.from([data]));\n }\n }\n }\n return hasher.digest();\n}\nexport const testData = DG.DataFrame.fromCsv(`countries,fasta,smiles,molregno,LON,Zip Code,Street Address Line 1,ImageUrl,user_id,error_message,xray,flag,magnitude,CS-id,pdb_id,accel_a,time_offset,chart,fit,Questions,empty_number,empty_string\nBelgium,MSNFHNEHVMQFYRNNLKTKGVFGRQ,CC(C(=O)OCCCc1cccnc1)c2cccc(c2)C(=O)c3ccccc3,1480014,36.276729583740234,995042300,14016 ROUTE 31W,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,1,1,1QBS,1,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.497360340644872, 1.7058694986686864, 5.278052678195135, 0.16000320889028383],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":2.374499797821045},{\"\"x\"\":0.6000000238418579,\"\"y\"\":2.6242473125457764},{\"\"x\"\":1.100000023841858,\"\"y\"\":2.367267608642578},{\"\"x\"\":1.600000023841858,\"\"y\"\":2.6723148822784424},{\"\"x\"\":2.0999999046325684,\"\"y\"\":2.6537344455718994},{\"\"x\"\":2.5999999046325684,\"\"y\"\":2.3651671409606934},{\"\"x\"\":3.0999999046325684,\"\"y\"\":2.5654284954071045},{\"\"x\"\":3.5999999046325684,\"\"y\"\":2.4160959720611572},{\"\"x\"\":4.099999904632568,\"\"y\"\":2.286726713180542},{\"\"x\"\":4.599999904632568,\"\"y\"\":2.5100042819976807},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.6676985025405884},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.680136501789093},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.3391543924808502},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.09038983285427094},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.19802775979042053}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[7.525235855508179, 1.3186911876809984, 5.335672608564294, 0.7860743343958098],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":7.988070487976074},{\"\"x\"\":0.6000000238418579,\"\"y\"\":7.018453121185303},{\"\"x\"\":1.100000023841858,\"\"y\"\":8.115279197692871},{\"\"x\"\":1.600000023841858,\"\"y\"\":7.486658096313477},{\"\"x\"\":2.0999999046325684,\"\"y\"\":7.396438121795654},{\"\"x\"\":2.5999999046325684,\"\"y\"\":7.477052211761475},{\"\"x\"\":3.0999999046325684,\"\"y\"\":6.913095474243164},{\"\"x\"\":3.5999999046325684,\"\"y\"\":8.01385498046875},{\"\"x\"\":4.099999904632568,\"\"y\"\":6.985900402069092},{\"\"x\"\":4.599999904632568,\"\"y\"\":6.970335960388184},{\"\"x\"\":5.099999904632568,\"\"y\"\":5.448817253112793},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.5534818172454834},{\"\"x\"\":6.099999904632568,\"\"y\"\":1.893947958946228},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.6340042352676392},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.8403874039649963}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,100,abc\nBurundi,MDYKETLLMPKTDFPMRGGLPNKEPQIQEKW,COc1ccc2cc(ccc2c1)C(C)C(=O)Oc3ccc(C)cc3OC,1480015,36.276729583740234,995073444,80 STATE HIGHWAY 310,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,2,2,1ZP8,2,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[4.431460753103398, 2.1691498799246745, 5.266445597102774, 0.7825762827017926],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":4.751083850860596},{\"\"x\"\":0.6000000238418579,\"\"y\"\":4.203000068664551},{\"\"x\"\":1.100000023841858,\"\"y\"\":4.415858745574951},{\"\"x\"\":1.600000023841858,\"\"y\"\":4.68414306640625},{\"\"x\"\":2.0999999046325684,\"\"y\"\":4.198400974273682},{\"\"x\"\":2.5999999046325684,\"\"y\"\":4.179222106933594},{\"\"x\"\":3.0999999046325684,\"\"y\"\":4.638473987579346},{\"\"x\"\":3.5999999046325684,\"\"y\"\":4.708553314208984},{\"\"x\"\":4.099999904632568,\"\"y\"\":4.291589260101318},{\"\"x\"\":4.599999904632568,\"\"y\"\":4.038082599639893},{\"\"x\"\":5.099999904632568,\"\"y\"\":3.4349939823150635},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.2194708585739136},{\"\"x\"\":6.099999904632568,\"\"y\"\":1.1920831203460693},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.5352635979652405},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.3346920311450958}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.339458017970126, -1.0734184310171178, 4.746332950550934, 0.2482416857595658],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.2139337658882141},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.4269562065601349},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.2441573292016983},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.146635964512825},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.08818462491035461},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.2560656666755676},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.42434045672416687},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.37111231684684753},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.5581737160682678},{\"\"x\"\":4.599999904632568,\"\"y\"\":1.183590054512024},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.5629843473434448},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.3211288452148438},{\"\"x\"\":6.099999904632568,\"\"y\"\":2.229961633682251},{\"\"x\"\":6.599999904632568,\"\"y\"\":2.2560226917266846},{\"\"x\"\":7.099999904632568,\"\"y\"\":2.2142398357391357}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nCameroon,MIEVFLFGIVLGLIPITLAGLFVTAYLQYRRGDQLDL,COc1ccc2cc(ccc2c1)C(C)C(=O)OCCCc3cccnc3,1480016,36.26095962524414,995153596,30-56 WHITESTONE EXPY,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,3,3,2BDJ,3,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[4.6760652578642325, 0.9046956320756703, 5.651408971856738, 0.07738846012184185],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":4.32425594329834},{\"\"x\"\":0.6000000238418579,\"\"y\"\":4.668442249298096},{\"\"x\"\":1.100000023841858,\"\"y\"\":4.379785060882568},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.0345139503479},{\"\"x\"\":2.0999999046325684,\"\"y\"\":4.878653526306152},{\"\"x\"\":2.5999999046325684,\"\"y\"\":4.3451313972473145},{\"\"x\"\":3.0999999046325684,\"\"y\"\":4.336992263793945},{\"\"x\"\":3.5999999046325684,\"\"y\"\":5.037430286407471},{\"\"x\"\":4.099999904632568,\"\"y\"\":5.0092692375183105},{\"\"x\"\":4.599999904632568,\"\"y\"\":4.151902675628662},{\"\"x\"\":5.099999904632568,\"\"y\"\":3.4066951274871826},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.3732759952545166},{\"\"x\"\":6.099999904632568,\"\"y\"\":1.673728108406067},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.48574790358543396},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.2783052325248718}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.938395863010111, -1.4658480661392117, 5.462702751996584, 0.3473139023615039],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.4941710829734802},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.15323974192142487},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.46373432874679565},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.3370431363582611},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.5179030299186707},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.27899765968322754},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.22075064480304718},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.5789918899536133},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.21169911324977875},{\"\"x\"\":4.599999904632568,\"\"y\"\":0.27857646346092224},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.0906332731246948},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.8520300388336182},{\"\"x\"\":6.099999904632568,\"\"y\"\":2.7177059650421143},{\"\"x\"\":6.599999904632568,\"\"y\"\":2.8680918216705322},{\"\"x\"\":7.099999904632568,\"\"y\"\":3.2413077354431152}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nCanada,MMELVLKTIIGPIVVGVVLRIVDKWLNKDK,CC(C(=O)NCCS)c1cccc(c1)C(=O)c2ccccc2,1480017,36.26095962524414,99515,30-56 WHITESTONE EXPY,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,4,4,1IAN,4,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[0.8597390975430008, 1.0957625732481946, 5.260537067987958, 0.07974187998177736],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.8190152645111084},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.8421689867973328},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.8740922212600708},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.8924275040626526},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.8249067664146423},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.9327669143676758},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.8522974252700806},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.8174492716789246},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.8394647240638733},{\"\"x\"\":4.599999904632568,\"\"y\"\":0.7139387726783752},{\"\"x\"\":5.099999904632568,\"\"y\"\":0.5561167597770691},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.3276226818561554},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.12479474395513535},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.13006797432899475},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.059702079743146896}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[5.760930219582546, 1.6591793293833013, 4.667155929720851, 0.7858109544121652],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":6.156993389129639},{\"\"x\"\":0.6000000238418579,\"\"y\"\":5.236701965332031},{\"\"x\"\":1.100000023841858,\"\"y\"\":6.010560512542725},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.495512962341309},{\"\"x\"\":2.0999999046325684,\"\"y\"\":6.087770462036133},{\"\"x\"\":2.5999999046325684,\"\"y\"\":5.79986572265625},{\"\"x\"\":3.0999999046325684,\"\"y\"\":5.597546577453613},{\"\"x\"\":3.5999999046325684,\"\"y\"\":5.520902156829834},{\"\"x\"\":4.099999904632568,\"\"y\"\":5.360654354095459},{\"\"x\"\":4.599999904632568,\"\"y\"\":3.5539746284484863},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.577236294746399},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.0001264810562134},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.9305797815322876},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.6033638715744019},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.4203685522079468}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nColombia,MDRTDEVSNHTHDKPTLTWFEEIFEEYHSPFHN,FC(F)(F)c1ccc(OC2CCNCC2)cc1,1480029,36.3309440612793,995152050,1 COURT HOUSE SQUARE,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,5,5,4UJ1,5,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[6.4995088314153655, 2.4270351004539914, 5.178659535348579, 0.625653346241577],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":6.496231555938721},{\"\"x\"\":0.6000000238418579,\"\"y\"\":6.42543363571167},{\"\"x\"\":1.100000023841858,\"\"y\"\":7.040063858032227},{\"\"x\"\":1.600000023841858,\"\"y\"\":6.1115403175354},{\"\"x\"\":2.0999999046325684,\"\"y\"\":6.680728435516357},{\"\"x\"\":2.5999999046325684,\"\"y\"\":6.406774520874023},{\"\"x\"\":3.0999999046325684,\"\"y\"\":6.611269474029541},{\"\"x\"\":3.5999999046325684,\"\"y\"\":5.889094352722168},{\"\"x\"\":4.099999904632568,\"\"y\"\":6.75344705581665},{\"\"x\"\":4.599999904632568,\"\"y\"\":6.361435890197754},{\"\"x\"\":5.099999904632568,\"\"y\"\":4.1666975021362305},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.172118902206421},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.801048994064331},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.4640021026134491},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.0010357667924836278}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[1.4734381347446401, 1.1649805188074196, 4.82958608866421, 0.09500545496710007],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":1.5279096364974976},{\"\"x\"\":0.6000000238418579,\"\"y\"\":1.3559974431991577},{\"\"x\"\":1.100000023841858,\"\"y\"\":1.5246378183364868},{\"\"x\"\":1.600000023841858,\"\"y\"\":1.5567657947540283},{\"\"x\"\":2.0999999046325684,\"\"y\"\":1.4114240407943726},{\"\"x\"\":2.5999999046325684,\"\"y\"\":1.4045010805130005},{\"\"x\"\":3.0999999046325684,\"\"y\"\":1.4769829511642456},{\"\"x\"\":3.5999999046325684,\"\"y\"\":1.4875500202178955},{\"\"x\"\":4.099999904632568,\"\"y\"\":1.2991987466812134},{\"\"x\"\":4.599999904632568,\"\"y\"\":0.922961413860321},{\"\"x\"\":5.099999904632568,\"\"y\"\":0.6520044803619385},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.15350978076457977},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.1078903079032898},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.17276449501514435},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.14066608250141144}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nCosta Rica,MKSTKEEIQTIKTLLKDSRTAKYHKRLQIVL,CC(C)Cc1ccc(cc1)C(C)C(=O)N2CCCC2C(=O)OCCCc3ccccc3,1480018,36.3309440612793,995084218,4041 SOUTHWESTERN BLVD,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,6,6,2BPW,6,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.4833641843311227, -1.8945978742090062, 4.671127708092568, 0.24159861311815153],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.0969524160027504},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.028483040630817413},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.22087176144123077},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.0068915546871721745},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.4305879771709442},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.44774115085601807},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.45346319675445557},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.2370593100786209},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.4657953977584839},{\"\"x\"\":4.599999904632568,\"\"y\"\":1.155200719833374},{\"\"x\"\":5.099999904632568,\"\"y\"\":2.2294070720672607},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.4311530590057373},{\"\"x\"\":6.099999904632568,\"\"y\"\":2.33846116065979},{\"\"x\"\":6.599999904632568,\"\"y\"\":2.608201026916504},{\"\"x\"\":7.099999904632568,\"\"y\"\":2.8136143684387207}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[5.224573521642033, 1.4454033924198528, 5.6014197746076535, 0.2823216054197577],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":4.95027494430542},{\"\"x\"\":0.6000000238418579,\"\"y\"\":5.1754679679870605},{\"\"x\"\":1.100000023841858,\"\"y\"\":5.276752948760986},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.589294910430908},{\"\"x\"\":2.0999999046325684,\"\"y\"\":5.616994857788086},{\"\"x\"\":2.5999999046325684,\"\"y\"\":5.120813846588135},{\"\"x\"\":3.0999999046325684,\"\"y\"\":5.340766906738281},{\"\"x\"\":3.5999999046325684,\"\"y\"\":4.876471042633057},{\"\"x\"\":4.099999904632568,\"\"y\"\":4.94999361038208},{\"\"x\"\":4.599999904632568,\"\"y\"\":5.162564754486084},{\"\"x\"\":5.099999904632568,\"\"y\"\":4.399557590484619},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.7977969646453857},{\"\"x\"\":6.099999904632568,\"\"y\"\":1.0229872465133667},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.48275601863861084},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.10408931970596313}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nCuba,MHAILRYFIRRLFYHIFYKIYSLISKKHQSLPSDVRQF,COc1ccc2c(c1)c(CC(=O)N3CCCC3C(=O)Oc4ccc(C)cc4OC)c(C)n2C(=O)c5ccc(Cl)cc5,1480019,36.33115768432617,995081928,1227 US HIGHWAY 11,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,7,7,1QBS,7,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[3.320838679713925, -1.2421619987316728, 4.831325425225256, 0.3236011098403072],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.3727470338344574},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.12365014106035233},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.48422467708587646},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.2264465093612671},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.16821794211864471},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.3879014551639557},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.5470244884490967},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.3419053554534912},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.7655120491981506},{\"\"x\"\":4.599999904632568,\"\"y\"\":1.2346516847610474},{\"\"x\"\":5.099999904632568,\"\"y\"\":2.453336715698242},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.9565491676330566},{\"\"x\"\":6.099999904632568,\"\"y\"\":3.335299491882324},{\"\"x\"\":6.599999904632568,\"\"y\"\":3.240290880203247},{\"\"x\"\":7.099999904632568,\"\"y\"\":3.1107218265533447}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[3.6401853521511094, 1.26211588875013, 5.399028074402744, 0.5089580830068091],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":3.8585598468780518},{\"\"x\"\":0.6000000238418579,\"\"y\"\":3.6077206134796143},{\"\"x\"\":1.100000023841858,\"\"y\"\":3.855252265930176},{\"\"x\"\":1.600000023841858,\"\"y\"\":3.619039297103882},{\"\"x\"\":2.0999999046325684,\"\"y\"\":3.839388370513916},{\"\"x\"\":2.5999999046325684,\"\"y\"\":3.335283041000366},{\"\"x\"\":3.0999999046325684,\"\"y\"\":3.571141481399536},{\"\"x\"\":3.5999999046325684,\"\"y\"\":3.4155046939849854},{\"\"x\"\":4.099999904632568,\"\"y\"\":3.7316646575927734},{\"\"x\"\":4.599999904632568,\"\"y\"\":3.0680155754089355},{\"\"x\"\":5.099999904632568,\"\"y\"\":2.891066551208496},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.6022753715515137},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.7652576565742493},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.6875326037406921},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.5828871726989746}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nItaly,MSNFHNEHVMQFYRNNLKTKGVFGRQ,CC(C)Cc1ccc(cc1)C(C)C(=O)N2CCCC2C(=O)OCCO[N+](=O)[O-],1480020,36.33115768432617,99502,\"168-46 91ST AVE., 2ND FLR\",https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,8,8,1ZP8,8,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.293592105923809, 1.3781586549141835, 5.1025898038676605, 0.03493851245291291],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":2.1287283897399902},{\"\"x\"\":0.6000000238418579,\"\"y\"\":2.267972230911255},{\"\"x\"\":1.100000023841858,\"\"y\"\":2.398442506790161},{\"\"x\"\":1.600000023841858,\"\"y\"\":2.5130622386932373},{\"\"x\"\":2.0999999046325684,\"\"y\"\":2.3255116939544678},{\"\"x\"\":2.5999999046325684,\"\"y\"\":2.127340793609619},{\"\"x\"\":3.0999999046325684,\"\"y\"\":2.47259783744812},{\"\"x\"\":3.5999999046325684,\"\"y\"\":2.131181478500366},{\"\"x\"\":4.099999904632568,\"\"y\"\":2.090421438217163},{\"\"x\"\":4.599999904632568,\"\"y\"\":2.02299165725708},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.1105059385299683},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.4494485855102539},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.1375635862350464},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.036351121962070465},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.1619771122932434}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[5.953125499439879, 1.2528620255306528, 5.187637440149802, 0.3110348753260886],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":5.6585283279418945},{\"\"x\"\":0.6000000238418579,\"\"y\"\":5.911152362823486},{\"\"x\"\":1.100000023841858,\"\"y\"\":5.924920082092285},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.8469438552856445},{\"\"x\"\":2.0999999046325684,\"\"y\"\":5.929472923278809},{\"\"x\"\":2.5999999046325684,\"\"y\"\":6.190037727355957},{\"\"x\"\":3.0999999046325684,\"\"y\"\":6.236179828643799},{\"\"x\"\":3.5999999046325684,\"\"y\"\":6.141019344329834},{\"\"x\"\":4.099999904632568,\"\"y\"\":5.295210838317871},{\"\"x\"\":4.599999904632568,\"\"y\"\":5.265801906585693},{\"\"x\"\":5.099999904632568,\"\"y\"\":3.3722851276397705},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.8299226760864258},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.32690900564193726},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.6274543404579163},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.8441857099533081}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nRwanda,MPNSEPASLLELFNSIATQGELVRSLKAGNASK,CC(C)Cc1ccc(cc1)C(C)C(=O)N2CCCC2C(=O)OCCO,1480021,36.33137130737305,995037247,\"168-46 91ST AVE., 2ND FLR\",https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,9,9,2BDJ,9,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[3.8209972202654474, 1.3779216716448506, 5.299882228439686, 0.06040645519069608],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":3.7821109294891357},{\"\"x\"\":0.6000000238418579,\"\"y\"\":3.542433023452759},{\"\"x\"\":1.100000023841858,\"\"y\"\":3.7008674144744873},{\"\"x\"\":1.600000023841858,\"\"y\"\":3.717301607131958},{\"\"x\"\":2.0999999046325684,\"\"y\"\":4.024452209472656},{\"\"x\"\":2.5999999046325684,\"\"y\"\":4.013899326324463},{\"\"x\"\":3.0999999046325684,\"\"y\"\":3.945094347000122},{\"\"x\"\":3.5999999046325684,\"\"y\"\":3.866621971130371},{\"\"x\"\":4.099999904632568,\"\"y\"\":3.7461626529693604},{\"\"x\"\":4.599999904632568,\"\"y\"\":3.3454740047454834},{\"\"x\"\":5.099999904632568,\"\"y\"\":2.61944317817688},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.999405026435852},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.46259793639183044},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.054134611040353775},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.05711187422275543}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[5.6318079657726035, 1.8495493770000595, 5.391793312471116, 0.17060707587348442],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":5.458079814910889},{\"\"x\"\":0.6000000238418579,\"\"y\"\":5.554427146911621},{\"\"x\"\":1.100000023841858,\"\"y\"\":5.799983024597168},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.364140033721924},{\"\"x\"\":2.0999999046325684,\"\"y\"\":5.864485740661621},{\"\"x\"\":2.5999999046325684,\"\"y\"\":5.4509806632995605},{\"\"x\"\":3.0999999046325684,\"\"y\"\":5.702574729919434},{\"\"x\"\":3.5999999046325684,\"\"y\"\":5.7314534187316895},{\"\"x\"\":4.099999904632568,\"\"y\"\":5.5123443603515625},{\"\"x\"\":4.599999904632568,\"\"y\"\":5.724395751953125},{\"\"x\"\":5.099999904632568,\"\"y\"\":4.354506969451904},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.7307666540145874},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.6305936574935913},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.035183437168598175},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.7575169205665588}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nSwitzerland,IRVVGRYLIEVWKAAGMDMDKVLFLWSSDEI,CN1CCC(CC1)Oc2ccc(cc2)C(F)(F)F,1480028,36.33137130737305,99504,92-11 179TH PLACE,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,9,10,1IAN,10,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[1.1190255865097471, 2.3163895161544437, 5.4968866182279195, 0.2035204047289052],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":1.1057683229446411},{\"\"x\"\":0.6000000238418579,\"\"y\"\":1.1019697189331055},{\"\"x\"\":1.100000023841858,\"\"y\"\":1.0818607807159424},{\"\"x\"\":1.600000023841858,\"\"y\"\":1.062997817993164},{\"\"x\"\":2.0999999046325684,\"\"y\"\":1.046447515487671},{\"\"x\"\":2.5999999046325684,\"\"y\"\":1.1217249631881714},{\"\"x\"\":3.0999999046325684,\"\"y\"\":1.2166996002197266},{\"\"x\"\":3.5999999046325684,\"\"y\"\":1.215477705001831},{\"\"x\"\":4.099999904632568,\"\"y\"\":1.0581893920898438},{\"\"x\"\":4.599999904632568,\"\"y\"\":1.1747995615005493},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.0181127786636353},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.5344523191452026},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.2569526433944702},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.1912207305431366},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.15060538053512573}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[3.1038581025805785, 2.0032224204185245, 5.087602825989163, 0.13277988512492753],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":3.0498509407043457},{\"\"x\"\":0.6000000238418579,\"\"y\"\":2.805217742919922},{\"\"x\"\":1.100000023841858,\"\"y\"\":3.3415253162384033},{\"\"x\"\":1.600000023841858,\"\"y\"\":3.0549843311309814},{\"\"x\"\":2.0999999046325684,\"\"y\"\":3.250074863433838},{\"\"x\"\":2.5999999046325684,\"\"y\"\":3.0432586669921875},{\"\"x\"\":3.0999999046325684,\"\"y\"\":3.265852451324463},{\"\"x\"\":3.5999999046325684,\"\"y\"\":2.9475724697113037},{\"\"x\"\":4.099999904632568,\"\"y\"\":3.1929898262023926},{\"\"x\"\":4.599999904632568,\"\"y\"\":2.7460060119628906},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.6175861358642578},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.3006608486175537},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.3444803059101105},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.015537971630692482},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.5527358055114746}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\n,,,,,,,,,,,,,,,,,,,,,`);\ntestData.columns.add(DG.Column.fromList(DG.TYPE.BYTE_ARRAY, 'BinaryImage', Array.from(new Uint8Array(11))));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWZyYW1lLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGF0YWZyYW1lLXV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRCQUE0QjtBQUM1QixPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RDLE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ3RDOzs7R0FHRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxLQUFtQixFQUFFLEdBQWM7SUFDdkUsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQztJQUM1QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7SUFDMUYsTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0lBQzVCLElBQUksa0JBQWtCLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3ZDLElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNwQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsa0JBQWtCLENBQUMsQ0FBQztZQUM1QyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekIsa0JBQWtCLElBQUksQ0FBQyxDQUFDO1NBQ3pCO0tBQ0Y7SUFDRCxPQUFPLGdCQUFnQixDQUFDO0FBQzFCLENBQUM7QUFFRCxNQUFNLFVBQVUsYUFBYSxDQUFDLEtBQW1CLEVBQUUsS0FBZ0I7SUFDakUsS0FBSyxhQUFMLEtBQUssY0FBTCxLQUFLLElBQUwsS0FBSyxHQUFLLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUM7SUFDaEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDakMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO0lBQ2xDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO1FBQ3hCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFDLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN0QyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQy9DLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUM7UUFDL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDekMsSUFBSSxRQUFRLEVBQUU7Z0JBQ1osTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2QyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzthQUNyQztpQkFBTTtnQkFDTCxNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pDLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN4QztTQUNGO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN6QixDQUFDO0FBRUQsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O3NCQStCdkIsQ0FBQyxDQUFDO0FBQ3hCLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCAqIGFzIHNoYTI1NiBmcm9tICdmYXN0LXNoYTI1Nic7XG4vKipcbiAqIEZvciBjb2x1bW5zIG9mIHN0cmluZyB0eXBlLiBDaGVja3Mgd2hldGhlciBjb2x1bW4gY29udGFpbnMgZW1wdHkgdmFsdWVzIGFuZCByZW1vdmVzIGNvcnJlc3BvbmRpbmcgcm93cyBpbiBjYXNlIHVzZXIgc2VsZWN0cyB0byByZW1vdmUuXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlRW1wdHlTdHJpbmdSb3dzKHRhYmxlOiBERy5EYXRhRnJhbWUsIGNvbDogREcuQ29sdW1uKTogbnVtYmVyW10ge1xuICBjb25zdCBjYXRzID0gY29sLmNhdGVnb3JpZXM7XG4gIGNvbnN0IGVtcHR5UmF3SW5kID0gY2F0cy5tYXAoKHZhbCwgaW5kKSA9PiAhdmFsID8gaW5kIDogbnVsbCkuZmlsdGVyKChpdCkgPT4gaXQgIT09IG51bGwpO1xuICBjb25zdCByYXdEYXRhID0gWy4uLmNvbC5nZXRSYXdEYXRhKCldO1xuICBjb25zdCBlbXB0eVJhd3NJbmRleGVzID0gW107XG4gIGxldCByZW1vdmVkUm93c0NvdW50ZXIgPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHRhYmxlLnJvd0NvdW50OyBpKyspIHtcbiAgICBpZiAoZW1wdHlSYXdJbmQuaW5jbHVkZXMocmF3RGF0YVtpXSkpIHtcbiAgICAgIHRhYmxlLnJvd3MucmVtb3ZlQXQoaSAtIHJlbW92ZWRSb3dzQ291bnRlcik7XG4gICAgICBlbXB0eVJhd3NJbmRleGVzLnB1c2goaSk7XG4gICAgICByZW1vdmVkUm93c0NvdW50ZXIgKz0gMTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVtcHR5UmF3c0luZGV4ZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNoRGF0YUZyYW1lKHRhYmxlOiBERy5EYXRhRnJhbWUsIG5hbWVzPzogc3RyaW5nW10pOiBVaW50OEFycmF5IHtcbiAgbmFtZXMgPz89IHRhYmxlLmNvbHVtbnMubmFtZXMoKTtcbiAgY29uc3QgaGFzaGVyID0gbmV3IHNoYTI1Ni5IYXNoKCk7XG4gIGNvbnN0IG9yZGVyID0gdGFibGUuZ2V0U29ydGVkT3JkZXIobmFtZXMpO1xuICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG4gIGZvciAoY29uc3QgbmFtZSBvZiBuYW1lcykge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRhYmxlLmNvbHVtbnMuYnlOYW1lKG5hbWUpO1xuICAgIGNvbnN0IGRhdGFBcnJheSA9IGNvbHVtbi5nZXRSYXdEYXRhKCk7XG4gICAgY29uc3QgaXNTdHJpbmcgPSBjb2x1bW4udHlwZSA9PSBERy5UWVBFLlNUUklORztcbiAgICBjb25zdCBjYXRzID0gY29sdW1uLmNhdGVnb3JpZXM7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChpc1N0cmluZykge1xuICAgICAgICBjb25zdCBkYXRhID0gY2F0c1tkYXRhQXJyYXlbb3JkZXJbaV1dXTtcbiAgICAgICAgaGFzaGVyLnVwZGF0ZShlbmNvZGVyLmVuY29kZShkYXRhKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBkYXRhID0gZGF0YUFycmF5W29yZGVyW2ldXTtcbiAgICAgICAgaGFzaGVyLnVwZGF0ZShVaW50OEFycmF5LmZyb20oW2RhdGFdKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBoYXNoZXIuZGlnZXN0KCk7XG59XG5cbmV4cG9ydCBjb25zdCB0ZXN0RGF0YSA9IERHLkRhdGFGcmFtZS5mcm9tQ3N2KGBjb3VudHJpZXMsZmFzdGEsc21pbGVzLG1vbHJlZ25vLExPTixaaXAgQ29kZSxTdHJlZXQgQWRkcmVzcyBMaW5lIDEsSW1hZ2VVcmwsdXNlcl9pZCxlcnJvcl9tZXNzYWdlLHhyYXksZmxhZyxtYWduaXR1ZGUsQ1MtaWQscGRiX2lkLGFjY2VsX2EsdGltZV9vZmZzZXQsY2hhcnQsZml0LFF1ZXN0aW9ucyxlbXB0eV9udW1iZXIsZW1wdHlfc3RyaW5nXG5CZWxnaXVtLE1TTkZITkVIVk1RRllSTk5MS1RLR1ZGR1JRLENDKEMoPU8pT0NDQ2MxY2NjbmMxKWMyY2NjYyhjMilDKD1PKWMzY2NjY2MzLDE0ODAwMTQsMzYuMjc2NzI5NTgzNzQwMjM0LDk5NTA0MjMwMCwxNDAxNiBST1VURSAzMVcsaHR0cHM6Ly9kYXRhZ3Jvay5haS9pbWcvc2xpZGVzL2FjY2Vzcy1kYi1jb25uZWN0LnBuZyxpZCxFcnJvck1lc3NhZ2UsXCJDT01QTkQgXG5BVE9NIFxuRU5EXCIsZmxhZywxLDEsMVFCUywxLDEuMjMsPGNoYXJ0PjwvY2hhcnQ+LFwie1wiXCJzZXJpZXNcIlwiOlt7XCJcIm5hbWVcIlwiOlwiXCJSdW46MjAyMy0wOC0wOFwiXCIsXCJcImZpdEZ1bmN0aW9uXCJcIjpcIlwic2lnbW9pZFwiXCIsXCJcImZpdExpbmVDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJwb2ludENvbG9yXCJcIjpcIlwiIzFmNzdiNFwiXCIsXCJcInNob3dQb2ludHNcIlwiOlwiXCJwb2ludHNcIlwiLFwiXCJwYXJhbWV0ZXJzXCJcIjpbMi40OTczNjAzNDA2NDQ4NzIsIDEuNzA1ODY5NDk4NjY4Njg2NCwgNS4yNzgwNTI2NzgxOTUxMzUsIDAuMTYwMDAzMjA4ODkwMjgzODNdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjIuMzc0NDk5Nzk3ODIxMDQ1fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Mi42MjQyNDczMTI1NDU3NzY0fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjoyLjM2NzI2NzYwODY0MjU3OH0se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6Mi42NzIzMTQ4ODIyNzg0NDI0fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Mi42NTM3MzQ0NDU1NzE4OTk0fSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Mi4zNjUxNjcxNDA5NjA2OTM0fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Mi41NjU0Mjg0OTU0MDcxMDQ1fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Mi40MTYwOTU5NzIwNjExNTcyfSx7XCJcInhcIlwiOjQuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjI4NjcyNjcxMzE4MDU0Mn0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi41MTAwMDQyODE5OTc2ODA3fSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjY2NzY5ODUwMjU0MDU4ODR9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNjgwMTM2NTAxNzg5MDkzfSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjMzOTE1NDM5MjQ4MDg1MDJ9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMDkwMzg5ODMyODU0MjcwOTR9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTk4MDI3NzU5NzkwNDIwNTN9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzcuNTI1MjM1ODU1NTA4MTc5LCAxLjMxODY5MTE4NzY4MDk5ODQsIDUuMzM1NjcyNjA4NTY0Mjk0LCAwLjc4NjA3NDMzNDM5NTgwOThdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjcuOTg4MDcwNDg3OTc2MDc0fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Ny4wMTg0NTMxMjExODUzMDN9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjguMTE1Mjc5MTk3NjkyODcxfSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjo3LjQ4NjY1ODA5NjMxMzQ3N30se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjcuMzk2NDM4MTIxNzk1NjU0fSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Ny40NzcwNTIyMTE3NjE0NzV9LHtcIlwieFwiXCI6My4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo2LjkxMzA5NTQ3NDI0MzE2NH0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjguMDEzODU0OTgwNDY4NzV9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjYuOTg1OTAwNDAyMDY5MDkyfSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo2Ljk3MDMzNTk2MDM4ODE4NH0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6NS40NDg4MTcyNTMxMTI3OTN9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuNTUzNDgxODE3MjQ1NDgzNH0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS44OTM5NDc5NTg5NDYyMjh9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNjM0MDA0MjM1MjY3NjM5Mn0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC44NDAzODc0MDM5NjQ5OTYzfV19XSxcIlwiY2hhcnRPcHRpb25zXCJcIjp7XCJcInhBeGlzTmFtZVwiXCI6XCJcIkNvbmMuXCJcIixcIlwieUF4aXNOYW1lXCJcIjpcIlwiQWN0aXZpdHlcIlwiLFwiXCJ0aXRsZVwiXCI6XCJcIkRvc2UtUmVzcG9uc2UgY3VydmVzXCJcIn19XCIsdGV4dCwxMDAsYWJjXG5CdXJ1bmRpLE1EWUtFVExMTVBLVERGUE1SR0dMUE5LRVBRSVFFS1csQ09jMWNjYzJjYyhjY2MyYzEpQyhDKUMoPU8pT2MzY2NjKEMpY2MzT0MsMTQ4MDAxNSwzNi4yNzY3Mjk1ODM3NDAyMzQsOTk1MDczNDQ0LDgwIFNUQVRFIEhJR0hXQVkgMzEwLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsMiwyLDFaUDgsMiwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzQuNDMxNDYwNzUzMTAzMzk4LCAyLjE2OTE0OTg3OTkyNDY3NDUsIDUuMjY2NDQ1NTk3MTAyNzc0LCAwLjc4MjU3NjI4MjcwMTc5MjZdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjQuNzUxMDgzODUwODYwNTk2fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6NC4yMDMwMDAwNjg2NjQ1NTF9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjQuNDE1ODU4NzQ1NTc0OTUxfSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjo0LjY4NDE0MzA2NjQwNjI1fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC4xOTg0MDA5NzQyNzM2ODJ9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo0LjE3OTIyMjEwNjkzMzU5NH0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjQuNjM4NDczOTg3NTc5MzQ2fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC43MDg1NTMzMTQyMDg5ODR9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjQuMjkxNTg5MjYwMTAxMzE4fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo0LjAzODA4MjU5OTYzOTg5M30se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My40MzQ5OTM5ODIzMTUwNjM1fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjIxOTQ3MDg1ODU3MzkxMzZ9LHtcIlwieFwiXCI6Ni4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMTkyMDgzMTIwMzQ2MDY5M30se1wiXCJ4XCJcIjo2LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC41MzUyNjM1OTc5NjUyNDA1fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjMzNDY5MjAzMTE0NTA5NTh9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzIuMzM5NDU4MDE3OTcwMTI2LCAtMS4wNzM0MTg0MzEwMTcxMTc4LCA0Ljc0NjMzMjk1MDU1MDkzNCwgMC4yNDgyNDE2ODU3NTk1NjU4XSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjowLjIxMzkzMzc2NTg4ODIxNDF9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjowLjQyNjk1NjIwNjU2MDEzNDl9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjAuMjQ0MTU3MzI5MjAxNjk4M30se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6MC4xNDY2MzU5NjQ1MTI4MjV9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjA4ODE4NDYyNDkxMDM1NDYxfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC4yNTYwNjU2NjY2NzU1Njc2fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC40MjQzNDA0NTY3MjQxNjY4N30se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuMzcxMTEyMzE2ODQ2ODQ3NTN9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNTU4MTczNzE2MDY4MjY3OH0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4xODM1OTAwNTQ1MTIwMjR9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuNTYyOTg0MzQ3MzQzNDQ0OH0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi4zMjExMjg4NDUyMTQ4NDM4fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjIyOTk2MTYzMzY4MjI1MX0se1wiXCJ4XCJcIjo2LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi4yNTYwMjI2OTE3MjY2ODQ2fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjIxNDIzOTgzNTczOTEzNTd9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbkNhbWVyb29uLE1JRVZGTEZHSVZMR0xJUElUTEFHTEZWVEFZTFFZUlJHRFFMREwsQ09jMWNjYzJjYyhjY2MyYzEpQyhDKUMoPU8pT0NDQ2MzY2NjbmMzLDE0ODAwMTYsMzYuMjYwOTU5NjI1MjQ0MTQsOTk1MTUzNTk2LDMwLTU2IFdISVRFU1RPTkUgRVhQWSxodHRwczovL2RhdGFncm9rLmFpL2ltZy9zbGlkZXMvYWNjZXNzLWRiLWNvbm5lY3QucG5nLGlkLEVycm9yTWVzc2FnZSxcIkNPTVBORCBcbkFUT00gXG5FTkRcIixmbGFnLDMsMywyQkRKLDMsMS4yMyw8Y2hhcnQ+PC9jaGFydD4sXCJ7XCJcInNlcmllc1wiXCI6W3tcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0RnVuY3Rpb25cIlwiOlwiXCJzaWdtb2lkXCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiIzFmNzdiNFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOls0LjY3NjA2NTI1Nzg2NDIzMjUsIDAuOTA0Njk1NjMyMDc1NjcwMywgNS42NTE0MDg5NzE4NTY3MzgsIDAuMDc3Mzg4NDYwMTIxODQxODVdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjQuMzI0MjU1OTQzMjk4MzR9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjo0LjY2ODQ0MjI0OTI5ODA5Nn0se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6NC4zNzk3ODUwNjA4ODI1Njh9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjUuMDM0NTEzOTUwMzQ3OX0se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjQuODc4NjUzNTI2MzA2MTUyfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC4zNDUxMzEzOTcyNDczMTQ1fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC4zMzY5OTIyNjM3OTM5NDV9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1LjAzNzQzMDI4NjQwNzQ3MX0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6NS4wMDkyNjkyMzc1MTgzMTA1fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo0LjE1MTkwMjY3NTYyODY2Mn0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My40MDY2OTUxMjc0ODcxODI2fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjM3MzI3NTk5NTI1NDUxNjZ9LHtcIlwieFwiXCI6Ni4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuNjczNzI4MTA4NDA2MDY3fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjQ4NTc0NzkwMzU4NTQzMzk2fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjI3ODMwNTIzMjUyNDg3MTh9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzIuOTM4Mzk1ODYzMDEwMTExLCAtMS40NjU4NDgwNjYxMzkyMTE3LCA1LjQ2MjcwMjc1MTk5NjU4NCwgMC4zNDczMTM5MDIzNjE1MDM5XSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjowLjQ5NDE3MTA4Mjk3MzQ4MDJ9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjowLjE1MzIzOTc0MTkyMTQyNDg3fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjQ2MzczNDMyODc0Njc5NTY1fSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjMzNzA0MzEzNjM1ODI2MTF9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjUxNzkwMzAyOTkxODY3MDd9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjI3ODk5NzY1OTY4MzIyNzU0fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC4yMjA3NTA2NDQ4MDMwNDcxOH0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuNTc4OTkxODg5OTUzNjEzM30se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4yMTE2OTkxMTMyNDk3Nzg3NX0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4yNzg1NzY0NjM0NjA5MjIyNH0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4wOTA2MzMyNzMxMjQ2OTQ4fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjg1MjAzMDAzODgzMzYxODJ9LHtcIlwieFwiXCI6Ni4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuNzE3NzA1OTY1MDQyMTE0M30se1wiXCJ4XCJcIjo2LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi44NjgwOTE4MjE2NzA1MzIyfSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjozLjI0MTMwNzczNTQ0MzExNTJ9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbkNhbmFkYSxNTUVMVkxLVElJR1BJVlZHVlZMUklWREtXTE5LREssQ0MoQyg9TylOQ0NTKWMxY2NjYyhjMSlDKD1PKWMyY2NjY2MyLDE0ODAwMTcsMzYuMjYwOTU5NjI1MjQ0MTQsOTk1MTUsMzAtNTYgV0hJVEVTVE9ORSBFWFBZLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsNCw0LDFJQU4sNCwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzAuODU5NzM5MDk3NTQzMDAwOCwgMS4wOTU3NjI1NzMyNDgxOTQ2LCA1LjI2MDUzNzA2Nzk4Nzk1OCwgMC4wNzk3NDE4Nzk5ODE3NzczNl0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6MC44MTkwMTUyNjQ1MTExMDg0fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6MC44NDIxNjg5ODY3OTczMzI4fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjg3NDA5MjIyMTI2MDA3MDh9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjAuODkyNDI3NTA0MDYyNjUyNn0se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuODI0OTA2NzY2NDE0NjQyM30se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuOTMyNzY2OTE0MzY3Njc1OH0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuODUyMjk3NDI1MjcwMDgwNn0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuODE3NDQ5MjcxNjc4OTI0Nn0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC44Mzk0NjQ3MjQwNjM4NzMzfSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjcxMzkzODc3MjY3ODM3NTJ9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNTU2MTE2NzU5Nzc3MDY5MX0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4zMjc2MjI2ODE4NTYxNTU0fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjEyNDc5NDc0Mzk1NTEzNTM1fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjEzMDA2Nzk3NDMyODk5NDc1fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjA1OTcwMjA3OTc0MzE0Njg5Nn1dfSx7XCJcIm5hbWVcIlwiOlwiXCJSdW46MjAyMy0wOC0wOFwiXCIsXCJcImZpdExpbmVDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJwb2ludENvbG9yXCJcIjpcIlwiI2ZmYmI3OFwiXCIsXCJcInNob3dQb2ludHNcIlwiOlwiXCJwb2ludHNcIlwiLFwiXCJwYXJhbWV0ZXJzXCJcIjpbNS43NjA5MzAyMTk1ODI1NDYsIDEuNjU5MTc5MzI5MzgzMzAxMywgNC42NjcxNTU5Mjk3MjA4NTEsIDAuNzg1ODEwOTU0NDEyMTY1Ml0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6Ni4xNTY5OTMzODkxMjk2Mzl9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjo1LjIzNjcwMTk2NTMzMjAzMX0se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6Ni4wMTA1NjA1MTI1NDI3MjV9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjUuNDk1NTEyOTYyMzQxMzA5fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Ni4wODc3NzA0NjIwMzYxMzN9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1Ljc5OTg2NTcyMjY1NjI1fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NS41OTc1NDY1Nzc0NTM2MTN9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1LjUyMDkwMjE1NjgyOTgzNH0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6NS4zNjA2NTQzNTQwOTU0NTl9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjMuNTUzOTc0NjI4NDQ4NDg2M30se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS41NzcyMzYyOTQ3NDYzOTl9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMDAwMTI2NDgxMDU2MjEzNH0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC45MzA1Nzk3ODE1MzIyODc2fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjYwMzM2Mzg3MTU3NDQwMTl9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNDIwMzY4NTUyMjA3OTQ2OH1dfV0sXCJcImNoYXJ0T3B0aW9uc1wiXCI6e1wiXCJ4QXhpc05hbWVcIlwiOlwiXCJDb25jLlwiXCIsXCJcInlBeGlzTmFtZVwiXCI6XCJcIkFjdGl2aXR5XCJcIixcIlwidGl0bGVcIlwiOlwiXCJEb3NlLVJlc3BvbnNlIGN1cnZlc1wiXCJ9fVwiLHRleHQsLFxuQ29sb21iaWEsTURSVERFVlNOSFRIREtQVExUV0ZFRUlGRUVZSFNQRkhOLEZDKEYpKEYpYzFjY2MoT0MyQ0NOQ0MyKWNjMSwxNDgwMDI5LDM2LjMzMDk0NDA2MTI3OTMsOTk1MTUyMDUwLDEgQ09VUlQgSE9VU0UgU1FVQVJFLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsNSw1LDRVSjEsNSwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzYuNDk5NTA4ODMxNDE1MzY1NSwgMi40MjcwMzUxMDA0NTM5OTE0LCA1LjE3ODY1OTUzNTM0ODU3OSwgMC42MjU2NTMzNDYyNDE1NzddLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjYuNDk2MjMxNTU1OTM4NzIxfSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Ni40MjU0MzM2MzU3MTE2N30se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6Ny4wNDAwNjM4NTgwMzIyMjd9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjYuMTExNTQwMzE3NTM1NH0se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjYuNjgwNzI4NDM1NTE2MzU3fSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Ni40MDY3NzQ1MjA4NzQwMjN9LHtcIlwieFwiXCI6My4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo2LjYxMTI2OTQ3NDAyOTU0MX0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjUuODg5MDk0MzUyNzIyMTY4fSx7XCJcInhcIlwiOjQuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo2Ljc1MzQ0NzA1NTgxNjY1fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo2LjM2MTQzNTg5MDE5Nzc1NH0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6NC4xNjY2OTc1MDIxMzYyMzA1fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjE3MjExODkwMjIwNjQyMX0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC44MDEwNDg5OTQwNjQzMzF9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNDY0MDAyMTAyNjEzNDQ5MX0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4wMDEwMzU3NjY3OTI0ODM2Mjc4fV19LHtcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiI2ZmYmI3OFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOlsxLjQ3MzQzODEzNDc0NDY0MDEsIDEuMTY0OTgwNTE4ODA3NDE5NiwgNC44Mjk1ODYwODg2NjQyMSwgMC4wOTUwMDU0NTQ5NjcxMDAwN10sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6MS41Mjc5MDk2MzY0OTc0OTc2fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6MS4zNTU5OTc0NDMxOTkxNTc3fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjoxLjUyNDYzNzgxODMzNjQ4Njh9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjEuNTU2NzY1Nzk0NzU0MDI4M30se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuNDExNDI0MDQwNzk0MzcyNn0se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuNDA0NTAxMDgwNTEzMDAwNX0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuNDc2OTgyOTUxMTY0MjQ1Nn0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuNDg3NTUwMDIwMjE3ODk1NX0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4yOTkxOTg3NDY2ODEyMTM0fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjkyMjk2MTQxMzg2MDMyMX0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC42NTIwMDQ0ODAzNjE5Mzg1fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjE1MzUwOTc4MDc2NDU3OTc3fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjEwNzg5MDMwNzkwMzI4OTh9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTcyNzY0NDk1MDE1MTQ0MzV9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTQwNjY2MDgyNTAxNDExNDR9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbkNvc3RhIFJpY2EsTUtTVEtFRUlRVElLVExMS0RTUlRBS1lIS1JMUUlWTCxDQyhDKUNjMWNjYyhjYzEpQyhDKUMoPU8pTjJDQ0NDMkMoPU8pT0NDQ2MzY2NjY2MzLDE0ODAwMTgsMzYuMzMwOTQ0MDYxMjc5Myw5OTUwODQyMTgsNDA0MSBTT1VUSFdFU1RFUk4gQkxWRCxodHRwczovL2RhdGFncm9rLmFpL2ltZy9zbGlkZXMvYWNjZXNzLWRiLWNvbm5lY3QucG5nLGlkLEVycm9yTWVzc2FnZSxcIkNPTVBORCBcbkFUT00gXG5FTkRcIixmbGFnLDYsNiwyQlBXLDYsMS4yMyw8Y2hhcnQ+PC9jaGFydD4sXCJ7XCJcInNlcmllc1wiXCI6W3tcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0RnVuY3Rpb25cIlwiOlwiXCJzaWdtb2lkXCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiIzFmNzdiNFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOlsyLjQ4MzM2NDE4NDMzMTEyMjcsIC0xLjg5NDU5Nzg3NDIwOTAwNjIsIDQuNjcxMTI3NzA4MDkyNTY4LCAwLjI0MTU5ODYxMzExODE1MTUzXSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjowLjA5Njk1MjQxNjAwMjc1MDR9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjowLjAyODQ4MzA0MDYzMDgxNzQxM30se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6MC4yMjA4NzE3NjE0NDEyMzA3N30se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6MC4wMDY4OTE1NTQ2ODcxNzIxNzQ1fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC40MzA1ODc5NzcxNzA5NDQyfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC40NDc3NDExNTA4NTYwMTgwN30se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuNDUzNDYzMTk2NzU0NDU1NTd9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjIzNzA1OTMxMDA3ODYyMDl9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNDY1Nzk1Mzk3NzU4NDgzOX0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4xNTUyMDA3MTk4MzMzNzR9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuMjI5NDA3MDcyMDY3MjYwN30se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi40MzExNTMwNTkwMDU3MzczfSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjMzODQ2MTE2MDY1OTc5fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjYwODIwMTAyNjkxNjUwNH0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi44MTM2MTQzNjg0Mzg3MjA3fV19LHtcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiI2ZmYmI3OFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOls1LjIyNDU3MzUyMTY0MjAzMywgMS40NDU0MDMzOTI0MTk4NTI4LCA1LjYwMTQxOTc3NDYwNzY1MzUsIDAuMjgyMzIxNjA1NDE5NzU3N10sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6NC45NTAyNzQ5NDQzMDU0Mn0se1wiXCJ4XCJcIjowLjYwMDAwMDAyMzg0MTg1NzksXCJcInlcIlwiOjUuMTc1NDY3OTY3OTg3MDYwNX0se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6NS4yNzY3NTI5NDg3NjA5ODZ9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjUuNTg5Mjk0OTEwNDMwOTA4fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NS42MTY5OTQ4NTc3ODgwODZ9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1LjEyMDgxMzg0NjU4ODEzNX0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjUuMzQwNzY2OTA2NzM4MjgxfSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC44NzY0NzEwNDI2MzMwNTd9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjQuOTQ5OTkzNjEwMzgyMDh9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjUuMTYyNTY0NzU0NDg2MDg0fSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo0LjM5OTU1NzU5MDQ4NDYxOX0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi43OTc3OTY5NjQ2NDUzODU3fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjAyMjk4NzI0NjUxMzM2Njd9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNDgyNzU2MDE4NjM4NjEwODR9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTA0MDg5MzE5NzA1OTYzMTN9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbkN1YmEsTUhBSUxSWUZJUlJMRllISUZZS0lZU0xJU0tLSFFTTFBTRFZSUUYsQ09jMWNjYzJjKGMxKWMoQ0MoPU8pTjNDQ0NDM0MoPU8pT2M0Y2NjKEMpY2M0T0MpYyhDKW4yQyg9TyljNWNjYyhDbCljYzUsMTQ4MDAxOSwzNi4zMzExNTc2ODQzMjYxNyw5OTUwODE5MjgsMTIyNyBVUyBISUdIV0FZIDExLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsNyw3LDFRQlMsNywxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzMuMzIwODM4Njc5NzEzOTI1LCAtMS4yNDIxNjE5OTg3MzE2NzI4LCA0LjgzMTMyNTQyNTIyNTI1NiwgMC4zMjM2MDExMDk4NDAzMDcyXSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjowLjM3Mjc0NzAzMzgzNDQ1NzR9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjowLjEyMzY1MDE0MTA2MDM1MjMzfSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjQ4NDIyNDY3NzA4NTg3NjQ2fSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjIyNjQ0NjUwOTM2MTI2NzF9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjE2ODIxNzk0MjExODY0NDcxfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC4zODc5MDE0NTUxNjM5NTU3fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC41NDcwMjQ0ODg0NDkwOTY3fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC4zNDE5MDUzNTU0NTM0OTEyfSx7XCJcInhcIlwiOjQuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjc2NTUxMjA0OTE5ODE1MDZ9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMjM0NjUxNjg0NzYxMDQ3NH0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi40NTMzMzY3MTU2OTgyNDJ9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuOTU2NTQ5MTY3NjMzMDU2Nn0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My4zMzUyOTk0OTE4ODIzMjR9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjMuMjQwMjkwODgwMjAzMjQ3fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjozLjExMDcyMTgyNjU1MzM0NDd9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzMuNjQwMTg1MzUyMTUxMTA5NCwgMS4yNjIxMTU4ODg3NTAxMywgNS4zOTkwMjgwNzQ0MDI3NDQsIDAuNTA4OTU4MDgzMDA2ODA5MV0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6My44NTg1NTk4NDY4NzgwNTE4fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6My42MDc3MjA2MTM0Nzk2MTQzfSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjozLjg1NTI1MjI2NTkzMDE3Nn0se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6My42MTkwMzkyOTcxMDM4ODJ9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjgzOTM4ODM3MDUxMzkxNn0se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjMuMzM1MjgzMDQxMDAwMzY2fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6My41NzExNDE0ODEzOTk1MzZ9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjQxNTUwNDY5Mzk4NDk4NTR9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjMuNzMxNjY0NjU3NTkyNzczNH0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My4wNjgwMTU1NzU0MDg5MzU1fSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjg5MTA2NjU1MTIwODQ5Nn0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS42MDIyNzUzNzE1NTE1MTM3fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjc2NTI1NzY1NjU3NDI0OTN9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNjg3NTMyNjAzNzQwNjkyMX0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC41ODI4ODcxNzI2OTg5NzQ2fV19XSxcIlwiY2hhcnRPcHRpb25zXCJcIjp7XCJcInhBeGlzTmFtZVwiXCI6XCJcIkNvbmMuXCJcIixcIlwieUF4aXNOYW1lXCJcIjpcIlwiQWN0aXZpdHlcIlwiLFwiXCJ0aXRsZVwiXCI6XCJcIkRvc2UtUmVzcG9uc2UgY3VydmVzXCJcIn19XCIsdGV4dCwsXG5JdGFseSxNU05GSE5FSFZNUUZZUk5OTEtUS0dWRkdSUSxDQyhDKUNjMWNjYyhjYzEpQyhDKUMoPU8pTjJDQ0NDMkMoPU8pT0NDT1tOK10oPU8pW08tXSwxNDgwMDIwLDM2LjMzMTE1NzY4NDMyNjE3LDk5NTAyLFwiMTY4LTQ2IDkxU1QgQVZFLiwgMk5EIEZMUlwiLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsOCw4LDFaUDgsOCwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzIuMjkzNTkyMTA1OTIzODA5LCAxLjM3ODE1ODY1NDkxNDE4MzUsIDUuMTAyNTg5ODAzODY3NjYwNSwgMC4wMzQ5Mzg1MTI0NTI5MTI5MV0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6Mi4xMjg3MjgzODk3Mzk5OTAyfSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Mi4yNjc5NzIyMzA5MTEyNTV9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjIuMzk4NDQyNTA2NzkwMTYxfSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjoyLjUxMzA2MjIzODY5MzIzNzN9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjoyLjMyNTUxMTY5Mzk1NDQ2Nzh9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjoyLjEyNzM0MDc5MzYwOTYxOX0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjIuNDcyNTk3ODM3NDQ4MTJ9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjoyLjEzMTE4MTQ3ODUwMDM2Nn0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi4wOTA0MjE0MzgyMTcxNjN9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuMDIyOTkxNjU3MjU3MDh9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMTEwNTA1OTM4NTI5OTY4M30se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC40NDk0NDg1ODU1MTAyNTM5fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjEzNzU2MzU4NjIzNTA0NjR9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMDM2MzUxMTIxOTYyMDcwNDY1fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjE2MTk3NzExMjI5MzI0MzR9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzUuOTUzMTI1NDk5NDM5ODc5LCAxLjI1Mjg2MjAyNTUzMDY1MjgsIDUuMTg3NjM3NDQwMTQ5ODAyLCAwLjMxMTAzNDg3NTMyNjA4ODZdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjUuNjU4NTI4MzI3OTQxODk0NX0se1wiXCJ4XCJcIjowLjYwMDAwMDAyMzg0MTg1NzksXCJcInlcIlwiOjUuOTExMTUyMzYyODIzNDg2fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjo1LjkyNDkyMDA4MjA5MjI4NX0se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6NS44NDY5NDM4NTUyODU2NDQ1fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NS45Mjk0NzI5MjMyNzg4MDl9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo2LjE5MDAzNzcyNzM1NTk1N30se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjYuMjM2MTc5ODI4NjQzNzk5fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Ni4xNDEwMTkzNDQzMjk4MzR9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjUuMjk1MjEwODM4MzE3ODcxfSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo1LjI2NTgwMTkwNjU4NTY5M30se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My4zNzIyODUxMjc2Mzk3NzA1fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjgyOTkyMjY3NjA4NjQyNTh9LHtcIlwieFwiXCI6Ni4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMzI2OTA5MDA1NjQxOTM3MjZ9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNjI3NDU0MzQwNDU3OTE2M30se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC44NDQxODU3MDk5NTMzMDgxfV19XSxcIlwiY2hhcnRPcHRpb25zXCJcIjp7XCJcInhBeGlzTmFtZVwiXCI6XCJcIkNvbmMuXCJcIixcIlwieUF4aXNOYW1lXCJcIjpcIlwiQWN0aXZpdHlcIlwiLFwiXCJ0aXRsZVwiXCI6XCJcIkRvc2UtUmVzcG9uc2UgY3VydmVzXCJcIn19XCIsdGV4dCwsXG5Sd2FuZGEsTVBOU0VQQVNMTEVMRk5TSUFUUUdFTFZSU0xLQUdOQVNLLENDKEMpQ2MxY2NjKGNjMSlDKEMpQyg9TylOMkNDQ0MyQyg9TylPQ0NPLDE0ODAwMjEsMzYuMzMxMzcxMzA3MzczMDUsOTk1MDM3MjQ3LFwiMTY4LTQ2IDkxU1QgQVZFLiwgMk5EIEZMUlwiLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsOSw5LDJCREosOSwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzMuODIwOTk3MjIwMjY1NDQ3NCwgMS4zNzc5MjE2NzE2NDQ4NTA2LCA1LjI5OTg4MjIyODQzOTY4NiwgMC4wNjA0MDY0NTUxOTA2OTYwOF0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6My43ODIxMTA5Mjk0ODkxMzU3fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6My41NDI0MzMwMjM0NTI3NTl9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjMuNzAwODY3NDE0NDc0NDg3M30se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6My43MTczMDE2MDcxMzE5NTh9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo0LjAyNDQ1MjIwOTQ3MjY1Nn0se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjQuMDEzODk5MzI2MzI0NDYzfSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6My45NDUwOTQzNDcwMDAxMjJ9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjg2NjYyMTk3MTEzMDM3MX0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My43NDYxNjI2NTI5NjkzNjA0fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjozLjM0NTQ3NDAwNDc0NTQ4MzR9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuNjE5NDQzMTc4MTc2ODh9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuOTk5NDA1MDI2NDM1ODUyfSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjQ2MjU5NzkzNjM5MTgzMDQ0fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjA1NDEzNDYxMTA0MDM1Mzc3NX0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4wNTcxMTE4NzQyMjI3NTU0M31dfSx7XCJcIm5hbWVcIlwiOlwiXCJSdW46MjAyMy0wOC0wOFwiXCIsXCJcImZpdExpbmVDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJwb2ludENvbG9yXCJcIjpcIlwiI2ZmYmI3OFwiXCIsXCJcInNob3dQb2ludHNcIlwiOlwiXCJwb2ludHNcIlwiLFwiXCJwYXJhbWV0ZXJzXCJcIjpbNS42MzE4MDc5NjU3NzI2MDM1LCAxLjg0OTU0OTM3NzAwMDA1OTUsIDUuMzkxNzkzMzEyNDcxMTE2LCAwLjE3MDYwNzA3NTg3MzQ4NDQyXSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjo1LjQ1ODA3OTgxNDkxMDg4OX0se1wiXCJ4XCJcIjowLjYwMDAwMDAyMzg0MTg1NzksXCJcInlcIlwiOjUuNTU0NDI3MTQ2OTExNjIxfSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjo1Ljc5OTk4MzAyNDU5NzE2OH0se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6NS4zNjQxNDAwMzM3MjE5MjR9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1Ljg2NDQ4NTc0MDY2MTYyMX0se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjUuNDUwOTgwNjYzMjk5NTYwNX0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjUuNzAyNTc0NzI5OTE5NDM0fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NS43MzE0NTM0MTg3MzE2ODk1fSx7XCJcInhcIlwiOjQuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo1LjUxMjM0NDM2MDM1MTU2MjV9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjUuNzI0Mzk1NzUxOTUzMTI1fSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo0LjM1NDUwNjk2OTQ1MTkwNH0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS43MzA3NjY2NTQwMTQ1ODc0fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjYzMDU5MzY1NzQ5MzU5MTN9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMDM1MTgzNDM3MTY4NTk4MTc1fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjc1NzUxNjkyMDU2NjU1ODh9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcblN3aXR6ZXJsYW5kLElSVlZHUllMSUVWV0tBQUdNRE1ES1ZMRkxXU1NERUksQ04xQ0NDKENDMSlPYzJjY2MoY2MyKUMoRikoRilGLDE0ODAwMjgsMzYuMzMxMzcxMzA3MzczMDUsOTk1MDQsOTItMTEgMTc5VEggUExBQ0UsaHR0cHM6Ly9kYXRhZ3Jvay5haS9pbWcvc2xpZGVzL2FjY2Vzcy1kYi1jb25uZWN0LnBuZyxpZCxFcnJvck1lc3NhZ2UsXCJDT01QTkQgXG5BVE9NIFxuRU5EXCIsZmxhZyw5LDEwLDFJQU4sMTAsMS4yMyw8Y2hhcnQ+PC9jaGFydD4sXCJ7XCJcInNlcmllc1wiXCI6W3tcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0RnVuY3Rpb25cIlwiOlwiXCJzaWdtb2lkXCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiIzFmNzdiNFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOlsxLjExOTAyNTU4NjUwOTc0NzEsIDIuMzE2Mzg5NTE2MTU0NDQzNywgNS40OTY4ODY2MTgyMjc5MTk1LCAwLjIwMzUyMDQwNDcyODkwNTJdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjEuMTA1NzY4MzIyOTQ0NjQxMX0se1wiXCJ4XCJcIjowLjYwMDAwMDAyMzg0MTg1NzksXCJcInlcIlwiOjEuMTAxOTY5NzE4OTMzMTA1NX0se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6MS4wODE4NjA3ODA3MTU5NDI0fSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjoxLjA2Mjk5NzgxNzk5MzE2NH0se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuMDQ2NDQ3NTE1NDg3NjcxfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MS4xMjE3MjQ5NjMxODgxNzE0fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MS4yMTY2OTk2MDAyMTk3MjY2fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MS4yMTU0Nzc3MDUwMDE4MzF9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMDU4MTg5MzkyMDg5ODQzOH0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4xNzQ3OTk1NjE1MDA1NDkzfSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjAxODExMjc3ODY2MzYzNTN9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNTM0NDUyMzE5MTQ1MjAyNn0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4yNTY5NTI2NDMzOTQ0NzAyfSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjE5MTIyMDczMDU0MzEzNjZ9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTUwNjA1MzgwNTM1MTI1NzN9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzMuMTAzODU4MTAyNTgwNTc4NSwgMi4wMDMyMjI0MjA0MTg1MjQ1LCA1LjA4NzYwMjgyNTk4OTE2MywgMC4xMzI3Nzk4ODUxMjQ5Mjc1M10sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6My4wNDk4NTA5NDA3MDQzNDU3fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Mi44MDUyMTc3NDI5MTk5MjJ9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjMuMzQxNTI1MzE2MjM4NDAzM30se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6My4wNTQ5ODQzMzExMzA5ODE0fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6My4yNTAwNzQ4NjM0MzM4Mzh9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjA0MzI1ODY2Njk5MjE4NzV9LHtcIlwieFwiXCI6My4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjI2NTg1MjQ1MTMyNDQ2M30se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjIuOTQ3NTcyNDY5NzExMzAzN30se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My4xOTI5ODk4MjYyMDIzOTI2fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjc0NjAwNjAxMTk2Mjg5MDZ9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuNjE3NTg2MTM1ODY0MjU3OH0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4zMDA2NjA4NDg2MTc1NTM3fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjM0NDQ4MDMwNTkxMDExMDV9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMDE1NTM3OTcxNjMwNjkyNDgyfSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjU1MjczNTgwNTUxMTQ3NDZ9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbiwsLCwsLCwsLCwsLCwsLCwsLCwsLGApO1xudGVzdERhdGEuY29sdW1ucy5hZGQoREcuQ29sdW1uLmZyb21MaXN0KERHLlRZUEUuQllURV9BUlJBWSwgJ0JpbmFyeUltYWdlJywgQXJyYXkuZnJvbShuZXcgVWludDhBcnJheSgxMSkpKSk7XG4iXX0=","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nimport * as grok from 'datagrok-api/grok';\nimport * as DG from 'datagrok-api/dg';\nimport { testData } from './dataframe-utils';\nimport { changeOptionsSaveLayout, filterAsync, loadLayout, selectFilterChangeCurrent, testViewerInternal } from './test-viewer-utils';\nconst STANDART_TIMEOUT = 30000;\nconst BENCHMARK_TIMEOUT = 10800000;\nconst stdLog = console.log.bind(console);\nconst stdInfo = console.info.bind(console);\nconst stdWarn = console.warn.bind(console);\nconst stdError = console.error.bind(console);\nexport const tests = {};\nconst autoTestsCatName = 'Auto Tests';\nconst demoCatName = 'Demo';\nconst detectorsCatName = 'Detectors';\nconst coreCatName = 'Core';\nconst wasRegistered = {};\nexport let currentCategory;\nexport var assure;\n(function (assure) {\n function notNull(value, name) {\n if (value == null)\n throw new Error(`${name == null ? 'Value' : name} not defined`);\n }\n assure.notNull = notNull;\n})(assure || (assure = {}));\nexport class TestContext {\n constructor(catchUnhandled, report) {\n this.catchUnhandled = true;\n this.report = false;\n if (catchUnhandled !== undefined)\n this.catchUnhandled = catchUnhandled;\n if (report !== undefined)\n this.report = report;\n }\n ;\n}\nexport class Test {\n constructor(category, name, test, options) {\n var _a;\n this.category = category;\n this.name = name;\n options !== null && options !== void 0 ? options : (options = {});\n (_a = options.timeout) !== null && _a !== void 0 ? _a : (options.timeout = STANDART_TIMEOUT);\n this.options = options;\n this.test = () => __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n let result = '';\n try {\n result = yield test();\n }\n catch (e) {\n reject(e);\n }\n resolve(result);\n }));\n });\n }\n}\nexport class Category {\n}\nexport class TestExecutionOptions {\n}\nexport function testEvent(event, handler, trigger, ms = 0, reason = `timeout`) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n const sub = event.subscribe((args) => {\n try {\n handler(args);\n resolve('OK');\n }\n catch (e) {\n reject(e);\n }\n finally {\n sub.unsubscribe();\n clearTimeout(timeout);\n }\n });\n const timeout = setTimeout(() => {\n sub.unsubscribe();\n // eslint-disable-next-line prefer-promise-reject-errors\n reject(reason);\n }, ms);\n trigger();\n });\n });\n}\nexport function testEventAsync(event, handler, trigger, ms = 0, reason = `timeout`) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n const sub = event.subscribe((args) => {\n handler(args).then(() => {\n resolve('OK');\n }).catch((e) => {\n reject(e);\n }).finally(() => {\n sub.unsubscribe();\n clearTimeout(timeout);\n });\n });\n const timeout = setTimeout(() => {\n sub.unsubscribe();\n // eslint-disable-next-line prefer-promise-reject-errors\n reject(reason);\n }, ms);\n trigger();\n });\n });\n}\nexport function test(name, test, options) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n if (tests[currentCategory].tests == undefined)\n tests[currentCategory].tests = [];\n tests[currentCategory].tests.push(new Test(currentCategory, name, test, options));\n}\n/* Tests two objects for equality, throws an exception if they are not equal. */\nexport function expect(actual, expected = true, error) {\n if (error)\n error = `${error}, `;\n else\n error = '';\n if (actual !== expected)\n throw new Error(`${error}Expected \"${expected}\", got \"${actual}\"`);\n}\nexport function expectFloat(actual, expected, tolerance = 0.001, error) {\n if ((actual === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) ||\n (actual === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) ||\n (actual === Number.NaN && expected === Number.NaN) || (isNaN(actual) && isNaN(expected)))\n return;\n const areEqual = Math.abs(actual - expected) < tolerance;\n expect(areEqual, true, `${error !== null && error !== void 0 ? error : ''} (tolerance = ${tolerance})`);\n if (!areEqual)\n throw new Error(`Expected ${expected}, got ${actual} (tolerance = ${tolerance})`);\n}\nexport function expectTable(actual, expected, error) {\n const expectedRowCount = expected.rowCount;\n const actualRowCount = actual.rowCount;\n expect(actualRowCount, expectedRowCount, `${error !== null && error !== void 0 ? error : ''}, row count`);\n for (const column of expected.columns) {\n const actualColumn = actual.columns.byName(column.name);\n if (actualColumn == null)\n throw new Error(`Column ${column.name} not found`);\n if (actualColumn.type != column.type)\n throw new Error(`Column ${column.name} type expected ${column.type} got ${actualColumn.type}`);\n for (let i = 0; i < expectedRowCount; i++) {\n const value = column.get(i);\n const actualValue = actualColumn.get(i);\n if (column.type == DG.TYPE.FLOAT)\n expectFloat(actualValue, value, 0.0001, error);\n else if (column.type == DG.TYPE.DATE_TIME)\n expect(actualValue.isSame(value), true, error);\n else\n expect(actualValue, value, error);\n }\n }\n}\nexport function expectObject(actual, expected) {\n for (const [expectedKey, expectedValue] of Object.entries(expected)) {\n if (!actual.hasOwnProperty(expectedKey))\n throw new Error(`Expected property \"${expectedKey}\" not found`);\n const actualValue = actual[expectedKey];\n if (actualValue instanceof Array && expectedValue instanceof Array)\n expectArray(actualValue, expectedValue);\n else if (actualValue instanceof Object && expectedValue instanceof Object)\n expectObject(actualValue, expectedValue);\n else if (Number.isFinite(actualValue) && Number.isFinite(expectedValue))\n expectFloat(actualValue, expectedValue);\n else if (actualValue != expectedValue)\n throw new Error(`Expected (${expectedValue}) for key '${expectedKey}', got (${actualValue})`);\n }\n}\nexport function expectArray(actual, expected) {\n const actualLength = actual.length;\n const expectedLength = expected.length;\n if (actualLength != expectedLength) {\n throw new Error(`Arrays are of different length: actual array length is ${actualLength} ` +\n `and expected array length is ${expectedLength}`);\n }\n for (let i = 0; i < actualLength; i++) {\n if (actual[i] instanceof Array && expected[i] instanceof Array)\n expectArray(actual[i], expected[i]);\n else if (actual[i] instanceof Object && expected[i] instanceof Object)\n expectObject(actual[i], expected[i]);\n else if (actual[i] != expected[i])\n throw new Error(`Expected ${expected[i]} at position ${i}, got ${actual[i]}`);\n }\n}\n/* Defines a test suite. */\nexport function category(category, tests_, options) {\n var _a;\n currentCategory = category;\n tests_();\n if (tests[currentCategory]) {\n tests[currentCategory].clear = (_a = options === null || options === void 0 ? void 0 : options.clear) !== null && _a !== void 0 ? _a : true;\n tests[currentCategory].timeout = options === null || options === void 0 ? void 0 : options.timeout;\n tests[currentCategory].benchmarks = options === null || options === void 0 ? void 0 : options.benchmarks;\n tests[currentCategory].stressTests = options === null || options === void 0 ? void 0 : options.stressTests;\n }\n}\n/* Defines a function to be executed before the tests in this category are executed. */\nexport function before(before) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n tests[currentCategory].before = before;\n}\n/* Defines a function to be executed after the tests in this category are executed. */\nexport function after(after) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n tests[currentCategory].after = after;\n}\nfunction addNamespace(s, f) {\n return s.replace(new RegExp(f.name, 'gi'), f.nqName);\n}\nexport function initAutoTests(package_, module) {\n var _a, _b, _c, _d;\n return __awaiter(this, void 0, void 0, function* () {\n const packageId = package_.id;\n if (wasRegistered[packageId])\n return;\n const moduleTests = module ? module.tests : tests;\n if (moduleTests[autoTestsCatName] !== undefined ||\n moduleTests[demoCatName] !== undefined ||\n Object.keys(moduleTests).find((c) => c.startsWith(autoTestsCatName) || c.startsWith(coreCatName))) {\n wasRegistered[packageId] = true;\n return;\n }\n if (package_.name === 'DevTools' || (!!module && module._package.name === 'DevTools')) {\n for (const f of window.dartTests) {\n const arr = f.name.split(/\\s*\\|\\s*!/g);\n let name = (_a = arr.pop()) !== null && _a !== void 0 ? _a : f.name;\n let cat = arr.length ? coreCatName + ': ' + arr.join(': ') : coreCatName;\n let fullName = name.split(' | ');\n name = fullName[fullName.length - 1];\n fullName.unshift(cat);\n fullName.pop();\n cat = fullName.join(': ');\n if (moduleTests[cat] === undefined)\n moduleTests[cat] = { tests: [], clear: true };\n moduleTests[cat].tests.push(new Test(cat, name, f.test, { isAggregated: false, timeout: (_c = (_b = f.options) === null || _b === void 0 ? void 0 : _b.timeout) !== null && _c !== void 0 ? _c : STANDART_TIMEOUT, skipReason: (_d = f.options) === null || _d === void 0 ? void 0 : _d.skipReason }));\n }\n }\n const moduleAutoTests = [];\n const moduleDemo = [];\n const moduleDetectors = [];\n const packFunctions = yield grok.dapi.functions.filter(`package.id = \"${packageId}\"`).list();\n const reg = new RegExp(/skip:\\s*([^,\\s]+)|wait:\\s*(\\d+)|cat:\\s*([^,\\s]+)|timeout:\\s*(\\d+)/g);\n for (const f of packFunctions) {\n const tests = f.options['test'];\n const demo = f.options['demoPath'];\n if ((tests && Array.isArray(tests) && tests.length)) {\n for (let i = 0; i < tests.length; i++) {\n const res = tests[i].matchAll(reg);\n const map = {};\n Array.from(res).forEach((arr) => {\n if (arr[0].startsWith('skip'))\n map['skip'] = arr[1];\n else if (arr[0].startsWith('wait'))\n map['wait'] = parseInt(arr[2]);\n else if (arr[0].startsWith('cat'))\n map['cat'] = arr[3];\n else if (arr[0].startsWith('timeout'))\n map['timeout'] = parseInt(arr[4]);\n });\n const test = new Test(autoTestsCatName, tests.length === 1 ? f.name : `${f.name} ${i + 1}`, () => __awaiter(this, void 0, void 0, function* () {\n const res = yield grok.functions.eval(addNamespace(tests[i], f));\n if (map.wait)\n yield delay(map.wait);\n // eslint-disable-next-line no-throw-literal\n if (typeof res === 'boolean' && !res)\n throw `Failed: ${tests[i]}, expected true, got ${res}`;\n }), { skipReason: map.skip, timeout: DG.Test.isInBenchmark ? map.benchmarkTimeout : map.timeout });\n if (map.cat) {\n const cat = autoTestsCatName + ': ' + map.cat;\n test.category = cat;\n if (moduleTests[cat] === undefined)\n moduleTests[cat] = { tests: [], clear: true };\n moduleTests[cat].tests.push(test);\n }\n else\n moduleAutoTests.push(test);\n }\n }\n if (demo) {\n const wait = f.options['demoWait'] ? parseInt(f.options['demoWait']) : undefined;\n const test = new Test(demoCatName, f.friendlyName, () => __awaiter(this, void 0, void 0, function* () {\n grok.shell.isInDemo = true;\n if (grok.shell.view(DG.View.BROWSE) === undefined)\n grok.shell.v = DG.View.createByType(DG.View.BROWSE);\n yield delay(300);\n grok.shell.clearLastError();\n yield f.apply();\n yield delay(wait ? wait : 2000);\n const unhandled = yield grok.shell.lastError;\n if (unhandled)\n throw new Error(unhandled);\n grok.shell.isInDemo = false;\n }), { skipReason: f.options['demoSkip'] });\n moduleDemo.push(test);\n }\n if (f.hasTag('semTypeDetector')) {\n const test = new Test(detectorsCatName, f.friendlyName, () => __awaiter(this, void 0, void 0, function* () {\n const arr = [];\n for (const col of testData.clone().columns) {\n const res = yield f.apply([col]);\n arr.push(res || col.semType);\n }\n expect(arr.filter((i) => i).length, 1);\n }), { skipReason: f.options['skipTest'] });\n moduleDetectors.push(test);\n }\n }\n wasRegistered[packageId] = true;\n if (moduleAutoTests.length)\n moduleTests[autoTestsCatName] = { tests: moduleAutoTests, clear: true };\n if (moduleDemo.length)\n moduleTests[demoCatName] = { tests: moduleDemo, clear: true };\n if (moduleDetectors.length)\n moduleTests[detectorsCatName] = { tests: moduleDetectors, clear: false };\n });\n}\nfunction redefineConsole() {\n const logs = [];\n console.log = (...args) => {\n logs.push(...args);\n stdLog(...args);\n };\n console.info = (...args) => {\n logs.push(...args);\n stdInfo(...args);\n };\n console.warn = (...args) => {\n logs.push(...args);\n stdWarn(...args);\n };\n console.error = (...args) => {\n logs.push(...args);\n stdError(...args);\n };\n return logs;\n}\nfunction resetConsole() {\n console.log = stdLog;\n console.info = stdInfo;\n console.warn = stdWarn;\n console.error = stdError;\n}\nexport function runTests(options) {\n var _a, _b, _c;\n var _d;\n return __awaiter(this, void 0, void 0, function* () {\n const package_ = (_b = (_a = grok.functions.getCurrentCall()) === null || _a === void 0 ? void 0 : _a.func) === null || _b === void 0 ? void 0 : _b.package;\n yield initAutoTests(package_);\n const results = [];\n console.log(`Running tests`);\n options !== null && options !== void 0 ? options : (options = {});\n (_c = (_d = options).testContext) !== null && _c !== void 0 ? _c : (_d.testContext = new TestContext());\n grok.shell.clearLastError();\n const categories = [];\n const logs = redefineConsole();\n if (options === null || options === void 0 ? void 0 : options.stressTest) {\n yield InvokeStressTests(options);\n }\n else {\n yield InvokeAllTests(tests, options);\n }\n for (let r of results) {\n r.result = r.result.toString().replace(/\"/g, '\\'');\n if (r.logs != undefined)\n r.logs = r.logs.toString().replace(/\"/g, '\\'');\n }\n return results;\n function InvokeCategoryMethod(method, category) {\n return __awaiter(this, void 0, void 0, function* () {\n var invokationResult = undefined;\n try {\n if (method !== undefined) {\n yield timeout(() => __awaiter(this, void 0, void 0, function* () {\n yield method();\n }), 100000, `before ${category}: timeout error`);\n }\n }\n catch (x) {\n invokationResult = yield getResult(x);\n }\n return invokationResult;\n });\n }\n function InvokeStressTests(options) {\n var _a, _b, _c, _d, _e, _f;\n return __awaiter(this, void 0, void 0, function* () {\n let testInvocationMap = [];\n for (const [key, value] of Object.entries(tests)) {\n let testsToInvoke = (_a = value.tests) === null || _a === void 0 ? void 0 : _a.filter((test) => { var _a; return (_a = test.options) === null || _a === void 0 ? void 0 : _a.stressTest; });\n if (value.stressTests) {\n testsToInvoke = (_b = value.tests) === null || _b === void 0 ? void 0 : _b.filter((test) => { var _a, _b; return ((_a = test.options) === null || _a === void 0 ? void 0 : _a.stressTest) === undefined || ((_b = test.options) === null || _b === void 0 ? void 0 : _b.stressTest) === true; });\n }\n const skipped = (_c = value.tests) === null || _c === void 0 ? void 0 : _c.every((t) => { var _a; return (_a = t.options) === null || _a === void 0 ? void 0 : _a.skipReason; });\n if (skipped)\n continue;\n for (let test of testsToInvoke !== null && testsToInvoke !== void 0 ? testsToInvoke : []) {\n if (((_d = test.options) === null || _d === void 0 ? void 0 : _d.skipReason) == null) {\n testInvocationMap.push({ test, value });\n }\n }\n }\n testInvocationMap = shuffle(testInvocationMap);\n const res = [];\n for (let testingObj of testInvocationMap) {\n yield InvokeCategoryMethod(testingObj.value.before, (_e = options.category) !== null && _e !== void 0 ? _e : '');\n let testRun = yield execTest(testingObj.test, options === null || options === void 0 ? void 0 : options.test, logs, DG.Test.isInBenchmark ? testingObj.value.benchmarkTimeout : testingObj.value.timeout, package_.name, options.verbose);\n if (testRun)\n res.push(testRun);\n console.log(`Test: ${test === null || test === void 0 ? void 0 : test.name}; result: ${testRun}`);\n yield InvokeCategoryMethod(testingObj.value.after, (_f = options.category) !== null && _f !== void 0 ? _f : '');\n }\n results.push(...res);\n });\n }\n function InvokeAllTests(categoriesToInvoke, options) {\n var _a, _b, _c, _d, _e, _f, _g;\n return __awaiter(this, void 0, void 0, function* () {\n try {\n for (const [key, value] of Object.entries(categoriesToInvoke)) {\n if ((!!(options === null || options === void 0 ? void 0 : options.category) && !key.toLowerCase().startsWith(options === null || options === void 0 ? void 0 : options.category.toLowerCase())) ||\n ((_a = options.exclude) === null || _a === void 0 ? void 0 : _a.some((c) => key.startsWith(c))))\n continue;\n stdLog(`Started ${key} category`);\n const skipped = (_b = value.tests) === null || _b === void 0 ? void 0 : _b.every((t) => { var _a; return (_a = t.options) === null || _a === void 0 ? void 0 : _a.skipReason; });\n if (!skipped)\n value.beforeStatus = yield InvokeCategoryMethod(value.before, (_c = options.category) !== null && _c !== void 0 ? _c : '');\n const t = (_d = value.tests) !== null && _d !== void 0 ? _d : [];\n const res = [];\n if (value.clear) {\n for (let i = 0; i < t.length; i++) {\n if (t[i].options) {\n if (((_e = t[i].options) === null || _e === void 0 ? void 0 : _e.benchmark) === undefined) {\n if (!t[i].options)\n t[i].options = {};\n t[i].options.benchmark = (_f = value.benchmarks) !== null && _f !== void 0 ? _f : false;\n }\n }\n let testRun = yield execTest(t[i], options === null || options === void 0 ? void 0 : options.test, logs, DG.Test.isInBenchmark ? value.benchmarkTimeout : value.timeout, package_.name, options.verbose);\n if (testRun)\n res.push(testRun);\n grok.shell.closeAll();\n DG.Balloon.closeAll();\n }\n }\n else {\n for (let i = 0; i < t.length; i++) {\n let testRun = yield execTest(t[i], options === null || options === void 0 ? void 0 : options.test, logs, DG.Test.isInBenchmark ? value.benchmarkTimeout : value.timeout, package_.name, options.verbose);\n if (testRun)\n res.push(testRun);\n }\n }\n const data = res.filter((d) => d.result != 'skipped');\n if (!skipped)\n value.afterStatus = yield InvokeCategoryMethod(value.after, (_g = options.category) !== null && _g !== void 0 ? _g : '');\n // Clear after category\n // grok.shell.closeAll();\n // DG.Balloon.closeAll();\n if (value.afterStatus)\n data.push({ date: new Date().toISOString(), logs: '', category: key, name: 'after', result: value.afterStatus, success: false, ms: 0, skipped: false });\n if (value.beforeStatus)\n data.push({ date: new Date().toISOString(), logs: '', category: key, name: 'before', result: value.beforeStatus, success: false, ms: 0, skipped: false });\n results.push(...data);\n }\n }\n finally {\n resetConsole();\n }\n if (options.testContext.catchUnhandled && (!DG.Test.isInBenchmark)) {\n yield delay(1000);\n const error = yield grok.shell.lastError;\n const params = {\n logs: '',\n date: new Date().toISOString(),\n category: 'Unhandled exceptions',\n name: 'Exception',\n result: error !== null && error !== void 0 ? error : '', success: !error, ms: 0, skipped: false\n };\n results.push(params);\n params.package = package_.name;\n if (grok.shell.reportTest != null)\n yield grok.shell.reportTest('package', params);\n else {\n yield fetch(`${grok.dapi.root}/log/tests/package`, {\n method: 'POST', headers: { 'Content-Type': 'application/json' },\n credentials: 'same-origin',\n body: JSON.stringify(params)\n });\n }\n }\n });\n }\n });\n}\nfunction getResult(x) {\n return __awaiter(this, void 0, void 0, function* () {\n return `${x.toString()}\\n${x.stack ? (yield DG.Logger.translateStackTrace(x.stack)) : ''}`;\n });\n}\nfunction execTest(t, predicate, logs, categoryTimeout, packageName, verbose) {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n return __awaiter(this, void 0, void 0, function* () {\n logs.length = 0;\n let r;\n let type = 'package';\n const filter = predicate != undefined && (t.name.toLowerCase() !== predicate.toLowerCase());\n let skip = ((_a = t.options) === null || _a === void 0 ? void 0 : _a.skipReason) || filter;\n let skipReason = filter ? 'skipped' : (_b = t.options) === null || _b === void 0 ? void 0 : _b.skipReason;\n if (DG.Test.isInBenchmark && !((_c = t.options) === null || _c === void 0 ? void 0 : _c.benchmark)) {\n stdLog(`SKIPPED: ${t.category} ${t.name} doesnt available in benchmark mode`);\n return undefined;\n }\n if (!skip)\n stdLog(`Started ${t.category} ${t.name}`);\n const start = Date.now();\n try {\n if (skip)\n r = { date: new Date().toISOString(), success: true, result: skipReason, ms: 0, skipped: true };\n else {\n let timeout_ = ((_d = t.options) === null || _d === void 0 ? void 0 : _d.timeout) === STANDART_TIMEOUT &&\n categoryTimeout ? categoryTimeout : (_e = t.options) === null || _e === void 0 ? void 0 : _e.timeout;\n timeout_ = (timeout_ === STANDART_TIMEOUT && DG.Test.isInBenchmark) ? BENCHMARK_TIMEOUT : timeout_;\n r = { date: new Date().toISOString(), success: true, result: (_f = yield timeout(t.test, timeout_)) !== null && _f !== void 0 ? _f : 'OK', ms: 0, skipped: false };\n }\n }\n catch (x) {\n stdError(x);\n r = { date: new Date().toISOString(), success: false, result: yield getResult(x), ms: 0, skipped: false };\n }\n if (((_g = t.options) === null || _g === void 0 ? void 0 : _g.isAggregated) && r.result.constructor === DG.DataFrame) {\n const col = r.result.col('success');\n if (col)\n r.success = col.stats.sum === col.length;\n if (!verbose) {\n const df = r.result;\n df.columns.remove('stack');\n df.rows.removeWhere((r) => r.get('success'));\n r.result = df;\n }\n r.result = r.result.toCsv();\n }\n r.logs = logs.join('\\n');\n r.ms = Date.now() - start;\n if (!skip)\n stdLog(`Finished ${t.category} ${t.name} for ${r.ms} ms`);\n r.category = t.category;\n r.name = t.name;\n if (!filter) {\n let params = {\n 'success': r.success, 'result': r.result, 'ms': r.ms,\n 'skipped': r.skipped, 'package': packageName, 'category': t.category, 'name': t.name, 'logs': r.logs,\n };\n if (r.result.constructor == Object) {\n const res = Object.keys(r.result).reduce((acc, k) => (Object.assign(Object.assign({}, acc), { ['result.' + k]: r.result[k] })), {});\n params = Object.assign(Object.assign({}, params), res);\n }\n if (params.result instanceof DG.DataFrame)\n params.result = JSON.stringify((_h = params.result) === null || _h === void 0 ? void 0 : _h.toJson()) || '';\n if (grok.shell.reportTest != null)\n yield grok.shell.reportTest(type, params);\n else {\n yield fetch(`${grok.dapi.root}/log/tests/${type}`, {\n method: 'POST', headers: { 'Content-Type': 'application/json' },\n credentials: 'same-origin',\n body: JSON.stringify(params)\n });\n }\n }\n return r;\n });\n}\nexport function shuffle(array) {\n const newArr = array.slice();\n newArr.sort(() => Math.random() - 0.5);\n return newArr;\n}\n;\n/* Waits [ms] milliseconds */\nexport function delay(ms) {\n return __awaiter(this, void 0, void 0, function* () {\n yield new Promise((r) => setTimeout(r, ms));\n });\n}\nexport function awaitCheck(checkHandler, error = 'Timeout exceeded', wait = 500, interval = 50) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n clearInterval(intervalId);\n reject(new Error(error));\n }, wait);\n // @ts-ignore\n const intervalId = setInterval(() => {\n if (checkHandler()) {\n clearInterval(intervalId);\n resolve();\n }\n }, interval);\n });\n });\n}\n// Returns test execution result or an error in case of timeout\nexport function timeout(func, testTimeout, timeoutReason = 'EXECUTION TIMEOUT') {\n return __awaiter(this, void 0, void 0, function* () {\n let timeout = null;\n const timeoutPromise = new Promise((_, reject) => {\n timeout = setTimeout(() => {\n // eslint-disable-next-line prefer-promise-reject-errors\n reject(timeoutReason);\n }, testTimeout);\n });\n try {\n return yield Promise.race([func(), timeoutPromise]);\n }\n finally {\n if (timeout)\n clearTimeout(timeout);\n }\n });\n}\nexport function isDialogPresent(dialogTitle) {\n const dialogs = DG.Dialog.getOpenDialogs();\n for (let i = 0; i < dialogs.length; i++) {\n if (dialogs[i].title == dialogTitle)\n return true;\n }\n return false;\n}\n/** Expects an asynchronous {@link action} to throw an exception. Use {@link check} to perform\n * deeper inspection of the exception if necessary.\n * @param {function(): Promise<void>} action\n * @param {function(any): boolean} check\n * @return {Promise<void>}\n */\nexport function expectExceptionAsync(action, check) {\n return __awaiter(this, void 0, void 0, function* () {\n let caught = false;\n let checked = false;\n try {\n yield action();\n }\n catch (e) {\n caught = true;\n checked = !check || check(e);\n }\n finally {\n if (!caught)\n throw new Error('An exception is expected but not thrown');\n if (!checked)\n throw new Error('An expected exception is thrown, but it does not satisfy the condition');\n }\n });\n}\nconst catDF = DG.DataFrame.fromColumns([DG.Column.fromStrings('col', ['val1', 'val2', 'val3'])]);\n/**\n * Universal test for viewers. It search viewers in DOM by tags: canvas, svg, img, input, h1, a\n * @param {string} v Viewer name\n * @param {DG.DataFrame} df Dataframe to use. Should have at least 3 rows\n * @param {boolean} options.detectSemanticTypes Specify whether to detect semantic types or not\n * @param {boolean} options.readOnly If set to true, the dataframe will not be modified during the test\n * @param {boolean} options.arbitraryDfTest If set to false, test on arbitrary dataframe\n * (one categorical column) will not be performed\n * @param {object} options List of options (optional)\n * @return {Promise<void>} The test is considered successful if it completes without errors\n */\nexport function testViewer(v, df, options) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n const packageName = (_a = options === null || options === void 0 ? void 0 : options.packageName) !== null && _a !== void 0 ? _a : '';\n if (options === null || options === void 0 ? void 0 : options.detectSemanticTypes)\n yield grok.data.detectSemanticTypes(df);\n const tv = grok.shell.addTableView(df);\n try {\n //1. Open, do nothing and close\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded);\n //in case viewer with async rendering - wait for render to complete\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, undefined, options.awaitViewer);\n //2. Open viewer, run selection, filter, etc. and close\n if (!(options === null || options === void 0 ? void 0 : options.readOnly)) {\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, selectFilterChangeCurrent);\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, selectFilterChangeCurrent, options.awaitViewer);\n }\n //2. Open viewer, change options, save layout and close\n let propsAndLayout = null;\n propsAndLayout = yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, changeOptionsSaveLayout);\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n propsAndLayout = yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, changeOptionsSaveLayout, options.awaitViewer);\n //3. Load layout\n yield testViewerInternal(tv, v, packageName, grok.events.onViewLayoutApplied, loadLayout, undefined, propsAndLayout === null || propsAndLayout === void 0 ? void 0 : propsAndLayout.layout, { savedProps: propsAndLayout === null || propsAndLayout === void 0 ? void 0 : propsAndLayout.savedProps });\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewLayoutApplied, loadLayout, options.awaitViewer, propsAndLayout === null || propsAndLayout === void 0 ? void 0 : propsAndLayout.layout, { savedProps: propsAndLayout === null || propsAndLayout === void 0 ? void 0 : propsAndLayout.savedProps });\n //4. Open viewer on arbitary dataset\n if ((options === null || options === void 0 ? void 0 : options.arbitraryDfTest) !== false) {\n tv.dataFrame = catDF;\n yield delay(50);\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded);\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, undefined, options.awaitViewer);\n }\n //5. Call postponed filtering\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, filterAsync);\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, filterAsync, options.awaitViewer);\n }\n finally {\n // closeAll() is handling by common test workflow\n // grok.shell.closeAll();\n // DG.Balloon.closeAll();\n }\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXRDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU3QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSx5QkFBeUIsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXRJLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0FBQy9CLE1BQU0saUJBQWlCLEdBQUcsUUFBUSxDQUFDO0FBRW5DLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3pDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzNDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzNDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRTdDLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FFZCxFQUFFLENBQUM7QUFFUCxNQUFNLGdCQUFnQixHQUFHLFlBQVksQ0FBQztBQUN0QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUM7QUFDM0IsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUM7QUFDckMsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDO0FBQzNCLE1BQU0sYUFBYSxHQUErQixFQUFFLENBQUM7QUFDckQsTUFBTSxDQUFDLElBQUksZUFBdUIsQ0FBQztBQUVuQyxNQUFNLEtBQVcsTUFBTSxDQUt0QjtBQUxE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SyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNoQixNQUFNLGtCQUFrQixDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ3hFLElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFdBQVc7b0JBQ3RCLE1BQU0sa0JBQWtCLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLE9BQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUM1RztZQUVELDZCQUE2QjtZQUM3QixNQUFNLGtCQUFrQixDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ3JGLElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFdBQVc7Z0JBQ3RCLE1BQU0sa0JBQWtCLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLE9BQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUU5RztnQkFBUztZQUNSLGlEQUFpRDtZQUNqRCx5QkFBeUI7WUFDekIseUJBQXlCO1NBQzFCOztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGVzdERhdGEgfSBmcm9tICcuL2RhdGFmcmFtZS11dGlscyc7XG5pbXBvcnQgVGltZW91dCA9IE5vZGVKUy5UaW1lb3V0O1xuaW1wb3J0IHsgY2hhbmdlT3B0aW9uc1NhdmVMYXlvdXQsIGZpbHRlckFzeW5jLCBsb2FkTGF5b3V0LCBzZWxlY3RGaWx0ZXJDaGFuZ2VDdXJyZW50LCB0ZXN0Vmlld2VySW50ZXJuYWwgfSBmcm9tICcuL3Rlc3Qtdmlld2VyLXV0aWxzJztcblxuY29uc3QgU1RBTkRBUlRfVElNRU9VVCA9IDMwMDAwO1xuY29uc3QgQkVOQ0hNQVJLX1RJTUVPVVQgPSAxMDgwMDAwMDtcblxuY29uc3Qgc3RkTG9nID0gY29uc29sZS5sb2cuYmluZChjb25zb2xlKTtcbmNvbnN0IHN0ZEluZm8gPSBjb25zb2xlLmluZm8uYmluZChjb25zb2xlKTtcbmNvbnN0IHN0ZFdhcm4gPSBjb25zb2xlLndhcm4uYmluZChjb25zb2xlKTtcbmNvbnN0IHN0ZEVycm9yID0gY29uc29sZS5lcnJvci5iaW5kKGNvbnNvbGUpO1xuXG5leHBvcnQgY29uc3QgdGVzdHM6IHtcbiAgW2tleTogc3RyaW5nXTogQ2F0ZWdvcnlcbn0gPSB7fTtcblxuY29uc3QgYXV0b1Rlc3RzQ2F0TmFtZSA9ICdBdXRvIFRlc3RzJztcbmNvbnN0IGRlbW9DYXROYW1lID0gJ0RlbW8nO1xuY29uc3QgZGV0ZWN0b3JzQ2F0TmFtZSA9ICdEZXRlY3RvcnMnO1xuY29uc3QgY29yZUNhdE5hbWUgPSAnQ29yZSc7XG5jb25zdCB3YXNSZWdpc3RlcmVkOiB7IFtrZXk6IHN0cmluZ106IGJvb2xlYW4gfSA9IHt9O1xuZXhwb3J0IGxldCBjdXJyZW50Q2F0ZWdvcnk6IHN0cmluZztcblxuZXhwb3J0IG5hbWVzcGFjZSBhc3N1cmUge1xuICBleHBvcnQgZnVuY3Rpb24gbm90TnVsbCh2YWx1ZTogYW55LCBuYW1lPzogc3RyaW5nKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bmFtZSA9PSBudWxsID8gJ1ZhbHVlJyA6IG5hbWV9IG5vdCBkZWZpbmVkYCk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZXN0T3B0aW9ucyB7XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIGJlbmNobWFya1RpbWVvdXQ/OiBudW1iZXI7XG4gIHVuaGFuZGxlZEV4Y2VwdGlvblRpbWVvdXQ/OiBudW1iZXI7XG4gIHNraXBSZWFzb24/OiBzdHJpbmc7XG4gIGlzQWdncmVnYXRlZD86IGJvb2xlYW47XG4gIGJlbmNobWFyaz86IGJvb2xlYW47XG4gIHN0cmVzc1Rlc3Q/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhdGVnb3J5T3B0aW9ucyB7XG4gIGNsZWFyPzogYm9vbGVhbjtcbiAgdGltZW91dD86IG51bWJlcjtcbiAgYmVuY2htYXJrcz86IGJvb2xlYW47XG4gIHN0cmVzc1Rlc3RzPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFRlc3RDb250ZXh0IHtcbiAgc3RyZXNzVGVzdD86IGJvb2xlYW47XG4gIGNhdGNoVW5oYW5kbGVkID0gdHJ1ZTtcbiAgcmVwb3J0ID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoY2F0Y2hVbmhhbmRsZWQ/OiBib29sZWFuLCByZXBvcnQ/OiBib29sZWFuKSB7XG4gICAgaWYgKGNhdGNoVW5oYW5kbGVkICE9PSB1bmRlZmluZWQpIHRoaXMuY2F0Y2hVbmhhbmRsZWQgPSBjYXRjaFVuaGFuZGxlZDtcbiAgICBpZiAocmVwb3J0ICE9PSB1bmRlZmluZWQpIHRoaXMucmVwb3J0ID0gcmVwb3J0O1xuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgVGVzdCB7XG4gIHRlc3Q6ICgpID0+IFByb21pc2U8YW55PjtcbiAgbmFtZTogc3RyaW5nO1xuICBjYXRlZ29yeTogc3RyaW5nO1xuICBvcHRpb25zPzogVGVzdE9wdGlvbnM7XG5cbiAgY29uc3RydWN0b3IoY2F0ZWdvcnk6IHN0cmluZywgbmFtZTogc3RyaW5nLCB0ZXN0OiAoKSA9PiBQcm9taXNlPGFueT4sIG9wdGlvbnM/OiBUZXN0T3B0aW9ucykge1xuICAgIHRoaXMuY2F0ZWdvcnkgPSBjYXRlZ29yeTtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIG9wdGlvbnMgPz89IHt9O1xuICAgIG9wdGlvbnMudGltZW91dCA/Pz0gU1RBTkRBUlRfVElNRU9VVDtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMudGVzdCA9IGFzeW5jICgpOiBQcm9taXNlPGFueT4gPT4ge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9ICcnO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHRlc3QoKTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENhdGVnb3J5IHtcbiAgdGVzdHM/OiBUZXN0W107XG4gIGJlZm9yZT86ICgpID0+IFByb21pc2U8dm9pZD47XG4gIGFmdGVyPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblxuICBiZWZvcmVTdGF0dXM/OiBzdHJpbmc7XG4gIGFmdGVyU3RhdHVzPzogc3RyaW5nO1xuICBjbGVhcj86IGJvb2xlYW47XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIGJlbmNobWFya3M/OiBib29sZWFuO1xuICBiZW5jaG1hcmtUaW1lb3V0PzogbnVtYmVyO1xuICBzdHJlc3NUZXN0cz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBUZXN0RXhlY3V0aW9uT3B0aW9ucyB7XG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xuICB0ZXN0Pzogc3RyaW5nO1xuICB0ZXN0Q29udGV4dD86IFRlc3RDb250ZXh0O1xuICBleGNsdWRlPzogc3RyaW5nW107XG4gIHZlcmJvc2U/OiBib29sZWFuO1xuICBzdHJlc3NUZXN0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRlc3RFdmVudDxUPihldmVudDogT2JzZXJ2YWJsZTxUPixcbiAgaGFuZGxlcjogKGFyZ3M6IFQpID0+IHZvaWQsIHRyaWdnZXI6ICgpID0+IHZvaWQsIG1zOiBudW1iZXIgPSAwLCByZWFzb246IHN0cmluZyA9IGB0aW1lb3V0YFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdWIgPSBldmVudC5zdWJzY3JpYmUoKGFyZ3M6IFQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGhhbmRsZXIoYXJncyk7XG4gICAgICAgIHJlc29sdmUoJ09LJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9yc1xuICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgfSwgbXMpO1xuICAgIHRyaWdnZXIoKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZXN0RXZlbnRBc3luYzxUPihldmVudDogT2JzZXJ2YWJsZTxUPixcbiAgaGFuZGxlcjogKGFyZ3M6IFQpID0+IFByb21pc2U8dm9pZD4sIHRyaWdnZXI6ICgpID0+IHZvaWQsIG1zOiBudW1iZXIgPSAwLCByZWFzb246IHN0cmluZyA9IGB0aW1lb3V0YFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdWIgPSBldmVudC5zdWJzY3JpYmUoKGFyZ3M6IFQpID0+IHtcbiAgICAgIGhhbmRsZXIoYXJncykudGhlbigoKSA9PiB7XG4gICAgICAgIHJlc29sdmUoJ09LJyk7XG4gICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9KS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1wcm9taXNlLXJlamVjdC1lcnJvcnNcbiAgICAgIHJlamVjdChyZWFzb24pO1xuICAgIH0sIG1zKTtcbiAgICB0cmlnZ2VyKCk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGVzdChuYW1lOiBzdHJpbmcsIHRlc3Q6ICgpID0+IFByb21pc2U8YW55Piwgb3B0aW9ucz86IFRlc3RPcHRpb25zKTogdm9pZCB7XG4gIGlmICh0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldID09IHVuZGVmaW5lZClcbiAgICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldID0ge307XG4gIGlmICh0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLnRlc3RzID09IHVuZGVmaW5lZClcbiAgICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLnRlc3RzID0gW107XG4gIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMhLnB1c2gobmV3IFRlc3QoY3VycmVudENhdGVnb3J5LCBuYW1lLCB0ZXN0LCBvcHRpb25zKSk7XG59XG5cbi8qIFRlc3RzIHR3byBvYmplY3RzIGZvciBlcXVhbGl0eSwgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGV5IGFyZSBub3QgZXF1YWwuICovXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0KGFjdHVhbDogYW55LCBleHBlY3RlZDogYW55ID0gdHJ1ZSwgZXJyb3I/OiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKGVycm9yKVxuICAgIGVycm9yID0gYCR7ZXJyb3J9LCBgO1xuICBlbHNlIGVycm9yID0gJyc7XG4gIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKVxuICAgIHRocm93IG5ldyBFcnJvcihgJHtlcnJvcn1FeHBlY3RlZCBcIiR7ZXhwZWN0ZWR9XCIsIGdvdCBcIiR7YWN0dWFsfVwiYCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RGbG9hdChhY3R1YWw6IG51bWJlciwgZXhwZWN0ZWQ6IG51bWJlciwgdG9sZXJhbmNlID0gMC4wMDEsIGVycm9yPzogc3RyaW5nKTogdm9pZCB7XG4gIGlmICgoYWN0dWFsID09PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgJiYgZXhwZWN0ZWQgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSkgfHxcbiAgICAoYWN0dWFsID09PSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkgJiYgZXhwZWN0ZWQgPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSkgfHxcbiAgICAoYWN0dWFsID09PSBOdW1iZXIuTmFOICYmIGV4cGVjdGVkID09PSBOdW1iZXIuTmFOKSB8fCAoaXNOYU4oYWN0dWFsKSAmJiBpc05hTihleHBlY3RlZCkpKVxuICAgIHJldHVybjtcbiAgY29uc3QgYXJlRXF1YWwgPSBNYXRoLmFicyhhY3R1YWwgLSBleHBlY3RlZCkgPCB0b2xlcmFuY2U7XG4gIGV4cGVjdChhcmVFcXVhbCwgdHJ1ZSwgYCR7ZXJyb3IgPz8gJyd9ICh0b2xlcmFuY2UgPSAke3RvbGVyYW5jZX0pYCk7XG4gIGlmICghYXJlRXF1YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSwgZ290ICR7YWN0dWFsfSAodG9sZXJhbmNlID0gJHt0b2xlcmFuY2V9KWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0VGFibGUoYWN0dWFsOiBERy5EYXRhRnJhbWUsIGV4cGVjdGVkOiBERy5EYXRhRnJhbWUsIGVycm9yPzogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGV4cGVjdGVkUm93Q291bnQgPSBleHBlY3RlZC5yb3dDb3VudDtcbiAgY29uc3QgYWN0dWFsUm93Q291bnQgPSBhY3R1YWwucm93Q291bnQ7XG4gIGV4cGVjdChhY3R1YWxSb3dDb3VudCwgZXhwZWN0ZWRSb3dDb3VudCwgYCR7ZXJyb3IgPz8gJyd9LCByb3cgY291bnRgKTtcblxuICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBleHBlY3RlZC5jb2x1bW5zKSB7XG4gICAgY29uc3QgYWN0dWFsQ29sdW1uID0gYWN0dWFsLmNvbHVtbnMuYnlOYW1lKGNvbHVtbi5uYW1lKTtcbiAgICBpZiAoYWN0dWFsQ29sdW1uID09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiAke2NvbHVtbi5uYW1lfSBub3QgZm91bmRgKTtcbiAgICBpZiAoYWN0dWFsQ29sdW1uLnR5cGUgIT0gY29sdW1uLnR5cGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiAke2NvbHVtbi5uYW1lfSB0eXBlIGV4cGVjdGVkICR7Y29sdW1uLnR5cGV9IGdvdCAke2FjdHVhbENvbHVtbi50eXBlfWApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRSb3dDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbHVtbi5nZXQoaSk7XG4gICAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGFjdHVhbENvbHVtbi5nZXQoaSk7XG4gICAgICBpZiAoY29sdW1uLnR5cGUgPT0gREcuVFlQRS5GTE9BVClcbiAgICAgICAgZXhwZWN0RmxvYXQoYWN0dWFsVmFsdWUsIHZhbHVlLCAwLjAwMDEsIGVycm9yKTtcbiAgICAgIGVsc2UgaWYgKGNvbHVtbi50eXBlID09IERHLlRZUEUuREFURV9USU1FKVxuICAgICAgICBleHBlY3QoYWN0dWFsVmFsdWUuaXNTYW1lKHZhbHVlKSwgdHJ1ZSwgZXJyb3IpO1xuICAgICAgZWxzZVxuICAgICAgICBleHBlY3QoYWN0dWFsVmFsdWUsIHZhbHVlLCBlcnJvcik7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RPYmplY3QoYWN0dWFsOiB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBleHBlY3RlZDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkge1xuICBmb3IgKGNvbnN0IFtleHBlY3RlZEtleSwgZXhwZWN0ZWRWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKCFhY3R1YWwuaGFzT3duUHJvcGVydHkoZXhwZWN0ZWRLZXkpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBwcm9wZXJ0eSBcIiR7ZXhwZWN0ZWRLZXl9XCIgbm90IGZvdW5kYCk7XG5cbiAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGFjdHVhbFtleHBlY3RlZEtleV07XG4gICAgaWYgKGFjdHVhbFZhbHVlIGluc3RhbmNlb2YgQXJyYXkgJiYgZXhwZWN0ZWRWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KVxuICAgICAgZXhwZWN0QXJyYXkoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKGFjdHVhbFZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmIGV4cGVjdGVkVmFsdWUgaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgICBleHBlY3RPYmplY3QoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKE51bWJlci5pc0Zpbml0ZShhY3R1YWxWYWx1ZSkgJiYgTnVtYmVyLmlzRmluaXRlKGV4cGVjdGVkVmFsdWUpKVxuICAgICAgZXhwZWN0RmxvYXQoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKGFjdHVhbFZhbHVlICE9IGV4cGVjdGVkVmFsdWUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICgke2V4cGVjdGVkVmFsdWV9KSBmb3Iga2V5ICcke2V4cGVjdGVkS2V5fScsIGdvdCAoJHthY3R1YWxWYWx1ZX0pYCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGVjdEFycmF5KGFjdHVhbDogQXJyYXlMaWtlPGFueT4sIGV4cGVjdGVkOiBBcnJheUxpa2U8YW55Pikge1xuICBjb25zdCBhY3R1YWxMZW5ndGggPSBhY3R1YWwubGVuZ3RoO1xuICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDtcblxuICBpZiAoYWN0dWFsTGVuZ3RoICE9IGV4cGVjdGVkTGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBcnJheXMgYXJlIG9mIGRpZmZlcmVudCBsZW5ndGg6IGFjdHVhbCBhcnJheSBsZW5ndGggaXMgJHthY3R1YWxMZW5ndGh9IGAgK1xuICAgICAgYGFuZCBleHBlY3RlZCBhcnJheSBsZW5ndGggaXMgJHtleHBlY3RlZExlbmd0aH1gKTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0dWFsTGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoYWN0dWFsW2ldIGluc3RhbmNlb2YgQXJyYXkgJiYgZXhwZWN0ZWRbaV0gaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgIGV4cGVjdEFycmF5KGFjdHVhbFtpXSwgZXhwZWN0ZWRbaV0pO1xuICAgIGVsc2UgaWYgKGFjdHVhbFtpXSBpbnN0YW5jZW9mIE9iamVjdCAmJiBleHBlY3RlZFtpXSBpbnN0YW5jZW9mIE9iamVjdClcbiAgICAgIGV4cGVjdE9iamVjdChhY3R1YWxbaV0sIGV4cGVjdGVkW2ldKTtcbiAgICBlbHNlIGlmIChhY3R1YWxbaV0gIT0gZXhwZWN0ZWRbaV0pXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7ZXhwZWN0ZWRbaV19IGF0IHBvc2l0aW9uICR7aX0sIGdvdCAke2FjdHVhbFtpXX1gKTtcbiAgfVxufVxuXG4vKiBEZWZpbmVzIGEgdGVzdCBzdWl0ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYXRlZ29yeShjYXRlZ29yeTogc3RyaW5nLCB0ZXN0c186ICgpID0+IHZvaWQsIG9wdGlvbnM/OiBDYXRlZ29yeU9wdGlvbnMpOiB2b2lkIHtcbiAgY3VycmVudENhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gIHRlc3RzXygpO1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSkge1xuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0uY2xlYXIgPSBvcHRpb25zPy5jbGVhciA/PyB0cnVlO1xuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGltZW91dCA9IG9wdGlvbnM/LnRpbWVvdXQ7XG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XS5iZW5jaG1hcmtzID0gb3B0aW9ucz8uYmVuY2htYXJrcztcbiAgICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLnN0cmVzc1Rlc3RzID0gb3B0aW9ucz8uc3RyZXNzVGVzdHM7XG4gIH1cbn1cblxuLyogRGVmaW5lcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGJlZm9yZSB0aGUgdGVzdHMgaW4gdGhpcyBjYXRlZ29yeSBhcmUgZXhlY3V0ZWQuICovXG5leHBvcnQgZnVuY3Rpb24gYmVmb3JlKGJlZm9yZTogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSA9PSB1bmRlZmluZWQpXG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XSA9IHt9O1xuICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLmJlZm9yZSA9IGJlZm9yZTtcbn1cblxuLyogRGVmaW5lcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGFmdGVyIHRoZSB0ZXN0cyBpbiB0aGlzIGNhdGVnb3J5IGFyZSBleGVjdXRlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlcihhZnRlcjogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSA9PSB1bmRlZmluZWQpXG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XSA9IHt9O1xuICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLmFmdGVyID0gYWZ0ZXI7XG59XG5cbmZ1bmN0aW9uIGFkZE5hbWVzcGFjZShzOiBzdHJpbmcsIGY6IERHLkZ1bmMpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKG5ldyBSZWdFeHAoZi5uYW1lLCAnZ2knKSwgZi5ucU5hbWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5pdEF1dG9UZXN0cyhwYWNrYWdlXzogREcuUGFja2FnZSwgbW9kdWxlPzogYW55KSB7XG4gIGNvbnN0IHBhY2thZ2VJZCA9IHBhY2thZ2VfLmlkO1xuICBpZiAod2FzUmVnaXN0ZXJlZFtwYWNrYWdlSWRdKSByZXR1cm47XG4gIGNvbnN0IG1vZHVsZVRlc3RzID0gbW9kdWxlID8gbW9kdWxlLnRlc3RzIDogdGVzdHM7XG4gIGlmIChtb2R1bGVUZXN0c1thdXRvVGVzdHNDYXROYW1lXSAhPT0gdW5kZWZpbmVkIHx8XG4gICAgbW9kdWxlVGVzdHNbZGVtb0NhdE5hbWVdICE9PSB1bmRlZmluZWQgfHxcbiAgICBPYmplY3Qua2V5cyhtb2R1bGVUZXN0cykuZmluZCgoYykgPT4gYy5zdGFydHNXaXRoKGF1dG9UZXN0c0NhdE5hbWUpIHx8IGMuc3RhcnRzV2l0aChjb3JlQ2F0TmFtZSkpKSB7XG4gICAgd2FzUmVnaXN0ZXJlZFtwYWNrYWdlSWRdID0gdHJ1ZTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHBhY2thZ2VfLm5hbWUgPT09ICdEZXZUb29scycgfHwgKCEhbW9kdWxlICYmIG1vZHVsZS5fcGFja2FnZS5uYW1lID09PSAnRGV2VG9vbHMnKSkge1xuICAgIGZvciAoY29uc3QgZiBvZiAoPGFueT53aW5kb3cpLmRhcnRUZXN0cykge1xuICAgICAgY29uc3QgYXJyID0gZi5uYW1lLnNwbGl0KC9cXHMqXFx8XFxzKiEvZyk7XG4gICAgICBsZXQgbmFtZSA9IGFyci5wb3AoKSA/PyBmLm5hbWU7XG4gICAgICBsZXQgY2F0ID0gYXJyLmxlbmd0aCA/IGNvcmVDYXROYW1lICsgJzogJyArIGFyci5qb2luKCc6ICcpIDogY29yZUNhdE5hbWU7XG4gICAgICBsZXQgZnVsbE5hbWU6IHN0cmluZ1tdID0gbmFtZS5zcGxpdCgnIHwgJyk7XG4gICAgICBuYW1lID0gZnVsbE5hbWVbZnVsbE5hbWUubGVuZ3RoIC0gMV07XG4gICAgICBmdWxsTmFtZS51bnNoaWZ0KGNhdCk7XG4gICAgICBmdWxsTmFtZS5wb3AoKTtcbiAgICAgIGNhdCA9IGZ1bGxOYW1lLmpvaW4oJzogJyk7XG4gICAgICBpZiAobW9kdWxlVGVzdHNbY2F0XSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICBtb2R1bGVUZXN0c1tjYXRdID0geyB0ZXN0czogW10sIGNsZWFyOiB0cnVlIH07XG4gICAgICBtb2R1bGVUZXN0c1tjYXRdLnRlc3RzLnB1c2gobmV3IFRlc3QoY2F0LCBuYW1lLCBmLnRlc3QsIHsgaXNBZ2dyZWdhdGVkOiBmYWxzZSwgdGltZW91dDogZi5vcHRpb25zPy50aW1lb3V0ID8/IFNUQU5EQVJUX1RJTUVPVVQsIHNraXBSZWFzb246IGYub3B0aW9ucz8uc2tpcFJlYXNvbiB9KSk7XG4gICAgfVxuICB9XG4gIGNvbnN0IG1vZHVsZUF1dG9UZXN0cyA9IFtdO1xuICBjb25zdCBtb2R1bGVEZW1vID0gW107XG4gIGNvbnN0IG1vZHVsZURldGVjdG9ycyA9IFtdO1xuICBjb25zdCBwYWNrRnVuY3Rpb25zID0gYXdhaXQgZ3Jvay5kYXBpLmZ1bmN0aW9ucy5maWx0ZXIoYHBhY2thZ2UuaWQgPSBcIiR7cGFja2FnZUlkfVwiYCkubGlzdCgpO1xuICBjb25zdCByZWcgPSBuZXcgUmVnRXhwKC9za2lwOlxccyooW14sXFxzXSspfHdhaXQ6XFxzKihcXGQrKXxjYXQ6XFxzKihbXixcXHNdKyl8dGltZW91dDpcXHMqKFxcZCspL2cpO1xuICBmb3IgKGNvbnN0IGYgb2YgcGFja0Z1bmN0aW9ucykge1xuICAgIGNvbnN0IHRlc3RzID0gZi5vcHRpb25zWyd0ZXN0J107XG4gICAgY29uc3QgZGVtbyA9IGYub3B0aW9uc1snZGVtb1BhdGgnXTtcbiAgICBpZiAoKHRlc3RzICYmIEFycmF5LmlzQXJyYXkodGVzdHMpICYmIHRlc3RzLmxlbmd0aCkpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVzdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcmVzID0gKHRlc3RzW2ldIGFzIHN0cmluZykubWF0Y2hBbGwocmVnKTtcbiAgICAgICAgY29uc3QgbWFwOiB7IHNraXA/OiBzdHJpbmcsIHdhaXQ/OiBudW1iZXIsIGNhdD86IHN0cmluZywgdGltZW91dD86IG51bWJlciwgYmVuY2htYXJrVGltZW91dD86IG51bWJlciB9ID0ge307XG4gICAgICAgIEFycmF5LmZyb20ocmVzKS5mb3JFYWNoKChhcnIpID0+IHtcbiAgICAgICAgICBpZiAoYXJyWzBdLnN0YXJ0c1dpdGgoJ3NraXAnKSkgbWFwWydza2lwJ10gPSBhcnJbMV07XG4gICAgICAgICAgZWxzZSBpZiAoYXJyWzBdLnN0YXJ0c1dpdGgoJ3dhaXQnKSkgbWFwWyd3YWl0J10gPSBwYXJzZUludChhcnJbMl0pO1xuICAgICAgICAgIGVsc2UgaWYgKGFyclswXS5zdGFydHNXaXRoKCdjYXQnKSkgbWFwWydjYXQnXSA9IGFyclszXTtcbiAgICAgICAgICBlbHNlIGlmIChhcnJbMF0uc3RhcnRzV2l0aCgndGltZW91dCcpKSBtYXBbJ3RpbWVvdXQnXSA9IHBhcnNlSW50KGFycls0XSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB0ZXN0ID0gbmV3IFRlc3QoYXV0b1Rlc3RzQ2F0TmFtZSwgdGVzdHMubGVuZ3RoID09PSAxID8gZi5uYW1lIDogYCR7Zi5uYW1lfSAke2kgKyAxfWAsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBncm9rLmZ1bmN0aW9ucy5ldmFsKGFkZE5hbWVzcGFjZSh0ZXN0c1tpXSwgZikpO1xuICAgICAgICAgIGlmIChtYXAud2FpdCkgYXdhaXQgZGVsYXkobWFwLndhaXQpO1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gICAgICAgICAgaWYgKHR5cGVvZiByZXMgPT09ICdib29sZWFuJyAmJiAhcmVzKSB0aHJvdyBgRmFpbGVkOiAke3Rlc3RzW2ldfSwgZXhwZWN0ZWQgdHJ1ZSwgZ290ICR7cmVzfWA7XG4gICAgICAgIH0sIHsgc2tpcFJlYXNvbjogbWFwLnNraXAsIHRpbWVvdXQ6IERHLlRlc3QuaXNJbkJlbmNobWFyayA/IG1hcC5iZW5jaG1hcmtUaW1lb3V0IDogbWFwLnRpbWVvdXQgfSk7XG4gICAgICAgIGlmIChtYXAuY2F0KSB7XG4gICAgICAgICAgY29uc3QgY2F0OiBzdHJpbmcgPSBhdXRvVGVzdHNDYXROYW1lICsgJzogJyArIG1hcC5jYXQ7XG4gICAgICAgICAgdGVzdC5jYXRlZ29yeSA9IGNhdDtcbiAgICAgICAgICBpZiAobW9kdWxlVGVzdHNbY2F0XSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgbW9kdWxlVGVzdHNbY2F0XSA9IHsgdGVzdHM6IFtdLCBjbGVhcjogdHJ1ZSB9O1xuICAgICAgICAgIG1vZHVsZVRlc3RzW2NhdF0udGVzdHMucHVzaCh0ZXN0KTtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgbW9kdWxlQXV0b1Rlc3RzLnB1c2godGVzdCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChkZW1vKSB7XG4gICAgICBjb25zdCB3YWl0ID0gZi5vcHRpb25zWydkZW1vV2FpdCddID8gcGFyc2VJbnQoZi5vcHRpb25zWydkZW1vV2FpdCddKSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHRlc3QgPSBuZXcgVGVzdChkZW1vQ2F0TmFtZSwgZi5mcmllbmRseU5hbWUsIGFzeW5jICgpID0+IHtcbiAgICAgICAgZ3Jvay5zaGVsbC5pc0luRGVtbyA9IHRydWU7XG4gICAgICAgIGlmIChncm9rLnNoZWxsLnZpZXcoREcuVmlldy5CUk9XU0UpID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgZ3Jvay5zaGVsbC52ID0gREcuVmlldy5jcmVhdGVCeVR5cGUoREcuVmlldy5CUk9XU0UpO1xuICAgICAgICBhd2FpdCBkZWxheSgzMDApO1xuICAgICAgICBncm9rLnNoZWxsLmNsZWFyTGFzdEVycm9yKCk7XG4gICAgICAgIGF3YWl0IGYuYXBwbHkoKTtcbiAgICAgICAgYXdhaXQgZGVsYXkod2FpdCA/IHdhaXQgOiAyMDAwKTtcbiAgICAgICAgY29uc3QgdW5oYW5kbGVkID0gYXdhaXQgZ3Jvay5zaGVsbC5sYXN0RXJyb3I7XG4gICAgICAgIGlmICh1bmhhbmRsZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHVuaGFuZGxlZCk7XG4gICAgICAgIGdyb2suc2hlbGwuaXNJbkRlbW8gPSBmYWxzZTtcbiAgICAgIH0sIHsgc2tpcFJlYXNvbjogZi5vcHRpb25zWydkZW1vU2tpcCddIH0pO1xuICAgICAgbW9kdWxlRGVtby5wdXNoKHRlc3QpO1xuICAgIH1cbiAgICBpZiAoZi5oYXNUYWcoJ3NlbVR5cGVEZXRlY3RvcicpKSB7XG4gICAgICBjb25zdCB0ZXN0ID0gbmV3IFRlc3QoZGV0ZWN0b3JzQ2F0TmFtZSwgZi5mcmllbmRseU5hbWUsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYXJyID0gW107XG4gICAgICAgIGZvciAoY29uc3QgY29sIG9mIHRlc3REYXRhLmNsb25lKCkuY29sdW1ucykge1xuICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGYuYXBwbHkoW2NvbF0pO1xuICAgICAgICAgIGFyci5wdXNoKHJlcyB8fCBjb2wuc2VtVHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwZWN0KGFyci5maWx0ZXIoKGkpID0+IGkpLmxlbmd0aCwgMSk7XG4gICAgICB9LCB7IHNraXBSZWFzb246IGYub3B0aW9uc1snc2tpcFRlc3QnXSB9KTtcbiAgICAgIG1vZHVsZURldGVjdG9ycy5wdXNoKHRlc3QpO1xuICAgIH1cbiAgfVxuICB3YXNSZWdpc3RlcmVkW3BhY2thZ2VJZF0gPSB0cnVlO1xuICBpZiAobW9kdWxlQXV0b1Rlc3RzLmxlbmd0aClcbiAgICBtb2R1bGVUZXN0c1thdXRvVGVzdHNDYXROYW1lXSA9IHsgdGVzdHM6IG1vZHVsZUF1dG9UZXN0cywgY2xlYXI6IHRydWUgfTtcbiAgaWYgKG1vZHVsZURlbW8ubGVuZ3RoKVxuICAgIG1vZHVsZVRlc3RzW2RlbW9DYXROYW1lXSA9IHsgdGVzdHM6IG1vZHVsZURlbW8sIGNsZWFyOiB0cnVlIH07XG4gIGlmIChtb2R1bGVEZXRlY3RvcnMubGVuZ3RoKVxuICAgIG1vZHVsZVRlc3RzW2RldGVjdG9yc0NhdE5hbWVdID0geyB0ZXN0czogbW9kdWxlRGV0ZWN0b3JzLCBjbGVhcjogZmFsc2UgfTtcbn1cblxuZnVuY3Rpb24gcmVkZWZpbmVDb25zb2xlKCk6IGFueVtdIHtcbiAgY29uc3QgbG9nczogYW55W10gPSBbXTtcbiAgY29uc29sZS5sb2cgPSAoLi4uYXJncykgPT4ge1xuICAgIGxvZ3MucHVzaCguLi5hcmdzKTtcbiAgICBzdGRMb2coLi4uYXJncyk7XG4gIH07XG4gIGNvbnNvbGUuaW5mbyA9ICguLi5hcmdzKSA9PiB7XG4gICAgbG9ncy5wdXNoKC4uLmFyZ3MpO1xuICAgIHN0ZEluZm8oLi4uYXJncyk7XG4gIH07XG4gIGNvbnNvbGUud2FybiA9ICguLi5hcmdzKSA9PiB7XG4gICAgbG9ncy5wdXNoKC4uLmFyZ3MpO1xuICAgIHN0ZFdhcm4oLi4uYXJncyk7XG4gIH07XG4gIGNvbnNvbGUuZXJyb3IgPSAoLi4uYXJncykgPT4ge1xuICAgIGxvZ3MucHVzaCguLi5hcmdzKTtcbiAgICBzdGRFcnJvciguLi5hcmdzKTtcbiAgfTtcbiAgcmV0dXJuIGxvZ3M7XG59XG5cbmZ1bmN0aW9uIHJlc2V0Q29uc29sZSgpOiB2b2lkIHtcbiAgY29uc29sZS5sb2cgPSBzdGRMb2c7XG4gIGNvbnNvbGUuaW5mbyA9IHN0ZEluZm87XG4gIGNvbnNvbGUud2FybiA9IHN0ZFdhcm47XG4gIGNvbnNvbGUuZXJyb3IgPSBzdGRFcnJvcjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1blRlc3RzKG9wdGlvbnM/OiBUZXN0RXhlY3V0aW9uT3B0aW9ucykge1xuICBjb25zdCBwYWNrYWdlXyA9IGdyb2suZnVuY3Rpb25zLmdldEN1cnJlbnRDYWxsKCk/LmZ1bmM/LnBhY2thZ2U7XG4gIGF3YWl0IGluaXRBdXRvVGVzdHMocGFja2FnZV8pO1xuICBjb25zdCByZXN1bHRzOiB7XG4gICAgY2F0ZWdvcnk/OiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcsIHN1Y2Nlc3M6IGJvb2xlYW4sXG4gICAgcmVzdWx0OiBzdHJpbmcsIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4sIGxvZ3M/OiBzdHJpbmdcbiAgfVtdID0gW107XG4gIGNvbnNvbGUubG9nKGBSdW5uaW5nIHRlc3RzYCk7XG4gIG9wdGlvbnMgPz89IHt9O1xuICBvcHRpb25zIS50ZXN0Q29udGV4dCA/Pz0gbmV3IFRlc3RDb250ZXh0KCk7XG4gIGdyb2suc2hlbGwuY2xlYXJMYXN0RXJyb3IoKTtcbiAgY29uc3QgY2F0ZWdvcmllcyA9IFtdO1xuICBjb25zdCBsb2dzID0gcmVkZWZpbmVDb25zb2xlKCk7XG5cbiAgaWYgKG9wdGlvbnM/LnN0cmVzc1Rlc3QpIHtcbiAgICBhd2FpdCBJbnZva2VTdHJlc3NUZXN0cyhvcHRpb25zKTtcbiAgfVxuICBlbHNlIHtcbiAgICBhd2FpdCBJbnZva2VBbGxUZXN0cyh0ZXN0cywgb3B0aW9ucyk7XG4gIH1cbiAgZm9yIChsZXQgciBvZiByZXN1bHRzKSB7XG4gICAgci5yZXN1bHQgPSByLnJlc3VsdC50b1N0cmluZygpLnJlcGxhY2UoL1wiL2csICdcXCcnKTtcbiAgICBpZiAoci5sb2dzICE9IHVuZGVmaW5lZClcbiAgICAgIHIubG9ncyA9IHIubG9ncyEudG9TdHJpbmcoKS5yZXBsYWNlKC9cIi9nLCAnXFwnJyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG5cbiAgYXN5bmMgZnVuY3Rpb24gSW52b2tlQ2F0ZWdvcnlNZXRob2QobWV0aG9kOiAoKCkgPT4gUHJvbWlzZTx2b2lkPikgfCB1bmRlZmluZWQsIGNhdGVnb3J5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICAgIHZhciBpbnZva2F0aW9uUmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgIHRyeSB7XG4gICAgICBpZiAobWV0aG9kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXdhaXQgdGltZW91dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgbWV0aG9kKCk7XG4gICAgICAgIH0sIDEwMDAwMCwgYGJlZm9yZSAke2NhdGVnb3J5fTogdGltZW91dCBlcnJvcmApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKHg6IGFueSkge1xuICAgICAgaW52b2thdGlvblJlc3VsdCA9IGF3YWl0IGdldFJlc3VsdCh4KTtcbiAgICB9XG4gICAgcmV0dXJuIGludm9rYXRpb25SZXN1bHRcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIEludm9rZVN0cmVzc1Rlc3RzKG9wdGlvbnM6IFRlc3RFeGVjdXRpb25PcHRpb25zKSB7XG4gICAgbGV0IHRlc3RJbnZvY2F0aW9uTWFwOiBhbnlbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRlc3RzKSkge1xuICAgICAgbGV0IHRlc3RzVG9JbnZva2UgPSB2YWx1ZS50ZXN0cz8uZmlsdGVyKCh0ZXN0KSA9PiB0ZXN0Lm9wdGlvbnM/LnN0cmVzc1Rlc3QpO1xuICAgICAgaWYgKHZhbHVlLnN0cmVzc1Rlc3RzKSB7XG4gICAgICAgIHRlc3RzVG9JbnZva2UgPSB2YWx1ZS50ZXN0cz8uZmlsdGVyKCh0ZXN0KSA9PiB0ZXN0Lm9wdGlvbnM/LnN0cmVzc1Rlc3QgPT09IHVuZGVmaW5lZCB8fCB0ZXN0Lm9wdGlvbnM/LnN0cmVzc1Rlc3QgPT09IHRydWUpXG4gICAgICB9XG5cblxuICAgICAgY29uc3Qgc2tpcHBlZCA9IHZhbHVlLnRlc3RzPy5ldmVyeSgodCkgPT4gdC5vcHRpb25zPy5za2lwUmVhc29uKTtcbiAgICAgIGlmIChza2lwcGVkKVxuICAgICAgICBjb250aW51ZTtcblxuICAgICAgZm9yIChsZXQgdGVzdCBvZiB0ZXN0c1RvSW52b2tlID8/IFtdKSB7XG4gICAgICAgIGlmICh0ZXN0Lm9wdGlvbnM/LnNraXBSZWFzb24gPT0gbnVsbCkge1xuICAgICAgICAgIHRlc3RJbnZvY2F0aW9uTWFwLnB1c2goeyB0ZXN0LCB2YWx1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0ZXN0SW52b2NhdGlvbk1hcCA9IHNodWZmbGUodGVzdEludm9jYXRpb25NYXApO1xuXG4gICAgY29uc3QgcmVzID0gW107XG4gICAgZm9yIChsZXQgdGVzdGluZ09iaiBvZiB0ZXN0SW52b2NhdGlvbk1hcCkge1xuICAgICAgYXdhaXQgSW52b2tlQ2F0ZWdvcnlNZXRob2QodGVzdGluZ09iai52YWx1ZS5iZWZvcmUsIG9wdGlvbnMuY2F0ZWdvcnkgPz8gJycpXG4gICAgICBsZXQgdGVzdFJ1biA9IGF3YWl0IGV4ZWNUZXN0KHRlc3RpbmdPYmoudGVzdCwgb3B0aW9ucz8udGVzdCwgbG9ncywgREcuVGVzdC5pc0luQmVuY2htYXJrID8gdGVzdGluZ09iai52YWx1ZS5iZW5jaG1hcmtUaW1lb3V0IDogdGVzdGluZ09iai52YWx1ZS50aW1lb3V0LCBwYWNrYWdlXy5uYW1lLCBvcHRpb25zLnZlcmJvc2UpO1xuICAgICAgaWYgKHRlc3RSdW4pXG4gICAgICAgIHJlcy5wdXNoKHRlc3RSdW4pO1xuICAgICAgY29uc29sZS5sb2coYFRlc3Q6ICR7dGVzdD8ubmFtZX07IHJlc3VsdDogJHt0ZXN0UnVufWApO1xuICAgICAgYXdhaXQgSW52b2tlQ2F0ZWdvcnlNZXRob2QodGVzdGluZ09iai52YWx1ZS5hZnRlciwgb3B0aW9ucy5jYXRlZ29yeSA/PyAnJylcbiAgICB9XG5cbiAgICByZXN1bHRzLnB1c2goLi4ucmVzKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIEludm9rZUFsbFRlc3RzKGNhdGVnb3JpZXNUb0ludm9rZTogeyBba2V5OiBzdHJpbmddOiBDYXRlZ29yeSB9LCBvcHRpb25zOiBUZXN0RXhlY3V0aW9uT3B0aW9ucykge1xuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhjYXRlZ29yaWVzVG9JbnZva2UpKSB7XG4gICAgICAgIGlmICgoISFvcHRpb25zPy5jYXRlZ29yeSAmJiAha2V5LnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChvcHRpb25zPy5jYXRlZ29yeS50b0xvd2VyQ2FzZSgpKSkgfHxcbiAgICAgICAgICBvcHRpb25zLmV4Y2x1ZGU/LnNvbWUoKGMpID0+IGtleS5zdGFydHNXaXRoKGMpKSlcbiAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICBzdGRMb2coYFN0YXJ0ZWQgJHtrZXl9IGNhdGVnb3J5YCk7XG4gICAgICAgIGNvbnN0IHNraXBwZWQgPSB2YWx1ZS50ZXN0cz8uZXZlcnkoKHQpID0+IHQub3B0aW9ucz8uc2tpcFJlYXNvbik7XG4gICAgICAgIGlmICghc2tpcHBlZClcbiAgICAgICAgICB2YWx1ZS5iZWZvcmVTdGF0dXMgPSBhd2FpdCBJbnZva2VDYXRlZ29yeU1ldGhvZCh2YWx1ZS5iZWZvcmUsIG9wdGlvbnMuY2F0ZWdvcnkgPz8gJycpO1xuICAgICAgICBjb25zdCB0ID0gdmFsdWUudGVzdHMgPz8gW107XG4gICAgICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgICAgICBpZiAodmFsdWUuY2xlYXIpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0W2ldLm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgaWYgKHRbaV0ub3B0aW9ucz8uYmVuY2htYXJrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRbaV0ub3B0aW9ucylcbiAgICAgICAgICAgICAgICAgIHRbaV0ub3B0aW9ucyA9IHt9XG4gICAgICAgICAgICAgICAgdFtpXS5vcHRpb25zIS5iZW5jaG1hcmsgPSB2YWx1ZS5iZW5jaG1hcmtzID8/IGZhbHNlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgdGVzdFJ1biA9IGF3YWl0IGV4ZWNUZXN0KHRbaV0sIG9wdGlvbnM/LnRlc3QsIGxvZ3MsIERHLlRlc3QuaXNJbkJlbmNobWFyayA/IHZhbHVlLmJlbmNobWFya1RpbWVvdXQgOiB2YWx1ZS50aW1lb3V0LCBwYWNrYWdlXy5uYW1lLCBvcHRpb25zLnZlcmJvc2UpO1xuICAgICAgICAgICAgaWYgKHRlc3RSdW4pXG4gICAgICAgICAgICAgIHJlcy5wdXNoKHRlc3RSdW4pO1xuICAgICAgICAgICAgZ3Jvay5zaGVsbC5jbG9zZUFsbCgpO1xuICAgICAgICAgICAgREcuQmFsbG9vbi5jbG9zZUFsbCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB0ZXN0UnVuID0gYXdhaXQgZXhlY1Rlc3QodFtpXSwgb3B0aW9ucz8udGVzdCwgbG9ncywgREcuVGVzdC5pc0luQmVuY2htYXJrID8gdmFsdWUuYmVuY2htYXJrVGltZW91dCA6IHZhbHVlLnRpbWVvdXQsIHBhY2thZ2VfLm5hbWUsIG9wdGlvbnMudmVyYm9zZSk7XG4gICAgICAgICAgICBpZiAodGVzdFJ1bilcbiAgICAgICAgICAgICAgcmVzLnB1c2godGVzdFJ1bik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRhdGEgPSByZXMuZmlsdGVyKChkKSA9PiBkLnJlc3VsdCAhPSAnc2tpcHBlZCcpO1xuXG4gICAgICAgIGlmICghc2tpcHBlZClcbiAgICAgICAgICB2YWx1ZS5hZnRlclN0YXR1cyA9IGF3YWl0IEludm9rZUNhdGVnb3J5TWV0aG9kKHZhbHVlLmFmdGVyLCBvcHRpb25zLmNhdGVnb3J5ID8/ICcnKTtcblxuICAgICAgICAvLyBDbGVhciBhZnRlciBjYXRlZ29yeVxuICAgICAgICAvLyBncm9rLnNoZWxsLmNsb3NlQWxsKCk7XG4gICAgICAgIC8vIERHLkJhbGxvb24uY2xvc2VBbGwoKTtcbiAgICAgICAgaWYgKHZhbHVlLmFmdGVyU3RhdHVzKVxuICAgICAgICAgIGRhdGEucHVzaCh7IGRhdGU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwgbG9nczogJycsIGNhdGVnb3J5OiBrZXksIG5hbWU6ICdhZnRlcicsIHJlc3VsdDogdmFsdWUuYWZ0ZXJTdGF0dXMsIHN1Y2Nlc3M6IGZhbHNlLCBtczogMCwgc2tpcHBlZDogZmFsc2UgfSk7XG4gICAgICAgIGlmICh2YWx1ZS5iZWZvcmVTdGF0dXMpXG4gICAgICAgICAgZGF0YS5wdXNoKHsgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLCBsb2dzOiAnJywgY2F0ZWdvcnk6IGtleSwgbmFtZTogJ2JlZm9yZScsIHJlc3VsdDogdmFsdWUuYmVmb3JlU3RhdHVzLCBzdWNjZXNzOiBmYWxzZSwgbXM6IDAsIHNraXBwZWQ6IGZhbHNlIH0pO1xuICAgICAgICByZXN1bHRzLnB1c2goLi4uZGF0YSk7XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHJlc2V0Q29uc29sZSgpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy50ZXN0Q29udGV4dCEuY2F0Y2hVbmhhbmRsZWQgJiYgKCFERy5UZXN0LmlzSW5CZW5jaG1hcmspKSB7XG4gICAgICBhd2FpdCBkZWxheSgxMDAwKTtcbiAgICAgIGNvbnN0IGVycm9yID0gYXdhaXQgZ3Jvay5zaGVsbC5sYXN0RXJyb3I7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxvZ3M6ICcnLFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIGNhdGVnb3J5OiAnVW5oYW5kbGVkIGV4Y2VwdGlvbnMnLFxuICAgICAgICBuYW1lOiAnRXhjZXB0aW9uJyxcbiAgICAgICAgcmVzdWx0OiBlcnJvciA/PyAnJywgc3VjY2VzczogIWVycm9yLCBtczogMCwgc2tpcHBlZDogZmFsc2VcbiAgICAgIH07XG4gICAgICByZXN1bHRzLnB1c2gocGFyYW1zKTtcbiAgICAgICg8YW55PnBhcmFtcykucGFja2FnZSA9IHBhY2thZ2VfLm5hbWU7XG4gICAgICBpZiAoKDxhbnk+Z3Jvay5zaGVsbCkucmVwb3J0VGVzdCAhPSBudWxsKVxuICAgICAgICBhd2FpdCAoPGFueT5ncm9rLnNoZWxsKS5yZXBvcnRUZXN0KCdwYWNrYWdlJywgcGFyYW1zKTtcbiAgICAgIGVsc2Uge1xuICAgICAgICBhd2FpdCBmZXRjaChgJHtncm9rLmRhcGkucm9vdH0vbG9nL3Rlc3RzL3BhY2thZ2VgLCB7XG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICAgIGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nLFxuICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHBhcmFtcylcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFJlc3VsdCh4OiBhbnkpOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gYCR7eC50b1N0cmluZygpfVxcbiR7eC5zdGFjayA/IChhd2FpdCBERy5Mb2dnZXIudHJhbnNsYXRlU3RhY2tUcmFjZSh4LnN0YWNrKSkgOiAnJ31gO1xufVxuXG5hc3luYyBmdW5jdGlvbiBleGVjVGVzdCh0OiBUZXN0LCBwcmVkaWNhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCwgbG9nczogYW55W10sXG4gIGNhdGVnb3J5VGltZW91dD86IG51bWJlciwgcGFja2FnZU5hbWU/OiBzdHJpbmcsIHZlcmJvc2U/OiBib29sZWFuKTogUHJvbWlzZTxhbnk+IHtcbiAgbG9ncy5sZW5ndGggPSAwO1xuICBsZXQgcjogeyBkYXRlOiBzdHJpbmcsIGNhdGVnb3J5Pzogc3RyaW5nLCBuYW1lPzogc3RyaW5nLCBzdWNjZXNzOiBib29sZWFuLCByZXN1bHQ6IGFueSwgbXM6IG51bWJlciwgc2tpcHBlZDogYm9vbGVhbiwgbG9ncz86IHN0cmluZyB9O1xuICBsZXQgdHlwZTogc3RyaW5nID0gJ3BhY2thZ2UnO1xuICBjb25zdCBmaWx0ZXIgPSBwcmVkaWNhdGUgIT0gdW5kZWZpbmVkICYmICh0Lm5hbWUudG9Mb3dlckNhc2UoKSAhPT0gcHJlZGljYXRlLnRvTG93ZXJDYXNlKCkpO1xuICBsZXQgc2tpcCA9IHQub3B0aW9ucz8uc2tpcFJlYXNvbiB8fCBmaWx0ZXI7XG4gIGxldCBza2lwUmVhc29uID0gZmlsdGVyID8gJ3NraXBwZWQnIDogdC5vcHRpb25zPy5za2lwUmVhc29uO1xuXG4gIGlmIChERy5UZXN0LmlzSW5CZW5jaG1hcmsgJiYgIXQub3B0aW9ucz8uYmVuY2htYXJrKSB7XG4gICAgc3RkTG9nKGBTS0lQUEVEOiAke3QuY2F0ZWdvcnl9ICR7dC5uYW1lfSBkb2VzbnQgYXZhaWxhYmxlIGluIGJlbmNobWFyayBtb2RlYCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICghc2tpcClcbiAgICBzdGRMb2coYFN0YXJ0ZWQgJHt0LmNhdGVnb3J5fSAke3QubmFtZX1gKTtcbiAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICB0cnkge1xuICAgIGlmIChza2lwKVxuICAgICAgciA9IHsgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLCBzdWNjZXNzOiB0cnVlLCByZXN1bHQ6IHNraXBSZWFzb24hLCBtczogMCwgc2tpcHBlZDogdHJ1ZSB9O1xuICAgIGVsc2Uge1xuICAgICAgbGV0IHRpbWVvdXRfID0gdC5vcHRpb25zPy50aW1lb3V0ID09PSBTVEFOREFSVF9USU1FT1VUICYmXG4gICAgICAgIGNhdGVnb3J5VGltZW91dCA/IGNhdGVnb3J5VGltZW91dCA6IHQub3B0aW9ucz8udGltZW91dCE7XG4gICAgICB0aW1lb3V0XyA9ICh0aW1lb3V0XyA9PT0gU1RBTkRBUlRfVElNRU9VVCAmJiBERy5UZXN0LmlzSW5CZW5jaG1hcmspID8gQkVOQ0hNQVJLX1RJTUVPVVQgOiB0aW1lb3V0XztcbiAgICAgIHIgPSB7IGRhdGU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwgc3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBhd2FpdCB0aW1lb3V0KHQudGVzdCwgdGltZW91dF8pID8/ICdPSycsIG1zOiAwLCBza2lwcGVkOiBmYWxzZSB9O1xuICAgIH1cbiAgfSBjYXRjaCAoeDogYW55KSB7XG4gICAgc3RkRXJyb3IoeCk7XG4gICAgciA9IHsgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLCBzdWNjZXNzOiBmYWxzZSwgcmVzdWx0OiBhd2FpdCBnZXRSZXN1bHQoeCksIG1zOiAwLCBza2lwcGVkOiBmYWxzZSB9O1xuICB9XG4gIGlmICh0Lm9wdGlvbnM/LmlzQWdncmVnYXRlZCAmJiByLnJlc3VsdC5jb25zdHJ1Y3RvciA9PT0gREcuRGF0YUZyYW1lKSB7XG4gICAgY29uc3QgY29sID0gci5yZXN1bHQuY29sKCdzdWNjZXNzJyk7XG4gICAgaWYgKGNvbClcbiAgICAgIHIuc3VjY2VzcyA9IGNvbC5zdGF0cy5zdW0gPT09IGNvbC5sZW5ndGg7XG4gICAgaWYgKCF2ZXJib3NlKSB7XG4gICAgICBjb25zdCBkZiA9IHIucmVzdWx0O1xuICAgICAgZGYuY29sdW1ucy5yZW1vdmUoJ3N0YWNrJyk7XG4gICAgICBkZi5yb3dzLnJlbW92ZVdoZXJlKChyKSA9PiByLmdldCgnc3VjY2VzcycpKTtcbiAgICAgIHIucmVzdWx0ID0gZGY7XG4gICAgfVxuICAgIHIucmVzdWx0ID0gci5yZXN1bHQudG9Dc3YoKTtcbiAgfVxuICByLmxvZ3MgPSBsb2dzLmpvaW4oJ1xcbicpO1xuICByLm1zID0gRGF0ZS5ub3coKSAtIHN0YXJ0O1xuICBpZiAoIXNraXApXG4gICAgc3RkTG9nKGBGaW5pc2hlZCAke3QuY2F0ZWdvcnl9ICR7dC5uYW1lfSBmb3IgJHtyLm1zfSBtc2ApO1xuICByLmNhdGVnb3J5ID0gdC5jYXRlZ29yeTtcbiAgci5uYW1lID0gdC5uYW1lO1xuICBpZiAoIWZpbHRlcikge1xuICAgIGxldCBwYXJhbXMgPSB7XG4gICAgICAnc3VjY2Vzcyc6IHIuc3VjY2VzcywgJ3Jlc3VsdCc6IHIucmVzdWx0LCAnbXMnOiByLm1zLFxuICAgICAgJ3NraXBwZWQnOiByLnNraXBwZWQsICdwYWNrYWdlJzogcGFja2FnZU5hbWUsICdjYXRlZ29yeSc6IHQuY2F0ZWdvcnksICduYW1lJzogdC5uYW1lLCAnbG9ncyc6IHIubG9ncyxcbiAgICB9O1xuICAgIGlmIChyLnJlc3VsdC5jb25zdHJ1Y3RvciA9PSBPYmplY3QpIHtcbiAgICAgIGNvbnN0IHJlcyA9IE9iamVjdC5rZXlzKHIucmVzdWx0KS5yZWR1Y2UoKGFjYywgaykgPT4gKHsgLi4uYWNjLCBbJ3Jlc3VsdC4nICsga106IHIucmVzdWx0W2tdIH0pLCB7fSk7XG4gICAgICBwYXJhbXMgPSB7IC4uLnBhcmFtcywgLi4ucmVzIH07XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5yZXN1bHQgaW5zdGFuY2VvZiBERy5EYXRhRnJhbWUpXG4gICAgICBwYXJhbXMucmVzdWx0ID0gSlNPTi5zdHJpbmdpZnkocGFyYW1zLnJlc3VsdD8udG9Kc29uKCkpIHx8ICcnO1xuXG4gICAgaWYgKCg8YW55Pmdyb2suc2hlbGwpLnJlcG9ydFRlc3QgIT0gbnVsbClcbiAgICAgIGF3YWl0ICg8YW55Pmdyb2suc2hlbGwpLnJlcG9ydFRlc3QodHlwZSwgcGFyYW1zKTtcbiAgICBlbHNlIHtcbiAgICAgIGF3YWl0IGZldGNoKGAke2dyb2suZGFwaS5yb290fS9sb2cvdGVzdHMvJHt0eXBlfWAsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBjcmVkZW50aWFsczogJ3NhbWUtb3JpZ2luJyxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkocGFyYW1zKVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2h1ZmZsZShhcnJheTogYW55W10pOiBhbnlbXSB7XG4gIGNvbnN0IG5ld0FyciA9IGFycmF5LnNsaWNlKCk7XG4gIG5ld0Fyci5zb3J0KCgpID0+IE1hdGgucmFuZG9tKCkgLSAwLjUpO1xuICByZXR1cm4gbmV3QXJyO1xufTtcblxuLyogV2FpdHMgW21zXSBtaWxsaXNlY29uZHMgKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWxheShtczogbnVtYmVyKSB7XG4gIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIG1zKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhd2FpdENoZWNrKGNoZWNrSGFuZGxlcjogKCkgPT4gYm9vbGVhbixcbiAgZXJyb3I6IHN0cmluZyA9ICdUaW1lb3V0IGV4Y2VlZGVkJywgd2FpdDogbnVtYmVyID0gNTAwLCBpbnRlcnZhbDogbnVtYmVyID0gNTApOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG4gICAgICByZWplY3QobmV3IEVycm9yKGVycm9yKSk7XG4gICAgfSwgd2FpdCk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGludGVydmFsSWQ6IFRpbWVvdXQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBpZiAoY2hlY2tIYW5kbGVyKCkpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbElkKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0sIGludGVydmFsKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgdGVzdCBleGVjdXRpb24gcmVzdWx0IG9yIGFuIGVycm9yIGluIGNhc2Ugb2YgdGltZW91dFxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRpbWVvdXQoZnVuYzogKCkgPT4gUHJvbWlzZTxhbnk+LCB0ZXN0VGltZW91dDogbnVtYmVyLCB0aW1lb3V0UmVhc29uOiBzdHJpbmcgPSAnRVhFQ1VUSU9OIFRJTUVPVVQnKTogUHJvbWlzZTxhbnk+IHtcbiAgbGV0IHRpbWVvdXQ6IGFueSA9IG51bGw7XG4gIGNvbnN0IHRpbWVvdXRQcm9taXNlID0gbmV3IFByb21pc2U8YW55PigoXywgcmVqZWN0KSA9PiB7XG4gICAgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1wcm9taXNlLXJlamVjdC1lcnJvcnNcbiAgICAgIHJlamVjdCh0aW1lb3V0UmVhc29uKTtcbiAgICB9LCB0ZXN0VGltZW91dCk7XG4gIH0pO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBQcm9taXNlLnJhY2UoW2Z1bmMoKSwgdGltZW91dFByb21pc2VdKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAodGltZW91dClcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNEaWFsb2dQcmVzZW50KGRpYWxvZ1RpdGxlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgZGlhbG9ncyA9IERHLkRpYWxvZy5nZXRPcGVuRGlhbG9ncygpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpYWxvZ3MubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZGlhbG9nc1tpXS50aXRsZSA9PSBkaWFsb2dUaXRsZSlcbiAgICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqIEV4cGVjdHMgYW4gYXN5bmNocm9ub3VzIHtAbGluayBhY3Rpb259IHRvIHRocm93IGFuIGV4Y2VwdGlvbi4gVXNlIHtAbGluayBjaGVja30gdG8gcGVyZm9ybVxuICogZGVlcGVyIGluc3BlY3Rpb24gb2YgdGhlIGV4Y2VwdGlvbiBpZiBuZWNlc3NhcnkuXG4gKiBAcGFyYW0gIHtmdW5jdGlvbigpOiBQcm9taXNlPHZvaWQ+fSBhY3Rpb25cbiAqIEBwYXJhbSAge2Z1bmN0aW9uKGFueSk6IGJvb2xlYW59IGNoZWNrXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXhwZWN0RXhjZXB0aW9uQXN5bmMoYWN0aW9uOiAoKSA9PiBQcm9taXNlPHZvaWQ+LFxuICBjaGVjaz86IChleGNlcHRpb246IGFueSkgPT4gYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICBsZXQgY2F1Z2h0OiBib29sZWFuID0gZmFsc2U7XG4gIGxldCBjaGVja2VkOiBib29sZWFuID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgYXdhaXQgYWN0aW9uKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjYXVnaHQgPSB0cnVlO1xuICAgIGNoZWNrZWQgPSAhY2hlY2sgfHwgY2hlY2soZSk7XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKCFjYXVnaHQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FuIGV4Y2VwdGlvbiBpcyBleHBlY3RlZCBidXQgbm90IHRocm93bicpO1xuICAgIGlmICghY2hlY2tlZClcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW4gZXhwZWN0ZWQgZXhjZXB0aW9uIGlzIHRocm93biwgYnV0IGl0IGRvZXMgbm90IHNhdGlzZnkgdGhlIGNvbmRpdGlvbicpO1xuICB9XG59XG5cbmNvbnN0IGNhdERGID0gREcuRGF0YUZyYW1lLmZyb21Db2x1bW5zKFtERy5Db2x1bW4uZnJvbVN0cmluZ3MoJ2NvbCcsIFsndmFsMScsICd2YWwyJywgJ3ZhbDMnXSldKTtcblxuLyoqXG4gKiBVbml2ZXJzYWwgdGVzdCBmb3Igdmlld2Vycy4gSXQgc2VhcmNoIHZpZXdlcnMgaW4gRE9NIGJ5IHRhZ3M6IGNhbnZhcywgc3ZnLCBpbWcsIGlucHV0LCBoMSwgYVxuICogQHBhcmFtICB7c3RyaW5nfSB2IFZpZXdlciBuYW1lXG4gKiBAcGFyYW0gIHtERy5EYXRhRnJhbWV9IGRmIERhdGFmcmFtZSB0byB1c2UuIFNob3VsZCBoYXZlIGF0IGxlYXN0IDMgcm93c1xuICogQHBhcmFtICB7Ym9vbGVhbn0gb3B0aW9ucy5kZXRlY3RTZW1hbnRpY1R5cGVzIFNwZWNpZnkgd2hldGhlciB0byBkZXRlY3Qgc2VtYW50aWMgdHlwZXMgb3Igbm90XG4gKiBAcGFyYW0gIHtib29sZWFufSBvcHRpb25zLnJlYWRPbmx5IElmIHNldCB0byB0cnVlLCB0aGUgZGF0YWZyYW1lIHdpbGwgbm90IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgdGVzdFxuICogQHBhcmFtICB7Ym9vbGVhbn0gb3B0aW9ucy5hcmJpdHJhcnlEZlRlc3QgSWYgc2V0IHRvIGZhbHNlLCB0ZXN0IG9uIGFyYml0cmFyeSBkYXRhZnJhbWVcbiAqIChvbmUgY2F0ZWdvcmljYWwgY29sdW1uKSB3aWxsIG5vdCBiZSBwZXJmb3JtZWRcbiAqIEBwYXJhbSAge29iamVjdH0gb3B0aW9ucyBMaXN0IG9mIG9wdGlvbnMgKG9wdGlvbmFsKVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gVGhlIHRlc3QgaXMgY29uc2lkZXJlZCBzdWNjZXNzZnVsIGlmIGl0IGNvbXBsZXRlcyB3aXRob3V0IGVycm9yc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdGVzdFZpZXdlcih2OiBzdHJpbmcsIGRmOiBERy5EYXRhRnJhbWUsIG9wdGlvbnM/OiB7XG4gIGRldGVjdFNlbWFudGljVHlwZXM/OiBib29sZWFuLCByZWFkT25seT86IGJvb2xlYW4sIGFyYml0cmFyeURmVGVzdD86IGJvb2xlYW4sXG4gIHBhY2thZ2VOYW1lPzogc3RyaW5nLCBhd2FpdFZpZXdlcj86ICh2aWV3ZXI6IERHLlZpZXdlcikgPT4gUHJvbWlzZTx2b2lkPlxufSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwYWNrYWdlTmFtZSA9IG9wdGlvbnM/LnBhY2thZ2VOYW1lID8/ICcnO1xuICBpZiAob3B0aW9ucz8uZGV0ZWN0U2VtYW50aWNUeXBlcylcbiAgICBhd2FpdCBncm9rLmRhdGEuZGV0ZWN0U2VtYW50aWNUeXBlcyhkZik7XG4gIGNvbnN0IHR2ID0gZ3Jvay5zaGVsbC5hZGRUYWJsZVZpZXcoZGYpO1xuXG4gIHRyeSB7XG4gICAgLy8xLiBPcGVuLCBkbyBub3RoaW5nIGFuZCBjbG9zZVxuICAgIGF3YWl0IHRlc3RWaWV3ZXJJbnRlcm5hbCh0diwgdiwgcGFja2FnZU5hbWUsIGdyb2suZXZlbnRzLm9uVmlld2VyQWRkZWQpO1xuICAgIC8vaW4gY2FzZSB2aWV3ZXIgd2l0aCBhc3luYyByZW5kZXJpbmcgLSB3YWl0IGZvciByZW5kZXIgdG8gY29tcGxldGVcbiAgICBpZiAob3B0aW9ucz8uYXdhaXRWaWV3ZXIpXG4gICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCB1bmRlZmluZWQsIG9wdGlvbnMhLmF3YWl0Vmlld2VyKTtcblxuICAgIC8vMi4gT3BlbiB2aWV3ZXIsIHJ1biBzZWxlY3Rpb24sIGZpbHRlciwgZXRjLiBhbmQgY2xvc2VcbiAgICBpZiAoIW9wdGlvbnM/LnJlYWRPbmx5KSB7XG4gICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCBzZWxlY3RGaWx0ZXJDaGFuZ2VDdXJyZW50KTtcbiAgICAgIGlmIChvcHRpb25zPy5hd2FpdFZpZXdlcilcbiAgICAgICAgYXdhaXQgdGVzdFZpZXdlckludGVybmFsKHR2LCB2LCBwYWNrYWdlTmFtZSwgZ3Jvay5ldmVudHMub25WaWV3ZXJBZGRlZCwgc2VsZWN0RmlsdGVyQ2hhbmdlQ3VycmVudCwgb3B0aW9ucyEuYXdhaXRWaWV3ZXIpO1xuICAgIH1cblxuICAgIC8vMi4gT3BlbiB2aWV3ZXIsIGNoYW5nZSBvcHRpb25zLCBzYXZlIGxheW91dCBhbmQgY2xvc2VcbiAgICBsZXQgcHJvcHNBbmRMYXlvdXQ6IHsgbGF5b3V0OiBhbnksIHNhdmVkUHJvcHM6IGFueSB9IHwgbnVsbCA9IG51bGw7XG4gICAgcHJvcHNBbmRMYXlvdXQgPSBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCBjaGFuZ2VPcHRpb25zU2F2ZUxheW91dCk7XG4gICAgaWYgKG9wdGlvbnM/LmF3YWl0Vmlld2VyKVxuICAgICAgcHJvcHNBbmRMYXlvdXQgPSBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLFxuICAgICAgICBjaGFuZ2VPcHRpb25zU2F2ZUxheW91dCwgb3B0aW9ucyEuYXdhaXRWaWV3ZXIpXG5cbiAgICAvLzMuIExvYWQgbGF5b3V0XG4gICAgYXdhaXQgdGVzdFZpZXdlckludGVybmFsKHR2LCB2LCBwYWNrYWdlTmFtZSwgZ3Jvay5ldmVudHMub25WaWV3TGF5b3V0QXBwbGllZCwgbG9hZExheW91dCwgdW5kZWZpbmVkLCBwcm9wc0FuZExheW91dD8ubGF5b3V0LFxuICAgICAgeyBzYXZlZFByb3BzOiBwcm9wc0FuZExheW91dD8uc2F2ZWRQcm9wcyB9KTtcbiAgICBpZiAob3B0aW9ucz8uYXdhaXRWaWV3ZXIpXG4gICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdMYXlvdXRBcHBsaWVkLCBsb2FkTGF5b3V0LCBvcHRpb25zIS5hd2FpdFZpZXdlcixcbiAgICAgICAgcHJvcHNBbmRMYXlvdXQ/LmxheW91dCwgeyBzYXZlZFByb3BzOiBwcm9wc0FuZExheW91dD8uc2F2ZWRQcm9wcyB9KTtcblxuICAgIC8vNC4gT3BlbiB2aWV3ZXIgb24gYXJiaXRhcnkgZGF0YXNldFxuICAgIGlmIChvcHRpb25zPy5hcmJpdHJhcnlEZlRlc3QgIT09IGZhbHNlKSB7XG4gICAgICB0di5kYXRhRnJhbWUgPSBjYXRERjtcbiAgICAgIGF3YWl0IGRlbGF5KDUwKTtcbiAgICAgIGF3YWl0IHRlc3RWaWV3ZXJJbnRlcm5hbCh0diwgdiwgcGFja2FnZU5hbWUsIGdyb2suZXZlbnRzLm9uVmlld2VyQWRkZWQpO1xuICAgICAgaWYgKG9wdGlvbnM/LmF3YWl0Vmlld2VyKVxuICAgICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCB1bmRlZmluZWQsIG9wdGlvbnMhLmF3YWl0Vmlld2VyKTtcbiAgICB9XG5cbiAgICAvLzUuIENhbGwgcG9zdHBvbmVkIGZpbHRlcmluZ1xuICAgIGF3YWl0IHRlc3RWaWV3ZXJJbnRlcm5hbCh0diwgdiwgcGFja2FnZU5hbWUsIGdyb2suZXZlbnRzLm9uVmlld2VyQWRkZWQsIGZpbHRlckFzeW5jKTtcbiAgICBpZiAob3B0aW9ucz8uYXdhaXRWaWV3ZXIpXG4gICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCBmaWx0ZXJBc3luYywgb3B0aW9ucyEuYXdhaXRWaWV3ZXIpO1xuXG4gIH0gZmluYWxseSB7XG4gICAgLy8gY2xvc2VBbGwoKSBpcyBoYW5kbGluZyBieSBjb21tb24gdGVzdCB3b3JrZmxvd1xuICAgIC8vIGdyb2suc2hlbGwuY2xvc2VBbGwoKTtcbiAgICAvLyBERy5CYWxsb29uLmNsb3NlQWxsKCk7XG4gIH1cbn1cbiJdfQ==","export var DimReductionMethods;\n(function (DimReductionMethods) {\n DimReductionMethods[\"UMAP\"] = \"UMAP\";\n DimReductionMethods[\"T_SNE\"] = \"t-SNE\";\n})(DimReductionMethods || (DimReductionMethods = {}));\n;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSxtQkFHWDtBQUhELFdBQVksbUJBQW1CO0lBQzNCLG9DQUFhLENBQUE7SUFDYixzQ0FBZSxDQUFBO0FBQ25CLENBQUMsRUFIVyxtQkFBbUIsS0FBbkIsbUJBQW1CLFFBRzlCO0FBQUEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIERpbVJlZHVjdGlvbk1ldGhvZHN7XG4gICAgVU1BUCA9ICdVTUFQJyxcbiAgICBUX1NORSA9ICd0LVNORSdcbn07XG4iXX0=","export var StringMetricsNames;\n(function (StringMetricsNames) {\n StringMetricsNames[\"Levenshtein\"] = \"Levenshtein\";\n StringMetricsNames[\"JaroWinkler\"] = \"Jaro-Winkler\";\n StringMetricsNames[\"Manhattan\"] = \"Manhattan\";\n StringMetricsNames[\"Onehot\"] = \"One-Hot\";\n})(StringMetricsNames || (StringMetricsNames = {}));\nexport var VectorMetricsNames;\n(function (VectorMetricsNames) {\n VectorMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(VectorMetricsNames || (VectorMetricsNames = {}));\nexport var BitArrayMetricsNames;\n(function (BitArrayMetricsNames) {\n BitArrayMetricsNames[\"Tanimoto\"] = \"Tanimoto\";\n BitArrayMetricsNames[\"Dice\"] = \"Dice\";\n BitArrayMetricsNames[\"Asymmetric\"] = \"Asymmetric\";\n BitArrayMetricsNames[\"BraunBlanquet\"] = \"Braun-Blanquet\";\n BitArrayMetricsNames[\"Cosine\"] = \"Cosine\";\n BitArrayMetricsNames[\"Kulczynski\"] = \"Kulczynski\";\n BitArrayMetricsNames[\"McConnaughey\"] = \"Mc-Connaughey\";\n BitArrayMetricsNames[\"RogotGoldberg\"] = \"Rogot-Goldberg\";\n BitArrayMetricsNames[\"Russel\"] = \"Russel\";\n BitArrayMetricsNames[\"Sokal\"] = \"Sokal\";\n BitArrayMetricsNames[\"Hamming\"] = \"Hamming\";\n BitArrayMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(BitArrayMetricsNames || (BitArrayMetricsNames = {}));\nexport var IntArrayMetricsNames;\n(function (IntArrayMetricsNames) {\n IntArrayMetricsNames[\"TanimotoIntArray\"] = \"TanimotoIntArray\";\n})(IntArrayMetricsNames || (IntArrayMetricsNames = {}));\nexport var DistanceMetricsSubjects;\n(function (DistanceMetricsSubjects) {\n DistanceMetricsSubjects[\"Vector\"] = \"Vector\";\n DistanceMetricsSubjects[\"String\"] = \"String\";\n DistanceMetricsSubjects[\"BitArray\"] = \"BitArray\";\n DistanceMetricsSubjects[\"MacroMolecule\"] = \"MacroMolecule\";\n DistanceMetricsSubjects[\"Number\"] = \"Number\";\n DistanceMetricsSubjects[\"IntArray\"] = \"IntArray\";\n DistanceMetricsSubjects[\"NumberArray\"] = \"NumberArray\";\n})(DistanceMetricsSubjects || (DistanceMetricsSubjects = {}));\nexport var NumberMetricsNames;\n(function (NumberMetricsNames) {\n NumberMetricsNames[\"Difference\"] = \"Difference\";\n})(NumberMetricsNames || (NumberMetricsNames = {}));\nexport var NumberArrayMetricsNames;\n(function (NumberArrayMetricsNames) {\n NumberArrayMetricsNames[\"CommonItems\"] = \"Common Items\";\n})(NumberArrayMetricsNames || (NumberArrayMetricsNames = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBTixJQUFZLGtCQUtUO0FBTEgsV0FBWSxrQkFBa0I7SUFDMUIsaURBQTJCLENBQUE7SUFDM0Isa0RBQTRCLENBQUE7SUFDNUIsNkNBQXVCLENBQUE7SUFDdkIsd0NBQWtCLENBQUE7QUFDcEIsQ0FBQyxFQUxTLGtCQUFrQixLQUFsQixrQkFBa0IsUUFLM0I7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFVDtBQUZILFdBQVksa0JBQWtCO0lBQzFCLDZDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFGUyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTNCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBYVQ7QUFiSCxXQUFZLG9CQUFvQjtJQUM1Qiw2Q0FBcUIsQ0FBQTtJQUNyQixxQ0FBYSxDQUFBO0lBQ2IsaURBQXlCLENBQUE7SUFDekIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsaURBQXlCLENBQUE7SUFDekIsc0RBQThCLENBQUE7SUFDOUIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsdUNBQWUsQ0FBQTtJQUNmLDJDQUFtQixDQUFBO0lBQ25CLCtDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFiUyxvQkFBb0IsS0FBcEIsb0JBQW9CLFFBYTdCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBRVg7QUFGRCxXQUFZLG9CQUFvQjtJQUM5Qiw2REFBcUMsQ0FBQTtBQUN2QyxDQUFDLEVBRlcsb0JBQW9CLEtBQXBCLG9CQUFvQixRQUUvQjtBQUVELE1BQU0sQ0FBTixJQUFZLHVCQVFUO0FBUkgsV0FBWSx1QkFBdUI7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7SUFDckIsMERBQStCLENBQUE7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7SUFDckIsc0RBQTJCLENBQUE7QUFDN0IsQ0FBQyxFQVJTLHVCQUF1QixLQUF2Qix1QkFBdUIsUUFRaEM7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFWDtBQUZELFdBQVksa0JBQWtCO0lBQzVCLCtDQUF5QixDQUFBO0FBQzNCLENBQUMsRUFGVyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTdCO0FBRUQsTUFBTSxDQUFOLElBQVksdUJBRVg7QUFGRCxXQUFZLHVCQUF1QjtJQUNqQyx1REFBNEIsQ0FBQTtBQUM5QixDQUFDLEVBRlcsdUJBQXVCLEtBQXZCLHVCQUF1QixRQUVsQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIFN0cmluZ01ldHJpY3NOYW1lcyB7XG4gICAgTGV2ZW5zaHRlaW4gPSAnTGV2ZW5zaHRlaW4nLFxuICAgIEphcm9XaW5rbGVyID0gJ0phcm8tV2lua2xlcicsXG4gICAgTWFuaGF0dGFuID0gJ01hbmhhdHRhbicsXG4gICAgT25laG90ID0gJ09uZS1Ib3QnLFxuICB9XG5cbmV4cG9ydCBlbnVtIFZlY3Rvck1ldHJpY3NOYW1lcyB7XG4gICAgRXVjbGlkZWFuID0gJ0V1Y2xpZGVhbicsXG4gIH1cblxuZXhwb3J0IGVudW0gQml0QXJyYXlNZXRyaWNzTmFtZXMge1xuICAgIFRhbmltb3RvID0gJ1Rhbmltb3RvJyxcbiAgICBEaWNlID0gJ0RpY2UnLFxuICAgIEFzeW1tZXRyaWMgPSAnQXN5bW1ldHJpYycsXG4gICAgQnJhdW5CbGFucXVldCA9ICdCcmF1bi1CbGFucXVldCcsXG4gICAgQ29zaW5lID0gJ0Nvc2luZScsXG4gICAgS3VsY3p5bnNraSA9ICdLdWxjenluc2tpJyxcbiAgICBNY0Nvbm5hdWdoZXkgPSAnTWMtQ29ubmF1Z2hleScsXG4gICAgUm9nb3RHb2xkYmVyZyA9ICdSb2dvdC1Hb2xkYmVyZycsXG4gICAgUnVzc2VsID0gJ1J1c3NlbCcsXG4gICAgU29rYWwgPSAnU29rYWwnLFxuICAgIEhhbW1pbmcgPSAnSGFtbWluZycsXG4gICAgRXVjbGlkZWFuID0gJ0V1Y2xpZGVhbicsXG4gIH1cblxuZXhwb3J0IGVudW0gSW50QXJyYXlNZXRyaWNzTmFtZXMge1xuICBUYW5pbW90b0ludEFycmF5ID0gJ1Rhbmltb3RvSW50QXJyYXknLFxufVxuXG5leHBvcnQgZW51bSBEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cyB7XG4gICAgVmVjdG9yID0gJ1ZlY3RvcicsXG4gICAgU3RyaW5nID0gJ1N0cmluZycsXG4gICAgQml0QXJyYXkgPSAnQml0QXJyYXknLFxuICAgIE1hY3JvTW9sZWN1bGUgPSAnTWFjcm9Nb2xlY3VsZScsXG4gICAgTnVtYmVyID0gJ051bWJlcicsXG4gICAgSW50QXJyYXkgPSAnSW50QXJyYXknLFxuICAgIE51bWJlckFycmF5ID0gJ051bWJlckFycmF5JyxcbiAgfVxuXG5leHBvcnQgZW51bSBOdW1iZXJNZXRyaWNzTmFtZXMge1xuICBEaWZmZXJlbmNlID0gJ0RpZmZlcmVuY2UnLFxufVxuXG5leHBvcnQgZW51bSBOdW1iZXJBcnJheU1ldHJpY3NOYW1lcyB7XG4gIENvbW1vbkl0ZW1zID0gJ0NvbW1vbiBJdGVtcycsXG59XG4iXX0=","const peq = new Uint32Array(0x10000);\nconst myers_32 = (a, b) => {\n const n = a.length;\n const m = b.length;\n const lst = 1 << (n - 1);\n let pv = -1;\n let mv = 0;\n let sc = n;\n let i = n;\n while (i--) {\n peq[a.charCodeAt(i)] |= 1 << i;\n }\n for (i = 0; i < m; i++) {\n let eq = peq[b.charCodeAt(i)];\n const xv = eq | mv;\n eq |= ((eq & pv) + pv) ^ pv;\n mv |= ~(eq | pv);\n pv &= eq;\n if (mv & lst) {\n sc++;\n }\n if (pv & lst) {\n sc--;\n }\n mv = (mv << 1) | 1;\n pv = (pv << 1) | ~(xv | mv);\n mv &= xv;\n }\n i = n;\n while (i--) {\n peq[a.charCodeAt(i)] = 0;\n }\n return sc;\n};\nconst myers_x = (b, a) => {\n const n = a.length;\n const m = b.length;\n const mhc = [];\n const phc = [];\n const hsize = Math.ceil(n / 32);\n const vsize = Math.ceil(m / 32);\n for (let i = 0; i < hsize; i++) {\n phc[i] = -1;\n mhc[i] = 0;\n }\n let j = 0;\n for (; j < vsize - 1; j++) {\n let mv = 0;\n let pv = -1;\n const start = j * 32;\n const vlen = Math.min(32, m) + start;\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] |= 1 << k;\n }\n for (let i = 0; i < n; i++) {\n const eq = peq[a.charCodeAt(i)];\n const pb = (phc[(i / 32) | 0] >>> i) & 1;\n const mb = (mhc[(i / 32) | 0] >>> i) & 1;\n const xv = eq | mv;\n const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;\n let ph = mv | ~(xh | pv);\n let mh = pv & xh;\n if ((ph >>> 31) ^ pb) {\n phc[(i / 32) | 0] ^= 1 << i;\n }\n if ((mh >>> 31) ^ mb) {\n mhc[(i / 32) | 0] ^= 1 << i;\n }\n ph = (ph << 1) | pb;\n mh = (mh << 1) | mb;\n pv = mh | ~(xv | ph);\n mv = ph & xv;\n }\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] = 0;\n }\n }\n let mv = 0;\n let pv = -1;\n const start = j * 32;\n const vlen = Math.min(32, m - start) + start;\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] |= 1 << k;\n }\n let score = m;\n for (let i = 0; i < n; i++) {\n const eq = peq[a.charCodeAt(i)];\n const pb = (phc[(i / 32) | 0] >>> i) & 1;\n const mb = (mhc[(i / 32) | 0] >>> i) & 1;\n const xv = eq | mv;\n const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;\n let ph = mv | ~(xh | pv);\n let mh = pv & xh;\n score += (ph >>> (m - 1)) & 1;\n score -= (mh >>> (m - 1)) & 1;\n if ((ph >>> 31) ^ pb) {\n phc[(i / 32) | 0] ^= 1 << i;\n }\n if ((mh >>> 31) ^ mb) {\n mhc[(i / 32) | 0] ^= 1 << i;\n }\n ph = (ph << 1) | pb;\n mh = (mh << 1) | mb;\n pv = mh | ~(xv | ph);\n mv = ph & xv;\n }\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] = 0;\n }\n return score;\n};\nconst distance = (a, b) => {\n if (a.length < b.length) {\n const tmp = b;\n b = a;\n a = tmp;\n }\n if (b.length === 0) {\n return a.length;\n }\n if (a.length <= 32) {\n return myers_32(a, b);\n }\n return myers_x(a, b);\n};\nconst closest = (str, arr) => {\n let min_distance = Infinity;\n let min_index = 0;\n for (let i = 0; i < arr.length; i++) {\n const dist = distance(str, arr[i]);\n if (dist < min_distance) {\n min_distance = dist;\n min_index = i;\n }\n }\n return arr[min_index];\n};\nexport { closest, distance };\n","export default class BitArray {\n constructor(arg, defaultValue = false) {\n this._length = 0;\n this._version = 0;\n this._updateLevel = 0;\n this._selectedCount = 0;\n this._selectedCountVersion = -1;\n this._selectedIndexesVersion = -1;\n this._versionedName = '';\n this._versionedNameVersion = -1;\n this.SHRINK_THRESHOLD = 0x100;\n if (typeof arg === 'number') {\n const length = arg;\n const buff = BitArray._createBuffer(length);\n if (defaultValue) {\n for (let i = 0; i < buff.length; i++)\n buff[i] = -1;\n }\n this._data = buff;\n this._length = length;\n }\n else if (arg instanceof Uint32Array) {\n this._data = arg;\n this._length = defaultValue;\n }\n else {\n throw new Error('Invalid constructor');\n }\n }\n getRawData() { return this._data; }\n assureGoez(num, argName) {\n if (num < 0)\n throw new Error(`${argName} should be greater than zero`);\n }\n assureInRange(value, min, max, argName) {\n if ((value < min) || (value > max))\n throw new Error(`Argument ${argName} (${value}) out of range (${min}, ${max})`);\n }\n copy(src, dst, count) {\n for (let i = 0; i < count; i++)\n dst[i] = src[i];\n }\n copyFrom(other) {\n if (this._length != other._length)\n throw new Error(`Lengths differ (${this._length} != ${other._length})`);\n this.copy(other._data, this._data, this.lengthInInts);\n this._version++;\n }\n get length() {\n return this._length;\n }\n get buffer() {\n return this._data;\n }\n set buffer(data) {\n this._data = data;\n this._version++;\n }\n get version() {\n return this._version;\n }\n set version(value) {\n this._version = value;\n }\n incrementVersion(notify = true) {\n this._version++;\n }\n get lengthInInts() {\n return Math.floor((this._length + 0x1f) / 0x20);\n }\n get versionedName() {\n return this._version == this._versionedNameVersion ? this._versionedName : '';\n }\n set versionedName(name) {\n this._versionedName = name;\n this._versionedNameVersion = this._version;\n }\n get self() {\n return this;\n }\n setLength(value) {\n if (value < 0)\n throw new Error('should be >= 0');\n if (value == this._length)\n return;\n const nIntsNeeded = Math.floor((value + 0x1f) / 0x20);\n if ((nIntsNeeded > this._data.length) || ((nIntsNeeded + this.SHRINK_THRESHOLD) < this._data.length)) {\n const newData = new Uint32Array(nIntsNeeded);\n this.copy(this._data, newData, (nIntsNeeded > this._data.length) ? this._data.length : nIntsNeeded);\n this._data = newData;\n }\n if (value > this._length) {\n if (this._length % 0x20 > 0)\n this._data[this.lengthInInts - 1] &= (1 << ((this._length % 0x20) & 0x1f)) - 1;\n this._data.fill(0, this.lengthInInts, nIntsNeeded);\n }\n this._length = value;\n this._version++;\n }\n static fromAnd(set1, set2) {\n if (set1._length != set2._length)\n throw new Error(`Lengths differ (${set1._length} != ${set2._length})`);\n const temp = new BitArray(set1._length);\n temp._length = set1._length;\n temp._data = BitArray._createBuffer(temp._length);\n temp._version = 0;\n const len = set1.lengthInInts;\n for (let i = 0; i < len; i++)\n temp._data[i] = set1._data[i] & set2._data[i];\n return temp;\n }\n static _createBuffer(length) {\n return new Uint32Array(Math.floor((length + 0x1f) / 0x20));\n }\n static fromValues(values) {\n const temp = new BitArray(values.length);\n temp._version = 0;\n for (let i = 0; i < temp._length; i++) {\n if (values[i])\n temp._data[Math.floor(i / 0x20)] |= 1 << ((i % 0x20) & 0x1f);\n }\n return temp;\n }\n /// Constructs a [BitSet] of length [count], where idx-th bit is determined by a call to [flag] (idx).\n static fromSeq(count, flag) {\n const temp = new BitArray(count);\n for (let i = 0; i < count; ++i)\n temp.setBit(i, flag(i));\n temp._version = 0;\n return temp;\n }\n /// Constructs a [BitSet] from a string [s] containing '0' or '1'.\n static fromString(s) {\n return BitArray.fromSeq(s.length, (i) => s.charAt(i) == '1');\n }\n /// Constructs a [BitSet], based on length [_length] and byte array [_data].\n static fromUint32Array(_length, _data) {\n const temp = new BitArray(_length);\n temp._data = _data;\n return temp;\n }\n /// Deserializes a [BitSet] from [bytes].\n static fromBytes(bytes) {\n const len = bytes.length;\n const temp = new BitArray(len * 8);\n temp._data = new Uint32Array(Math.floor((len + 3) / 4));\n temp._length = len * 8;\n let num1 = 0;\n let num2 = 0;\n while ((len - num2) >= 4) {\n temp._data[num1++] = (((bytes[num2] & 0xff) | ((bytes[num2 + 1] & 0xff) << 8)) |\n ((bytes[num2 + 2] & 0xff) << 0x10)) | ((bytes[num2 + 3] & 0xff) << 0x18);\n num2 += 4;\n }\n if (len - num2 == 3)\n temp._data[num1] = (bytes[num2 + 2] & 0xff) << 0x10;\n if (len - num2 == 2)\n temp._data[num1] |= (bytes[num2 + 1] & 0xff) << 8;\n if (len - num2 == 1)\n temp._data[num1] |= bytes[num2] & 0xff;\n temp._version = 0;\n return temp;\n }\n toString() {\n return `${this._length} bits, ${this.countBits(true)} set`;\n }\n /// Performs deep comparison of two bitsets.\n equals(other) {\n if (this == other)\n return true;\n if (other == null)\n return false;\n if (this._length != other._length)\n return false;\n if (this._length == 0)\n return true;\n for (let i = 0; i < this._data.length - 1; i++)\n if (this._data[i] != other._data[i])\n return false;\n for (let i = (this._data.length - 1) * 8; i < this._length; i++) {\n if (this.getBit(i) != other.getBit(i))\n return false;\n }\n return true;\n }\n /** Clones a bitset. */\n clone() {\n const bitArray = new BitArray(0, false);\n bitArray._data = Uint32Array.from(this._data); // effective length: (lengthInInts)\n bitArray._length = this._length;\n bitArray._version = this._version;\n return bitArray;\n }\n /** Initializes a bitset. */\n init(flag, notify) {\n this.setAll(false, false);\n for (let i = 0; i < this._length; i++) {\n if (flag(i))\n this._data[Math.floor(i / 0x20)] |= 1 << ((i % 0x20) & 0x1f);\n }\n this.incrementVersion(notify);\n return this;\n }\n /// Inverts a bitset.\n invert(notify = true) {\n for (let i = 0; i < this._data.length; i++)\n this._data[i] ^= -1;\n this.incrementVersion(notify);\n }\n /// Sets all bits to [value], optionally suppressing notifications.\n setAll(value, notify = false) {\n const flags = value ? -1 : 0;\n const len = this.lengthInInts;\n for (let i = 0; i < len; i++) //todo: optimize\n this._data[i] = flags;\n this.incrementVersion(notify);\n }\n /// Sets bits at [indexes] position to [value].\n /// Clears the bitset if [clear] flag is true.\n /// Change notification is raised when [notify] is true.\n setIndexes(indexes, value = true, clear = true, notify = true) {\n if (clear)\n this.setAll(!value, false);\n for (const i of indexes)\n this.setFast(i, value);\n this.incrementVersion(notify);\n }\n everyIndex(indexes, value = true) {\n for (const index of indexes) {\n if (this.getBit(index) != value)\n return false;\n }\n return true;\n }\n anyIndex(indexes, value = true) {\n for (const index of indexes) {\n if (this.getBit(index) == value)\n return true;\n }\n return false;\n }\n setWhere(check, value = true, clear = true, notify = true, allowClear = true) {\n if (clear && allowClear)\n this.setAll(!value, false);\n if (allowClear) {\n for (let i = 0; i < this._length; i++) {\n if (check(i))\n this.setFast(i, value);\n }\n }\n else {\n for (let i = 0; i < this._length; i++)\n this.setFast(i, check(i) ? value : !value);\n }\n this.incrementVersion(notify);\n }\n getRange(from, to) {\n this.assureInRange(from, 0, this._length - 1, 'from');\n this.assureInRange(to, 0, this._length, 'to');\n const arr = [];\n for (let i = from; i < to; ++i)\n arr.push(this.getBit(i));\n return BitArray.fromValues(arr);\n }\n getRangeAsList(from, to) {\n this.assureInRange(from, 0, this._length - 1, 'from');\n this.assureInRange(to, 0, this._length, 'to');\n const arr = [];\n for (let i = from; i < to; ++i)\n arr.push(this.getBit(i));\n return arr;\n }\n setRange(from, to, value, notify = true) {\n this.assureInRange(from, 0, this._length - 1, 'from');\n this.assureInRange(to, 0, this._length - 1, 'to');\n const start = Math.min(from, to);\n const end = Math.max(from, to);\n //todo: optimize\n if (value) {\n for (let i = start; i <= end; i++)\n this.setTrue(i);\n }\n else {\n for (let i = start; i <= end; i++)\n this.setFalse(i);\n }\n this.incrementVersion(notify);\n return this;\n }\n /// Sets n randomly chosen bits to value, remaining bits to !value.\n setRandom(n, value, notify = true) {\n if (n < 0 || n > this._length)\n throw new Error('n must be >= 0 && <= Count');\n if (n > this._length / 2)\n this.setRandom(this._length - n, !value);\n this.setAll(!value);\n for (let k = 0; k < n;) {\n const i = Math.floor(Math.random() * this._length);\n if (this.getBit(i) == value)\n continue;\n this.setFast(i, value);\n k++;\n }\n this.incrementVersion(notify);\n }\n /// Modifies current bitset by performing the bitwise AND operation against the\n /// corresponding elements in the specified bitset.\n and(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] &= value._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Performs the bitwise AND NOT operation on the elements in the current bitset\n /// against the corresponding elements in the specified bitset.\n andNot(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n const len = this.lengthInInts;\n for (let num2 = 0; num2 < len; num2++)\n this._data[num2] &= ~value._data[num2];\n this.incrementVersion(notify);\n return this;\n }\n /// Performs the bitwise NOT AND operation on the elements in the current bitset\n /// against the corresponding elements in the specified bitset.\n notAnd(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] = (~this._data[i]) & value._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Inverts all bit values in the current bitset\n not(notify = true) {\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] = ~this._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Performs the bitwise OR operation on the elements in the current bitset\n /// against the corresponding elements in the specified bitset.\n or(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] |= value._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Performs the bitwise exclusive OR operation on the elements in the current bitset\n /// against the corresponding elements in the specified bitset.\n xor(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] ^= value._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Inserts n 0-bits at position pos, resizing self and shifting bits appropriately.\n insertAt(pos, n, flag = false) {\n this.assureInRange(pos, 0, this._length, 'pos');\n if (n == 0)\n return;\n //TODO: optimize\n //the most primitive implementation, optimize it later!\n // beginUpdate();\n const oldlength = this._length;\n this.setLength(this._length + n);\n //if (!contains(!flag)) return; // nothing to do\n for (let i = oldlength - 1; i >= pos; i--)\n this.setBit(i + n, this.getBit(i));\n for (let i = pos; i < pos + n; i++)\n this.setBit(i, flag);\n // endUpdate();\n }\n /// Deletes n bits beginning at position pos, resizing self and shifting remaining\n /// bits appropriately.\n removeAt(pos, n = 1) {\n // the most primitive implementation, optimize it later!\n if (n < 0)\n throw new Error('n cannot be negative');\n this.assureInRange(pos, 0, this._length - n, 'pos');\n if (this.contains(true)) {\n for (let i = pos; i < this._length - n; i++)\n this.setBit(i, this.getBit(i + n));\n }\n this.setLength(this._length - n);\n }\n removeByMask(mask, flag = true) {\n if (this._length != mask.length)\n throw new Error('length != mask.length');\n if (mask == this) { // no need to iterate\n this.setLength(mask.countBits(!flag));\n this.setAll(!flag);\n }\n else {\n let dstIdx = 0;\n for (let srcIdx = -1; (srcIdx = mask.findNext(srcIdx, !flag)) != -1;)\n this.setFast(dstIdx++, this.getBit(srcIdx));\n this._length = dstIdx;\n this._version++;\n }\n return this;\n }\n /// Similar to the [] operator.\n getBit(pos) {\n return (this._data[Math.floor(pos / 0x20)] & (1 << (pos & 0x1f))) != 0;\n }\n /// Similar to the [] operator.\n setBit(pos, bit, notify = true) {\n this.setFast(pos, bit);\n if (notify)\n this._version++;\n else\n this._version++;\n }\n /// Sets [i]-th bit to [value], does not check bounds, does not increment version\n setFast(i, value) {\n if (value)\n this._data[Math.floor(i / 0x20)] |= 1 << (i & 0x1f);\n else\n this._data[Math.floor(i / 0x20)] &= ~(1 << (i & 0x1f));\n }\n setTrue(pos) {\n this._data[Math.floor(pos / 0x20)] |= 1 << (pos & 0x1f);\n }\n setFalse(pos) {\n this._data[Math.floor(pos / 0x20)] &= ~(1 << (pos & 0x1f));\n }\n trueCount() {\n return this.countBits(true);\n }\n falseCount() {\n return this.countBits(false);\n }\n /// Counts bits of the specified value.\n countBits(value) {\n if (this._length == 0)\n return 0;\n if (this._selectedCountVersion != this._version) {\n this._selectedCount = 0;\n const len = this.lengthInInts;\n let i = 0;\n for (; i < len - 1; i++) {\n for (let k = this._data[i]; k != 0; k >>>= 8) { //todo: cast data[i] to uint\n this._selectedCount += BitArray._onBitCount[k & 0xff];\n }\n }\n // The last int.\n let k = this._data[i];\n const remainingBits = this._length & 0x1f;\n if (remainingBits != 0) /* if remainingBits == 0, the last int is fully used and ALL bits should be left as is */\n k &= ~((4294967295) << remainingBits);\n for (; k != 0; k >>>= 8)\n this._selectedCount += BitArray._onBitCount[k & 0xff];\n this._selectedCountVersion = this._version;\n }\n return (value ? this._selectedCount : this._length - this._selectedCount);\n }\n /// Returns a number of set bits where also [check] is true\n countWhere(check) {\n let result = 0;\n if (this.trueCount() == this._length) {\n for (let i = 0; i < this._length; i++)\n result += check(i) ? 1 : 0;\n }\n else {\n for (let i = -1; (i = this.findNext(i, true)) != -1;)\n result += check(i) ? 1 : 0;\n }\n return result;\n }\n /// Performs bit \"and\" and counts bits of the specified value, without bitset modification.\n andWithCountBits(second, value) {\n if (this._length == 0)\n return 0;\n let count = 0;\n const len = this.lengthInInts;\n let i = 0;\n for (; i < len - 1; i++) {\n for (let k = this._data[i] & second._data[i]; k != 0; k >>>= 8)\n count += BitArray._onBitCount[k & 0xff];\n }\n // The last int.\n let k = this._data[i] & second._data[i];\n const remainingBits = this._length & 0x1f;\n if (remainingBits != 0)\n k &= ~((4294967295) << remainingBits);\n for (; k != 0; k >>>= 8)\n count += BitArray._onBitCount[k & 0xff];\n return (value ? count : this._length - count);\n }\n clear() {\n this.setLength(0);\n }\n contains(value) {\n return this.findNext(-1, value) >= 0;\n }\n get allTrue() {\n return this.countBits(true) == this._length;\n }\n get allFalse() {\n return this.countBits(false) == this._length;\n }\n get anyTrue() {\n return this.countBits(true) > 0;\n }\n get anyFalse() {\n return this.countBits(false) > 0;\n }\n /// Returns the position of the next bit of the specified value, starting from the specified position.\n /// Returns -1, if there are no such bits.\n findNext(index, value = true) {\n this.assureInRange(index, -1, this._length, 'index');\n if (index >= this._length - 1)\n return -1;\n index = index < 0 ? 0 : index + 1; // skip start\n let unusedBits = index & 0x1f;\n const numInts = this.lengthInInts;\n for (let i = Math.floor(index / 32); i < numInts; i++) {\n let k = (value ? this._data[i] : ~this._data[i]); // uint cast\n if (unusedBits != 0) {\n k &= ((0xffffffff << unusedBits) & 0xffffffff);\n unusedBits = 0;\n }\n else if (!value && k == -4294967296) /* looking for false, all bits are set */ {\n continue;\n }\n for (let j = 0; k != 0; j += 8, k >>>= 8) {\n const p = BitArray._firstOnBit[k & 0xff];\n if (p >= 0) {\n index = p + (i * 32) + j;\n if (index >= this._length)\n return -1;\n return index;\n }\n }\n }\n return -1;\n }\n /// Finds previous bit of the specified value in the bitset.\n findPrev(index, value = true) {\n if (index == 0)\n return -1;\n this.assureInRange(index, -1, this._length, 'index');\n index = index < 0 ? this._length - 1 : index - 1; // skip start\n const lastIntIdx = Math.floor(index / 0x20);\n let remainingBits = (index + 1) & 0x1f;\n for (let i = lastIntIdx; i >= 0; i--) {\n let k = (value ? this._data[i] : ~this._data[i]); // cast\n if (remainingBits != 0) {\n k &= ~((4294967295) << remainingBits);\n remainingBits = 0;\n }\n for (let j = 24; k != 0; j -= 8, k <<= 8) {\n const p = BitArray._lastOnBit[k >>> 0x18];\n if (p >= 0)\n return p + (i * 32) + j;\n }\n }\n return -1;\n }\n}\nBitArray._onBitCount = Int8Array.from([\n 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,\n 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\n 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,\n 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,\n 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,\n 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8\n]);\nBitArray._firstOnBit = Int8Array.from([\n -1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0\n]);\nBitArray._lastOnBit = Int8Array.from([\n -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,\n 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7\n]);\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYml0LWFycmF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYml0LWFycmF5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxPQUFPLE9BQU8sUUFBUTtJQW9FM0IsWUFBWSxHQUF5QixFQUFFLGVBQWlDLEtBQUs7UUFackUsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUNaLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFDYixpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUNqQixtQkFBYyxHQUFHLENBQUMsQ0FBQztRQUNuQiwwQkFBcUIsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzQiw0QkFBdUIsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM3QixtQkFBYyxHQUFHLEVBQUUsQ0FBQztRQUNwQiwwQkFBcUIsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuQyxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFLdkIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7WUFDM0IsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDO1lBQ25CLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUMsSUFBSSxZQUFZLEVBQUU7Z0JBQ2hCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtvQkFDbEMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2FBQ2hCO1lBQ0QsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7WUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7U0FDdkI7YUFBTSxJQUFJLEdBQUcsWUFBWSxXQUFXLEVBQUU7WUFDckMsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFrQixDQUFDO1lBQ2hDLElBQUksQ0FBQyxPQUFPLEdBQUcsWUFBc0IsQ0FBQztTQUN2QzthQUFNO1lBQ0wsTUFBTSxJ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QUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Q0FBQyxDQUFDLENBQUM7QUFFNUMsb0JBQVcsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDO0lBQ2xDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUMvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztDQUFDLENBQUMsQ0FBQztBQUU1QyxtQkFBVSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUM7SUFDakMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQy9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0NBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgY2xhc3MgQml0QXJyYXkge1xuICBzdGF0aWMgX29uQml0Q291bnQgPSBJbnQ4QXJyYXkuZnJvbShbXG4gICAgMCwgMSwgMSwgMiwgMSwgMiwgMiwgMywgMSwgMiwgMiwgMywgMiwgMywgMywgNCxcbiAgICAxLCAyLCAyLCAzLCAyLCAzLCAzLCA0LCAyLCAzLCAzLCA0LCAzLCA0LCA0LCA1LFxuICAgIDEsIDIsIDIsIDMsIDIsIDMsIDMsIDQsIDIsIDMsIDMsIDQsIDMsIDQsIDQsIDUsXG4gICAgMiwgMywgMywgNCwgMywgNCwgNCwgNSwgMywgNCwgNCwgNSwgNCwgNSwgNSwgNixcbiAgICAxLCAyLCAyLCAzLCAyLCAzLCAzLCA0LCAyLCAzLCAzLCA0LCAzLCA0LCA0LCA1LFxuICAgIDIsIDMsIDMsIDQsIDMsIDQsIDQsIDUsIDMsIDQsIDQsIDUsIDQsIDUsIDUsIDYsXG4gICAgMiwgMywgMywgNCwgMywgNCwgNCwgNSwgMywgNCwgNCwgNSwgNCwgNSwgNSwgNixcbiAgICAzLCA0LCA0LCA1LCA0LCA1LCA1LCA2LCA0LCA1LCA1LCA2LCA1LCA2LCA2LCA3LFxuICAgIDEsIDIsIDIsIDMsIDIsIDMsIDMsIDQsIDIsIDMsIDMsIDQsIDMsIDQsIDQsIDUsXG4gICAgMiwgMywgMywgNCwgMywgNCwgNCwgNSwgMywgNCwgNCwgNSwgNCwgNSwgNSwgNixcbiAgICAyLCAzLCAzLCA0LCAzLCA0LCA0LCA1LCAzLCA0LCA0LCA1LCA0LCA1LCA1LCA2LFxuICAgIDMsIDQsIDQsIDUsIDQsIDUsIDUsIDYsIDQsIDUsIDUsIDYsIDUsIDYsIDYsIDcsXG4gICAgMiwgMywgMywgNCwgMywgNCwgNCwgNSwgMywgNCwgNCwgNSwgNCwgNSwgNSwgNixcbiAgICAzLCA0LCA0LCA1LCA0LCA1LCA1LCA2LCA0LCA1LCA1LCA2LCA1LCA2LCA2LCA3LFxuICAgIDMsIDQsIDQsIDUsIDQsIDUsIDUsIDYsIDQsIDUsIDUsIDYsIDUsIDYsIDYsIDcsXG4gICAgNCwgNSwgNSwgNiwgNSwgNiwgNiwgNywgNSwgNiwgNiwgNywgNiwgNywgNywgOF0pO1xuXG4gIHN0YXRpYyBfZmlyc3RPbkJpdCA9IEludDhBcnJheS5mcm9tKFtcbiAgICAtMSwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA0LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDUsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNCwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA2LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDQsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNSwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA0LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDcsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNCwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA1LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDQsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNiwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA0LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDUsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNCwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMF0pO1xuXG4gIHN0YXRpYyBfbGFzdE9uQml0ID0gSW50OEFycmF5LmZyb20oW1xuICAgIC0xLCAwLCAxLCAxLCAyLCAyLCAyLCAyLCAzLCAzLCAzLCAzLCAzLCAzLCAzLCAzLFxuICAgIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsXG4gICAgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSxcbiAgICA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LFxuICAgIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsXG4gICAgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNixcbiAgICA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LFxuICAgIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsXG4gICAgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNyxcbiAgICA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LFxuICAgIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsXG4gICAgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNyxcbiAgICA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LFxuICAgIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsXG4gICAgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNyxcbiAgICA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3XSk7XG5cbiAgcHJpdmF0ZSBfZGF0YTogVWludDMyQXJyYXk7XG4gIHByaXZhdGUgX2xlbmd0aCA9IDA7XG4gIHByaXZhdGUgX3ZlcnNpb24gPSAwO1xuICBwcml2YXRlIF91cGRhdGVMZXZlbCA9IDA7XG4gIHByaXZhdGUgX3NlbGVjdGVkQ291bnQgPSAwO1xuICBwcml2YXRlIF9zZWxlY3RlZENvdW50VmVyc2lvbiA9IC0xO1xuICBwcml2YXRlIF9zZWxlY3RlZEluZGV4ZXNWZXJzaW9uID0gLTE7XG4gIHByaXZhdGUgX3ZlcnNpb25lZE5hbWUgPSAnJztcbiAgcHJpdmF0ZSBfdmVyc2lvbmVkTmFtZVZlcnNpb24gPSAtMTtcbiAgU0hSSU5LX1RIUkVTSE9MRCA9IDB4MTAwO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IFVpbnQzMkFycmF5LCBsZW5ndGg6IG51bWJlcilcbiAgY29uc3RydWN0b3IobGVuZ3RoOiBudW1iZXIsIGRlZmF1bHRWYWx1ZT86IGJvb2xlYW4pXG4gIGNvbnN0cnVjdG9yKGFyZzogbnVtYmVyIHwgVWludDMyQXJyYXksIGRlZmF1bHRWYWx1ZTogYm9vbGVhbiB8IG51bWJlciA9IGZhbHNlKSB7XG4gICAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSBhcmc7XG4gICAgICBjb25zdCBidWZmID0gQml0QXJyYXkuX2NyZWF0ZUJ1ZmZlcihsZW5ndGgpO1xuICAgICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmYubGVuZ3RoOyBpKyspXG4gICAgICAgICAgYnVmZltpXSA9IC0xO1xuICAgICAgfVxuICAgICAgdGhpcy5fZGF0YSA9IGJ1ZmY7XG4gICAgICB0aGlzLl9sZW5ndGggPSBsZW5ndGg7XG4gICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBVaW50MzJBcnJheSkge1xuICAgICAgdGhpcy5fZGF0YSA9IGFyZyBhcyBVaW50MzJBcnJheTtcbiAgICAgIHRoaXMuX2xlbmd0aCA9IGRlZmF1bHRWYWx1ZSBhcyBudW1iZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgfVxuXG5cbiAgZ2V0UmF3RGF0YSgpIHsgcmV0dXJuIHRoaXMuX2RhdGE7IH1cblxuICBhc3N1cmVHb2V6KG51bTogbnVtYmVyLCBhcmdOYW1lOiBTdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAobnVtIDwgMCkgdGhyb3cgbmV3IEVycm9yKGAke2FyZ05hbWV9IHNob3VsZCBiZSBncmVhdGVyIHRoYW4gemVyb2ApO1xuICB9XG5cbiAgYXNzdXJlSW5SYW5nZSh2YWx1ZTogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIGFyZ05hbWU6IFN0cmluZyk6IHZvaWQge1xuICAgIGlmICgodmFsdWUgPCBtaW4pIHx8ICh2YWx1ZSA+IG1heCkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEFyZ3VtZW50ICR7YXJnTmFtZX0gKCR7dmFsdWV9KSBvdXQgb2YgcmFuZ2UgKCR7bWlufSwgJHttYXh9KWApO1xuICB9XG5cbiAgY29weShzcmM6IFVpbnQzMkFycmF5LCBkc3Q6IFVpbnQzMkFycmF5LCBjb3VudDogbnVtYmVyKTogdm9pZCB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKVxuICAgICAgZHN0W2ldID0gc3JjW2ldO1xuICB9XG5cbiAgY29weUZyb20ob3RoZXI6IEJpdEFycmF5KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCAhPSBvdGhlci5fbGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMZW5ndGhzIGRpZmZlciAoJHt0aGlzLl9sZW5ndGh9ICE9ICR7b3RoZXIuX2xlbmd0aH0pYCk7XG4gICAgdGhpcy5jb3B5KG90aGVyLl9kYXRhLCB0aGlzLl9kYXRhLCB0aGlzLmxlbmd0aEluSW50cyk7XG4gICAgdGhpcy5fdmVyc2lvbisrO1xuICB9XG5cbiAgZ2V0IGxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGJ1ZmZlcigpIHtcbiAgICByZXR1cm4gdGhpcy5fZGF0YTtcbiAgfVxuXG4gIHNldCBidWZmZXIoZGF0YTogVWludDMyQXJyYXkpIHtcbiAgICB0aGlzLl9kYXRhID0gZGF0YTtcbiAgICB0aGlzLl92ZXJzaW9uKys7XG4gIH1cblxuICBnZXQgdmVyc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmVyc2lvbjtcbiAgfVxuXG4gIHNldCB2ZXJzaW9uKHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLl92ZXJzaW9uID0gdmFsdWU7XG4gIH1cblxuICBpbmNyZW1lbnRWZXJzaW9uKG5vdGlmeSA9IHRydWUpOiB2b2lkIHtcbiAgICB0aGlzLl92ZXJzaW9uKys7XG4gIH1cblxuICBnZXQgbGVuZ3RoSW5JbnRzKCkge1xuICAgIHJldHVybiBNYXRoLmZsb29yKCh0aGlzLl9sZW5ndGggKyAweDFmKSAvIDB4MjApO1xuICB9XG5cbiAgZ2V0IHZlcnNpb25lZE5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZlcnNpb24gPT0gdGhpcy5fdmVyc2lvbmVkTmFtZVZlcnNpb24gPyB0aGlzLl92ZXJzaW9uZWROYW1lIDogJyc7XG4gIH1cblxuICBzZXQgdmVyc2lvbmVkTmFtZShuYW1lOiBzdHJpbmcpIHtcbiAgICB0aGlzLl92ZXJzaW9uZWROYW1lID0gbmFtZTtcbiAgICB0aGlzLl92ZXJzaW9uZWROYW1lVmVyc2lvbiA9IHRoaXMuX3ZlcnNpb247XG4gIH1cblxuICBnZXQgc2VsZigpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHNldExlbmd0aCh2YWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHZhbHVlIDwgMClcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2hvdWxkIGJlID49IDAnKTtcblxuICAgIGlmICh2YWx1ZSA9PSB0aGlzLl9sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBuSW50c05lZWRlZCA9IE1hdGguZmxvb3IoKHZhbHVlICsgMHgxZikgLyAweDIwKTtcbiAgICBpZiAoKG5JbnRzTmVlZGVkID4gdGhpcy5fZGF0YS5sZW5ndGgpIHx8ICgobkludHNOZWVkZWQgKyB0aGlzLlNIUklOS19USFJFU0hPTEQpIDwgdGhpcy5fZGF0YS5sZW5ndGgpKSB7XG4gICAgICBjb25zdCBuZXdEYXRhID0gbmV3IFVpbnQzMkFycmF5KG5JbnRzTmVlZGVkKTtcbiAgICAgIHRoaXMuY29weSh0aGlzLl9kYXRhLCBuZXdEYXRhLCAobkludHNOZWVkZWQgPiB0aGlzLl9kYXRhLmxlbmd0aCkgPyB0aGlzLl9kYXRhLmxlbmd0aCA6IG5JbnRzTmVlZGVkKTtcbiAgICAgIHRoaXMuX2RhdGEgPSBuZXdEYXRhO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSA+IHRoaXMuX2xlbmd0aCkge1xuICAgICAgaWYgKHRoaXMuX2xlbmd0aCAlIDB4MjAgPiAwKVxuICAgICAgICB0aGlzLl9kYXRhW3RoaXMubGVuZ3RoSW5JbnRzIC0gMV0gJj0gKDEgPDwgKCh0aGlzLl9sZW5ndGggJSAweDIwKSAmIDB4MWYpKSAtIDE7XG5cbiAgICAgIHRoaXMuX2RhdGEuZmlsbCgwLCB0aGlzLmxlbmd0aEluSW50cywgbkludHNOZWVkZWQpO1xuICAgIH1cbiAgICB0aGlzLl9sZW5ndGggPSB2YWx1ZTtcbiAgICB0aGlzLl92ZXJzaW9uKys7XG4gIH1cblxuICBzdGF0aWMgZnJvbUFuZChzZXQxOiBCaXRBcnJheSwgc2V0MjogQml0QXJyYXkpOiBCaXRBcnJheSB7XG4gICAgaWYgKHNldDEuX2xlbmd0aCAhPSBzZXQyLl9sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYExlbmd0aHMgZGlmZmVyICgke3NldDEuX2xlbmd0aH0gIT0gJHtzZXQyLl9sZW5ndGh9KWApO1xuXG4gICAgY29uc3QgdGVtcCA9IG5ldyBCaXRBcnJheShzZXQxLl9sZW5ndGgpO1xuICAgIHRlbXAuX2xlbmd0aCA9IHNldDEuX2xlbmd0aDtcbiAgICB0ZW1wLl9kYXRhID0gQml0QXJyYXkuX2NyZWF0ZUJ1ZmZlcih0ZW1wLl9sZW5ndGgpO1xuICAgIHRlbXAuX3ZlcnNpb24gPSAwO1xuXG4gICAgY29uc3QgbGVuID0gc2V0MS5sZW5ndGhJbkludHM7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIHRlbXAuX2RhdGFbaV0gPSBzZXQxLl9kYXRhW2ldICYgc2V0Mi5fZGF0YVtpXTtcblxuICAgIHJldHVybiB0ZW1wO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgX2NyZWF0ZUJ1ZmZlcihsZW5ndGg6IG51bWJlcik6IFVpbnQzMkFycmF5IHtcbiAgICByZXR1cm4gbmV3IFVpbnQzMkFycmF5KE1hdGguZmxvb3IoKGxlbmd0aCArIDB4MWYpIC8gMHgyMCkpO1xuICB9XG5cbiAgc3RhdGljIGZyb21WYWx1ZXModmFsdWVzOiBBcnJheTxib29sZWFuPik6IEJpdEFycmF5IHtcbiAgICBjb25zdCB0ZW1wID0gbmV3IEJpdEFycmF5KHZhbHVlcy5sZW5ndGgpO1xuICAgIHRlbXAuX3ZlcnNpb24gPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZW1wLl9sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHZhbHVlc1tpXSlcbiAgICAgICAgdGVtcC5fZGF0YVtNYXRoLmZsb29yKGkgLyAweDIwKV0gfD0gMSA8PCAoKGkgJSAweDIwKSAmIDB4MWYpO1xuICAgIH1cbiAgICByZXR1cm4gdGVtcDtcbiAgfVxuXG4gIC8vLyBDb25zdHJ1Y3RzIGEgW0JpdFNldF0gb2YgbGVuZ3RoIFtjb3VudF0sIHdoZXJlIGlkeC10aCBiaXQgaXMgZGV0ZXJtaW5lZCBieSBhIGNhbGwgdG8gW2ZsYWddIChpZHgpLlxuICBzdGF0aWMgZnJvbVNlcShjb3VudDogbnVtYmVyLCBmbGFnOiBGdW5jdGlvbik6IEJpdEFycmF5IHtcbiAgICBjb25zdCB0ZW1wID0gbmV3IEJpdEFycmF5KGNvdW50KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyArK2kpXG4gICAgICB0ZW1wLnNldEJpdChpLCBmbGFnKGkpKTtcblxuICAgIHRlbXAuX3ZlcnNpb24gPSAwO1xuICAgIHJldHVybiB0ZW1wO1xuICB9XG5cbiAgLy8vIENvbnN0cnVjdHMgYSBbQml0U2V0XSBmcm9tIGEgc3RyaW5nIFtzXSBjb250YWluaW5nICcwJyBvciAnMScuXG4gIHN0YXRpYyBmcm9tU3RyaW5nKHM6IHN0cmluZyk6IEJpdEFycmF5IHtcbiAgICByZXR1cm4gQml0QXJyYXkuZnJvbVNlcShzLmxlbmd0aCwgKGk6IG51bWJlcikgPT4gcy5jaGFyQXQoaSkgPT0gJzEnKTtcbiAgfVxuXG4gIC8vLyBDb25zdHJ1Y3RzIGEgW0JpdFNldF0sIGJhc2VkIG9uIGxlbmd0aCBbX2xlbmd0aF0gYW5kIGJ5dGUgYXJyYXkgW19kYXRhXS5cbiAgc3RhdGljIGZyb21VaW50MzJBcnJheShfbGVuZ3RoOiBudW1iZXIsIF9kYXRhOiBVaW50MzJBcnJheSk6IEJpdEFycmF5IHtcbiAgICBjb25zdCB0ZW1wID0gbmV3IEJpdEFycmF5KF9sZW5ndGgpO1xuICAgIHRlbXAuX2RhdGEgPSBfZGF0YTtcbiAgICByZXR1cm4gdGVtcDtcbiAgfVxuXG4gIC8vLyBEZXNlcmlhbGl6ZXMgYSBbQml0U2V0XSBmcm9tIFtieXRlc10uXG4gIHN0YXRpYyBmcm9tQnl0ZXMoYnl0ZXM6IFVpbnQ4QXJyYXkpOiBCaXRBcnJheSB7XG4gICAgY29uc3QgbGVuID0gYnl0ZXMubGVuZ3RoO1xuICAgIGNvbnN0IHRlbXAgPSBuZXcgQml0QXJyYXkobGVuICogOCk7XG4gICAgdGVtcC5fZGF0YSA9IG5ldyBVaW50MzJBcnJheShNYXRoLmZsb29yKChsZW4gKyAzKSAvIDQpKTtcbiAgICB0ZW1wLl9sZW5ndGggPSBsZW4gKiA4O1xuICAgIGxldCBudW0xID0gMDtcbiAgICBsZXQgbnVtMiA9IDA7XG5cbiAgICB3aGlsZSAoKGxlbiAtIG51bTIpID49IDQpIHtcbiAgICAgIHRlbXAuX2RhdGFbbnVtMSsrXSA9IChcbiAgICAgICAgKChieXRlc1tudW0yXSAmIDB4ZmYpIHwgKChieXRlc1tudW0yICsgMV0gJiAweGZmKSA8PCA4KSkgfFxuICAgICAgICAoKGJ5dGVzW251bTIgKyAyXSAmIDB4ZmYpIDw8IDB4MTApXG4gICAgICApIHwgKChieXRlc1tudW0yICsgM10gJiAweGZmKSA8PCAweDE4KTtcblxuICAgICAgbnVtMiArPSA0O1xuICAgIH1cblxuICAgIGlmIChsZW4gLSBudW0yID09IDMpXG4gICAgICB0ZW1wLl9kYXRhW251bTFdID0gKGJ5dGVzW251bTIgKyAyXSAmIDB4ZmYpIDw8IDB4MTA7XG5cbiAgICBpZiAobGVuIC0gbnVtMiA9PSAyKVxuICAgICAgdGVtcC5fZGF0YVtudW0xXSB8PSAoYnl0ZXNbbnVtMiArIDFdICYgMHhmZikgPDwgODtcblxuICAgIGlmIChsZW4gLSBudW0yID09IDEpXG4gICAgICB0ZW1wLl9kYXRhW251bTFdIHw9IGJ5dGVzW251bTJdICYgMHhmZjtcblxuICAgIHRlbXAuX3ZlcnNpb24gPSAwO1xuICAgIHJldHVybiB0ZW1wO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy5fbGVuZ3RofSBiaXRzLCAke3RoaXMuY291bnRCaXRzKHRydWUpfSBzZXRgO1xuICB9XG5cbiAgLy8vIFBlcmZvcm1zIGRlZXAgY29tcGFyaXNvbiBvZiB0d28gYml0c2V0cy5cbiAgZXF1YWxzKG90aGVyOiBCaXRBcnJheSk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzID09IG90aGVyKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAob3RoZXIgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICh0aGlzLl9sZW5ndGggIT0gb3RoZXIuX2xlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICh0aGlzLl9sZW5ndGggPT0gMCkgcmV0dXJuIHRydWU7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoIC0gMTsgaSsrKVxuICAgICAgaWYgKHRoaXMuX2RhdGFbaV0gIT0gb3RoZXIuX2RhdGFbaV0pIHJldHVybiBmYWxzZTtcblxuICAgIGZvciAobGV0IGkgPSAodGhpcy5fZGF0YS5sZW5ndGggLSAxKSAqIDg7IGkgPCB0aGlzLl9sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHRoaXMuZ2V0Qml0KGkpICE9IG90aGVyLmdldEJpdChpKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBDbG9uZXMgYSBiaXRzZXQuICovXG4gIGNsb25lKCk6IEJpdEFycmF5IHtcbiAgICBjb25zdCBiaXRBcnJheSA9IG5ldyBCaXRBcnJheSgwLCBmYWxzZSk7XG4gICAgYml0QXJyYXkuX2RhdGEgPSBVaW50MzJBcnJheS5mcm9tKHRoaXMuX2RhdGEpOyAvLyBlZmZlY3RpdmUgbGVuZ3RoOiAobGVuZ3RoSW5JbnRzKVxuICAgIGJpdEFycmF5Ll9sZW5ndGggPSB0aGlzLl9sZW5ndGg7XG4gICAgYml0QXJyYXkuX3ZlcnNpb24gPSB0aGlzLl92ZXJzaW9uO1xuICAgIHJldHVybiBiaXRBcnJheTtcbiAgfVxuXG4gIC8qKiBJbml0aWFsaXplcyBhIGJpdHNldC4gKi9cbiAgaW5pdChmbGFnOiBGdW5jdGlvbiwgbm90aWZ5OiBib29sZWFuKTogQml0QXJyYXkge1xuICAgIHRoaXMuc2V0QWxsKGZhbHNlLCBmYWxzZSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2xlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoZmxhZyhpKSlcbiAgICAgICAgdGhpcy5fZGF0YVtNYXRoLmZsb29yKGkgLyAweDIwKV0gfD0gMSA8PCAoKGkgJSAweDIwKSAmIDB4MWYpO1xuICAgIH1cblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8vIEludmVydHMgYSBiaXRzZXQuXG4gIGludmVydChub3RpZnkgPSB0cnVlKTogdm9pZCB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9kYXRhLmxlbmd0aDsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSBePSAtMTtcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICB9XG5cbiAgLy8vIFNldHMgYWxsIGJpdHMgdG8gW3ZhbHVlXSwgb3B0aW9uYWxseSBzdXBwcmVzc2luZyBub3RpZmljYXRpb25zLlxuICBzZXRBbGwodmFsdWU6IGJvb2xlYW4sIG5vdGlmeSA9IGZhbHNlKTogdm9pZCB7XG4gICAgY29uc3QgZmxhZ3MgPSB2YWx1ZSA/IC0xIDogMDtcbiAgICBjb25zdCBsZW4gPSB0aGlzLmxlbmd0aEluSW50cztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIC8vdG9kbzogb3B0aW1pemVcbiAgICAgIHRoaXMuX2RhdGFbaV0gPSBmbGFncztcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICB9XG5cbiAgLy8vIFNldHMgYml0cyBhdCBbaW5kZXhlc10gcG9zaXRpb24gdG8gW3ZhbHVlXS5cbiAgLy8vIENsZWFycyB0aGUgYml0c2V0IGlmIFtjbGVhcl0gZmxhZyBpcyB0cnVlLlxuICAvLy8gQ2hhbmdlIG5vdGlmaWNhdGlvbiBpcyByYWlzZWQgd2hlbiBbbm90aWZ5XSBpcyB0cnVlLlxuICBzZXRJbmRleGVzKGluZGV4ZXM6IEFycmF5PG51bWJlcj4sIHZhbHVlID0gdHJ1ZSwgY2xlYXIgPSB0cnVlLCBub3RpZnkgPSB0cnVlKTogdm9pZCB7XG4gICAgaWYgKGNsZWFyKVxuICAgICAgdGhpcy5zZXRBbGwoIXZhbHVlLCBmYWxzZSk7XG5cbiAgICBmb3IgKGNvbnN0IGkgb2YgaW5kZXhlcylcbiAgICAgIHRoaXMuc2V0RmFzdChpLCB2YWx1ZSk7XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgfVxuXG4gIGV2ZXJ5SW5kZXgoaW5kZXhlczogQXJyYXk8bnVtYmVyPiwgdmFsdWUgPSB0cnVlKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBpbmRleGVzKSB7XG4gICAgICBpZiAodGhpcy5nZXRCaXQoaW5kZXgpICE9IHZhbHVlKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgYW55SW5kZXgoaW5kZXhlczogQXJyYXk8bnVtYmVyPiwgdmFsdWUgPSB0cnVlKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBpbmRleGVzKSB7XG4gICAgICBpZiAodGhpcy5nZXRCaXQoaW5kZXgpID09IHZhbHVlKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc2V0V2hlcmUoY2hlY2s6IEZ1bmN0aW9uLCB2YWx1ZSA9IHRydWUsIGNsZWFyID0gdHJ1ZSwgbm90aWZ5ID0gdHJ1ZSwgYWxsb3dDbGVhciA9IHRydWUpOiB2b2lkIHtcbiAgICBpZiAoY2xlYXIgJiYgYWxsb3dDbGVhcilcbiAgICAgIHRoaXMuc2V0QWxsKCF2YWx1ZSwgZmFsc2UpO1xuXG4gICAgaWYgKGFsbG93Q2xlYXIpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGNoZWNrKGkpKVxuICAgICAgICAgIHRoaXMuc2V0RmFzdChpLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbGVuZ3RoOyBpKyspXG4gICAgICAgIHRoaXMuc2V0RmFzdChpLCBjaGVjayhpKSA/IHZhbHVlIDogIXZhbHVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgfVxuXG4gIGdldFJhbmdlKGZyb206IG51bWJlciwgdG86IG51bWJlcik6IEJpdEFycmF5IHtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UoZnJvbSwgMCwgdGhpcy5fbGVuZ3RoIC0gMSwgJ2Zyb20nKTtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UodG8sIDAsIHRoaXMuX2xlbmd0aCwgJ3RvJyk7XG4gICAgY29uc3QgYXJyOiBBcnJheTxib29sZWFuPiA9IFtdO1xuICAgIGZvciAobGV0IGkgPSBmcm9tOyBpIDwgdG87ICsraSlcbiAgICAgIGFyci5wdXNoKHRoaXMuZ2V0Qml0KGkpKTtcbiAgICByZXR1cm4gQml0QXJyYXkuZnJvbVZhbHVlcyhhcnIpO1xuICB9XG5cbiAgZ2V0UmFuZ2VBc0xpc3QoZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyKTogYm9vbGVhbltdIHtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UoZnJvbSwgMCwgdGhpcy5fbGVuZ3RoIC0gMSwgJ2Zyb20nKTtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UodG8sIDAsIHRoaXMuX2xlbmd0aCwgJ3RvJyk7XG4gICAgY29uc3QgYXJyOiBib29sZWFuW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gZnJvbTsgaSA8IHRvOyArK2kpXG4gICAgICBhcnIucHVzaCh0aGlzLmdldEJpdChpKSk7XG4gICAgcmV0dXJuIGFycjtcbiAgfVxuXG5cbiAgc2V0UmFuZ2UoZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyLCB2YWx1ZTogYm9vbGVhbiwgbm90aWZ5ID0gdHJ1ZSk6IEJpdEFycmF5IHtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UoZnJvbSwgMCwgdGhpcy5fbGVuZ3RoIC0gMSwgJ2Zyb20nKTtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UodG8sIDAsIHRoaXMuX2xlbmd0aCAtIDEsICd0bycpO1xuXG4gICAgY29uc3Qgc3RhcnQgPSBNYXRoLm1pbihmcm9tLCB0byk7XG4gICAgY29uc3QgZW5kID0gTWF0aC5tYXgoZnJvbSwgdG8pO1xuXG4gICAgLy90b2RvOiBvcHRpbWl6ZVxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgaSsrKVxuICAgICAgICB0aGlzLnNldFRydWUoaSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8PSBlbmQ7IGkrKylcbiAgICAgICAgdGhpcy5zZXRGYWxzZShpKTtcbiAgICB9XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vLyBTZXRzIG4gcmFuZG9tbHkgY2hvc2VuIGJpdHMgdG8gdmFsdWUsIHJlbWFpbmluZyBiaXRzIHRvICF2YWx1ZS5cbiAgc2V0UmFuZG9tKG46IG51bWJlciwgdmFsdWU6IGJvb2xlYW4sIG5vdGlmeSA9IHRydWUpOiB2b2lkIHtcbiAgICBpZiAobiA8IDAgfHwgbiA+IHRoaXMuX2xlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcignbiBtdXN0IGJlID49IDAgJiYgPD0gQ291bnQnKTtcblxuICAgIGlmIChuID4gdGhpcy5fbGVuZ3RoIC8gMilcbiAgICAgIHRoaXMuc2V0UmFuZG9tKHRoaXMuX2xlbmd0aCAtIG4sICF2YWx1ZSk7XG5cbiAgICB0aGlzLnNldEFsbCghdmFsdWUpO1xuXG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBuOykge1xuICAgICAgY29uc3QgaSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHRoaXMuX2xlbmd0aCk7XG4gICAgICBpZiAodGhpcy5nZXRCaXQoaSkgPT0gdmFsdWUpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5zZXRGYXN0KGksIHZhbHVlKTtcbiAgICAgIGsrKztcbiAgICB9XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgfVxuXG4gIC8vLyBNb2RpZmllcyBjdXJyZW50IGJpdHNldCBieSBwZXJmb3JtaW5nIHRoZSBiaXR3aXNlIEFORCBvcGVyYXRpb24gYWdhaW5zdCB0aGVcbiAgLy8vIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIGFuZCh2YWx1ZTogQml0QXJyYXksIG5vdGlmeSA9IHRydWUpOiBCaXRBcnJheSB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCAhPSB2YWx1ZS5fbGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBsZW5ndGhzIGRpZmZlci4nKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0aGlzLmxlbmd0aEluSW50czsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSAmPSB2YWx1ZS5fZGF0YVtpXTtcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8vIFBlcmZvcm1zIHRoZSBiaXR3aXNlIEFORCBOT1Qgb3BlcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBiaXRzZXRcbiAgLy8vIGFnYWluc3QgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIGFuZE5vdCh2YWx1ZTogQml0QXJyYXksIG5vdGlmeSA9IHRydWUpOiBCaXRBcnJheSB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCAhPSB2YWx1ZS5fbGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBsZW5ndGhzIGRpZmZlci4nKTtcblxuICAgIGNvbnN0IGxlbiA9IHRoaXMubGVuZ3RoSW5JbnRzO1xuICAgIGZvciAobGV0IG51bTIgPSAwOyBudW0yIDwgbGVuOyBudW0yKyspXG4gICAgICB0aGlzLl9kYXRhW251bTJdICY9IH52YWx1ZS5fZGF0YVtudW0yXTtcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8vIFBlcmZvcm1zIHRoZSBiaXR3aXNlIE5PVCBBTkQgb3BlcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBiaXRzZXRcbiAgLy8vIGFnYWluc3QgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIG5vdEFuZCh2YWx1ZTogQml0QXJyYXksIG5vdGlmeSA9IHRydWUpOiBCaXRBcnJheSB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCAhPSB2YWx1ZS5fbGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBsZW5ndGhzIGRpZmZlci4nKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0aGlzLmxlbmd0aEluSW50czsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSA9ICh+dGhpcy5fZGF0YVtpXSkgJiB2YWx1ZS5fZGF0YVtpXTtcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8vIEludmVydHMgYWxsIGJpdCB2YWx1ZXMgaW4gdGhlIGN1cnJlbnQgYml0c2V0XG4gIG5vdChub3RpZnkgPSB0cnVlKTogQml0QXJyYXkge1xuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0aGlzLmxlbmd0aEluSW50czsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSA9IH50aGlzLl9kYXRhW2ldO1xuXG4gICAgdGhpcy5pbmNyZW1lbnRWZXJzaW9uKG5vdGlmeSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLy8gUGVyZm9ybXMgdGhlIGJpdHdpc2UgT1Igb3BlcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBiaXRzZXRcbiAgLy8vIGFnYWluc3QgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIG9yKHZhbHVlOiBCaXRBcnJheSwgbm90aWZ5ID0gdHJ1ZSkge1xuICAgIGlmICh0aGlzLl9sZW5ndGggIT0gdmFsdWUuX2xlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXJyYXkgbGVuZ3RocyBkaWZmZXIuJyk7XG5cbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gdGhpcy5sZW5ndGhJbkludHM7IGkgPCBsZW47IGkrKylcbiAgICAgIHRoaXMuX2RhdGFbaV0gfD0gdmFsdWUuX2RhdGFbaV07XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vLyBQZXJmb3JtcyB0aGUgYml0d2lzZSBleGNsdXNpdmUgT1Igb3BlcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBiaXRzZXRcbiAgLy8vIGFnYWluc3QgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIHhvcih2YWx1ZTogQml0QXJyYXksIG5vdGlmeSA9IHRydWUpIHtcbiAgICBpZiAodGhpcy5fbGVuZ3RoICE9IHZhbHVlLl9sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FycmF5IGxlbmd0aHMgZGlmZmVyLicpO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHRoaXMubGVuZ3RoSW5JbnRzOyBpIDwgbGVuOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldIF49IHZhbHVlLl9kYXRhW2ldO1xuXG4gICAgdGhpcy5pbmNyZW1lbnRWZXJzaW9uKG5vdGlmeSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLy8gSW5zZXJ0cyBuIDAtYml0cyBhdCBwb3NpdGlvbiBwb3MsIHJlc2l6aW5nIHNlbGYgYW5kIHNoaWZ0aW5nIGJpdHMgYXBwcm9wcmlhdGVseS5cbiAgaW5zZXJ0QXQocG9zOiBudW1iZXIsIG46IG51bWJlciwgZmxhZyA9IGZhbHNlKTogdm9pZCB7XG4gICAgdGhpcy5hc3N1cmVJblJhbmdlKHBvcywgMCwgdGhpcy5fbGVuZ3RoLCAncG9zJyk7XG5cbiAgICBpZiAobiA9PSAwKSByZXR1cm47XG5cbiAgICAvL1RPRE86IG9wdGltaXplXG4gICAgLy90aGUgbW9zdCBwcmltaXRpdmUgaW1wbGVtZW50YXRpb24sIG9wdGltaXplIGl0IGxhdGVyIVxuXG4gICAgLy8gYmVnaW5VcGRhdGUoKTtcbiAgICBjb25zdCBvbGRsZW5ndGggPSB0aGlzLl9sZW5ndGg7XG4gICAgdGhpcy5zZXRMZW5ndGgodGhpcy5fbGVuZ3RoICsgbik7XG5cbiAgICAvL2lmICghY29udGFpbnMoIWZsYWcpKSByZXR1cm47IC8vIG5vdGhpbmcgdG8gZG9cblxuICAgIGZvciAobGV0IGkgPSBvbGRsZW5ndGggLSAxOyBpID49IHBvczsgaS0tKVxuICAgICAgdGhpcy5zZXRCaXQoaSArIG4sIHRoaXMuZ2V0Qml0KGkpKTtcblxuICAgIGZvciAobGV0IGkgPSBwb3M7IGkgPCBwb3MgKyBuOyBpKyspXG4gICAgICB0aGlzLnNldEJpdChpLCBmbGFnKTtcblxuICAgIC8vIGVuZFVwZGF0ZSgpO1xuICB9XG5cbiAgLy8vIERlbGV0ZXMgbiBiaXRzIGJlZ2lubmluZyBhdCBwb3NpdGlvbiBwb3MsIHJlc2l6aW5nIHNlbGYgYW5kIHNoaWZ0aW5nIHJlbWFpbmluZ1xuICAvLy8gYml0cyBhcHByb3ByaWF0ZWx5LlxuICByZW1vdmVBdChwb3M6IG51bWJlciwgbiA9IDEpOiB2b2lkIHtcbiAgICAvLyB0aGUgbW9zdCBwcmltaXRpdmUgaW1wbGVtZW50YXRpb24sIG9wdGltaXplIGl0IGxhdGVyIVxuICAgIGlmIChuIDwgMClcbiAgICAgIHRocm93IG5ldyBFcnJvcignbiBjYW5ub3QgYmUgbmVnYXRpdmUnKTtcblxuICAgIHRoaXMuYXNzdXJlSW5SYW5nZShwb3MsIDAsIHRoaXMuX2xlbmd0aCAtIG4sICdwb3MnKTtcblxuICAgIGlmICh0aGlzLmNvbnRhaW5zKHRydWUpKSB7XG4gICAgICBmb3IgKGxldCBpID0gcG9zOyBpIDwgdGhpcy5fbGVuZ3RoIC0gbjsgaSsrKVxuICAgICAgICB0aGlzLnNldEJpdChpLCB0aGlzLmdldEJpdChpICsgbikpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0TGVuZ3RoKHRoaXMuX2xlbmd0aCAtIG4pO1xuICB9XG5cbiAgcmVtb3ZlQnlNYXNrKG1hc2s6IEJpdEFycmF5LCBmbGFnID0gdHJ1ZSk6IEJpdEFycmF5IHtcbiAgICBpZiAodGhpcy5fbGVuZ3RoICE9IG1hc2subGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggIT0gbWFzay5sZW5ndGgnKTtcblxuICAgIGlmIChtYXNrID09IHRoaXMpIHsgLy8gbm8gbmVlZCB0byBpdGVyYXRlXG4gICAgICB0aGlzLnNldExlbmd0aChtYXNrLmNvdW50Qml0cyghZmxhZykpO1xuICAgICAgdGhpcy5zZXRBbGwoIWZsYWcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgZHN0SWR4ID0gMDtcblxuICAgICAgZm9yIChsZXQgc3JjSWR4ID0gLTE7IChzcmNJZHggPSBtYXNrLmZpbmROZXh0KHNyY0lkeCwgIWZsYWcpKSAhPSAtMTspXG4gICAgICAgIHRoaXMuc2V0RmFzdChkc3RJZHgrKywgdGhpcy5nZXRCaXQoc3JjSWR4KSk7XG5cbiAgICAgIHRoaXMuX2xlbmd0aCA9IGRzdElkeDtcbiAgICAgIHRoaXMuX3ZlcnNpb24rKztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vLyBTaW1pbGFyIHRvIHRoZSBbXSBvcGVyYXRvci5cbiAgZ2V0Qml0KHBvczogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLl9kYXRhW01hdGguZmxvb3IocG9zIC8gMHgyMCldICYgKDEgPDwgKHBvcyAmIDB4MWYpKSkgIT0gMDtcbiAgfVxuXG4gIC8vLyBTaW1pbGFyIHRvIHRoZSBbXSBvcGVyYXRvci5cbiAgc2V0Qml0KHBvczogbnVtYmVyLCBiaXQ6IGJvb2xlYW4sIG5vdGlmeSA9IHRydWUpIHtcbiAgICB0aGlzLnNldEZhc3QocG9zLCBiaXQpO1xuICAgIGlmIChub3RpZnkpXG4gICAgICB0aGlzLl92ZXJzaW9uKys7XG4gICAgZWxzZVxuICAgICAgdGhpcy5fdmVyc2lvbisrO1xuICB9XG5cbiAgLy8vIFNldHMgW2ldLXRoIGJpdCB0byBbdmFsdWVdLCBkb2VzIG5vdCBjaGVjayBib3VuZHMsIGRvZXMgbm90IGluY3JlbWVudCB2ZXJzaW9uXG4gIHNldEZhc3QoaTogbnVtYmVyLCB2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh2YWx1ZSlcbiAgICAgIHRoaXMuX2RhdGFbTWF0aC5mbG9vcihpIC8gMHgyMCldIHw9IDEgPDwgKGkgJiAweDFmKTtcbiAgICBlbHNlXG4gICAgICB0aGlzLl9kYXRhW01hdGguZmxvb3IoaSAvIDB4MjApXSAmPSB+KDEgPDwgKGkgJiAweDFmKSk7XG4gIH1cblxuICBzZXRUcnVlKHBvczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5fZGF0YVtNYXRoLmZsb29yKHBvcyAvIDB4MjApXSB8PSAxIDw8IChwb3MgJiAweDFmKTtcbiAgfVxuXG4gIHNldEZhbHNlKHBvczogbnVtYmVyKSB7XG4gICAgdGhpcy5fZGF0YVtNYXRoLmZsb29yKHBvcyAvIDB4MjApXSAmPSB+KDEgPDwgKHBvcyAmIDB4MWYpKTtcbiAgfVxuXG4gIHRydWVDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNvdW50Qml0cyh0cnVlKTtcbiAgfVxuXG4gIGZhbHNlQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jb3VudEJpdHMoZmFsc2UpO1xuICB9XG5cbiAgLy8vIENvdW50cyBiaXRzIG9mIHRoZSBzcGVjaWZpZWQgdmFsdWUuXG4gIGNvdW50Qml0cyh2YWx1ZTogYm9vbGVhbik6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCA9PSAwKSByZXR1cm4gMDtcblxuICAgIGlmICh0aGlzLl9zZWxlY3RlZENvdW50VmVyc2lvbiAhPSB0aGlzLl92ZXJzaW9uKSB7XG4gICAgICB0aGlzLl9zZWxlY3RlZENvdW50ID0gMDtcbiAgICAgIGNvbnN0IGxlbiA9IHRoaXMubGVuZ3RoSW5JbnRzO1xuICAgICAgbGV0IGkgPSAwO1xuICAgICAgZm9yICg7IGkgPCBsZW4gLSAxOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgayA9IHRoaXMuX2RhdGFbaV07IGsgIT0gMDsgayA+Pj49IDgpIHsgLy90b2RvOiBjYXN0IGRhdGFbaV0gdG8gdWludFxuICAgICAgICAgIHRoaXMuX3NlbGVjdGVkQ291bnQgKz0gQml0QXJyYXkuX29uQml0Q291bnRbayAmIDB4ZmZdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSBsYXN0IGludC5cbiAgICAgIGxldCBrID0gdGhpcy5fZGF0YVtpXTtcbiAgICAgIGNvbnN0IHJlbWFpbmluZ0JpdHMgPSB0aGlzLl9sZW5ndGggJiAweDFmO1xuICAgICAgaWYgKHJlbWFpbmluZ0JpdHMgIT0gMCkgLyogaWYgcmVtYWluaW5nQml0cyA9PSAwLCB0aGUgbGFzdCBpbnQgaXMgZnVsbHkgdXNlZCBhbmQgQUxMIGJpdHMgc2hvdWxkIGJlIGxlZnQgYXMgaXMgKi9cbiAgICAgICAgayAmPSB+KCg0Mjk0OTY3Mjk1KSA8PCByZW1haW5pbmdCaXRzKTtcblxuICAgICAgZm9yICg7IGsgIT0gMDsgayA+Pj49IDgpXG4gICAgICAgIHRoaXMuX3NlbGVjdGVkQ291bnQgKz0gQml0QXJyYXkuX29uQml0Q291bnRbayAmIDB4ZmZdO1xuXG4gICAgICB0aGlzLl9zZWxlY3RlZENvdW50VmVyc2lvbiA9IHRoaXMuX3ZlcnNpb247XG4gICAgfVxuXG4gICAgcmV0dXJuICh2YWx1ZSA/IHRoaXMuX3NlbGVjdGVkQ291bnQgOiB0aGlzLl9sZW5ndGggLSB0aGlzLl9zZWxlY3RlZENvdW50KTtcbiAgfVxuXG4gIC8vLyBSZXR1cm5zIGEgbnVtYmVyIG9mIHNldCBiaXRzIHdoZXJlIGFsc28gW2NoZWNrXSBpcyB0cnVlXG4gIGNvdW50V2hlcmUoY2hlY2s6IEZ1bmN0aW9uKTogbnVtYmVyIHtcbiAgICBsZXQgcmVzdWx0ID0gMDtcbiAgICBpZiAodGhpcy50cnVlQ291bnQoKSA9PSB0aGlzLl9sZW5ndGgpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbGVuZ3RoOyBpKyspXG4gICAgICAgIHJlc3VsdCArPSBjaGVjayhpKSA/IDEgOiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBpID0gLTE7IChpID0gdGhpcy5maW5kTmV4dChpLCB0cnVlKSkgIT0gLTE7KVxuICAgICAgICByZXN1bHQgKz0gY2hlY2soaSkgPyAxIDogMDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vLyBQZXJmb3JtcyBiaXQgXCJhbmRcIiBhbmQgY291bnRzIGJpdHMgb2YgdGhlIHNwZWNpZmllZCB2YWx1ZSwgd2l0aG91dCBiaXRzZXQgbW9kaWZpY2F0aW9uLlxuICBhbmRXaXRoQ291bnRCaXRzKHNlY29uZDogQml0QXJyYXksIHZhbHVlOiBib29sZWFuKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5fbGVuZ3RoID09IDApIHJldHVybiAwO1xuXG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBjb25zdCBsZW4gPSB0aGlzLmxlbmd0aEluSW50cztcbiAgICBsZXQgaSA9IDA7XG4gICAgZm9yICg7IGkgPCBsZW4gLSAxOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGsgPSB0aGlzLl9kYXRhW2ldICYgc2Vjb25kLl9kYXRhW2ldOyBrICE9IDA7IGsgPj4+PSA4KVxuICAgICAgICBjb3VudCArPSBCaXRBcnJheS5fb25CaXRDb3VudFtrICYgMHhmZl07XG4gICAgfVxuXG4gICAgLy8gVGhlIGxhc3QgaW50LlxuICAgIGxldCBrID0gdGhpcy5fZGF0YVtpXSAmIHNlY29uZC5fZGF0YVtpXTtcbiAgICBjb25zdCByZW1haW5pbmdCaXRzID0gdGhpcy5fbGVuZ3RoICYgMHgxZjtcbiAgICBpZiAocmVtYWluaW5nQml0cyAhPSAwKVxuICAgICAgayAmPSB+KCg0Mjk0OTY3Mjk1KSA8PCByZW1haW5pbmdCaXRzKTtcbiAgICBmb3IgKDsgayAhPSAwOyBrID4+Pj0gOClcbiAgICAgIGNvdW50ICs9IEJpdEFycmF5Ll9vbkJpdENvdW50W2sgJiAweGZmXTtcblxuICAgIHJldHVybiAodmFsdWUgPyBjb3VudCA6IHRoaXMuX2xlbmd0aCAtIGNvdW50KTtcbiAgfVxuXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuc2V0TGVuZ3RoKDApO1xuICB9XG5cbiAgY29udGFpbnModmFsdWU6IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5maW5kTmV4dCgtMSwgdmFsdWUpID49IDA7XG4gIH1cblxuICBnZXQgYWxsVHJ1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb3VudEJpdHModHJ1ZSkgPT0gdGhpcy5fbGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGFsbEZhbHNlKCkge1xuICAgIHJldHVybiB0aGlzLmNvdW50Qml0cyhmYWxzZSkgPT0gdGhpcy5fbGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGFueVRydWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuY291bnRCaXRzKHRydWUpID4gMDtcbiAgfVxuXG4gIGdldCBhbnlGYWxzZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb3VudEJpdHMoZmFsc2UpID4gMDtcbiAgfVxuXG4gIC8vLyBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgbmV4dCBiaXQgb2YgdGhlIHNwZWNpZmllZCB2YWx1ZSwgc3RhcnRpbmcgZnJvbSB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLlxuICAvLy8gUmV0dXJucyAtMSwgaWYgdGhlcmUgYXJlIG5vIHN1Y2ggYml0cy5cbiAgZmluZE5leHQoaW5kZXg6IG51bWJlciwgdmFsdWUgPSB0cnVlKTogbnVtYmVyIHtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UoaW5kZXgsIC0xLCB0aGlzLl9sZW5ndGgsICdpbmRleCcpO1xuXG4gICAgaWYgKGluZGV4ID49IHRoaXMuX2xlbmd0aCAtIDEpIHJldHVybiAtMTtcbiAgICBpbmRleCA9IGluZGV4IDwgMCA/IDAgOiBpbmRleCArIDE7IC8vIHNraXAgc3RhcnRcbiAgICBsZXQgdW51c2VkQml0cyA9IGluZGV4ICYgMHgxZjtcbiAgICBjb25zdCBudW1JbnRzID0gdGhpcy5sZW5ndGhJbkludHM7XG5cbiAgICBmb3IgKGxldCBpID0gTWF0aC5mbG9vcihpbmRleCAvIDMyKTsgaSA8IG51bUludHM7IGkrKykge1xuICAgICAgbGV0IGsgPSAodmFsdWUgPyB0aGlzLl9kYXRhW2ldIDogfnRoaXMuX2RhdGFbaV0pOyAvLyB1aW50IGNhc3RcbiAgICAgIGlmICh1bnVzZWRCaXRzICE9IDApIHtcbiAgICAgICAgayAmPSAoKDB4ZmZmZmZmZmYgPDwgdW51c2VkQml0cykgJiAweGZmZmZmZmZmKTtcbiAgICAgICAgdW51c2VkQml0cyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKCF2YWx1ZSAmJiBrID09IC00Mjk0OTY3Mjk2KSAvKiBsb29raW5nIGZvciBmYWxzZSwgYWxsIGJpdHMgYXJlIHNldCAqL3tcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBrICE9IDA7IGogKz0gOCwgayA+Pj49IDgpIHtcbiAgICAgICAgY29uc3QgcCA9IEJpdEFycmF5Ll9maXJzdE9uQml0W2sgJiAweGZmXTtcbiAgICAgICAgaWYgKHAgPj0gMCkge1xuICAgICAgICAgIGluZGV4ID0gcCArIChpICogMzIpICsgajtcbiAgICAgICAgICBpZiAoaW5kZXggPj0gdGhpcy5fbGVuZ3RoKSByZXR1cm4gLTE7XG4gICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIC8vLyBGaW5kcyBwcmV2aW91cyBiaXQgb2YgdGhlIHNwZWNpZmllZCB2YWx1ZSBpbiB0aGUgYml0c2V0LlxuICBmaW5kUHJldihpbmRleDogbnVtYmVyLCB2YWx1ZSA9IHRydWUpOiBudW1iZXIge1xuICAgIGlmIChpbmRleCA9PSAwKSByZXR1cm4gLTE7XG4gICAgdGhpcy5hc3N1cmVJblJhbmdlKGluZGV4LCAtMSwgdGhpcy5fbGVuZ3RoLCAnaW5kZXgnKTtcblxuICAgIGluZGV4ID0gaW5kZXggPCAwID8gdGhpcy5fbGVuZ3RoIC0gMSA6IGluZGV4IC0gMTsgLy8gc2tpcCBzdGFydFxuXG4gICAgY29uc3QgbGFzdEludElkeCA9IE1hdGguZmxvb3IoaW5kZXggLyAweDIwKTtcbiAgICBsZXQgcmVtYWluaW5nQml0cyA9IChpbmRleCArIDEpICYgMHgxZjtcblxuICAgIGZvciAobGV0IGkgPSBsYXN0SW50SWR4OyBpID49IDA7IGktLSkge1xuICAgICAgbGV0IGsgPSAodmFsdWUgPyB0aGlzLl9kYXRhW2ldIDogfnRoaXMuX2RhdGFbaV0pOyAvLyBjYXN0XG4gICAgICBpZiAocmVtYWluaW5nQml0cyAhPSAwKSB7XG4gICAgICAgIGsgJj0gfigoNDI5NDk2NzI5NSkgPDwgcmVtYWluaW5nQml0cyk7XG4gICAgICAgIHJlbWFpbmluZ0JpdHMgPSAwO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaiA9IDI0OyBrICE9IDA7IGogLT0gOCwgayA8PD0gOCkge1xuICAgICAgICBjb25zdCBwID0gQml0QXJyYXkuX2xhc3RPbkJpdFtrID4+PiAweDE4XTtcbiAgICAgICAgaWYgKHAgPj0gMClcbiAgICAgICAgICByZXR1cm4gcCArIChpICogMzIpICsgajtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG59XG4iXX0=","export function hamming(args = {}) {\n function getDistanceF() {\n if (!args || !args.scoringMatrix || !args.alphabetIndexes)\n return (a, b) => a === b ? 0 : 1;\n if (args.scoringMatrix.length !== Object.keys(args.alphabetIndexes).length)\n throw new Error('Scoring matrix and alphabet indexes should have the same length');\n const indexes = args.alphabetIndexes;\n const matrix = args.scoringMatrix;\n //const matrixMap = new Map<string, Map<string, number>>();\n //const map2: any = {};\n const minCharCode = Math.min(...Object.keys(indexes).map((k) => k.charCodeAt(0))) + 1;\n const scorringArray = new Float32Array((matrix.length + minCharCode) * (matrix.length + minCharCode));\n Object.entries(indexes).forEach(([key, index]) => {\n //matrixMap.set(key, new Map<string, number>());\n //map2[key] = {};\n const matrixRow = matrix[index];\n Object.entries(indexes).forEach(([key2, index2]) => {\n //matrixMap.get(key)!.set(key2, matrixRow[index2]);\n scorringArray[key.charCodeAt(0) * matrix.length + key2.charCodeAt(0)] = matrixRow[index2];\n //map2[key][key2] = matrixRow[index2];\n });\n });\n return (a, b) => {\n return 1 - scorringArray[a.charCodeAt(0) * matrix.length + b.charCodeAt(0)];\n };\n }\n const distanceF = getDistanceF();\n const threshold = args?.threshold ?? 0;\n return (seq1, seq2) => {\n // hamming distance should only be used with same size strings,\n // but still, lets add a check and if they are not same length add the difference to the result\n let diff = 0;\n const s1l = seq1.length;\n const s2l = seq2.length;\n const thresholdLimit = Math.ceil(Math.max(s1l, s2l) * (1 - threshold));\n if (s1l !== s2l)\n diff = Math.abs(s1l - s2l);\n let result = 0;\n for (let i = 0; i < Math.min(s1l, s2l); i++) {\n if (seq1[i] !== seq2[i]) {\n result += distanceF(seq1[i], seq2[i]);\n if (result > thresholdLimit)\n return 1;\n }\n }\n result += diff;\n result /= Math.max(s1l, s2l);\n return result;\n };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFtbWluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhhbW1pbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxVQUFVLE9BQU8sQ0FBQyxPQUF3QyxFQUFFO0lBQ2hFLFNBQVMsWUFBWTtRQUNuQixJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlO1lBQ3ZELE9BQU8sQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLE1BQU07WUFDeEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpRUFBaUUsQ0FBQyxDQUFDO1FBQ3JGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUNsQywyREFBMkQ7UUFDM0QsdUJBQXVCO1FBQ3ZCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXRGLE1BQU0sYUFBYSxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUN0RyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDL0MsZ0RBQWdEO1lBQ2hELGlCQUFpQjtZQUNqQixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsRUFBRSxFQUFFO2dCQUNqRCxtREFBbUQ7Z0JBQ25ELGFBQWEsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDMUYsc0NBQXNDO1lBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxFQUFFO1lBQzlCLE9BQU8sQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlFLENBQUMsQ0FBQztJQUNKLENBQUM7SUFDRCxNQUFNLFNBQVMsR0FBRyxZQUFZLEVBQUUsQ0FBQztJQUVqQyxNQUFNLFNBQVMsR0FBRyxJQUFJLEVBQUUsU0FBUyxJQUFJLENBQUMsQ0FBQztJQUV2QyxPQUFPLENBQUMsSUFBWSxFQUFFLElBQVksRUFBRSxFQUFFO1FBQ3BDLCtEQUErRDtRQUMvRCwrRkFBK0Y7UUFDL0YsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUN4QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3hCLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUN2RSxJQUFJLEdBQUcsS0FBSyxHQUFHO1lBQ2IsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBRTdCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNmLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzVDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUN4QixNQUFNLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEMsSUFBSSxNQUFNLEdBQUcsY0FBYztvQkFDekIsT0FBTyxDQUFDLENBQUM7WUFDYixDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sSUFBSSxJQUFJLENBQUM7UUFDZixNQUFNLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDN0IsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7bW1EaXN0YW5jZUZ1bmN0aW9uQXJncywgbW1EaXN0YW5jZUZ1bmN0aW9uVHlwZX0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW1taW5nKGFyZ3M6IFBhcnRpYWw8bW1EaXN0YW5jZUZ1bmN0aW9uQXJncz4gPSB7fSk6IG1tRGlzdGFuY2VGdW5jdGlvblR5cGUge1xuICBmdW5jdGlvbiBnZXREaXN0YW5jZUYoKTogKGE6IHN0cmluZywgYjogc3RyaW5nKSA9PiBudW1iZXIge1xuICAgIGlmICghYXJncyB8fCAhYXJncy5zY29yaW5nTWF0cml4IHx8ICFhcmdzLmFscGhhYmV0SW5kZXhlcylcbiAgICAgIHJldHVybiAoYTogc3RyaW5nLCBiOiBzdHJpbmcpID0+IGEgPT09IGIgPyAwIDogMTtcbiAgICBpZiAoYXJncy5zY29yaW5nTWF0cml4Lmxlbmd0aCAhPT0gT2JqZWN0LmtleXMoYXJncy5hbHBoYWJldEluZGV4ZXMpLmxlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2NvcmluZyBtYXRyaXggYW5kIGFscGhhYmV0IGluZGV4ZXMgc2hvdWxkIGhhdmUgdGhlIHNhbWUgbGVuZ3RoJyk7XG4gICAgY29uc3QgaW5kZXhlcyA9IGFyZ3MuYWxwaGFiZXRJbmRleGVzO1xuICAgIGNvbnN0IG1hdHJpeCA9IGFyZ3Muc2NvcmluZ01hdHJpeDtcbiAgICAvL2NvbnN0IG1hdHJpeE1hcCA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBudW1iZXI+PigpO1xuICAgIC8vY29uc3QgbWFwMjogYW55ID0ge307XG4gICAgY29uc3QgbWluQ2hhckNvZGUgPSBNYXRoLm1pbiguLi5PYmplY3Qua2V5cyhpbmRleGVzKS5tYXAoKGspID0+IGsuY2hhckNvZGVBdCgwKSkpICsgMTtcblxuICAgIGNvbnN0IHNjb3JyaW5nQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KChtYXRyaXgubGVuZ3RoICsgbWluQ2hhckNvZGUpICogKG1hdHJpeC5sZW5ndGggKyBtaW5DaGFyQ29kZSkpO1xuICAgIE9iamVjdC5lbnRyaWVzKGluZGV4ZXMpLmZvckVhY2goKFtrZXksIGluZGV4XSkgPT4ge1xuICAgICAgLy9tYXRyaXhNYXAuc2V0KGtleSwgbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKSk7XG4gICAgICAvL21hcDJba2V5XSA9IHt9O1xuICAgICAgY29uc3QgbWF0cml4Um93ID0gbWF0cml4W2luZGV4XTtcbiAgICAgIE9iamVjdC5lbnRyaWVzKGluZGV4ZXMpLmZvckVhY2goKFtrZXkyLCBpbmRleDJdKSA9PiB7XG4gICAgICAgIC8vbWF0cml4TWFwLmdldChrZXkpIS5zZXQoa2V5MiwgbWF0cml4Um93W2luZGV4Ml0pO1xuICAgICAgICBzY29ycmluZ0FycmF5W2tleS5jaGFyQ29kZUF0KDApICogbWF0cml4Lmxlbmd0aCArIGtleTIuY2hhckNvZGVBdCgwKV0gPSBtYXRyaXhSb3dbaW5kZXgyXTtcbiAgICAgICAgLy9tYXAyW2tleV1ba2V5Ml0gPSBtYXRyaXhSb3dbaW5kZXgyXTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiAoYTogc3RyaW5nLCBiOiBzdHJpbmcpID0+IHtcbiAgICAgIHJldHVybiAxIC0gc2NvcnJpbmdBcnJheVthLmNoYXJDb2RlQXQoMCkgKiBtYXRyaXgubGVuZ3RoICsgYi5jaGFyQ29kZUF0KDApXTtcbiAgICB9O1xuICB9XG4gIGNvbnN0IGRpc3RhbmNlRiA9IGdldERpc3RhbmNlRigpO1xuXG4gIGNvbnN0IHRocmVzaG9sZCA9IGFyZ3M/LnRocmVzaG9sZCA/PyAwO1xuXG4gIHJldHVybiAoc2VxMTogc3RyaW5nLCBzZXEyOiBzdHJpbmcpID0+IHtcbiAgICAvLyBoYW1taW5nIGRpc3RhbmNlIHNob3VsZCBvbmx5IGJlIHVzZWQgd2l0aCBzYW1lIHNpemUgc3RyaW5ncyxcbiAgICAvLyBidXQgc3RpbGwsIGxldHMgYWRkIGEgY2hlY2sgYW5kIGlmIHRoZXkgYXJlIG5vdCBzYW1lIGxlbmd0aCBhZGQgdGhlIGRpZmZlcmVuY2UgdG8gdGhlIHJlc3VsdFxuICAgIGxldCBkaWZmID0gMDtcbiAgICBjb25zdCBzMWwgPSBzZXExLmxlbmd0aDtcbiAgICBjb25zdCBzMmwgPSBzZXEyLmxlbmd0aDtcbiAgICBjb25zdCB0aHJlc2hvbGRMaW1pdCA9IE1hdGguY2VpbChNYXRoLm1heChzMWwsIHMybCkgKiAoMSAtIHRocmVzaG9sZCkpO1xuICAgIGlmIChzMWwgIT09IHMybClcbiAgICAgIGRpZmYgPSBNYXRoLmFicyhzMWwgLSBzMmwpO1xuXG4gICAgbGV0IHJlc3VsdCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNYXRoLm1pbihzMWwsIHMybCk7IGkrKykge1xuICAgICAgaWYgKHNlcTFbaV0gIT09IHNlcTJbaV0pIHtcbiAgICAgICAgcmVzdWx0ICs9IGRpc3RhbmNlRihzZXExW2ldLCBzZXEyW2ldKTtcbiAgICAgICAgaWYgKHJlc3VsdCA+IHRocmVzaG9sZExpbWl0KVxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQgKz0gZGlmZjtcbiAgICByZXN1bHQgLz0gTWF0aC5tYXgoczFsLCBzMmwpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59XG4iXX0=","// Blosum 62 matrix for protein sequences\nconst BLOSUM62 = [[4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3, -2, 0, -2, -1, 0, -4],\n [-1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3, -2, -3, -1, 0, -1, -4],\n [-2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3, 0, -2, -3, -2, 1, 0, -4, -2, -3, 3, 0, -1, -4],\n [-2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4, -3, -3, 4, 1, -1, -4],\n [0, -3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1, -2, -2, -1, -3, -3, -2, -4],\n [-1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1, -2, 0, 3, -1, -4],\n [-1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3, 1, -2, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1, -4],\n [0, -2, 0, -1, -3, -2, -2, 6, -2, -4, -4, -2, -3, -3, -2, 0, -2, -2, -3, -3, -1, -2, -1, -4],\n [-2, 0, 1, -1, -3, 0, 0, -2, 8, -3, -3, -1, -2, -1, -2, -1, -2, -2, 2, -3, 0, 0, -1, -4],\n [-1, -3, -3, -3, -1, -3, -3, -4, -3, 4, 2, -3, 1, 0, -3, -2, -1, -3, -1, 3, -3, -3, -1, -4],\n [-1, -2, -3, -4, -1, -2, -3, -4, -3, 2, 4, -2, 2, 0, -3, -2, -1, -2, -1, 1, -4, -3, -1, -4],\n [-1, 2, 0, -1, -3, 1, 1, -2, -1, -3, -2, 5, -1, -3, -1, 0, -1, -3, -2, -2, 0, 1, -1, -4],\n [-1, -1, -2, -3, -1, 0, -2, -3, -2, 1, 2, -1, 5, 0, -2, -1, -1, -1, -1, 1, -3, -1, -1, -4],\n [-2, -3, -3, -3, -2, -3, -3, -3, -1, 0, 0, -3, 0, 6, -4, -2, -2, 1, 3, -1, -3, -3, -1, -4],\n [-1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4, 7, -1, -1, -4, -3, -2, -2, -1, -2, -4],\n [1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2, 0, -1, -2, -1, 4, 1, -3, -2, -2, 0, 0, 0, -4],\n [0, -1, 0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1, 1, 5, -2, -2, 0, -1, -1, 0, -4],\n [-3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1, 1, -4, -3, -2, 11, 2, -3, -4, -3, -2, -4],\n [-2, -2, -2, -3, -2, -1, -2, -3, 2, -1, -1, -2, -1, 3, -3, -2, -2, 2, 7, -1, -3, -2, -1, -4],\n [0, -3, -3, -3, -1, -2, -2, -3, -3, 3, 1, -2, 1, -1, -2, -2, 0, -3, -1, 4, -3, -2, -1, -4],\n [-2, -1, 3, 4, -3, 0, 1, -1, 0, -3, -4, 0, -3, -3, -2, 0, -1, -4, -3, -3, 4, 1, -1, -4],\n [-1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3, 1, -1, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1, -4],\n [0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 0, 0, -2, -1, -1, -1, -1, -1, -4],\n [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 1]];\n// Protein indexes for BLOSUM matrix\nconst ProtIndexes = {\n 'A': 0, 'R': 1, 'N': 2, 'D': 3, 'C': 4, 'Q': 5, 'E': 6, 'G': 7, 'H': 8,\n 'I': 9, 'L': 10, 'K': 11, 'M': 12, 'F': 13, 'P': 14, 'S': 15, 'T': 16,\n 'W': 17, 'Y': 18, 'V': 19, 'B': 20, 'Z': 21, 'X': 22, '*': 23\n};\nconst defaultArgs = {\n gapOpen: 1,\n gapExtend: 0.6,\n scoringMatrix: BLOSUM62,\n alphabetIndexes: ProtIndexes\n};\n/** Returns a function that calculates the distance between two sequences based on gap penalty and matrix\n * @param {Partial<NeedlemanWunschArgs>}args - arguments for Needleman-Wunsch algorithm like gap penalty, Scoring matrix..\n * @return {mmDistanceFunctionType} - function that calculates the distance between two sequences\n*/\nexport function needlemanWunsch(args) {\n const maxLen = 10000;\n const charCodeArray = new Uint16Array(0x10000);\n const { gapOpen, gapExtend, scoringMatrix, alphabetIndexes } = { ...defaultArgs, ...args };\n Object.entries(alphabetIndexes).forEach(([k, v]) => charCodeArray[k.charCodeAt(0)] = v);\n // As we don't need traceback, no need to store the whole matrix\n // Instead, we will store only the last two rows\n const matrix = [\n new Float32Array(maxLen),\n new Float32Array(maxLen)\n ];\n return (seq1, seq2) => {\n // similarly, we need to keep track of what operation led to the current cell\n // i.e. whether we came from the left, top or diagonal to assign gap open/gap extend penalty\n const verticalGaps = new Array(seq1.length + 1).fill(false);\n const horizontalGaps = new Array(seq1.length + 1).fill(false);\n //variables to keep track which row we are in\n // they will swap places on each iteration\n let prevRow = 0;\n let currRow = 1;\n // Initialize first row\n for (let i = 1; i < seq1.length + 1; i++) {\n matrix[0][i] = -gapExtend - (i - 1) * gapExtend;\n matrix[1][i] = 0;\n }\n matrix[0][0] = 0;\n // Calculate the rest of the matrix\n for (let i = 1; i < seq2.length + 1; i++) {\n matrix[currRow][0] = -gapExtend - (i - 1) * gapExtend;\n for (let j = 1; j < seq1.length + 1; j++) {\n const diagonal = matrix[prevRow][j - 1] +\n scoringMatrix[charCodeArray[seq1.charCodeAt(j - 1)]][charCodeArray[seq2.charCodeAt(i - 1)]];\n const top = matrix[prevRow][j] - (verticalGaps[j] || i === 1 || i === seq2.length ? gapExtend : gapOpen);\n const left = matrix[currRow][j - 1] - (horizontalGaps[j - 1] || j === 1 || j === seq1.length ? gapExtend : gapOpen);\n matrix[currRow][j] = Math.max(diagonal, left, top);\n // update gap arrays\n if (matrix[currRow][j] === diagonal) {\n verticalGaps[j] = false;\n horizontalGaps[j] = false;\n }\n else if (matrix[currRow][j] === left) {\n verticalGaps[j] = false;\n horizontalGaps[j] = true;\n }\n else {\n verticalGaps[j] = true;\n horizontalGaps[j] = false;\n }\n }\n // Swap rows\n prevRow = currRow;\n currRow = (currRow + 1) % 2;\n }\n // as the matrix is the similarity matrix, but we are interested in distance,\n // we need compare it to perfect match score to get reasonable distance\n // const perfectMatchSeq1 = seq1.split('').map((c) => scoringMatrix[alphabetIndexes[c]][alphabetIndexes[c]])\n // .reduce((a, b) => a + b, 0);\n // const perfectMatchSeq2 = seq2.split('').map((c) => scoringMatrix[alphabetIndexes[c]][alphabetIndexes[c]])\n // .reduce((a, b) => a + b, 0);\n // const maxScore = Math.max(perfectMatchSeq1, perfectMatchSeq2);\n const maxScore = Math.min(seq1.length, seq2.length);\n return (maxScore - matrix[prevRow][seq1.length]) / maxScore;\n };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVlZGxlbWFuLXd1bnNjaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm5lZWRsZW1hbi13dW5zY2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EseUNBQXlDO0FBQ3pDLE1BQU0sUUFBUSxHQUNkLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNwRixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6RixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3JGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RGLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzVGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN4RixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDM0YsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzNGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN4RixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzFGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDL0YsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNwRixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzFGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUYsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RGLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0YsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFD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QUNELDZFQUE2RTtRQUM3RSx1RUFBdUU7UUFDdkUsNEdBQTRHO1FBQzVHLGlDQUFpQztRQUNqQyw0R0FBNEc7UUFDNUcsaUNBQWlDO1FBQ2pDLGlFQUFpRTtRQUNqRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BELE9BQU8sQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQztJQUM5RCxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25BcmdzLCBtbURpc3RhbmNlRnVuY3Rpb25UeXBlfSBmcm9tICcuL3R5cGVzJztcblxuLy8gQmxvc3VtIDYyIG1hdHJpeCBmb3IgcHJvdGVpbiBzZXF1ZW5jZXNcbmNvbnN0IEJMT1NVTTYyOkFycmF5PEFycmF5PG51bWJlcj4+ID1cbltbNCwgLTEsIC0yLCAtMiwgMCwgLTEsIC0xLCAwLCAtMiwgLTEsIC0xLCAtMSwgLTEsIC0yLCAtMSwgMSwgMCwgLTMsIC0yLCAwLCAtMiwgLTEsIDAsIC00XSxcbiAgWy0xLCA1LCAwLCAtMiwgLTMsIDEsIDAsIC0yLCAwLCAtMywgLTIsIDIsIC0xLCAtMywgLTIsIC0xLCAtMSwgLTMsIC0yLCAtMywgLTEsIDAsIC0xLCAtNF0sXG4gIFstMiwgMCwgNiwgMSwgLTMsIDAsIDAsIDAsIDEsIC0zLCAtMywgMCwgLTIsIC0zLCAtMiwgMSwgMCwgLTQsIC0yLCAtMywgMywgMCwgLTEsIC00XSxcbiAgWy0yLCAtMiwgMSwgNiwgLTMsIDAsIDIsIC0xLCAtMSwgLTMsIC00LCAtMSwgLTMsIC0zLCAtMSwgMCwgLTEsIC00LCAtMywgLTMsIDQsIDEsIC0xLCAtNF0sXG4gIFswLCAtMywgLTMsIC0zLCA5LCAtMywgLTQsIC0zLCAtMywgLTEsIC0xLCAtMywgLTEsIC0yLCAtMywgLTEsIC0xLCAtMiwgLTIsIC0xLCAtMywgLTMsIC0yLCAtNF0sXG4gIFstMSwgMSwgMCwgMCwgLTMsIDUsIDIsIC0yLCAwLCAtMywgLTIsIDEsIDAsIC0zLCAtMSwgMCwgLTEsIC0yLCAtMSwgLTIsIDAsIDMsIC0xLCAtNF0sXG4gIFstMSwgMCwgMCwgMiwgLTQsIDIsIDUsIC0yLCAwLCAtMywgLTMsIDEsIC0yLCAtMywgLTEsIDAsIC0xLCAtMywgLTIsIC0yLCAxLCA0LCAtMSwgLTRdLFxuICBbMCwgLTIsIDAsIC0xLCAtMywgLTIsIC0yLCA2LCAtMiwgLTQsIC00LCAtMiwgLTMsIC0zLCAtMiwgMCwgLTIsIC0yLCAtMywgLTMsIC0xLCAtMiwgLTEsIC00XSxcbiAgWy0yLCAwLCAxLCAtMSwgLTMsIDAsIDAsIC0yLCA4LCAtMywgLTMsIC0xLCAtMiwgLTEsIC0yLCAtMSwgLTIsIC0yLCAyLCAtMywgMCwgMCwgLTEsIC00XSxcbiAgWy0xLCAtMywgLTMsIC0zLCAtMSwgLTMsIC0zLCAtNCwgLTMsIDQsIDIsIC0zLCAxLCAwLCAtMywgLTIsIC0xLCAtMywgLTEsIDMsIC0zLCAtMywgLTEsIC00XSxcbiAgWy0xLCAtMiwgLTMsIC00LCAtMSwgLTIsIC0zLCAtNCwgLTMsIDIsIDQsIC0yLCAyLCAwLCAtMywgLTIsIC0xLCAtMiwgLTEsIDEsIC00LCAtMywgLTEsIC00XSxcbiAgWy0xLCAyLCAwLCAtMSwgLTMsIDEsIDEsIC0yLCAtMSwgLTMsIC0yLCA1LCAtMSwgLTMsIC0xLCAwLCAtMSwgLTMsIC0yLCAtMiwgMCwgMSwgLTEsIC00XSxcbiAgWy0xLCAtMSwgLTIsIC0zLCAtMSwgMCwgLTIsIC0zLCAtMiwgMSwgMiwgLTEsIDUsIDAsIC0yLCAtMSwgLTEsIC0xLCAtMSwgMSwgLTMsIC0xLCAtMSwgLTRdLFxuICBbLTIsIC0zLCAtMywgLTMsIC0yLCAtMywgLTMsIC0zLCAtMSwgMCwgMCwgLTMsIDAsIDYsIC00LCAtMiwgLTIsIDEsIDMsIC0xLCAtMywgLTMsIC0xLCAtNF0sXG4gIFstMSwgLTIsIC0yLCAtMSwgLTMsIC0xLCAtMSwgLTIsIC0yLCAtMywgLTMsIC0xLCAtMiwgLTQsIDcsIC0xLCAtMSwgLTQsIC0zLCAtMiwgLTIsIC0xLCAtMiwgLTRdLFxuICBbMSwgLTEsIDEsIDAsIC0xLCAwLCAwLCAwLCAtMSwgLTIsIC0yLCAwLCAtMSwgLTIsIC0xLCA0LCAxLCAtMywgLTIsIC0yLCAwLCAwLCAwLCAtNF0sXG4gIFswLCAtMSwgMCwgLTEsIC0xLCAtMSwgLTEsIC0yLCAtMiwgLTEsIC0xLCAtMSwgLTEsIC0yLCAtMSwgMSwgNSwgLTIsIC0yLCAwLCAtMSwgLTEsIDAsIC00XSxcbiAgWy0zLCAtMywgLTQsIC00LCAtMiwgLTIsIC0zLCAtMiwgLTIsIC0zLCAtMiwgLTMsIC0xLCAxLCAtNCwgLTMsIC0yLCAxMSwgMiwgLTMsIC00LCAtMywgLTIsIC00XSxcbiAgWy0yLCAtMiwgLTIsIC0zLCAtMiwgLTEsIC0yLCAtMywgMiwgLTEsIC0xLCAtMiwgLTEsIDMsIC0zLCAtMiwgLTIsIDIsIDcsIC0xLCAtMywgLTIsIC0xLCAtNF0sXG4gIFswLCAtMywgLTMsIC0zLCAtMSwgLTIsIC0yLCAtMywgLTMsIDMsIDEsIC0yLCAxLCAtMSwgLTIsIC0yLCAwLCAtMywgLTEsIDQsIC0zLCAtMiwgLTEsIC00XSxcbiAgWy0yLCAtMSwgMywgNCwgLTMsIDAsIDEsIC0xLCAwLCAtMywgLTQsIDAsIC0zLCAtMywgLTIsIDAsIC0xLCAtNCwgLTMsIC0zLCA0LCAxLCAtMSwgLTRdLFxuICBbLTEsIDAsIDAsIDEsIC0zLCAzLCA0LCAtMiwgMCwgLTMsIC0zLCAxLCAtMSwgLTMsIC0xLCAwLCAtMSwgLTMsIC0yLCAtMiwgMSwgNCwgLTEsIC00XSxcbiAgWzAsIC0xLCAtMSwgLTEsIC0yLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMiwgMCwgMCwgLTIsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTRdLFxuICBbLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAxXV07XG5cbi8vIFByb3RlaW4gaW5kZXhlcyBmb3IgQkxPU1VNIG1hdHJpeFxuY29uc3QgUHJvdEluZGV4ZXM6IHtbaWQ6c3RyaW5nXTpudW1iZXJ9ID0ge1xuICAnQSc6IDAsICdSJzogMSwgJ04nOiAyLCAnRCc6IDMsICdDJzogNCwgJ1EnOiA1LCAnRSc6IDYsICdHJzogNywgJ0gnOiA4LFxuICAnSSc6IDksICdMJzogMTAsICdLJzogMTEsICdNJzogMTIsICdGJzogMTMsICdQJzogMTQsICdTJzogMTUsICdUJzogMTYsXG4gICdXJzogMTcsICdZJzogMTgsICdWJzogMTksICdCJzogMjAsICdaJzogMjEsICdYJzogMjIsICcqJzogMjNcbn07XG5cbnR5cGUgTmVlZGxlbWFuV3Vuc2NoQXJncyA9IG1tRGlzdGFuY2VGdW5jdGlvbkFyZ3MgJiB7XG4gIGdhcE9wZW46IG51bWJlcjtcbiAgZ2FwRXh0ZW5kOiBudW1iZXI7XG59XG5cbmNvbnN0IGRlZmF1bHRBcmdzOiBOZWVkbGVtYW5XdW5zY2hBcmdzID0ge1xuICBnYXBPcGVuOiAxLFxuICBnYXBFeHRlbmQ6IDAuNixcbiAgc2NvcmluZ01hdHJpeDogQkxPU1VNNjIsXG4gIGFscGhhYmV0SW5kZXhlczogUHJvdEluZGV4ZXNcbn07XG5cbi8qKiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBjYWxjdWxhdGVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byBzZXF1ZW5jZXMgYmFzZWQgb24gZ2FwIHBlbmFsdHkgYW5kIG1hdHJpeFxuICogQHBhcmFtIHtQYXJ0aWFsPE5lZWRsZW1hbld1bnNjaEFyZ3M+fWFyZ3MgLSBhcmd1bWVudHMgZm9yIE5lZWRsZW1hbi1XdW5zY2ggYWxnb3JpdGhtIGxpa2UgZ2FwIHBlbmFsdHksIFNjb3JpbmcgbWF0cml4Li5cbiAqIEByZXR1cm4ge21tRGlzdGFuY2VGdW5jdGlvblR5cGV9IC0gZnVuY3Rpb24gdGhhdCBjYWxjdWxhdGVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byBzZXF1ZW5jZXNcbiovXG5leHBvcnQgZnVuY3Rpb24gbmVlZGxlbWFuV3Vuc2NoKGFyZ3M6IFBhcnRpYWw8TmVlZGxlbWFuV3Vuc2NoQXJncz4pOiBtbURpc3RhbmNlRnVuY3Rpb25UeXBlIHtcbiAgY29uc3QgbWF4TGVuID0gMTAwMDA7XG4gIGNvbnN0IGNoYXJDb2RlQXJyYXkgPSBuZXcgVWludDE2QXJyYXkoMHgxMDAwMCk7XG5cbiAgY29uc3Qge2dhcE9wZW4sIGdhcEV4dGVuZCwgc2NvcmluZ01hdHJpeCwgYWxwaGFiZXRJbmRleGVzfSA9IHsuLi5kZWZhdWx0QXJncywgLi4uYXJnc307XG4gIE9iamVjdC5lbnRyaWVzKGFscGhhYmV0SW5kZXhlcykuZm9yRWFjaCgoW2ssIHZdKSA9PiBjaGFyQ29kZUFycmF5W2suY2hhckNvZGVBdCgwKV0gPSB2KTtcbiAgLy8gQXMgd2UgZG9uJ3QgbmVlZCB0cmFjZWJhY2ssIG5vIG5lZWQgdG8gc3RvcmUgdGhlIHdob2xlIG1hdHJpeFxuICAvLyBJbnN0ZWFkLCB3ZSB3aWxsIHN0b3JlIG9ubHkgdGhlIGxhc3QgdHdvIHJvd3NcbiAgY29uc3QgbWF0cml4OiBBcnJheTxGbG9hdDMyQXJyYXk+ID0gW1xuICAgIG5ldyBGbG9hdDMyQXJyYXkobWF4TGVuKSxcbiAgICBuZXcgRmxvYXQzMkFycmF5KG1heExlbilcbiAgXTtcbiAgcmV0dXJuIChzZXExOiBzdHJpbmcsIHNlcTI6IHN0cmluZykgOiBudW1iZXIgPT4ge1xuICAgIC8vIHNpbWlsYXJseSwgd2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIHdoYXQgb3BlcmF0aW9uIGxlZCB0byB0aGUgY3VycmVudCBjZWxsXG4gICAgLy8gaS5lLiB3aGV0aGVyIHdlIGNhbWUgZnJvbSB0aGUgbGVmdCwgdG9wIG9yIGRpYWdvbmFsIHRvIGFzc2lnbiBnYXAgb3Blbi9nYXAgZXh0ZW5kIHBlbmFsdHlcblxuICAgIGNvbnN0IHZlcnRpY2FsR2FwczogYm9vbGVhbltdID0gbmV3IEFycmF5PGJvb2xlYW4+KHNlcTEubGVuZ3RoICsxKS5maWxsKGZhbHNlKTtcbiAgICBjb25zdCBob3Jpem9udGFsR2FwczogYm9vbGVhbltdID0gbmV3IEFycmF5PGJvb2xlYW4+KHNlcTEubGVuZ3RoICsxKS5maWxsKGZhbHNlKTtcbiAgICAvL3ZhcmlhYmxlcyB0byBrZWVwIHRyYWNrIHdoaWNoIHJvdyB3ZSBhcmUgaW5cbiAgICAvLyB0aGV5IHdpbGwgc3dhcCBwbGFjZXMgb24gZWFjaCBpdGVyYXRpb25cbiAgICBsZXQgcHJldlJvdyA9IDA7XG4gICAgbGV0IGN1cnJSb3cgPSAxO1xuICAgIC8vIEluaXRpYWxpemUgZmlyc3Qgcm93XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBzZXExLmxlbmd0aCArIDE7IGkrKykge1xuICAgICAgbWF0cml4WzBdW2ldID0gLWdhcEV4dGVuZCAtIChpIC0gMSkgKiBnYXBFeHRlbmQ7XG4gICAgICBtYXRyaXhbMV1baV0gPSAwO1xuICAgIH1cbiAgICBtYXRyaXhbMF1bMF0gPSAwO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHRoZSByZXN0IG9mIHRoZSBtYXRyaXhcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHNlcTIubGVuZ3RoICsgMTsgaSsrKSB7XG4gICAgICBtYXRyaXhbY3VyclJvd11bMF0gPSAtZ2FwRXh0ZW5kIC0gKGkgLSAxKSAqIGdhcEV4dGVuZDtcbiAgICAgIGZvciAobGV0IGogPSAxOyBqIDwgc2VxMS5sZW5ndGggKyAxOyBqKyspIHtcbiAgICAgICAgY29uc3QgZGlhZ29uYWwgPVxuICAgICAgICAgIG1hdHJpeFtwcmV2Um93XVtqIC0gMV0gK1xuICAgICAgICAgICAgc2NvcmluZ01hdHJpeFtjaGFyQ29kZUFycmF5W3NlcTEuY2hhckNvZGVBdChqIC0gMSldXVtjaGFyQ29kZUFycmF5W3NlcTIuY2hhckNvZGVBdChpIC0gMSldXTtcbiAgICAgICAgY29uc3QgdG9wID0gbWF0cml4W3ByZXZSb3ddW2pdIC0gKHZlcnRpY2FsR2Fwc1tqXSB8fCBpID09PSAxIHx8IGkgPT09IHNlcTIubGVuZ3RoID8gZ2FwRXh0ZW5kIDogZ2FwT3BlbiApO1xuICAgICAgICBjb25zdCBsZWZ0ID0gbWF0cml4W2N1cnJSb3ddW2ogLSAxXSAtIChob3Jpem9udGFsR2Fwc1tqIC0gMV0gfHwgaiA9PT0gMSB8fCBqID09PSBzZXExLmxlbmd0aCA/IGdhcEV4dGVuZCA6IGdhcE9wZW4pO1xuICAgICAgICBtYXRyaXhbY3VyclJvd11bal0gPSBNYXRoLm1heChcbiAgICAgICAgICBkaWFnb25hbCwgbGVmdCwgdG9wXG4gICAgICAgICk7XG4gICAgICAgIC8vIHVwZGF0ZSBnYXAgYXJyYXlzXG4gICAgICAgIGlmIChtYXRyaXhbY3VyclJvd11bal0gPT09IGRpYWdvbmFsKSB7XG4gICAgICAgICAgdmVydGljYWxHYXBzW2pdID0gZmFsc2U7XG4gICAgICAgICAgaG9yaXpvbnRhbEdhcHNbal0gPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmIChtYXRyaXhbY3VyclJvd11bal0gPT09IGxlZnQpIHtcbiAgICAgICAgICB2ZXJ0aWNhbEdhcHNbal0gPSBmYWxzZTtcbiAgICAgICAgICBob3Jpem9udGFsR2Fwc1tqXSA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmVydGljYWxHYXBzW2pdID0gdHJ1ZTtcbiAgICAgICAgICBob3Jpem9udGFsR2Fwc1tqXSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBTd2FwIHJvd3NcbiAgICAgIHByZXZSb3cgPSBjdXJyUm93O1xuICAgICAgY3VyclJvdyA9IChjdXJyUm93ICsgMSkgJSAyO1xuICAgIH1cbiAgICAvLyBhcyB0aGUgbWF0cml4IGlzIHRoZSBzaW1pbGFyaXR5IG1hdHJpeCwgYnV0IHdlIGFyZSBpbnRlcmVzdGVkIGluIGRpc3RhbmNlLFxuICAgIC8vIHdlIG5lZWQgY29tcGFyZSBpdCB0byBwZXJmZWN0IG1hdGNoIHNjb3JlIHRvIGdldCByZWFzb25hYmxlIGRpc3RhbmNlXG4gICAgLy8gY29uc3QgcGVyZmVjdE1hdGNoU2VxMSA9IHNlcTEuc3BsaXQoJycpLm1hcCgoYykgPT4gc2NvcmluZ01hdHJpeFthbHBoYWJldEluZGV4ZXNbY11dW2FscGhhYmV0SW5kZXhlc1tjXV0pXG4gICAgLy8gICAucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCk7XG4gICAgLy8gY29uc3QgcGVyZmVjdE1hdGNoU2VxMiA9IHNlcTIuc3BsaXQoJycpLm1hcCgoYykgPT4gc2NvcmluZ01hdHJpeFthbHBoYWJldEluZGV4ZXNbY11dW2FscGhhYmV0SW5kZXhlc1tjXV0pXG4gICAgLy8gICAucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCk7XG4gICAgLy8gY29uc3QgbWF4U2NvcmUgPSBNYXRoLm1heChwZXJmZWN0TWF0Y2hTZXExLCBwZXJmZWN0TWF0Y2hTZXEyKTtcbiAgICBjb25zdCBtYXhTY29yZSA9IE1hdGgubWluKHNlcTEubGVuZ3RoLCBzZXEyLmxlbmd0aCk7XG4gICAgcmV0dXJuIChtYXhTY29yZSAtIG1hdHJpeFtwcmV2Um93XVtzZXExLmxlbmd0aF0pIC8gbWF4U2NvcmU7XG4gIH07XG59XG4iXX0=","import { hamming } from './hamming';\nimport { levenstein } from './levenstein';\nimport { needlemanWunsch } from './needleman-wunsch';\n/** Enum containing currently supported macromolecule distance functions\n * Hamming distance will be used if the sequences are already aligned\n * Needleman distance will be used for protein sequences with known BLOSUM62 matrix\n * Levenshtein distance will be used for nucleotide sequences as for them substitution matrix is same as identity matrix\n */\nexport var MmDistanceFunctionsNames;\n(function (MmDistanceFunctionsNames) {\n MmDistanceFunctionsNames[\"HAMMING\"] = \"Hamming\";\n MmDistanceFunctionsNames[\"LEVENSHTEIN\"] = \"Levenshtein\";\n MmDistanceFunctionsNames[\"NEEDLEMANN_WUNSCH\"] = \"Needlemann-Wunsch\";\n MmDistanceFunctionsNames[\"MONOMER_CHEMICAL_DISTANCE\"] = \"Monomer chemical distance\";\n})(MmDistanceFunctionsNames || (MmDistanceFunctionsNames = {}));\n;\nexport const mmDistanceFunctions = {\n [MmDistanceFunctionsNames.HAMMING]: hamming,\n [MmDistanceFunctionsNames.LEVENSHTEIN]: levenstein,\n [MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH]: needlemanWunsch,\n [MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE]: hamming\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjcm9tb2xlY3VsZS1kaXN0YW5jZS1mdW5jdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNyb21vbGVjdWxlLWRpc3RhbmNlLWZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBR25EOzs7O0dBSUc7QUFDSCxNQUFNLENBQU4sSUFBWSx3QkFLWDtBQUxELFdBQVksd0JBQXdCO0lBQ2xDLCtDQUFtQixDQUFBO0lBQ25CLHVEQUEyQixDQUFBO0lBQzNCLG1FQUF1QyxDQUFBO0lBQ3ZDLG1GQUF1RCxDQUFBO0FBQ3pELENBQUMsRUFMVyx3QkFBd0IsS0FBeEIsd0JBQXdCLFFBS25DO0FBQUEsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUE4RTtJQUM1RyxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU87SUFDM0MsQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxVQUFVO0lBQ2xELENBQUMsd0JBQXdCLENBQUMsaUJBQWlCLENBQUMsRUFBRSxlQUFlO0lBQzdELENBQUMsd0JBQXdCLENBQUMseUJBQXlCLENBQUMsRUFBRSxPQUFPO0NBQzlELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2hhbW1pbmd9IGZyb20gJy4vaGFtbWluZyc7XG5pbXBvcnQge2xldmVuc3RlaW59IGZyb20gJy4vbGV2ZW5zdGVpbic7XG5pbXBvcnQge25lZWRsZW1hbld1bnNjaH0gZnJvbSAnLi9uZWVkbGVtYW4td3Vuc2NoJztcbmltcG9ydCB7bW1EaXN0YW5jZUZ1bmN0aW9uVHlwZX0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKiBFbnVtIGNvbnRhaW5pbmcgY3VycmVudGx5IHN1cHBvcnRlZCBtYWNyb21vbGVjdWxlIGRpc3RhbmNlIGZ1bmN0aW9uc1xuICogSGFtbWluZyBkaXN0YW5jZSB3aWxsIGJlIHVzZWQgaWYgdGhlIHNlcXVlbmNlcyBhcmUgYWxyZWFkeSBhbGlnbmVkXG4gKiBOZWVkbGVtYW4gZGlzdGFuY2Ugd2lsbCBiZSB1c2VkIGZvciBwcm90ZWluIHNlcXVlbmNlcyB3aXRoIGtub3duIEJMT1NVTTYyIG1hdHJpeFxuICogTGV2ZW5zaHRlaW4gZGlzdGFuY2Ugd2lsbCBiZSB1c2VkIGZvciBudWNsZW90aWRlIHNlcXVlbmNlcyBhcyBmb3IgdGhlbSBzdWJzdGl0dXRpb24gbWF0cml4IGlzIHNhbWUgYXMgaWRlbnRpdHkgbWF0cml4XG4gKi9cbmV4cG9ydCBlbnVtIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB7XG4gIEhBTU1JTkcgPSAnSGFtbWluZycsXG4gIExFVkVOU0hURUlOID0gJ0xldmVuc2h0ZWluJyxcbiAgTkVFRExFTUFOTl9XVU5TQ0ggPSAnTmVlZGxlbWFubi1XdW5zY2gnLFxuICBNT05PTUVSX0NIRU1JQ0FMX0RJU1RBTkNFID0gJ01vbm9tZXIgY2hlbWljYWwgZGlzdGFuY2UnXG59O1xuXG5leHBvcnQgY29uc3QgbW1EaXN0YW5jZUZ1bmN0aW9uczogUmVjb3JkPE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcywgKHZhbHVlPzogYW55KSA9PiBtbURpc3RhbmNlRnVuY3Rpb25UeXBlPiA9IHtcbiAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5IQU1NSU5HXTogaGFtbWluZyxcbiAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5MRVZFTlNIVEVJTl06IGxldmVuc3RlaW4sXG4gIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTkVFRExFTUFOTl9XVU5TQ0hdOiBuZWVkbGVtYW5XdW5zY2gsXG4gIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTU9OT01FUl9DSEVNSUNBTF9ESVNUQU5DRV06IGhhbW1pbmdcbn07XG4iXX0=","import { distance } from 'fastest-levenshtein';\nexport function levenstein() {\n return (seq1, seq2) => {\n return distance(seq1, seq2) / Math.max(seq1.length, seq2.length);\n };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGV2ZW5zdGVpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxldmVuc3RlaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRzdDLE1BQU0sVUFBVSxVQUFVO0lBQ3hCLE9BQU8sQ0FBQyxJQUFZLEVBQUUsSUFBWSxFQUFFLEVBQUU7UUFDcEMsT0FBTyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkUsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7ZGlzdGFuY2V9IGZyb20gJ2Zhc3Rlc3QtbGV2ZW5zaHRlaW4nO1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25UeXBlfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGxldmVuc3RlaW4oKTogbW1EaXN0YW5jZUZ1bmN0aW9uVHlwZSB7XG4gIHJldHVybiAoc2VxMTogc3RyaW5nLCBzZXEyOiBzdHJpbmcpID0+IHtcbiAgICByZXR1cm4gZGlzdGFuY2Uoc2VxMSwgc2VxMikgLyBNYXRoLm1heChzZXExLmxlbmd0aCwgc2VxMi5sZW5ndGgpO1xuICB9O1xufVxuIl19","import BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport { BitArrayMetricsNames } from './typed-metrics/consts';\nimport { MmDistanceFunctionsNames } from './macromolecule-distance-functions';\nexport const similarityMetric = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoSimilarity,\n [BitArrayMetricsNames.Dice]: diceSimilarity,\n [BitArrayMetricsNames.Asymmetric]: asymmetricSimilarity,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetSimilarity,\n [BitArrayMetricsNames.Cosine]: cosineSimilarity,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiSimilarity,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheySimilarity,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergSimilarity,\n [BitArrayMetricsNames.Russel]: russelSimilarity,\n [BitArrayMetricsNames.Sokal]: sokalSimilarity,\n [BitArrayMetricsNames.Hamming]: hammingSimilarity,\n [BitArrayMetricsNames.Euclidean]: euclideanSimilarity,\n};\nexport const distanceMetrics = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoDistance,\n [BitArrayMetricsNames.Dice]: diceDistance,\n [BitArrayMetricsNames.Asymmetric]: asymmetricDistance,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetDistance,\n [BitArrayMetricsNames.Cosine]: cosineDistance,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiDistance,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheyDistance,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergDistance,\n [BitArrayMetricsNames.Russel]: russelDistance,\n [BitArrayMetricsNames.Sokal]: sokalDistance,\n [BitArrayMetricsNames.Hamming]: hammingDistance,\n [BitArrayMetricsNames.Euclidean]: euclideanDistance,\n};\nexport const CHEM_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Dice,\n BitArrayMetricsNames.Cosine\n];\nexport const SEQ_SPACE_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Asymmetric,\n BitArrayMetricsNames.Cosine,\n BitArrayMetricsNames.Sokal\n];\nexport const MACROMOLECULE_SIMILARITY_METRICS = [\n MmDistanceFunctionsNames.HAMMING,\n MmDistanceFunctionsNames.LEVENSHTEIN,\n MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE,\n MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH\n];\nexport function tanimotoSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 1.0;\n const common = x.andWithCountBits(y, true);\n return common / (total - common);\n}\nexport function tanimotoDistance(x, y) {\n return 1 - tanimotoSimilarity(x, y);\n}\nexport function tanimotoDistanceIntArray(x, y) {\n const xb = new BitArray(x, x.length * 32);\n const yb = new BitArray(y, y.length * 32);\n return getDistanceFromSimilarity(tanimotoSimilarity(xb, yb));\n}\nexport function diceSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return 2 * common / total;\n}\nexport function diceDistance(x, y) {\n return 1 - diceSimilarity(x, y);\n}\nexport function cosineSimilarity(x, y) {\n const total = x.trueCount() * y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / Math.sqrt(total);\n}\nexport function cosineDistance(x, y) {\n return 1 - cosineSimilarity(x, y);\n}\nexport function euclideanSimilarity(x, y) {\n return getSimilarityFromDistance(euclideanDistance(x, y));\n}\nexport function euclideanDistance(x, y) {\n return Math.sqrt(x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true));\n}\nexport function hammingSimilarity(x, y) {\n return getSimilarityFromDistance(hammingDistance(x, y));\n}\nexport function hammingDistance(x, y) {\n return x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true);\n}\nexport function sokalSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const common = x.andWithCountBits(y, true);\n return common / (2 * total - 3 * common);\n}\nexport function sokalDistance(x, y) {\n return 1 - sokalSimilarity(x, y);\n}\nexport function kulczynskiSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total) / (2 * totalProd);\n}\nexport function kulczynskiDistance(x, y) {\n return getDistanceFromSimilarity(kulczynskiSimilarity(x, y));\n}\nexport function mcConnaugheySimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total - totalProd) / totalProd;\n}\nexport function mcConnaugheyDistance(x, y) {\n return getDistanceFromSimilarity(mcConnaugheySimilarity(x, y));\n}\nexport function asymmetricSimilarity(x, y) {\n const min = Math.min(x.trueCount(), y.trueCount());\n if (min == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / min;\n}\nexport function asymmetricDistance(x, y) {\n return 1 - asymmetricSimilarity(x, y);\n}\nexport function braunBlanquetSimilarity(x, y) {\n const max = Math.max(x.trueCount(), y.trueCount());\n if (max == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / max;\n}\nexport function braunBlanquetDistance(x, y) {\n return getDistanceFromSimilarity(braunBlanquetSimilarity(x, y));\n}\nexport function russelSimilarity(x, y) {\n if (x.length == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / x.length;\n}\nexport function russelDistance(x, y) {\n return getDistanceFromSimilarity(russelSimilarity(x, y));\n}\nexport function rogotGoldbergSimilarity(x, y) {\n const common = x.andWithCountBits(y, true);\n const total = x.countBits(true) + y.countBits(true);\n const len = x.length;\n const diff = len - total + common;\n if ((common == len) || (diff == len))\n return 1.0;\n else\n return common / total + diff / (2 * len - total);\n}\nexport function rogotGoldbergDistance(x, y) {\n return getDistanceFromSimilarity(rogotGoldbergSimilarity(x, y));\n}\nexport function getSimilarityFromDistance(distance) {\n return 1 / (1 + distance);\n}\nexport function getDistanceFromSimilarity(similarity) {\n return similarity === 0 ? 3.402823E+38 : (1 / similarity) - 1;\n}\nexport function numericDistance(args) {\n if (args && args.range != undefined && args.range > 0) {\n const range = args.range;\n return (a, b) => Math.abs(a - b) / range;\n }\n return (a, b) => Math.abs(a - b);\n}\nexport function commonItemsCount(args) {\n const mostCommon = args?.mostCommon ?? new Set();\n return (arr1, arr2) => {\n const len1 = arr1.length;\n const len2 = arr2.length;\n let count = 0;\n let i1 = 0;\n let i2 = 0;\n while ((i1 < len1) && (i2 < len2)) {\n if (arr1[i1] === arr2[i2]) {\n if (!mostCommon?.has(arr1[i1]))\n ++count;\n ++i1;\n ++i2;\n }\n else if (arr1[i1] < arr2[i2]) {\n ++i1;\n }\n else {\n ++i2;\n }\n }\n return count;\n };\n}\nexport function inverseCommonItemsCount(args) {\n const f = commonItemsCount(args);\n return (arr1, arr2) => {\n if (arr2.length === 0 || arr1.length === 0)\n return 10000;\n return Math.min(arr1.length, arr2.length) / (f(arr1, arr2) + 0.0001);\n };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sUUFBUSxNQUFNLHlDQUF5QyxDQUFDO0FBQy9ELE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBRTVFLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUE2RDtJQUN4RixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFLGtCQUFrQjtJQUNuRCxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFLGNBQWM7SUFDM0MsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxvQkFBb0I7SUFDdkQsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsRUFBRSx1QkFBdUI7SUFDN0QsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxnQkFBZ0I7SUFDL0MsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxvQkFBb0I7SUFDdkQsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsRUFBRSxzQkFBc0I7SUFDM0QsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsRUFBRSx1QkFBdUI7SUFDN0QsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxnQkFBZ0I7SUFDL0MsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFlO0lBQzdDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLEVBQUUsaUJBQWlCO0lBQ2pELENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLEVBQUUsbUJBQW1CO0NBQ3RELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQTZEO0lBQ3ZGLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLEVB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QkFDVixFQUFFLEVBQUUsQ0FBQztnQkFDTCxFQUFFLEVBQUUsQ0FBQztZQUNQLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQUMsRUFBRSxFQUFFLENBQUM7WUFBQyxDQUFDO2lCQUFNLENBQUM7Z0JBQUMsRUFBRSxFQUFFLENBQUM7WUFBQyxDQUFDO1FBQzFELENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsdUJBQXVCLENBQUMsSUFBaUM7SUFDdkUsTUFBTSxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsT0FBTyxDQUFDLElBQXVCLEVBQUUsSUFBdUIsRUFBRSxFQUFFO1FBQzFELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQ3hDLE9BQU8sS0FBSyxDQUFDO1FBRWYsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQztJQUN2RSxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQge0JpdEFycmF5TWV0cmljc05hbWVzfSBmcm9tICcuL3R5cGVkLW1ldHJpY3MvY29uc3RzJztcbmltcG9ydCB7TW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzfSBmcm9tICcuL21hY3JvbW9sZWN1bGUtZGlzdGFuY2UtZnVuY3Rpb25zJztcblxuZXhwb3J0IGNvbnN0IHNpbWlsYXJpdHlNZXRyaWM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9dOiB0YW5pbW90b1NpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXTogZGljZVNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXTogYXN5bW1ldHJpY1NpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XTogYnJhdW5CbGFucXVldFNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdOiBjb3NpbmVTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV06IGt1bGN6eW5za2lTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuTWNDb25uYXVnaGV5XTogbWNDb25uYXVnaGV5U2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddOiByb2dvdEdvbGRiZXJnU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJ1c3NlbF06IHJ1c3NlbFNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF06IHNva2FsU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkhhbW1pbmddOiBoYW1taW5nU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGV1Y2xpZGVhblNpbWlsYXJpdHksXG59O1xuXG5leHBvcnQgY29uc3QgZGlzdGFuY2VNZXRyaWNzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KSA9PiBudW1iZXIgfSA9IHtcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXTogdGFuaW1vdG9EaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkRpY2VdOiBkaWNlRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXTogYXN5bW1ldHJpY0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQnJhdW5CbGFucXVldF06IGJyYXVuQmxhbnF1ZXREaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV06IGNvc2luZURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV06IGt1bGN6eW5za2lEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLk1jQ29ubmF1Z2hleV06IG1jQ29ubmF1Z2hleURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUm9nb3RHb2xkYmVyZ106IHJvZ290R29sZGJlcmdEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJ1c3NlbF06IHJ1c3NlbERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdOiBzb2thbERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuSGFtbWluZ106IGhhbW1pbmdEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGV1Y2xpZGVhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IENIRU1fU0lNSUxBUklUWV9NRVRSSUNTID0gW1xuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90byxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZSxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTtcbmV4cG9ydCBjb25zdCBTRVFfU1BBQ0VfU0lNSUxBUklUWV9NRVRSSUNTID0gW1xuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90byxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpYyxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF07XG5leHBvcnQgY29uc3QgTUFDUk9NT0xFQ1VMRV9TSU1JTEFSSVRZX01FVFJJQ1MgPSBbXG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5IQU1NSU5HLFxuICBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU4sXG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5NT05PTUVSX0NIRU1JQ0FMX0RJU1RBTkNFLFxuICBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTkVFRExFTUFOTl9XVU5TQ0hcbl07XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHRhbmltb3RvU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWwgPT0gMCkgcmV0dXJuIDEuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gKHRvdGFsIC0gY29tbW9uKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRhbmltb3RvRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIDEgLSB0YW5pbW90b1NpbWlsYXJpdHkoeCwgeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0YW5pbW90b0Rpc3RhbmNlSW50QXJyYXkoeDogVWludDMyQXJyYXksIHk6IFVpbnQzMkFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgeGIgPSBuZXcgQml0QXJyYXkoeCwgeC5sZW5ndGggKiAzMik7XG4gIGNvbnN0IHliID0gbmV3IEJpdEFycmF5KHksIHkubGVuZ3RoICogMzIpO1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eSh0YW5pbW90b1NpbWlsYXJpdHkoeGIsIHliKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWNlU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWwgPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gMiAqIGNvbW1vbiAvIHRvdGFsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGljZURpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiAxIC0gZGljZVNpbWlsYXJpdHkoeCwgeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmVTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSAqIHkudHJ1ZUNvdW50KCk7XG4gIGlmICh0b3RhbCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyBNYXRoLnNxcnQodG90YWwpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29zaW5lRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIDEgLSBjb3NpbmVTaW1pbGFyaXR5KHgsIHkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXVjbGlkZWFuU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZShldWNsaWRlYW5EaXN0YW5jZSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldWNsaWRlYW5EaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5zcXJ0KHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpIC0gMiAqIHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW1taW5nU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZShoYW1taW5nRGlzdGFuY2UoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFtbWluZ0Rpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKSAtIDIgKiB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzb2thbFNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgdG90YWwgPSB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKTtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gKDIgKiB0b3RhbCAtIDMgKiBjb21tb24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc29rYWxEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gMSAtIHNva2FsU2ltaWxhcml0eSh4LCB5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGt1bGN6eW5za2lTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCk7XG4gIGNvbnN0IHRvdGFsUHJvZCA9IHgudHJ1ZUNvdW50KCkgKiB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWxQcm9kID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIChjb21tb24gKiB0b3RhbCkgLyAoMiAqIHRvdGFsUHJvZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBrdWxjenluc2tpRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoa3VsY3p5bnNraVNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWNDb25uYXVnaGV5U2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBjb25zdCB0b3RhbFByb2QgPSB4LnRydWVDb3VudCgpICogeS50cnVlQ291bnQoKTtcbiAgaWYgKHRvdGFsUHJvZCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiAoY29tbW9uICogdG90YWwgLSB0b3RhbFByb2QpIC8gdG90YWxQcm9kO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWNDb25uYXVnaGV5RGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkobWNDb25uYXVnaGV5U2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3ltbWV0cmljU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCBtaW4gPSBNYXRoLm1pbih4LnRydWVDb3VudCgpLCB5LnRydWVDb3VudCgpKTtcbiAgaWYgKG1pbiA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyBtaW47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3ltbWV0cmljRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIDEgLSBhc3ltbWV0cmljU2ltaWxhcml0eSh4LCB5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJyYXVuQmxhbnF1ZXRTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IG1heCA9IE1hdGgubWF4KHgudHJ1ZUNvdW50KCksIHkudHJ1ZUNvdW50KCkpO1xuICBpZiAobWF4ID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvIG1heDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJyYXVuQmxhbnF1ZXREaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShicmF1bkJsYW5xdWV0U2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydXNzZWxTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGlmICh4Lmxlbmd0aCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyB4Lmxlbmd0aDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1c3NlbERpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KHJ1c3NlbFNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcm9nb3RHb2xkYmVyZ1NpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICBjb25zdCB0b3RhbCA9IHguY291bnRCaXRzKHRydWUpICsgeS5jb3VudEJpdHModHJ1ZSk7XG4gIGNvbnN0IGxlbiA9IHgubGVuZ3RoO1xuICBjb25zdCBkaWZmID0gbGVuIC0gdG90YWwgKyBjb21tb247XG4gIGlmICgoY29tbW9uID09IGxlbikgfHwgKGRpZmYgPT0gbGVuKSkgcmV0dXJuIDEuMDtcbiAgZWxzZSByZXR1cm4gY29tbW9uIC8gdG90YWwgKyBkaWZmIC8gKDIgKiBsZW4gLSB0b3RhbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByb2dvdEdvbGRiZXJnRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkocm9nb3RHb2xkYmVyZ1NpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZShkaXN0YW5jZTogbnVtYmVyKSB7XG4gIHJldHVybiAxIC8gKDEgKyBkaXN0YW5jZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KHNpbWlsYXJpdHk6IG51bWJlcikgeyAvL2luIGNhc2Ugc2ltaWxhcml0eSBpcyAwLCB1c2UgbWF4IG51bWJlciBmb3IgZmxvYXQzMlxuICByZXR1cm4gc2ltaWxhcml0eSA9PT0gMCA/IDMuNDAyODIzRSszOCA6ICgxIC8gc2ltaWxhcml0eSkgLSAxO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbnVtZXJpY0Rpc3RhbmNlKGFyZ3M/OiB7cmFuZ2U/OiBudW1iZXJ9KSB7XG4gIGlmIChhcmdzICYmIGFyZ3MucmFuZ2UgIT0gdW5kZWZpbmVkICYmIGFyZ3MucmFuZ2UgPiAwKSB7XG4gICAgY29uc3QgcmFuZ2UgPSBhcmdzLnJhbmdlO1xuICAgIHJldHVybiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IE1hdGguYWJzKGEgLSBiKSAvIHJhbmdlO1xuICB9XG5cbiAgcmV0dXJuIChhOiBudW1iZXIsIGI6IG51bWJlcikgPT4gTWF0aC5hYnMoYSAtIGIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tbW9uSXRlbXNDb3VudChhcmdzPzoge21vc3RDb21tb24/OiBTZXQ8bnVtYmVyPn0pIHtcbiAgY29uc3QgbW9zdENvbW1vbiA9IGFyZ3M/Lm1vc3RDb21tb24gPz8gbmV3IFNldDxudW1iZXI+KCk7XG4gIHJldHVybiAoYXJyMTogQXJyYXlMaWtlPG51bWJlcj4sIGFycjI6IEFycmF5TGlrZTxudW1iZXI+KSA9PiB7XG4gICAgY29uc3QgbGVuMSA9IGFycjEubGVuZ3RoO1xuICAgIGNvbnN0IGxlbjIgPSBhcnIyLmxlbmd0aDtcbiAgICBsZXQgY291bnQgPSAwO1xuICAgIGxldCBpMSA9IDA7XG4gICAgbGV0IGkyID0gMDtcblxuICAgIHdoaWxlICgoaTEgPCBsZW4xKSAmJiAoaTIgPCBsZW4yKSkge1xuICAgICAgaWYgKGFycjFbaTFdID09PSBhcnIyW2kyXSkge1xuICAgICAgICBpZiAoIW1vc3RDb21tb24/LmhhcyhhcnIxW2kxXSkpXG4gICAgICAgICAgKytjb3VudDtcbiAgICAgICAgKytpMTtcbiAgICAgICAgKytpMjtcbiAgICAgIH0gZWxzZSBpZiAoYXJyMVtpMV0gPCBhcnIyW2kyXSkgeyArK2kxOyB9IGVsc2UgeyArK2kyOyB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvdW50O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW52ZXJzZUNvbW1vbkl0ZW1zQ291bnQoYXJncz86IHttb3N0Q29tbW9uPzogU2V0PG51bWJlcj59KSB7XG4gIGNvbnN0IGYgPSBjb21tb25JdGVtc0NvdW50KGFyZ3MpO1xuICByZXR1cm4gKGFycjE6IEFycmF5TGlrZTxudW1iZXI+LCBhcnIyOiBBcnJheUxpa2U8bnVtYmVyPikgPT4ge1xuICAgIGlmIChhcnIyLmxlbmd0aCA9PT0gMCB8fCBhcnIxLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiAxMDAwMDtcblxuICAgIHJldHVybiBNYXRoLm1pbihhcnIxLmxlbmd0aCwgYXJyMi5sZW5ndGgpIC8gKGYoYXJyMSwgYXJyMikgKyAwLjAwMDEpO1xuICB9O1xufVxuIl19","import * as fl from 'fastest-levenshtein';\nimport { jaroWinkler } from 'jaro-winkler-typescript';\nimport { asymmetricDistance, braunBlanquetDistance, cosineDistance, diceDistance, euclideanDistance, hammingDistance, kulczynskiDistance, mcConnaugheyDistance, rogotGoldbergDistance, russelDistance, sokalDistance, tanimotoDistance, numericDistance, tanimotoDistanceIntArray, inverseCommonItemsCount, } from '../distance-metrics-methods';\nimport { calculateEuclideanDistance } from '@datagrok-libraries/utils/src/vector-operations';\nimport { mmDistanceFunctions, MmDistanceFunctionsNames } from '../macromolecule-distance-functions';\nimport { DistanceMetricsSubjects, BitArrayMetricsNames, StringMetricsNames, VectorMetricsNames, NumberMetricsNames, IntArrayMetricsNames, NumberArrayMetricsNames } from './consts';\nexport const vectorDistanceMetricsMethods = {\n [VectorMetricsNames.Euclidean]: calculateEuclideanDistance,\n};\nexport const stringDistanceMetricsMethods = {\n [StringMetricsNames.Levenshtein]: fl.distance,\n [StringMetricsNames.JaroWinkler]: jaroWinkler,\n [StringMetricsNames.Manhattan]: manhattanDistance,\n [StringMetricsNames.Onehot]: categoricalDistance,\n};\nexport const bitArrayDistanceMetricsMethods = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoDistance,\n [BitArrayMetricsNames.Dice]: diceDistance,\n [BitArrayMetricsNames.Asymmetric]: asymmetricDistance,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetDistance,\n [BitArrayMetricsNames.Cosine]: cosineDistance,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiDistance,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheyDistance,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergDistance,\n [BitArrayMetricsNames.Russel]: russelDistance,\n [BitArrayMetricsNames.Sokal]: sokalDistance,\n [BitArrayMetricsNames.Hamming]: hammingDistance,\n [BitArrayMetricsNames.Euclidean]: euclideanDistance,\n};\nexport const intArrayDistanceMetricsMethods = {\n [IntArrayMetricsNames.TanimotoIntArray]: tanimotoDistanceIntArray,\n};\nexport const numberDistanceMetricsMethods = {\n [NumberMetricsNames.Difference]: numericDistance,\n};\nexport const numberArrayDistanceMetrics = {\n [NumberArrayMetricsNames.CommonItems]: inverseCommonItemsCount,\n};\nexport const AvailableMetrics = {\n [DistanceMetricsSubjects.Vector]: {\n [VectorMetricsNames.Euclidean]: vectorDistanceMetricsMethods[VectorMetricsNames.Euclidean],\n },\n [DistanceMetricsSubjects.String]: {\n [StringMetricsNames.Levenshtein]: stringDistanceMetricsMethods[StringMetricsNames.Levenshtein],\n [StringMetricsNames.JaroWinkler]: stringDistanceMetricsMethods[StringMetricsNames.JaroWinkler],\n [StringMetricsNames.Manhattan]: stringDistanceMetricsMethods[StringMetricsNames.Manhattan],\n [StringMetricsNames.Onehot]: stringDistanceMetricsMethods[StringMetricsNames.Onehot],\n },\n [DistanceMetricsSubjects.BitArray]: {\n [BitArrayMetricsNames.Tanimoto]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Tanimoto],\n [BitArrayMetricsNames.Dice]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Dice],\n [BitArrayMetricsNames.Asymmetric]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Asymmetric],\n [BitArrayMetricsNames.BraunBlanquet]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.BraunBlanquet],\n [BitArrayMetricsNames.Cosine]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Cosine],\n [BitArrayMetricsNames.Kulczynski]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Kulczynski],\n [BitArrayMetricsNames.McConnaughey]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.McConnaughey],\n [BitArrayMetricsNames.RogotGoldberg]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.RogotGoldberg],\n [BitArrayMetricsNames.Russel]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Russel],\n [BitArrayMetricsNames.Sokal]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Sokal],\n },\n [DistanceMetricsSubjects.MacroMolecule]: {\n [MmDistanceFunctionsNames.HAMMING]: mmDistanceFunctions[MmDistanceFunctionsNames.HAMMING],\n [MmDistanceFunctionsNames.LEVENSHTEIN]: mmDistanceFunctions[MmDistanceFunctionsNames.LEVENSHTEIN],\n [MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH]: mmDistanceFunctions[MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH],\n [MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE]: mmDistanceFunctions[MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE],\n },\n [DistanceMetricsSubjects.Number]: {\n [NumberMetricsNames.Difference]: numberDistanceMetricsMethods[NumberMetricsNames.Difference],\n },\n [DistanceMetricsSubjects.IntArray]: {\n [IntArrayMetricsNames.TanimotoIntArray]: intArrayDistanceMetricsMethods[IntArrayMetricsNames.TanimotoIntArray],\n },\n [DistanceMetricsSubjects.NumberArray]: {\n [NumberArrayMetricsNames.CommonItems]: numberArrayDistanceMetrics[NumberArrayMetricsNames.CommonItems],\n },\n};\nexport const MetricToDataType = Object.keys(AvailableMetrics)\n .reduce((ret, key) => {\n for (const val of Object.keys(AvailableMetrics[key]))\n ret[val] = key;\n return ret;\n}, {});\nexport function isStringMetric(name) {\n return MetricToDataType[name] == 'String';\n}\nexport function isBitArrayMetric(name) {\n return MetricToDataType[name] == 'BitArray';\n}\nexport function isVectorMetric(name) {\n return MetricToDataType[name] == 'Vector';\n}\nexport function isMacroMoleculeMetric(name) {\n return MetricToDataType[name] == DistanceMetricsSubjects.MacroMolecule.toString();\n}\nexport function isNumericMetric(name) {\n return MetricToDataType[name] == DistanceMetricsSubjects.Number.toString();\n}\nexport function isNumberArrayMetric(name) {\n return MetricToDataType[name] == DistanceMetricsSubjects.NumberArray.toString();\n}\n/** Manhattan distance between two sequences (match - 0, mismatch - 1) normalized for length. */\nexport function manhattanDistance(s1, s2) {\n if (s1.length !== s2.length) {\n return 1;\n }\n else {\n let dist = 0;\n for (let i = 1; i < s1.length; i++)\n dist += s1[i] == s2[i] ? 0 : 1;\n return dist / s1.length;\n }\n}\nexport function categoricalDistance(s1, s2) {\n return s1 === s2 ? 0 : 1;\n}\n/** Unified class implementing different string measures. */\nexport class Measure {\n /**\n * Creates an instance of Measure with .\n * @param {string} method Method to calculate distance between strings.\n * @memberof Measurer\n */\n constructor(method) {\n this.method = method;\n this.dataType = MetricToDataType[method];\n }\n /**\n * Returns true if the metric needs arguments to be calculated.\n * @param {KnownMetrics} method Metric to check if it needs arguments.\n * @return {boolean} True if the metric needs arguments.\n * @memberof Measure\n */\n metricNeedsArgs(method) {\n return isMacroMoleculeMetric(method) || isNumericMetric(method) || isNumberArrayMetric(method);\n }\n /**\n * Returns custom string distance function specified.\n * @param {opts} opts Options for the measure. used for macromolecule distances\n * @return {DistanceMetric} Callback of the measure chosen.\n * @memberof Measurer\n */\n getMeasure(opts) {\n const dict = AvailableMetrics;\n if (!dict.hasOwnProperty(this.dataType) || !dict[this.dataType].hasOwnProperty(this.method))\n throw new Error(`Unknown measure ${this.method} for data type ${this.dataType}`);\n return this.metricNeedsArgs(this.method) ?\n dict[this.dataType][this.method](opts) :\n dict[this.dataType][this.method];\n }\n /**\n * Returns custom string distance by the given data type.\n * @param {AvailableDataTypes} dataType Metric's data type\n * @return {string[]} Metric names which expects the given data type\n * @memberof Measurer\n */\n static getMetricByDataType(dataType) {\n return Object.keys(AvailableMetrics[dataType]);\n }\n /** Returns metric names available.\n * @memberof Measurer\n */\n static get availableMeasures() {\n return Object.keys(AvailableMetrics);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWQtbWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInR5cGVkLW1ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxQyxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFcEQsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixxQkFBcUIsRUFDckIsY0FBYyxFQUNkLFlBQVksRUFDWixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZix3QkFBd0IsRUFDeEIsdUJBQXVCLEdBQ3hCLE1BQU0sNkJBQTZCLENBQUM7QUFFckMsT0FBTyxFQUFDLDBCQUEwQixFQUFDLE1BQU0saURBQWlELENBQUM7QUFHM0YsT0FBTyxFQUFDLG1CQUFtQixFQUFFLHdCQUF3QixFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDbEcsT0FBTyxFQUFDLHVCQUF1QixFQUFFLG9CQUFvQixFQUNuRCxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxvQkFBb0IsRUFDaEYsdUJBQXVCLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFHM0MsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQXlEO0lBQ2hHLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsMEJBQTBCO0NBQzNELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBeUQ7SUFDaEcsQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUTtJQUM3QyxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxFQUFFLFdBQVc7SUFDN0MsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxpQkFBaUI7SUFDakQsQ0FBQyxrQkFBa0Is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QUFNLENBQUMsSUFBSSxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakcsQ0FBQztJQUNEOzs7OztPQUtHO0lBQ0ksVUFBVSxDQUFDLElBQVU7UUFDMUIsTUFBTSxJQUFJLEdBRU4sZ0JBQWdCLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUN6RixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixJQUFJLENBQUMsTUFBTSxrQkFBa0IsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDbkYsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBcUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzdFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBbUIsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsbUJBQW1CLENBQUMsUUFBNEI7UUFDNUQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxLQUFLLGlCQUFpQjtRQUMxQixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmbCBmcm9tICdmYXN0ZXN0LWxldmVuc2h0ZWluJztcbmltcG9ydCB7amFyb1dpbmtsZXJ9IGZyb20gJ2phcm8td2lua2xlci10eXBlc2NyaXB0JztcbmltcG9ydCB7RGlzdGFuY2VNZXRyaWN9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7XG4gIGFzeW1tZXRyaWNEaXN0YW5jZSxcbiAgYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBjb3NpbmVEaXN0YW5jZSxcbiAgZGljZURpc3RhbmNlLFxuICBldWNsaWRlYW5EaXN0YW5jZSxcbiAgaGFtbWluZ0Rpc3RhbmNlLFxuICBrdWxjenluc2tpRGlzdGFuY2UsXG4gIG1jQ29ubmF1Z2hleURpc3RhbmNlLFxuICByb2dvdEdvbGRiZXJnRGlzdGFuY2UsXG4gIHJ1c3NlbERpc3RhbmNlLFxuICBzb2thbERpc3RhbmNlLFxuICB0YW5pbW90b0Rpc3RhbmNlLFxuICBudW1lcmljRGlzdGFuY2UsXG4gIHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSxcbiAgaW52ZXJzZUNvbW1vbkl0ZW1zQ291bnQsXG59IGZyb20gJy4uL2Rpc3RhbmNlLW1ldHJpY3MtbWV0aG9kcyc7XG5cbmltcG9ydCB7Y2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2V9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3ZlY3Rvci1vcGVyYXRpb25zJztcbmltcG9ydCBCaXRBcnJheSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy9iaXQtYXJyYXknO1xuaW1wb3J0IHtWZWN0b3IsIFN0cmluZ0RpY3Rpb25hcnl9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7bW1EaXN0YW5jZUZ1bmN0aW9ucywgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzfSBmcm9tICcuLi9tYWNyb21vbGVjdWxlLWRpc3RhbmNlLWZ1bmN0aW9ucyc7XG5pbXBvcnQge0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLCBCaXRBcnJheU1ldHJpY3NOYW1lcyxcbiAgU3RyaW5nTWV0cmljc05hbWVzLCBWZWN0b3JNZXRyaWNzTmFtZXMsIE51bWJlck1ldHJpY3NOYW1lcywgSW50QXJyYXlNZXRyaWNzTmFtZXMsXG4gIE51bWJlckFycmF5TWV0cmljc05hbWVzfSBmcm9tICcuL2NvbnN0cyc7XG5cblxuZXhwb3J0IGNvbnN0IHZlY3RvckRpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBWZWN0b3IsIHk6IFZlY3RvcikgPT4gbnVtYmVyIH0gPSB7XG4gIFtWZWN0b3JNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogY2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2UsXG59O1xuXG5leHBvcnQgY29uc3Qgc3RyaW5nRGlzdGFuY2VNZXRyaWNzTWV0aG9kczogeyBbbmFtZTogc3RyaW5nXTogKHg6IHN0cmluZywgeTogc3RyaW5nKSA9PiBudW1iZXIgfSA9IHtcbiAgW1N0cmluZ01ldHJpY3NOYW1lcy5MZXZlbnNodGVpbl06IGZsLmRpc3RhbmNlLFxuICBbU3RyaW5nTWV0cmljc05hbWVzLkphcm9XaW5rbGVyXTogamFyb1dpbmtsZXIsXG4gIFtTdHJpbmdNZXRyaWNzTmFtZXMuTWFuaGF0dGFuXTogbWFuaGF0dGFuRGlzdGFuY2UsXG4gIFtTdHJpbmdNZXRyaWNzTmFtZXMuT25laG90XTogY2F0ZWdvcmljYWxEaXN0YW5jZSxcbn07XG5cbmV4cG9ydCBjb25zdCBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9dOiB0YW5pbW90b0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV06IGRpY2VEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkFzeW1tZXRyaWNdOiBhc3ltbWV0cmljRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XTogYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTogY29zaW5lRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5LdWxjenluc2tpXToga3VsY3p5bnNraURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuTWNDb25uYXVnaGV5XTogbWNDb25uYXVnaGV5RGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXTogcm9nb3RHb2xkYmVyZ0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXTogcnVzc2VsRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF06IHNva2FsRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5IYW1taW5nXTogaGFtbWluZ0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogZXVjbGlkZWFuRGlzdGFuY2UsXG59O1xuXG5leHBvcnQgY29uc3QgaW50QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogVWludDMyQXJyYXksIHk6IFVpbnQzMkFycmF5KSA9PiBudW1iZXIgfSA9IHtcbiAgW0ludEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvSW50QXJyYXldOiB0YW5pbW90b0Rpc3RhbmNlSW50QXJyYXksXG59O1xuXG5leHBvcnQgY29uc3QgbnVtYmVyRGlzdGFuY2VNZXRyaWNzTWV0aG9kczogeyBbbmFtZTogc3RyaW5nXTogKGFyZ3M6IGFueSkgPT4gKHg6IG51bWJlciwgeTogbnVtYmVyKSA9PiBudW1iZXIgfSA9IHtcbiAgW051bWJlck1ldHJpY3NOYW1lcy5EaWZmZXJlbmNlXTogbnVtZXJpY0Rpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IG51bWJlckFycmF5RGlzdGFuY2VNZXRyaWNzOlxueyBbbmFtZTogc3RyaW5nXTogKGFyZ3M6IGFueSkgPT4gKHg6IEFycmF5TGlrZTxudW1iZXI+LCB5OiBBcnJheUxpa2U8bnVtYmVyPikgPT4gbnVtYmVyIH0gPSB7XG4gIFtOdW1iZXJBcnJheU1ldHJpY3NOYW1lcy5Db21tb25JdGVtc106IGludmVyc2VDb21tb25JdGVtc0NvdW50LFxufTtcblxuZXhwb3J0IGNvbnN0IEF2YWlsYWJsZU1ldHJpY3MgPSB7XG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5WZWN0b3JdOiB7XG4gICAgW1ZlY3Rvck1ldHJpY3NOYW1lcy5FdWNsaWRlYW5dOiB2ZWN0b3JEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1ZlY3Rvck1ldHJpY3NOYW1lcy5FdWNsaWRlYW5dLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuU3RyaW5nXToge1xuICAgIFtTdHJpbmdNZXRyaWNzTmFtZXMuTGV2ZW5zaHRlaW5dOiBzdHJpbmdEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1N0cmluZ01ldHJpY3NOYW1lcy5MZXZlbnNodGVpbl0sXG4gICAgW1N0cmluZ01ldHJpY3NOYW1lcy5KYXJvV2lua2xlcl06IHN0cmluZ0Rpc3RhbmNlTWV0cmljc01ldGhvZHNbU3RyaW5nTWV0cmljc05hbWVzLkphcm9XaW5rbGVyXSxcbiAgICBbU3RyaW5nTWV0cmljc05hbWVzLk1hbmhhdHRhbl06IHN0cmluZ0Rpc3RhbmNlTWV0cmljc01ldGhvZHNbU3RyaW5nTWV0cmljc05hbWVzLk1hbmhhdHRhbl0sXG4gICAgW1N0cmluZ01ldHJpY3NOYW1lcy5PbmVob3RdOiBzdHJpbmdEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1N0cmluZ01ldHJpY3NOYW1lcy5PbmVob3RdLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuQml0QXJyYXldOiB7XG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpY106IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQnJhdW5CbGFucXVldF06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLkt1bGN6eW5za2ldOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLk1jQ29ubmF1Z2hleV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5SdXNzZWxdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuTWFjcm9Nb2xlY3VsZV06IHsgLy8gb3B0aW9uYWwgYXJncyBuZWVkZWQgZm9yIG1hY3JvbW9sZWN1bGUgZnVuY3Rpb25zIHdoaWNoIGluaXRpYWxpemUgdGhlbVxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuSEFNTUlOR106IG1tRGlzdGFuY2VGdW5jdGlvbnNbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkddLFxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU5dOiBtbURpc3RhbmNlRnVuY3Rpb25zW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5MRVZFTlNIVEVJTl0sXG4gICAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5ORUVETEVNQU5OX1dVTlNDSF06IG1tRGlzdGFuY2VGdW5jdGlvbnNbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk5FRURMRU1BTk5fV1VOU0NIXSxcbiAgICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk1PTk9NRVJfQ0hFTUlDQUxfRElTVEFOQ0VdOlxuICAgICAgbW1EaXN0YW5jZUZ1bmN0aW9uc1tNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTU9OT01FUl9DSEVNSUNBTF9ESVNUQU5DRV0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5OdW1iZXJdOiB7XG4gICAgW051bWJlck1ldHJpY3NOYW1lcy5EaWZmZXJlbmNlXTogbnVtYmVyRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tOdW1iZXJNZXRyaWNzTmFtZXMuRGlmZmVyZW5jZV0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5JbnRBcnJheV06IHtcbiAgICBbSW50QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9JbnRBcnJheV06IGludEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tJbnRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b0ludEFycmF5XSxcbiAgfSxcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLk51bWJlckFycmF5XToge1xuICAgIFtOdW1iZXJBcnJheU1ldHJpY3NOYW1lcy5Db21tb25JdGVtc106IG51bWJlckFycmF5RGlzdGFuY2VNZXRyaWNzW051bWJlckFycmF5TWV0cmljc05hbWVzLkNvbW1vbkl0ZW1zXSxcbiAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBNZXRyaWNUb0RhdGFUeXBlOiBTdHJpbmdEaWN0aW9uYXJ5ID0gT2JqZWN0LmtleXMoQXZhaWxhYmxlTWV0cmljcylcbiAgLnJlZHVjZSgocmV0OiBTdHJpbmdEaWN0aW9uYXJ5LCBrZXkpID0+IHtcbiAgICBmb3IgKGNvbnN0IHZhbCBvZiBPYmplY3Qua2V5cyhBdmFpbGFibGVNZXRyaWNzW2tleSBhcyBBdmFpbGFibGVEYXRhVHlwZXNdKSlcbiAgICAgIHJldFt2YWwgYXMgQXZhaWxhYmxlRGF0YVR5cGVzXSA9IGtleTtcblxuICAgIHJldHVybiByZXQ7XG4gIH0sIHt9KTtcblxuZXhwb3J0IHR5cGUgQXZhaWxhYmxlRGF0YVR5cGVzID0ga2V5b2YgdHlwZW9mIEF2YWlsYWJsZU1ldHJpY3M7XG5leHBvcnQgdHlwZSBWZWN0b3JNZXRyaWNzID0ga2V5b2YgdHlwZW9mIEF2YWlsYWJsZU1ldHJpY3NbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuVmVjdG9yXTtcbmV4cG9ydCB0eXBlIFN0cmluZ01ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5TdHJpbmddO1xuZXhwb3J0IHR5cGUgQml0QXJyYXlNZXRyaWNzID0ga2V5b2YgdHlwZW9mIEF2YWlsYWJsZU1ldHJpY3NbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuQml0QXJyYXldO1xuZXhwb3J0IHR5cGUgTnVtYmVyTWV0cmljcyA9IGtleW9mIHR5cGVvZiBBdmFpbGFibGVNZXRyaWNzW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLk51bWJlcl07XG5leHBvcnQgdHlwZSBJbnRBcnJheU1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5JbnRBcnJheV07XG5leHBvcnQgdHlwZSBOdW1iZXJBcnJheU1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5OdW1iZXJBcnJheV07XG5leHBvcnQgdHlwZSBLbm93bk1ldHJpY3MgPSBTdHJpbmdNZXRyaWNzIHwgQml0QXJyYXlNZXRyaWNzIHwgVmVjdG9yTWV0cmljcyB8XG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB8IE51bWJlck1ldHJpY3NOYW1lcyB8IEludEFycmF5TWV0cmljc05hbWVzIHwgTnVtYmVyQXJyYXlNZXRyaWNzTmFtZXM7XG5cbmV4cG9ydCB0eXBlIFZhbGlkVHlwZXMgPVxuICB7IGRhdGE6IHN0cmluZ1tdLCBtZXRyaWM6IFN0cmluZ01ldHJpY3MgfCBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMgfSB8XG4gIHsgZGF0YTogVmVjdG9yW10sIG1ldHJpYzogVmVjdG9yTWV0cmljcyB9IHxcbiAgeyBkYXRhOiBCaXRBcnJheVtdLCBtZXRyaWM6IEJpdEFycmF5TWV0cmljcyB9IHxcbiAgeyBkYXRhOiBudW1iZXJbXSwgbWV0cmljOiBOdW1iZXJNZXRyaWNzTmFtZXMgfTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nTWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSAnU3RyaW5nJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQml0QXJyYXlNZXRyaWMobmFtZTogS25vd25NZXRyaWNzKSB7XG4gIHJldHVybiBNZXRyaWNUb0RhdGFUeXBlW25hbWVdID09ICdCaXRBcnJheSc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlY3Rvck1ldHJpYyhuYW1lOiBLbm93bk1ldHJpY3MpIHtcbiAgcmV0dXJuIE1ldHJpY1RvRGF0YVR5cGVbbmFtZV0gPT0gJ1ZlY3Rvcic7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc01hY3JvTW9sZWN1bGVNZXRyaWMobmFtZTogS25vd25NZXRyaWNzKSB7XG4gIHJldHVybiBNZXRyaWNUb0RhdGFUeXBlW25hbWVdID09IERpc3RhbmNlTWV0cmljc1N1YmplY3RzLk1hY3JvTW9sZWN1bGUudG9TdHJpbmcoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtZXJpY01ldHJpYyhuYW1lOiBLbm93bk1ldHJpY3MpIHtcbiAgcmV0dXJuIE1ldHJpY1RvRGF0YVR5cGVbbmFtZV0gPT0gRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuTnVtYmVyLnRvU3RyaW5nKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlckFycmF5TWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSBEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5OdW1iZXJBcnJheS50b1N0cmluZygpO1xufVxuXG4vKiogTWFuaGF0dGFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHNlcXVlbmNlcyAobWF0Y2ggLSAwLCBtaXNtYXRjaCAtIDEpIG5vcm1hbGl6ZWQgZm9yIGxlbmd0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYW5oYXR0YW5EaXN0YW5jZShzMTogc3RyaW5nLCBzMjogc3RyaW5nKTogbnVtYmVyIHtcbiAgaWYgKHMxLmxlbmd0aCAhPT0gczIubGVuZ3RoKSB7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgbGV0IGRpc3Q6IG51bWJlciA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBzMS5sZW5ndGg7IGkrKylcbiAgICAgIGRpc3QgKz0gczFbaV0gPT0gczJbaV0gPyAwIDogMTtcbiAgICByZXR1cm4gZGlzdCAvIHMxLmxlbmd0aDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2F0ZWdvcmljYWxEaXN0YW5jZShzMTogc3RyaW5nLCBzMjogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIHMxID09PSBzMiA/IDAgOiAxO1xufVxuXG4vKiogVW5pZmllZCBjbGFzcyBpbXBsZW1lbnRpbmcgZGlmZmVyZW50IHN0cmluZyBtZWFzdXJlcy4gKi9cbmV4cG9ydCBjbGFzcyBNZWFzdXJlIHtcbiAgcHJvdGVjdGVkIG1ldGhvZDogS25vd25NZXRyaWNzO1xuICBwcm90ZWN0ZWQgZGF0YVR5cGU6IEF2YWlsYWJsZURhdGFUeXBlcztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBNZWFzdXJlIHdpdGggLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kIE1ldGhvZCB0byBjYWxjdWxhdGUgZGlzdGFuY2UgYmV0d2VlbiBzdHJpbmdzLlxuICAgKiBAbWVtYmVyb2YgTWVhc3VyZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1ldGhvZDogS25vd25NZXRyaWNzKSB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gICAgdGhpcy5kYXRhVHlwZSA9IE1ldHJpY1RvRGF0YVR5cGVbbWV0aG9kXSBhcyBBdmFpbGFibGVEYXRhVHlwZXM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBtZXRyaWMgbmVlZHMgYXJndW1lbnRzIHRvIGJlIGNhbGN1bGF0ZWQuXG4gICAqIEBwYXJhbSB7S25vd25NZXRyaWNzfSBtZXRob2QgTWV0cmljIHRvIGNoZWNrIGlmIGl0IG5lZWRzIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWV0cmljIG5lZWRzIGFyZ3VtZW50cy5cbiAgICogQG1lbWJlcm9mIE1lYXN1cmVcbiAgICovXG4gIHB1YmxpYyBtZXRyaWNOZWVkc0FyZ3MobWV0aG9kOiBLbm93bk1ldHJpY3MpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNNYWNyb01vbGVjdWxlTWV0cmljKG1ldGhvZCkgfHwgaXNOdW1lcmljTWV0cmljKG1ldGhvZCkgfHwgaXNOdW1iZXJBcnJheU1ldHJpYyhtZXRob2QpO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIGN1c3RvbSBzdHJpbmcgZGlzdGFuY2UgZnVuY3Rpb24gc3BlY2lmaWVkLlxuICAgKiBAcGFyYW0ge29wdHN9IG9wdHMgT3B0aW9ucyBmb3IgdGhlIG1lYXN1cmUuIHVzZWQgZm9yIG1hY3JvbW9sZWN1bGUgZGlzdGFuY2VzXG4gICAqIEByZXR1cm4ge0Rpc3RhbmNlTWV0cmljfSBDYWxsYmFjayBvZiB0aGUgbWVhc3VyZSBjaG9zZW4uXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgcHVibGljIGdldE1lYXN1cmUob3B0cz86IGFueSk6IERpc3RhbmNlTWV0cmljIHtcbiAgICBjb25zdCBkaWN0OiB7IFtrZXk6IHN0cmluZ106XG4gICAgICB7W2tleTI6IHN0cmluZ106IERpc3RhbmNlTWV0cmljIHwgKChvcHRzOiBhbnkpID0+IERpc3RhbmNlTWV0cmljKX1cbiAgICB9ID0gQXZhaWxhYmxlTWV0cmljcztcbiAgICBpZiAoIWRpY3QuaGFzT3duUHJvcGVydHkodGhpcy5kYXRhVHlwZSkgfHwgIWRpY3RbdGhpcy5kYXRhVHlwZV0uaGFzT3duUHJvcGVydHkodGhpcy5tZXRob2QpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIG1lYXN1cmUgJHt0aGlzLm1ldGhvZH0gZm9yIGRhdGEgdHlwZSAke3RoaXMuZGF0YVR5cGV9YCk7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljTmVlZHNBcmdzKHRoaXMubWV0aG9kKSA/XG4gICAgICAoZGljdFt0aGlzLmRhdGFUeXBlXVt0aGlzLm1ldGhvZF0gYXMgKChvcHRzOiBhbnkpID0+IERpc3RhbmNlTWV0cmljKSkob3B0cykgOlxuICAgICAgZGljdFt0aGlzLmRhdGFUeXBlXVt0aGlzLm1ldGhvZF0gYXMgRGlzdGFuY2VNZXRyaWM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBjdXN0b20gc3RyaW5nIGRpc3RhbmNlIGJ5IHRoZSBnaXZlbiBkYXRhIHR5cGUuXG4gICAqIEBwYXJhbSB7QXZhaWxhYmxlRGF0YVR5cGVzfSBkYXRhVHlwZSBNZXRyaWMncyBkYXRhIHR5cGVcbiAgICogQHJldHVybiB7c3RyaW5nW119IE1ldHJpYyBuYW1lcyB3aGljaCBleHBlY3RzIHRoZSBnaXZlbiBkYXRhIHR5cGVcbiAgICogQG1lbWJlcm9mIE1lYXN1cmVyXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdldE1ldHJpY0J5RGF0YVR5cGUoZGF0YVR5cGU6IEF2YWlsYWJsZURhdGFUeXBlcyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoQXZhaWxhYmxlTWV0cmljc1tkYXRhVHlwZV0pO1xuICB9XG5cbiAgLyoqIFJldHVybnMgbWV0cmljIG5hbWVzIGF2YWlsYWJsZS5cbiAgICogQG1lbWJlcm9mIE1lYXN1cmVyXG4gICAqL1xuICBzdGF0aWMgZ2V0IGF2YWlsYWJsZU1lYXN1cmVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoQXZhaWxhYmxlTWV0cmljcyk7XG4gIH1cbn1cbiJdfQ==","import { Vector } from './type-declarations';\nimport { randomFloat, randomInt } from './random';\n/**\n * Asserts a condition by throwing an Error.\n *\n * @export\n * @param {boolean} [condition=false] Condition to assert.\n * @param {string} [message='Assertion error.'] Message to output.\n * @throws {Error}\n */\nexport function assert(condition = false, message = 'Assertion error.') {\n if (!condition)\n throw new Error(message);\n}\n/**\n * Creates new two-dimensional array and fills it with the value given.\n *\n * @param {number} dimension1 The first dimension of the coordinates (number of rows).\n * @param {number} dimension2 The second dimension of the coordinates (number of columns).\n * @param {number} [fill=0] A value to fill the coordinates with.\n * @return {Coordinates} A two-dimensional filled with the value given.\n * @todo Might be slow since used Array.map. Probably needs performance revision.\n */\nexport function initCoordinates(dimension1, dimension2, fill = 0) {\n return new Array(dimension1).fill(fill).map(() => (new Vector(dimension2).fill(fill)));\n}\n/**\n * Transpose matrix.\n *\n * @export\n * @param {Matrix} matrix The matrix to be transposed.\n * @return {Matrix} Transposed matrix.\n * @todo Might be slow since used Array.map. Probably needs performance revision.\n */\nexport function transposeMatrix(matrix) {\n return new Array(matrix[0].length).fill(0)\n .map((_, i) => (new Vector(matrix.length).fill(0).map((_, j) => (matrix[j][i]))));\n}\n/**\n * Adds two vectors with the second one to be multiplied by the given ratio.\n *\n * @export\n * @param {Vector} p The first vector to add.\n * @param {Vector} q The second vector to add.\n * @param {number} [multiplier=1] A multiplier to be used before the second vector is added.\n * @return {Vector} New vector contained the result of operation p+multiplier*q.\n */\nexport function vectorAdd(p, q, multiplier = 1) {\n const nItems = p.length;\n assert(nItems == q.length, 'Vector lengths do not match.');\n const total = new Vector(nItems);\n for (let i = 0; i < p.length; ++i)\n total[i] = p[i] + multiplier * q[i];\n return total;\n}\n/**\n * Sums the vector's items.\n *\n * @param {Vector} v The vector to be summed.\n * @return {number} The vector's items sum.\n */\nfunction itemsSum(v) {\n let total = 0;\n for (let i = 0; i < v.length; ++i)\n total += v[i];\n return total;\n}\n/**\n * Suqares the vector's items.\n *\n * @param {Vector} v The vector to square.\n * @return {Vector} A new vector containing the original's items squared.\n */\nfunction vectorSquare(v) {\n const nItems = v.length;\n const total = new Vector(nItems);\n for (let i = 0; i < v.length; ++i)\n total[i] = v[i] * v[i];\n return total;\n}\nexport function vectorLength(v) {\n let sqrSum = 0;\n for (let i = 0; i < v.length; i++)\n sqrSum += v[i] * v[i];\n return Math.sqrt(sqrSum);\n}\nexport function vectorDotProduct(v1, v2) {\n if (v1.length != v2.length)\n throw new Error('The dimensionality of the vectors must match');\n let prod = 0;\n for (let i = 0; i < v1.length; i++)\n prod += v1[i] * v2[i];\n return prod;\n}\n/**\n * Creates a matrix filled with random floating point values.\n *\n * @export\n * @param {number} dimension1 The first dimension of the matrix.\n * @param {number} dimension2 The second dimension of the matrix.\n * @param {number} [scale=1.] Max value given by random generator.\n * @return {Matrix} A new matrix filled with random floating point values.\n */\nexport function fillRandomMatrix(dimension1, dimension2, scale = 1.) {\n const matrix = initCoordinates(dimension1, dimension2);\n for (let i = 0; i < dimension1; ++i) {\n for (let j = 0; j < dimension2; ++j)\n matrix[i][j] = randomFloat(scale);\n }\n return matrix;\n}\n/**\n * Calculates Euclidean distance between two vectors.\n *\n * @export\n * @param {Vector} p The first vector.\n * @param {Vector} q The second vector.\n * @return {number} Euclidean distance between the given vectors.\n */\nexport function calculateEuclideanDistance(p, q) {\n let result = 0;\n const len = p.length;\n if (len !== q.length)\n throw new Error('The dimensionality of the vectors must match');\n for (let i = 0; i < len; ++i)\n result += Math.pow((p[i] - q[i]), 2);\n return Math.sqrt(result);\n}\n/**\n * Creates a distance matrix using a custom distance function.\n *\n * @export\n * @param {Vectors} data Input vectors to calculate distances.\n * @param {DistanceMetric} distance Custom distance function.\n * @return {Matrix} Calculated custom distance matrix.\n */\nexport function calcDistanceMatrix(data, distance) {\n const nItems = data.length;\n const matrix = initCoordinates(nItems, nItems, 0);\n for (let i = 0; i < nItems; ++i) {\n for (let j = i + 1; j < nItems; ++j) {\n const d = (data[i] == null) || (data[j] == null) ? 0 : distance(data[i], data[j]);\n matrix[i][j] = matrix[j][i] = d;\n }\n }\n return matrix;\n}\n/**\n * Creates a distance matrix using a custom distance function.\n *\n * @export\n * @param {Vectors} data Input vectors to calculate distances.\n * @param {DistanceMetric} distance Custom distance function.\n * @return {Matrix} Calculated custom distance matrix.\n */\nexport function calcNormalizedDistanceMatrix(data, distance) {\n const nItems = data.length;\n const matrix = initCoordinates(nItems, nItems, 0);\n let max = Number.MIN_VALUE;\n let min = Number.MAX_VALUE;\n for (let i = 0; i < nItems; ++i) {\n for (let j = i; j < nItems; ++j) {\n const d = (data[i] == null) || (data[j] == null || i === j) ? 0 : distance(data[i], data[j]);\n matrix[i][j] = matrix[j][i] = d;\n if (d > max)\n max = d;\n if (d < min)\n min = d;\n }\n }\n for (let i = 0; i < nItems; ++i) {\n for (let j = i + 1; j < nItems; ++j)\n matrix[i][j] = matrix[j][i] = (matrix[i][j] - min) / (max - min);\n }\n return matrix;\n}\n/** Generates array from a range [begin; end] or [begin; end) if endExclusive. **/\nexport function genRange(begin, end, endExclusive = false) {\n const nItems = end - begin + (endExclusive ? 0 : 1);\n const series = new Int32Array(nItems);\n for (let i = 0; i < nItems; ++i)\n series[i] = begin + i;\n return series;\n}\n/**\n * Returns order of values as if they are sorted.\n *\n * @export\n * @param {any[]} values Input array.\n * @param {boolean} [reverse=false] Whether to return reversed order.\n * @return {number[]} The order computed.\n */\nexport function argSort(values, reverse = false) {\n const sortfn = reverse ? (a, b) => (b[0] - a[0]) : (a, b) => (a[0] - b[0]);\n const decor = (v, i) => [v, i]; // set index to value\n const undecor = (a) => a[1]; // leave only index\n const _argsort = (arr) => arr.map(decor).sort(sortfn).map(undecor);\n return _argsort(values);\n}\n/**\n * Returns the indexes of the most diverse objects according to the dist function\n * @param {number} length total number of objects\n * @param {number} n number of diverse elements to find\n * @param {(i1: number, i2: number) => number} dist a function which calculates distance between\n * two objects using their indexes\n * @returns {number[]} The indexes of the most diverse objects\n */\nexport function getDiverseSubset(length, n, dist) {\n function maxBy(values, orderBy) {\n let maxValue = null;\n let maxOrderBy = null;\n for (const element of values) {\n const elementOrderBy = orderBy(element);\n if (maxOrderBy == null || elementOrderBy > maxOrderBy) {\n maxValue = element;\n maxOrderBy = elementOrderBy;\n }\n }\n return maxValue;\n }\n const subset = [randomInt(length - 1)];\n const complement = new Set();\n for (let i = 0; i < length; ++i) {\n if (!subset.includes(i))\n complement.add(i);\n }\n while (subset.length < n) {\n const idx = maxBy(complement.values(), (i) => Math.min.apply(Math, subset.map(function (val, index) {\n return dist(i, val);\n })));\n if (idx) {\n subset.push(idx);\n complement.delete(idx);\n }\n }\n return subset;\n}\n/**\n * Returns normalized vector.\n *\n * @export\n * @param {Vector} data numerical array\n */\nexport function normalize(data) {\n const len = data.length;\n let sum = 0;\n let sumOfSquares = 0;\n for (let i = 0; i < len; ++i) {\n sum += data[i];\n sumOfSquares += Math.pow(data[i], 2);\n }\n const mean = sum / len;\n const stdDevInverse = 1.0 / Math.sqrt(sumOfSquares / len - Math.pow(mean, 2));\n for (let i = 0; i < len; ++i)\n data[i] = (data[i] - mean) * stdDevInverse;\n return data;\n}\n/**\n * Finds set difference between two lists.\n * @param {any[]} a The first list.\n * @param {any[]} b The second list.\n * @return {any[]}\n */\nexport function setDifference(a, b) {\n const bSet = new Set(b);\n return Array.from(new Set(a.filter((x) => !bSet.has(x))).values());\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yLW9wZXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ2ZWN0b3Itb3BlcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVMsTUFBTSxFQUF1QyxNQUFNLHFCQUFxQixDQUFDO0FBQ3pGLE9BQU8sRUFBQyxXQUFXLEVBQUUsU0FBUyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBRWhEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLFlBQXFCLEtBQUssRUFBRSxVQUFrQixrQkFBa0I7SUFDckYsSUFBSSxDQUFDLFNBQVM7UUFDWixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsVUFBa0IsRUFBRSxVQUFrQixFQUFFLE9BQWUsQ0FBQztJQUN0RixPQUFPLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxNQUFjO0lBQzVDLE9BQU8sSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDdkMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENB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QUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztBQUNyRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtNYXRyaXgsIFZlY3RvciwgQ29vcmRpbmF0ZXMsIFZlY3RvcnMsIERpc3RhbmNlTWV0cmljfSBmcm9tICcuL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7cmFuZG9tRmxvYXQsIHJhbmRvbUludH0gZnJvbSAnLi9yYW5kb20nO1xuXG4vKipcbiAqIEFzc2VydHMgYSBjb25kaXRpb24gYnkgdGhyb3dpbmcgYW4gRXJyb3IuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtib29sZWFufSBbY29uZGl0aW9uPWZhbHNlXSBDb25kaXRpb24gdG8gYXNzZXJ0LlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlPSdBc3NlcnRpb24gZXJyb3IuJ10gTWVzc2FnZSB0byBvdXRwdXQuXG4gKiBAdGhyb3dzIHtFcnJvcn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChjb25kaXRpb246IGJvb2xlYW4gPSBmYWxzZSwgbWVzc2FnZTogc3RyaW5nID0gJ0Fzc2VydGlvbiBlcnJvci4nKSB7XG4gIGlmICghY29uZGl0aW9uKVxuICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIG5ldyB0d28tZGltZW5zaW9uYWwgYXJyYXkgYW5kIGZpbGxzIGl0IHdpdGggdGhlIHZhbHVlIGdpdmVuLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBkaW1lbnNpb24xIFRoZSBmaXJzdCBkaW1lbnNpb24gb2YgdGhlIGNvb3JkaW5hdGVzIChudW1iZXIgb2Ygcm93cykuXG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMiBUaGUgc2Vjb25kIGRpbWVuc2lvbiBvZiB0aGUgY29vcmRpbmF0ZXMgKG51bWJlciBvZiBjb2x1bW5zKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZmlsbD0wXSBBIHZhbHVlIHRvIGZpbGwgdGhlIGNvb3JkaW5hdGVzIHdpdGguXG4gKiBAcmV0dXJuIHtDb29yZGluYXRlc30gQSB0d28tZGltZW5zaW9uYWwgZmlsbGVkIHdpdGggdGhlIHZhbHVlIGdpdmVuLlxuICogQHRvZG8gTWlnaHQgYmUgc2xvdyBzaW5jZSB1c2VkIEFycmF5Lm1hcC4gUHJvYmFibHkgbmVlZHMgcGVyZm9ybWFuY2UgcmV2aXNpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0Q29vcmRpbmF0ZXMoZGltZW5zaW9uMTogbnVtYmVyLCBkaW1lbnNpb24yOiBudW1iZXIsIGZpbGw6IG51bWJlciA9IDApOiBDb29yZGluYXRlcyB7XG4gIHJldHVybiBuZXcgQXJyYXkoZGltZW5zaW9uMSkuZmlsbChmaWxsKS5tYXAoKCkgPT4gKG5ldyBWZWN0b3IoZGltZW5zaW9uMikuZmlsbChmaWxsKSkpO1xufVxuXG4vKipcbiAqIFRyYW5zcG9zZSBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtNYXRyaXh9IG1hdHJpeCBUaGUgbWF0cml4IHRvIGJlIHRyYW5zcG9zZWQuXG4gKiBAcmV0dXJuIHtNYXRyaXh9IFRyYW5zcG9zZWQgbWF0cml4LlxuICogQHRvZG8gTWlnaHQgYmUgc2xvdyBzaW5jZSB1c2VkIEFycmF5Lm1hcC4gUHJvYmFibHkgbmVlZHMgcGVyZm9ybWFuY2UgcmV2aXNpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2VNYXRyaXgobWF0cml4OiBNYXRyaXgpOiBNYXRyaXgge1xuICByZXR1cm4gbmV3IEFycmF5KG1hdHJpeFswXS5sZW5ndGgpLmZpbGwoMClcbiAgICAubWFwKChfLCBpKSA9PiAobmV3IFZlY3RvcihtYXRyaXgubGVuZ3RoKS5maWxsKDApLm1hcCgoXywgaikgPT4gKG1hdHJpeFtqXVtpXSkpKSk7XG59XG5cbi8qKlxuICogQWRkcyB0d28gdmVjdG9ycyB3aXRoIHRoZSBzZWNvbmQgb25lIHRvIGJlIG11bHRpcGxpZWQgYnkgdGhlIGdpdmVuIHJhdGlvLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7VmVjdG9yfSBwIFRoZSBmaXJzdCB2ZWN0b3IgdG8gYWRkLlxuICogQHBhcmFtIHtWZWN0b3J9IHEgVGhlIHNlY29uZCB2ZWN0b3IgdG8gYWRkLlxuICogQHBhcmFtIHtudW1iZXJ9IFttdWx0aXBsaWVyPTFdIEEgbXVsdGlwbGllciB0byBiZSB1c2VkIGJlZm9yZSB0aGUgc2Vjb25kIHZlY3RvciBpcyBhZGRlZC5cbiAqIEByZXR1cm4ge1ZlY3Rvcn0gTmV3IHZlY3RvciBjb250YWluZWQgdGhlIHJlc3VsdCBvZiBvcGVyYXRpb24gcCttdWx0aXBsaWVyKnEuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZWN0b3JBZGQocDogVmVjdG9yLCBxOiBWZWN0b3IsIG11bHRpcGxpZXI6IG51bWJlciA9IDEpOiBWZWN0b3Ige1xuICBjb25zdCBuSXRlbXMgPSBwLmxlbmd0aDtcblxuICBhc3NlcnQobkl0ZW1zID09IHEubGVuZ3RoLCAnVmVjdG9yIGxlbmd0aHMgZG8gbm90IG1hdGNoLicpO1xuXG4gIGNvbnN0IHRvdGFsID0gbmV3IFZlY3RvcihuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcC5sZW5ndGg7ICsraSlcbiAgICB0b3RhbFtpXSA9IHBbaV0gKyBtdWx0aXBsaWVyICogcVtpXTtcblxuICByZXR1cm4gdG90YWw7XG59XG5cbi8qKlxuICogU3VtcyB0aGUgdmVjdG9yJ3MgaXRlbXMuXG4gKlxuICogQHBhcmFtIHtWZWN0b3J9IHYgVGhlIHZlY3RvciB0byBiZSBzdW1tZWQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSB2ZWN0b3IncyBpdGVtcyBzdW0uXG4gKi9cbmZ1bmN0aW9uIGl0ZW1zU3VtKHY6IFZlY3Rvcik6IG51bWJlciB7XG4gIGxldCB0b3RhbCA9IDA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2Lmxlbmd0aDsgKytpKVxuICAgIHRvdGFsICs9IHZbaV07XG5cbiAgcmV0dXJuIHRvdGFsO1xufVxuXG4vKipcbiAqIFN1cWFyZXMgdGhlIHZlY3RvcidzIGl0ZW1zLlxuICpcbiAqIEBwYXJhbSB7VmVjdG9yfSB2IFRoZSB2ZWN0b3IgdG8gc3F1YXJlLlxuICogQHJldHVybiB7VmVjdG9yfSBBIG5ldyB2ZWN0b3IgY29udGFpbmluZyB0aGUgb3JpZ2luYWwncyBpdGVtcyBzcXVhcmVkLlxuICovXG5mdW5jdGlvbiB2ZWN0b3JTcXVhcmUodjogVmVjdG9yKTogVmVjdG9yIHtcbiAgY29uc3Qgbkl0ZW1zID0gdi5sZW5ndGg7XG4gIGNvbnN0IHRvdGFsID0gbmV3IFZlY3RvcihuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdi5sZW5ndGg7ICsraSlcbiAgICB0b3RhbFtpXSA9IHZbaV0gKiB2W2ldO1xuXG4gIHJldHVybiB0b3RhbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZlY3Rvckxlbmd0aCh2OiBWZWN0b3IpOiBudW1iZXIge1xuICBsZXQgc3FyU3VtOiBudW1iZXIgPSAwO1xuICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgdi5sZW5ndGg7IGkrKylcbiAgICBzcXJTdW0gKz0gdltpXSAqIHZbaV07XG4gIHJldHVybiBNYXRoLnNxcnQoc3FyU3VtKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZlY3RvckRvdFByb2R1Y3QodjE6IFZlY3RvciwgdjI6IFZlY3Rvcik6IG51bWJlciB7XG4gIGlmICh2MS5sZW5ndGggIT0gdjIubGVuZ3RoKVxuICAgIHRocm93IG5ldyBFcnJvcignVGhlIGRpbWVuc2lvbmFsaXR5IG9mIHRoZSB2ZWN0b3JzIG11c3QgbWF0Y2gnKTtcbiAgbGV0IHByb2Q6IG51bWJlciA9IDA7XG4gIGZvciAobGV0IGk6IG51bWJlciA9IDA7IGkgPCB2MS5sZW5ndGg7IGkrKylcbiAgICBwcm9kICs9IHYxW2ldICogdjJbaV07XG4gIHJldHVybiBwcm9kO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZmlsbGVkIHdpdGggcmFuZG9tIGZsb2F0aW5nIHBvaW50IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMSBUaGUgZmlyc3QgZGltZW5zaW9uIG9mIHRoZSBtYXRyaXguXG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMiBUaGUgc2Vjb25kIGRpbWVuc2lvbiBvZiB0aGUgbWF0cml4LlxuICogQHBhcmFtIHtudW1iZXJ9IFtzY2FsZT0xLl0gTWF4IHZhbHVlIGdpdmVuIGJ5IHJhbmRvbSBnZW5lcmF0b3IuXG4gKiBAcmV0dXJuIHtNYXRyaXh9IEEgbmV3IG1hdHJpeCBmaWxsZWQgd2l0aCByYW5kb20gZmxvYXRpbmcgcG9pbnQgIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGxSYW5kb21NYXRyaXgoZGltZW5zaW9uMTogbnVtYmVyLCBkaW1lbnNpb24yOiBudW1iZXIsIHNjYWxlOiBudW1iZXIgPSAxLik6IE1hdHJpeCB7XG4gIGNvbnN0IG1hdHJpeCA9IGluaXRDb29yZGluYXRlcyhkaW1lbnNpb24xLCBkaW1lbnNpb24yKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbWVuc2lvbjE7ICsraSkge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgZGltZW5zaW9uMjsgKytqKVxuICAgICAgbWF0cml4W2ldW2pdID0gcmFuZG9tRmxvYXQoc2NhbGUpO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyBFdWNsaWRlYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjdG9ycy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3Rvcn0gcCBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHtWZWN0b3J9IHEgVGhlIHNlY29uZCB2ZWN0b3IuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEV1Y2xpZGVhbiBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBnaXZlbiB2ZWN0b3JzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2UocDogVmVjdG9yLCBxOiBWZWN0b3IpOiBudW1iZXIge1xuICBsZXQgcmVzdWx0ID0gMDtcbiAgY29uc3QgbGVuID0gcC5sZW5ndGg7XG5cbiAgaWYgKGxlbiAhPT0gcS5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGltZW5zaW9uYWxpdHkgb2YgdGhlIHZlY3RvcnMgbXVzdCBtYXRjaCcpO1xuICBcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICByZXN1bHQgKz0gKHBbaV0gLSBxW2ldKSAqKiAyO1xuICBcbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkaXN0YW5jZSBtYXRyaXggdXNpbmcgYSBjdXN0b20gZGlzdGFuY2UgZnVuY3Rpb24uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3JzfSBkYXRhIElucHV0IHZlY3RvcnMgdG8gY2FsY3VsYXRlIGRpc3RhbmNlcy5cbiAqIEBwYXJhbSB7RGlzdGFuY2VNZXRyaWN9IGRpc3RhbmNlIEN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge01hdHJpeH0gQ2FsY3VsYXRlZCBjdXN0b20gZGlzdGFuY2UgbWF0cml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY0Rpc3RhbmNlTWF0cml4KGRhdGE6IFZlY3RvcnMsIGRpc3RhbmNlOiBEaXN0YW5jZU1ldHJpYyk6IE1hdHJpeCB7XG4gIGNvbnN0IG5JdGVtcyA9IGRhdGEubGVuZ3RoO1xuICBjb25zdCBtYXRyaXggPSBpbml0Q29vcmRpbmF0ZXMobkl0ZW1zLCBuSXRlbXMsIDApO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBuSXRlbXM7ICsraikge1xuICAgICAgY29uc3QgZDogbnVtYmVyID0gKGRhdGFbaV0gPT0gbnVsbCkgfHwgKGRhdGFbal0gPT0gbnVsbCkgPyAwIDogZGlzdGFuY2UoZGF0YVtpXSwgZGF0YVtqXSk7XG4gICAgICBtYXRyaXhbaV1bal0gPSBtYXRyaXhbal1baV0gPSBkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWF0cml4O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkaXN0YW5jZSBtYXRyaXggdXNpbmcgYSBjdXN0b20gZGlzdGFuY2UgZnVuY3Rpb24uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3JzfSBkYXRhIElucHV0IHZlY3RvcnMgdG8gY2FsY3VsYXRlIGRpc3RhbmNlcy5cbiAqIEBwYXJhbSB7RGlzdGFuY2VNZXRyaWN9IGRpc3RhbmNlIEN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge01hdHJpeH0gQ2FsY3VsYXRlZCBjdXN0b20gZGlzdGFuY2UgbWF0cml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY05vcm1hbGl6ZWREaXN0YW5jZU1hdHJpeChkYXRhOiBWZWN0b3JzLCBkaXN0YW5jZTogRGlzdGFuY2VNZXRyaWMpOiBNYXRyaXgge1xuICBjb25zdCBuSXRlbXMgPSBkYXRhLmxlbmd0aDtcbiAgY29uc3QgbWF0cml4ID0gaW5pdENvb3JkaW5hdGVzKG5JdGVtcywgbkl0ZW1zLCAwKTtcbiAgbGV0IG1heCA9IE51bWJlci5NSU5fVkFMVUU7XG4gIGxldCBtaW4gPSBOdW1iZXIuTUFYX1ZBTFVFO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5JdGVtczsgKytpKSB7XG4gICAgZm9yIChsZXQgaiA9IGk7IGogPCBuSXRlbXM7ICsraikge1xuICAgICAgY29uc3QgZDogbnVtYmVyID0gKGRhdGFbaV0gPT0gbnVsbCkgfHwgKGRhdGFbal0gPT0gbnVsbCB8fCBpID09PSBqKSA/IDAgOiBkaXN0YW5jZShkYXRhW2ldLCBkYXRhW2pdKTtcbiAgICAgIG1hdHJpeFtpXVtqXSA9IG1hdHJpeFtqXVtpXSA9IGQ7XG4gICAgICBpZiAoZCA+IG1heCkgbWF4ID0gZDtcbiAgICAgIGlmIChkIDwgbWluKSBtaW4gPSBkO1xuICAgIH1cbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IG5JdGVtczsgKytpKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgbkl0ZW1zOyArK2opXG4gICAgICBtYXRyaXhbaV1bal0gPSBtYXRyaXhbal1baV0gPSAobWF0cml4W2ldW2pdIC0gbWluKSAvIChtYXggLSBtaW4pO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKiBHZW5lcmF0ZXMgYXJyYXkgZnJvbSBhIHJhbmdlIFtiZWdpbjsgZW5kXSBvciBbYmVnaW47IGVuZCkgaWYgZW5kRXhjbHVzaXZlLiAqKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5SYW5nZShiZWdpbjogbnVtYmVyLCBlbmQ6IG51bWJlciwgZW5kRXhjbHVzaXZlID0gZmFsc2UpOiBJbnQzMkFycmF5IHtcbiAgY29uc3Qgbkl0ZW1zID0gZW5kIC0gYmVnaW4gKyAoZW5kRXhjbHVzaXZlID8gMCA6IDEpO1xuICBjb25zdCBzZXJpZXMgPSBuZXcgSW50MzJBcnJheShuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpXG4gICAgc2VyaWVzW2ldID0gYmVnaW4gKyBpO1xuXG4gIHJldHVybiBzZXJpZXM7XG59XG5cbi8qKlxuICogUmV0dXJucyBvcmRlciBvZiB2YWx1ZXMgYXMgaWYgdGhleSBhcmUgc29ydGVkLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7YW55W119IHZhbHVlcyBJbnB1dCBhcnJheS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldmVyc2U9ZmFsc2VdIFdoZXRoZXIgdG8gcmV0dXJuIHJldmVyc2VkIG9yZGVyLlxuICogQHJldHVybiB7bnVtYmVyW119IFRoZSBvcmRlciBjb21wdXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFyZ1NvcnQodmFsdWVzOiBhbnlbXSwgcmV2ZXJzZSA9IGZhbHNlKTogbnVtYmVyW10ge1xuICBjb25zdCBzb3J0Zm4gPSByZXZlcnNlID8gKGE6IGFueVtdLCBiOiBhbnlbXSkgPT4gKGJbMF0gLSBhWzBdKSA6IChhOiBhbnlbXSwgYjogYW55W10pID0+IChhWzBdIC0gYlswXSk7XG4gIGNvbnN0IGRlY29yID0gKHY6IGFueSwgaTogbnVtYmVyKSA9PiBbdiwgaV07IC8vIHNldCBpbmRleCB0byB2YWx1ZVxuICBjb25zdCB1bmRlY29yID0gKGE6IGFueVtdKSA9PiBhWzFdOyAvLyBsZWF2ZSBvbmx5IGluZGV4XG4gIGNvbnN0IF9hcmdzb3J0ID0gKGFycjogYW55W10pID0+IGFyci5tYXAoZGVjb3IpLnNvcnQoc29ydGZuKS5tYXAodW5kZWNvcik7XG4gIHJldHVybiBfYXJnc29ydCh2YWx1ZXMpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGluZGV4ZXMgb2YgdGhlIG1vc3QgZGl2ZXJzZSBvYmplY3RzIGFjY29yZGluZyB0byB0aGUgZGlzdCBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCB0b3RhbCBudW1iZXIgb2Ygb2JqZWN0c1xuICogQHBhcmFtIHtudW1iZXJ9IG4gbnVtYmVyIG9mIGRpdmVyc2UgZWxlbWVudHMgdG8gZmluZFxuICogQHBhcmFtIHsoaTE6IG51bWJlciwgaTI6IG51bWJlcikgPT4gbnVtYmVyfSBkaXN0IGEgZnVuY3Rpb24gd2hpY2ggY2FsY3VsYXRlcyBkaXN0YW5jZSBiZXR3ZWVuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHdvIG9iamVjdHMgdXNpbmcgdGhlaXIgaW5kZXhlc1xuICogQHJldHVybnMge251bWJlcltdfSBUaGUgaW5kZXhlcyBvZiB0aGUgbW9zdCBkaXZlcnNlIG9iamVjdHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERpdmVyc2VTdWJzZXQobGVuZ3RoOiBudW1iZXIsIG46IG51bWJlciwgZGlzdDogKGkxOiBudW1iZXIsIGkyOiBudW1iZXIpID0+IG51bWJlcik6IG51bWJlcltdIHtcbiAgZnVuY3Rpb24gbWF4QnkodmFsdWVzOiBJdGVyYWJsZUl0ZXJhdG9yPG51bWJlcj4sIG9yZGVyQnk6IChpOiBudW1iZXIpID0+IG51bWJlcikge1xuICAgIGxldCBtYXhWYWx1ZSA9IG51bGw7XG4gICAgbGV0IG1heE9yZGVyQnkgPSBudWxsO1xuXG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHZhbHVlcykge1xuICAgICAgY29uc3QgZWxlbWVudE9yZGVyQnkgPSBvcmRlckJ5KGVsZW1lbnQpO1xuICAgICAgaWYgKG1heE9yZGVyQnkgPT0gbnVsbCB8fCBlbGVtZW50T3JkZXJCeSA+IG1heE9yZGVyQnkpIHtcbiAgICAgICAgbWF4VmFsdWUgPSBlbGVtZW50O1xuICAgICAgICBtYXhPcmRlckJ5ID0gZWxlbWVudE9yZGVyQnk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXhWYWx1ZTtcbiAgfVxuXG4gIGNvbnN0IHN1YnNldCA9IFtyYW5kb21JbnQobGVuZ3RoIC0gMSldO1xuICBjb25zdCBjb21wbGVtZW50ID0gbmV3IFNldCgpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoIXN1YnNldC5pbmNsdWRlcyhpKSlcbiAgICAgIGNvbXBsZW1lbnQuYWRkKGkpO1xuICB9XG5cbiAgd2hpbGUgKHN1YnNldC5sZW5ndGggPCBuKSB7XG4gICAgY29uc3QgaWR4ID0gbWF4QnkoXG4gICAgICBjb21wbGVtZW50LnZhbHVlcygpIGFzIEl0ZXJhYmxlSXRlcmF0b3I8bnVtYmVyPixcbiAgICAgIChpKSA9PiBNYXRoLm1pbi5hcHBseShNYXRoLCBzdWJzZXQubWFwKGZ1bmN0aW9uKHZhbCwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGRpc3QoaSwgdmFsKTtcbiAgICAgIH0pKSk7XG4gICAgaWYgKGlkeCkge1xuICAgICAgc3Vic2V0LnB1c2goaWR4KTtcbiAgICAgIGNvbXBsZW1lbnQuZGVsZXRlKGlkeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdWJzZXQ7XG59XG5cbi8qKlxuICogUmV0dXJucyBub3JtYWxpemVkIHZlY3Rvci5cbiAqIFxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3J9IGRhdGEgbnVtZXJpY2FsIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUoZGF0YTogVmVjdG9yKTogVmVjdG9yIHtcbiAgY29uc3QgbGVuID0gZGF0YS5sZW5ndGg7XG4gIGxldCBzdW0gPSAwO1xuICBsZXQgc3VtT2ZTcXVhcmVzID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgc3VtICs9IGRhdGFbaV07XG4gICAgc3VtT2ZTcXVhcmVzICs9IGRhdGFbaV0gKiogMjtcbiAgfVxuXG4gIGNvbnN0IG1lYW4gPSBzdW0gLyBsZW47XG4gIGNvbnN0IHN0ZERldkludmVyc2UgPSAxLjAgLyBNYXRoLnNxcnQoc3VtT2ZTcXVhcmVzIC8gbGVuIC0gbWVhbiAqKiAyKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgIGRhdGFbaV0gPSAoZGF0YVtpXSAtIG1lYW4pICogc3RkRGV2SW52ZXJzZTtcblxuICByZXR1cm4gZGF0YTtcbn1cblxuLyoqXG4gKiBGaW5kcyBzZXQgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBsaXN0cy5cbiAqIEBwYXJhbSB7YW55W119IGEgVGhlIGZpcnN0IGxpc3QuXG4gKiBAcGFyYW0ge2FueVtdfSBiIFRoZSBzZWNvbmQgbGlzdC5cbiAqIEByZXR1cm4ge2FueVtdfVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0RGlmZmVyZW5jZShhOiBhbnlbXSwgYjogYW55W10pOiBhbnlbXSB7XG4gIGNvbnN0IGJTZXQgPSBuZXcgU2V0KGIpO1xuICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KGEuZmlsdGVyKCh4KSA9PiAhYlNldC5oYXMoeCkpKS52YWx1ZXMoKSk7XG59XG4iXX0=","const __WEBPACK_NAMESPACE_OBJECT__ = ui;","export const DIM_RED_PREPROCESSING_FUNCTION_TAG = 'dim-red-preprocessing-function';\nexport const DIM_RED_POSTPROCESSING_FUNCTION_TAG = 'dim-red-postprocessing-function';\nexport const DIM_RED_DEFAULT_POSTPROCESSING_FUNCTION_META = 'defaultPostProcessingFunction';\nexport const SUPPORTED_SEMTYPES_TAG = 'supportedSemTypes';\nexport const SUPPORTED_TYPES_TAG = 'supportedTypes';\nexport const SUPPORTED_UNITS_TAG = 'supportedUnits';\nexport const SUPPORTED_DISTANCE_FUNCTIONS_TAG = 'supportedDistanceFunctions';\nexport const BYPASS_LARGE_DATA_WARNING = 'bypassLargeDataWarning';\nexport const SHOW_SCATTERPLOT_PROGRESS = 'show-scatterplot-progress';\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLGdDQUFnQyxDQUFDO0FBQ25GLE1BQU0sQ0FBQyxNQUFNLG1DQUFtQyxHQUFHLGlDQUFpQyxDQUFDO0FBQ3JGLE1BQU0sQ0FBQyxNQUFNLDRDQUE0QyxHQUFHLCtCQUErQixDQUFDO0FBQzVGLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLG1CQUFtQixDQUFDO0FBQzFELE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDO0FBQ3BELE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDO0FBQ3BELE1BQU0sQ0FBQyxNQUFNLGdDQUFnQyxHQUFHLDRCQUE0QixDQUFDO0FBQzdFLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLHdCQUF3QixDQUFDO0FBQ2xFLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLDJCQUEyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IERJTV9SRURfUFJFUFJPQ0VTU0lOR19GVU5DVElPTl9UQUcgPSAnZGltLXJlZC1wcmVwcm9jZXNzaW5nLWZ1bmN0aW9uJztcbmV4cG9ydCBjb25zdCBESU1fUkVEX1BPU1RQUk9DRVNTSU5HX0ZVTkNUSU9OX1RBRyA9ICdkaW0tcmVkLXBvc3Rwcm9jZXNzaW5nLWZ1bmN0aW9uJztcbmV4cG9ydCBjb25zdCBESU1fUkVEX0RFRkFVTFRfUE9TVFBST0NFU1NJTkdfRlVOQ1RJT05fTUVUQSA9ICdkZWZhdWx0UG9zdFByb2Nlc3NpbmdGdW5jdGlvbic7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX1NFTVRZUEVTX1RBRyA9ICdzdXBwb3J0ZWRTZW1UeXBlcyc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX1RZUEVTX1RBRyA9ICdzdXBwb3J0ZWRUeXBlcyc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX1VOSVRTX1RBRyA9ICdzdXBwb3J0ZWRVbml0cyc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX0RJU1RBTkNFX0ZVTkNUSU9OU19UQUcgPSAnc3VwcG9ydGVkRGlzdGFuY2VGdW5jdGlvbnMnO1xuZXhwb3J0IGNvbnN0IEJZUEFTU19MQVJHRV9EQVRBX1dBUk5JTkcgPSAnYnlwYXNzTGFyZ2VEYXRhV2FybmluZyc7XG5leHBvcnQgY29uc3QgU0hPV19TQ0FUVEVSUExPVF9QUk9HUkVTUyA9ICdzaG93LXNjYXR0ZXJwbG90LXByb2dyZXNzJztcbiJdfQ==","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n/** Calculates Clusters based on dbscan algorithm in wasm.\n * @param embedX - embeddings x location.\n * @param embedY - embeddings y location.\n * @param minPts - minimum number of points in a cluster.\n * @param epsilon - epsilon.\n * @returns array with cluster indexes.\n */\nexport function getDbscanWorker(embedX, embedY, epsilon, minPts) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise(function (resolve, reject) {\n const worker = new Worker(new URL('./clustering-worker', import.meta.url));\n worker.postMessage({ embedX, embedY, minPts, epsilon });\n worker.onmessage = ({ data: { error, clusters } }) => {\n worker.terminate();\n error ? reject(error) : resolve(clusters);\n };\n });\n });\n}\n//# sourceMappingURL=dbscan-worker-creator.js.map","function euclideanAggregationWgsl(arraySize) {\n return `\n var sum = 0.0;\n for (var i = 0u; i < ${arraySize}; i = i + 1u) {\n sum = sum + distances[i] * distances[i] * computeInfo.weights[i] * computeInfo.weights[i];\n }\n return sqrt(sum);\n `;\n}\n;\nfunction manhattanAggregationWgsl(arraySize) {\n return `\n var sum = 0.0;\n for (var i = 0u; i < ${arraySize}; i = i + 1u) {\n sum = sum + abs(distances[i]) * computeInfo.weights[i];\n }\n return sum;\n `;\n}\nexport var WEBGSLAGGREGATION;\n(function (WEBGSLAGGREGATION) {\n WEBGSLAGGREGATION[\"EUCLIDEAN\"] = \"EUCLIDEAN\";\n WEBGSLAGGREGATION[\"MANHATTAN\"] = \"MANHATTAN\";\n})(WEBGSLAGGREGATION || (WEBGSLAGGREGATION = {}));\nexport const WEBGSLAGGREGATIONFUNCTIONS = {\n [WEBGSLAGGREGATION.EUCLIDEAN]: euclideanAggregationWgsl,\n [WEBGSLAGGREGATION.MANHATTAN]: manhattanAggregationWgsl\n};\n//# sourceMappingURL=webGPU-aggregation.js.map","/* eslint-disable max-len */\n// in all the functions below, the variables a and b are assumed to be arrays of uint32/f32\n//values which are infered from the code this chunk is injected into\n// also, we have access to computeInfo struct, which contains the following fields:\n// computeInfo.entrySizes: array of arrays of u32 containing the sizes of the entries\n// other fields are specific to the distance function should be injected from the main script that calls this function,\n// and should be available in the supplementaryInfo struct\n// like the similarity matrix for monomer chemical distance.\n// the getProcessInfo function should return correct buffer allocation mechanism for the supplementaryInfo,\n// for every entry list\n// the maxDistance variable is also assumed to be available in the\n// scope of the function, in case of knn it is the distance in the last postion of knn on this index,\n// in case of sparse matrix, it can be just the threshold for the distance.\n// hamming distance for sequnences of uint32 arrays of max length ${maxArraySize}\nexport function webGPUHamming(_maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n let sizeDiff: u32 = maxLength - minLength;\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength)) - f32(sizeDiff);\n\n var diff: f32 = 0.0;\n for (var i = 0u; i < ${_maxArraySize}; i = i + 1u) {\n diff = diff + f32(a[i] != b[i]);\n if (diff > maxIntDistance) {\n return 1.0;\n }\n }\n diff += f32(sizeDiff);\n return diff / ${_maxArraySize};\n `;\n}\nexport function webGPUMonomerChemicalDistance(_maxArraySize, entryIndex) {\n // it is assumet that suppInfo struct contains correct matrix called similarityMatrix${entryIndex}, (similarityMatrix0, similarityMatrix1, etc)\n // this should be guaranteed by the getProcessInfo function.\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n let sizeDiff: u32 = maxLength - minLength;\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength)) - f32(sizeDiff);\n\n let simMatrix = &(suppInfo.similarityMatrix${entryIndex}); // using pointers make things faster\n var diff: f32 = 0.0;\n for (var i = 0u; i < ${_maxArraySize}; i = i + 1u) {\n diff = diff + 1.0 - (*simMatrix)[u32(a[i])][u32(b[i])];\n if (diff > maxIntDistance) {\n return 1.0;\n }\n }\n diff += f32(sizeDiff);\n return diff / ${_maxArraySize};\n `;\n}\nexport function webGPULevenstein(maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n\n let maxIntDistance = ceil(maxDistance * f32(maxLength));\n\n // we will store two arrays as matrix and swap the working indices per pass.\n // this way we can reduce memory usage per computation to just O(aLength)\n // the grid will have aLength + 1 columns and bLength + 1 rows\n // this will be guaranteed by iteration, but the array sizes must be known at compile time, so we will use a fixed size of maxArraySize\n var dynamicPassMat: array<array<f32, ${maxArraySize + 1}u>, 2>; // initialize to 0\n \n var prevIndex: u32 = 0;\n var curIndex: u32 = 1; // we will swap these indices per pass\n\n // initialize the first row\n for (var i = 0u; i <= aLength; i = i + 1u) {\n dynamicPassMat[prevIndex][i] = f32(i);\n }\n\n // iterate over the rows\n for (var i = 1u; i <= bLength; i = i + 1u) {\n dynamicPassMat[curIndex][0] = f32(i);\n var minEntry: f32 = f32(maxLength);\n let prevRow = &dynamicPassMat[prevIndex];\n let curRow = &dynamicPassMat[curIndex];\n let bMon = u32(b[i - 1]);\n for (var j = 1u; j <= aLength; j = j + 1u) {\n var cost: f32 = f32(a[j - 1] != bMon);\n var res: f32 = min(\n min(\n (*prevRow)[j] + 1.0, // deletion\n (*curRow)[j - 1] + 1.0, // insertion\n ),\n (*prevRow)[j - 1] + cost // substitution\n );\n (*curRow)[j] = res;\n if (res < minEntry) {\n minEntry = res;\n }\n }\n // swap the indices\n let temp: u32 = prevIndex;\n prevIndex = curIndex;\n curIndex = temp;\n if (minEntry > maxIntDistance) {\n return 1.0;\n }\n }\n\n return dynamicPassMat[prevIndex][aLength] / f32(maxLength);\n `;\n}\nexport function webGPUNeedlemanWunsch(maxArraySize, entryIndex) {\n // version of the levenshtain where the cost of substitution is customizable\n // it is assumet that suppInfo struct contains correct matrix called similarityMatrix${entryIndex}, (similarityMatrix0, similarityMatrix1, etc)\n // and gapOpenPenalty, gapExtensionPenalty\n // this should be guaranteed by the getProcessInfo function.\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength));\n // we will store two arrays as matrix and swap the working indices per pass.\n // this way we can reduce memory usage per computation to just O(aLength)\n // the grid will have aLength + 1 columns and bLength + 1 rows\n // this will be guaranteed by iteration, but the array sizes must be known at compile time, so we will use a fixed size of maxArraySize\n var dynamicPassMat: array<array<f32, ${maxArraySize + 1}u>, 2>; // initialize to 0\n \n // we need to keep track of which operation led to the current cell\n // i.e. whether we came from the left, top or diagonal to assign gap open/gap extend penalty\n var verticalGaps: array<u32, ${maxArraySize + 1}u>;\n var horizontalGaps: array<u32, ${maxArraySize + 1}u>;\n\n let gapOpenPenalty: f32 = suppInfo.gapOpenPenalty${entryIndex};\n let gapExtensionPenalty: f32 = suppInfo.gapExtensionPenalty${entryIndex};\n var prevIndex: u32 = 0;\n var curIndex: u32 = 1; // we will swap these indices per pass\n // initialize the first row\n for (var i = 0u; i <= aLength; i = i + 1u) {\n dynamicPassMat[prevIndex][i] = gapExtensionPenalty + f32(i - 1) * gapExtensionPenalty; // accounting for the fact that left and right gaps are less costly\n dynamicPassMat[curIndex][i] = 0.0;\n }\n dynamicPassMat[0][0] = 0.0;\n\n let simMatrix = &suppInfo.similarityMatrix${entryIndex}; // using pointers make things faster\n // iterate over the rows\n for (var i = 1u; i <= bLength; i = i + 1u) {\n let prevRow = &dynamicPassMat[prevIndex];\n let curRow = &dynamicPassMat[curIndex];\n (*curRow)[0] = gapExtensionPenalty + f32(i - 1) * gapExtensionPenalty;\n var minEntry: f32 = f32(maxLength);\n let monB = u32(b[i - 1]);\n for (var j = 1u; j <= aLength; j = j + 1u) {\n let monA = u32(a[j - 1]);\n \n let cost: f32 = (*prevRow)[j - 1] + 1f - (*simMatrix)[monA][monB];\n var top = (*prevRow)[j]; // deletion\n if (verticalGaps[j] > 0 || i == 1 || i == bLength) {\n top = top + gapExtensionPenalty;\n } else {\n top = top + gapOpenPenalty;\n }\n var left = (*curRow)[j - 1]; // insertion\n if (horizontalGaps[j - 1] > 0 || j == 1 || j == aLength) {\n left = left + gapExtensionPenalty;\n } else {\n left = left + gapOpenPenalty;\n }\n var res: f32 = min(\n min(\n top, // deletion\n left, // insertion\n ),\n cost // substitution\n );\n (*curRow)[j] = res;\n if (res < minEntry) {\n minEntry = res;\n }\n // update the horizontal and vertical gaps\n if (res == cost) {\n verticalGaps[j] = 0;\n horizontalGaps[j] = 0;\n } else if (res == left) {\n verticalGaps[j] = 0;\n horizontalGaps[j] = 1;\n } else {\n verticalGaps[j] = 1;\n horizontalGaps[j] = 0;\n }\n }\n // swap the indices\n let temp: u32 = prevIndex;\n prevIndex = curIndex;\n curIndex = temp;\n if (minEntry > maxIntDistance) {\n return 1.0;\n }\n }\n return dynamicPassMat[prevIndex][aLength] / f32(minLength);\n\n `;\n}\nexport function webGPUEuclidean(maxArraySize, _entryIndex) {\n return `\n var dist: f32 = 0.0;\n for (var i = 0u; i < ${maxArraySize}; i = i + 1u) {\n dist = dist + f32(a[i] - b[i]) * f32(a[i] - b[i]);\n }\n return sqrt(dist);\n `;\n}\nexport function webGPUManhattan(maxArraySize, _entryIndex) {\n return `\n var dist: f32 = 0.0;\n for (var i = 0u; i < ${maxArraySize}; i = i + 1u) {\n dist = dist + abs(f32(a[i] - b[i]));\n }\n return dist;\n `;\n}\nexport function webGPUOneHotDistance(_maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n if (aLength != bLength) {\n return 1.0;\n }\n for (var i = 0u; i < aLength; i = i + 1u) {\n if(a[i] != b[i]) {\n return 1.0;\n }\n }\n return 0.0;\n `;\n}\nexport function webGPUNumericDistance(_maxArraySize, entryIndex) {\n // we assume that range${entryIndex} is available in the supplementaryInfo struct\n return `\n let range = suppInfo.range${entryIndex};\n return f32(abs(f32(a[0]) - f32(b[0])) / range);\n `;\n}\n// tanimoto distance for uint32 arrays of length ${maxArraySize}\nexport function webGPUTanimotoBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n\n if (onBitsa == 0u && onBitsb == 0u) {\n return 0.0;\n }\n\n let totalOnBits = onBitsa + onBitsb;\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n\n return 1.0 - f32(commonBits) / f32(totalOnBits - commonBits);\n `;\n}\nexport function webGPUAsymmetricBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let min = min(onBitsa, onBitsb);\n if (min == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / f32(min);\n `;\n}\nexport function webGPUCosineBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let total = onBitsa * onBitsb; // p.s. here total is taken by multiplying\n if (total == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / sqrt(f32(total));\n `;\n}\nexport function webGPUSokalBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let total = onBitsa + onBitsb;\n if (total == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / f32(total * 2 - commonBits * 3);\n `;\n}\nexport var WEBGPUDISTANCE;\n(function (WEBGPUDISTANCE) {\n WEBGPUDISTANCE[\"HAMMING\"] = \"Hamming\";\n WEBGPUDISTANCE[\"EUCLIDEAN\"] = \"Euclidean\";\n WEBGPUDISTANCE[\"MANHATTAN\"] = \"Manhattan\";\n WEBGPUDISTANCE[\"TANIMOTO\"] = \"Tanimoto\";\n WEBGPUDISTANCE[\"LEVENSTEIN\"] = \"Levenshtein\";\n WEBGPUDISTANCE[\"NEEDLEMAN_WUNSCH\"] = \"Needlemann-Wunsch\";\n WEBGPUDISTANCE[\"MONOMER_CHEMICAL_DISTANCE\"] = \"Monomer chemical distance\";\n WEBGPUDISTANCE[\"SOKAL\"] = \"Sokal\";\n WEBGPUDISTANCE[\"COSINE\"] = \"Cosine\";\n WEBGPUDISTANCE[\"ASYMMETRIC\"] = \"Asymmetric\";\n WEBGPUDISTANCE[\"Difference\"] = \"Difference\";\n WEBGPUDISTANCE[\"OneHot\"] = \"One-Hot\";\n})(WEBGPUDISTANCE || (WEBGPUDISTANCE = {}));\nexport const webGPUFunctions = {\n [WEBGPUDISTANCE.HAMMING]: webGPUHamming,\n [WEBGPUDISTANCE.EUCLIDEAN]: webGPUEuclidean,\n [WEBGPUDISTANCE.MANHATTAN]: webGPUManhattan,\n [WEBGPUDISTANCE.TANIMOTO]: webGPUTanimotoBitArray,\n [WEBGPUDISTANCE.LEVENSTEIN]: webGPULevenstein,\n [WEBGPUDISTANCE.NEEDLEMAN_WUNSCH]: webGPUNeedlemanWunsch,\n [WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE]: webGPUMonomerChemicalDistance,\n [WEBGPUDISTANCE.SOKAL]: webGPUSokalBitArray,\n [WEBGPUDISTANCE.COSINE]: webGPUCosineBitArray,\n [WEBGPUDISTANCE.ASYMMETRIC]: webGPUAsymmetricBitArray,\n [WEBGPUDISTANCE.Difference]: webGPUNumericDistance,\n [WEBGPUDISTANCE.OneHot]: webGPUOneHotDistance\n};\nexport const distanceFunctionComplexity = {\n [WEBGPUDISTANCE.HAMMING]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.EUCLIDEAN]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.MANHATTAN]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.TANIMOTO]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.SOKAL]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.COSINE]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.ASYMMETRIC]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.LEVENSTEIN]: (maxEntrySize) => Math.ceil(maxEntrySize * maxEntrySize / 60),\n [WEBGPUDISTANCE.NEEDLEMAN_WUNSCH]: (maxEntrySize) => Math.ceil(maxEntrySize * maxEntrySize / 60),\n [WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE]: (maxEntrySize) => Math.ceil(maxEntrySize / 25),\n [WEBGPUDISTANCE.Difference]: (_maxEntrySize) => 1,\n [WEBGPUDISTANCE.OneHot]: (_maxEntrySize) => Math.ceil(_maxEntrySize / 40),\n};\nexport const TypeSupportedDistances = {\n [\"STRING\" /* WGPUENTRYTYPE.STRING */]: new Set([WEBGPUDISTANCE.HAMMING, WEBGPUDISTANCE.LEVENSTEIN, WEBGPUDISTANCE.NEEDLEMAN_WUNSCH, WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE, WEBGPUDISTANCE.OneHot]),\n [\"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */]: new Set([WEBGPUDISTANCE.HAMMING, WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE, WEBGPUDISTANCE.LEVENSTEIN, WEBGPUDISTANCE.NEEDLEMAN_WUNSCH, WEBGPUDISTANCE.TANIMOTO, WEBGPUDISTANCE.COSINE, WEBGPUDISTANCE.SOKAL, WEBGPUDISTANCE.ASYMMETRIC, WEBGPUDISTANCE.OneHot, WEBGPUDISTANCE.Difference]),\n [\"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.OneHot, WEBGPUDISTANCE.Difference]),\n [\"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.Difference]),\n [\"NUMBER\" /* WGPUENTRYTYPE.NUMBER */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.Difference]),\n [\"BITARRAY\" /* WGPUENTRYTYPE.BITARRAY */]: new Set([WEBGPUDISTANCE.TANIMOTO, WEBGPUDISTANCE.COSINE, WEBGPUDISTANCE.SOKAL, WEBGPUDISTANCE.ASYMMETRIC])\n};\n//# sourceMappingURL=webGPU-multicol-distances.js.map","export var MatrixMatrixOpType;\n(function (MatrixMatrixOpType) {\n MatrixMatrixOpType[\"ADD\"] = \"ADD\";\n MatrixMatrixOpType[\"SUB\"] = \"SUB\";\n MatrixMatrixOpType[\"MULT\"] = \"MULT\";\n})(MatrixMatrixOpType || (MatrixMatrixOpType = {}));\nexport var MatrixOpType;\n(function (MatrixOpType) {\n MatrixOpType[\"SQUARE\"] = \"SQUARE\";\n MatrixOpType[\"INVERSE\"] = \"INVERSE\";\n MatrixOpType[\"TRANSPOSE\"] = \"TRANSPOSE\";\n MatrixOpType[\"NORM\"] = \"NORM\";\n MatrixOpType[\"COLUMN_NORM\"] = \"COLUMN_NORM\";\n})(MatrixOpType || (MatrixOpType = {}));\nexport var MatrixScalarOpType;\n(function (MatrixScalarOpType) {\n MatrixScalarOpType[\"SCALARMULT\"] = \"SCALARMULT\";\n MatrixScalarOpType[\"SCALARADD\"] = \"SCALARADD\";\n MatrixScalarOpType[\"SCALARPOW\"] = \"SCALARPOW\";\n})(MatrixScalarOpType || (MatrixScalarOpType = {}));\n//# sourceMappingURL=types.js.map","// eslint-disable-next-line @typescript-eslint/unbound-method\nconst toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array, except those that contain bigint values).\n *\n * @param value - Object to check.\n * @returns True if the object is an array or a typed array.\n */\nexport function isAnyArray(value) {\n const tag = toString.call(value);\n return tag.endsWith('Array]') && !tag.includes('Big');\n}\n//# sourceMappingURL=index.js.map","export const DIMENSIONALITY_REDUCER_TERMINATE_EVENT = 'dimensionality-reducer-terminate-event';\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxNQUFNLHNDQUFzQyxHQUFHLHdDQUF3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IERJTUVOU0lPTkFMSVRZX1JFRFVDRVJfVEVSTUlOQVRFX0VWRU5UID0gJ2RpbWVuc2lvbmFsaXR5LXJlZHVjZXItdGVybWluYXRlLWV2ZW50JztcbiJdfQ==","export var DistanceAggregationMethods;\n(function (DistanceAggregationMethods) {\n DistanceAggregationMethods[\"EUCLIDEAN\"] = \"EUCLIDEAN\";\n DistanceAggregationMethods[\"MANHATTAN\"] = \"MANHATTAN\";\n})(DistanceAggregationMethods || (DistanceAggregationMethods = {}));\n;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSwwQkFHVDtBQUhILFdBQVksMEJBQTBCO0lBQ2xDLHFEQUF1QixDQUFBO0lBQ3ZCLHFEQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFIUywwQkFBMEIsS0FBMUIsMEJBQTBCLFFBR25DO0FBQUEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIERpc3RhbmNlQWdncmVnYXRpb25NZXRob2RzIHtcbiAgICBFVUNMSURFQU4gPSAnRVVDTElERUFOJyxcbiAgICBNQU5IQVRUQU4gPSAnTUFOSEFUVEFOJyxcbiAgfTtcblxuZXhwb3J0IHR5cGUgRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCA9IGtleW9mIHR5cGVvZiBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kcztcbiJdfQ==","import { DistanceAggregationMethods } from './types';\nexport const isNil = (x) => x === null || x === undefined;\nexport function insertSmaller(distancesAr, indexes, num, index) {\n if (num > distancesAr[distancesAr.length - 1])\n return;\n const newPosition = distancesAr.findIndex((v) => num < v);\n distancesAr.pop();\n distancesAr.splice(newPosition, 0, num);\n indexes.pop();\n indexes.splice(newPosition, 0, index);\n}\nexport function insertLarger(distancesAr, indexes, num, index) {\n if (num < distancesAr[distancesAr.length - 1])\n return;\n const newPosition = distancesAr.findIndex((v) => num > v);\n distancesAr.pop();\n distancesAr.splice(newPosition, 0, num);\n indexes.pop();\n indexes.splice(newPosition, 0, index);\n}\nexport function getAggregationFunction(aggregationMethod, weights) {\n switch (aggregationMethod) {\n case DistanceAggregationMethods.MANHATTAN:\n return (vs) => vs.reduce((acc, val, idx) => acc + val * weights[idx], 0);\n default:\n return (vs) => {\n // euclidean\n const sum = vs.reduce((acc, val, idx) => acc + (val * weights[idx]) ** 2, 0);\n return Math.sqrt(sum);\n };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTRCLDBCQUEwQixFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRTlFLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssU0FBUyxDQUFDO0FBRS9ELE1BQU0sVUFBVSxhQUFhLENBQUMsV0FBcUIsRUFBRSxPQUFpQixFQUFFLEdBQVcsRUFBRSxLQUFhO0lBQ2hHLElBQUksR0FBRyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQztRQUN6QyxPQUFPO0lBRVQsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzFELFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNsQixXQUFXLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDeEMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ2QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFFRCxNQUFNLFVBQVUsWUFBWSxDQUFDLFdBQXFCLEVBQUUsT0FBaUIsRUFBRSxHQUFXLEVBQUUsS0FBYTtJQUMvRixJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUM7UUFDekMsT0FBTztJQUVULE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMxRCxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDbEIsV0FBVyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3hDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNkLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQsTUFBTSxVQUFVLHNCQUFzQixDQUNwQyxpQkFBNEMsRUFBRSxPQUFpQjtJQUUvRCxRQUFRLGlCQUFpQixFQUFFLENBQUM7UUFDMUIsS0FBSywwQkFBMEIsQ0FBQyxTQUFTO1lBQ3ZDLE9BQU8sQ0FBQyxFQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckY7WUFDRSxPQUFPLENBQUMsRUFBWSxFQUFFLEVBQUU7Z0JBQ3RCLFlBQVk7Z0JBQ1osTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUM3RSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEIsQ0FBQyxDQUFDO0lBQ04sQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0Rpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsIERpc3RhbmNlQWdncmVnYXRpb25NZXRob2RzfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGlzTmlsID0gKHg6IGFueSkgPT4geCA9PT0gbnVsbCB8fCB4ID09PSB1bmRlZmluZWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRTbWFsbGVyKGRpc3RhbmNlc0FyOiBudW1iZXJbXSwgaW5kZXhlczogbnVtYmVyW10sIG51bTogbnVtYmVyLCBpbmRleDogbnVtYmVyKSB7XG4gIGlmIChudW0gPiBkaXN0YW5jZXNBcltkaXN0YW5jZXNBci5sZW5ndGgtMV0pXG4gICAgcmV0dXJuO1xuXG4gIGNvbnN0IG5ld1Bvc2l0aW9uID0gZGlzdGFuY2VzQXIuZmluZEluZGV4KCh2KSA9PiBudW0gPCB2KTtcbiAgZGlzdGFuY2VzQXIucG9wKCk7XG4gIGRpc3RhbmNlc0FyLnNwbGljZShuZXdQb3NpdGlvbiwgMCwgbnVtKTtcbiAgaW5kZXhlcy5wb3AoKTtcbiAgaW5kZXhlcy5zcGxpY2UobmV3UG9zaXRpb24sIDAsIGluZGV4KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydExhcmdlcihkaXN0YW5jZXNBcjogbnVtYmVyW10sIGluZGV4ZXM6IG51bWJlcltdLCBudW06IG51bWJlciwgaW5kZXg6IG51bWJlcikge1xuICBpZiAobnVtIDwgZGlzdGFuY2VzQXJbZGlzdGFuY2VzQXIubGVuZ3RoLTFdKVxuICAgIHJldHVybjtcblxuICBjb25zdCBuZXdQb3NpdGlvbiA9IGRpc3RhbmNlc0FyLmZpbmRJbmRleCgodikgPT4gbnVtID4gdik7XG4gIGRpc3RhbmNlc0FyLnBvcCgpO1xuICBkaXN0YW5jZXNBci5zcGxpY2UobmV3UG9zaXRpb24sIDAsIG51bSk7XG4gIGluZGV4ZXMucG9wKCk7XG4gIGluZGV4ZXMuc3BsaWNlKG5ld1Bvc2l0aW9uLCAwLCBpbmRleCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBZ2dyZWdhdGlvbkZ1bmN0aW9uKFxuICBhZ2dyZWdhdGlvbk1ldGhvZDogRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCwgd2VpZ2h0czogbnVtYmVyW11cbik6ICh2YWx1ZXM6IG51bWJlcltdKSA9PiBudW1iZXIge1xuICBzd2l0Y2ggKGFnZ3JlZ2F0aW9uTWV0aG9kKSB7XG4gICAgY2FzZSBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kcy5NQU5IQVRUQU46XG4gICAgICByZXR1cm4gKHZzOiBudW1iZXJbXSkgPT4gdnMucmVkdWNlKChhY2MsIHZhbCwgaWR4KSA9PiBhY2MgKyB2YWwgKiB3ZWlnaHRzW2lkeF0sIDApO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gKHZzOiBudW1iZXJbXSkgPT4ge1xuICAgICAgICAvLyBldWNsaWRlYW5cbiAgICAgICAgY29uc3Qgc3VtID0gdnMucmVkdWNlKChhY2MsIHZhbCwgaWR4KSA9PiBhY2MgKyAodmFsICogd2VpZ2h0c1tpZHhdKSAqKiAyLCAwKTtcbiAgICAgICAgcmV0dXJuIE1hdGguc3FydChzdW0pO1xuICAgICAgfTtcbiAgfVxufVxuIl19","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport { BYPASS_LARGE_DATA_WARNING, SHOW_SCATTERPLOT_PROGRESS } from '../functionEditors/consts';\nimport { getDbscanWorker } from '@datagrok-libraries/math';\nimport { DIMENSIONALITY_REDUCER_TERMINATE_EVENT } from './consts';\nimport { getNormalizedEmbeddings } from './embeddings-space';\nexport function getEmbeddingColsNames(df) {\n const axes = ['Embed_X', 'Embed_Y'];\n const colNameInd = df.columns.names().filter((it) => it.includes(axes[0])).length + 1;\n return axes.map((it) => `${it}_${colNameInd}`);\n}\nexport function getEmbeddingViewerName(columns, method) {\n const colNames = columns.length > 4 ? `${columns.length} columns` : columns.map((it) => it.name).join(', ');\n return `${method} (${colNames})`;\n}\nexport async function multiColReduceDimensionality(table, columns, method, metrics, weights, preprocessingFunctions, aggregationMethod, plotEmbeddings = true, clusterEmbeddings = false, dimRedOptions = { preprocessingFuncArgs: [] }, uiOptions = {}, postProcessingFunc = null, postProcFuncArgs = {}) {\n const scatterPlotProps = {\n showXAxis: false,\n showYAxis: false,\n showXSelector: false,\n showYSelector: false,\n };\n if (columns.length !== metrics.length || columns.length !== preprocessingFunctions.length ||\n columns.length !== weights.length || columns.length !== dimRedOptions.preprocessingFuncArgs.length) {\n throw new Error('columns, metrics and preprocessing functions, weights and function arguments' +\n 'must have the same length');\n }\n const tv = plotEmbeddings ? (uiOptions.tableView ?? grok.shell.tableView(table.name) ?? grok.shell.addTableView(table)) : null;\n const doReduce = async () => {\n const pg = DG.TaskBarProgressIndicator.create(`Initializing ${uiOptions.scatterPlotName ?? 'dimensionality reduction'} ...`);\n let scatterPlot = undefined;\n try {\n const embedColsNames = getEmbeddingColsNames(table);\n function progressFunc(_nEpoch, epochsLength, embeddings) {\n let embedXCol = null;\n let embedYCol = null;\n if (!table.columns.names().includes(embedColsNames[0])) {\n embedXCol = table.columns.add(DG.Column.float(embedColsNames[0], table.rowCount));\n embedYCol = table.columns.add(DG.Column.float(embedColsNames[1], table.rowCount));\n if (plotEmbeddings && !scatterPlot) {\n scatterPlot = tv\n .scatterPlot({ ...scatterPlotProps, x: embedColsNames[0], y: embedColsNames[1],\n title: uiOptions.scatterPlotName ?? getEmbeddingViewerName(columns, method) });\n }\n }\n else {\n embedXCol = table.columns.byName(embedColsNames[0]);\n embedYCol = table.columns.byName(embedColsNames[1]);\n }\n if (uiOptions[SHOW_SCATTERPLOT_PROGRESS]) {\n scatterPlot?.root && ui.setUpdateIndicator(scatterPlot.root, false);\n embedXCol.init((i) => embeddings[0] ? embeddings[0][i] : undefined);\n embedYCol.init((i) => embeddings[1] ? embeddings[1][i] : undefined);\n }\n const progress = (_nEpoch / epochsLength * 100);\n pg.update(progress, `Running ${uiOptions.scatterPlotName ?? 'dimensionality reduction'}... ${progress.toFixed(0)}%`);\n }\n async function getDimRed() {\n table.columns.add(DG.Column.float(embedColsNames[0], table.rowCount));\n table.columns.add(DG.Column.float(embedColsNames[1], table.rowCount));\n let resolveF = null;\n if (plotEmbeddings) {\n scatterPlot = tv\n .scatterPlot({ ...scatterPlotProps, x: embedColsNames[0], y: embedColsNames[1],\n title: uiOptions.scatterPlotName ?? getEmbeddingViewerName(columns, method) });\n ui.setUpdateIndicator(scatterPlot.root, true);\n }\n const sub = grok.events.onViewerClosed.subscribe((args) => {\n const v = args.args.viewer;\n if (v?.getOptions()?.look?.title && scatterPlot?.getOptions()?.look?.title &&\n v?.getOptions()?.look?.title === scatterPlot?.getOptions()?.look?.title) {\n grok.events.fireCustomEvent(DIMENSIONALITY_REDUCER_TERMINATE_EVENT, {});\n sub.unsubscribe();\n resolveF?.();\n pg.close();\n }\n });\n const dimRedResPromise = new Promise(async (resolve, reject) => {\n try {\n resolveF = resolve;\n const encodedColEntries = [];\n for (let i = 0; i < preprocessingFunctions.length; ++i) {\n const pf = preprocessingFunctions[i];\n if (!dimRedOptions.distanceFnArgs)\n dimRedOptions.distanceFnArgs = [];\n if (pf) {\n const colInputName = pf.inputs[0].name;\n const metricInputName = pf.inputs[1].name;\n const { entries, options } = await pf.apply({ [colInputName]: columns[i], [metricInputName]: metrics[i],\n ...(dimRedOptions.preprocessingFuncArgs[i] ?? {}) });\n encodedColEntries.push({ entries, options });\n dimRedOptions.distanceFnArgs.push(options);\n }\n else {\n const entries = columns[i].toList();\n const options = {};\n encodedColEntries.push({ entries, options });\n dimRedOptions.distanceFnArgs.push(options);\n }\n }\n const res = await getNormalizedEmbeddings(encodedColEntries.map((it) => it.entries), method, metrics, weights, aggregationMethod, dimRedOptions, uiOptions[BYPASS_LARGE_DATA_WARNING] ? undefined : progressFunc);\n resolve(res);\n }\n catch (e) {\n reject(e);\n }\n });\n const res = await dimRedResPromise;\n pg.close();\n sub.unsubscribe();\n return res;\n }\n const res = await getDimRed();\n if (clusterEmbeddings && res) {\n const clusterPg = DG.TaskBarProgressIndicator.create(`Clustering embeddings ...`);\n try {\n const clusterRes = await getDbscanWorker(res[0], res[1], dimRedOptions.dbScanEpsilon ?? 0.01, dimRedOptions.dbScanMinPts ?? 4);\n const clusterColName = table.columns.getUnusedName('Cluster (DBSCAN)');\n const clusterCol = table.columns.addNewString(clusterColName);\n clusterCol.init((i) => clusterRes[i].toString());\n if (scatterPlot)\n scatterPlot.props.colorColumnName = clusterColName;\n }\n catch (e) {\n grok.shell.error('Clustering embeddings failed');\n console.error(e);\n }\n finally {\n clusterPg.close();\n }\n }\n if (res) {\n const embedXCol = table.columns.byName(embedColsNames[0]);\n const embedYCol = table.columns.byName(embedColsNames[1]);\n embedXCol.init((i) => res[0][i]);\n embedYCol.init((i) => res[1][i]);\n if (postProcessingFunc) {\n try {\n const col1InputName = postProcessingFunc.inputs[0].name;\n const col2InputName = postProcessingFunc.inputs[1].name;\n await postProcessingFunc\n .prepare({ [col1InputName]: embedXCol, [col2InputName]: embedYCol, ...postProcFuncArgs })\n .call(true);\n }\n catch (e) {\n grok.shell.error('Post-processing failed');\n console.error(e);\n }\n }\n if (scatterPlot) {\n ui.setUpdateIndicator(scatterPlot.root, false);\n scatterPlot.helpUrl = '/help/compute/sequence-space';\n return scatterPlot;\n }\n }\n }\n catch (e) {\n grok.shell.error('Dimensionality reduction failed');\n console.error(e);\n pg.close();\n if (scatterPlot)\n ui.setUpdateIndicator(scatterPlot.root, false);\n }\n };\n return new Promise(async (resolve, reject) => {\n try {\n if (uiOptions.fastRowCount && table.rowCount > uiOptions.fastRowCount && !uiOptions[BYPASS_LARGE_DATA_WARNING]) {\n ui.dialog()\n .add(ui.divText('Analysis might take several minutes. Do you want to continue?'))\n .onOK(async () => {\n try {\n const res = await doReduce();\n resolve(res);\n }\n catch (e) {\n reject(e);\n }\n })\n .onCancel(() => resolve(undefined))\n .show();\n }\n else {\n const res = await doReduce();\n resolve(res);\n }\n }\n catch (e) {\n reject(e);\n }\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlLWRpbWVuc2lvbmFsaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVkdWNlLWRpbWVuc2lvbmFsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sbUJBQW1CLENBQUM7QUFDMUMsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXRDLE9BQU8sRUFBQyx5QkFBeUIsRUFBRSx5QkFBeUIsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBRS9GLE9BQU8sRUFBaUIsZUFBZSxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDekUsT0FBTyxFQUFDLHNDQUFzQyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBRWhFLE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBYTNELE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxFQUFnQjtJQUNwRCxNQUFNLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNwQyxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQVUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDOUYsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0FBQ2pELENBQUM7QUFFRCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsT0FBb0IsRUFBRSxNQUEyQjtJQUN0RixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxVQUFVLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUcsT0FBTyxHQUFHLE1BQU0sS0FBSyxRQUFRLEdBQUcsQ0FBQztBQUNuQyxDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSw0QkFBNEIsQ0FBQyxLQUFtQixFQUFFLE9BQW9CLEVBQzFGLE1BQTJCLEVBQUUsT0FBdUIsRUFBRSxPQUFpQixFQUN2RSxzQkFBc0QsRUFDdEQsaUJBQTRDLEVBQUUsaUJBQTBCLElBQUksRUFBRSxvQkFBNkIsS0FBSyxFQUNoSCxnQkFDWSxFQUFDLHFCQUFxQixFQUFFLEVBQUUsRUFBQyxFQUN2QyxZQUE2QixFQUFFLEVBQUUscUJBQXFDLElBQUksRUFBRSxtQkFBNEIsRUFBRTtJQUUxRyxNQUFNLGdCQUFnQixHQUFHO1FBQ3ZCLFNBQVMsRUFBRSxLQUFLO1FBQ2hCLFNBQVMsRUFBRSxLQUFLO1FBQ2hCLGFBQWEsRUFBRSxLQUFLO1FBQ3BCLGFBQWEsRUFBRSxLQUFLO0tBQ3JCLENBQUM7SUFDRixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLHNCQUFzQixDQUFDLE1BQU07UUFDdkYsT0FBTyxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssYUFBYSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3JHLE1BQU0sSUFBSSxLQUFLLENBQUMsOEVBQThFO1lBQzVGLDJCQUEyQixDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELE1BQU0sRUFBRSxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFFL0gsTUFBTSxRQUFRLEdBQUcsS0FBSyxJQUFJLEVBQUU7UUFDMUIsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FDM0MsZ0JBQWdCLFNBQVMsQ0FBQyxlQUFlLElBQUksMEJBQTBCLE1BQU0sQ0FBQyxDQUFDO1FBQ2pGLElBQUksV0FBVyxHQUFxQyxTQUFTLENBQUM7UUFDOUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxjQUFjLEdBQUcscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEQsU0FBUyxZQUFZLENBQUMsT0FBZSxFQUFFLFlBQW9CLEVBQUUsVUFBc0I7Z0JBQ2pGLElBQUksU0FBUyxHQUFxQixJQUFJLENBQUM7Z0JBQ3ZDLElBQUksU0FBUyxHQUFxQixJQUFJLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUN2RCxTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO29CQUNsRixTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO29CQUNsRixJQUFJLGNBQWMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO3dCQUNuQyxXQUFXLEdBQUcsRUFBRzs2QkFDZCxXQUFXLENBQUMsRUFBQyxHQUFHLGdCQUFnQixFQUFFLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7NEJBQzNFLEtBQUssRUFBRSxTQUFTLENBQUMsZUFBZSxJQUFJLHNCQUFzQixDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsRUFBQyxDQUFDLENBQUM7b0JBQ3BGLENBQUM7Z0JBQ0gsQ0FBQztxQkFBTSxDQUFDO29CQUNOLFNBQVMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDcEQsU0FBUyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0RCxDQUFDO2dCQUVELElBQUksU0FBUyxDQUFDLHlCQUF5QixDQUFDLEVBQUUsQ0FBQztvQkFDekMsV0FBVyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsa0JBQWtCLENBQUMsV0FBWSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDckUsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUNwRSxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQ3RFLENBQUM7Z0JBQ0QsTUFBTSxRQUFRLEdBQUcsQ0FBQyxPQUFPLEdBQUcsWUFBWSxHQUFHLEdBQUcsQ0FBQyxDQUFDO2dCQUNoRCxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFDaEIsV0FBVyxTQUFTLENBQUMsZUFBZSxJQUFJLDBCQUEwQixPQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JHLENBQUM7WUFDRCxLQUFLLFVBQVUsU0FBUztnQkFDdEIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUN0RSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RFLElBQUksUUFBUSxHQUFvQixJQUFJLENBQUM7Z0JBQ3JDLElBQUksY0FBYyxFQUFFLENBQUM7b0JBQ25CLFdBQVcsR0FBRyxFQUFHO3lCQUNkLFdBQVcsQ0FBQyxFQUFDLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQzt3QkFDM0UsS0FBSyxFQUFFLFNBQVMsQ0FBQyxlQUFlLElBQUksc0JBQXNCLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxFQUFDLENBQUMsQ0FBQztvQkFDbEYsRUFBRSxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2hELENBQUM7Z0JBRUQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7b0JBQ3hELE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBbUMsQ0FBQztvQkFDeEQsSUFBSSxDQUFDLEVBQUUsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssSUFBSSxXQUFXLEVBQUUsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUs7d0JBQ3hFLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxLQUFLLFdBQVcsRUFBRSxVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUM7d0JBQzFFLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLHNDQUFzQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO3dCQUN4RSxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7d0JBQ2xCLFFBQVEsRUFBRSxFQUFFLENBQUM7d0JBQ2IsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNiLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7Z0JBRUgsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLE9BQU8sQ0FBcUIsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtvQkFDakYsSUFBSSxDQUFDO3dCQUNILFFBQVEsR0FBRyxPQUFPLENBQUM7d0JBQ25CLE1BQU0saUJBQWlCLEdBQW1DLEVBQUUsQ0FBQzt3QkFDN0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDOzRCQUN2RCxNQUFNLEVBQUUsR0FBRyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDckMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjO2dDQUMvQixhQUFhLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQzs0QkFDcEMsSUFBSSxFQUFFLEVBQUUsQ0FBQztnQ0FDUCxNQUFNLFlBQVksR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztnQ0FDdkMsTUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0NBQzFDLE1BQU0sRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFDLEdBQ3hCLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsWUFBWSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztvQ0FDdkUsR0FBRyxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUM7Z0NBQ3RELGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDO2dDQUMzQyxhQUFhLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzs0QkFDN0MsQ0FBQztpQ0FBTSxDQUFDO2dDQUNOLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQ0FDcEMsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDO2dDQUNuQixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztnQ0FDM0MsYUFBYSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7NEJBQzdDLENBQUM7d0JBQ0gsQ0FBQzt3QkFDRCxNQUFNLEdBQUcsR0FBRyxNQUFNLHVCQUF1QixDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFDekYsT0FBTyxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxhQUFhLEVBQ2xELFNBQVMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDO3dCQUNuRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ2YsQ0FBQztvQkFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO3dCQUNYLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDWixDQUFDO2dCQUNILENBQUMsQ0FBQyxDQUFDO2dCQUNILE1BQU0sR0FBRyxHQUFHLE1BQU0sZ0JBQWdCLENBQUM7Z0JBQ25DLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ2xCLE9BQU8sR0FBRyxDQUFDO1lBQ2IsQ0FBQztZQUNELE1BQU0sR0FBRyxHQUFHLE1BQU0sU0FBUyxFQUFFLENBQUM7WUFFOUIsSUFBSSxpQkFBaUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztnQkFDN0IsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO2dCQUNsRixJQUFJLENBQUM7b0JBQ0gsTUFBTSxVQUFVLEdBQUcsTUFBTSxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFDckQsYUFBYSxDQUFDLGFBQWEsSUFBSSxJQUFJLEVBQUUsYUFBYSxDQUFDLFlBQVksSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDeEUsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsQ0FBQztvQkFDdkUsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLENBQUM7b0JBQzlELFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO29CQUNqRCxJQUFJLFdBQVc7d0JBQ1osV0FBb0MsQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLGNBQWMsQ0FBQztnQkFDakYsQ0FBQztnQkFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUNYLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7b0JBQ2pELE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLENBQUM7d0JBQVMsQ0FBQztvQkFDVCxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3BCLENBQUM7WUFDSCxDQUFDO1lBQ0QsSUFBSSxHQUFHLEVBQUUsQ0FBQztnQkFDUixNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDMUQsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzFELFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakMsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO29CQUN2QixJQUFJLENBQUM7d0JBQ0gsTUFBTSxhQUFhLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQzt3QkFDeEQsTUFBTSxhQUFhLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQzt3QkFDeEQsTUFBTSxrQkFBa0I7NkJBQ3JCLE9BQU8sQ0FBQyxFQUFDLENBQUMsYUFBYSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsYUFBYSxDQUFDLEVBQUUsU0FBUyxFQUFFLEdBQUcsZ0JBQWdCLEVBQUMsQ0FBQzs2QkFDdEYsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNoQixDQUFDO29CQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7d0JBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQzt3QkFDM0MsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbkIsQ0FBQztnQkFDSCxDQUFDO2dCQUNELElBQUksV0FBVyxFQUFFLENBQUM7b0JBQ2hCLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBRSxXQUFvQyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDeEUsV0FBb0MsQ0FBQyxPQUFPLEdBQUcsOEJBQThCLENBQUM7b0JBQy9FLE9BQU8sV0FBbUMsQ0FBQztnQkFDN0MsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7WUFDcEQsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqQixFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxJQUFJLFdBQVc7Z0JBQ2IsRUFBRSxDQUFDLGtCQUFrQixDQUFFLFdBQW9DLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzdFLENBQUM7SUFDSCxDQUFDLENBQUM7SUFDRixPQUFPLElBQUksT0FBTyxDQUFtQyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQzdFLElBQUksQ0FBQztZQUNILElBQUksU0FBUyxDQUFDLFlBQVksSUFBSSxLQUFLLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQyxZQUFZLElBQUksQ0FBQyxTQUFTLENBQUMseUJBQXlCLENBQUMsRUFBRSxDQUFDO2dCQUMvRyxFQUFFLENBQUMsTUFBTSxFQUFFO3FCQUNSLEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLCtEQUErRCxDQUFDLENBQUM7cUJBQ2hGLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRTtvQkFDZixJQUFJLENBQUM7d0JBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxRQUFRLEVBQUUsQ0FBQzt3QkFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNmLENBQUM7b0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQzt3QkFDWCxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ1osQ0FBQztnQkFDSCxDQUFDLENBQUM7cUJBQ0QsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDbEMsSUFBSSxFQUFFLENBQUM7WUFDWixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxHQUFHLEdBQUcsTUFBTSxRQUFRLEVBQUUsQ0FBQztnQkFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ1osQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuaW1wb3J0ICogYXMgdWkgZnJvbSAnZGF0YWdyb2stYXBpL3VpJztcbmltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5pbXBvcnQge0tub3duTWV0cmljc30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQge0JZUEFTU19MQVJHRV9EQVRBX1dBUk5JTkcsIFNIT1dfU0NBVFRFUlBMT1RfUFJPR1JFU1N9IGZyb20gJy4uL2Z1bmN0aW9uRWRpdG9ycy9jb25zdHMnO1xuaW1wb3J0IHtNYXRyaXgsIE9wdGlvbnN9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7SURCU2Nhbk9wdGlvbnMsIGdldERic2Nhbldvcmtlcn0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy9tYXRoJztcbmltcG9ydCB7RElNRU5TSU9OQUxJVFlfUkVEVUNFUl9URVJNSU5BVEVfRVZFTlR9IGZyb20gJy4vY29uc3RzJztcbmltcG9ydCB7UHJlcHJvY2Vzc0Z1bmN0aW9uUmV0dXJuVHlwZX0gZnJvbSAnLi4vZnVuY3Rpb25FZGl0b3JzL2RpbWVuc2lvbmFsaXR5LXJlZHVjdGlvbi1lZGl0b3InO1xuaW1wb3J0IHtnZXROb3JtYWxpemVkRW1iZWRkaW5nc30gZnJvbSAnLi9lbWJlZGRpbmdzLXNwYWNlJztcbmltcG9ydCB7RGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZH0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3R5cGVzJztcbmltcG9ydCB7SVRTTkVPcHRpb25zLCBJVU1BUE9wdGlvbnN9IGZyb20gJy4vbXVsdGktY29sdW1uLWRpbS1yZWR1Y2VyJztcbmltcG9ydCB7RGltUmVkdWN0aW9uTWV0aG9kc30gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCB0eXBlIERpbVJlZFVpT3B0aW9ucyA9IHtcbiAgW0JZUEFTU19MQVJHRV9EQVRBX1dBUk5JTkddPzogYm9vbGVhbixcbiAgW1NIT1dfU0NBVFRFUlBMT1RfUFJPR1JFU1NdPzogYm9vbGVhbixcbiAgZmFzdFJvd0NvdW50PzogbnVtYmVyLFxuICBzY2F0dGVyUGxvdE5hbWU/OiBzdHJpbmcsXG4gIHRhYmxlVmlldz86IERHLlRhYmxlVmlldyxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVtYmVkZGluZ0NvbHNOYW1lcyhkZjogREcuRGF0YUZyYW1lKSB7XG4gIGNvbnN0IGF4ZXMgPSBbJ0VtYmVkX1gnLCAnRW1iZWRfWSddO1xuICBjb25zdCBjb2xOYW1lSW5kID0gZGYuY29sdW1ucy5uYW1lcygpLmZpbHRlcigoaXQ6IHN0cmluZykgPT4gaXQuaW5jbHVkZXMoYXhlc1swXSkpLmxlbmd0aCArIDE7XG4gIHJldHVybiBheGVzLm1hcCgoaXQpID0+IGAke2l0fV8ke2NvbE5hbWVJbmR9YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbWJlZGRpbmdWaWV3ZXJOYW1lKGNvbHVtbnM6IERHLkNvbHVtbltdLCBtZXRob2Q6IERpbVJlZHVjdGlvbk1ldGhvZHMpIHtcbiAgY29uc3QgY29sTmFtZXMgPSBjb2x1bW5zLmxlbmd0aCA+IDQgPyBgJHtjb2x1bW5zLmxlbmd0aH0gY29sdW1uc2AgOiBjb2x1bW5zLm1hcCgoaXQpID0+IGl0Lm5hbWUpLmpvaW4oJywgJyk7XG4gIHJldHVybiBgJHttZXRob2R9ICgke2NvbE5hbWVzfSlgO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbXVsdGlDb2xSZWR1Y2VEaW1lbnNpb25hbGl0eSh0YWJsZTogREcuRGF0YUZyYW1lLCBjb2x1bW5zOiBERy5Db2x1bW5bXSxcbiAgbWV0aG9kOiBEaW1SZWR1Y3Rpb25NZXRob2RzLCBtZXRyaWNzOiBLbm93bk1ldHJpY3NbXSwgd2VpZ2h0czogbnVtYmVyW10sXG4gIHByZXByb2Nlc3NpbmdGdW5jdGlvbnM6IChERy5GdW5jIHwgbnVsbCB8IHVuZGVmaW5lZClbXSxcbiAgYWdncmVnYXRpb25NZXRob2Q6IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsIHBsb3RFbWJlZGRpbmdzOiBib29sZWFuID0gdHJ1ZSwgY2x1c3RlckVtYmVkZGluZ3M6IGJvb2xlYW4gPSBmYWxzZSxcbiAgZGltUmVkT3B0aW9uczogKElVTUFQT3B0aW9ucyB8IElUU05FT3B0aW9ucykgJiBQYXJ0aWFsPElEQlNjYW5PcHRpb25zPiAmIHtwcmVwcm9jZXNzaW5nRnVuY0FyZ3M6IE9wdGlvbnNbXX0gJlxuICAgIE9wdGlvbnMgPSB7cHJlcHJvY2Vzc2luZ0Z1bmNBcmdzOiBbXX0sXG4gIHVpT3B0aW9uczogRGltUmVkVWlPcHRpb25zID0ge30sIHBvc3RQcm9jZXNzaW5nRnVuYzogREcuRnVuYyB8IG51bGwgPSBudWxsLCBwb3N0UHJvY0Z1bmNBcmdzOiBPcHRpb25zID0ge31cbik6IFByb21pc2U8REcuU2NhdHRlclBsb3RWaWV3ZXIgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3Qgc2NhdHRlclBsb3RQcm9wcyA9IHtcbiAgICBzaG93WEF4aXM6IGZhbHNlLFxuICAgIHNob3dZQXhpczogZmFsc2UsXG4gICAgc2hvd1hTZWxlY3RvcjogZmFsc2UsXG4gICAgc2hvd1lTZWxlY3RvcjogZmFsc2UsXG4gIH07XG4gIGlmIChjb2x1bW5zLmxlbmd0aCAhPT0gbWV0cmljcy5sZW5ndGggfHwgY29sdW1ucy5sZW5ndGggIT09IHByZXByb2Nlc3NpbmdGdW5jdGlvbnMubGVuZ3RoIHx8XG4gICAgY29sdW1ucy5sZW5ndGggIT09IHdlaWdodHMubGVuZ3RoIHx8IGNvbHVtbnMubGVuZ3RoICE9PSBkaW1SZWRPcHRpb25zLnByZXByb2Nlc3NpbmdGdW5jQXJncy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbHVtbnMsIG1ldHJpY3MgYW5kIHByZXByb2Nlc3NpbmcgZnVuY3Rpb25zLCB3ZWlnaHRzIGFuZCBmdW5jdGlvbiBhcmd1bWVudHMnICtcbiAgICAgICdtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoJyk7XG4gIH1cblxuICBjb25zdCB0diA9IHBsb3RFbWJlZGRpbmdzID8gKHVpT3B0aW9ucy50YWJsZVZpZXcgPz8gZ3Jvay5zaGVsbC50YWJsZVZpZXcodGFibGUubmFtZSkgPz8gZ3Jvay5zaGVsbC5hZGRUYWJsZVZpZXcodGFibGUpKSA6IG51bGw7XG5cbiAgY29uc3QgZG9SZWR1Y2UgPSBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGcgPSBERy5UYXNrQmFyUHJvZ3Jlc3NJbmRpY2F0b3IuY3JlYXRlKFxuICAgICAgYEluaXRpYWxpemluZyAke3VpT3B0aW9ucy5zY2F0dGVyUGxvdE5hbWUgPz8gJ2RpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbid9IC4uLmApO1xuICAgIGxldCBzY2F0dGVyUGxvdDogREcuU2NhdHRlclBsb3RWaWV3ZXIgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGVtYmVkQ29sc05hbWVzID0gZ2V0RW1iZWRkaW5nQ29sc05hbWVzKHRhYmxlKTtcbiAgICAgIGZ1bmN0aW9uIHByb2dyZXNzRnVuYyhfbkVwb2NoOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmdzOiBudW1iZXJbXVtdKSB7XG4gICAgICAgIGxldCBlbWJlZFhDb2w6IERHLkNvbHVtbiB8IG51bGwgPSBudWxsO1xuICAgICAgICBsZXQgZW1iZWRZQ29sOiBERy5Db2x1bW4gfCBudWxsID0gbnVsbDtcbiAgICAgICAgaWYgKCF0YWJsZS5jb2x1bW5zLm5hbWVzKCkuaW5jbHVkZXMoZW1iZWRDb2xzTmFtZXNbMF0pKSB7XG4gICAgICAgICAgZW1iZWRYQ29sID0gdGFibGUuY29sdW1ucy5hZGQoREcuQ29sdW1uLmZsb2F0KGVtYmVkQ29sc05hbWVzWzBdLCB0YWJsZS5yb3dDb3VudCkpO1xuICAgICAgICAgIGVtYmVkWUNvbCA9IHRhYmxlLmNvbHVtbnMuYWRkKERHLkNvbHVtbi5mbG9hdChlbWJlZENvbHNOYW1lc1sxXSwgdGFibGUucm93Q291bnQpKTtcbiAgICAgICAgICBpZiAocGxvdEVtYmVkZGluZ3MgJiYgIXNjYXR0ZXJQbG90KSB7XG4gICAgICAgICAgICBzY2F0dGVyUGxvdCA9IHR2IVxuICAgICAgICAgICAgICAuc2NhdHRlclBsb3Qoey4uLnNjYXR0ZXJQbG90UHJvcHMsIHg6IGVtYmVkQ29sc05hbWVzWzBdLCB5OiBlbWJlZENvbHNOYW1lc1sxXSxcbiAgICAgICAgICAgICAgICB0aXRsZTogdWlPcHRpb25zLnNjYXR0ZXJQbG90TmFtZSA/PyBnZXRFbWJlZGRpbmdWaWV3ZXJOYW1lKGNvbHVtbnMsIG1ldGhvZCl9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW1iZWRYQ29sID0gdGFibGUuY29sdW1ucy5ieU5hbWUoZW1iZWRDb2xzTmFtZXNbMF0pO1xuICAgICAgICAgIGVtYmVkWUNvbCA9IHRhYmxlLmNvbHVtbnMuYnlOYW1lKGVtYmVkQ29sc05hbWVzWzFdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1aU9wdGlvbnNbU0hPV19TQ0FUVEVSUExPVF9QUk9HUkVTU10pIHtcbiAgICAgICAgICBzY2F0dGVyUGxvdD8ucm9vdCAmJiB1aS5zZXRVcGRhdGVJbmRpY2F0b3Ioc2NhdHRlclBsb3QhLnJvb3QsIGZhbHNlKTtcbiAgICAgICAgICBlbWJlZFhDb2wuaW5pdCgoaSkgPT4gZW1iZWRkaW5nc1swXSA/IGVtYmVkZGluZ3NbMF1baV0gOiB1bmRlZmluZWQpO1xuICAgICAgICAgIGVtYmVkWUNvbC5pbml0KChpKSA9PiBlbWJlZGRpbmdzWzFdID8gZW1iZWRkaW5nc1sxXVtpXSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvZ3Jlc3MgPSAoX25FcG9jaCAvIGVwb2Noc0xlbmd0aCAqIDEwMCk7XG4gICAgICAgIHBnLnVwZGF0ZShwcm9ncmVzcyxcbiAgICAgICAgICBgUnVubmluZyAke3VpT3B0aW9ucy5zY2F0dGVyUGxvdE5hbWUgPz8gJ2RpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbid9Li4uICR7cHJvZ3Jlc3MudG9GaXhlZCgwKX0lYCk7XG4gICAgICB9XG4gICAgICBhc3luYyBmdW5jdGlvbiBnZXREaW1SZWQoKSB7XG4gICAgICAgIHRhYmxlLmNvbHVtbnMuYWRkKERHLkNvbHVtbi5mbG9hdChlbWJlZENvbHNOYW1lc1swXSwgdGFibGUucm93Q291bnQpKTtcbiAgICAgICAgdGFibGUuY29sdW1ucy5hZGQoREcuQ29sdW1uLmZsb2F0KGVtYmVkQ29sc05hbWVzWzFdLCB0YWJsZS5yb3dDb3VudCkpO1xuICAgICAgICBsZXQgcmVzb2x2ZUY6IEZ1bmN0aW9uIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGlmIChwbG90RW1iZWRkaW5ncykge1xuICAgICAgICAgIHNjYXR0ZXJQbG90ID0gdHYhXG4gICAgICAgICAgICAuc2NhdHRlclBsb3Qoey4uLnNjYXR0ZXJQbG90UHJvcHMsIHg6IGVtYmVkQ29sc05hbWVzWzBdLCB5OiBlbWJlZENvbHNOYW1lc1sxXSxcbiAgICAgICAgICAgICAgdGl0bGU6IHVpT3B0aW9ucy5zY2F0dGVyUGxvdE5hbWUgPz8gZ2V0RW1iZWRkaW5nVmlld2VyTmFtZShjb2x1bW5zLCBtZXRob2QpfSk7XG4gICAgICAgICAgdWkuc2V0VXBkYXRlSW5kaWNhdG9yKHNjYXR0ZXJQbG90LnJvb3QsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3ViID0gZ3Jvay5ldmVudHMub25WaWV3ZXJDbG9zZWQuc3Vic2NyaWJlKChhcmdzKSA9PiB7XG4gICAgICAgICAgY29uc3QgdiA9IGFyZ3MuYXJncy52aWV3ZXIgYXMgdW5rbm93biBhcyBERy5WaWV3ZXI8YW55PjtcbiAgICAgICAgICBpZiAodj8uZ2V0T3B0aW9ucygpPy5sb29rPy50aXRsZSAmJiBzY2F0dGVyUGxvdD8uZ2V0T3B0aW9ucygpPy5sb29rPy50aXRsZSAmJlxuICAgICAgICAgICAgdj8uZ2V0T3B0aW9ucygpPy5sb29rPy50aXRsZSA9PT0gc2NhdHRlclBsb3Q/LmdldE9wdGlvbnMoKT8ubG9vaz8udGl0bGUpIHtcbiAgICAgICAgICAgIGdyb2suZXZlbnRzLmZpcmVDdXN0b21FdmVudChESU1FTlNJT05BTElUWV9SRURVQ0VSX1RFUk1JTkFURV9FVkVOVCwge30pO1xuICAgICAgICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICByZXNvbHZlRj8uKCk7XG4gICAgICAgICAgICBwZy5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZGltUmVkUmVzUHJvbWlzZSA9IG5ldyBQcm9taXNlPE1hdHJpeCB8IHVuZGVmaW5lZD4oYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNvbHZlRiA9IHJlc29sdmU7XG4gICAgICAgICAgICBjb25zdCBlbmNvZGVkQ29sRW50cmllczogUHJlcHJvY2Vzc0Z1bmN0aW9uUmV0dXJuVHlwZVtdID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXByb2Nlc3NpbmdGdW5jdGlvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgY29uc3QgcGYgPSBwcmVwcm9jZXNzaW5nRnVuY3Rpb25zW2ldO1xuICAgICAgICAgICAgICBpZiAoIWRpbVJlZE9wdGlvbnMuZGlzdGFuY2VGbkFyZ3MpXG4gICAgICAgICAgICAgICAgZGltUmVkT3B0aW9ucy5kaXN0YW5jZUZuQXJncyA9IFtdO1xuICAgICAgICAgICAgICBpZiAocGYpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xJbnB1dE5hbWUgPSBwZi5pbnB1dHNbMF0ubmFtZTtcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJbnB1dE5hbWUgPSBwZi5pbnB1dHNbMV0ubmFtZTtcbiAgICAgICAgICAgICAgICBjb25zdCB7ZW50cmllcywgb3B0aW9uc306IFByZXByb2Nlc3NGdW5jdGlvblJldHVyblR5cGUgPVxuICAgICAgICAgICAgICAgIGF3YWl0IHBmLmFwcGx5KHtbY29sSW5wdXROYW1lXTogY29sdW1uc1tpXSwgW21ldHJpY0lucHV0TmFtZV06IG1ldHJpY3NbaV0sXG4gICAgICAgICAgICAgICAgICAuLi4oZGltUmVkT3B0aW9ucy5wcmVwcm9jZXNzaW5nRnVuY0FyZ3NbaV0gPz8ge30pfSk7XG4gICAgICAgICAgICAgICAgZW5jb2RlZENvbEVudHJpZXMucHVzaCh7ZW50cmllcywgb3B0aW9uc30pO1xuICAgICAgICAgICAgICAgIGRpbVJlZE9wdGlvbnMuZGlzdGFuY2VGbkFyZ3MucHVzaChvcHRpb25zKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRyaWVzID0gY29sdW1uc1tpXS50b0xpc3QoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgICAgICAgICAgICAgZW5jb2RlZENvbEVudHJpZXMucHVzaCh7ZW50cmllcywgb3B0aW9uc30pO1xuICAgICAgICAgICAgICAgIGRpbVJlZE9wdGlvbnMuZGlzdGFuY2VGbkFyZ3MucHVzaChvcHRpb25zKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2V0Tm9ybWFsaXplZEVtYmVkZGluZ3MoZW5jb2RlZENvbEVudHJpZXMubWFwKChpdCkgPT4gaXQuZW50cmllcyksIG1ldGhvZCxcbiAgICAgICAgICAgICAgbWV0cmljcywgd2VpZ2h0cywgYWdncmVnYXRpb25NZXRob2QsIGRpbVJlZE9wdGlvbnMsXG4gICAgICAgICAgICAgIHVpT3B0aW9uc1tCWVBBU1NfTEFSR0VfREFUQV9XQVJOSU5HXSA/IHVuZGVmaW5lZCA6IHByb2dyZXNzRnVuYyk7XG4gICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGRpbVJlZFJlc1Byb21pc2U7XG4gICAgICAgIHBnLmNsb3NlKCk7XG4gICAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2V0RGltUmVkKCk7XG5cbiAgICAgIGlmIChjbHVzdGVyRW1iZWRkaW5ncyAmJiByZXMpIHtcbiAgICAgICAgY29uc3QgY2x1c3RlclBnID0gREcuVGFza0JhclByb2dyZXNzSW5kaWNhdG9yLmNyZWF0ZShgQ2x1c3RlcmluZyBlbWJlZGRpbmdzIC4uLmApO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGNsdXN0ZXJSZXMgPSBhd2FpdCBnZXREYnNjYW5Xb3JrZXIocmVzWzBdLCByZXNbMV0sXG4gICAgICAgICAgICBkaW1SZWRPcHRpb25zLmRiU2NhbkVwc2lsb24gPz8gMC4wMSwgZGltUmVkT3B0aW9ucy5kYlNjYW5NaW5QdHMgPz8gNCk7XG4gICAgICAgICAgY29uc3QgY2x1c3RlckNvbE5hbWUgPSB0YWJsZS5jb2x1bW5zLmdldFVudXNlZE5hbWUoJ0NsdXN0ZXIgKERCU0NBTiknKTtcbiAgICAgICAgICBjb25zdCBjbHVzdGVyQ29sID0gdGFibGUuY29sdW1ucy5hZGROZXdTdHJpbmcoY2x1c3RlckNvbE5hbWUpO1xuICAgICAgICAgIGNsdXN0ZXJDb2wuaW5pdCgoaSkgPT4gY2x1c3RlclJlc1tpXS50b1N0cmluZygpKTtcbiAgICAgICAgICBpZiAoc2NhdHRlclBsb3QpXG4gICAgICAgICAgICAoc2NhdHRlclBsb3QgYXMgREcuU2NhdHRlclBsb3RWaWV3ZXIpLnByb3BzLmNvbG9yQ29sdW1uTmFtZSA9IGNsdXN0ZXJDb2xOYW1lO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgZ3Jvay5zaGVsbC5lcnJvcignQ2x1c3RlcmluZyBlbWJlZGRpbmdzIGZhaWxlZCcpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgY2x1c3RlclBnLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgY29uc3QgZW1iZWRYQ29sID0gdGFibGUuY29sdW1ucy5ieU5hbWUoZW1iZWRDb2xzTmFtZXNbMF0pO1xuICAgICAgICBjb25zdCBlbWJlZFlDb2wgPSB0YWJsZS5jb2x1bW5zLmJ5TmFtZShlbWJlZENvbHNOYW1lc1sxXSk7XG4gICAgICAgIGVtYmVkWENvbC5pbml0KChpKSA9PiByZXNbMF1baV0pO1xuICAgICAgICBlbWJlZFlDb2wuaW5pdCgoaSkgPT4gcmVzWzFdW2ldKTtcbiAgICAgICAgaWYgKHBvc3RQcm9jZXNzaW5nRnVuYykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjb2wxSW5wdXROYW1lID0gcG9zdFByb2Nlc3NpbmdGdW5jLmlucHV0c1swXS5uYW1lO1xuICAgICAgICAgICAgY29uc3QgY29sMklucHV0TmFtZSA9IHBvc3RQcm9jZXNzaW5nRnVuYy5pbnB1dHNbMV0ubmFtZTtcbiAgICAgICAgICAgIGF3YWl0IHBvc3RQcm9jZXNzaW5nRnVuY1xuICAgICAgICAgICAgICAucHJlcGFyZSh7W2NvbDFJbnB1dE5hbWVdOiBlbWJlZFhDb2wsIFtjb2wySW5wdXROYW1lXTogZW1iZWRZQ29sLCAuLi5wb3N0UHJvY0Z1bmNBcmdzfSlcbiAgICAgICAgICAgICAgLmNhbGwodHJ1ZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZ3Jvay5zaGVsbC5lcnJvcignUG9zdC1wcm9jZXNzaW5nIGZhaWxlZCcpO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjYXR0ZXJQbG90KSB7XG4gICAgICAgICAgdWkuc2V0VXBkYXRlSW5kaWNhdG9yKChzY2F0dGVyUGxvdCBhcyBERy5TY2F0dGVyUGxvdFZpZXdlcikucm9vdCwgZmFsc2UpO1xuICAgICAgICAgIChzY2F0dGVyUGxvdCBhcyBERy5TY2F0dGVyUGxvdFZpZXdlcikuaGVscFVybCA9ICcvaGVscC9jb21wdXRlL3NlcXVlbmNlLXNwYWNlJztcbiAgICAgICAgICByZXR1cm4gc2NhdHRlclBsb3QgYXMgREcuU2NhdHRlclBsb3RWaWV3ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBncm9rLnNoZWxsLmVycm9yKCdEaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gZmFpbGVkJyk7XG4gICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgcGcuY2xvc2UoKTtcbiAgICAgIGlmIChzY2F0dGVyUGxvdClcbiAgICAgICAgdWkuc2V0VXBkYXRlSW5kaWNhdG9yKChzY2F0dGVyUGxvdCBhcyBERy5TY2F0dGVyUGxvdFZpZXdlcikucm9vdCwgZmFsc2UpO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPERHLlNjYXR0ZXJQbG90Vmlld2VyIHwgdW5kZWZpbmVkPihhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh1aU9wdGlvbnMuZmFzdFJvd0NvdW50ICYmIHRhYmxlLnJvd0NvdW50ID4gdWlPcHRpb25zLmZhc3RSb3dDb3VudCAmJiAhdWlPcHRpb25zW0JZUEFTU19MQVJHRV9EQVRBX1dBUk5JTkddKSB7XG4gICAgICAgIHVpLmRpYWxvZygpXG4gICAgICAgICAgLmFkZCh1aS5kaXZUZXh0KCdBbmFseXNpcyBtaWdodCB0YWtlIHNldmVyYWwgbWludXRlcy4gRG8geW91IHdhbnQgdG8gY29udGludWU/JykpXG4gICAgICAgICAgLm9uT0soYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZG9SZWR1Y2UoKTtcbiAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgICAub25DYW5jZWwoKCkgPT4gcmVzb2x2ZSh1bmRlZmluZWQpKVxuICAgICAgICAgIC5zaG93KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBkb1JlZHVjZSgpO1xuICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmVqZWN0KGUpO1xuICAgIH1cbiAgfSk7XG59XG4iXX0=","import { createMultiDimRedWorker } from './multi-dim-red-worker-creator';\nimport { normalize } from '@datagrok-libraries/utils/src/vector-operations';\nexport async function getNormalizedEmbeddings(dataCols, methodName, distanceMetrics, weights, distanceAggregation, options, progressFunc) {\n let dimensionalityReduceRes = await createMultiDimRedWorker(dataCols, distanceMetrics, methodName, weights, distanceAggregation, options, progressFunc);\n dimensionalityReduceRes = dimensionalityReduceRes.map((it) => normalize(it));\n return dimensionalityReduceRes;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1iZWRkaW5ncy1zcGFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImVtYmVkZGluZ3Mtc3BhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sZ0NBQWdDLENBQUM7QUFFdkUsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGlEQUFpRCxDQUFDO0FBSTFFLE1BQU0sQ0FBQyxLQUFLLFVBQVUsdUJBQXVCLENBQzNDLFFBQXNCLEVBQ3RCLFVBQStCLEVBQy9CLGVBQStCLEVBQy9CLE9BQWlCLEVBQ2pCLG1CQUE4QyxFQUM5QyxPQUFZLEVBQUUsWUFBbUY7SUFFakcsSUFBSSx1QkFBdUIsR0FDbkIsTUFBTSx1QkFBdUIsQ0FDM0IsUUFBUSxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE9BQU8sRUFBRSxZQUFZLENBQzNGLENBQUM7SUFFVix1QkFBdUIsR0FBRyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdFLE9BQU8sdUJBQXVCLENBQUM7QUFDakMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TWF0cml4fSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge0tub3duTWV0cmljc30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQge2NyZWF0ZU11bHRpRGltUmVkV29ya2VyfSBmcm9tICcuL211bHRpLWRpbS1yZWQtd29ya2VyLWNyZWF0b3InO1xuaW1wb3J0IHtEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kfSBmcm9tICcuLi9kaXN0YW5jZS1tYXRyaXgvdHlwZXMnO1xuaW1wb3J0IHtub3JtYWxpemV9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3ZlY3Rvci1vcGVyYXRpb25zJztcbmltcG9ydCB7RGltUmVkdWN0aW9uTWV0aG9kc30gZnJvbSAnLi90eXBlcyc7XG5cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldE5vcm1hbGl6ZWRFbWJlZGRpbmdzKFxuICBkYXRhQ29sczogQXJyYXk8YW55W10+LFxuICBtZXRob2ROYW1lOiBEaW1SZWR1Y3Rpb25NZXRob2RzLFxuICBkaXN0YW5jZU1ldHJpY3M6IEtub3duTWV0cmljc1tdLFxuICB3ZWlnaHRzOiBudW1iZXJbXSxcbiAgZGlzdGFuY2VBZ2dyZWdhdGlvbjogRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCxcbiAgb3B0aW9uczogYW55LCBwcm9ncmVzc0Z1bmM/OiAoZXBvY2g6IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZzogbnVtYmVyW11bXSkgPT4gdm9pZFxuKTogUHJvbWlzZTxNYXRyaXg+IHtcbiAgbGV0IGRpbWVuc2lvbmFsaXR5UmVkdWNlUmVzOiBNYXRyaXggPVxuICAgICAgICAgIGF3YWl0IGNyZWF0ZU11bHRpRGltUmVkV29ya2VyKFxuICAgICAgICAgICAgZGF0YUNvbHMsIGRpc3RhbmNlTWV0cmljcywgbWV0aG9kTmFtZSwgd2VpZ2h0cywgZGlzdGFuY2VBZ2dyZWdhdGlvbiwgb3B0aW9ucywgcHJvZ3Jlc3NGdW5jXG4gICAgICAgICAgKTtcblxuICBkaW1lbnNpb25hbGl0eVJlZHVjZVJlcyA9IGRpbWVuc2lvbmFsaXR5UmVkdWNlUmVzLm1hcCgoaXQpID0+IG5vcm1hbGl6ZShpdCkpO1xuICByZXR1cm4gZGltZW5zaW9uYWxpdHlSZWR1Y2VSZXM7XG59XG5cbiJdfQ==","import * as grok from 'datagrok-api/grok';\nimport { DIMENSIONALITY_REDUCER_TERMINATE_EVENT } from './consts';\nimport { isNil } from '../distance-matrix/utils';\nexport async function createMultiDimRedWorker(data, metrics, method, weights, aggregationMethod, options, progressFunc) {\n if (!options.distanceFnArgs)\n throw new Error('options.distanceFnArgs must be defined');\n if (data.length !== metrics.length || data.length !== options.distanceFnArgs.length || data.length !== weights.length)\n throw new Error('data, metrics and options and weights must have the same length');\n return new Promise(function (resolve, reject) {\n const worker = new Worker(new URL('./mulit-column-dim-reducer-worker', import.meta.url));\n worker.postMessage({\n columnsData: data,\n distanceMetrics: metrics,\n method: method,\n options: options,\n weights: weights,\n aggregationMethod: aggregationMethod,\n });\n const terminateSub = grok.events.onCustomEvent(DIMENSIONALITY_REDUCER_TERMINATE_EVENT).subscribe(() => {\n try {\n worker?.terminate();\n }\n finally {\n terminateSub.unsubscribe();\n }\n });\n worker.onmessage = ({ data: { error, embedding, epochNum, epochsLength } }) => {\n if (!isNil(epochNum) && !isNil(epochsLength)) {\n progressFunc && progressFunc(epochNum, epochsLength, embedding);\n return;\n }\n terminateSub.unsubscribe();\n if (error)\n reject(error);\n else\n resolve(embedding);\n // terminate the worker after some time. immidiate termination causes crashes.\n setTimeout(() => worker.terminate(), 100);\n };\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktZGltLXJlZC13b3JrZXItY3JlYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm11bHRpLWRpbS1yZWQtd29ya2VyLWNyZWF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEVBQUMsc0NBQXNDLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFJaEUsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBRS9DLE1BQU0sQ0FBQyxLQUFLLFVBQVUsdUJBQXVCLENBQUMsSUFBa0IsRUFBRSxPQUF1QixFQUFFLE1BQTJCLEVBQ3BILE9BQWlCLEVBQUUsaUJBQTRDLEVBQy9ELE9BQVksRUFBRSxZQUFtRjtJQUVqRyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWM7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0lBQzVELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsTUFBTTtRQUNuSCxNQUFNLElBQUksS0FBSyxDQUFDLGlFQUFpRSxDQUFDLENBQUM7SUFDckYsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFTLE9BQU8sRUFBRSxNQUFNO1FBQ3pDLE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLG1DQUFtQyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN6RixNQUFNLENBQUMsV0FBVyxDQUFDO1lBQ2pCLFdBQVcsRUFBRSxJQUFJO1lBQ2pCLGVBQWUsRUFBRSxPQUFPO1lBQ3hCLE1BQU0sRUFBRSxNQUFNO1lBQ2QsT0FBTyxFQUFFLE9BQU87WUFDaEIsT0FBTyxFQUFFLE9BQU87WUFDaEIsaUJBQWlCLEVBQUUsaUJBQWlCO1NBQ3JDLENBQUMsQ0FBQztRQUNILE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLHNDQUFzQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNwRyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDO1lBQ3RCLENBQUM7b0JBQVMsQ0FBQztnQkFDVCxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDN0IsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUMsSUFBSSxFQUFFLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFDLEVBQUMsRUFBRSxFQUFFO1lBQ3hFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztnQkFDN0MsWUFBWSxJQUFJLFlBQVksQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUNoRSxPQUFPO1lBQ1QsQ0FBQztZQUNELFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQixJQUFJLEtBQUs7Z0JBQ1AsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDOztnQkFFZCxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDckIsOEVBQThFO1lBQzlFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtLbm93bk1ldHJpY3N9IGZyb20gJy4uL3R5cGVkLW1ldHJpY3MvdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcbmltcG9ydCB7RElNRU5TSU9OQUxJVFlfUkVEVUNFUl9URVJNSU5BVEVfRVZFTlR9IGZyb20gJy4vY29uc3RzJztcbmltcG9ydCB7TWF0cml4fSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge0RpbVJlZHVjdGlvbk1ldGhvZHN9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kfSBmcm9tICcuLi9kaXN0YW5jZS1tYXRyaXgvdHlwZXMnO1xuaW1wb3J0IHtpc05pbH0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3V0aWxzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU11bHRpRGltUmVkV29ya2VyKGRhdGE6IEFycmF5PGFueVtdPiwgbWV0cmljczogS25vd25NZXRyaWNzW10sIG1ldGhvZDogRGltUmVkdWN0aW9uTWV0aG9kcyxcbiAgd2VpZ2h0czogbnVtYmVyW10sIGFnZ3JlZ2F0aW9uTWV0aG9kOiBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kLFxuICBvcHRpb25zOiBhbnksIHByb2dyZXNzRnVuYz86IChlcG9jaDogbnVtYmVyLCBlcG9jaHNMZW5ndGg6IG51bWJlciwgZW1iZWRkaW5nOiBudW1iZXJbXVtdKSA9PiB2b2lkXG4pOiBQcm9taXNlPE1hdHJpeD4ge1xuICBpZiAoIW9wdGlvbnMuZGlzdGFuY2VGbkFyZ3MpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdvcHRpb25zLmRpc3RhbmNlRm5BcmdzIG11c3QgYmUgZGVmaW5lZCcpO1xuICBpZiAoZGF0YS5sZW5ndGggIT09IG1ldHJpY3MubGVuZ3RoIHx8IGRhdGEubGVuZ3RoICE9PSBvcHRpb25zLmRpc3RhbmNlRm5BcmdzLmxlbmd0aCB8fCBkYXRhLmxlbmd0aCAhPT0gd2VpZ2h0cy5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhLCBtZXRyaWNzIGFuZCBvcHRpb25zIGFuZCB3ZWlnaHRzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGgnKTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGNvbnN0IHdvcmtlciA9IG5ldyBXb3JrZXIobmV3IFVSTCgnLi9tdWxpdC1jb2x1bW4tZGltLXJlZHVjZXItd29ya2VyJywgaW1wb3J0Lm1ldGEudXJsKSk7XG4gICAgd29ya2VyLnBvc3RNZXNzYWdlKHtcbiAgICAgIGNvbHVtbnNEYXRhOiBkYXRhLFxuICAgICAgZGlzdGFuY2VNZXRyaWNzOiBtZXRyaWNzLFxuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBvcHRpb25zOiBvcHRpb25zLFxuICAgICAgd2VpZ2h0czogd2VpZ2h0cyxcbiAgICAgIGFnZ3JlZ2F0aW9uTWV0aG9kOiBhZ2dyZWdhdGlvbk1ldGhvZCxcbiAgICB9KTtcbiAgICBjb25zdCB0ZXJtaW5hdGVTdWIgPSBncm9rLmV2ZW50cy5vbkN1c3RvbUV2ZW50KERJTUVOU0lPTkFMSVRZX1JFRFVDRVJfVEVSTUlOQVRFX0VWRU5UKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgd29ya2VyPy50ZXJtaW5hdGUoKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRlcm1pbmF0ZVN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHdvcmtlci5vbm1lc3NhZ2UgPSAoe2RhdGE6IHtlcnJvciwgZW1iZWRkaW5nLCBlcG9jaE51bSwgZXBvY2hzTGVuZ3RofX0pID0+IHtcbiAgICAgIGlmICghaXNOaWwoZXBvY2hOdW0pICYmICFpc05pbChlcG9jaHNMZW5ndGgpKSB7XG4gICAgICAgIHByb2dyZXNzRnVuYyAmJiBwcm9ncmVzc0Z1bmMoZXBvY2hOdW0sIGVwb2Noc0xlbmd0aCwgZW1iZWRkaW5nKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGVybWluYXRlU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICBpZiAoZXJyb3IpXG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICBlbHNlXG4gICAgICAgIHJlc29sdmUoZW1iZWRkaW5nKTtcbiAgICAgIC8vIHRlcm1pbmF0ZSB0aGUgd29ya2VyIGFmdGVyIHNvbWUgdGltZS4gaW1taWRpYXRlIHRlcm1pbmF0aW9uIGNhdXNlcyBjcmFzaGVzLlxuICAgICAgc2V0VGltZW91dCgoKSA9PiB3b3JrZXIudGVybWluYXRlKCksIDEwMCk7XG4gICAgfTtcbiAgfSk7XG59XG4iXX0=","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {_package} from '../package-test';\n\n// tests for dimensionality reduction\n\nimport {category, expect, test} from '@datagrok-libraries/utils/src/test';\nimport {DimReductionMethods} from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/types';\nimport {KnownMetrics, NumberMetricsNames, StringMetricsNames} from '@datagrok-libraries/ml/src/typed-metrics';\nimport {multiColReduceDimensionality}\n from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/reduce-dimensionality';\n\nconst DEMOG_COLNAMES = {\n SUBJ: 'subj',\n STUDY: 'study',\n SITE: 'site',\n AGE: 'age',\n SEX: 'sex',\n RACE: 'race',\n DISEASE: 'disease',\n WEIGHT: 'weight',\n HEIGHT: 'height',\n} as const;\ncategory('Dimensionality reduction: UMAP', () => {\n test('Numeric column', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.AGE], DimReductionMethods.UMAP, [NumberMetricsNames.Difference]);\n }, {timeout: 30000});\n\n test('String column', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.SEX], DimReductionMethods.UMAP, [StringMetricsNames.Onehot]);\n }, {timeout: 30000});\n\n test('Numeric and string columns', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.SEX, DEMOG_COLNAMES.AGE], DimReductionMethods.UMAP,\n [StringMetricsNames.Onehot, NumberMetricsNames.Difference]);\n });\n\n test('All demog columns', async () => {\n const allDemogCols = grok.data.demo.demog(10).columns.toList()\n .filter((col) => Object.values(DEMOG_COLNAMES).includes(col.name as any)); ;\n const distFuncs = allDemogCols.map((col) => col.type === DG.COLUMN_TYPE.STRING ?\n StringMetricsNames.Onehot : NumberMetricsNames.Difference);\n const colNames = allDemogCols.map((col) => col.name);\n await testDimensionalityReductionUI( colNames, DimReductionMethods.UMAP, distFuncs);\n });\n});\n\ncategory('Dimensionality reduction: T-SNE', () => {\n test('Numeric column', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.AGE], DimReductionMethods.T_SNE, [NumberMetricsNames.Difference]);\n }, {timeout: 30000});\n\n test('String column', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.SEX], DimReductionMethods.T_SNE, [StringMetricsNames.Onehot]);\n }, {timeout: 30000});\n\n test('Numeric and string columns', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.SEX, DEMOG_COLNAMES.AGE], DimReductionMethods.T_SNE,\n [StringMetricsNames.Onehot, NumberMetricsNames.Difference]);\n });\n\n test('All demog columns', async () => {\n const allDemogCols = grok.data.demo.demog(10).columns.toList()\n .filter((col) => Object.values(DEMOG_COLNAMES).includes(col.name as any));\n const distFuncs = allDemogCols.map((col) => col.type === DG.COLUMN_TYPE.STRING ?\n StringMetricsNames.Onehot : NumberMetricsNames.Difference);\n const colNames = allDemogCols.map((col) => col.name);\n await testDimensionalityReductionUI(colNames, DimReductionMethods.T_SNE, distFuncs);\n });\n});\n\nasync function testDimensionalityReductionUI(\n columns: string[], methodName: DimReductionMethods, metrics: KnownMetrics[],\n) {\n const df = grok.data.demo.demog(100);\n const _tv = grok.shell.addTableView(df);\n const dimRedResult = await multiColReduceDimensionality(\n df, columns.map((c) => df.col(c)!), methodName, metrics,\n columns.map(() => 1), columns.map(() => undefined),\n 'EUCLIDEAN', true, true, {preprocessingFuncArgs: columns.map(() => ({}))});\n expect(!!dimRedResult, true, 'No scatterplot returned');\n const addedEmbeddingsCols = df.columns.names().filter((c) => c.toLowerCase().startsWith('embed'));\n expect(addedEmbeddingsCols.length, 2, 'Wrong number of embeddings added');\n const clusterColName = df.columns.names().find((c) => c.toLowerCase().startsWith('cluster'));\n expect(!!clusterColName, true, 'No cluster column added');\n for (const embedColName of addedEmbeddingsCols) {\n const c = df.col(embedColName)!;\n expect(new Array(c.length).fill(null).every((_, i) => !c.isNone(i) && !isNaN(c.get(i))), true,\n 'Embedding column has null-ish values');\n }\n await new Promise((resolve) => setTimeout(resolve, 500));\n}\n","// Runtime system for exported C/C++-functions call.\n// It was previousely developed and does NOT provide call wasm-functions in WebWorkers.\n\n// type-to-heap correspondence\nconst heapMap = {'i32': 'HEAP32', // Int32Array\n 'f32': 'HEAPF32', // Float32Array\n};\n\n// type signature to typed array ,app\nconst typeMap = {'i32': Int32Array, // Int32Array\n 'f32': Float32Array, // Float32Array\n};\n\n// type-to-shift map\nconst shiftMap = {'i32': 2, // Int32Array\n 'f32': 2, // Float32Array\n};\n\n// type-to-column_creator map\nconst typeToColumnCreatorMap = {'i32': DG.Column.fromInt32Array,\n 'f32': DG.Column.fromFloat32Array};\n\n\n// CLASSES THAT ARE USED BY CPP-WRAPPER\n\n// simple argument: a number\nclass Arg {\n constructor(data) {\n this.data = data;\n }\n\n complementArrOfParams(arrOfParams) {\n arrOfParams.push(this.data);\n }\n\n complementArrOfTypes(arrOfTypes) {\n arrOfTypes.push('number');\n }\n\n allocateMemoryForBuffer(module) {}\n\n isMemoryForBufferAllocated() {\n return true;\n }\n\n putDataToBuffer(module) {}\n\n getDataFromBuffer(module) {}\n\n freeBuffer(module) {}\n}\n\n// column argument\nclass ArgColumn extends Arg {\n constructor(data, targetType, toUpdate = false) {\n super(data);\n this.type = targetType;\n this.toUpdate = toUpdate;\n this.buf = 0;\n this.numOfRows = data.length;\n }\n\n complementArrOfParams(arrOfParams) {\n arrOfParams.push(this.buf);\n arrOfParams.push(this.numOfRows);\n }\n\n complementArrOfTypes(arrOfTypes) {\n arrOfTypes.push('number');\n arrOfTypes.push('number');\n }\n\n allocateMemoryForBuffer(module) {\n this.buf = module._malloc(this.numOfRows * typeMap[this.type].BYTES_PER_ELEMENT);\n }\n\n isMemoryForBufferAllocated() {\n return (this.buf != 0);\n }\n\n putDataToBuffer(module) {\n if (this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const shift = shiftMap[type];\n const heap = module[heapMap[type]];\n let array = null;\n const col = this.data;\n\n if (((col.type == 'int') && (type == 'i32')) ||\n ((col.type == 'double') && (type == 'f32')))\n array = col.getRawData();\n else\n array = new typeMap[type](col.getRawData());\n\n if (array)\n heap.set(array, this.buf >> shift);\n }\n }\n\n getDataFromBuffer(module) {\n if (this.toUpdate && this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const heap = module[heapMap[type]];\n const buffer = this.buf;\n const bytes = typeMap[type].BYTES_PER_ELEMENT;\n const array = this.data.getRawData();\n\n for (let i = 0; i < this.numOfRows; i++)\n array[i] = heap[buffer / bytes + i];\n }\n }\n\n freeBuffer(module) {\n if (this.isMemoryForBufferAllocated()) {\n module._free(this.buf);\n this.buf = 0;\n }\n }\n}\n\n// new column argument: a new column is created\nclass ArgNewColumn extends ArgColumn {\n constructor(targetType, numOfRows) {\n super([], targetType, true);\n this.numOfRows = numOfRows;\n }\n\n putDataToBuffer(module) {}\n\n getDataFromBuffer(module) {\n if (this.toUpdate && this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const heap = module[heapMap[type]];\n const buf = this.buf;\n\n const columnCreator = typeToColumnCreatorMap[type];\n\n const arr = new typeMap[type](this.numOfRows);\n\n for (let i = 0; i < arr.length; i++)\n arr[i] = heap[buf / arr.BYTES_PER_ELEMENT + i];\n\n this.data = columnCreator('name', arr);\n\n //console.log(arr);\n\n // This makes mistake, when this.numOfRows = 5 (TODO: investigate why)\n //this.data = columnCreator('name', new typeMap[type](heap.buffer, this.buf, this.numOfRows));\n\n //console.log(this.data.getRawData());\n }\n }\n}\n\n// an array of columns argument\nclass ArgColumns extends Arg {\n constructor(data, targetType, toUpdate = false) {\n super(data);\n this.type = targetType;\n this.toUpdate = toUpdate;\n this.buf = 0;\n this.numOfColumns = data.length;\n this.numOfRows = data[0].length;\n }\n\n complementArrOfParams(arrOfParams) {\n arrOfParams.push(this.buf);\n arrOfParams.push(this.numOfRows);\n arrOfParams.push(this.numOfColumns);\n }\n\n complementArrOfTypes(arrOfTypes) {\n arrOfTypes.push('number');\n arrOfTypes.push('number');\n arrOfTypes.push('number');\n }\n\n allocateMemoryForBuffer(module) {\n this.buf = module._malloc(this.numOfRows * this.numOfColumns *\n typeMap[this.type].BYTES_PER_ELEMENT);\n }\n\n isMemoryForBufferAllocated() {\n return (this.buf != 0);\n }\n\n putDataToBuffer(module) {\n if (this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const shift = shiftMap[type];\n const heap = module[heapMap[type]];\n const numOfBytes = typeMap[type].BYTES_PER_ELEMENT;\n\n // put columns data to buffer\n for (let i = 0; i < this.numOfColumns; i++) {\n let array = null;\n const col = this.data[i];\n\n if (((col.type == 'int') && (type == 'i32')) ||\n ((col.type == 'double') && (type == 'f32')))\n array = col.getRawData();\n else\n array = new typeMap[type](col.getRawData());\n\n // check data array\n if (array != null)\n heap.set(array, (this.buf + i * this.numOfRows * numOfBytes) >> shift);\n }\n }\n }\n\n getDataFromBuffer(module) {\n if (this.toUpdate && this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const heap = module[heapMap[type]];\n const numOfRows = this.numOfRows;\n const numOfCols = this.numOfColumns;\n const arr = new typeMap[type](heap.buffer, this.buf, numOfRows * numOfCols);\n\n for (let i = 0; i < numOfCols; i++) {\n const colData = this.data[i].getRawData();\n for (let j = 0; j < numOfRows; j++)\n colData[j] = arr[j + i * numOfRows];\n }\n }\n }\n\n freeBuffer(module) {\n if (this.isMemoryForBufferAllocated()) {\n module._free(this.buf);\n this.buf = 0;\n }\n }\n}\n\n// an array of new columns: new columns are created\nclass ArgNewColumns extends ArgColumns {\n constructor(targetType, numOfRows, numOfColumns) {\n super([[]], targetType, true);\n this.data = [];\n this.numOfColumns = numOfColumns;\n this.numOfRows = numOfRows;\n }\n\n putDataToBuffer(module) { }\n\n getDataFromBuffer(module) {\n if (this.toUpdate && this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const heap = module[heapMap[type]];\n const numOfRows = this.numOfRows;\n const numOfCols = this.numOfColumns;\n const numOfBytes = typeMap[type].BYTES_PER_ELEMENT;\n const columnCreator = typeToColumnCreatorMap[type];\n const buf = this.buf;\n\n for (let i = 0; i < numOfCols; i++) {\n const arr = new typeMap[type](numOfRows);\n\n for (let j = 0; j < numOfRows; j++)\n arr[j] = heap[buf / numOfBytes + j + i * numOfRows];\n\n this.data.push(columnCreator((i + 1).toString(), arr));\n }\n\n // create columns: here, may be a problem when numOfRows = 5\n /*for(let i = 0; i < numOfCols; i++)\n this.data.push(columnCreator((i + 1).toString(), new typeMap[type](heap.buffer,\n this.buf + i * numOfRows * numOfBytes, numOfRows)));*/\n }\n }\n}\n\n// a wrapper for exported C/C++-function call\nfunction cppFuncWrapper(module, cFuncName, returnType, args) {\n let result;\n\n // allocate memory for buffers\n for (const arg of args)\n arg.allocateMemoryForBuffer(module);\n\n let isEnoughOfMemoryAllocated = true;\n\n // check memory allocation\n for (const arg of args)\n isEnoughOfMemoryAllocated &= arg.isMemoryForBufferAllocated();\n\n // run exported function if enough of memory is allocated\n if (isEnoughOfMemoryAllocated) {\n const params = []; // arguments that are put to the exported function\n const types = []; // their types\n\n // prepare data that is put to exported function\n for (const arg of args) {\n arg.complementArrOfParams(params);\n arg.complementArrOfTypes(types);\n arg.putDataToBuffer(module);\n }\n\n const extendedTypeOfReturn = (returnType == 'num') ? 'number' : null;\n\n // call exported function\n if (extendedTypeOfReturn)\n result = module.ccall(cFuncName, extendedTypeOfReturn, types, params);\n else\n result = module.ccall(cFuncName, extendedTypeOfReturn, types, params);\n\n // update and get data from buffers if required\n for (const arg of args)\n arg.getDataFromBuffer(module);\n }\n\n // clear buffers\n for (const arg of args)\n arg.freeBuffer(module);\n\n if (result != undefined)\n return result;\n} // cppFuncWrapper\n\n\n// A LAYER BETWEEN JS AND CPP-WRAPPER\n\n// Parameters creator\nconst Param = {\n intColumn(column) {\n return new ArgColumn(column, 'i32');\n },\n\n newIntColumn(numOfRows) {\n return new ArgNewColumn('i32', numOfRows);\n },\n\n intColumns(columns) {\n return new ArgColumns(columns.toList(), 'i32');\n },\n\n newIntColumns(numOfRows, numOfColumns) {\n return new ArgNewColumns('i32', numOfRows, numOfColumns);\n },\n\n floatColumn(column) {\n return new ArgColumn(column, 'f32');\n },\n\n newFloatColumn(numOfRows) {\n return new ArgNewColumn('f32', numOfRows);\n },\n\n floatColumns(columns) {\n return new ArgColumns(columns.toList(), 'f32');\n },\n\n newFloatColumns(numOfRows, numOfColumns) {\n return new ArgNewColumns('f32', numOfRows, numOfColumns);\n },\n\n int(number) {\n return new Arg(number);\n },\n\n num(number) {\n return new Arg(number);\n },\n};\n\n// Return value creator\nconst Return = {\n tableFromColumns(argColumns) {\n return DG.DataFrame.fromColumns(argColumns.data);\n },\n\n num(number) {\n return number;\n },\n\n int(number) {\n return number;\n },\n\n double(number) {\n return number;\n },\n\n column(argColumn) {\n return argColumn.data;\n },\n};\n\n// The main tool that combines all together\nexport function callWasm(module, funcName, inputs) {\n // get specification of exported C/C++-function\n const funcSpecification = module[funcName];\n\n // get argumnets\n const args = funcSpecification.arguments;\n\n // array of arguments that further are used by cpp-wrapper\n const cppFuncInput = [];\n\n // complete an input for cpp\n let i = 0;\n for (const key in args) {\n const arg = args[key];\n\n // skip auxiliry element\n if (key == '_callResult')\n continue;\n\n // create an argument\n switch (arg.type) {\n case 'floatColumns':\n case 'int':\n case 'num':\n case 'floatColumn':\n case 'intColumn':\n case 'intColumns':\n arg.data = Param[arg.type](inputs[i]);\n i++;\n break;\n case 'newFloatColumns':\n case 'newIntColumns':\n const val1 = args[arg['numOfRows']['ref']].data[arg['numOfRows']['value']];\n const val2 = args[arg['numOfColumns']['ref']].data[arg['numOfColumns']['value']];\n arg.data = Param[arg.type](val1, val2);\n break;\n case 'newFloatColumn':\n case 'newIntColumn':\n const val = args[arg['numOfRows']['ref']].data[arg['numOfRows']['value']];\n arg.data = Param[arg.type](val);\n break;\n } // switch\n\n cppFuncInput.push(args[key].data);\n } // for key\n\n // CALL EXPORTED CPP-FUNCTION\n const callResult = cppFuncWrapper(module, funcName, 'num', cppFuncInput);\n\n // store result that is returned by exported cpp-function\n args._callResult = Param.num(callResult);\n\n // create output\n const output = funcSpecification.output;\n\n // if a single object must be returned\n if (output['type'] != 'objects')\n return Return[output['type']](args[output['source']].data);\n\n const arrayToReturn = [];\n\n // push data of the required arguments\n for (const name of output['source'])\n arrayToReturn.push(args[name].data.data);\n\n return arrayToReturn;\n} // callWasm\n","// Utilities for calling wasm-functions via webworker.\n\n// We use an approach that is well described here:\n// https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97\n// It has been modified for usage in DATAGROK.\n\n// Constants for wasm-functions in webworkers runtime system\nconst TYPE = 'type';\nconst NUM_TYPE = 'num';\nconst FLOAT_COLUMN_TYPE = 'floatColumn';\nconst INT_COLUMN_TYPE = 'intColumn';\nconst FLOAT_COLUMNS_TYPE = 'floatColumns';\nconst NEW_FLOAT_COLUMNS_TYPE = 'newFloatColumns';\nconst INT_COLUMNS_TYPE = 'intColumns';\nconst NEW_INT_COLUMNS_TYPE = 'newIntColumns';\nconst NEW_FLOAT_COLUMN_TYPE = 'newFloatColumn';\nconst NEW_INT_COLUMN_TYPE = 'newIntColumn';\nconst COLUMN = 'column';\nconst CALL_RESULT = '_callResult';\nconst NUM_OF_ROWS = 'numOfRows';\nconst NUM_OF_COLUMNS = 'numOfColumns';\nconst REF = 'ref';\nconst VALUE = 'value';\nconst TABLE_OF_COLUMNS = 'tableFromColumns';\nconst OBJECTS = 'objects';\nconst INT_TYPE = 'int';\nconst DOUBLE_TYPE = 'double';\nconst NUMBER = 'number';\n\n// Type-to-heap correspondence.\n// It is required for JS-module generated by Emscripten,\n// and it is used, when passing array data to/from wasm-functions.\n// More info can be found at the following link:\n// https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97\nconst heapMap = {\n 'intColumn': \"HEAP32\",\n 'floatColumn': \"HEAPF32\",\n 'floatColumns': \"HEAPF32\",\n 'newFloatColumns': \"HEAPF32\",\n 'intColumns': \"HEAP32\",\n 'newIntColumns': \"HEAP32\",\n 'newFloatColumn': \"HEAPF32\",\n 'newIntColumn': \"HEAP32\"\n };\n\n// Type signature to typed array map.\n// It is used, when manipulating column(s).\nconst typeMap = {\n 'intColumn': Int32Array,\n 'floatColumn': Float32Array,\n 'floatColumns': Float32Array,\n 'newFloatColumns': Float32Array,\n 'intColumns': Int32Array, \n 'newIntColumns': Int32Array,\n 'newFloatColumn': Float32Array,\n 'newIntColumn': Int32Array\n }; \n\n// Type-to-shift map.\n// It is used, when passing array to/from wasm-functions.\n// More info can be found at the following link:\n// https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97 \nconst shiftMap = {'intColumn': 2, \n 'floatColumn': 2, \n 'floatColumns': 2, \n 'newFloatColumns': 2, \n 'intColumns': 2, \n 'newIntColumns': 2,\n 'newFloatColumn': 2,\n 'newIntColumn': 2\n }; \n\n// Get input for C++-function.\n// This function takes specification of arguments (argsSpecification) & input data (inputVals)\n// and returns input that will be further used in cpp/wasm-function.\nexport function getCppInput(argsSpecification, inputVals) {\n let cppFuncInput = [];\n let ref;\n\n // complete an input for cpp\n let i = 0;\n for(const key in argsSpecification) {\n const arg = argsSpecification[key]; \n const type = arg.type;\n \n // skip auxiliry element\n if(key === CALL_RESULT) \n continue;\n\n // here, we consider each type of input\n switch(type) { \n \n // numbers\n case NUM_TYPE: \n case INT_TYPE:\n case DOUBLE_TYPE:\n arg.data = inputVals[i];\n i++;\n break;\n\n // column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n\n let array;\n\n // this is OK if type of column and target type coinside\n //array = inputVals[i].getRawData();\n\n const col = inputVals[i];\n const len = col.length;\n\n // here, we check types and perform an appropriate transform\n if( ( (col.type === INT_TYPE) && (type === INT_COLUMN_TYPE) ) \n || ( (col.type === DOUBLE_TYPE) && (type === FLOAT_COLUMN_TYPE) ) )\n array = col.getRawData().slice(0, len);\n else\n array = new typeMap[type](col.getRawData().slice(0, len));\n\n /*if(((col.type == 'int') && (type == INT_COLUMN_TYPE)) \n || ((col.type == 'double') && (type == FLOAT_COLUMN_TYPE)))\n array = col.getRawData();\n else\n array = new typeMap[type](col.getRawData());*/\n\n // check types\n arg.data = { 'array': array,\n 'numOfRows': len}; \n \n i++;\n break;\n\n // new column \n case NEW_INT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n let val = 0; \n\n ref = arg[NUM_OF_ROWS][REF];\n\n if (argsSpecification[ref].type === NUM_TYPE)\n val = argsSpecification[ref].data;\n else\n val = argsSpecification[ref].data[arg[NUM_OF_ROWS][VALUE]]; \n\n arg.data = {'numOfRows': val};\n\n i++;\n break;\n\n // columns or column_list\n case INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE: \n let arrays = []; \n\n // this is OK if type of columns and target type coinside\n //for(let col of inputVals[i].toList())\n // arrays.push(col.getRawData());\n\n const rowCount = inputVals[i].byIndex(0).length;\n\n // here, we check types and perform an appropriate transform\n for(const col of inputVals[i].toList())\n if( ( (col.type === INT_TYPE) && (type === INT_COLUMN_TYPE) ) \n || ( (col.type === DOUBLE_TYPE) && (type === FLOAT_COLUMN_TYPE) ) )\n arrays.push(col.getRawData().slice(0, rowCount));\n else\n arrays.push(new typeMap[type](col.getRawData().slice(0, rowCount)));\n \n /*for(let col of inputVals[i].toList())\n if(((col.type == 'int') && (type == INT_COLUMN_TYPE)) \n || ((col.type == 'double') && (type == FLOAT_COLUMN_TYPE)))\n arrays.push(col.getRawData());\n else\n arrays.push(new typeMap[type](col.getRawData()));*/\n\n arg.data = { 'arrays': arrays,\n 'numOfRows': rowCount,\n 'numOfColumns': arrays.length};\n\n i++; \n break;\n\n // new columns or new column_list\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n let val1 = 0;\n let val2 = 0;\n\n ref = arg[NUM_OF_ROWS][REF];\n\n if (argsSpecification[ref].type === NUM_TYPE)\n val1 = argsSpecification[ref].data;\n else\n val1 = argsSpecification[ref].data[arg[NUM_OF_ROWS][VALUE]];\n\n ref = arg[NUM_OF_COLUMNS][REF];\n\n //console.log('Ref:');\n //console.log(ref);\n //console.log(argsSpecification[ref].data);\n\n if (argsSpecification[ref].type === NUM_TYPE)\n val2 = argsSpecification[ref].data;\n else\n val2 = argsSpecification[ref].data[arg[NUM_OF_COLUMNS][VALUE]]; \n\n arg.data = {'numOfRows': val1,\n 'numOfColumns': val2};\n\n i++;\n break; \n\n default: \n return; // TODO: specify behaviour \n } // switch \n\n cppFuncInput.push(arg);\n } // for key\n\n //console.log('cppFuncInput:');\n //console.log(cppFuncInput);\n\n return cppFuncInput;\n} // getCppInput\n\n// Allocate memory for buffers for array data\nfunction allocateMemoryForBuffer(module, inputs) {\n for(const arg of inputs) { \n const type = arg.type;\n\n switch(type) { // Process each type of input\n\n // numbers\n case NUM_TYPE: \n case INT_TYPE:\n case DOUBLE_TYPE:\n break;\n\n // column & new column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n arg.data.buf = module._malloc(arg.data.numOfRows * typeMap[type].BYTES_PER_ELEMENT);\n break;\n\n // columns & new columns\n case INT_COLUMNS_TYPE: \n case NEW_INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE: \n case NEW_FLOAT_COLUMNS_TYPE: // allocation memory for columns that are created\n arg.data.buf = module._malloc(arg.data.numOfRows * arg.data.numOfColumns \n * typeMap[type].BYTES_PER_ELEMENT);\n break;\n\n // TODO: process other cases and mistakes\n default:\n break; \n } \n }\n \n //console.log('inputs after memory allocation:');\n //console.log(inputs);\n} // allocateMemoryForBuffer\n\n// Get array of values that are put to wasm-function.\nfunction getArrOfWasmParams(inputs) {\n let params = [];\n\n // Process each type of input\n for(const arg of inputs) {\n switch (arg.type) {\n\n // numbers\n case NUM_TYPE: \n case INT_TYPE:\n case DOUBLE_TYPE:\n params.push(arg.data);\n break;\n\n // column & new column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n params.push(arg.data.buf); \n params.push(arg.data.numOfRows);\n break;\n \n // columns & new columns\n case INT_COLUMNS_TYPE:\n case NEW_INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE: \n params.push(arg.data.buf);\n params.push(arg.data.numOfRows);\n params.push(arg.data.numOfColumns);\n break;\n \n // TODO: process other cases and mistakes\n default:\n break;\n }\n }\n\n return params;\n} // getArrOfWasmParams\n\n// Get array of types that are put to wasm-function.\nfunction getArrOfWasmTypes(inputs) {\n let types = [];\n\n for(const arg of inputs) {\n switch (arg.type) { // Process each type of input\n\n // numbers\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n types.push(NUMBER);\n break;\n\n // column & new column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n types.push(NUMBER); \n types.push(NUMBER);\n break;\n \n // columns & new columns\n case INT_COLUMNS_TYPE:\n case NEW_INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n types.push(NUMBER);\n types.push(NUMBER);\n types.push(NUMBER);\n break;\n\n // TODO: process other cases and mistakes\n default:\n break;\n }\n }\n\n return types;\n} // getArrOfWasmTypes\n\n// Put array data to buffer\nfunction putDataToBuffer(module, inputs) {\n let shift;\n let heap; \n \n for(const arg of inputs) {\n const type = arg.type;\n\n switch (type) { // Process each type of input\n\n // numbers\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE: \n break;\n \n // column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE: \n shift = shiftMap[type];\n heap = module[heapMap[type]]; \n heap.set(arg.data.array, arg.data.buf >> shift);\n break;\n \n // columns\n case INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n shift = shiftMap[type];\n heap = module[heapMap[type]];\n let numOfBytes = typeMap[type].BYTES_PER_ELEMENT;\n let buf = arg.data.buf;\n let numOfColumns = arg.data.numOfColumns;\n let numOfRows = arg.data.numOfRows;\n let arrays = arg.data.arrays;\n\n for(let i = 0; i < numOfColumns; i++)\n heap.set(arrays[i], (buf + i * numOfRows * numOfBytes) >> shift);\n \n break;\n\n // new column(s)\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE: \n break;\n\n // TODO: process other cases and mistakes\n default:\n break;\n }\n }\n} // putDataToBuffer\n\n// Get array data from buffer.\nfunction getDataFromBuffer(module, inputs) {\n\n let heap;\n let numOfRows;\n let numOfCols;\n let numOfBytes; \n let buf;\n\n for(const arg of inputs) {\n const type = arg.type;\n\n switch (type) { // Process each type of input\n \n // number\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n break;\n\n // column(s)\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case FLOAT_COLUMNS_TYPE: \n case INT_COLUMNS_TYPE: \n break;\n\n // new column\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n heap = module[heapMap[type]];\n numOfRows = arg.data.numOfRows;\n numOfBytes = typeMap[type].BYTES_PER_ELEMENT; \n buf = arg.data.buf;\n let array = new typeMap[type](numOfRows);\n\n for(let j = 0; j < numOfRows; j++)\n array[j] = heap[buf / numOfBytes + j];\n\n arg.array = array;\n\n break;\n\n // new columns\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE: \n heap = module[heapMap[type]];\n numOfRows = arg.data.numOfRows;\n numOfCols = arg.data.numOfColumns;\n numOfBytes = typeMap[type].BYTES_PER_ELEMENT; \n buf = arg.data.buf;\n let arrays = [];\n\n for(let i = 0; i < numOfCols; i++) {\n let arr = new typeMap[type](numOfRows);\n\n for(let j = 0; j < numOfRows; j++)\n arr[j] = heap[buf / numOfBytes + j + i * numOfRows]; \n \n arrays.push(arr);\n }\n\n arg.arrays = arrays;\n \n break;\n \n // TODO: process other cases and mistakes\n default:\n break;\n }\n } \n} // getDataFromBuffer\n\n// Clear memory allocated for array data\nfunction clearMemoryForBuffer(module, inputs) {\n for(const arg of inputs) \n switch(arg.type) { // process each type of input\n\n // number\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n break;\n\n // each non-number case\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE: \n case INT_COLUMNS_TYPE:\n case NEW_INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n module._free(arg.data.buf);\n break;\n\n // TODO: process other cases and mistakes\n default:\n break; \n } \n} // clearMemoryForBuffer\n\n// Extract newly created data: new column(s) are created\nfunction extractNewlyCreatedData(funcSpecificationArgs, argsAfterWasmCall) {\n // type-to-column_creator map\n const typeToColumnCreatorMap = {'newFloatColumns': DG.Column.fromFloat32Array,\n 'newIntColumns': DG.Column.fromInt32Array,\n 'newFloatColumn': DG.Column.fromFloat32Array,\n 'newIntColumn': DG.Column.fromInt32Array};\n\n let i = 0;\n\n for(const key in funcSpecificationArgs) \n {\n const arg = funcSpecificationArgs[key];\n\n switch(arg.type){ // Process each type\n\n // number\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n break;\n\n // column(s)\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case FLOAT_COLUMNS_TYPE:\n case INT_COLUMNS_TYPE:\n break;\n\n // new column\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n let name;\n\n // specify name for column\n if(arg.name == undefined)\n name = (0).toString();\n else \n names = arg.name;\n\n arg.column = typeToColumnCreatorMap[arg.type](name,\n argsAfterWasmCall[i].array);\n break;\n\n // new columns\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n let columns = [];\n let length = argsAfterWasmCall[i].arrays.length;\n\n let names = [];\n\n // specify name for column\n if(arg.names == undefined)\n for(let k = 1; k <= length; k++)\n names.push((k).toString());\n else names = arg.names;\n\n for(let j = 0; j < length; j++)\n columns.push(typeToColumnCreatorMap[arg.type](names[j],\n argsAfterWasmCall[i].arrays[j]));\n\n arg.columns = columns;\n \n break;\n\n // TODO: process other cases and mistakes\n default:\n break;\n }\n\n i++;\n }\n} // extractNewlyCreatedData\n\n// Get output data: overall output is created\nfunction getOutput(funcSpecification) { \n let output = funcSpecification.output;\n \n const typeToDataFieldMap = {'newFloatColumns': 'columns',\n 'newIntColumns': 'columns',\n 'newFloatColumn': 'column',\n 'newIntColumn': 'column'};\n\n switch(output.type) {\n\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n return funcSpecification.arguments[output.source];\n break;\n\n case COLUMN:\n return funcSpecification.arguments[output.source].column;\n break;\n\n case TABLE_OF_COLUMNS:\n return DG.DataFrame.fromColumns(funcSpecification.arguments[output.source].columns);\n break;\n\n case OBJECTS:\n let arrayToReturn = [];\n \n // push data of the required arguments\n for(let name of output.source) {\n let arg = funcSpecification.arguments[name];\n arrayToReturn.push(arg[typeToDataFieldMap[arg.type]]);\n } \n\n return arrayToReturn;\n break;\n\n // TODO: process other cases and mistakes\n default:\n break;\n }\n\n} // getOutput\n\n// Clear newly created data fields (new column(s))\nfunction clearNewlyCreatedData(funcSpecificationArgs) { \n for(const key in funcSpecificationArgs) {\n const arg = funcSpecificationArgs[key];\n\n switch (arg.type) {\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE: \n case INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n break;\n\n case NEW_INT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n arg.column = null; \n break;\n\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n arg.columns = null;\n break;\n \n // TODO: process other cases and mistakes\n default:\n break;\n }\n }\n} // clearNewlyCreatedData\n\n// THE MAIN FUNCTION: a wrapper for C++-function call\nexport function cppWrapper(module, args, cppFuncName, returnType) {\n // allocate memory for arrays that are passed to C++-function\n allocateMemoryForBuffer(module, args);\n\n // put data (just column(s)) to allocated buffers\n putDataToBuffer(module, args);\n\n // create array of parameters that are passed to C++-function\n let params = getArrOfWasmParams(args);\n\n //console.log('params:');\n //console.log(params);\n\n // create array of parameters' types that are passed to C++-function\n let types = getArrOfWasmTypes(args);\n \n //console.log('types:');\n //console.log(types);\n\n // call wasm-function\n let result = module.ccall(cppFuncName, returnType, types, params);\n \n //console.log(result);\n\n // get data from buffers (just column(s))\n getDataFromBuffer(module, args); \n\n // clear memory that was previousely allocated\n clearMemoryForBuffer(module, args);\n\n //console.log('done');\n\n return result;\n}\n\n// Get the required output.\n// It takes a specification of the function and the data computed\n// and extracts the required results.\nexport function getResult(funcSpecification, dataFromWebWorker) {\n funcSpecification.arguments._callResult = dataFromWebWorker.callResult; \n\n extractNewlyCreatedData(funcSpecification.arguments, dataFromWebWorker.args); \n\n let outPut = getOutput(funcSpecification);\n\n // Below, we remove newly created column(s), which are created at the extraction-step.\n // It is especially required, when multiple call of wasm-functions in webworker.\n clearNewlyCreatedData(funcSpecification.arguments);\n\n return outPut;\n}","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\n// Inputs correctness check tools\n\n//Limitation constants\nconst COMP_MIN = 1;\nconst SAMPLES_COUNT_MIN = 1;\nconst FEATURES_COUNT_MIN = 1;\nconst PERCENTAGE_MIN = 0;\nconst PERCENTAGE_MAX = 100;\nconst MAX_ELEMENTS_COUNT = 100000000;\n\n// Error messages\nconst COMP_POSITVE_MES = 'components must be positive.';\nconst COMP_EXCESS = 'components must not be greater than features count.';\nconst INCORERRECT_MIN_MAX_MES = 'min must be less than max.';\nconst INCORERRECT_FEATURES_MES = 'features must be positive.';\nconst INCORERRECT_SAMPLES_MES = 'samples must be positive.';\nconst INCORERRECT_PERCENTAGE_MES = 'violators percentage must be from the range from 0 to 100.';\nconst DATAFRAME_IS_TOO_BIG_MES = 'dataframe is too big.';\nconst UNSUPPORTED_COLUMN_TYPE_MES = 'unsupported column type: ';\nconst INCORRECT_MIN_DIST_MES = 'min distance must be positive.';\nconst INCORRECT_SPREAD_MES = 'spread must be positive.';\nconst INCORRECT_EPOCH_MES = 'number of epoch must be at least 1.';\nconst INCORRECT_NEIBORS_MES = 'number of neibors must be at least 2 and not greater than samples count.';\nconst INCORRECT_ITERATIONS_MES = 'number of iterations must be at least 1.';\nconst INCORRECT_LEARNING_RATE_MES = 'learning rate must be positive.';\nconst INCORRECT_PERPLEXITY_MES = 'perplexity must be at least 2 and not greater than samples count.';\nconst INCORRECT_STEPS_MES = 'steps must be non-negative.';\nconst INCORRECT_CYCLES_MES = 'cycles must be positive.';\nconst INCORRECT_CUTOFF_MES = 'cutoff must be non-negative.';\n\n/** Check column type */\nexport function checkColumnType(col: DG.Column): void {\n if ((col.type != DG.COLUMN_TYPE.FLOAT) && (col.type != DG.COLUMN_TYPE.INT))\n throw new Error(UNSUPPORTED_COLUMN_TYPE_MES + col.type);\n}\n\n/** Check missing values */\nexport function checkMissingVals(col: DG.Column): void {\n if (col.stats.missingValueCount > 0 )\n throw new Error(`The column '${col.name}' has missing values.`);\n}\n\n// Check dimension reducer inputs\nexport function checkDimensionReducerInputs(features: DG.ColumnList, components: number): void {\n if (components < COMP_MIN)\n throw new Error(COMP_POSITVE_MES);\n\n if (components > features.length)\n throw new Error(COMP_EXCESS);\n\n for (const col of features) {\n checkColumnType(col);\n checkMissingVals(col);\n }\n}\n\n// Check UMAP inputs\nexport function checkUMAPinputs(features: DG.ColumnList, components: number, epochs: number,\n neighbors: number, minDist: number, spread: number): void {\n // General dim reducer checks\n checkDimensionReducerInputs(features, components);\n\n // Check data total size\n if (features.length * features.byIndex(0).length > MAX_ELEMENTS_COUNT)\n throw new Error(DATAFRAME_IS_TOO_BIG_MES);\n\n // UMAP specific checks\n\n if (minDist <= 0)\n throw new Error(INCORRECT_MIN_DIST_MES);\n\n if (spread <= 0)\n throw new Error(INCORRECT_SPREAD_MES);\n\n if (epochs < 1)\n throw new Error(INCORRECT_EPOCH_MES);\n\n if ((neighbors < 2) || (neighbors > features.byIndex(0).length))\n throw new Error(INCORRECT_NEIBORS_MES);\n}\n\n// Check t-SNE inputs\nexport function checkTSNEinputs(features: DG.ColumnList, components: number,\n learningRate: number, perplexity: number, iterations: number): void {\n // General dim reducer checks\n checkDimensionReducerInputs(features, components);\n\n // Check data total size\n if (features.length * features.byIndex(0).length > MAX_ELEMENTS_COUNT)\n throw new Error(DATAFRAME_IS_TOO_BIG_MES);\n\n // t-SNE specific checks\n\n if (learningRate < 0)\n throw new Error(INCORRECT_LEARNING_RATE_MES);\n\n if (iterations < 1)\n throw new Error(INCORRECT_ITERATIONS_MES);\n\n if ((perplexity < 2) || (perplexity > features.byIndex(0).length))\n throw new Error(INCORRECT_PERPLEXITY_MES);\n}\n\n// Check SPE inputs\nexport function checkSPEinputs(features: DG.ColumnList, dimension: number,\n steps: number, cycles: number, cutoff: number, lambda: number): void {\n // General dim reducer checks\n checkDimensionReducerInputs(features, dimension);\n\n // Check data total size\n if (features.length * features.byIndex(0).length > MAX_ELEMENTS_COUNT)\n throw new Error(DATAFRAME_IS_TOO_BIG_MES);\n\n // SPE specific checks\n\n if (steps < 0)\n throw new Error(INCORRECT_STEPS_MES);\n\n if (cycles <= 0)\n throw new Error(INCORRECT_CYCLES_MES);\n\n if (cutoff < 0)\n throw new Error(INCORRECT_CUTOFF_MES);\n\n if (lambda <= 0)\n throw new Error(INCORRECT_LEARNING_RATE_MES);\n}\n\n// Check wasm dimension reducer inputs\nexport function checkWasmDimensionReducerInputs(features: DG.ColumnList, components: number): void {\n // General dim reducer checks\n checkDimensionReducerInputs(features, components);\n\n // Check data total size\n if (features.length * features.byIndex(0).length > MAX_ELEMENTS_COUNT)\n throw new Error(DATAFRAME_IS_TOO_BIG_MES);\n}\n\n// Check inputs of data for SVM testing generator\nexport function checkGeneratorSVMinputs(samplesCount: number, featuresCount: number,\n min: number, max: number, violatorsPercentage: number): void {\n if (min >= max)\n throw new Error(INCORERRECT_MIN_MAX_MES);\n\n if (featuresCount < FEATURES_COUNT_MIN)\n throw new Error(INCORERRECT_FEATURES_MES);\n\n if (samplesCount < SAMPLES_COUNT_MIN)\n throw new Error(INCORERRECT_SAMPLES_MES);\n\n if ((violatorsPercentage < PERCENTAGE_MIN) || (violatorsPercentage > PERCENTAGE_MAX))\n throw new Error(INCORERRECT_PERCENTAGE_MES);\n}\n\n// Returns rows of column data\nexport function getRowsOfNumericalColumnns(columnList: DG.ColumnList): any[][] {\n const columns = columnList.toList();\n const rowCount = columns[0].length;\n const colCount = columns.length;\n\n const output = [] as any[][];\n\n for (let i = 0; i < rowCount; ++i)\n output.push(Array(colCount));\n\n for (let j = 0; j < colCount; ++j) {\n const col = columns[j];\n\n checkColumnType(col);\n\n const array = col.getRawData();\n\n for (let i = 0; i < rowCount; ++i)\n output[i][j] = array[i];\n }\n\n return output;\n}\n","// PLS specific constants\n\n/** Types of analysis using PLS */\nexport enum PLS_ANALYSIS {\n COMPUTE_COMPONENTS,\n PERFORM_MVA,\n DEMO,\n}\n\n/** Errors & warnings */\nexport enum ERROR_MSG {\n NO_DF = 'No dataframe is opened',\n NO_COLS = 'No numeric columns without missing values',\n ONE_COL = 'No columns to be used as features (just one numeric columns without missing values)',\n EMPTY_DF = 'Dataframe is empty',\n}\n\n/** Widget titles */\nexport enum TITLE {\n PREDICT = 'Predict',\n USING = 'Using',\n COMPONENTS = 'Components',\n PLS = 'PLS',\n MVA = 'Multivariate Analysis (PLS)',\n RUN = 'RUN',\n NAMES = 'Names',\n MODEL = 'Observed vs. Predicted',\n FEATURE = 'Feature',\n REGR_COEFS = 'Regression Coefficients',\n XLOADING = 'x.loading.p',\n LOADINGS = 'Loadings',\n XSCORE = 'x.score.t',\n YSCORE = 'y.score.u',\n SCORES = 'Scores',\n EXPL_VAR = 'Explained Variance',\n EXPLORE = 'Explore',\n FEATURES = 'Feature names',\n BROWSE = 'Browse',\n}\n\n/** Tooltips */\nexport enum HINT {\n PREDICT = 'Column with the response variable',\n FEATURES = 'Predictors (features)',\n COMPONENTS = 'Number of PLS components',\n PLS = 'Compute PLS components',\n MVA = 'Perform multivariate analysis',\n NAMES = 'Names of data samples',\n}\n\n/** Links to help */\nexport enum LINK {\n PLS = 'https://datagrok.ai/help/explore/multivariate-analysis/pls#pls-components',\n MVA = 'https://datagrok.ai/help/explore/multivariate-analysis/pls',\n MODEL = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/predicted-vs-reference',\n COEFFS = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/regression-coefficients',\n LOADINGS = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/loadings',\n EXPL_VARS = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/explained-variance',\n SCORES = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/scores',\n}\n\n/** Components consts */\nexport enum COMPONENTS {\n DEFAULT = 3,\n MIN = 1,\n}\n\n/** Items used for naming results */\nexport enum RESULT_NAMES {\n PREFIX = 'PLS',\n SUFFIX = '(predicted)',\n COMP = 'component',\n COMPS = 'components',\n}\n\n/** Indeces of wasm-computation output */\nexport enum WASM_OUTPUT_IDX {\n PREDICTION = 0,\n REGR_COEFFS = 1,\n T_SCORES = 2,\n U_SCORES = 3,\n X_LOADINGS = 4,\n Y_LOADINGS = 5,\n}\n\nexport const INT = 'Int';\nexport const TIMEOUT = 6;\nexport const RADIUS = [0.49, 0.79, 0.99];\nexport const LINE_WIDTH = 1;\nexport const X_COORD = 200;\nexport const Y_COORD = 200;\nexport const DELAY = 2000;\n\n/** Curves colors */\nexport enum COLOR {\n AXIS = '#838383',\n CIRCLE = '#0000FF',\n};\n\n/** Intro markdown for demo app */\nexport const DEMO_INTRO_MD = `# Data\nEach car has many features - patterns extraction is complicated.\n\n# Model\nPredict car price by its other features.\n\n# Try\nPress 'RUN' to perform multivariate analysis using partial least squares\n([PLS](https://en.wikipedia.org/wiki/Partial_least_squares_regression)) regression.\n\n# Essence\nThe method finds the latent factors that\n\n* capture the maximum variance in the features\n* maximize correlation with the response variable`;\n\n/** Description of demo results: wizard components */\nexport const DEMO_RESULTS = [\n {\n caption: TITLE.MODEL,\n text: 'Closer to the line means better price prediction.',\n },\n {\n caption: TITLE.SCORES,\n text: 'The latent factor values for each sample reflect the similarities and dissimilarities among observations.',\n },\n {\n caption: TITLE.LOADINGS,\n text: 'The impact of each feature on the latent factors: higher loading means stronger influence.',\n },\n {\n caption: TITLE.REGR_COEFS,\n text: 'Parameters of the obtained linear model: features make different contribution to the prediction.',\n },\n {\n caption: TITLE.EXPL_VAR,\n text: 'How well the latent components fit source data: closer to one means better fit.',\n },\n];\n\n/** Form results markdown for demo app */\nexport const DEMO_RESULTS_MD = DEMO_RESULTS.map((item) => `# ${item.caption}\\n\\n${item.text}`)\n .join('\\n\\n') + `\\n\\n# Learn more\n \n * [Multivariate analysis](${LINK.MVA}),\n * [ANOVA](https://datagrok.ai/help/explore/anova)`;\n","// Exploratory data analysis (EDA) tools\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {_principalComponentAnalysisInWebWorker,\n _partialLeastSquareRegressionInWebWorker} from '../wasm/EDAAPI';\n\nimport {checkWasmDimensionReducerInputs, checkUMAPinputs, checkTSNEinputs,\n getRowsOfNumericalColumnns} from './utils';\n\n// Principal components analysis (PCA)\nexport async function computePCA(table: DG.DataFrame, features: DG.ColumnList, components: number,\n center: boolean, scale: boolean): Promise<DG.DataFrame> {\n checkWasmDimensionReducerInputs(features, components);\n\n const centerNum = center ? 1 : 0;\n const scaleNum = scale ? 1 : 0;\n\n return await _principalComponentAnalysisInWebWorker(table, features, components, centerNum, scaleNum);\n}\n\n// Partial least square regression (PLS): TO REMOVE\nexport async function computePLS(\n table: DG.DataFrame, features: DG.ColumnList, predict: DG.Column, components: number,\n): Promise<any> {\n // Inputs are checked in the same manner as in PCA, since the same computations are applied.\n checkWasmDimensionReducerInputs(features, components);\n\n return await _partialLeastSquareRegressionInWebWorker(table, features, predict, components);\n}\n\n// Uniform Manifold Approximation and Projection (UMAP)\nexport async function computeUMAP(features: DG.ColumnList, components: number, epochs: number,\n neighbors: number, minDist: number, spread: number): Promise<DG.DataFrame> {\n // check inputs\n checkUMAPinputs(features, components, epochs, neighbors, minDist, spread);\n\n // get row-by-row data\n const data = getRowsOfNumericalColumnns(features);\n\n let workerOutput: any;\n\n // UMAP in webworker\n const promise = new Promise((resolve, _reject) => {\n const worker = new Worker(new URL('workers/umap-worker.ts', import.meta.url));\n\n worker.postMessage({\n data: data,\n options: {\n nComponents: components,\n nEpochs: epochs,\n nNeighbors: neighbors,\n minDist: minDist,\n spread: spread,\n }});\n\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(e.data.embeddings);\n };\n });\n\n await promise.then(\n (result) => {workerOutput = result;},\n (_error) => {throw new Error('applying UMAP fails.');},\n );\n\n const embeddings = workerOutput as number[][];\n const rowCount = embeddings.length;\n const range = [...Array(components).keys()];\n\n // Create output\n\n // columns data\n const umapColumnsData = range.map((_) => new Float32Array(rowCount));\n\n // perform transponation\n for (let i = 0; i < rowCount; ++i) {\n for (let j = 0; j < components; ++j)\n umapColumnsData[j][i] = embeddings[i][j];\n }\n\n return DG.DataFrame.fromColumns(range.map((i) =>\n DG.Column.fromFloat32Array('UMAP' + i.toString(), umapColumnsData[i]),\n ));\n} // computeUMAP\n\n// t-distributed stochastic neighbor embedding (t-SNE)\nexport async function computeTSNE(features: DG.ColumnList, components: number,\n learningRate: number, perplexity: number, iterations: number): Promise<DG.DataFrame> {\n // check inputs\n checkTSNEinputs(features, components, learningRate, perplexity, iterations);\n\n // get row-by-row data\n const data = getRowsOfNumericalColumnns(features);\n\n let workerOutput: any;\n\n // t-SNE in webworker\n const promise = new Promise((resolve, _reject) => {\n const worker = new Worker(new URL('workers/tsne-worker.ts', import.meta.url));\n\n worker.postMessage({\n data: data,\n options: {\n learningRate: learningRate,\n perplexity: perplexity,\n components: components,\n iterations: iterations,\n }});\n\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(e.data.embeddings);\n };\n });\n\n await promise.then(\n (result) => {workerOutput = result;},\n (_error) => {throw new Error('applying t-SNE fails.');},\n );\n\n const embeddings = workerOutput as any[];\n\n const rowCount = embeddings.length;\n const range = [...Array(components).keys()];\n\n // Create output\n\n // columns data\n const umapColumnsData = range.map((_) => new Float32Array(rowCount));\n\n // perform transponation\n for (let i = 0; i < rowCount; ++i) {\n for (let j = 0; j < components; ++j)\n umapColumnsData[j][i] = embeddings[i][j];\n }\n\n return DG.DataFrame.fromColumns(range.map((i) =>\n DG.Column.fromFloat32Array('tSNE' + i.toString(), umapColumnsData[i]),\n ));\n} // computeTSNE\n","// The following code is generated automatically.\n// JavaScript API for call wasm-functions from the module EDA\n\n// Imports for call wasm runtime-system: in the main stream and in webworkers\nimport {callWasm} from '../wasm/callWasm';\nimport {getCppInput, getResult} from '../wasm/callWasmForWebWorker';\n\nexport async function _initEDAAPI() {\n await initEDA();\n}\n\nexport function _principalComponentAnalysis(table, columns, componentsCount, centerNum, scaleNum) {\n return callWasm(EDA, 'principalComponentAnalysis', [columns, componentsCount, centerNum, scaleNum]);\n}\n\nexport async function _principalComponentAnalysisInWebWorker(table, columns, componentsCount, centerNum, scaleNum) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/principalComponentAnalysisWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['principalComponentAnalysis'].arguments,[columns, componentsCount, centerNum, scaleNum]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['principalComponentAnalysis'], e.data));\n }\n });\n}\n\nexport function _error(df, col1, col2) {\n return callWasm(EDA, 'error', [col1, col2]);\n}\n\nexport async function _errorInWebWorker(df, col1, col2) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/errorWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['error'].arguments,[col1, col2]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['error'], e.data));\n }\n });\n}\n\nexport function _partialLeastSquareRegression(table, features, predict, componentsCount) {\n return callWasm(EDA, 'partialLeastSquareRegression', [features, predict, componentsCount]);\n}\n\nexport async function _partialLeastSquareRegressionInWebWorker(table, features, predict, componentsCount) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/partialLeastSquareRegressionWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['partialLeastSquareRegression'].arguments,[features, predict, componentsCount]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['partialLeastSquareRegression'], e.data));\n }\n });\n}\n\nexport function _generateDataset(kernel, kernelParams, samplesCount, featuresCount, min, max, violatorsPercentage) {\n return callWasm(EDA, 'generateDataset', [kernel, kernelParams, samplesCount, featuresCount, min, max, violatorsPercentage]);\n}\n\nexport async function _generateDatasetInWebWorker(kernel, kernelParams, samplesCount, featuresCount, min, max, violatorsPercentage) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/generateDatasetWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['generateDataset'].arguments,[kernel, kernelParams, samplesCount, featuresCount, min, max, violatorsPercentage]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['generateDataset'], e.data));\n }\n });\n}\n\nexport function _normalizeDataset(data) {\n return callWasm(EDA, 'normalizeDataset', [data]);\n}\n\nexport async function _normalizeDatasetInWebWorker(data) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/normalizeDatasetWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['normalizeDataset'].arguments,[data]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['normalizeDataset'], e.data));\n }\n });\n}\n\nexport function _trainLSSVM(gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, dataset, labels) {\n return callWasm(EDA, 'trainLSSVM', [gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, dataset, labels]);\n}\n\nexport async function _trainLSSVMInWebWorker(gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, dataset, labels) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/trainLSSVMWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['trainLSSVM'].arguments,[gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, dataset, labels]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['trainLSSVM'], e.data));\n }\n });\n}\n\nexport function _predictByLSSVM(kernel, kernelParams, normalizedData, labels, means, stdDevs, modelParams, precomputedWeights, targetData) {\n return callWasm(EDA, 'predictByLSSVM', [kernel, kernelParams, normalizedData, labels, means, stdDevs, modelParams, precomputedWeights, targetData]);\n}\n\nexport async function _predictByLSSVMInWebWorker(kernel, kernelParams, normalizedData, labels, means, stdDevs, modelParams, precomputedWeights, targetData) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/predictByLSSVMWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['predictByLSSVM'].arguments,[kernel, kernelParams, normalizedData, labels, means, stdDevs, modelParams, precomputedWeights, targetData]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['predictByLSSVM'], e.data));\n }\n });\n}\n\nexport function _trainAndAnalyzeLSSVM(gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, confusionMatrixElementsCount, dataset, labels) {\n return callWasm(EDA, 'trainAndAnalyzeLSSVM', [gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, confusionMatrixElementsCount, dataset, labels]);\n}\n\nexport async function _trainAndAnalyzeLSSVMInWebWorker(gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, confusionMatrixElementsCount, dataset, labels) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/trainAndAnalyzeLSSVMWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['trainAndAnalyzeLSSVM'].arguments,[gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, confusionMatrixElementsCount, dataset, labels]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['trainAndAnalyzeLSSVM'], e.data));\n }\n });\n}\n\nexport function _fitLinearRegressionParamsWithDataNormalizing(features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, paramsCount) {\n return callWasm(EDA, 'fitLinearRegressionParamsWithDataNormalizing', [features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, paramsCount]);\n}\n\nexport async function _fitLinearRegressionParamsWithDataNormalizingInWebWorker(features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, paramsCount) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/fitLinearRegressionParamsWithDataNormalizingWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['fitLinearRegressionParamsWithDataNormalizing'].arguments,[features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, paramsCount]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['fitLinearRegressionParamsWithDataNormalizing'], e.data));\n }\n });\n}\n\nexport function _fitLinearRegressionParams(features, targets, paramsCount) {\n return callWasm(EDA, 'fitLinearRegressionParams', [features, targets, paramsCount]);\n}\n\nexport async function _fitLinearRegressionParamsInWebWorker(features, targets, paramsCount) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/fitLinearRegressionParamsWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['fitLinearRegressionParams'].arguments,[features, targets, paramsCount]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['fitLinearRegressionParams'], e.data));\n }\n });\n}\n\nexport function _fitSoftmax(features, featureAvgs, featureStdDevs, targets, classesCount, iterCount, learningRate, penalty, tolerance, paramsRows, paramsCols) {\n return callWasm(EDA, 'fitSoftmax', [features, featureAvgs, featureStdDevs, targets, classesCount, iterCount, learningRate, penalty, tolerance, paramsRows, paramsCols]);\n}\n\nexport async function _fitSoftmaxInWebWorker(features, featureAvgs, featureStdDevs, targets, classesCount, iterCount, learningRate, penalty, tolerance, paramsRows, paramsCols) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/fitSoftmaxWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['fitSoftmax'].arguments,[features, featureAvgs, featureStdDevs, targets, classesCount, iterCount, learningRate, penalty, tolerance, paramsRows, paramsCols]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['fitSoftmax'], e.data));\n }\n });\n}\n\n","// Tools for multivariate analysis by PLS\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {PLS_ANALYSIS, ERROR_MSG, TITLE, HINT, LINK, COMPONENTS, INT, TIMEOUT,\n RESULT_NAMES, WASM_OUTPUT_IDX, RADIUS, LINE_WIDTH, COLOR, X_COORD, Y_COORD,\n DEMO_INTRO_MD, DEMO_RESULTS_MD, DEMO_RESULTS} from './pls-constants';\nimport {checkWasmDimensionReducerInputs, checkColumnType, checkMissingVals} from '../utils';\nimport {_partialLeastSquareRegressionInWebWorker} from '../../wasm/EDAAPI';\nimport {carsDataframe} from '../data-generators';\n\nconst min = Math.min;\nconst max = Math.max;\n\n/** PLS analysis results */\nexport type PlsOutput = {\n prediction: DG.Column<DG.COLUMN_TYPE.FLOAT>,\n regressionCoefficients: DG.Column<DG.COLUMN_TYPE.FLOAT>,\n tScores: DG.Column<DG.COLUMN_TYPE.FLOAT>[],\n uScores: DG.Column<DG.COLUMN_TYPE.FLOAT>[],\n xLoadings: DG.Column<DG.COLUMN_TYPE.FLOAT>[],\n yLoadings: DG.Column<DG.COLUMN_TYPE.FLOAT>,\n};\n\n/** PLS analysis input */\nexport type PlsInput = {\n table: DG.DataFrame,\n features: DG.ColumnList,\n predict: DG.Column,\n components: number,\n names : DG.Column | undefined,\n};\n\n/** Return lines */\nexport function getLines(names: string[]): DG.FormulaLine[] {\n const lines: DG.FormulaLine[] = [];\n\n const addLine = (formula: string, radius: number) => {\n lines.push({\n type: 'line',\n formula: formula,\n width: LINE_WIDTH,\n visible: true,\n title: ' ',\n min: -radius,\n max: radius,\n color: COLOR.CIRCLE,\n });\n };\n\n names.forEach((xName) => {\n const x = '${' + xName + '}';\n lines.push({type: 'line', formula: `${x} = 0`, width: LINE_WIDTH, visible: true, title: ' ', color: COLOR.AXIS});\n\n names.forEach((yName) => {\n const y = '${' + yName + '}';\n\n RADIUS.forEach((r) => {\n addLine(y + ` = sqrt(${r*r} - ${x} * ${x})`, r);\n addLine(y + ` = -sqrt(${r*r} - ${x} * ${x})`, r);\n });\n });\n });\n\n return lines;\n}\n\n/** Partial least square regression (PLS) */\nexport async function getPlsAnalysis(input: PlsInput): Promise<PlsOutput> {\n checkWasmDimensionReducerInputs(input.features, input.components);\n\n // Check the responce column\n checkColumnType(input.predict);\n checkMissingVals(input.predict);\n\n const result = await _partialLeastSquareRegressionInWebWorker(\n input.table,\n input.features,\n input.predict,\n input.components,\n );\n\n return {\n prediction: result[WASM_OUTPUT_IDX.PREDICTION],\n regressionCoefficients: result[WASM_OUTPUT_IDX.REGR_COEFFS],\n tScores: result[WASM_OUTPUT_IDX.T_SCORES],\n uScores: result[WASM_OUTPUT_IDX.U_SCORES],\n xLoadings: result[WASM_OUTPUT_IDX.X_LOADINGS],\n yLoadings: result[WASM_OUTPUT_IDX.Y_LOADINGS],\n };\n}\n\n/** Return debiased predction by PLS regression */\nfunction debiasedPrediction(features: DG.ColumnList, params: DG.Column,\n target: DG.Column, biasedPrediction: DG.Column): DG.Column {\n const samples = target.length;\n const dim = features.length;\n const rawParams = params.getRawData();\n const debiased = new Float32Array(samples);\n const biased = biasedPrediction.getRawData();\n\n // Compute bias\n let bias = target.stats.avg;\n for (let i = 0; i < dim; ++i)\n bias -= rawParams[i] * features.byIndex(i).stats.avg;\n\n // Compute debiased prediction\n for (let i = 0; i < samples; ++i)\n debiased[i] = bias + biased[i];\n\n return DG.Column.fromFloat32Array('Debiased', debiased, samples);\n}\n\n/** Perform multivariate analysis using the PLS regression */\nasync function performMVA(input: PlsInput, analysisType: PLS_ANALYSIS): Promise<void> {\n const result = await getPlsAnalysis(input);\n\n const plsCols = result.tScores;\n const cols = input.table.columns;\n const features = input.features;\n const featuresNames = features.names();\n const prefix = (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS) ? RESULT_NAMES.PREFIX : TITLE.XSCORE;\n\n // add PLS components to the table\n plsCols.forEach((col, idx) => {\n col.name = cols.getUnusedName(`${prefix}${idx + 1}`);\n cols.add(col);\n });\n\n if (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS)\n return;\n\n //const view = grok.shell.tableView(input.table.name);\n\n const view = (analysisType === PLS_ANALYSIS.DEMO) ?\n (grok.shell.view(TITLE.BROWSE) as DG.BrowseView).preview as DG.TableView :\n grok.shell.tableView(input.table.name);\n\n // 0.1 Buffer table\n const buffer = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLE.FEATURE, featuresNames),\n result.regressionCoefficients,\n ]);\n\n // 0.2. Add X-Loadings\n result.xLoadings.forEach((col, idx) => {\n col.name = buffer.columns.getUnusedName(`${TITLE.XLOADING}${idx + 1}`);\n buffer.columns.add(col);\n });\n\n // 1. Predicted vs Reference scatter plot\n // Debias prediction (since PLS center data)\n const pred = debiasedPrediction(features, result.regressionCoefficients, input.predict, result.prediction);\n pred.name = cols.getUnusedName(`${input.predict.name} ${RESULT_NAMES.SUFFIX}`);\n cols.add(pred);\n const predictVsReferScatter = view.addViewer(DG.Viewer.scatterPlot(input.table, {\n title: TITLE.MODEL,\n xColumnName: input.predict.name,\n yColumnName: pred.name,\n showRegressionLine: true,\n markerType: DG.MARKER_TYPE.CIRCLE,\n labels: input.names?.name,\n help: LINK.MODEL,\n }));\n\n // 2. Regression Coefficients Bar Chart\n result.regressionCoefficients.name = TITLE.REGR_COEFS;\n const regrCoeffsBar = view.addViewer(DG.Viewer.barChart(buffer, {\n title: TITLE.REGR_COEFS,\n splitColumnName: TITLE.FEATURE,\n valueColumnName: result.regressionCoefficients.name,\n valueAggrType: DG.AGG.AVG,\n help: LINK.COEFFS,\n showValueSelector: false,\n showStackSelector: false,\n }));\n\n // 3. Loadings Scatter Plot\n result.xLoadings.forEach((col, idx) => col.name = `${TITLE.XLOADING}${idx + 1}`);\n const loadingsScatter = view.addViewer(DG.Viewer.scatterPlot(buffer, {\n title: TITLE.LOADINGS,\n xColumnName: `${TITLE.XLOADING}1`,\n yColumnName: `${TITLE.XLOADING}${result.xLoadings.length > 1 ? '2' : '1'}`,\n markerType: DG.MARKER_TYPE.CIRCLE,\n labels: TITLE.FEATURE,\n help: LINK.LOADINGS,\n }));\n\n // 4. Scores Scatter Plot\n\n // 4.1) data\n const scoreNames = plsCols.map((col) => col.name);\n result.uScores.forEach((col, idx) => {\n col.name = cols.getUnusedName(`${TITLE.YSCORE}${idx + 1}`);\n cols.add(col);\n scoreNames.push(col.name);\n });\n\n // 4.2) create scatter\n const scoresScatter = DG.Viewer.scatterPlot(input.table, {\n title: TITLE.SCORES,\n xColumnName: plsCols[0].name,\n yColumnName: (plsCols.length > 1) ? plsCols[1].name : result.uScores[0].name,\n markerType: DG.MARKER_TYPE.CIRCLE,\n labels: input.names?.name,\n help: LINK.SCORES,\n showViewerFormulaLines: true,\n });\n\n // 4.3) create lines & circles\n scoresScatter.meta.formulaLines.addAll(getLines(scoreNames));\n view.addViewer(scoresScatter);\n\n // 5. Explained Variances\n\n // 5.1) computation, source: the paper https://doi.org/10.1002/cem.2589\n // here, we use notations from this paper\n const q = result.yLoadings.getRawData();\n const p = result.xLoadings.map((col) => col.getRawData());\n const n = input.table.rowCount;\n const m = featuresNames.length;\n const A = input.components;\n const yExplVars = new Float32Array(A);\n const compNames = [] as string[];\n const xExplVars: Float32Array[] = [];\n for (let i = 0; i < m; ++i)\n xExplVars.push(new Float32Array(A));\n\n yExplVars[0] = q[0]**2 / n;\n compNames.push(`1 ${RESULT_NAMES.COMP}`);\n xExplVars.forEach((arr, idx) => {arr[0] = p[0][idx]**2 / n;});\n\n for (let comp = 1; comp < A; ++comp) {\n yExplVars[comp] = yExplVars[comp - 1] + q[comp]**2 / n;\n xExplVars.forEach((arr, idx) => arr[comp] = arr[comp - 1] + p[comp][idx]**2 / n);\n compNames.push(`${comp + 1} ${RESULT_NAMES.COMPS}`);\n }\n\n // 5.2) create df\n const explVarsDF = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLE.COMPONENTS, compNames),\n DG.Column.fromFloat32Array(input.predict.name, yExplVars),\n ]);\n\n xExplVars.forEach((arr, idx) => explVarsDF.columns.add(DG.Column.fromFloat32Array(featuresNames[idx], arr)));\n\n // 5.3) bar chart\n const explVarsBar = view.addViewer(DG.Viewer.barChart(explVarsDF, {\n title: TITLE.EXPL_VAR,\n splitColumnName: TITLE.COMPONENTS,\n valueColumnName: input.predict.name,\n valueAggrType: DG.AGG.AVG,\n help: LINK.EXPL_VARS,\n showCategorySelector: false,\n showStackSelector: false,\n }));\n\n // emphasize viewers in the demo case\n if (analysisType === PLS_ANALYSIS.DEMO) {\n const pages = [predictVsReferScatter, scoresScatter, loadingsScatter, regrCoeffsBar, explVarsBar]\n .map((viewer, idx) => {\n return {\n text: DEMO_RESULTS[idx].text,\n showNextTo: viewer.root,\n };\n });\n\n const wizard = ui.hints.addTextHint({title: TITLE.EXPLORE, pages: pages});\n wizard.helpUrl = LINK.MVA;\n grok.shell.windows.help.showHelp(ui.markdown(DEMO_RESULTS_MD));\n }\n} // performMVA\n\n/** Run multivariate analysis (PLS) */\nexport async function runMVA(analysisType: PLS_ANALYSIS): Promise<void> {\n const table = (analysisType === PLS_ANALYSIS.DEMO) ?\n ((grok.shell.view(TITLE.BROWSE) as DG.BrowseView).preview as DG.TableView).table :\n grok.shell.t;\n\n if (table === null) {\n grok.shell.warning(ERROR_MSG.NO_DF);\n return;\n }\n\n if (table.rowCount === 0) {\n grok.shell.warning(ERROR_MSG.EMPTY_DF);\n return;\n }\n\n const numColNames = [] as string[];\n const numCols = [] as DG.Column[];\n const strCols = [] as DG.Column[];\n\n const isValidNumeric = (col: DG.Column) =>\n ((col.type === DG.COLUMN_TYPE.INT) || (col.type === DG.COLUMN_TYPE.FLOAT)) &&\n (col.stats.missingValueCount === 0);\n\n table.columns.toList().forEach((col) => {\n if (isValidNumeric(col)) {\n numColNames.push(col.name);\n numCols.push(col);\n } else if (col.type === DG.COLUMN_TYPE.STRING)\n strCols.push(col);\n });\n\n if (numColNames.length === 0) {\n grok.shell.warning(ERROR_MSG.NO_COLS);\n return;\n }\n\n if (numColNames.length === 1) {\n grok.shell.warning(ERROR_MSG.ONE_COL);\n return;\n }\n\n // responce (to predict)\n let predict = numCols[numCols.length - 1];\n const predictInput = ui.input.column(TITLE.PREDICT, {table: table, value: predict, onValueChanged: (value) => {\n predict = value;\n updateIputs();\n }, filter: (col: DG.Column) => isValidNumeric(col)},\n );\n predictInput.setTooltip(HINT.PREDICT);\n\n // predictors (features)\n let features: DG.Column[];\n const featuresInput = ui.input.columns(TITLE.USING, {table: table, available: numColNames});\n featuresInput.onInput.subscribe(() => updateIputs());\n featuresInput.setTooltip(HINT.FEATURES);\n\n // components count\n let components = min(numColNames.length - 1, COMPONENTS.DEFAULT as number);\n const componentsInput = ui.input.forProperty(DG.Property.fromOptions({\n name: TITLE.COMPONENTS,\n inputType: INT,\n defaultValue: components,\n //@ts-ignore\n showPlusMinus: true,\n min: COMPONENTS.MIN,\n }));\n componentsInput.onInput.subscribe(() => updateIputs());\n componentsInput.setTooltip(HINT.COMPONENTS);\n\n let dlgTitle: string;\n let dlgHelpUrl: string;\n let dlgRunBtnTooltip: string;\n\n if (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS) {\n dlgTitle = TITLE.PLS;\n dlgHelpUrl = LINK.PLS;\n dlgRunBtnTooltip = HINT.PLS;\n } else {\n dlgTitle = TITLE.MVA;\n dlgHelpUrl = LINK.MVA;\n dlgRunBtnTooltip = HINT.MVA;\n }\n\n const updateIputs = () => {\n featuresInput.value = featuresInput.value.filter((col) => col !== predict);\n features = featuresInput.value;\n\n componentsInput.value = min(max(componentsInput.value ?? components, COMPONENTS.MIN), features.length);\n components = componentsInput.value;\n\n dlg.getButton(TITLE.RUN).disabled = (features.length === 0) || (components <= 0);\n };\n\n // names of samples\n let names = (strCols.length > 0) ? strCols[0] : undefined;\n const namesInputs = ui.input.column(TITLE.NAMES, {\n table: table,\n value: names,\n onValueChanged: () => names = predictInput.value ?? undefined,\n filter: (col: DG.Column) => col.type === DG.COLUMN_TYPE.STRING},\n );\n namesInputs.setTooltip(HINT.NAMES);\n namesInputs.root.hidden = (strCols.length === 0) || (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS);\n\n const dlg = ui.dialog({title: dlgTitle, helpUrl: dlgHelpUrl})\n .add(ui.form([predictInput, featuresInput, componentsInput, namesInputs]))\n .addButton(TITLE.RUN, async () => {\n dlg.close();\n\n await performMVA({\n table: table,\n features: DG.DataFrame.fromColumns(features).columns,\n predict: predict,\n components: components,\n names: names,\n }, analysisType);\n }, undefined, dlgRunBtnTooltip)\n .show({x: X_COORD, y: Y_COORD});\n\n // the following delay provides correct styles (see https://reddata.atlassian.net/browse/GROK-15196)\n setTimeout(() => {\n featuresInput.value = numCols.filter((col) => col !== predict);\n features = featuresInput.value;\n }, TIMEOUT);\n\n grok.shell.v.append(dlg.root);\n} // runMVA\n\n/** Run multivariate analysis demo */\nexport async function runDemoMVA(): Promise<void> {\n grok.shell.addTableView(carsDataframe());\n grok.shell.windows.help.visible = true;\n grok.shell.windows.help.showHelp(ui.markdown(DEMO_INTRO_MD));\n grok.shell.windows.showContextPanel = false;\n grok.shell.windows.showProperties = false;\n\n await runMVA(PLS_ANALYSIS.DEMO);\n}\n","// Regression tools\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {_fitLinearRegressionParamsWithDataNormalizing} from '../wasm/EDAAPI';\nimport {getPlsAnalysis} from './pls/pls-tools';\n\n// Default PLS components count\nconst PLS_COMPONENTS_COUNT = 10;\n\n/** Compute coefficients of linear regression */\nexport async function getLinearRegressionParams(features: DG.ColumnList, targets: DG.Column): Promise<Float32Array> {\n const featuresCount = features.length;\n const samplesCount = targets.length;\n\n const yAvg = targets.stats.avg;\n const yStdev = targets.stats.stdev;\n\n const params = new Float32Array(featuresCount + 1).fill(0);\n params[featuresCount] = yAvg;\n\n // The trivial case\n if ((yStdev === 0) || (samplesCount === 1))\n return params;\n\n try {\n // Analyze inputs sizes\n\n // Non-constant columns data\n const nonConstFeatureColsIndeces: number[] = [];\n const nonConstFeatureCols: DG.Column[] = [];\n const nonConstFeatureAvgs = new Float32Array(featuresCount);\n const nonConstFeatureStdevs = new Float32Array(featuresCount);\n\n let idx = 0;\n let nonConstFeaturesCount = 0;\n\n // Extract non-constant columns data\n for (const col of features) {\n const stats = col.stats;\n\n if (stats.stdev > 0) {\n nonConstFeatureColsIndeces.push(idx);\n nonConstFeatureCols.push(col);\n nonConstFeatureAvgs[nonConstFeaturesCount] = stats.avg;\n nonConstFeatureStdevs[nonConstFeaturesCount] = stats.stdev;\n ++nonConstFeaturesCount;\n }\n\n ++idx;\n }\n\n // The trivial case\n if (nonConstFeaturesCount === 0)\n return params;\n\n // Compute parameters of linear regression\n const tempParams = _fitLinearRegressionParamsWithDataNormalizing(\n DG.DataFrame.fromColumns(nonConstFeatureCols).columns,\n DG.Column.fromFloat32Array('xAvgs', nonConstFeatureAvgs, nonConstFeaturesCount),\n DG.Column.fromFloat32Array('xStdevs', nonConstFeatureStdevs, nonConstFeaturesCount),\n targets,\n yAvg,\n yStdev,\n nonConstFeaturesCount + 1,\n ).getRawData();\n\n // Extract params taking into account non-constant columns\n for (let i = 0; i < nonConstFeaturesCount; ++i)\n params[nonConstFeatureColsIndeces[i]] = tempParams[i];\n\n params[featuresCount] = tempParams[nonConstFeaturesCount];\n } catch (e) {\n // Apply PLS regression if regular linear regression failed\n const paramsByPLS = await getLinearRegressionParamsUsingPLS(\n features,\n targets,\n componentsCount(features.length, targets.length),\n );\n\n let tmpSum = 0;\n\n // Compute bias (due to the centering feature of PLS)\n for (let i = 0; i < featuresCount; ++i) {\n params[i] = paramsByPLS[i];\n tmpSum += paramsByPLS[i] * features.byIndex(i).stats.avg;\n }\n\n params[featuresCount] -= tmpSum;\n }\n\n return params;\n} // computeLinRegressionCoefs\n\n/** Return prediction of linear regression model */\nexport function getPredictionByLinearRegression(features: DG.ColumnList, params: Float32Array): DG.Column {\n const featuresCount = features.length;\n if (featuresCount !== params.length - 1)\n throw new Error('Incorrect parameters count');\n\n const col = features.byIndex(0);\n const samplesCount = col.length;\n const prediction = new Float32Array(samplesCount);\n\n let rawData = col.getRawData();\n const bias = params[featuresCount];\n let weight = params[0];\n\n for (let i = 0; i < samplesCount; ++i)\n prediction[i] = bias + weight * rawData[i];\n\n for (let j = 1; j < featuresCount; ++j) {\n rawData = features.byIndex(j).getRawData();\n weight = params[j];\n\n for (let i = 0; i < samplesCount; ++i)\n prediction[i] += weight * rawData[i];\n }\n\n return DG.Column.fromFloat32Array(\n features.getUnusedName('prediction'),\n prediction,\n samplesCount,\n );\n} // getPredictionByLinearRegression\n\n/** Generate test dataset */\nexport function getTestDatasetForLinearRegression(rowCount: number, colCount: number,\n featuresScale: number, featuresBias: number, paramsScale: number, paramsBias: number): DG.DataFrame {\n const df = grok.data.demo.randomWalk(rowCount, colCount + 1);\n const cols = df.columns;\n const noiseCol = cols.byIndex(colCount);\n noiseCol.name = 'y (noisy)';\n const yNoisy = noiseCol.getRawData();\n const y = new Float32Array(rowCount).fill(paramsBias);\n\n let idx = 0;\n let scale = 0;\n let bias = 0;\n let weight = 0;\n\n for (const col of cols) {\n col.name = `x${idx}`;\n scale = Math.random() * featuresScale;\n bias = Math.random() * featuresBias;\n const arr = col.getRawData();\n weight = Math.random() * paramsScale;\n\n for (let j = 0; j < rowCount; ++j) {\n arr[j] = scale * arr[j] + bias;\n y[j] += arr[j] * weight;\n }\n\n ++idx;\n\n if (idx === colCount)\n break;\n }\n\n scale = Math.random() * featuresScale;\n bias = Math.random() * featuresBias;\n\n for (let j = 0; j < rowCount; ++j)\n yNoisy[j] = scale * yNoisy[j] + y[j];\n\n cols.add(DG.Column.fromFloat32Array('y', y, rowCount));\n\n return df;\n} // getTestDatasetForLinearRegression\n\n/** Reteurn linear regression params using the PLS method */\nasync function getLinearRegressionParamsUsingPLS(features: DG.ColumnList,\n targets: DG.Column, components: number): Promise<Float32Array> {\n const plsAnalysis = await getPlsAnalysis({\n table: DG.DataFrame.fromColumns([targets]),\n features: features,\n predict: targets,\n components: components,\n names: undefined,\n });\n\n return plsAnalysis.regressionCoefficients.getRawData() as Float32Array;\n}\n\n/** Return number of PLS components to be used */\nconst componentsCount = (featuresCount: number, samplesCount: number) => {\n if (samplesCount <= featuresCount)\n return Math.min(PLS_COMPONENTS_COUNT, samplesCount);\n\n return Math.min(PLS_COMPONENTS_COUNT, featuresCount);\n};\n","// Predicitve tools based on the PLS method\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {TITLE, RESULT_NAMES} from './pls-constants';\nimport {getPlsAnalysis, PlsOutput, getLines} from './pls-tools';\nimport {LINK} from './pls-constants';\nimport {getPredictionByLinearRegression} from '../regression';\n\n// PLS ML specific constants\nconst EXTRA_ROWS = 1;\nconst SHIFT = 2;\nconst MIN_LOADINGS = 1;\nconst MIN_COLS_COUNT = SHIFT + MIN_LOADINGS;\nconst SIZE_ARR_LEN = 2;\nconst MODEL_IDX = 0;\nconst SCORES_IDX = 1;\nconst BYTES_PER_SIZES = SIZE_ARR_LEN * 4;\nconst BLOCK_SIZE = 64;\n\n/** Interactivity tresholds */\nenum INTERACTIVITY {\n MAX_SAMLPES = 100000,\n MAX_FEATURES = 1000,\n};\n\n/** Model specification */\ntype PlsModelSpecification = {\n params: Float32Array,\n names: string[],\n loadings: Float32Array[],\n dim: number,\n components: number,\n scores: DG.DataFrame,\n}\n\n/** PLS regression modeling tool */\nexport class PlsModel {\n /** Check applicability */\n static isApplicable(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n for (const col of features) {\n if (!col.matches('numerical'))\n return false;\n }\n if (!predictColumn.matches('numerical'))\n return false;\n\n return true;\n }\n\n /** Check interactivity */\n static isInteractive(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n return (features.length <= INTERACTIVITY.MAX_FEATURES) &&\n (predictColumn.length <= INTERACTIVITY.MAX_SAMLPES);\n }\n\n /** Specification of the PLS model */\n private specn: PlsModelSpecification | null = null;\n\n constructor(packedModel?: Uint8Array) {\n if (packedModel) {\n try {\n // Extract model's bytes count\n const sizeArr = new Uint32Array(packedModel.buffer, 0, SIZE_ARR_LEN); // 1-st element is a size of model bytes\n const modelDfBytesCount = sizeArr[MODEL_IDX];\n const scoresDfBytesCount = sizeArr[SCORES_IDX];\n\n // Model's bytes\n const modelBytes = new Uint8Array(packedModel.buffer, BYTES_PER_SIZES, modelDfBytesCount);\n\n // Model as dataframe\n const modelDf = DG.DataFrame.fromByteArray(modelBytes);\n const rowCount = modelDf.rowCount;\n const columns = modelDf.columns;\n const colsCount = columns.length;\n\n // Scores\n const scoresBytes = new Uint8Array(packedModel.buffer, BYTES_PER_SIZES + modelDfBytesCount, scoresDfBytesCount);\n const scores = DG.DataFrame.fromByteArray(scoresBytes);\n\n if (colsCount < MIN_COLS_COUNT)\n throw new Error('incorrect columns count');\n\n // Extract names of features\n const featureNames = columns.byName(TITLE.FEATURES).toList();\n\n // Extract parameters of the linear model\n const params = new Float32Array(rowCount);\n params.set(columns.byName(TITLE.REGR_COEFS).getRawData());\n\n // Extract loadings\n const components = colsCount - SHIFT;\n const loadings = new Array<Float32Array>(components);\n\n for (let i = 0; i < components; ++i) {\n loadings[i] = new Float32Array(rowCount);\n loadings[i].set(columns.byIndex(i + SHIFT).getRawData());\n }\n\n this.specn = {\n params: params,\n loadings: loadings,\n names: featureNames,\n dim: rowCount - EXTRA_ROWS,\n components: colsCount - SHIFT,\n scores: scores,\n };\n } catch (error) {\n throw new Error(`Failed to load model: ${(error instanceof Error ? error.message : 'the platform issue')}`);\n }\n }\n }\n\n /** Train model */\n public async fit(features: DG.ColumnList, target: DG.Column, components: number) {\n const analysis = await getPlsAnalysis({\n table: DG.DataFrame.fromColumns([target]),\n features: features,\n predict: target,\n components: components,\n names: undefined,\n });\n\n // 1. Names of features\n const featureNames = features.names();\n featureNames.push('_'); // add extra item\n\n // 2. Regression coefficients\n const params = this.getRegrCoeffs(features, target, analysis.regressionCoefficients);\n\n // 3. Loadings\n const loadings = this.getLoadings(components, analysis.xLoadings);\n\n // 4. Model specification\n this.specn = {\n names: featureNames,\n params: params,\n loadings: loadings,\n components: components,\n dim: features.length,\n scores: this.getScoresDf(analysis),\n };\n\n // 4. Compute explained variances\n this.computeExplVars(target.length, components, analysis.yLoadings);\n } // fit\n\n /** Return x-loadings with extra items reserved for explained variances */\n private getLoadings(components: number, loadingsCols: DG.Column[]): Float32Array[] {\n const res = Array<Float32Array>(components);\n const len = loadingsCols[0].length + EXTRA_ROWS;\n\n for (let i = 0; i < components; ++i) {\n res[i] = new Float32Array(len);\n res[i].set(loadingsCols[i].getRawData());\n }\n\n return res;\n }\n\n /** Return regression coefficients */\n private getRegrCoeffs(features: DG.ColumnList, target: DG.Column, regrCoefsCol: DG.Column): Float32Array {\n const dim = features.length;\n const params = new Float32Array(dim + EXTRA_ROWS);\n const paramsByPLS = regrCoefsCol.getRawData();\n\n let tmpSum = 0;\n\n for (let i = 0; i < dim; ++i) {\n params[i] = paramsByPLS[i];\n tmpSum += paramsByPLS[i] * features.byIndex(i).stats.avg;\n }\n\n // compute bias\n params[dim] = target.stats.avg - tmpSum;\n\n return params;\n }\n\n /** Return explained variances */\n private computeExplVars(samplesCount: number, components: number, yLoadings: DG.Column) {\n if (this.specn === null)\n throw new Error('Failed to compute explained variances');\n\n const raw = yLoadings.getRawData();\n const dim = this.specn.loadings[0].length - EXTRA_ROWS;\n\n // Compute, source: the paper https://doi.org/10.1002/cem.2589\n let explVar = raw[0]**2 / samplesCount;\n\n this.specn.loadings[0][dim] = explVar;\n\n for (let comp = 1; comp < components; ++comp) {\n explVar += raw[comp]**2 / samplesCount;\n this.specn.loadings[comp][dim] = explVar;\n }\n }\n\n /** Return packed model */\n public toBytes(): Uint8Array {\n if (this.specn === null)\n throw new Error('Failed to pack untrained model');\n\n // 1. Store model params in dataframe\n const modelDf = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLE.FEATURES, this.specn.names),\n DG.Column.fromFloat32Array(TITLE.REGR_COEFS, this.specn.params),\n ]);\n\n this.specn.loadings.forEach((array, idx) => modelDf.columns.add(DG.Column.fromFloat32Array(\n `${TITLE.XLOADING}${idx + 1}`,\n array,\n )));\n\n // 2. Pack model dataframe\n const modelDfBytes = modelDf.toByteArray();\n const modelDfBytesCount = modelDfBytes.length;\n\n const scoresBytes = this.specn.scores.toByteArray();\n const scoresBytesCount = scoresBytes.length;\n\n const requiredBytes = modelDfBytesCount + scoresBytesCount + BYTES_PER_SIZES;\n\n const packedModel = new Uint8Array((Math.ceil(requiredBytes / BLOCK_SIZE) + 1) * BLOCK_SIZE);\n\n // 4 bytes for storing model's bytes count\n const sizeArr = new Uint32Array(packedModel.buffer, 0, SIZE_ARR_LEN);\n sizeArr[MODEL_IDX] = modelDfBytesCount;\n sizeArr[SCORES_IDX] = scoresBytesCount;\n\n // Store model's bytes\n packedModel.set(modelDfBytes, BYTES_PER_SIZES);\n\n // Store scores bytes\n packedModel.set(scoresBytes, BYTES_PER_SIZES + modelDfBytesCount);\n\n return packedModel;\n } // toBytes\n\n /** Return prediction */\n public predict(features: DG.ColumnList): DG.Column {\n if (this.specn === null)\n throw new Error('Predicting failed: model is not trained');\n\n return getPredictionByLinearRegression(features, this.specn.params);\n }\n\n /** Return loadings and regression coefficients viewers */\n private loadingsParamsViewers(): DG.Viewer[] {\n if (this.specn === null)\n throw new Error('Failed to create loadings and parameters viewers: untrained model');\n\n const viewers: DG.Viewer[] = [];\n\n const dim = this.specn.dim;\n\n // Parameters and loadings dataframe\n const loadingsDf = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLE.FEATURES, this.specn.names.slice(0, -1)),\n DG.Column.fromFloat32Array(TITLE.REGR_COEFS, this.specn.params, dim),\n ]);\n\n const columns = loadingsDf.columns;\n const shift = columns.length;\n const components = this.specn.components;\n\n this.specn.loadings.forEach((arr, idx) => loadingsDf.columns.add(\n DG.Column.fromFloat32Array(`${TITLE.XLOADING}${idx + 1}`, arr, dim),\n ));\n\n // Loading scatterplot\n viewers.push(DG.Viewer.scatterPlot(loadingsDf, {\n title: TITLE.LOADINGS,\n xColumnName: columns.byIndex(shift).name,\n yColumnName: columns.byIndex(shift + (components > 1 ? 1 : 0)).name,\n markerType: DG.MARKER_TYPE.CIRCLE,\n labels: TITLE.FEATURES,\n help: LINK.LOADINGS,\n }));\n\n // Regression coefficients barchart\n viewers.push(DG.Viewer.barChart(loadingsDf, {\n title: TITLE.REGR_COEFS,\n splitColumnName: TITLE.FEATURES,\n valueColumnName: TITLE.REGR_COEFS,\n valueAggrType: DG.AGG.AVG,\n help: LINK.COEFFS,\n showValueSelector: false,\n showStackSelector: false,\n }));\n\n return viewers;\n } // getLoadingsParamsViewers\n\n /** Return explained variances viewer */\n private explVarsViewer(): DG.Viewer {\n if (this.specn === null)\n throw new Error('Failed to create exaplained variances viewer: untrained model');\n\n const components = this.specn.components;\n const dim = this.specn.dim;\n\n const compNames = new Array<string>(components);\n const explVars = new Float32Array(components);\n\n compNames[0] = `${RESULT_NAMES.COMP} 1`;\n explVars[0] = this.specn.loadings[0][dim];\n\n for (let i = 1; i < components; ++i) {\n compNames[i] = `${RESULT_NAMES.COMPS} ${i + 1}`;\n explVars[i] = this.specn.loadings[i][dim];\n }\n\n return DG.Viewer.barChart(DG.DataFrame.fromColumns([\n DG.Column.fromStrings(RESULT_NAMES.COMPS, compNames),\n DG.Column.fromFloat32Array(TITLE.EXPL_VAR, explVars),\n ]), {\n title: TITLE.EXPL_VAR,\n splitColumnName: RESULT_NAMES.COMPS,\n valueColumnName: TITLE.EXPL_VAR,\n valueAggrType: DG.AGG.AVG,\n help: LINK.EXPL_VARS,\n showCategorySelector: false,\n showStackSelector: false,\n showValueSelector: false,\n });\n }\n\n /** Returns viewers */\n public viewers(): DG.Viewer[] {\n if (this.specn === null)\n throw new Error('Failed to create viewers: untrained model');\n\n const viewers = this.loadingsParamsViewers();\n viewers.push(\n this.explVarsViewer(),\n this.getScoresScatter(),\n );\n\n return viewers;\n }\n\n /** Return dataframe with scores */\n private getScoresDf(analysis: PlsOutput): DG.DataFrame {\n const tScores = analysis.tScores;\n const uScores = analysis.uScores;\n\n tScores.forEach((col, idx) => col.name = `${TITLE.XSCORE}${idx + 1}`);\n uScores.forEach((col, idx) => col.name = `${TITLE.YSCORE}${idx + 1}`);\n\n return DG.DataFrame.fromColumns(tScores.concat(uScores));\n }\n\n /** Return scores scatter */\n private getScoresScatter(): DG.Viewer {\n if (this.specn === null)\n throw new Error('Failed to create scores scatter: untrained model');\n\n const names = this.specn.scores.columns.names();\n\n const scatter = DG.Viewer.scatterPlot(this.specn.scores, {\n title: TITLE.SCORES,\n xColumnName: names[0],\n yColumnName: names[1],\n markerType: DG.MARKER_TYPE.CIRCLE,\n help: LINK.SCORES,\n showViewerFormulaLines: true,\n });\n\n scatter.meta.formulaLines.addAll(getLines(names));\n\n return scatter;\n }\n};\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nconst TRESHOLD = 0.5;\nconst SHIFT = 1;\nconst LIMIT = 2;\n\n/** Check lengths of columns */\nfunction checkLen(target: DG.Column, prediction: DG.Column): void {\n if (target.length !== prediction.length)\n throw new Error(`Non-equal elements count: ${target.length} vs. ${prediction.length}`);\n}\n\n/** Return dataframe for testing regression & linear methods */\nexport function regressionDataset(samples: number, features: number, dependent: number): DG.DataFrame {\n // create main features\n const df = grok.data.demo.randomWalk(samples, features);\n const cols = df.columns;\n\n const coefs = new Float32Array(features);\n\n // main features raw data\n const raw = new Array<Float32Array>(features);\n for (let j = 0; j < features; ++j)\n raw[j] = cols.byIndex(j).getRawData() as Float32Array;\n\n // dependent features raw data\n for (let j = 0; j < dependent; ++j) {\n const arr = new Float32Array(samples);\n\n // generate coefficients\n for (let k = 0; k < features; ++k)\n coefs[k] = Math.random();\n\n for (let i = 0; i < samples; ++i) {\n for (let k = 0; k < features; ++k)\n arr[i] += coefs[k] * raw[k][i];\n }\n\n cols.add(DG.Column.fromFloat32Array(`y${j}`, arr));\n }\n\n return df;\n} // pcaTestDf\n\n/** Max absolute deviation of the column */\nexport function madNorm(col: DG.Column): number {\n let mad = 0;\n const rows = col.length;\n const raw = col.getRawData();\n\n for (let i = 0; i < rows; ++i)\n mad = Math.max(mad, Math.abs(raw[i]));\n\n return mad;\n}\n\n/** Max absolute deviation error */\nexport function madError(target: DG.Column, prediction: DG.Column): number {\n checkLen(target, prediction);\n\n let mad = 0;\n const rows = target.length;\n const raw1 = target.getRawData();\n const raw2 = prediction.getRawData();\n\n for (let i = 0; i < rows; ++i)\n mad = Math.max(mad, Math.abs(raw1[i] - raw2[i]));\n\n return mad;\n}\n\n/** Return dataframe for testing classifiers */\nexport function classificationDataset(samples: number, features: number, useShift: boolean): DG.DataFrame {\n const labels = new Array<string>(samples);\n const raw = new Array<Float32Array>(features);\n\n for (let j = 0; j < features; ++j) {\n const arr = new Float32Array(samples);\n\n for (let i = 0; i < samples; ++i)\n arr[i] = Math.random();\n\n raw[j] = arr;\n }\n\n const df = DG.DataFrame.fromColumns(raw.map((arr, idx) => DG.Column.fromFloat32Array(`#${idx}`, arr)));\n\n for (let i = 0; i < samples; ++i)\n labels[i] = raw.slice(0, LIMIT).map((arr) => (arr[i] > TRESHOLD) ? 'A' : 'B').join('');\n\n df.columns.add(DG.Column.fromStrings('Labels', labels));\n\n if (useShift) {\n for (let j = 0; j < features; ++j) {\n for (let i = 0; i < samples; ++i)\n raw[j][i] += (raw[j][i] > 0 ? 1 : -1) * SHIFT;\n }\n }\n\n return df;\n} // classificationDataset\n\n/** Return accuracy */\nexport function accuracy(target: DG.Column, prediction: DG.Column): number {\n checkLen(target, prediction);\n\n let correctPredictions = 0;\n const rows = target.length;\n\n if (rows < 1)\n return 1;\n\n for (let i = 0; i < rows; ++i) {\n if (target.get(i) === prediction.get(i))\n ++correctPredictions;\n }\n\n return correctPredictions / rows;\n}\n","// Tests for PCA, PLS & linear regression\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {_package} from '../package-test';\n\nimport {category, expect, test} from '@datagrok-libraries/utils/src/test';\nimport {computePCA} from '../eda-tools';\nimport {getPlsAnalysis} from '../pls/pls-tools';\nimport {PlsModel} from '../pls/pls-ml';\nimport {getLinearRegressionParams, getPredictionByLinearRegression} from '../regression';\nimport {regressionDataset, madNorm, madError} from './utils';\n\nconst ROWS = 100;\nconst ROWS_K = 100;\nconst COLS = 100;\nconst COMPONENTS = 3;\nconst TIMEOUT = 4000;\nconst INDEP_COLS = 2;\nconst DEP_COLS = 5;\nconst ERROR = 0.1;\n\ncategory('Principal component analysis', () => {\n test(`Performance: ${ROWS_K}K rows, ${COLS} cols, ${COMPONENTS} components`, async () => {\n const df = grok.data.demo.randomWalk(ROWS_K * 1000, COLS);\n await computePCA(df, df.columns, COMPONENTS, false, false);\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Data\n const df = regressionDataset(ROWS, COMPONENTS, DEP_COLS);\n\n // Apply\n const pca = await computePCA(df, df.columns, COMPONENTS + 1, false, false);\n\n // Check\n const lastPca = pca.columns.byIndex(COMPONENTS);\n const norm = madNorm(lastPca);\n\n // the last PCA component must be small due to df construction\n expect((norm < ERROR), true, 'Incorrect PCA computations');\n }, {timeout: TIMEOUT});\n}); // PCA\n\ncategory('Partial least squares regression', () => {\n test(`Performance: ${ROWS_K}K rows, ${COLS} cols, ${COMPONENTS} components`, async () => {\n // Data\n const df = grok.data.demo.randomWalk(ROWS_K * 1000, COLS);\n const cols = df.columns;\n\n // Apply\n await getPlsAnalysis({\n table: df,\n features: cols,\n predict: cols.byIndex(COLS - 1),\n components: COMPONENTS,\n names: undefined,\n });\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Data\n const df = regressionDataset(ROWS_K, COMPONENTS, DEP_COLS);\n const cols = df.columns;\n const target = cols.byIndex(COMPONENTS + DEP_COLS - 1);\n\n // Apply\n const plsRes = await getPlsAnalysis({\n table: df,\n features: cols,\n predict: target,\n components: COMPONENTS,\n names: undefined,\n });\n\n // Check deviation\n const deviation = madError(target, plsRes.prediction);\n expect(\n (deviation < ERROR),\n true,\n `Incorrect PLS computations, error is too big: ${deviation}; expected: < ${ERROR}`,\n );\n }, {timeout: TIMEOUT});\n\n test(`Predictive modeling: ${ROWS_K}K samples, ${COLS} features, ${COMPONENTS} components`, async () => {\n // Prepare data\n const df = regressionDataset(ROWS_K * 1000, COMPONENTS, COLS - COMPONENTS + 1);\n const features = df.columns;\n const target = features.byIndex(COLS);\n features.remove(target.name);\n\n // Train & pack model\n const model = new PlsModel();\n await model.fit(features, target, COMPONENTS);\n const packed = model.toBytes();\n\n // Unpack model & predict\n const unpackedModel = new PlsModel(packed);\n const prediction = unpackedModel.predict(features);\n\n // Check deviation\n const deviation = madError(target, prediction);\n expect(\n (deviation < ERROR),\n true,\n `Incorrect PLS (ML) computations, error is too big: ${deviation}; expected: < ${ERROR}`,\n );\n }, {timeout: TIMEOUT, benchmark: true});\n}); // PLS\n\ncategory('Linear regression', () => {\n test(`Performance: ${ROWS_K}K samples, ${COLS} features`, async () => {\n // Prepare data\n const df = regressionDataset(ROWS_K * 1000, COLS, 1);\n const features = df.columns;\n const target = features.byIndex(COLS);\n\n // Train & pack model\n const params = await getLinearRegressionParams(features, target);\n const packed = new Uint8Array(params.buffer);\n\n // Unpack & apply model\n const unpackedParams = new Float32Array(packed.buffer);\n getPredictionByLinearRegression(features, unpackedParams);\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Prepare data\n const df = regressionDataset(ROWS, INDEP_COLS, 1);\n const features = df.columns;\n const target = features.byIndex(INDEP_COLS);\n\n // Train & pack model\n const params = await getLinearRegressionParams(features, target);\n const packed = new Uint8Array(params.buffer);\n\n // Unpack & apply model\n const unpackedParams = new Float32Array(packed.buffer);\n const prediction = getPredictionByLinearRegression(features, unpackedParams);\n\n // Evaluate model\n const error = madError(prediction, prediction);\n expect(\n error < ERROR,\n true,\n `Incorrect linear regression computations, error is too big: ${error}; expected: < ${ERROR}`,\n );\n }, {timeout: TIMEOUT});\n}); // Linear regression\n","// Softmax classifier (multinomial logistic regression): https://en.wikipedia.org/wiki/Multinomial_logistic_regression\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {_fitSoftmax} from '../wasm/EDAAPI';\n\nconst ROWS_EXTRA = 1;\nconst COLS_EXTRA = 2;\nconst MIN_COLS_COUNT = 1 + COLS_EXTRA;\nconst AVGS_NAME = 'Avg-s';\nconst STDEVS_NAME = 'Stddev-s';\nconst PRED_NAME = 'predicted';\nconst DEFAULT_LEARNING_RATE = 1;\nconst DEFAULT_ITER_COUNT = 100;\nconst DEFAULT_PENALTY = 0.1;\nconst DEFAULT_TOLERANCE = 0.001;\nconst BYTES_PER_MODEL_SIZE = 4;\n\n/** Train data sizes */\ntype DataSpecification = {\n classesCount: number,\n featuresCount: number,\n};\n\n/** Target labels specification */\ntype TargetLabelsData = {\n oneHot: Array<Uint8Array>,\n weights: Uint32Array,\n};\n\n/** Interactivity tresholds */\nenum INTERACTIVITY {\n MAX_SAMLPES = 50000,\n MAX_FEATURES = 100,\n};\n\n/** Softmax classifier */\nexport class SoftmaxClassifier {\n /** Check applicability */\n static isApplicable(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n for (const col of features) {\n if (!col.matches('numerical'))\n return false;\n }\n\n return (predictColumn.type === DG.COLUMN_TYPE.STRING);\n }\n\n /** Check interactivity */\n static isInteractive(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n return (features.length <= INTERACTIVITY.MAX_FEATURES) &&\n (predictColumn.length <= INTERACTIVITY.MAX_SAMLPES);\n }\n\n private avgs: Float32Array;\n private stdevs: Float32Array;\n private categories: string[];\n private params: Float32Array[] | undefined = undefined;\n private classesCount = 1;\n private featuresCount = 1;\n\n constructor(specification?: DataSpecification, packedModel?: Uint8Array) {\n if (specification !== undefined) { // Create empty model\n /** features count */\n const n = specification.featuresCount;\n\n /** classes count */\n const c = specification.classesCount;\n\n if (n < 1)\n throw new Error('Incorrect features count');\n\n if (c < 1)\n throw new Error('Incorrect classes count');\n\n /** length of arrays */\n const len = n + ROWS_EXTRA;\n\n // Init model routine\n this.avgs = new Float32Array(len);\n this.stdevs = new Float32Array(len);\n this.categories = new Array<string>(len);\n this.featuresCount = n;\n this.classesCount = c;\n } else if (packedModel !== undefined) { // Get classifier from packed model (bytes)\n try {\n // Extract model's bytes count\n const sizeArr = new Uint32Array(packedModel.buffer, 0, 1);\n const bytesCount = sizeArr[0];\n\n // Model's bytes\n const modelBytes = new Uint8Array(packedModel.buffer, BYTES_PER_MODEL_SIZE, bytesCount);\n\n const modelDf = DG.DataFrame.fromByteArray(modelBytes);\n const columns = modelDf.columns;\n const colsCount = columns.length;\n\n if (colsCount < MIN_COLS_COUNT)\n throw new Error('incorrect columns count');\n\n this.classesCount = colsCount - COLS_EXTRA;\n this.featuresCount = modelDf.rowCount - ROWS_EXTRA;\n\n const c = this.classesCount;\n\n // extract params & categories\n this.params = new Array<Float32Array>(c);\n this.categories = new Array<string>(modelDf.rowCount);\n\n for (let i = 0; i < c; ++i) {\n const col = columns.byIndex(i);\n this.categories[i] = col.name;\n\n if (col.type !== DG.COLUMN_TYPE.FLOAT)\n throw new Error(`Incorrect input column type. Expected: float, passed: ${col.type}`);\n\n this.params[i] = col.getRawData() as Float32Array;\n }\n\n // extract averages\n const avgsCol = columns.byName(AVGS_NAME);\n if (avgsCol.type !== DG.COLUMN_TYPE.FLOAT)\n throw new Error('incorrect average values column type');\n this.avgs = avgsCol.getRawData() as Float32Array;\n\n // extract stdevs\n const stdevsCol = columns.byName(STDEVS_NAME);\n if (stdevsCol.type !== DG.COLUMN_TYPE.FLOAT)\n throw new Error('incorrect standard deviations column type');\n this.stdevs = stdevsCol.getRawData() as Float32Array;\n } catch (e) {\n throw new Error(`Failed to load model: ${(e instanceof Error ? e.message : 'the platform issue')}`);\n }\n } else\n throw new Error('Softmax classifier not initialized');\n }; // constructor\n\n /** Return packed softmax classifier */\n public toBytes(): Uint8Array {\n if (this.params === undefined)\n throw new Error('Non-trained model');\n\n const c = this.classesCount;\n const columns = new Array<DG.Column>(c + COLS_EXTRA);\n\n // params columns\n for (let i = 0; i < c; ++i)\n columns[i] = DG.Column.fromFloat32Array(this.categories[i], this.params[i]);\n\n // averages\n columns[c] = DG.Column.fromFloat32Array(AVGS_NAME, this.avgs);\n\n // stdevs\n columns[c + 1] = DG.Column.fromFloat32Array(STDEVS_NAME, this.stdevs);\n\n const modelDf = DG.DataFrame.fromColumns(columns);\n\n const modelBytes = modelDf.toByteArray();\n const bytesCount = modelBytes.length;\n\n // Packed model bytes, including bytes count\n const packedModel = new Uint8Array(bytesCount + BYTES_PER_MODEL_SIZE);\n\n // 4 bytes for storing model's bytes count\n const sizeArr = new Uint32Array(packedModel.buffer, 0, 1);\n sizeArr[0] = bytesCount;\n\n // Store model's bytes\n packedModel.set(modelBytes, BYTES_PER_MODEL_SIZE);\n\n return packedModel;\n } // toBytes\n\n /** Train classifier */\n public async fit(features: DG.ColumnList, target: DG.Column, rate: number = DEFAULT_LEARNING_RATE,\n iterations: number = DEFAULT_ITER_COUNT, penalty: number = DEFAULT_PENALTY, tolerance: number = DEFAULT_TOLERANCE) {\n if (features.length !== this.featuresCount)\n throw new Error('Training failes - incorrect features count');\n\n if ((rate <= 0) || (iterations < 1) || (penalty <= 0) || (tolerance <= 0))\n throw new Error('Training failes - incorrect fitting hyperparameters');\n\n // Extract statistics & categories\n this.extractStats(features);\n const rowsCount = target.length;\n const classesCount = target.categories.length;\n const cats = target.categories;\n for (let i = 0; i < classesCount; ++i)\n this.categories[i] = cats[i];\n\n try {\n // call wasm-computations\n const paramCols = _fitSoftmax(\n features,\n DG.Column.fromFloat32Array('avgs', this.avgs, this.featuresCount),\n DG.Column.fromFloat32Array('stdevs', this.stdevs, this.featuresCount),\n DG.Column.fromInt32Array('targets', target.getRawData() as Int32Array, rowsCount),\n classesCount,\n iterations, rate, penalty, tolerance,\n this.featuresCount + 1, classesCount,\n ).columns as DG.ColumnList;\n\n this.params = new Array<Float32Array>(classesCount);\n for (let i = 0; i < classesCount; ++i)\n this.params[i] = paramCols.byIndex(i).getRawData() as Float32Array;\n } catch (error) {\n try { // call fitting TS-computations (if wasm failed)\n this.params = await this.fitSoftmaxParams(\n features,\n target,\n iterations,\n rate,\n penalty,\n tolerance,\n ) as Float32Array[];\n } catch (error) {\n throw new Error('Training failes');\n }\n }\n\n if (this.params === undefined)\n throw new Error('Training failes');\n }; // fit\n\n /** Extract features' stats */\n private extractStats(features: DG.ColumnList): void {\n let j = 0;\n\n for (const col of features) {\n if ((col.type !== DG.COLUMN_TYPE.INT) && (col.type !== DG.COLUMN_TYPE.FLOAT))\n throw new Error('Training failes - incorrect features type');\n\n this.avgs[j] = col.stats.avg;\n this.stdevs[j] = col.stats.stdev;\n\n ++j;\n }\n } // extractStats\n\n /** Retrun normalized features */\n private normalized(features: DG.ColumnList): Array<Float32Array> {\n const m = features.byIndex(0).length;\n\n const X = new Array<Float32Array>(m);\n\n for (let i = 0; i < m; ++i)\n X[i] = new Float32Array(this.featuresCount);\n\n let j = 0;\n for (const col of features) {\n if ((col.type !== DG.COLUMN_TYPE.INT) && (col.type !== DG.COLUMN_TYPE.FLOAT))\n throw new Error('Training failes - incorrect features type');\n\n const raw = col.getRawData();\n const avg = this.avgs[j];\n const stdev = this.stdevs[j];\n\n if (stdev > 0) {\n for (let i = 0; i < m; ++i)\n X[i][j] = (raw[i] - avg) / stdev;\n } else {\n for (let i = 0; i < m; ++i)\n X[i][j] = 0;\n }\n\n ++j;\n }\n\n return X;\n } // normalized\n\n /** Retrun normalized & transposed features */\n private transposed(features: DG.ColumnList): Array<Float32Array> {\n const m = features.byIndex(0).length;\n const n = this.featuresCount;\n\n const X = new Array<Float32Array>(n);\n\n for (let i = 0; i < n; ++i)\n X[i] = new Float32Array(m);\n\n let j = 0;\n for (const col of features) {\n if ((col.type !== DG.COLUMN_TYPE.INT) && (col.type !== DG.COLUMN_TYPE.FLOAT))\n throw new Error('Training failes - incorrect features type');\n\n const raw = col.getRawData();\n const avg = this.avgs[j];\n const stdev = this.stdevs[j];\n\n if (stdev > 0) {\n for (let i = 0; i < m; ++i)\n X[j][i] = (raw[i] - avg) / stdev;\n } else {\n for (let i = 0; i < m; ++i)\n X[j][i] = 0;\n }\n\n ++j;\n }\n\n return X;\n } // transposed\n\n /** Return one-hot vectors and classes weights */\n private preprocessedTargets(target: DG.Column): TargetLabelsData {\n if (target.type !== DG.COLUMN_TYPE.STRING)\n throw new Error('Training failes - incorrect target type');\n\n const c = this.classesCount;\n const m = target.length;\n const raw = target.getRawData();\n\n const Y = new Array<Uint8Array>(m);\n const weights = new Uint32Array(c).fill(0);\n\n for (let i = 0; i < m; ++i)\n Y[i] = new Uint8Array(c).fill(0);\n\n for (let i = 0; i < m; ++i) {\n Y[i][raw[i]] = 1;\n ++weights[raw[i]];\n }\n\n return {\n oneHot: Y,\n weights: weights,\n };\n } // getOneHot\n\n /** Return prediction column */\n public predict(features: DG.ColumnList): DG.Column {\n if (this.params === undefined)\n throw new Error('Non-trained model');\n\n if (features.length !== this.featuresCount)\n throw new Error('Predcition fails: incorrect features count');\n\n // Normalize features\n const X = this.normalized(features);\n\n // Routine items\n const m = X.length;\n const n = this.featuresCount;\n const c = this.classesCount;\n let xBuf: Float32Array;\n let wBuf: Float32Array;\n const Z = new Float32Array(c);\n let sum: number;\n let max: number;\n let argMax: number;\n const predClass = new Array<string>(m);\n\n // get prediction for each sample\n for (let j = 0; j < m; ++j) {\n xBuf = X[j];\n sum = 0;\n\n for (let i = 0; i < c; ++i) {\n wBuf = this.params[i];\n sum = wBuf[n];\n\n for (let k = 0; k < n; ++k)\n sum += wBuf[k] * xBuf[k];\n\n Z[i] = Math.exp(sum);\n }\n\n max = Z[0];\n argMax = 0;\n\n for (let k = 1; k < c; ++k) {\n if (max < Z[k]) {\n max = Z[k];\n argMax = k;\n }\n }\n\n predClass[j] = this.categories[argMax];\n }\n\n return DG.Column.fromStrings(PRED_NAME, predClass);\n }\n\n /** Fit params in the webworker */\n private async fitSoftmaxParams(features: DG.ColumnList, target: DG.Column,\n iterations: number, rate: number, penalty: number, tolerance: number) {\n const targetData = this.preprocessedTargets(target);\n\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('./workers/softmax-worker.ts', import.meta.url));\n worker.postMessage({\n features: this.normalized(features),\n transposed: this.transposed(features),\n oneHot: targetData.oneHot,\n classesWeights: targetData.weights,\n targetRaw: target.getRawData(),\n iterations: iterations,\n rate: rate,\n penalty: penalty,\n tolerance: tolerance,\n });\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(e.data.params);\n console.log(`Loss: ${e.data.loss}`);\n };\n });\n }\n}; // SoftmaxClassifier\n","// XGBooster modeling tools\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {predict, fitInWebWorker} from '../wasm/xgbooster';\n\n/** Default hyperparameters */\nenum DEFAULT {\n ITERATIONS = 20,\n ETA = 0.3,\n MAX_DEPTH = 6,\n LAMBDA = 1,\n ALPHA = 0,\n};\n\n/** Interactivity tresholds */\nenum INTERACTIVITY {\n SAMLPES_HIGH = 100000,\n SAMLPES_MID = 50000,\n SAMPLES_LOW = 10000,\n FEATURES_HIGH = 10,\n FEATURES_MID = 20,\n FEATURES_LOW = 100,\n};\n\n/** Reserve sizes */\nenum RESERVED {\n MODEL = 10000000,\n UTILS = 1,\n PACK = 128,\n SIZE = 4,\n};\n\n/** XGBoost specific constants */\nconst MISSING_VALUE = DG.FLOAT_NULL;\nconst ALIGN_VAL = 4;\nconst BLOCK_SIZE = 64;\n\nenum TITLES {\n PREDICT = 'Prediction',\n TYPE = 'Type',\n PARAMS = 'Params count',\n CATS = 'Categories',\n CATS_SIZE = 'Categories size',\n}\n\n/** XGBoost modeling */\nexport class XGBooster {\n /** Check applicability */\n static isApplicable(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n for (const col of features) {\n if (!col.matches('numerical'))\n return false;\n }\n if (!predictColumn.matches('numerical') && !predictColumn.matches('string'))\n return false;\n\n return true;\n }\n\n /** Check interactivity */\n static isInteractive(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n const featuresCount = features.length;\n const samplesCount = predictColumn.length;\n\n if (samplesCount <= INTERACTIVITY.SAMPLES_LOW)\n return featuresCount <= INTERACTIVITY.FEATURES_LOW;\n\n if (samplesCount <= INTERACTIVITY.SAMLPES_MID)\n return featuresCount <= INTERACTIVITY.FEATURES_MID;\n\n if (samplesCount <= INTERACTIVITY.SAMLPES_HIGH)\n return featuresCount <= INTERACTIVITY.FEATURES_HIGH;\n\n return false;\n }\n\n private modelParams: Int32Array | undefined = undefined;\n private targetType: string | undefined = undefined;\n private targetCategories: string[] | undefined = undefined;\n\n constructor(packedModel?: Uint8Array) {\n if (packedModel) {\n try {\n let offset = 0;\n\n // Unpack header size\n const headArr = new Uint32Array(packedModel.buffer, offset, 1);\n const headerBytesSize = headArr[0];\n offset += RESERVED.SIZE;\n\n // Unpack header\n const headerDf = DG.DataFrame.fromByteArray(new Uint8Array(packedModel.buffer, offset, headerBytesSize));\n offset += headerBytesSize;\n\n // Extract model specification\n this.targetType = headerDf.get(TITLES.TYPE, 0) as string;\n const modelParamsCount = headerDf.get(TITLES.PARAMS, 0) as number;\n const categoriesBytesSize = headerDf.get(TITLES.CATS_SIZE, 0) as number;\n\n // Unpack categories\n if (categoriesBytesSize > 0) {\n const categoriesDf = DG.DataFrame.fromByteArray(\n new Uint8Array(packedModel.buffer, offset, categoriesBytesSize),\n );\n\n this.targetCategories = categoriesDf.col(TITLES.CATS)?.toList();\n }\n offset += categoriesBytesSize;\n\n offset = Math.ceil(offset / ALIGN_VAL) * ALIGN_VAL;\n\n // Unpack model params\n this.modelParams = new Int32Array(packedModel.buffer, offset, modelParamsCount);\n } catch (error) {\n throw new Error(`Failed to load model: ${(error instanceof Error ? error.message : 'the platform issue')}`);\n }\n }\n }\n\n /** Fit model */\n public async fit(features: DG.ColumnList, target: DG.Column, iterations: number = DEFAULT.ITERATIONS,\n eta: number = DEFAULT.ETA, maxDepth: number = DEFAULT.MAX_DEPTH, lambda: number = DEFAULT.LAMBDA,\n alpha: number = DEFAULT.ALPHA) {\n // Type of the target\n this.targetType = target.type;\n\n // Store categories of string target\n if (this.targetType === DG.COLUMN_TYPE.STRING)\n this.targetCategories = target.categories;\n\n // Train model params\n this.modelParams = await fitInWebWorker(features, target, MISSING_VALUE,\n iterations, eta, maxDepth, lambda, alpha, RESERVED.MODEL, RESERVED.UTILS,\n );\n }\n\n /** Predict using trained model */\n public predict(features: DG.ColumnList): DG.Column {\n if (this.modelParams === undefined)\n throw new Error('Failed to apply non-trained model');\n\n // Get prediction\n const prediction = predict(features, MISSING_VALUE, this.modelParams);\n\n // Create an appropriate column\n switch (this.targetType) {\n case DG.COLUMN_TYPE.STRING:\n return this.stringColPrediction(prediction);\n\n case DG.COLUMN_TYPE.INT:\n return this.intColPrediction(prediction);\n\n case DG.COLUMN_TYPE.BIG_INT:\n return this.bigIntColPrediction(prediction);\n\n default:\n return DG.Column.fromFloat32Array(TITLES.PREDICT, prediction);\n }\n }\n\n /** Return packed model */\n public toBytes(): Uint8Array {\n if ((this.modelParams === undefined) || (this.targetType === undefined))\n throw new Error('Failed to pack non-trained model');\n\n // Categories bytes\n const categoriesBytes = (this.targetCategories !== undefined) ? DG.DataFrame.fromColumns([\n DG.Column.fromList(DG.COLUMN_TYPE.STRING, TITLES.CATS, this.targetCategories),\n ]).toByteArray(): undefined;\n\n const categoriesBytesSize = (categoriesBytes !== undefined) ? categoriesBytes.length : 0;\n\n const modelParamsBytesSize = this.modelParams.length * this.modelParams.BYTES_PER_ELEMENT;\n\n // Header with model specification\n const headerDf = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLES.TYPE, [this.targetType]),\n DG.Column.fromInt32Array(TITLES.PARAMS, new Int32Array([this.modelParams.length])),\n DG.Column.fromInt32Array(TITLES.CATS_SIZE, new Int32Array([categoriesBytesSize])),\n ]);\n\n // Header bytes\n const headerBytes = headerDf.toByteArray();\n const headerBytesSize = headerBytes.length;\n\n // Packed model\n const reservedSize = Math.ceil((RESERVED.SIZE +\n headerBytesSize + categoriesBytesSize + modelParamsBytesSize + RESERVED.PACK) / BLOCK_SIZE) * BLOCK_SIZE;\n\n const packedModel = new Uint8Array(reservedSize);\n\n let offset = 0;\n\n // Pack header size\n const headArr = new Uint32Array(packedModel.buffer, offset, 1);\n headArr[0] = headerBytesSize;\n offset += RESERVED.SIZE;\n\n // Pack header\n packedModel.set(headerBytes, offset);\n offset += headerBytesSize;\n\n // Pack categories\n if (categoriesBytesSize > 0)\n packedModel.set(categoriesBytes!, offset);\n offset += categoriesBytesSize;\n\n offset = Math.ceil(offset / ALIGN_VAL) * ALIGN_VAL;\n\n // Pack model params\n packedModel.set(new Uint8Array(this.modelParams.buffer), offset);\n\n return packedModel;\n } // toBytes\n\n /** Return predicted string column */\n private stringColPrediction(prediction: Float32Array): DG.Column {\n const samplesCount = prediction.length;\n\n if (this.targetCategories === undefined)\n throw new Error('Predicting fails: undefined categories');\n\n const predClass = new Array<string>(samplesCount);\n\n const maxCategory = this.targetCategories.length - 1;\n const categoryIdx = (val: number) => Math.max(0, Math.min(val, maxCategory));\n\n for (let i = 0; i < samplesCount; ++i)\n predClass[i] = this.targetCategories[categoryIdx(Math.round(prediction[i]))];\n\n return DG.Column.fromList(DG.COLUMN_TYPE.STRING, TITLES.PREDICT, predClass);\n }\n\n /** Return predicted int column */\n private intColPrediction(prediction: Float32Array): DG.Column {\n const samplesCount = prediction.length;\n\n const rawInts = new Int32Array(samplesCount);\n\n for (let i = 0; i < samplesCount; ++i)\n rawInts[i] = Math.round(prediction[i]);\n\n return DG.Column.fromInt32Array(TITLES.PREDICT, rawInts, samplesCount);\n }\n\n /** Return predicted bigint column */\n private bigIntColPrediction(prediction: Float32Array): DG.Column {\n const samplesCount = prediction.length;\n\n const rawInts = new BigInt64Array(samplesCount);\n\n for (let i = 0; i < samplesCount; ++i)\n rawInts[i] = BigInt(Math.round(prediction[i]));\n\n return DG.Column.fromBigInt64Array(TITLES.PREDICT, rawInts);\n }\n}\n","// JavaScript API for call wasm-functions from the XGBoostAPI module\n\n// Data constants\nconst INT_BYTES = 4;\nconst FLOAT_BYTES = 4;\nconst SIZE_IDX = 0;\n\nexport async function initXgboost() {\n await initXGBoostModule();\n}\n\n/** Fit and return model params */\nexport function fit(features, target, missingValue, iterations, eta, maxDepth, lambda, alpha,\n modelReserve, utilsLength) {\n // Data size\n const samplesCount = target.length;\n const featuresCount = features.length;\n\n // Allocate memory\n const featuresBuf = XGBoostModule._malloc(samplesCount * featuresCount * FLOAT_BYTES);\n const targetBuf = XGBoostModule._malloc(samplesCount * FLOAT_BYTES);\n const modelBuf = XGBoostModule._malloc(modelReserve * INT_BYTES);\n const utilsBuf = XGBoostModule._malloc(utilsLength * INT_BYTES);\n\n // Wasm buffer routine\n const floatHeap = XGBoostModule.HEAPF32;\n let intHeap = XGBoostModule.HEAP32;\n let raw;\n\n // Put features to wasm buffer\n for (let j = 0; j < featuresCount; ++j) {\n raw = features.byIndex(j).getRawData();\n\n for (let i = 0; i < samplesCount; ++i)\n floatHeap[featuresBuf / FLOAT_BYTES + i + j * samplesCount] = raw[i];\n }\n\n // Put targets to wasm buffer\n raw = target.getRawData();\n for (let i = 0; i < samplesCount; ++i)\n floatHeap[targetBuf / FLOAT_BYTES + i] = raw[i];\n\n // Train model\n XGBoostModule._train(\n featuresBuf, samplesCount, featuresCount, missingValue, // features data\n targetBuf, samplesCount, // target data\n iterations, eta, maxDepth, lambda, alpha, // hyperparameters\n utilsBuf, utilsLength, // utils\n modelBuf, modelReserve, // model params to be trained\n );\n\n // Extract model params from wasm buffer\n intHeap = XGBoostModule.HEAP32;\n const paramsCount = intHeap[utilsBuf / INT_BYTES + SIZE_IDX];\n const params = new Int32Array(paramsCount);\n\n for (let i = 0; i < paramsCount; ++i)\n params[i] = intHeap[modelBuf / INT_BYTES + i];\n\n // Free allocated memory\n XGBoostModule._free(featuresBuf);\n XGBoostModule._free(targetBuf);\n XGBoostModule._free(utilsBuf);\n XGBoostModule._free(modelBuf);\n\n return params;\n} // fit\n\n/** Fit and return model params in webworker */\nexport async function fitInWebWorker(features, target, missingValue, iterations, eta, maxDepth, lambda, alpha,\n modelReserve, utilsLength) {\n return new Promise((resolve, reject) => {\n // Data size\n const samplesCount = target.length;\n const featuresCount = features.length;\n\n // Features raw data\n const featuresRaw = new Float32Array(samplesCount * featuresCount);\n let shift;\n let raw;\n for (let j = 0; j < featuresCount; ++j) {\n raw = features.byIndex(j).getRawData();\n shift = j * samplesCount;\n\n for (let i = 0; i < samplesCount; ++i)\n featuresRaw[i + shift] = raw[i];\n }\n\n const worker = new Worker(new URL('../wasm/workers/xgboostWorker.js', import.meta.url));\n\n worker.postMessage({\n features: featuresRaw,\n target: target.getRawData(),\n samplesCount: samplesCount,\n featuresCount: featuresCount,\n modelReserve: modelReserve,\n utilsLength: utilsLength,\n iterations: iterations,\n eta: eta,\n maxDepth: maxDepth,\n lambda: lambda,\n alpha: alpha,\n missingValue: missingValue,\n });\n\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(e.data.params);\n };\n });\n} // fitInWebWorker\n\n/** Return prediction by trained model */\nexport function predict(features, missingValue, params) {\n // Data & model sizes\n const samplesCount = features.byIndex(0).length;\n const featuresCount = features.length;\n const paramsCount = params.length;\n\n // Wasm buffer routine\n let floatHeap = XGBoostModule.HEAPF32;\n const intHeap = XGBoostModule.HEAP32;\n\n // Allocate memory\n const featuresBuf = XGBoostModule._malloc(samplesCount * featuresCount * FLOAT_BYTES);\n const targetBuf = XGBoostModule._malloc(samplesCount * FLOAT_BYTES);\n const modelBuf = XGBoostModule._malloc(paramsCount * INT_BYTES);\n\n // Put features to wasm buffer\n for (let j = 0; j < featuresCount; ++j) {\n const raw = features.byIndex(j).getRawData();\n\n for (let i = 0; i < samplesCount; ++i)\n floatHeap[featuresBuf / FLOAT_BYTES + i + j * samplesCount] = raw[i];\n }\n\n // Put model to wasm bufffer\n for (let i = 0; i < paramsCount; ++i)\n intHeap[modelBuf / INT_BYTES + i] = params[i];\n\n // Compute predictions\n XGBoostModule._predict(\n featuresBuf, samplesCount, featuresCount, missingValue, // features\n modelBuf, paramsCount, // model params\n targetBuf, samplesCount, // target to be predicted\n );\n\n // Extract predictions from wasm buffer\n floatHeap = XGBoostModule.HEAPF32;\n const prediction = new Float32Array(samplesCount);\n\n for (let i = 0; i < samplesCount; ++i)\n prediction[i] = floatHeap[targetBuf / FLOAT_BYTES + i];\n\n // Free allocated memory\n XGBoostModule._free(featuresBuf);\n XGBoostModule._free(targetBuf);\n XGBoostModule._free(modelBuf);\n\n return prediction;\n} // predict\n","// Tests for classifiers\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {_package} from '../package-test';\n\nimport {category, expect, test} from '@datagrok-libraries/utils/src/test';\n\nimport {classificationDataset, accuracy} from './utils';\nimport {SoftmaxClassifier} from '../softmax-classifier';\nimport {XGBooster} from '../xgbooster';\n\nconst ROWS_K = 50;\nconst MIN_COLS = 2;\nconst COLS = 100;\nconst TIMEOUT = 8000;\nconst MIN_ACCURACY = 0.9;\n\ncategory('Softmax', () => {\n test(`Performance: ${ROWS_K}K samples, ${COLS} features`, async () => {\n // Data\n const df = classificationDataset(ROWS_K * 1000, COLS, false);\n const features = df.columns;\n const target = features.byIndex(COLS);\n features.remove(target.name);\n\n // Fit & pack trained model\n const model = new SoftmaxClassifier({\n classesCount: target.categories.length,\n featuresCount: features.length,\n });\n await model.fit(features, target);\n const modelBytes = model.toBytes();\n\n // Unpack & apply model\n const unpackedModel = new SoftmaxClassifier(undefined, modelBytes);\n unpackedModel.predict(features);\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Prepare data\n const df = classificationDataset(ROWS_K, MIN_COLS, true);\n const features = df.columns;\n const target = features.byIndex(MIN_COLS);\n features.remove(target.name);\n\n // Fit & pack trained model\n const model = new SoftmaxClassifier({\n classesCount: target.categories.length,\n featuresCount: features.length,\n });\n\n await model.fit(features, target);\n const modelBytes = model.toBytes();\n\n // Unpack & apply model\n const unpackedModel = new SoftmaxClassifier(undefined, modelBytes);\n const prediction = unpackedModel.predict(features);\n\n // Evaluate accuracy\n const acc = accuracy(target, prediction);\n expect(\n acc > MIN_ACCURACY,\n true,\n `Softmax failed, too small accuracy: ${acc}; expected: <= ${MIN_ACCURACY}`,\n );\n }, {timeout: TIMEOUT});\n}); // Softmax\n\ncategory('XGBoost', () => {\n test(`Performance: ${ROWS_K}K samples, ${COLS} features`, async () => {\n // Data\n const df = classificationDataset(ROWS_K * 1000, COLS, false);\n const features = df.columns;\n const target = features.byIndex(COLS);\n features.remove(target.name);\n\n // Fit & pack trained model\n const model = new XGBooster();\n await model.fit(features, target);\n const modelBytes = model.toBytes();\n\n // Unpack & apply model\n const unpackedModel = new XGBooster(modelBytes);\n unpackedModel.predict(features);\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Prepare data\n const df = classificationDataset(ROWS_K, MIN_COLS, true);\n const features = df.columns;\n const target = features.byIndex(MIN_COLS);\n features.remove(target.name);\n\n // Fit & pack trained model\n const model = new XGBooster();\n\n await model.fit(features, target);\n const modelBytes = model.toBytes();\n\n // Unpack & apply model\n const unpackedModel = new XGBooster(modelBytes);\n const prediction = unpackedModel.predict(features);\n\n // Evaluate accuracy\n const acc = accuracy(target, prediction);\n expect(\n acc > MIN_ACCURACY,\n true,\n `XGBoost failed, too small accuracy: ${acc}; expected: <= ${MIN_ACCURACY}`,\n );\n }, {timeout: TIMEOUT});\n}); // XGBoost\n","import * as DG from 'datagrok-api/dg';\nimport {runTests, tests, TestContext} from '@datagrok-libraries/utils/src/test';\nimport './tests/dim-reduction-tests';\nimport './tests/linear-methods-tests';\nimport './tests/classifiers-tests';\nexport const _package = new DG.Package();\nexport {tests};\n\n//name: test\n//input: string category {optional: true}\n//input: string test {optional: true}\n//input: object testContext {optional: true}\n//output: dataframe result\nexport async function test(category: string, test: string, testContext: TestContext): Promise<DG.DataFrame> {\n const data = await runTests({category, test, testContext});\n return DG.DataFrame.fromObjects(data)!;\n}\n"],"names":["_scriptDir","exportCppDbscanLib","document","currentScript","src","undefined","readyPromiseResolve","readyPromiseReject","Module","Promise","resolve","reject","readBinary","moduleOverrides","Object","assign","ENVIRONMENT_IS_WEB","window","ENVIRONMENT_IS_WORKER","importScripts","scriptDirectory","process","versions","node","self","location","href","indexOf","substr","replace","lastIndexOf","url","xhr","XMLHttpRequest","open","responseType","send","Uint8Array","console","log","bind","wasmBinary","wasmMemory","err","warn","WebAssembly","abort","HEAP8","HEAPU8","HEAPU32","ABORT","updateMemoryViews","b","buffer","Int8Array","Int16Array","Int32Array","Uint16Array","Uint32Array","Float32Array","Float64Array","__ATPRERUN__","__ATINIT__","__ATPOSTRUN__","runDependencies","runDependencyWatcher","dependenciesFulfilled","what","e","RuntimeError","wasmBinaryFile","path","isDataURI","filename","startsWith","getBinary","file","instantiateArrayBuffer","binaryFile","imports","receiver","fetch","then","credentials","response","catch","getBinaryPromise","binary","instantiate","instance","reason","callRuntimeCallbacks","callbacks","length","shift","ExceptionInfo","excPtr","this","ptr","set_type","type","get_type","set_destructor","destructor","get_destructor","set_caught","caught","get_caught","set_rethrown","rethrown","get_rethrown","init","set_adjusted_ptr","adjustedPtr","get_adjusted_ptr","get_exception_ptr","___cxa_is_pointer_type","adjusted","emscripten_realloc_buffer","size","grow","byteLength","getCFunc","ident","UTF8Decoder","TextDecoder","ccall","returnType","argTypes","args","opts","toC","str","ret","len","i","c","charCodeAt","lengthBytesUTF8","stackAlloc","outPtr","maxBytesToWrite","heap","outIdx","endIdx","u","stringToUTF8Array","stringToUTF8","stringToUTF8OnStack","arr","array","set","func","cArgs","stack","converter","stackSave","apply","stackRestore","heapOrArray","idx","maxBytesToRead","endPtr","decode","subarray","u0","u1","u2","String","fromCharCode","ch","UTF8ArrayToString","Boolean","convertReturnValue","onDone","calledRun","wasmImports","dest","num","copyWithin","requestedSize","x","oldSize","maxHeapSize","cutDown","overGrownHeapSize","Math","min","max","callback","info","receiveInstance","module","cb","exports","unshift","clearInterval","removeRunDependency","result","instantiateStreaming","createWasm","arguments","run","doRun","postRun","preRun","setTimeout","numericArgs","every","runCaller","pop","ready","define","__esModule","digestLength","blockSize","K","hashBlocks","w","v","p","pos","a","d","f","g","h","j","t1","t2","Hash","state","temp","bufferLength","bytesHashed","finished","reset","prototype","clean","update","data","dataLength","Error","dataPos","finish","out","left","bitLenHi","bitLenLo","padLength","digest","_saveState","_restoreState","from","HMAC","key","inner","outer","pad","istate","ostate","hash","hmac","fillBuffer","counter","hkdfSalt","hkdf","salt","okm","hmac_","bufpos","fill","pbkdf2","password","iterations","dkLen","prf","ctr","t","dk","k","factory","sha256","str1","str2","options","jaroDist","caseSensitive","toUpperCase","m","len1","len2","floor","str1Hash","Array","str2Hash","point","charAt","jaro","prefix","minIndex","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","id","loaded","__webpack_modules__","call","amdO","definition","o","defineProperty","enumerable","get","chunkId","globalThis","Function","hmd","create","children","obj","prop","hasOwnProperty","r","Symbol","toStringTag","value","scriptUrl","scripts","getElementsByTagName","test","baseURI","DG","grok","testData","fromCsv","columns","add","fromList","BYTE_ARRAY","thisArg","_arguments","P","generator","fulfilled","step","next","rejected","done","STANDART_TIMEOUT","BENCHMARK_TIMEOUT","stdLog","stdInfo","stdWarn","stdError","error","tests","autoTestsCatName","demoCatName","detectorsCatName","coreCatName","wasRegistered","currentCategory","assure","DimReductionMethods","StringMetricsNames","VectorMetricsNames","BitArrayMetricsNames","IntArrayMetricsNames","NumberMetricsNames","NumberArrayMetricsNames","DistanceMetricsSubjects","notNull","name","TestContext","constructor","catchUnhandled","report","Test","category","_a","timeout","push","actual","expected","tests_","clear","benchmarks","stressTests","addNamespace","s","RegExp","nqName","runTests","_b","_c","_d","package_","getCurrentCall","package","packageId","moduleTests","keys","find","dartTests","split","cat","join","fullName","isAggregated","skipReason","moduleAutoTests","moduleDemo","moduleDetectors","packFunctions","functions","filter","list","reg","demo","isArray","res","matchAll","map","forEach","parseInt","eval","wait","skip","isInBenchmark","benchmarkTimeout","friendlyName","isInDemo","view","BROWSE","createByType","clearLastError","unhandled","lastError","hasTag","col","clone","semType","initAutoTests","results","testContext","logs","redefineConsole","stressTest","_e","_f","testInvocationMap","entries","testsToInvoke","skipped","newArr","slice","sort","random","shuffle","testingObj","InvokeCategoryMethod","before","testRun","execTest","verbose","after","InvokeStressTests","categoriesToInvoke","_g","toLowerCase","exclude","some","beforeStatus","benchmark","closeAll","afterStatus","date","Date","toISOString","success","ms","params","reportTest","root","method","headers","body","JSON","stringify","InvokeAllTests","toString","invokationResult","translateStackTrace","predicate","categoryTimeout","packageName","_h","start","now","timeout_","stats","sum","df","remove","rows","removeWhere","toCsv","reduce","acc","toJson","testTimeout","timeoutReason","timeoutPromise","_","race","clearTimeout","fromColumns","fromStrings","peq","distance","tmp","n","lst","pv","mv","sc","eq","xv","myers_32","mhc","phc","hsize","ceil","vsize","vlen","pb","mb","xh","ph","mh","score","myers_x","BitArray","arg","defaultValue","_length","_version","_updateLevel","_selectedCount","_selectedCountVersion","_selectedIndexesVersion","_versionedName","_versionedNameVersion","SHRINK_THRESHOLD","buff","_createBuffer","_data","getRawData","assureGoez","argName","assureInRange","copy","dst","count","copyFrom","other","lengthInInts","version","incrementVersion","notify","versionedName","setLength","nIntsNeeded","newData","fromAnd","set1","set2","fromValues","values","fromSeq","flag","setBit","fromString","fromUint32Array","fromBytes","bytes","num1","num2","countBits","equals","getBit","bitArray","setAll","invert","flags","setIndexes","indexes","setFast","everyIndex","index","anyIndex","setWhere","check","allowClear","getRange","to","getRangeAsList","setRange","end","setTrue","setFalse","setRandom","and","andNot","notAnd","not","or","xor","insertAt","oldlength","removeAt","contains","removeByMask","mask","dstIdx","srcIdx","findNext","bit","trueCount","falseCount","_onBitCount","remainingBits","countWhere","andWithCountBits","second","allTrue","allFalse","anyTrue","anyFalse","unusedBits","numInts","_firstOnBit","findPrev","_lastOnBit","hamming","distanceF","scoringMatrix","alphabetIndexes","matrix","minCharCode","scorringArray","matrixRow","key2","index2","getDistanceF","threshold","seq1","seq2","diff","s1l","s2l","thresholdLimit","abs","defaultArgs","gapOpen","gapExtend","MmDistanceFunctionsNames","mmDistanceFunctions","HAMMING","LEVENSHTEIN","NEEDLEMANN_WUNSCH","charCodeArray","verticalGaps","horizontalGaps","prevRow","currRow","diagonal","top","maxScore","MONOMER_CHEMICAL_DISTANCE","tanimotoSimilarity","y","total","common","getDistanceFromSimilarity","similarity","Tanimoto","Dice","Asymmetric","BraunBlanquet","Cosine","Kulczynski","McConnaughey","RogotGoldberg","Russel","Sokal","Hamming","Euclidean","vectorDistanceMetricsMethods","q","pow","sqrt","stringDistanceMetricsMethods","Levenshtein","JaroWinkler","Manhattan","s1","s2","dist","Onehot","bitArrayDistanceMetricsMethods","diceSimilarity","asymmetricSimilarity","braunBlanquetSimilarity","cosineSimilarity","totalProd","kulczynskiSimilarity","mcConnaugheySimilarity","rogotGoldbergSimilarity","russelSimilarity","sokalSimilarity","intArrayDistanceMetricsMethods","TanimotoIntArray","numberDistanceMetricsMethods","Difference","range","numberArrayDistanceMetrics","CommonItems","mostCommon","Set","arr1","arr2","i1","i2","has","commonItemsCount","AvailableMetrics","Vector","MacroMolecule","Number","IntArray","NumberArray","val","ui","BYPASS_LARGE_DATA_WARNING","SHOW_SCATTERPLOT_PROGRESS","WEBGSLAGGREGATION","WEBGPUDISTANCE","MatrixMatrixOpType","MatrixOpType","MatrixScalarOpType","EUCLIDEAN","MANHATTAN","TANIMOTO","LEVENSTEIN","NEEDLEMAN_WUNSCH","SOKAL","COSINE","ASYMMETRIC","OneHot","DIMENSIONALITY_REDUCER_TERMINATE_EVENT","DistanceAggregationMethods","isNil","getEmbeddingViewerName","it","async","multiColReduceDimensionality","table","metrics","weights","preprocessingFunctions","aggregationMethod","plotEmbeddings","clusterEmbeddings","dimRedOptions","preprocessingFuncArgs","uiOptions","postProcessingFunc","postProcFuncArgs","scatterPlotProps","showXAxis","showYAxis","showXSelector","showYSelector","tv","tableView","addTableView","doReduce","pg","scatterPlotName","scatterPlot","embedColsNames","axes","colNameInd","names","includes","getEmbeddingColsNames","progressFunc","_nEpoch","epochsLength","embeddings","embedXCol","embedYCol","byName","float","rowCount","title","progress","toFixed","getDimRed","resolveF","sub","onViewerClosed","subscribe","viewer","getOptions","look","fireCustomEvent","unsubscribe","close","dimRedResPromise","encodedColEntries","pf","distanceFnArgs","colInputName","inputs","metricInputName","toList","dataCols","methodName","distanceMetrics","distanceAggregation","dimensionalityReduceRes","worker","Worker","URL","postMessage","columnsData","terminateSub","onCustomEvent","terminate","onmessage","embedding","epochNum","createMultiDimRedWorker","sumOfSquares","mean","stdDevInverse","normalize","getNormalizedEmbeddings","clusterPg","clusterRes","embedX","embedY","epsilon","minPts","clusters","getDbscanWorker","dbScanEpsilon","dbScanMinPts","clusterColName","getUnusedName","addNewString","props","colorColumnName","col1InputName","col2InputName","prepare","helpUrl","fastRowCount","onOK","onCancel","show","DEMOG_COLNAMES","SUBJ","STUDY","SITE","AGE","SEX","RACE","DISEASE","WEIGHT","HEIGHT","testDimensionalityReductionUI","demog","addedEmbeddingsCols","embedColName","isNone","isNaN","UMAP","allDemogCols","distFuncs","STRING","colNames","T_SNE","heapMap","typeMap","shiftMap","typeToColumnCreatorMap","Column","fromInt32Array","fromFloat32Array","Arg","complementArrOfParams","arrOfParams","complementArrOfTypes","arrOfTypes","allocateMemoryForBuffer","isMemoryForBufferAllocated","putDataToBuffer","getDataFromBuffer","freeBuffer","ArgColumn","targetType","toUpdate","super","buf","numOfRows","_malloc","BYTES_PER_ELEMENT","_free","ArgNewColumn","columnCreator","ArgColumns","numOfColumns","numOfBytes","numOfCols","colData","ArgNewColumns","Param","intColumn","column","newIntColumn","intColumns","newIntColumns","floatColumn","newFloatColumn","floatColumns","newFloatColumns","int","number","Return","tableFromColumns","argColumns","DataFrame","double","argColumn","funcName","funcSpecification","cppFuncInput","val1","val2","callResult","cFuncName","isEnoughOfMemoryAllocated","types","extendedTypeOfReturn","cppFuncWrapper","_callResult","output","arrayToReturn","NUM_TYPE","FLOAT_COLUMN_TYPE","INT_COLUMN_TYPE","FLOAT_COLUMNS_TYPE","NEW_FLOAT_COLUMNS_TYPE","INT_COLUMNS_TYPE","NEW_INT_COLUMNS_TYPE","NEW_FLOAT_COLUMN_TYPE","NEW_INT_COLUMN_TYPE","COLUMN","CALL_RESULT","NUM_OF_ROWS","NUM_OF_COLUMNS","REF","VALUE","TABLE_OF_COLUMNS","OBJECTS","INT_TYPE","DOUBLE_TYPE","argsSpecification","inputVals","ref","arrays","byIndex","dataFromWebWorker","funcSpecificationArgs","argsAfterWasmCall","extractNewlyCreatedData","outPut","typeToDataFieldMap","source","getOutput","clearNewlyCreatedData","COMP_MIN","MAX_ELEMENTS_COUNT","COMP_POSITVE_MES","COMP_EXCESS","DATAFRAME_IS_TOO_BIG_MES","UNSUPPORTED_COLUMN_TYPE_MES","checkColumnType","FLOAT","INT","checkMissingVals","missingValueCount","features","components","checkDimensionReducerInputs","WASM_OUTPUT_IDX","RESULT_NAMES","COMPONENTS","LINK","HINT","TITLE","ERROR_MSG","PLS_ANALYSIS","computePCA","center","scale","centerNum","scaleNum","componentsCount","EDA","_principalComponentAnalysisInWebWorker","RADIUS","COLOR","caption","MODEL","text","SCORES","LOADINGS","REGR_COEFS","EXPL_VAR","item","MVA","getPlsAnalysis","input","predict","prediction","PREDICTION","regressionCoefficients","REGR_COEFFS","tScores","T_SCORES","uScores","U_SCORES","xLoadings","X_LOADINGS","yLoadings","Y_LOADINGS","getLinearRegressionParams","targets","featuresCount","samplesCount","yAvg","avg","yStdev","stdev","nonConstFeatureColsIndeces","nonConstFeatureCols","nonConstFeatureAvgs","nonConstFeatureStdevs","nonConstFeaturesCount","tempParams","featureAvgs","featureStdDevs","targetsAvg","targetsStdDev","paramsCount","_fitLinearRegressionParamsWithDataNormalizing","paramsByPLS","getLinearRegressionParamsUsingPLS","tmpSum","getPredictionByLinearRegression","rawData","bias","weight","INTERACTIVITY","PlsModel","isApplicable","predictColumn","matches","isInteractive","MAX_FEATURES","MAX_SAMLPES","packedModel","specn","sizeArr","modelDfBytesCount","scoresDfBytesCount","modelBytes","SIZE_ARR_LEN","modelDf","fromByteArray","colsCount","scoresBytes","scores","SHIFT","featureNames","FEATURES","loadings","dim","message","fit","target","analysis","getRegrCoeffs","getLoadings","getScoresDf","computeExplVars","loadingsCols","regrCoefsCol","raw","explVar","comp","toBytes","XLOADING","modelDfBytes","toByteArray","scoresBytesCount","requiredBytes","loadingsParamsViewers","viewers","loadingsDf","xColumnName","yColumnName","markerType","CIRCLE","labels","help","barChart","splitColumnName","valueColumnName","valueAggrType","AVG","COEFFS","showValueSelector","showStackSelector","explVarsViewer","compNames","explVars","COMP","COMPS","EXPL_VARS","showCategorySelector","getScoresScatter","XSCORE","YSCORE","concat","scatter","showViewerFormulaLines","meta","formulaLines","addAll","lines","addLine","formula","radius","width","visible","color","xName","AXIS","yName","getLines","checkLen","regressionDataset","samples","dependent","randomWalk","cols","coefs","madError","mad","raw1","raw2","classificationDataset","useShift","accuracy","correctPredictions","COLS","ERROR","ROWS_K","madNorm","deviation","model","packed","AVGS_NAME","STDEVS_NAME","SoftmaxClassifier","specification","classesCount","avgs","stdevs","categories","bytesCount","avgsCol","stdevsCol","rate","penalty","tolerance","extractStats","rowsCount","cats","paramCols","iterCount","learningRate","paramsRows","paramsCols","_fitSoftmax","fitSoftmaxParams","normalized","X","transposed","preprocessedTargets","Y","oneHot","xBuf","wBuf","Z","argMax","predClass","exp","targetData","classesWeights","targetRaw","loss","DEFAULT","RESERVED","MISSING_VALUE","TITLES","XGBooster","SAMPLES_LOW","FEATURES_LOW","SAMLPES_MID","FEATURES_MID","SAMLPES_HIGH","FEATURES_HIGH","modelParams","targetCategories","offset","headerBytesSize","SIZE","headerDf","TYPE","modelParamsCount","PARAMS","categoriesBytesSize","CATS_SIZE","categoriesDf","CATS","ITERATIONS","eta","ETA","maxDepth","MAX_DEPTH","lambda","LAMBDA","alpha","ALPHA","missingValue","modelReserve","utilsLength","featuresRaw","fitInWebWorker","UTILS","floatHeap","XGBoostModule","HEAPF32","intHeap","HEAP32","featuresBuf","targetBuf","modelBuf","_predict","stringColPrediction","intColPrediction","BIG_INT","bigIntColPrediction","PREDICT","categoriesBytes","modelParamsBytesSize","headerBytes","reservedSize","PACK","maxCategory","round","rawInts","BigInt64Array","BigInt","fromBigInt64Array","_package","fromObjects"],"sourceRoot":""}
1
+ {"version":3,"file":"package-test.js","mappings":"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AG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,IAEjDmS,EAASmG,YAAc7kB,UAAUuM,KAAK,EACjC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC9C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,IAEjDmS,EAASqG,WAAa/kB,UAAUuM,KAAK,EAChC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC9C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7C,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAC7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","sources":["webpack://eda/./node_modules/@datagrok-libraries/math/src/dbscan/wasm/wasmDbscan.js","webpack://eda/./node_modules/fast-sha256/sha256.js","webpack://eda/./node_modules/jaro-winkler-typescript/lib/index.js","webpack://eda/webpack/bootstrap","webpack://eda/webpack/runtime/amd options","webpack://eda/webpack/runtime/define property getters","webpack://eda/webpack/runtime/get javascript chunk filename","webpack://eda/webpack/runtime/global","webpack://eda/webpack/runtime/harmony module decorator","webpack://eda/webpack/runtime/hasOwnProperty shorthand","webpack://eda/webpack/runtime/make namespace object","webpack://eda/webpack/runtime/publicPath","webpack://eda/webpack/runtime/jsonp chunk loading","webpack://eda/external var \"DG\"","webpack://eda/external var \"grok\"","webpack://eda/./node_modules/@datagrok-libraries/utils/src/dataframe-utils.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/test.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/types.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/typed-metrics/consts.js","webpack://eda/./node_modules/fastest-levenshtein/esm/mod.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/bit-array.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/hamming.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/needleman-wunsch.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/macromolecule-distance-functions.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/levenstein.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-metrics-methods.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/typed-metrics/typed-metrics.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/vector-operations.js","webpack://eda/external var \"ui\"","webpack://eda/./node_modules/@datagrok-libraries/ml/src/functionEditors/consts.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/dbscan/wasm/dbscan-worker-creator.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/multi-col-distances/webGPU-aggregation.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/multi-col-distances/webGPU-multicol-distances.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/types.js","webpack://eda/./node_modules/is-any-array/lib-esm/index.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/consts.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/types.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/utils.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/reduce-dimensionality.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/embeddings-space.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/multi-dim-red-worker-creator.js","webpack://eda/./src/tests/dim-reduction-tests.ts","webpack://eda/./wasm/callWasm.js","webpack://eda/./wasm/callWasmForWebWorker.js","webpack://eda/./src/utils.ts","webpack://eda/./src/pls/pls-constants.ts","webpack://eda/./src/eda-tools.ts","webpack://eda/./wasm/EDAAPI.js","webpack://eda/./src/pls/pls-tools.ts","webpack://eda/./src/regression.ts","webpack://eda/./src/pls/pls-ml.ts","webpack://eda/./src/tests/utils.ts","webpack://eda/./src/tests/linear-methods-tests.ts","webpack://eda/./src/softmax-classifier.ts","webpack://eda/./src/xgbooster.ts","webpack://eda/./wasm/xgbooster.js","webpack://eda/./src/tests/classifiers-tests.ts","webpack://eda/./src/missing-values-imputation/ui-constants.ts","webpack://eda/./src/missing-values-imputation/knn-imputer.ts","webpack://eda/./src/missing-values-imputation/ui.ts","webpack://eda/./src/tests/mis-vals-imputation-tests.ts","webpack://eda/./src/package-test.ts"],"sourcesContent":["\r\nexport var exportCppDbscanLib = (() => {\r\n var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;\r\n \r\n return (\r\nfunction(exportCppDbscanLib = {}) {\r\n\r\n// include: shell.js\r\n// The Module object: Our interface to the outside world. We import\r\n// and export values on it. There are various ways Module can be used:\r\n// 1. Not defined. We create it here\r\n// 2. A function parameter, function(Module) { ..generated code.. }\r\n// 3. pre-run appended it, var Module = {}; ..generated code..\r\n// 4. External script tag defines var Module.\r\n// We need to check if Module already exists (e.g. case 3 above).\r\n// Substitution will be replaced with actual code on later stage of the build,\r\n// this way Closure Compiler will not mangle it (e.g. case 4. above).\r\n// Note that if you want to run closure, and also to use Module\r\n// after the generated code, you will need to define var Module = {};\r\n// before the code. Then that object will be used in the code, and you\r\n// can continue to use Module afterwards as well.\r\nvar Module = typeof exportCppDbscanLib != 'undefined' ? exportCppDbscanLib : {};\r\n\r\n// Set up the promise that indicates the Module is initialized\r\nvar readyPromiseResolve, readyPromiseReject;\r\nModule['ready'] = new Promise(function(resolve, reject) {\r\n readyPromiseResolve = resolve;\r\n readyPromiseReject = reject;\r\n});\r\n\r\n// --pre-jses are emitted after the Module integration code, so that they can\r\n// refer to Module (if they choose; they can also define Module)\r\n\r\n\r\n// Sometimes an existing Module object exists with properties\r\n// meant to overwrite the default module functionality. Here\r\n// we collect those properties and reapply _after_ we configure\r\n// the current environment's defaults to avoid having to be so\r\n// defensive during initialization.\r\nvar moduleOverrides = Object.assign({}, Module);\r\n\r\nvar arguments_ = [];\r\nvar thisProgram = './this.program';\r\nvar quit_ = (status, toThrow) => {\r\n throw toThrow;\r\n};\r\n\r\n// Determine the runtime environment we are in. You can customize this by\r\n// setting the ENVIRONMENT setting at compile time (see settings.js).\r\n\r\n// Attempt to auto-detect the environment\r\nvar ENVIRONMENT_IS_WEB = typeof window == 'object';\r\nvar ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';\r\n// N.b. Electron.js environment is simultaneously a NODE-environment, but\r\n// also a web environment.\r\nvar ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';\r\nvar ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;\r\n\r\n// `/` should be present at the end if `scriptDirectory` is not empty\r\nvar scriptDirectory = '';\r\nfunction locateFile(path) {\r\n if (Module['locateFile']) {\r\n return Module['locateFile'](path, scriptDirectory);\r\n }\r\n return scriptDirectory + path;\r\n}\r\n\r\n// Hooks that are implemented differently in different runtime environments.\r\nvar read_,\r\n readAsync,\r\n readBinary,\r\n setWindowTitle;\r\n\r\n// Note that this includes Node.js workers when relevant (pthreads is enabled).\r\n// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and\r\n// ENVIRONMENT_IS_NODE.\r\nif (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {\r\n if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled\r\n scriptDirectory = self.location.href;\r\n } else if (typeof document != 'undefined' && document.currentScript) { // web\r\n scriptDirectory = document.currentScript.src;\r\n }\r\n // When MODULARIZE, this JS may be executed later, after document.currentScript\r\n // is gone, so we saved it, and we use it here instead of any other info.\r\n if (_scriptDir) {\r\n scriptDirectory = _scriptDir;\r\n }\r\n // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.\r\n // otherwise, slice off the final part of the url to find the script directory.\r\n // if scriptDirectory does not contain a slash, lastIndexOf will return -1,\r\n // and scriptDirectory will correctly be replaced with an empty string.\r\n // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),\r\n // they are removed because they could contain a slash.\r\n if (scriptDirectory.indexOf('blob:') !== 0) {\r\n scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, \"\").lastIndexOf('/')+1);\r\n } else {\r\n scriptDirectory = '';\r\n }\r\n\r\n // Differentiate the Web Worker from the Node Worker case, as reading must\r\n // be done differently.\r\n {\r\n// include: web_or_worker_shell_read.js\r\nread_ = (url) => {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('GET', url, false);\r\n xhr.send(null);\r\n return xhr.responseText;\r\n }\r\n\r\n if (ENVIRONMENT_IS_WORKER) {\r\n readBinary = (url) => {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('GET', url, false);\r\n xhr.responseType = 'arraybuffer';\r\n xhr.send(null);\r\n return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));\r\n };\r\n }\r\n\r\n readAsync = (url, onload, onerror) => {\r\n var xhr = new XMLHttpRequest();\r\n xhr.open('GET', url, true);\r\n xhr.responseType = 'arraybuffer';\r\n xhr.onload = () => {\r\n if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0\r\n onload(xhr.response);\r\n return;\r\n }\r\n onerror();\r\n };\r\n xhr.onerror = onerror;\r\n xhr.send(null);\r\n }\r\n\r\n// end include: web_or_worker_shell_read.js\r\n }\r\n\r\n setWindowTitle = (title) => document.title = title;\r\n} else\r\n{\r\n}\r\n\r\nvar out = Module['print'] || console.log.bind(console);\r\nvar err = Module['printErr'] || console.warn.bind(console);\r\n\r\n// Merge back in the overrides\r\nObject.assign(Module, moduleOverrides);\r\n// Free the object hierarchy contained in the overrides, this lets the GC\r\n// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.\r\nmoduleOverrides = null;\r\n\r\n// Emit code to handle expected values on the Module object. This applies Module.x\r\n// to the proper local x. This has two benefits: first, we only emit it if it is\r\n// expected to arrive, and second, by using a local everywhere else that can be\r\n// minified.\r\n\r\nif (Module['arguments']) arguments_ = Module['arguments'];\r\n\r\nif (Module['thisProgram']) thisProgram = Module['thisProgram'];\r\n\r\nif (Module['quit']) quit_ = Module['quit'];\r\n\r\n// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message\r\n\r\n\r\n// end include: shell.js\r\n// include: preamble.js\r\n// === Preamble library stuff ===\r\n\r\n// Documentation for the public APIs defined in this file must be updated in:\r\n// site/source/docs/api_reference/preamble.js.rst\r\n// A prebuilt local version of the documentation is available at:\r\n// site/build/text/docs/api_reference/preamble.js.txt\r\n// You can also build docs locally as HTML or other formats in site/\r\n// An online HTML version (which may be of a different version of Emscripten)\r\n// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html\r\n\r\nvar wasmBinary;\r\nif (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];\r\nvar noExitRuntime = Module['noExitRuntime'] || true;\r\n\r\nif (typeof WebAssembly != 'object') {\r\n abort('no native wasm support detected');\r\n}\r\n\r\n// Wasm globals\r\n\r\nvar wasmMemory;\r\n\r\n//========================================\r\n// Runtime essentials\r\n//========================================\r\n\r\n// whether we are quitting the application. no code should run after this.\r\n// set in exit() and abort()\r\nvar ABORT = false;\r\n\r\n// set by exit() and abort(). Passed to 'onExit' handler.\r\n// NOTE: This is also used as the process return code code in shell environments\r\n// but only when noExitRuntime is false.\r\nvar EXITSTATUS;\r\n\r\n/** @type {function(*, string=)} */\r\nfunction assert(condition, text) {\r\n if (!condition) {\r\n // This build was created without ASSERTIONS defined. `assert()` should not\r\n // ever be called in this configuration but in case there are callers in\r\n // the wild leave this simple abort() implemenation here for now.\r\n abort(text);\r\n }\r\n}\r\n\r\n// Memory management\r\n\r\nvar HEAP,\r\n/** @type {!Int8Array} */\r\n HEAP8,\r\n/** @type {!Uint8Array} */\r\n HEAPU8,\r\n/** @type {!Int16Array} */\r\n HEAP16,\r\n/** @type {!Uint16Array} */\r\n HEAPU16,\r\n/** @type {!Int32Array} */\r\n HEAP32,\r\n/** @type {!Uint32Array} */\r\n HEAPU32,\r\n/** @type {!Float32Array} */\r\n HEAPF32,\r\n/** @type {!Float64Array} */\r\n HEAPF64;\r\n\r\nfunction updateMemoryViews() {\r\n var b = wasmMemory.buffer;\r\n Module['HEAP8'] = HEAP8 = new Int8Array(b);\r\n Module['HEAP16'] = HEAP16 = new Int16Array(b);\r\n Module['HEAP32'] = HEAP32 = new Int32Array(b);\r\n Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);\r\n Module['HEAPU16'] = HEAPU16 = new Uint16Array(b);\r\n Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);\r\n Module['HEAPF32'] = HEAPF32 = new Float32Array(b);\r\n Module['HEAPF64'] = HEAPF64 = new Float64Array(b);\r\n}\r\n\r\n// include: runtime_init_table.js\r\n// In regular non-RELOCATABLE mode the table is exported\r\n// from the wasm module and this will be assigned once\r\n// the exports are available.\r\nvar wasmTable;\r\n\r\n// end include: runtime_init_table.js\r\n// include: runtime_stack_check.js\r\n// end include: runtime_stack_check.js\r\n// include: runtime_assertions.js\r\n// end include: runtime_assertions.js\r\nvar __ATPRERUN__ = []; // functions called before the runtime is initialized\r\nvar __ATINIT__ = []; // functions called during startup\r\nvar __ATEXIT__ = []; // functions called during shutdown\r\nvar __ATPOSTRUN__ = []; // functions called after the main() is called\r\n\r\nvar runtimeInitialized = false;\r\n\r\nvar runtimeKeepaliveCounter = 0;\r\n\r\nfunction keepRuntimeAlive() {\r\n return noExitRuntime || runtimeKeepaliveCounter > 0;\r\n}\r\n\r\nfunction preRun() {\r\n if (Module['preRun']) {\r\n if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];\r\n while (Module['preRun'].length) {\r\n addOnPreRun(Module['preRun'].shift());\r\n }\r\n }\r\n callRuntimeCallbacks(__ATPRERUN__);\r\n}\r\n\r\nfunction initRuntime() {\r\n runtimeInitialized = true;\r\n\r\n \r\n callRuntimeCallbacks(__ATINIT__);\r\n}\r\n\r\nfunction postRun() {\r\n\r\n if (Module['postRun']) {\r\n if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];\r\n while (Module['postRun'].length) {\r\n addOnPostRun(Module['postRun'].shift());\r\n }\r\n }\r\n\r\n callRuntimeCallbacks(__ATPOSTRUN__);\r\n}\r\n\r\nfunction addOnPreRun(cb) {\r\n __ATPRERUN__.unshift(cb);\r\n}\r\n\r\nfunction addOnInit(cb) {\r\n __ATINIT__.unshift(cb);\r\n}\r\n\r\nfunction addOnExit(cb) {\r\n}\r\n\r\nfunction addOnPostRun(cb) {\r\n __ATPOSTRUN__.unshift(cb);\r\n}\r\n\r\n// include: runtime_math.js\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul\r\n\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround\r\n\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32\r\n\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc\r\n\r\n// end include: runtime_math.js\r\n// A counter of dependencies for calling run(). If we need to\r\n// do asynchronous work before running, increment this and\r\n// decrement it. Incrementing must happen in a place like\r\n// Module.preRun (used by emcc to add file preloading).\r\n// Note that you can add dependencies in preRun, even though\r\n// it happens right before run - run will be postponed until\r\n// the dependencies are met.\r\nvar runDependencies = 0;\r\nvar runDependencyWatcher = null;\r\nvar dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled\r\n\r\nfunction getUniqueRunDependency(id) {\r\n return id;\r\n}\r\n\r\nfunction addRunDependency(id) {\r\n runDependencies++;\r\n\r\n if (Module['monitorRunDependencies']) {\r\n Module['monitorRunDependencies'](runDependencies);\r\n }\r\n\r\n}\r\n\r\nfunction removeRunDependency(id) {\r\n runDependencies--;\r\n\r\n if (Module['monitorRunDependencies']) {\r\n Module['monitorRunDependencies'](runDependencies);\r\n }\r\n\r\n if (runDependencies == 0) {\r\n if (runDependencyWatcher !== null) {\r\n clearInterval(runDependencyWatcher);\r\n runDependencyWatcher = null;\r\n }\r\n if (dependenciesFulfilled) {\r\n var callback = dependenciesFulfilled;\r\n dependenciesFulfilled = null;\r\n callback(); // can add another dependenciesFulfilled\r\n }\r\n }\r\n}\r\n\r\n/** @param {string|number=} what */\r\nfunction abort(what) {\r\n if (Module['onAbort']) {\r\n Module['onAbort'](what);\r\n }\r\n\r\n what = 'Aborted(' + what + ')';\r\n // TODO(sbc): Should we remove printing and leave it up to whoever\r\n // catches the exception?\r\n err(what);\r\n\r\n ABORT = true;\r\n EXITSTATUS = 1;\r\n\r\n what += '. Build with -sASSERTIONS for more info.';\r\n\r\n // Use a wasm runtime error, because a JS error might be seen as a foreign\r\n // exception, which means we'd run destructors on it. We need the error to\r\n // simply make the program stop.\r\n // FIXME This approach does not work in Wasm EH because it currently does not assume\r\n // all RuntimeErrors are from traps; it decides whether a RuntimeError is from\r\n // a trap or not based on a hidden field within the object. So at the moment\r\n // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that\r\n // allows this in the wasm spec.\r\n\r\n // Suppress closure compiler warning here. Closure compiler's builtin extern\r\n // defintion for WebAssembly.RuntimeError claims it takes no arguments even\r\n // though it can.\r\n // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.\r\n /** @suppress {checkTypes} */\r\n var e = new WebAssembly.RuntimeError(what);\r\n\r\n readyPromiseReject(e);\r\n // Throw the error whether or not MODULARIZE is set because abort is used\r\n // in code paths apart from instantiation where an exception is expected\r\n // to be thrown when abort is called.\r\n throw e;\r\n}\r\n\r\n// include: memoryprofiler.js\r\n// end include: memoryprofiler.js\r\n// include: URIUtils.js\r\n// Prefix of data URIs emitted by SINGLE_FILE and related options.\r\nvar dataURIPrefix = 'data:application/octet-stream;base64,';\r\n\r\n// Indicates whether filename is a base64 data URI.\r\nfunction isDataURI(filename) {\r\n // Prefix of data URIs emitted by SINGLE_FILE and related options.\r\n return filename.startsWith(dataURIPrefix);\r\n}\r\n\r\n// Indicates whether filename is delivered via file protocol (as opposed to http/https)\r\nfunction isFileURI(filename) {\r\n return filename.startsWith('file://');\r\n}\r\n\r\n// end include: URIUtils.js\r\n// include: runtime_exceptions.js\r\n// end include: runtime_exceptions.js\r\nvar wasmBinaryFile;\r\n wasmBinaryFile = 'wasmDbscan.wasm';\r\n if (!isDataURI(wasmBinaryFile)) {\r\n wasmBinaryFile = locateFile(wasmBinaryFile);\r\n }\r\n\r\nfunction getBinary(file) {\r\n try {\r\n if (file == wasmBinaryFile && wasmBinary) {\r\n return new Uint8Array(wasmBinary);\r\n }\r\n if (readBinary) {\r\n return readBinary(file);\r\n }\r\n throw \"both async and sync fetching of the wasm failed\";\r\n }\r\n catch (err) {\r\n abort(err);\r\n }\r\n}\r\n\r\nfunction getBinaryPromise(binaryFile) {\r\n // If we don't have the binary yet, try to load it asynchronously.\r\n // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.\r\n // See https://github.com/github/fetch/pull/92#issuecomment-140665932\r\n // Cordova or Electron apps are typically loaded from a file:// url.\r\n // So use fetch if it is available and the url is not a file, otherwise fall back to XHR.\r\n if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {\r\n if (typeof fetch == 'function'\r\n ) {\r\n return fetch(binaryFile, { credentials: 'same-origin' }).then(function(response) {\r\n if (!response['ok']) {\r\n throw \"failed to load wasm binary file at '\" + binaryFile + \"'\";\r\n }\r\n return response['arrayBuffer']();\r\n }).catch(function () {\r\n return getBinary(binaryFile);\r\n });\r\n }\r\n }\r\n\r\n // Otherwise, getBinary should be able to get it synchronously\r\n return Promise.resolve().then(function() { return getBinary(binaryFile); });\r\n}\r\n\r\nfunction instantiateArrayBuffer(binaryFile, imports, receiver) {\r\n return getBinaryPromise(binaryFile).then(function(binary) {\r\n return WebAssembly.instantiate(binary, imports);\r\n }).then(function (instance) {\r\n return instance;\r\n }).then(receiver, function(reason) {\r\n err('failed to asynchronously prepare wasm: ' + reason);\r\n\r\n abort(reason);\r\n });\r\n}\r\n\r\nfunction instantiateAsync(binary, binaryFile, imports, callback) {\r\n if (!binary &&\r\n typeof WebAssembly.instantiateStreaming == 'function' &&\r\n !isDataURI(binaryFile) &&\r\n typeof fetch == 'function') {\r\n return fetch(binaryFile, { credentials: 'same-origin' }).then(function(response) {\r\n // Suppress closure warning here since the upstream definition for\r\n // instantiateStreaming only allows Promise<Repsponse> rather than\r\n // an actual Response.\r\n // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.\r\n /** @suppress {checkTypes} */\r\n var result = WebAssembly.instantiateStreaming(response, imports);\r\n\r\n return result.then(\r\n callback,\r\n function(reason) {\r\n // We expect the most common failure cause to be a bad MIME type for the binary,\r\n // in which case falling back to ArrayBuffer instantiation should work.\r\n err('wasm streaming compile failed: ' + reason);\r\n err('falling back to ArrayBuffer instantiation');\r\n return instantiateArrayBuffer(binaryFile, imports, callback);\r\n });\r\n });\r\n } else {\r\n return instantiateArrayBuffer(binaryFile, imports, callback);\r\n }\r\n}\r\n\r\n// Create the wasm instance.\r\n// Receives the wasm imports, returns the exports.\r\nfunction createWasm() {\r\n // prepare imports\r\n var info = {\r\n 'env': wasmImports,\r\n 'wasi_snapshot_preview1': wasmImports,\r\n };\r\n // Load the wasm module and create an instance of using native support in the JS engine.\r\n // handle a generated wasm instance, receiving its exports and\r\n // performing other necessary setup\r\n /** @param {WebAssembly.Module=} module*/\r\n function receiveInstance(instance, module) {\r\n var exports = instance.exports;\r\n\r\n Module['asm'] = exports;\r\n\r\n wasmMemory = Module['asm']['memory'];\r\n updateMemoryViews();\r\n\r\n wasmTable = Module['asm']['__indirect_function_table'];\r\n\r\n addOnInit(Module['asm']['__wasm_call_ctors']);\r\n\r\n removeRunDependency('wasm-instantiate');\r\n\r\n return exports;\r\n }\r\n // wait for the pthread pool (if any)\r\n addRunDependency('wasm-instantiate');\r\n\r\n // Prefer streaming instantiation if available.\r\n function receiveInstantiationResult(result) {\r\n // 'result' is a ResultObject object which has both the module and instance.\r\n // receiveInstance() will swap in the exports (to Module.asm) so they can be called\r\n // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.\r\n // When the regression is fixed, can restore the above PTHREADS-enabled path.\r\n receiveInstance(result['instance']);\r\n }\r\n\r\n // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback\r\n // to manually instantiate the Wasm module themselves. This allows pages to\r\n // run the instantiation parallel to any other async startup actions they are\r\n // performing.\r\n // Also pthreads and wasm workers initialize the wasm instance through this\r\n // path.\r\n if (Module['instantiateWasm']) {\r\n\r\n try {\r\n return Module['instantiateWasm'](info, receiveInstance);\r\n } catch(e) {\r\n err('Module.instantiateWasm callback failed with error: ' + e);\r\n // If instantiation fails, reject the module ready promise.\r\n readyPromiseReject(e);\r\n }\r\n }\r\n\r\n // If instantiation fails, reject the module ready promise.\r\n instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult).catch(readyPromiseReject);\r\n return {}; // no exports yet; we'll fill them in later\r\n}\r\n\r\n// Globals used by JS i64 conversions (see makeSetValue)\r\nvar tempDouble;\r\nvar tempI64;\r\n\r\n// include: runtime_debug.js\r\n// end include: runtime_debug.js\r\n// === Body ===\r\n\r\n\r\n// end include: preamble.js\r\n\r\n /** @constructor */\r\n function ExitStatus(status) {\r\n this.name = 'ExitStatus';\r\n this.message = 'Program terminated with exit(' + status + ')';\r\n this.status = status;\r\n }\r\n\r\n function callRuntimeCallbacks(callbacks) {\r\n while (callbacks.length > 0) {\r\n // Pass the module as the first argument.\r\n callbacks.shift()(Module);\r\n }\r\n }\r\n\r\n \r\n /**\r\n * @param {number} ptr\r\n * @param {string} type\r\n */\r\n function getValue(ptr, type = 'i8') {\r\n if (type.endsWith('*')) type = '*';\r\n switch (type) {\r\n case 'i1': return HEAP8[((ptr)>>0)];\r\n case 'i8': return HEAP8[((ptr)>>0)];\r\n case 'i16': return HEAP16[((ptr)>>1)];\r\n case 'i32': return HEAP32[((ptr)>>2)];\r\n case 'i64': return HEAP32[((ptr)>>2)];\r\n case 'float': return HEAPF32[((ptr)>>2)];\r\n case 'double': return HEAPF64[((ptr)>>3)];\r\n case '*': return HEAPU32[((ptr)>>2)];\r\n default: abort('invalid type for getValue: ' + type);\r\n }\r\n }\r\n\r\n \r\n /**\r\n * @param {number} ptr\r\n * @param {number} value\r\n * @param {string} type\r\n */\r\n function setValue(ptr, value, type = 'i8') {\r\n if (type.endsWith('*')) type = '*';\r\n switch (type) {\r\n case 'i1': HEAP8[((ptr)>>0)] = value; break;\r\n case 'i8': HEAP8[((ptr)>>0)] = value; break;\r\n case 'i16': HEAP16[((ptr)>>1)] = value; break;\r\n case 'i32': HEAP32[((ptr)>>2)] = value; break;\r\n case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break;\r\n case 'float': HEAPF32[((ptr)>>2)] = value; break;\r\n case 'double': HEAPF64[((ptr)>>3)] = value; break;\r\n case '*': HEAPU32[((ptr)>>2)] = value; break;\r\n default: abort('invalid type for setValue: ' + type);\r\n }\r\n }\r\n\r\n /** @constructor */\r\n function ExceptionInfo(excPtr) {\r\n this.excPtr = excPtr;\r\n this.ptr = excPtr - 24;\r\n \r\n this.set_type = function(type) {\r\n HEAPU32[(((this.ptr)+(4))>>2)] = type;\r\n };\r\n \r\n this.get_type = function() {\r\n return HEAPU32[(((this.ptr)+(4))>>2)];\r\n };\r\n \r\n this.set_destructor = function(destructor) {\r\n HEAPU32[(((this.ptr)+(8))>>2)] = destructor;\r\n };\r\n \r\n this.get_destructor = function() {\r\n return HEAPU32[(((this.ptr)+(8))>>2)];\r\n };\r\n \r\n this.set_caught = function (caught) {\r\n caught = caught ? 1 : 0;\r\n HEAP8[(((this.ptr)+(12))>>0)] = caught;\r\n };\r\n \r\n this.get_caught = function () {\r\n return HEAP8[(((this.ptr)+(12))>>0)] != 0;\r\n };\r\n \r\n this.set_rethrown = function (rethrown) {\r\n rethrown = rethrown ? 1 : 0;\r\n HEAP8[(((this.ptr)+(13))>>0)] = rethrown;\r\n };\r\n \r\n this.get_rethrown = function () {\r\n return HEAP8[(((this.ptr)+(13))>>0)] != 0;\r\n };\r\n \r\n // Initialize native structure fields. Should be called once after allocated.\r\n this.init = function(type, destructor) {\r\n this.set_adjusted_ptr(0);\r\n this.set_type(type);\r\n this.set_destructor(destructor);\r\n }\r\n \r\n this.set_adjusted_ptr = function(adjustedPtr) {\r\n HEAPU32[(((this.ptr)+(16))>>2)] = adjustedPtr;\r\n };\r\n \r\n this.get_adjusted_ptr = function() {\r\n return HEAPU32[(((this.ptr)+(16))>>2)];\r\n };\r\n \r\n // Get pointer which is expected to be received by catch clause in C++ code. It may be adjusted\r\n // when the pointer is casted to some of the exception object base classes (e.g. when virtual\r\n // inheritance is used). When a pointer is thrown this method should return the thrown pointer\r\n // itself.\r\n this.get_exception_ptr = function() {\r\n // Work around a fastcomp bug, this code is still included for some reason in a build without\r\n // exceptions support.\r\n var isPointer = ___cxa_is_pointer_type(this.get_type());\r\n if (isPointer) {\r\n return HEAPU32[((this.excPtr)>>2)];\r\n }\r\n var adjusted = this.get_adjusted_ptr();\r\n if (adjusted !== 0) return adjusted;\r\n return this.excPtr;\r\n };\r\n }\r\n \r\n var exceptionLast = 0;\r\n \r\n var uncaughtExceptionCount = 0;\r\n function ___cxa_throw(ptr, type, destructor) {\r\n var info = new ExceptionInfo(ptr);\r\n // Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception.\r\n info.init(type, destructor);\r\n exceptionLast = ptr;\r\n uncaughtExceptionCount++;\r\n throw exceptionLast;\r\n }\r\n\r\n function _abort() {\r\n abort('');\r\n }\r\n\r\n function _emscripten_memcpy_big(dest, src, num) {\r\n HEAPU8.copyWithin(dest, src, src + num);\r\n }\r\n\r\n function getHeapMax() {\r\n // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate\r\n // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side\r\n // for any code that deals with heap sizes, which would require special\r\n // casing all heap size related code to treat 0 specially.\r\n return 2147483648;\r\n }\r\n \r\n function emscripten_realloc_buffer(size) {\r\n var b = wasmMemory.buffer;\r\n try {\r\n // round size grow request up to wasm page size (fixed 64KB per spec)\r\n wasmMemory.grow((size - b.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size\r\n updateMemoryViews();\r\n return 1 /*success*/;\r\n } catch(e) {\r\n }\r\n // implicit 0 return to save code size (caller will cast \"undefined\" into 0\r\n // anyhow)\r\n }\r\n function _emscripten_resize_heap(requestedSize) {\r\n var oldSize = HEAPU8.length;\r\n requestedSize = requestedSize >>> 0;\r\n // With multithreaded builds, races can happen (another thread might increase the size\r\n // in between), so return a failure, and let the caller retry.\r\n \r\n // Memory resize rules:\r\n // 1. Always increase heap size to at least the requested size, rounded up\r\n // to next page multiple.\r\n // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap\r\n // geometrically: increase the heap size according to\r\n // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most\r\n // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).\r\n // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap\r\n // linearly: increase the heap size by at least\r\n // MEMORY_GROWTH_LINEAR_STEP bytes.\r\n // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by\r\n // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest\r\n // 4. If we were unable to allocate as much memory, it may be due to\r\n // over-eager decision to excessively reserve due to (3) above.\r\n // Hence if an allocation fails, cut down on the amount of excess\r\n // growth, in an attempt to succeed to perform a smaller allocation.\r\n \r\n // A limit is set for how much we can grow. We should not exceed that\r\n // (the wasm binary specifies it, so if we tried, we'd fail anyhow).\r\n var maxHeapSize = getHeapMax();\r\n if (requestedSize > maxHeapSize) {\r\n return false;\r\n }\r\n \r\n let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple;\r\n \r\n // Loop through potential heap size increases. If we attempt a too eager\r\n // reservation that fails, cut down on the attempted size and reserve a\r\n // smaller bump instead. (max 3 times, chosen somewhat arbitrarily)\r\n for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {\r\n var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth\r\n // but limit overreserving (default to capping at +96MB overgrowth at most)\r\n overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 );\r\n \r\n var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536));\r\n \r\n var replacement = emscripten_realloc_buffer(newSize);\r\n if (replacement) {\r\n \r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n function getCFunc(ident) {\r\n var func = Module['_' + ident]; // closure exported function\r\n return func;\r\n }\r\n \r\n \r\n function writeArrayToMemory(array, buffer) {\r\n HEAP8.set(array, buffer);\r\n }\r\n \r\n function lengthBytesUTF8(str) {\r\n var len = 0;\r\n for (var i = 0; i < str.length; ++i) {\r\n // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code\r\n // unit, not a Unicode code point of the character! So decode\r\n // UTF16->UTF32->UTF8.\r\n // See http://unicode.org/faq/utf_bom.html#utf16-3\r\n var c = str.charCodeAt(i); // possibly a lead surrogate\r\n if (c <= 0x7F) {\r\n len++;\r\n } else if (c <= 0x7FF) {\r\n len += 2;\r\n } else if (c >= 0xD800 && c <= 0xDFFF) {\r\n len += 4; ++i;\r\n } else {\r\n len += 3;\r\n }\r\n }\r\n return len;\r\n }\r\n \r\n function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {\r\n // Parameter maxBytesToWrite is not optional. Negative values, 0, null,\r\n // undefined and false each don't write out any bytes.\r\n if (!(maxBytesToWrite > 0))\r\n return 0;\r\n \r\n var startIdx = outIdx;\r\n var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.\r\n for (var i = 0; i < str.length; ++i) {\r\n // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code\r\n // unit, not a Unicode code point of the character! So decode\r\n // UTF16->UTF32->UTF8.\r\n // See http://unicode.org/faq/utf_bom.html#utf16-3\r\n // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description\r\n // and https://www.ietf.org/rfc/rfc2279.txt\r\n // and https://tools.ietf.org/html/rfc3629\r\n var u = str.charCodeAt(i); // possibly a lead surrogate\r\n if (u >= 0xD800 && u <= 0xDFFF) {\r\n var u1 = str.charCodeAt(++i);\r\n u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);\r\n }\r\n if (u <= 0x7F) {\r\n if (outIdx >= endIdx) break;\r\n heap[outIdx++] = u;\r\n } else if (u <= 0x7FF) {\r\n if (outIdx + 1 >= endIdx) break;\r\n heap[outIdx++] = 0xC0 | (u >> 6);\r\n heap[outIdx++] = 0x80 | (u & 63);\r\n } else if (u <= 0xFFFF) {\r\n if (outIdx + 2 >= endIdx) break;\r\n heap[outIdx++] = 0xE0 | (u >> 12);\r\n heap[outIdx++] = 0x80 | ((u >> 6) & 63);\r\n heap[outIdx++] = 0x80 | (u & 63);\r\n } else {\r\n if (outIdx + 3 >= endIdx) break;\r\n heap[outIdx++] = 0xF0 | (u >> 18);\r\n heap[outIdx++] = 0x80 | ((u >> 12) & 63);\r\n heap[outIdx++] = 0x80 | ((u >> 6) & 63);\r\n heap[outIdx++] = 0x80 | (u & 63);\r\n }\r\n }\r\n // Null-terminate the pointer to the buffer.\r\n heap[outIdx] = 0;\r\n return outIdx - startIdx;\r\n }\r\n function stringToUTF8(str, outPtr, maxBytesToWrite) {\r\n return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);\r\n }\r\n function stringToUTF8OnStack(str) {\r\n var size = lengthBytesUTF8(str) + 1;\r\n var ret = stackAlloc(size);\r\n stringToUTF8(str, ret, size);\r\n return ret;\r\n }\r\n \r\n var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;\r\n \r\n /**\r\n * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given\r\n * array that contains uint8 values, returns a copy of that string as a\r\n * Javascript String object.\r\n * heapOrArray is either a regular array, or a JavaScript typed array view.\r\n * @param {number} idx\r\n * @param {number=} maxBytesToRead\r\n * @return {string}\r\n */\r\n function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) {\r\n var endIdx = idx + maxBytesToRead;\r\n var endPtr = idx;\r\n // TextDecoder needs to know the byte length in advance, it doesn't stop on\r\n // null terminator by itself. Also, use the length info to avoid running tiny\r\n // strings through TextDecoder, since .subarray() allocates garbage.\r\n // (As a tiny code save trick, compare endPtr against endIdx using a negation,\r\n // so that undefined means Infinity)\r\n while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;\r\n \r\n if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {\r\n return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));\r\n }\r\n var str = '';\r\n // If building with TextDecoder, we have already computed the string length\r\n // above, so test loop end condition against that\r\n while (idx < endPtr) {\r\n // For UTF8 byte structure, see:\r\n // http://en.wikipedia.org/wiki/UTF-8#Description\r\n // https://www.ietf.org/rfc/rfc2279.txt\r\n // https://tools.ietf.org/html/rfc3629\r\n var u0 = heapOrArray[idx++];\r\n if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }\r\n var u1 = heapOrArray[idx++] & 63;\r\n if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }\r\n var u2 = heapOrArray[idx++] & 63;\r\n if ((u0 & 0xF0) == 0xE0) {\r\n u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;\r\n } else {\r\n u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);\r\n }\r\n \r\n if (u0 < 0x10000) {\r\n str += String.fromCharCode(u0);\r\n } else {\r\n var ch = u0 - 0x10000;\r\n str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));\r\n }\r\n }\r\n return str;\r\n }\r\n \r\n \r\n /**\r\n * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the\r\n * emscripten HEAP, returns a copy of that string as a Javascript String object.\r\n *\r\n * @param {number} ptr\r\n * @param {number=} maxBytesToRead - An optional length that specifies the\r\n * maximum number of bytes to read. You can omit this parameter to scan the\r\n * string until the first \u0000 byte. If maxBytesToRead is passed, and the string\r\n * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the\r\n * string will cut short at that byte index (i.e. maxBytesToRead will not\r\n * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing\r\n * frequent uses of UTF8ToString() with and without maxBytesToRead may throw\r\n * JS JIT optimizations off, so it is worth to consider consistently using one\r\n * @return {string}\r\n */\r\n function UTF8ToString(ptr, maxBytesToRead) {\r\n return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';\r\n }\r\n \r\n /**\r\n * @param {string|null=} returnType\r\n * @param {Array=} argTypes\r\n * @param {Arguments|Array=} args\r\n * @param {Object=} opts\r\n */\r\n function ccall(ident, returnType, argTypes, args, opts) {\r\n // For fast lookup of conversion functions\r\n var toC = {\r\n 'string': (str) => {\r\n var ret = 0;\r\n if (str !== null && str !== undefined && str !== 0) { // null string\r\n // at most 4 bytes per UTF-8 code point, +1 for the trailing '\\0'\r\n ret = stringToUTF8OnStack(str);\r\n }\r\n return ret;\r\n },\r\n 'array': (arr) => {\r\n var ret = stackAlloc(arr.length);\r\n writeArrayToMemory(arr, ret);\r\n return ret;\r\n }\r\n };\r\n \r\n function convertReturnValue(ret) {\r\n if (returnType === 'string') {\r\n \r\n return UTF8ToString(ret);\r\n }\r\n if (returnType === 'boolean') return Boolean(ret);\r\n return ret;\r\n }\r\n \r\n var func = getCFunc(ident);\r\n var cArgs = [];\r\n var stack = 0;\r\n if (args) {\r\n for (var i = 0; i < args.length; i++) {\r\n var converter = toC[argTypes[i]];\r\n if (converter) {\r\n if (stack === 0) stack = stackSave();\r\n cArgs[i] = converter(args[i]);\r\n } else {\r\n cArgs[i] = args[i];\r\n }\r\n }\r\n }\r\n var ret = func.apply(null, cArgs);\r\n function onDone(ret) {\r\n if (stack !== 0) stackRestore(stack);\r\n return convertReturnValue(ret);\r\n }\r\n \r\n ret = onDone(ret);\r\n return ret;\r\n }\r\n \r\n /**\r\n * @param {string=} returnType\r\n * @param {Array=} argTypes\r\n * @param {Object=} opts\r\n */\r\n function cwrap(ident, returnType, argTypes, opts) {\r\n // When the function takes numbers and returns a number, we can just return\r\n // the original function\r\n var numericArgs = !argTypes || argTypes.every((type) => type === 'number' || type === 'boolean');\r\n var numericRet = returnType !== 'string';\r\n if (numericRet && numericArgs && !opts) {\r\n return getCFunc(ident);\r\n }\r\n return function() {\r\n return ccall(ident, returnType, argTypes, arguments, opts);\r\n }\r\n }\r\n\r\nvar wasmImports = {\r\n \"__cxa_throw\": ___cxa_throw,\r\n \"abort\": _abort,\r\n \"emscripten_memcpy_big\": _emscripten_memcpy_big,\r\n \"emscripten_resize_heap\": _emscripten_resize_heap\r\n};\r\nvar asm = createWasm();\r\n/** @type {function(...*):?} */\r\nvar ___wasm_call_ctors = function() {\r\n return (___wasm_call_ctors = Module[\"asm\"][\"__wasm_call_ctors\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar _dbscan = Module[\"_dbscan\"] = function() {\r\n return (_dbscan = Module[\"_dbscan\"] = Module[\"asm\"][\"dbscan\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar ___errno_location = function() {\r\n return (___errno_location = Module[\"asm\"][\"__errno_location\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar _malloc = Module[\"_malloc\"] = function() {\r\n return (_malloc = Module[\"_malloc\"] = Module[\"asm\"][\"malloc\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar _free = Module[\"_free\"] = function() {\r\n return (_free = Module[\"_free\"] = Module[\"asm\"][\"free\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar stackSave = function() {\r\n return (stackSave = Module[\"asm\"][\"stackSave\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar stackRestore = function() {\r\n return (stackRestore = Module[\"asm\"][\"stackRestore\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar stackAlloc = function() {\r\n return (stackAlloc = Module[\"asm\"][\"stackAlloc\"]).apply(null, arguments);\r\n};\r\n\r\n/** @type {function(...*):?} */\r\nvar ___cxa_is_pointer_type = function() {\r\n return (___cxa_is_pointer_type = Module[\"asm\"][\"__cxa_is_pointer_type\"]).apply(null, arguments);\r\n};\r\n\r\n\r\n\r\n// include: postamble.js\r\n// === Auto-generated postamble setup entry stuff ===\r\n\r\nModule[\"ccall\"] = ccall;\r\nModule[\"cwrap\"] = cwrap;\r\n\r\n\r\nvar calledRun;\r\n\r\ndependenciesFulfilled = function runCaller() {\r\n // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)\r\n if (!calledRun) run();\r\n if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled\r\n};\r\n\r\nfunction run() {\r\n\r\n if (runDependencies > 0) {\r\n return;\r\n }\r\n\r\n preRun();\r\n\r\n // a preRun added a dependency, run will be called later\r\n if (runDependencies > 0) {\r\n return;\r\n }\r\n\r\n function doRun() {\r\n // run may have just been called through dependencies being fulfilled just in this very frame,\r\n // or while the async setStatus time below was happening\r\n if (calledRun) return;\r\n calledRun = true;\r\n Module['calledRun'] = true;\r\n\r\n if (ABORT) return;\r\n\r\n initRuntime();\r\n\r\n readyPromiseResolve(Module);\r\n if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();\r\n\r\n postRun();\r\n }\r\n\r\n if (Module['setStatus']) {\r\n Module['setStatus']('Running...');\r\n setTimeout(function() {\r\n setTimeout(function() {\r\n Module['setStatus']('');\r\n }, 1);\r\n doRun();\r\n }, 1);\r\n } else\r\n {\r\n doRun();\r\n }\r\n}\r\n\r\nif (Module['preInit']) {\r\n if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];\r\n while (Module['preInit'].length > 0) {\r\n Module['preInit'].pop()();\r\n }\r\n}\r\n\r\nrun();\r\n\r\n\r\n// end include: postamble.js\r\n\r\n\r\n return exportCppDbscanLib.ready\r\n}\r\n\r\n);\r\n})();\r\nif (typeof exports === 'object' && typeof module === 'object')\r\n module.exports = exportCppDbscanLib;\r\nelse if (typeof define === 'function' && define['amd'])\r\n define([], function() { return exportCppDbscanLib; });\r\nelse if (typeof exports === 'object')\r\n exports[\"exportCppDbscanLib\"] = exportCppDbscanLib;\r\n","(function (root, factory) {\n // Hack to make all exports of this module sha256 function object properties.\n var exports = {};\n factory(exports);\n var sha256 = exports[\"default\"];\n for (var k in exports) {\n sha256[k] = exports[k];\n }\n \n if (typeof module === 'object' && typeof module.exports === 'object') {\n module.exports = sha256;\n } else if (typeof define === 'function' && define.amd) {\n define(function() { return sha256; }); \n } else {\n root.sha256 = sha256;\n }\n})(this, function(exports) {\n\"use strict\";\nexports.__esModule = true;\n// SHA-256 (+ HMAC and PBKDF2) for JavaScript.\n//\n// Written in 2014-2016 by Dmitry Chestnykh.\n// Public domain, no warranty.\n//\n// Functions (accept and return Uint8Arrays):\n//\n// sha256(message) -> hash\n// sha256.hmac(key, message) -> mac\n// sha256.pbkdf2(password, salt, rounds, dkLen) -> dk\n//\n// Classes:\n//\n// new sha256.Hash()\n// new sha256.HMAC(key)\n//\nexports.digestLength = 32;\nexports.blockSize = 64;\n// SHA-256 constants\nvar K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,\n 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,\n 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,\n 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,\n 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,\n 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,\n 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,\n 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,\n 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\nfunction hashBlocks(w, v, p, pos, len) {\n var a, b, c, d, e, f, g, h, u, i, j, t1, t2;\n while (len >= 64) {\n a = v[0];\n b = v[1];\n c = v[2];\n d = v[3];\n e = v[4];\n f = v[5];\n g = v[6];\n h = v[7];\n for (i = 0; i < 16; i++) {\n j = pos + i * 4;\n w[i] = (((p[j] & 0xff) << 24) | ((p[j + 1] & 0xff) << 16) |\n ((p[j + 2] & 0xff) << 8) | (p[j + 3] & 0xff));\n }\n for (i = 16; i < 64; i++) {\n u = w[i - 2];\n t1 = (u >>> 17 | u << (32 - 17)) ^ (u >>> 19 | u << (32 - 19)) ^ (u >>> 10);\n u = w[i - 15];\n t2 = (u >>> 7 | u << (32 - 7)) ^ (u >>> 18 | u << (32 - 18)) ^ (u >>> 3);\n w[i] = (t1 + w[i - 7] | 0) + (t2 + w[i - 16] | 0);\n }\n for (i = 0; i < 64; i++) {\n t1 = (((((e >>> 6 | e << (32 - 6)) ^ (e >>> 11 | e << (32 - 11)) ^\n (e >>> 25 | e << (32 - 25))) + ((e & f) ^ (~e & g))) | 0) +\n ((h + ((K[i] + w[i]) | 0)) | 0)) | 0;\n t2 = (((a >>> 2 | a << (32 - 2)) ^ (a >>> 13 | a << (32 - 13)) ^\n (a >>> 22 | a << (32 - 22))) + ((a & b) ^ (a & c) ^ (b & c))) | 0;\n h = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n v[0] += a;\n v[1] += b;\n v[2] += c;\n v[3] += d;\n v[4] += e;\n v[5] += f;\n v[6] += g;\n v[7] += h;\n pos += 64;\n len -= 64;\n }\n return pos;\n}\n// Hash implements SHA256 hash algorithm.\nvar Hash = /** @class */ (function () {\n function Hash() {\n this.digestLength = exports.digestLength;\n this.blockSize = exports.blockSize;\n // Note: Int32Array is used instead of Uint32Array for performance reasons.\n this.state = new Int32Array(8); // hash state\n this.temp = new Int32Array(64); // temporary state\n this.buffer = new Uint8Array(128); // buffer for data to hash\n this.bufferLength = 0; // number of bytes in buffer\n this.bytesHashed = 0; // number of total bytes hashed\n this.finished = false; // indicates whether the hash was finalized\n this.reset();\n }\n // Resets hash state making it possible\n // to re-use this instance to hash other data.\n Hash.prototype.reset = function () {\n this.state[0] = 0x6a09e667;\n this.state[1] = 0xbb67ae85;\n this.state[2] = 0x3c6ef372;\n this.state[3] = 0xa54ff53a;\n this.state[4] = 0x510e527f;\n this.state[5] = 0x9b05688c;\n this.state[6] = 0x1f83d9ab;\n this.state[7] = 0x5be0cd19;\n this.bufferLength = 0;\n this.bytesHashed = 0;\n this.finished = false;\n return this;\n };\n // Cleans internal buffers and re-initializes hash state.\n Hash.prototype.clean = function () {\n for (var i = 0; i < this.buffer.length; i++) {\n this.buffer[i] = 0;\n }\n for (var i = 0; i < this.temp.length; i++) {\n this.temp[i] = 0;\n }\n this.reset();\n };\n // Updates hash state with the given data.\n //\n // Optionally, length of the data can be specified to hash\n // fewer bytes than data.length.\n //\n // Throws error when trying to update already finalized hash:\n // instance must be reset to use it again.\n Hash.prototype.update = function (data, dataLength) {\n if (dataLength === void 0) { dataLength = data.length; }\n if (this.finished) {\n throw new Error(\"SHA256: can't update because hash was finished.\");\n }\n var dataPos = 0;\n this.bytesHashed += dataLength;\n if (this.bufferLength > 0) {\n while (this.bufferLength < 64 && dataLength > 0) {\n this.buffer[this.bufferLength++] = data[dataPos++];\n dataLength--;\n }\n if (this.bufferLength === 64) {\n hashBlocks(this.temp, this.state, this.buffer, 0, 64);\n this.bufferLength = 0;\n }\n }\n if (dataLength >= 64) {\n dataPos = hashBlocks(this.temp, this.state, data, dataPos, dataLength);\n dataLength %= 64;\n }\n while (dataLength > 0) {\n this.buffer[this.bufferLength++] = data[dataPos++];\n dataLength--;\n }\n return this;\n };\n // Finalizes hash state and puts hash into out.\n //\n // If hash was already finalized, puts the same value.\n Hash.prototype.finish = function (out) {\n if (!this.finished) {\n var bytesHashed = this.bytesHashed;\n var left = this.bufferLength;\n var bitLenHi = (bytesHashed / 0x20000000) | 0;\n var bitLenLo = bytesHashed << 3;\n var padLength = (bytesHashed % 64 < 56) ? 64 : 128;\n this.buffer[left] = 0x80;\n for (var i = left + 1; i < padLength - 8; i++) {\n this.buffer[i] = 0;\n }\n this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff;\n this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff;\n this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff;\n this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff;\n this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff;\n this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff;\n this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff;\n this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff;\n hashBlocks(this.temp, this.state, this.buffer, 0, padLength);\n this.finished = true;\n }\n for (var i = 0; i < 8; i++) {\n out[i * 4 + 0] = (this.state[i] >>> 24) & 0xff;\n out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff;\n out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff;\n out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff;\n }\n return this;\n };\n // Returns the final hash digest.\n Hash.prototype.digest = function () {\n var out = new Uint8Array(this.digestLength);\n this.finish(out);\n return out;\n };\n // Internal function for use in HMAC for optimization.\n Hash.prototype._saveState = function (out) {\n for (var i = 0; i < this.state.length; i++) {\n out[i] = this.state[i];\n }\n };\n // Internal function for use in HMAC for optimization.\n Hash.prototype._restoreState = function (from, bytesHashed) {\n for (var i = 0; i < this.state.length; i++) {\n this.state[i] = from[i];\n }\n this.bytesHashed = bytesHashed;\n this.finished = false;\n this.bufferLength = 0;\n };\n return Hash;\n}());\nexports.Hash = Hash;\n// HMAC implements HMAC-SHA256 message authentication algorithm.\nvar HMAC = /** @class */ (function () {\n function HMAC(key) {\n this.inner = new Hash();\n this.outer = new Hash();\n this.blockSize = this.inner.blockSize;\n this.digestLength = this.inner.digestLength;\n var pad = new Uint8Array(this.blockSize);\n if (key.length > this.blockSize) {\n (new Hash()).update(key).finish(pad).clean();\n }\n else {\n for (var i = 0; i < key.length; i++) {\n pad[i] = key[i];\n }\n }\n for (var i = 0; i < pad.length; i++) {\n pad[i] ^= 0x36;\n }\n this.inner.update(pad);\n for (var i = 0; i < pad.length; i++) {\n pad[i] ^= 0x36 ^ 0x5c;\n }\n this.outer.update(pad);\n this.istate = new Uint32Array(8);\n this.ostate = new Uint32Array(8);\n this.inner._saveState(this.istate);\n this.outer._saveState(this.ostate);\n for (var i = 0; i < pad.length; i++) {\n pad[i] = 0;\n }\n }\n // Returns HMAC state to the state initialized with key\n // to make it possible to run HMAC over the other data with the same\n // key without creating a new instance.\n HMAC.prototype.reset = function () {\n this.inner._restoreState(this.istate, this.inner.blockSize);\n this.outer._restoreState(this.ostate, this.outer.blockSize);\n return this;\n };\n // Cleans HMAC state.\n HMAC.prototype.clean = function () {\n for (var i = 0; i < this.istate.length; i++) {\n this.ostate[i] = this.istate[i] = 0;\n }\n this.inner.clean();\n this.outer.clean();\n };\n // Updates state with provided data.\n HMAC.prototype.update = function (data) {\n this.inner.update(data);\n return this;\n };\n // Finalizes HMAC and puts the result in out.\n HMAC.prototype.finish = function (out) {\n if (this.outer.finished) {\n this.outer.finish(out);\n }\n else {\n this.inner.finish(out);\n this.outer.update(out, this.digestLength).finish(out);\n }\n return this;\n };\n // Returns message authentication code.\n HMAC.prototype.digest = function () {\n var out = new Uint8Array(this.digestLength);\n this.finish(out);\n return out;\n };\n return HMAC;\n}());\nexports.HMAC = HMAC;\n// Returns SHA256 hash of data.\nfunction hash(data) {\n var h = (new Hash()).update(data);\n var digest = h.digest();\n h.clean();\n return digest;\n}\nexports.hash = hash;\n// Function hash is both available as module.hash and as default export.\nexports[\"default\"] = hash;\n// Returns HMAC-SHA256 of data under the key.\nfunction hmac(key, data) {\n var h = (new HMAC(key)).update(data);\n var digest = h.digest();\n h.clean();\n return digest;\n}\nexports.hmac = hmac;\n// Fills hkdf buffer like this:\n// T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)\nfunction fillBuffer(buffer, hmac, info, counter) {\n // Counter is a byte value: check if it overflowed.\n var num = counter[0];\n if (num === 0) {\n throw new Error(\"hkdf: cannot expand more\");\n }\n // Prepare HMAC instance for new data with old key.\n hmac.reset();\n // Hash in previous output if it was generated\n // (i.e. counter is greater than 1).\n if (num > 1) {\n hmac.update(buffer);\n }\n // Hash in info if it exists.\n if (info) {\n hmac.update(info);\n }\n // Hash in the counter.\n hmac.update(counter);\n // Output result to buffer and clean HMAC instance.\n hmac.finish(buffer);\n // Increment counter inside typed array, this works properly.\n counter[0]++;\n}\nvar hkdfSalt = new Uint8Array(exports.digestLength); // Filled with zeroes.\nfunction hkdf(key, salt, info, length) {\n if (salt === void 0) { salt = hkdfSalt; }\n if (length === void 0) { length = 32; }\n var counter = new Uint8Array([1]);\n // HKDF-Extract uses salt as HMAC key, and key as data.\n var okm = hmac(salt, key);\n // Initialize HMAC for expanding with extracted key.\n // Ensure no collisions with `hmac` function.\n var hmac_ = new HMAC(okm);\n // Allocate buffer.\n var buffer = new Uint8Array(hmac_.digestLength);\n var bufpos = buffer.length;\n var out = new Uint8Array(length);\n for (var i = 0; i < length; i++) {\n if (bufpos === buffer.length) {\n fillBuffer(buffer, hmac_, info, counter);\n bufpos = 0;\n }\n out[i] = buffer[bufpos++];\n }\n hmac_.clean();\n buffer.fill(0);\n counter.fill(0);\n return out;\n}\nexports.hkdf = hkdf;\n// Derives a key from password and salt using PBKDF2-HMAC-SHA256\n// with the given number of iterations.\n//\n// The number of bytes returned is equal to dkLen.\n//\n// (For better security, avoid dkLen greater than hash length - 32 bytes).\nfunction pbkdf2(password, salt, iterations, dkLen) {\n var prf = new HMAC(password);\n var len = prf.digestLength;\n var ctr = new Uint8Array(4);\n var t = new Uint8Array(len);\n var u = new Uint8Array(len);\n var dk = new Uint8Array(dkLen);\n for (var i = 0; i * len < dkLen; i++) {\n var c = i + 1;\n ctr[0] = (c >>> 24) & 0xff;\n ctr[1] = (c >>> 16) & 0xff;\n ctr[2] = (c >>> 8) & 0xff;\n ctr[3] = (c >>> 0) & 0xff;\n prf.reset();\n prf.update(salt);\n prf.update(ctr);\n prf.finish(u);\n for (var j = 0; j < len; j++) {\n t[j] = u[j];\n }\n for (var j = 2; j <= iterations; j++) {\n prf.reset();\n prf.update(u).finish(u);\n for (var k = 0; k < len; k++) {\n t[k] ^= u[k];\n }\n }\n for (var j = 0; j < len && i * len + j < dkLen; j++) {\n dk[i * len + j] = t[j];\n }\n }\n for (var i = 0; i < len; i++) {\n t[i] = u[i] = 0;\n }\n for (var i = 0; i < 4; i++) {\n ctr[i] = 0;\n }\n prf.clean();\n return dk;\n}\nexports.pbkdf2 = pbkdf2;\n});\n","\"use strict\";\n// Reference: https://www.geeksforgeeks.org/jaro-and-jaro-winkler-similarity/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.jaroWinkler = exports.jaro = void 0;\n/**\n *\n * @param str1 String 1 for compare\n * @param str2 String 2 for compare\n * @param options to control case sensitive or not\n */\nfunction jaro(str1, str2, options) {\n // Exit early if either are empty.\n if (str1.length === 0 || str2.length === 0) {\n return 0;\n }\n // Convert to upper if case-sensitive is false.\n if (options && !options.caseSensitive) {\n str1 = str1.toUpperCase();\n str2 = str2.toUpperCase();\n }\n // Exact match\n if (str1 === str2) {\n return 1;\n }\n // Number of matches\n var m = 0;\n // Length of two Strings\n var len1 = str1.length;\n var len2 = str2.length;\n // Maximum distance\n var window = Math.floor(Math.max(len1, len2) / 2) - 1;\n // Hash for matches\n var str1Hash = new Array(len1);\n var str2Hash = new Array(len2);\n for (var i = 0; i < len1; i++) {\n for (var j = Math.max(0, i - window); j <= Math.min(len2, i + window + 1); j++) {\n if (!str1Hash[i] && !str2Hash[j] && str1[i] === str2[j]) {\n ++m;\n str1Hash[i] = str2Hash[j] = true;\n break;\n }\n }\n }\n // Exit early if no matches were found.\n if (m === 0) {\n return 0;\n }\n // Count the transpositions.\n var t = 0;\n var point = 0;\n for (var i = 0; i < len1; i++) {\n if (str1Hash[i]) {\n while (!str2Hash[point]) {\n point++;\n }\n if (str1.charAt(i) !== str2.charAt(point++)) {\n t++;\n }\n }\n }\n t /= 2;\n return (m / len1 + m / len2 + (m - t) / m) / 3;\n}\nexports.jaro = jaro;\n/**\n *\n * @param str1 String 1 for compare\n * @param str2 String 2 for compare\n * @param options to control case sensitive or not\n */\nfunction jaroWinkler(str1, str2, options) {\n // Jaro Distance\n var jaroDist = jaro(str1, str2, options);\n // Same prefix length, maxium is 4\n var prefix = 0;\n if (jaroDist > 0.7) {\n var minIndex = Math.min(str1.length, str2.length);\n var i = 0;\n while (str1[i] === str2[i] && i < 4 && i < minIndex) {\n ++prefix;\n i++;\n }\n jaroDist += 0.1 * prefix * (1 - jaroDist);\n }\n return jaroDist;\n}\nexports.jaroWinkler = jaroWinkler;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdO = {};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","// This function allow to reference async chunks\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.hmd = (module) => {\n\tmodule = Object.create(module);\n\tif (!module.children) module.children = [];\n\tObject.defineProperty(module, 'exports', {\n\t\tenumerable: true,\n\t\tset: () => {\n\t\t\tthrow new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);\n\t\t}\n\t});\n\treturn module;\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t255: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n// no on chunks loaded\n\n// no jsonp function","const __WEBPACK_NAMESPACE_OBJECT__ = DG;","const __WEBPACK_NAMESPACE_OBJECT__ = grok;","/* eslint-disable max-len */\nimport * as DG from 'datagrok-api/dg';\nimport * as sha256 from 'fast-sha256';\n/**\n * For columns of string type. Checks whether column contains empty values and removes corresponding rows in case user selects to remove.\n *\n */\nexport function removeEmptyStringRows(table, col) {\n const cats = col.categories;\n const emptyRawInd = cats.map((val, ind) => !val ? ind : null).filter((it) => it !== null);\n const rawData = [...col.getRawData()];\n const emptyRawsIndexes = [];\n let removedRowsCounter = 0;\n for (let i = 0; i < table.rowCount; i++) {\n if (emptyRawInd.includes(rawData[i])) {\n table.rows.removeAt(i - removedRowsCounter);\n emptyRawsIndexes.push(i);\n removedRowsCounter += 1;\n }\n }\n return emptyRawsIndexes;\n}\nexport function hashDataFrame(table, names) {\n names !== null && names !== void 0 ? names : (names = table.columns.names());\n const hasher = new sha256.Hash();\n const order = table.getSortedOrder(names);\n const encoder = new TextEncoder();\n for (const name of names) {\n const column = table.columns.byName(name);\n const dataArray = column.getRawData();\n const isString = column.type == DG.TYPE.STRING;\n const cats = column.categories;\n for (let i = 0; i < dataArray.length; i++) {\n if (isString) {\n const data = cats[dataArray[order[i]]];\n hasher.update(encoder.encode(data));\n }\n else {\n const data = dataArray[order[i]];\n hasher.update(Uint8Array.from([data]));\n }\n }\n }\n return hasher.digest();\n}\nexport const testData = DG.DataFrame.fromCsv(`countries,fasta,smiles,molregno,LON,Zip Code,Street Address Line 1,ImageUrl,user_id,error_message,xray,flag,magnitude,CS-id,pdb_id,accel_a,time_offset,chart,fit,Questions,empty_number,empty_string\nBelgium,MSNFHNEHVMQFYRNNLKTKGVFGRQ,CC(C(=O)OCCCc1cccnc1)c2cccc(c2)C(=O)c3ccccc3,1480014,36.276729583740234,995042300,14016 ROUTE 31W,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,1,1,1QBS,1,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.497360340644872, 1.7058694986686864, 5.278052678195135, 0.16000320889028383],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":2.374499797821045},{\"\"x\"\":0.6000000238418579,\"\"y\"\":2.6242473125457764},{\"\"x\"\":1.100000023841858,\"\"y\"\":2.367267608642578},{\"\"x\"\":1.600000023841858,\"\"y\"\":2.6723148822784424},{\"\"x\"\":2.0999999046325684,\"\"y\"\":2.6537344455718994},{\"\"x\"\":2.5999999046325684,\"\"y\"\":2.3651671409606934},{\"\"x\"\":3.0999999046325684,\"\"y\"\":2.5654284954071045},{\"\"x\"\":3.5999999046325684,\"\"y\"\":2.4160959720611572},{\"\"x\"\":4.099999904632568,\"\"y\"\":2.286726713180542},{\"\"x\"\":4.599999904632568,\"\"y\"\":2.5100042819976807},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.6676985025405884},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.680136501789093},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.3391543924808502},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.09038983285427094},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.19802775979042053}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[7.525235855508179, 1.3186911876809984, 5.335672608564294, 0.7860743343958098],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":7.988070487976074},{\"\"x\"\":0.6000000238418579,\"\"y\"\":7.018453121185303},{\"\"x\"\":1.100000023841858,\"\"y\"\":8.115279197692871},{\"\"x\"\":1.600000023841858,\"\"y\"\":7.486658096313477},{\"\"x\"\":2.0999999046325684,\"\"y\"\":7.396438121795654},{\"\"x\"\":2.5999999046325684,\"\"y\"\":7.477052211761475},{\"\"x\"\":3.0999999046325684,\"\"y\"\":6.913095474243164},{\"\"x\"\":3.5999999046325684,\"\"y\"\":8.01385498046875},{\"\"x\"\":4.099999904632568,\"\"y\"\":6.985900402069092},{\"\"x\"\":4.599999904632568,\"\"y\"\":6.970335960388184},{\"\"x\"\":5.099999904632568,\"\"y\"\":5.448817253112793},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.5534818172454834},{\"\"x\"\":6.099999904632568,\"\"y\"\":1.893947958946228},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.6340042352676392},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.8403874039649963}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,100,abc\nBurundi,MDYKETLLMPKTDFPMRGGLPNKEPQIQEKW,COc1ccc2cc(ccc2c1)C(C)C(=O)Oc3ccc(C)cc3OC,1480015,36.276729583740234,995073444,80 STATE HIGHWAY 310,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,2,2,1ZP8,2,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[4.431460753103398, 2.1691498799246745, 5.266445597102774, 0.7825762827017926],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":4.751083850860596},{\"\"x\"\":0.6000000238418579,\"\"y\"\":4.203000068664551},{\"\"x\"\":1.100000023841858,\"\"y\"\":4.415858745574951},{\"\"x\"\":1.600000023841858,\"\"y\"\":4.68414306640625},{\"\"x\"\":2.0999999046325684,\"\"y\"\":4.198400974273682},{\"\"x\"\":2.5999999046325684,\"\"y\"\":4.179222106933594},{\"\"x\"\":3.0999999046325684,\"\"y\"\":4.638473987579346},{\"\"x\"\":3.5999999046325684,\"\"y\"\":4.708553314208984},{\"\"x\"\":4.099999904632568,\"\"y\"\":4.291589260101318},{\"\"x\"\":4.599999904632568,\"\"y\"\":4.038082599639893},{\"\"x\"\":5.099999904632568,\"\"y\"\":3.4349939823150635},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.2194708585739136},{\"\"x\"\":6.099999904632568,\"\"y\"\":1.1920831203460693},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.5352635979652405},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.3346920311450958}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.339458017970126, -1.0734184310171178, 4.746332950550934, 0.2482416857595658],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.2139337658882141},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.4269562065601349},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.2441573292016983},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.146635964512825},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.08818462491035461},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.2560656666755676},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.42434045672416687},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.37111231684684753},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.5581737160682678},{\"\"x\"\":4.599999904632568,\"\"y\"\":1.183590054512024},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.5629843473434448},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.3211288452148438},{\"\"x\"\":6.099999904632568,\"\"y\"\":2.229961633682251},{\"\"x\"\":6.599999904632568,\"\"y\"\":2.2560226917266846},{\"\"x\"\":7.099999904632568,\"\"y\"\":2.2142398357391357}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nCameroon,MIEVFLFGIVLGLIPITLAGLFVTAYLQYRRGDQLDL,COc1ccc2cc(ccc2c1)C(C)C(=O)OCCCc3cccnc3,1480016,36.26095962524414,995153596,30-56 WHITESTONE EXPY,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,3,3,2BDJ,3,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[4.6760652578642325, 0.9046956320756703, 5.651408971856738, 0.07738846012184185],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":4.32425594329834},{\"\"x\"\":0.6000000238418579,\"\"y\"\":4.668442249298096},{\"\"x\"\":1.100000023841858,\"\"y\"\":4.379785060882568},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.0345139503479},{\"\"x\"\":2.0999999046325684,\"\"y\"\":4.878653526306152},{\"\"x\"\":2.5999999046325684,\"\"y\"\":4.3451313972473145},{\"\"x\"\":3.0999999046325684,\"\"y\"\":4.336992263793945},{\"\"x\"\":3.5999999046325684,\"\"y\"\":5.037430286407471},{\"\"x\"\":4.099999904632568,\"\"y\"\":5.0092692375183105},{\"\"x\"\":4.599999904632568,\"\"y\"\":4.151902675628662},{\"\"x\"\":5.099999904632568,\"\"y\"\":3.4066951274871826},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.3732759952545166},{\"\"x\"\":6.099999904632568,\"\"y\"\":1.673728108406067},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.48574790358543396},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.2783052325248718}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.938395863010111, -1.4658480661392117, 5.462702751996584, 0.3473139023615039],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.4941710829734802},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.15323974192142487},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.46373432874679565},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.3370431363582611},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.5179030299186707},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.27899765968322754},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.22075064480304718},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.5789918899536133},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.21169911324977875},{\"\"x\"\":4.599999904632568,\"\"y\"\":0.27857646346092224},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.0906332731246948},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.8520300388336182},{\"\"x\"\":6.099999904632568,\"\"y\"\":2.7177059650421143},{\"\"x\"\":6.599999904632568,\"\"y\"\":2.8680918216705322},{\"\"x\"\":7.099999904632568,\"\"y\"\":3.2413077354431152}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nCanada,MMELVLKTIIGPIVVGVVLRIVDKWLNKDK,CC(C(=O)NCCS)c1cccc(c1)C(=O)c2ccccc2,1480017,36.26095962524414,99515,30-56 WHITESTONE EXPY,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,4,4,1IAN,4,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[0.8597390975430008, 1.0957625732481946, 5.260537067987958, 0.07974187998177736],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.8190152645111084},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.8421689867973328},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.8740922212600708},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.8924275040626526},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.8249067664146423},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.9327669143676758},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.8522974252700806},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.8174492716789246},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.8394647240638733},{\"\"x\"\":4.599999904632568,\"\"y\"\":0.7139387726783752},{\"\"x\"\":5.099999904632568,\"\"y\"\":0.5561167597770691},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.3276226818561554},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.12479474395513535},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.13006797432899475},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.059702079743146896}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[5.760930219582546, 1.6591793293833013, 4.667155929720851, 0.7858109544121652],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":6.156993389129639},{\"\"x\"\":0.6000000238418579,\"\"y\"\":5.236701965332031},{\"\"x\"\":1.100000023841858,\"\"y\"\":6.010560512542725},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.495512962341309},{\"\"x\"\":2.0999999046325684,\"\"y\"\":6.087770462036133},{\"\"x\"\":2.5999999046325684,\"\"y\"\":5.79986572265625},{\"\"x\"\":3.0999999046325684,\"\"y\"\":5.597546577453613},{\"\"x\"\":3.5999999046325684,\"\"y\"\":5.520902156829834},{\"\"x\"\":4.099999904632568,\"\"y\"\":5.360654354095459},{\"\"x\"\":4.599999904632568,\"\"y\"\":3.5539746284484863},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.577236294746399},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.0001264810562134},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.9305797815322876},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.6033638715744019},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.4203685522079468}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nColombia,MDRTDEVSNHTHDKPTLTWFEEIFEEYHSPFHN,FC(F)(F)c1ccc(OC2CCNCC2)cc1,1480029,36.3309440612793,995152050,1 COURT HOUSE SQUARE,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,5,5,4UJ1,5,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[6.4995088314153655, 2.4270351004539914, 5.178659535348579, 0.625653346241577],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":6.496231555938721},{\"\"x\"\":0.6000000238418579,\"\"y\"\":6.42543363571167},{\"\"x\"\":1.100000023841858,\"\"y\"\":7.040063858032227},{\"\"x\"\":1.600000023841858,\"\"y\"\":6.1115403175354},{\"\"x\"\":2.0999999046325684,\"\"y\"\":6.680728435516357},{\"\"x\"\":2.5999999046325684,\"\"y\"\":6.406774520874023},{\"\"x\"\":3.0999999046325684,\"\"y\"\":6.611269474029541},{\"\"x\"\":3.5999999046325684,\"\"y\"\":5.889094352722168},{\"\"x\"\":4.099999904632568,\"\"y\"\":6.75344705581665},{\"\"x\"\":4.599999904632568,\"\"y\"\":6.361435890197754},{\"\"x\"\":5.099999904632568,\"\"y\"\":4.1666975021362305},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.172118902206421},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.801048994064331},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.4640021026134491},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.0010357667924836278}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[1.4734381347446401, 1.1649805188074196, 4.82958608866421, 0.09500545496710007],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":1.5279096364974976},{\"\"x\"\":0.6000000238418579,\"\"y\"\":1.3559974431991577},{\"\"x\"\":1.100000023841858,\"\"y\"\":1.5246378183364868},{\"\"x\"\":1.600000023841858,\"\"y\"\":1.5567657947540283},{\"\"x\"\":2.0999999046325684,\"\"y\"\":1.4114240407943726},{\"\"x\"\":2.5999999046325684,\"\"y\"\":1.4045010805130005},{\"\"x\"\":3.0999999046325684,\"\"y\"\":1.4769829511642456},{\"\"x\"\":3.5999999046325684,\"\"y\"\":1.4875500202178955},{\"\"x\"\":4.099999904632568,\"\"y\"\":1.2991987466812134},{\"\"x\"\":4.599999904632568,\"\"y\"\":0.922961413860321},{\"\"x\"\":5.099999904632568,\"\"y\"\":0.6520044803619385},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.15350978076457977},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.1078903079032898},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.17276449501514435},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.14066608250141144}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nCosta Rica,MKSTKEEIQTIKTLLKDSRTAKYHKRLQIVL,CC(C)Cc1ccc(cc1)C(C)C(=O)N2CCCC2C(=O)OCCCc3ccccc3,1480018,36.3309440612793,995084218,4041 SOUTHWESTERN BLVD,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,6,6,2BPW,6,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.4833641843311227, -1.8945978742090062, 4.671127708092568, 0.24159861311815153],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.0969524160027504},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.028483040630817413},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.22087176144123077},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.0068915546871721745},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.4305879771709442},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.44774115085601807},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.45346319675445557},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.2370593100786209},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.4657953977584839},{\"\"x\"\":4.599999904632568,\"\"y\"\":1.155200719833374},{\"\"x\"\":5.099999904632568,\"\"y\"\":2.2294070720672607},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.4311530590057373},{\"\"x\"\":6.099999904632568,\"\"y\"\":2.33846116065979},{\"\"x\"\":6.599999904632568,\"\"y\"\":2.608201026916504},{\"\"x\"\":7.099999904632568,\"\"y\"\":2.8136143684387207}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[5.224573521642033, 1.4454033924198528, 5.6014197746076535, 0.2823216054197577],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":4.95027494430542},{\"\"x\"\":0.6000000238418579,\"\"y\"\":5.1754679679870605},{\"\"x\"\":1.100000023841858,\"\"y\"\":5.276752948760986},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.589294910430908},{\"\"x\"\":2.0999999046325684,\"\"y\"\":5.616994857788086},{\"\"x\"\":2.5999999046325684,\"\"y\"\":5.120813846588135},{\"\"x\"\":3.0999999046325684,\"\"y\"\":5.340766906738281},{\"\"x\"\":3.5999999046325684,\"\"y\"\":4.876471042633057},{\"\"x\"\":4.099999904632568,\"\"y\"\":4.94999361038208},{\"\"x\"\":4.599999904632568,\"\"y\"\":5.162564754486084},{\"\"x\"\":5.099999904632568,\"\"y\"\":4.399557590484619},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.7977969646453857},{\"\"x\"\":6.099999904632568,\"\"y\"\":1.0229872465133667},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.48275601863861084},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.10408931970596313}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nCuba,MHAILRYFIRRLFYHIFYKIYSLISKKHQSLPSDVRQF,COc1ccc2c(c1)c(CC(=O)N3CCCC3C(=O)Oc4ccc(C)cc4OC)c(C)n2C(=O)c5ccc(Cl)cc5,1480019,36.33115768432617,995081928,1227 US HIGHWAY 11,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,7,7,1QBS,7,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[3.320838679713925, -1.2421619987316728, 4.831325425225256, 0.3236011098403072],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":0.3727470338344574},{\"\"x\"\":0.6000000238418579,\"\"y\"\":0.12365014106035233},{\"\"x\"\":1.100000023841858,\"\"y\"\":0.48422467708587646},{\"\"x\"\":1.600000023841858,\"\"y\"\":0.2264465093612671},{\"\"x\"\":2.0999999046325684,\"\"y\"\":0.16821794211864471},{\"\"x\"\":2.5999999046325684,\"\"y\"\":0.3879014551639557},{\"\"x\"\":3.0999999046325684,\"\"y\"\":0.5470244884490967},{\"\"x\"\":3.5999999046325684,\"\"y\"\":0.3419053554534912},{\"\"x\"\":4.099999904632568,\"\"y\"\":0.7655120491981506},{\"\"x\"\":4.599999904632568,\"\"y\"\":1.2346516847610474},{\"\"x\"\":5.099999904632568,\"\"y\"\":2.453336715698242},{\"\"x\"\":5.599999904632568,\"\"y\"\":2.9565491676330566},{\"\"x\"\":6.099999904632568,\"\"y\"\":3.335299491882324},{\"\"x\"\":6.599999904632568,\"\"y\"\":3.240290880203247},{\"\"x\"\":7.099999904632568,\"\"y\"\":3.1107218265533447}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[3.6401853521511094, 1.26211588875013, 5.399028074402744, 0.5089580830068091],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":3.8585598468780518},{\"\"x\"\":0.6000000238418579,\"\"y\"\":3.6077206134796143},{\"\"x\"\":1.100000023841858,\"\"y\"\":3.855252265930176},{\"\"x\"\":1.600000023841858,\"\"y\"\":3.619039297103882},{\"\"x\"\":2.0999999046325684,\"\"y\"\":3.839388370513916},{\"\"x\"\":2.5999999046325684,\"\"y\"\":3.335283041000366},{\"\"x\"\":3.0999999046325684,\"\"y\"\":3.571141481399536},{\"\"x\"\":3.5999999046325684,\"\"y\"\":3.4155046939849854},{\"\"x\"\":4.099999904632568,\"\"y\"\":3.7316646575927734},{\"\"x\"\":4.599999904632568,\"\"y\"\":3.0680155754089355},{\"\"x\"\":5.099999904632568,\"\"y\"\":2.891066551208496},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.6022753715515137},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.7652576565742493},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.6875326037406921},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.5828871726989746}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nItaly,MSNFHNEHVMQFYRNNLKTKGVFGRQ,CC(C)Cc1ccc(cc1)C(C)C(=O)N2CCCC2C(=O)OCCO[N+](=O)[O-],1480020,36.33115768432617,99502,\"168-46 91ST AVE., 2ND FLR\",https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,8,8,1ZP8,8,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[2.293592105923809, 1.3781586549141835, 5.1025898038676605, 0.03493851245291291],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":2.1287283897399902},{\"\"x\"\":0.6000000238418579,\"\"y\"\":2.267972230911255},{\"\"x\"\":1.100000023841858,\"\"y\"\":2.398442506790161},{\"\"x\"\":1.600000023841858,\"\"y\"\":2.5130622386932373},{\"\"x\"\":2.0999999046325684,\"\"y\"\":2.3255116939544678},{\"\"x\"\":2.5999999046325684,\"\"y\"\":2.127340793609619},{\"\"x\"\":3.0999999046325684,\"\"y\"\":2.47259783744812},{\"\"x\"\":3.5999999046325684,\"\"y\"\":2.131181478500366},{\"\"x\"\":4.099999904632568,\"\"y\"\":2.090421438217163},{\"\"x\"\":4.599999904632568,\"\"y\"\":2.02299165725708},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.1105059385299683},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.4494485855102539},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.1375635862350464},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.036351121962070465},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.1619771122932434}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[5.953125499439879, 1.2528620255306528, 5.187637440149802, 0.3110348753260886],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":5.6585283279418945},{\"\"x\"\":0.6000000238418579,\"\"y\"\":5.911152362823486},{\"\"x\"\":1.100000023841858,\"\"y\"\":5.924920082092285},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.8469438552856445},{\"\"x\"\":2.0999999046325684,\"\"y\"\":5.929472923278809},{\"\"x\"\":2.5999999046325684,\"\"y\"\":6.190037727355957},{\"\"x\"\":3.0999999046325684,\"\"y\"\":6.236179828643799},{\"\"x\"\":3.5999999046325684,\"\"y\"\":6.141019344329834},{\"\"x\"\":4.099999904632568,\"\"y\"\":5.295210838317871},{\"\"x\"\":4.599999904632568,\"\"y\"\":5.265801906585693},{\"\"x\"\":5.099999904632568,\"\"y\"\":3.3722851276397705},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.8299226760864258},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.32690900564193726},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.6274543404579163},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.8441857099533081}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nRwanda,MPNSEPASLLELFNSIATQGELVRSLKAGNASK,CC(C)Cc1ccc(cc1)C(C)C(=O)N2CCCC2C(=O)OCCO,1480021,36.33137130737305,995037247,\"168-46 91ST AVE., 2ND FLR\",https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,9,9,2BDJ,9,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[3.8209972202654474, 1.3779216716448506, 5.299882228439686, 0.06040645519069608],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":3.7821109294891357},{\"\"x\"\":0.6000000238418579,\"\"y\"\":3.542433023452759},{\"\"x\"\":1.100000023841858,\"\"y\"\":3.7008674144744873},{\"\"x\"\":1.600000023841858,\"\"y\"\":3.717301607131958},{\"\"x\"\":2.0999999046325684,\"\"y\"\":4.024452209472656},{\"\"x\"\":2.5999999046325684,\"\"y\"\":4.013899326324463},{\"\"x\"\":3.0999999046325684,\"\"y\"\":3.945094347000122},{\"\"x\"\":3.5999999046325684,\"\"y\"\":3.866621971130371},{\"\"x\"\":4.099999904632568,\"\"y\"\":3.7461626529693604},{\"\"x\"\":4.599999904632568,\"\"y\"\":3.3454740047454834},{\"\"x\"\":5.099999904632568,\"\"y\"\":2.61944317817688},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.999405026435852},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.46259793639183044},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.054134611040353775},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.05711187422275543}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[5.6318079657726035, 1.8495493770000595, 5.391793312471116, 0.17060707587348442],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":5.458079814910889},{\"\"x\"\":0.6000000238418579,\"\"y\"\":5.554427146911621},{\"\"x\"\":1.100000023841858,\"\"y\"\":5.799983024597168},{\"\"x\"\":1.600000023841858,\"\"y\"\":5.364140033721924},{\"\"x\"\":2.0999999046325684,\"\"y\"\":5.864485740661621},{\"\"x\"\":2.5999999046325684,\"\"y\"\":5.4509806632995605},{\"\"x\"\":3.0999999046325684,\"\"y\"\":5.702574729919434},{\"\"x\"\":3.5999999046325684,\"\"y\"\":5.7314534187316895},{\"\"x\"\":4.099999904632568,\"\"y\"\":5.5123443603515625},{\"\"x\"\":4.599999904632568,\"\"y\"\":5.724395751953125},{\"\"x\"\":5.099999904632568,\"\"y\"\":4.354506969451904},{\"\"x\"\":5.599999904632568,\"\"y\"\":1.7307666540145874},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.6305936574935913},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.035183437168598175},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.7575169205665588}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\nSwitzerland,IRVVGRYLIEVWKAAGMDMDKVLFLWSSDEI,CN1CCC(CC1)Oc2ccc(cc2)C(F)(F)F,1480028,36.33137130737305,99504,92-11 179TH PLACE,https://datagrok.ai/img/slides/access-db-connect.png,id,ErrorMessage,\"COMPND \nATOM \nEND\",flag,9,10,1IAN,10,1.23,<chart></chart>,\"{\"\"series\"\":[{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitFunction\"\":\"\"sigmoid\"\",\"\"fitLineColor\"\":\"\"#1f77b4\"\",\"\"pointColor\"\":\"\"#1f77b4\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[1.1190255865097471, 2.3163895161544437, 5.4968866182279195, 0.2035204047289052],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":1.1057683229446411},{\"\"x\"\":0.6000000238418579,\"\"y\"\":1.1019697189331055},{\"\"x\"\":1.100000023841858,\"\"y\"\":1.0818607807159424},{\"\"x\"\":1.600000023841858,\"\"y\"\":1.062997817993164},{\"\"x\"\":2.0999999046325684,\"\"y\"\":1.046447515487671},{\"\"x\"\":2.5999999046325684,\"\"y\"\":1.1217249631881714},{\"\"x\"\":3.0999999046325684,\"\"y\"\":1.2166996002197266},{\"\"x\"\":3.5999999046325684,\"\"y\"\":1.215477705001831},{\"\"x\"\":4.099999904632568,\"\"y\"\":1.0581893920898438},{\"\"x\"\":4.599999904632568,\"\"y\"\":1.1747995615005493},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.0181127786636353},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.5344523191452026},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.2569526433944702},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.1912207305431366},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.15060538053512573}]},{\"\"name\"\":\"\"Run:2023-08-08\"\",\"\"fitLineColor\"\":\"\"#ffbb78\"\",\"\"pointColor\"\":\"\"#ffbb78\"\",\"\"showPoints\"\":\"\"points\"\",\"\"parameters\"\":[3.1038581025805785, 2.0032224204185245, 5.087602825989163, 0.13277988512492753],\"\"points\"\":[{\"\"x\"\":0.10000000149011612,\"\"y\"\":3.0498509407043457},{\"\"x\"\":0.6000000238418579,\"\"y\"\":2.805217742919922},{\"\"x\"\":1.100000023841858,\"\"y\"\":3.3415253162384033},{\"\"x\"\":1.600000023841858,\"\"y\"\":3.0549843311309814},{\"\"x\"\":2.0999999046325684,\"\"y\"\":3.250074863433838},{\"\"x\"\":2.5999999046325684,\"\"y\"\":3.0432586669921875},{\"\"x\"\":3.0999999046325684,\"\"y\"\":3.265852451324463},{\"\"x\"\":3.5999999046325684,\"\"y\"\":2.9475724697113037},{\"\"x\"\":4.099999904632568,\"\"y\"\":3.1929898262023926},{\"\"x\"\":4.599999904632568,\"\"y\"\":2.7460060119628906},{\"\"x\"\":5.099999904632568,\"\"y\"\":1.6175861358642578},{\"\"x\"\":5.599999904632568,\"\"y\"\":0.3006608486175537},{\"\"x\"\":6.099999904632568,\"\"y\"\":0.3444803059101105},{\"\"x\"\":6.599999904632568,\"\"y\"\":0.015537971630692482},{\"\"x\"\":7.099999904632568,\"\"y\"\":0.5527358055114746}]}],\"\"chartOptions\"\":{\"\"xAxisName\"\":\"\"Conc.\"\",\"\"yAxisName\"\":\"\"Activity\"\",\"\"title\"\":\"\"Dose-Response curves\"\"}}\",text,,\n,,,,,,,,,,,,,,,,,,,,,`);\ntestData.columns.add(DG.Column.fromList(DG.TYPE.BYTE_ARRAY, 'BinaryImage', Array.from(new Uint8Array(11))));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWZyYW1lLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGF0YWZyYW1lLXV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRCQUE0QjtBQUM1QixPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RDLE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ3RDOzs7R0FHRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxLQUFtQixFQUFFLEdBQWM7SUFDdkUsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQztJQUM1QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7SUFDMUYsTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0lBQzVCLElBQUksa0JBQWtCLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3ZDLElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNwQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsa0JBQWtCLENBQUMsQ0FBQztZQUM1QyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekIsa0JBQWtCLElBQUksQ0FBQyxDQUFDO1NBQ3pCO0tBQ0Y7SUFDRCxPQUFPLGdCQUFnQixDQUFDO0FBQzFCLENBQUM7QUFFRCxNQUFNLFVBQVUsYUFBYSxDQUFDLEtBQW1CLEVBQUUsS0FBZ0I7SUFDakUsS0FBSyxhQUFMLEtBQUssY0FBTCxLQUFLLElBQUwsS0FBSyxHQUFLLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUM7SUFDaEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDakMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO0lBQ2xDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO1FBQ3hCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFDLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN0QyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQy9DLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUM7UUFDL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDekMsSUFBSSxRQUFRLEVBQUU7Z0JBQ1osTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2QyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzthQUNyQztpQkFBTTtnQkFDTCxNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pDLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN4QztTQUNGO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUN6QixDQUFDO0FBRUQsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O3NCQStCdkIsQ0FBQyxDQUFDO0FBQ3hCLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCAqIGFzIHNoYTI1NiBmcm9tICdmYXN0LXNoYTI1Nic7XG4vKipcbiAqIEZvciBjb2x1bW5zIG9mIHN0cmluZyB0eXBlLiBDaGVja3Mgd2hldGhlciBjb2x1bW4gY29udGFpbnMgZW1wdHkgdmFsdWVzIGFuZCByZW1vdmVzIGNvcnJlc3BvbmRpbmcgcm93cyBpbiBjYXNlIHVzZXIgc2VsZWN0cyB0byByZW1vdmUuXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlRW1wdHlTdHJpbmdSb3dzKHRhYmxlOiBERy5EYXRhRnJhbWUsIGNvbDogREcuQ29sdW1uKTogbnVtYmVyW10ge1xuICBjb25zdCBjYXRzID0gY29sLmNhdGVnb3JpZXM7XG4gIGNvbnN0IGVtcHR5UmF3SW5kID0gY2F0cy5tYXAoKHZhbCwgaW5kKSA9PiAhdmFsID8gaW5kIDogbnVsbCkuZmlsdGVyKChpdCkgPT4gaXQgIT09IG51bGwpO1xuICBjb25zdCByYXdEYXRhID0gWy4uLmNvbC5nZXRSYXdEYXRhKCldO1xuICBjb25zdCBlbXB0eVJhd3NJbmRleGVzID0gW107XG4gIGxldCByZW1vdmVkUm93c0NvdW50ZXIgPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHRhYmxlLnJvd0NvdW50OyBpKyspIHtcbiAgICBpZiAoZW1wdHlSYXdJbmQuaW5jbHVkZXMocmF3RGF0YVtpXSkpIHtcbiAgICAgIHRhYmxlLnJvd3MucmVtb3ZlQXQoaSAtIHJlbW92ZWRSb3dzQ291bnRlcik7XG4gICAgICBlbXB0eVJhd3NJbmRleGVzLnB1c2goaSk7XG4gICAgICByZW1vdmVkUm93c0NvdW50ZXIgKz0gMTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVtcHR5UmF3c0luZGV4ZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNoRGF0YUZyYW1lKHRhYmxlOiBERy5EYXRhRnJhbWUsIG5hbWVzPzogc3RyaW5nW10pOiBVaW50OEFycmF5IHtcbiAgbmFtZXMgPz89IHRhYmxlLmNvbHVtbnMubmFtZXMoKTtcbiAgY29uc3QgaGFzaGVyID0gbmV3IHNoYTI1Ni5IYXNoKCk7XG4gIGNvbnN0IG9yZGVyID0gdGFibGUuZ2V0U29ydGVkT3JkZXIobmFtZXMpO1xuICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG4gIGZvciAoY29uc3QgbmFtZSBvZiBuYW1lcykge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRhYmxlLmNvbHVtbnMuYnlOYW1lKG5hbWUpO1xuICAgIGNvbnN0IGRhdGFBcnJheSA9IGNvbHVtbi5nZXRSYXdEYXRhKCk7XG4gICAgY29uc3QgaXNTdHJpbmcgPSBjb2x1bW4udHlwZSA9PSBERy5UWVBFLlNUUklORztcbiAgICBjb25zdCBjYXRzID0gY29sdW1uLmNhdGVnb3JpZXM7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChpc1N0cmluZykge1xuICAgICAgICBjb25zdCBkYXRhID0gY2F0c1tkYXRhQXJyYXlbb3JkZXJbaV1dXTtcbiAgICAgICAgaGFzaGVyLnVwZGF0ZShlbmNvZGVyLmVuY29kZShkYXRhKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBkYXRhID0gZGF0YUFycmF5W29yZGVyW2ldXTtcbiAgICAgICAgaGFzaGVyLnVwZGF0ZShVaW50OEFycmF5LmZyb20oW2RhdGFdKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBoYXNoZXIuZGlnZXN0KCk7XG59XG5cbmV4cG9ydCBjb25zdCB0ZXN0RGF0YSA9IERHLkRhdGFGcmFtZS5mcm9tQ3N2KGBjb3VudHJpZXMsZmFzdGEsc21pbGVzLG1vbHJlZ25vLExPTixaaXAgQ29kZSxTdHJlZXQgQWRkcmVzcyBMaW5lIDEsSW1hZ2VVcmwsdXNlcl9pZCxlcnJvcl9tZXNzYWdlLHhyYXksZmxhZyxtYWduaXR1ZGUsQ1MtaWQscGRiX2lkLGFjY2VsX2EsdGltZV9vZmZzZXQsY2hhcnQsZml0LFF1ZXN0aW9ucyxlbXB0eV9udW1iZXIsZW1wdHlfc3RyaW5nXG5CZWxnaXVtLE1TTkZITkVIVk1RRllSTk5MS1RLR1ZGR1JRLENDKEMoPU8pT0NDQ2MxY2NjbmMxKWMyY2NjYyhjMilDKD1PKWMzY2NjY2MzLDE0ODAwMTQsMzYuMjc2NzI5NTgzNzQwMjM0LDk5NTA0MjMwMCwxNDAxNiBST1VURSAzMVcsaHR0cHM6Ly9kYXRhZ3Jvay5haS9pbWcvc2xpZGVzL2FjY2Vzcy1kYi1jb25uZWN0LnBuZyxpZCxFcnJvck1lc3NhZ2UsXCJDT01QTkQgXG5BVE9NIFxuRU5EXCIsZmxhZywxLDEsMVFCUywxLDEuMjMsPGNoYXJ0PjwvY2hhcnQ+LFwie1wiXCJzZXJpZXNcIlwiOlt7XCJcIm5hbWVcIlwiOlwiXCJSdW46MjAyMy0wOC0wOFwiXCIsXCJcImZpdEZ1bmN0aW9uXCJcIjpcIlwic2lnbW9pZFwiXCIsXCJcImZpdExpbmVDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJwb2ludENvbG9yXCJcIjpcIlwiIzFmNzdiNFwiXCIsXCJcInNob3dQb2ludHNcIlwiOlwiXCJwb2ludHNcIlwiLFwiXCJwYXJhbWV0ZXJzXCJcIjpbMi40OTczNjAzNDA2NDQ4NzIsIDEuNzA1ODY5NDk4NjY4Njg2NCwgNS4yNzgwNTI2NzgxOTUxMzUsIDAuMTYwMDAzMjA4ODkwMjgzODNdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjIuMzc0NDk5Nzk3ODIxMDQ1fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Mi42MjQyNDczMTI1NDU3NzY0fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjoyLjM2NzI2NzYwODY0MjU3OH0se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6Mi42NzIzMTQ4ODIyNzg0NDI0fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Mi42NTM3MzQ0NDU1NzE4OTk0fSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Mi4zNjUxNjcxNDA5NjA2OTM0fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Mi41NjU0Mjg0OTU0MDcxMDQ1fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Mi40MTYwOTU5NzIwNjExNTcyfSx7XCJcInhcIlwiOjQuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjI4NjcyNjcxMzE4MDU0Mn0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi41MTAwMDQyODE5OTc2ODA3fSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjY2NzY5ODUwMjU0MDU4ODR9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNjgwMTM2NTAxNzg5MDkzfSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjMzOTE1NDM5MjQ4MDg1MDJ9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMDkwMzg5ODMyODU0MjcwOTR9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTk4MDI3NzU5NzkwNDIwNTN9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzcuNTI1MjM1ODU1NTA4MTc5LCAxLjMxODY5MTE4NzY4MDk5ODQsIDUuMzM1NjcyNjA4NTY0Mjk0LCAwLjc4NjA3NDMzNDM5NTgwOThdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjcuOTg4MDcwNDg3OTc2MDc0fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Ny4wMTg0NTMxMjExODUzMDN9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjguMTE1Mjc5MTk3NjkyODcxfSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjo3LjQ4NjY1ODA5NjMxMzQ3N30se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjcuMzk2NDM4MTIxNzk1NjU0fSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Ny40NzcwNTIyMTE3NjE0NzV9LHtcIlwieFwiXCI6My4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo2LjkxMzA5NTQ3NDI0MzE2NH0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjguMDEzODU0OTgwNDY4NzV9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjYuOTg1OTAwNDAyMDY5MDkyfSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo2Ljk3MDMzNTk2MDM4ODE4NH0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6NS40NDg4MTcyNTMxMTI3OTN9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuNTUzNDgxODE3MjQ1NDgzNH0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS44OTM5NDc5NTg5NDYyMjh9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNjM0MDA0MjM1MjY3NjM5Mn0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC44NDAzODc0MDM5NjQ5OTYzfV19XSxcIlwiY2hhcnRPcHRpb25zXCJcIjp7XCJcInhBeGlzTmFtZVwiXCI6XCJcIkNvbmMuXCJcIixcIlwieUF4aXNOYW1lXCJcIjpcIlwiQWN0aXZpdHlcIlwiLFwiXCJ0aXRsZVwiXCI6XCJcIkRvc2UtUmVzcG9uc2UgY3VydmVzXCJcIn19XCIsdGV4dCwxMDAsYWJjXG5CdXJ1bmRpLE1EWUtFVExMTVBLVERGUE1SR0dMUE5LRVBRSVFFS1csQ09jMWNjYzJjYyhjY2MyYzEpQyhDKUMoPU8pT2MzY2NjKEMpY2MzT0MsMTQ4MDAxNSwzNi4yNzY3Mjk1ODM3NDAyMzQsOTk1MDczNDQ0LDgwIFNUQVRFIEhJR0hXQVkgMzEwLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsMiwyLDFaUDgsMiwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzQuNDMxNDYwNzUzMTAzMzk4LCAyLjE2OTE0OTg3OTkyNDY3NDUsIDUuMjY2NDQ1NTk3MTAyNzc0LCAwLjc4MjU3NjI4MjcwMTc5MjZdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjQuNzUxMDgzODUwODYwNTk2fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6NC4yMDMwMDAwNjg2NjQ1NTF9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjQuNDE1ODU4NzQ1NTc0OTUxfSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjo0LjY4NDE0MzA2NjQwNjI1fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC4xOTg0MDA5NzQyNzM2ODJ9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo0LjE3OTIyMjEwNjkzMzU5NH0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjQuNjM4NDczOTg3NTc5MzQ2fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC43MDg1NTMzMTQyMDg5ODR9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjQuMjkxNTg5MjYwMTAxMzE4fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo0LjAzODA4MjU5OTYzOTg5M30se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My40MzQ5OTM5ODIzMTUwNjM1fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjIxOTQ3MDg1ODU3MzkxMzZ9LHtcIlwieFwiXCI6Ni4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMTkyMDgzMTIwMzQ2MDY5M30se1wiXCJ4XCJcIjo2LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC41MzUyNjM1OTc5NjUyNDA1fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjMzNDY5MjAzMTE0NTA5NTh9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzIuMzM5NDU4MDE3OTcwMTI2LCAtMS4wNzM0MTg0MzEwMTcxMTc4LCA0Ljc0NjMzMjk1MDU1MDkzNCwgMC4yNDgyNDE2ODU3NTk1NjU4XSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjowLjIxMzkzMzc2NTg4ODIxNDF9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjowLjQyNjk1NjIwNjU2MDEzNDl9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjAuMjQ0MTU3MzI5MjAxNjk4M30se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6MC4xNDY2MzU5NjQ1MTI4MjV9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjA4ODE4NDYyNDkxMDM1NDYxfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC4yNTYwNjU2NjY2NzU1Njc2fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC40MjQzNDA0NTY3MjQxNjY4N30se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuMzcxMTEyMzE2ODQ2ODQ3NTN9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNTU4MTczNzE2MDY4MjY3OH0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4xODM1OTAwNTQ1MTIwMjR9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuNTYyOTg0MzQ3MzQzNDQ0OH0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi4zMjExMjg4NDUyMTQ4NDM4fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjIyOTk2MTYzMzY4MjI1MX0se1wiXCJ4XCJcIjo2LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi4yNTYwMjI2OTE3MjY2ODQ2fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjIxNDIzOTgzNTczOTEzNTd9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbkNhbWVyb29uLE1JRVZGTEZHSVZMR0xJUElUTEFHTEZWVEFZTFFZUlJHRFFMREwsQ09jMWNjYzJjYyhjY2MyYzEpQyhDKUMoPU8pT0NDQ2MzY2NjbmMzLDE0ODAwMTYsMzYuMjYwOTU5NjI1MjQ0MTQsOTk1MTUzNTk2LDMwLTU2IFdISVRFU1RPTkUgRVhQWSxodHRwczovL2RhdGFncm9rLmFpL2ltZy9zbGlkZXMvYWNjZXNzLWRiLWNvbm5lY3QucG5nLGlkLEVycm9yTWVzc2FnZSxcIkNPTVBORCBcbkFUT00gXG5FTkRcIixmbGFnLDMsMywyQkRKLDMsMS4yMyw8Y2hhcnQ+PC9jaGFydD4sXCJ7XCJcInNlcmllc1wiXCI6W3tcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0RnVuY3Rpb25cIlwiOlwiXCJzaWdtb2lkXCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiIzFmNzdiNFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOls0LjY3NjA2NTI1Nzg2NDIzMjUsIDAuOTA0Njk1NjMyMDc1NjcwMywgNS42NTE0MDg5NzE4NTY3MzgsIDAuMDc3Mzg4NDYwMTIxODQxODVdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjQuMzI0MjU1OTQzMjk4MzR9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjo0LjY2ODQ0MjI0OTI5ODA5Nn0se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6NC4zNzk3ODUwNjA4ODI1Njh9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjUuMDM0NTEzOTUwMzQ3OX0se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjQuODc4NjUzNTI2MzA2MTUyfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC4zNDUxMzEzOTcyNDczMTQ1fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC4zMzY5OTIyNjM3OTM5NDV9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1LjAzNzQzMDI4NjQwNzQ3MX0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6NS4wMDkyNjkyMzc1MTgzMTA1fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo0LjE1MTkwMjY3NTYyODY2Mn0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My40MDY2OTUxMjc0ODcxODI2fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjM3MzI3NTk5NTI1NDUxNjZ9LHtcIlwieFwiXCI6Ni4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuNjczNzI4MTA4NDA2MDY3fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjQ4NTc0NzkwMzU4NTQzMzk2fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjI3ODMwNTIzMjUyNDg3MTh9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzIuOTM4Mzk1ODYzMDEwMTExLCAtMS40NjU4NDgwNjYxMzkyMTE3LCA1LjQ2MjcwMjc1MTk5NjU4NCwgMC4zNDczMTM5MDIzNjE1MDM5XSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjowLjQ5NDE3MTA4Mjk3MzQ4MDJ9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjowLjE1MzIzOTc0MTkyMTQyNDg3fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjQ2MzczNDMyODc0Njc5NTY1fSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjMzNzA0MzEzNjM1ODI2MTF9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjUxNzkwMzAyOTkxODY3MDd9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjI3ODk5NzY1OTY4MzIyNzU0fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC4yMjA3NTA2NDQ4MDMwNDcxOH0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuNTc4OTkxODg5OTUzNjEzM30se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4yMTE2OTkxMTMyNDk3Nzg3NX0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4yNzg1NzY0NjM0NjA5MjIyNH0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4wOTA2MzMyNzMxMjQ2OTQ4fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjg1MjAzMDAzODgzMzYxODJ9LHtcIlwieFwiXCI6Ni4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuNzE3NzA1OTY1MDQyMTE0M30se1wiXCJ4XCJcIjo2LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi44NjgwOTE4MjE2NzA1MzIyfSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjozLjI0MTMwNzczNTQ0MzExNTJ9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbkNhbmFkYSxNTUVMVkxLVElJR1BJVlZHVlZMUklWREtXTE5LREssQ0MoQyg9TylOQ0NTKWMxY2NjYyhjMSlDKD1PKWMyY2NjY2MyLDE0ODAwMTcsMzYuMjYwOTU5NjI1MjQ0MTQsOTk1MTUsMzAtNTYgV0hJVEVTVE9ORSBFWFBZLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsNCw0LDFJQU4sNCwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzAuODU5NzM5MDk3NTQzMDAwOCwgMS4wOTU3NjI1NzMyNDgxOTQ2LCA1LjI2MDUzNzA2Nzk4Nzk1OCwgMC4wNzk3NDE4Nzk5ODE3NzczNl0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6MC44MTkwMTUyNjQ1MTExMDg0fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6MC44NDIxNjg5ODY3OTczMzI4fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjg3NDA5MjIyMTI2MDA3MDh9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjAuODkyNDI3NTA0MDYyNjUyNn0se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuODI0OTA2NzY2NDE0NjQyM30se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuOTMyNzY2OTE0MzY3Njc1OH0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuODUyMjk3NDI1MjcwMDgwNn0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuODE3NDQ5MjcxNjc4OTI0Nn0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC44Mzk0NjQ3MjQwNjM4NzMzfSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjcxMzkzODc3MjY3ODM3NTJ9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNTU2MTE2NzU5Nzc3MDY5MX0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4zMjc2MjI2ODE4NTYxNTU0fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjEyNDc5NDc0Mzk1NTEzNTM1fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjEzMDA2Nzk3NDMyODk5NDc1fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjA1OTcwMjA3OTc0MzE0Njg5Nn1dfSx7XCJcIm5hbWVcIlwiOlwiXCJSdW46MjAyMy0wOC0wOFwiXCIsXCJcImZpdExpbmVDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJwb2ludENvbG9yXCJcIjpcIlwiI2ZmYmI3OFwiXCIsXCJcInNob3dQb2ludHNcIlwiOlwiXCJwb2ludHNcIlwiLFwiXCJwYXJhbWV0ZXJzXCJcIjpbNS43NjA5MzAyMTk1ODI1NDYsIDEuNjU5MTc5MzI5MzgzMzAxMywgNC42NjcxNTU5Mjk3MjA4NTEsIDAuNzg1ODEwOTU0NDEyMTY1Ml0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6Ni4xNTY5OTMzODkxMjk2Mzl9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjo1LjIzNjcwMTk2NTMzMjAzMX0se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6Ni4wMTA1NjA1MTI1NDI3MjV9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjUuNDk1NTEyOTYyMzQxMzA5fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Ni4wODc3NzA0NjIwMzYxMzN9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1Ljc5OTg2NTcyMjY1NjI1fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NS41OTc1NDY1Nzc0NTM2MTN9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1LjUyMDkwMjE1NjgyOTgzNH0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6NS4zNjA2NTQzNTQwOTU0NTl9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjMuNTUzOTc0NjI4NDQ4NDg2M30se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS41NzcyMzYyOTQ3NDYzOTl9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMDAwMTI2NDgxMDU2MjEzNH0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC45MzA1Nzk3ODE1MzIyODc2fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjYwMzM2Mzg3MTU3NDQwMTl9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNDIwMzY4NTUyMjA3OTQ2OH1dfV0sXCJcImNoYXJ0T3B0aW9uc1wiXCI6e1wiXCJ4QXhpc05hbWVcIlwiOlwiXCJDb25jLlwiXCIsXCJcInlBeGlzTmFtZVwiXCI6XCJcIkFjdGl2aXR5XCJcIixcIlwidGl0bGVcIlwiOlwiXCJEb3NlLVJlc3BvbnNlIGN1cnZlc1wiXCJ9fVwiLHRleHQsLFxuQ29sb21iaWEsTURSVERFVlNOSFRIREtQVExUV0ZFRUlGRUVZSFNQRkhOLEZDKEYpKEYpYzFjY2MoT0MyQ0NOQ0MyKWNjMSwxNDgwMDI5LDM2LjMzMDk0NDA2MTI3OTMsOTk1MTUyMDUwLDEgQ09VUlQgSE9VU0UgU1FVQVJFLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsNSw1LDRVSjEsNSwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzYuNDk5NTA4ODMxNDE1MzY1NSwgMi40MjcwMzUxMDA0NTM5OTE0LCA1LjE3ODY1OTUzNTM0ODU3OSwgMC42MjU2NTMzNDYyNDE1NzddLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjYuNDk2MjMxNTU1OTM4NzIxfSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Ni40MjU0MzM2MzU3MTE2N30se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6Ny4wNDAwNjM4NTgwMzIyMjd9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjYuMTExNTQwMzE3NTM1NH0se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjYuNjgwNzI4NDM1NTE2MzU3fSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Ni40MDY3NzQ1MjA4NzQwMjN9LHtcIlwieFwiXCI6My4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo2LjYxMTI2OTQ3NDAyOTU0MX0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjUuODg5MDk0MzUyNzIyMTY4fSx7XCJcInhcIlwiOjQuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo2Ljc1MzQ0NzA1NTgxNjY1fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo2LjM2MTQzNTg5MDE5Nzc1NH0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6NC4xNjY2OTc1MDIxMzYyMzA1fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjE3MjExODkwMjIwNjQyMX0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC44MDEwNDg5OTQwNjQzMzF9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNDY0MDAyMTAyNjEzNDQ5MX0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4wMDEwMzU3NjY3OTI0ODM2Mjc4fV19LHtcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiI2ZmYmI3OFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOlsxLjQ3MzQzODEzNDc0NDY0MDEsIDEuMTY0OTgwNTE4ODA3NDE5NiwgNC44Mjk1ODYwODg2NjQyMSwgMC4wOTUwMDU0NTQ5NjcxMDAwN10sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6MS41Mjc5MDk2MzY0OTc0OTc2fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6MS4zNTU5OTc0NDMxOTkxNTc3fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjoxLjUyNDYzNzgxODMzNjQ4Njh9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjEuNTU2NzY1Nzk0NzU0MDI4M30se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuNDExNDI0MDQwNzk0MzcyNn0se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuNDA0NTAxMDgwNTEzMDAwNX0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuNDc2OTgyOTUxMTY0MjQ1Nn0se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuNDg3NTUwMDIwMjE3ODk1NX0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4yOTkxOTg3NDY2ODEyMTM0fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjkyMjk2MTQxMzg2MDMyMX0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC42NTIwMDQ0ODAzNjE5Mzg1fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjE1MzUwOTc4MDc2NDU3OTc3fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjEwNzg5MDMwNzkwMzI4OTh9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTcyNzY0NDk1MDE1MTQ0MzV9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTQwNjY2MDgyNTAxNDExNDR9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbkNvc3RhIFJpY2EsTUtTVEtFRUlRVElLVExMS0RTUlRBS1lIS1JMUUlWTCxDQyhDKUNjMWNjYyhjYzEpQyhDKUMoPU8pTjJDQ0NDMkMoPU8pT0NDQ2MzY2NjY2MzLDE0ODAwMTgsMzYuMzMwOTQ0MDYxMjc5Myw5OTUwODQyMTgsNDA0MSBTT1VUSFdFU1RFUk4gQkxWRCxodHRwczovL2RhdGFncm9rLmFpL2ltZy9zbGlkZXMvYWNjZXNzLWRiLWNvbm5lY3QucG5nLGlkLEVycm9yTWVzc2FnZSxcIkNPTVBORCBcbkFUT00gXG5FTkRcIixmbGFnLDYsNiwyQlBXLDYsMS4yMyw8Y2hhcnQ+PC9jaGFydD4sXCJ7XCJcInNlcmllc1wiXCI6W3tcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0RnVuY3Rpb25cIlwiOlwiXCJzaWdtb2lkXCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiIzFmNzdiNFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOlsyLjQ4MzM2NDE4NDMzMTEyMjcsIC0xLjg5NDU5Nzg3NDIwOTAwNjIsIDQuNjcxMTI3NzA4MDkyNTY4LCAwLjI0MTU5ODYxMzExODE1MTUzXSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjowLjA5Njk1MjQxNjAwMjc1MDR9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjowLjAyODQ4MzA0MDYzMDgxNzQxM30se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6MC4yMjA4NzE3NjE0NDEyMzA3N30se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6MC4wMDY4OTE1NTQ2ODcxNzIxNzQ1fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC40MzA1ODc5NzcxNzA5NDQyfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC40NDc3NDExNTA4NTYwMTgwN30se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjAuNDUzNDYzMTk2NzU0NDU1NTd9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjIzNzA1OTMxMDA3ODYyMDl9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNDY1Nzk1Mzk3NzU4NDgzOX0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4xNTUyMDA3MTk4MzMzNzR9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuMjI5NDA3MDcyMDY3MjYwN30se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi40MzExNTMwNTkwMDU3MzczfSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjMzODQ2MTE2MDY1OTc5fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjYwODIwMTAyNjkxNjUwNH0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi44MTM2MTQzNjg0Mzg3MjA3fV19LHtcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiI2ZmYmI3OFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOls1LjIyNDU3MzUyMTY0MjAzMywgMS40NDU0MDMzOTI0MTk4NTI4LCA1LjYwMTQxOTc3NDYwNzY1MzUsIDAuMjgyMzIxNjA1NDE5NzU3N10sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6NC45NTAyNzQ5NDQzMDU0Mn0se1wiXCJ4XCJcIjowLjYwMDAwMDAyMzg0MTg1NzksXCJcInlcIlwiOjUuMTc1NDY3OTY3OTg3MDYwNX0se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6NS4yNzY3NTI5NDg3NjA5ODZ9LHtcIlwieFwiXCI6MS42MDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjUuNTg5Mjk0OTEwNDMwOTA4fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NS42MTY5OTQ4NTc3ODgwODZ9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1LjEyMDgxMzg0NjU4ODEzNX0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjUuMzQwNzY2OTA2NzM4MjgxfSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NC44NzY0NzEwNDI2MzMwNTd9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjQuOTQ5OTkzNjEwMzgyMDh9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjUuMTYyNTY0NzU0NDg2MDg0fSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo0LjM5OTU1NzU5MDQ4NDYxOX0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi43OTc3OTY5NjQ2NDUzODU3fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjAyMjk4NzI0NjUxMzM2Njd9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNDgyNzU2MDE4NjM4NjEwODR9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTA0MDg5MzE5NzA1OTYzMTN9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbkN1YmEsTUhBSUxSWUZJUlJMRllISUZZS0lZU0xJU0tLSFFTTFBTRFZSUUYsQ09jMWNjYzJjKGMxKWMoQ0MoPU8pTjNDQ0NDM0MoPU8pT2M0Y2NjKEMpY2M0T0MpYyhDKW4yQyg9TyljNWNjYyhDbCljYzUsMTQ4MDAxOSwzNi4zMzExNTc2ODQzMjYxNyw5OTUwODE5MjgsMTIyNyBVUyBISUdIV0FZIDExLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsNyw3LDFRQlMsNywxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzMuMzIwODM4Njc5NzEzOTI1LCAtMS4yNDIxNjE5OTg3MzE2NzI4LCA0LjgzMTMyNTQyNTIyNTI1NiwgMC4zMjM2MDExMDk4NDAzMDcyXSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjowLjM3Mjc0NzAzMzgzNDQ1NzR9LHtcIlwieFwiXCI6MC42MDAwMDAwMjM4NDE4NTc5LFwiXCJ5XCJcIjowLjEyMzY1MDE0MTA2MDM1MjMzfSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjQ4NDIyNDY3NzA4NTg3NjQ2fSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjowLjIyNjQ0NjUwOTM2MTI2NzF9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjowLjE2ODIxNzk0MjExODY0NDcxfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC4zODc5MDE0NTUxNjM5NTU3fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC41NDcwMjQ0ODg0NDkwOTY3fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MC4zNDE5MDUzNTU0NTM0OTEyfSx7XCJcInhcIlwiOjQuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjc2NTUxMjA0OTE5ODE1MDZ9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMjM0NjUxNjg0NzYxMDQ3NH0se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi40NTMzMzY3MTU2OTgyNDJ9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuOTU2NTQ5MTY3NjMzMDU2Nn0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My4zMzUyOTk0OTE4ODIzMjR9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjMuMjQwMjkwODgwMjAzMjQ3fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjozLjExMDcyMTgyNjU1MzM0NDd9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzMuNjQwMTg1MzUyMTUxMTA5NCwgMS4yNjIxMTU4ODg3NTAxMywgNS4zOTkwMjgwNzQ0MDI3NDQsIDAuNTA4OTU4MDgzMDA2ODA5MV0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6My44NTg1NTk4NDY4NzgwNTE4fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6My42MDc3MjA2MTM0Nzk2MTQzfSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjozLjg1NTI1MjI2NTkzMDE3Nn0se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6My42MTkwMzkyOTcxMDM4ODJ9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjgzOTM4ODM3MDUxMzkxNn0se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjMuMzM1MjgzMDQxMDAwMzY2fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6My41NzExNDE0ODEzOTk1MzZ9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjQxNTUwNDY5Mzk4NDk4NTR9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjMuNzMxNjY0NjU3NTkyNzczNH0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My4wNjgwMTU1NzU0MDg5MzU1fSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjg5MTA2NjU1MTIwODQ5Nn0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS42MDIyNzUzNzE1NTE1MTM3fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjc2NTI1NzY1NjU3NDI0OTN9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNjg3NTMyNjAzNzQwNjkyMX0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC41ODI4ODcxNzI2OTg5NzQ2fV19XSxcIlwiY2hhcnRPcHRpb25zXCJcIjp7XCJcInhBeGlzTmFtZVwiXCI6XCJcIkNvbmMuXCJcIixcIlwieUF4aXNOYW1lXCJcIjpcIlwiQWN0aXZpdHlcIlwiLFwiXCJ0aXRsZVwiXCI6XCJcIkRvc2UtUmVzcG9uc2UgY3VydmVzXCJcIn19XCIsdGV4dCwsXG5JdGFseSxNU05GSE5FSFZNUUZZUk5OTEtUS0dWRkdSUSxDQyhDKUNjMWNjYyhjYzEpQyhDKUMoPU8pTjJDQ0NDMkMoPU8pT0NDT1tOK10oPU8pW08tXSwxNDgwMDIwLDM2LjMzMTE1NzY4NDMyNjE3LDk5NTAyLFwiMTY4LTQ2IDkxU1QgQVZFLiwgMk5EIEZMUlwiLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsOCw4LDFaUDgsOCwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzIuMjkzNTkyMTA1OTIzODA5LCAxLjM3ODE1ODY1NDkxNDE4MzUsIDUuMTAyNTg5ODAzODY3NjYwNSwgMC4wMzQ5Mzg1MTI0NTI5MTI5MV0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6Mi4xMjg3MjgzODk3Mzk5OTAyfSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Mi4yNjc5NzIyMzA5MTEyNTV9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjIuMzk4NDQyNTA2NzkwMTYxfSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjoyLjUxMzA2MjIzODY5MzIzNzN9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjoyLjMyNTUxMTY5Mzk1NDQ2Nzh9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjoyLjEyNzM0MDc5MzYwOTYxOX0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjIuNDcyNTk3ODM3NDQ4MTJ9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjoyLjEzMTE4MTQ3ODUwMDM2Nn0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6Mi4wOTA0MjE0MzgyMTcxNjN9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuMDIyOTkxNjU3MjU3MDh9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMTEwNTA1OTM4NTI5OTY4M30se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC40NDk0NDg1ODU1MTAyNTM5fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjEzNzU2MzU4NjIzNTA0NjR9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMDM2MzUxMTIxOTYyMDcwNDY1fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjE2MTk3NzExMjI5MzI0MzR9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzUuOTUzMTI1NDk5NDM5ODc5LCAxLjI1Mjg2MjAyNTUzMDY1MjgsIDUuMTg3NjM3NDQwMTQ5ODAyLCAwLjMxMTAzNDg3NTMyNjA4ODZdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjUuNjU4NTI4MzI3OTQxODk0NX0se1wiXCJ4XCJcIjowLjYwMDAwMDAyMzg0MTg1NzksXCJcInlcIlwiOjUuOTExMTUyMzYyODIzNDg2fSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjo1LjkyNDkyMDA4MjA5MjI4NX0se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6NS44NDY5NDM4NTUyODU2NDQ1fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NS45Mjk0NzI5MjMyNzg4MDl9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo2LjE5MDAzNzcyNzM1NTk1N30se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjYuMjM2MTc5ODI4NjQzNzk5fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6Ni4xNDEwMTkzNDQzMjk4MzR9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjUuMjk1MjEwODM4MzE3ODcxfSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo1LjI2NTgwMTkwNjU4NTY5M30se1wiXCJ4XCJcIjo1LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My4zNzIyODUxMjc2Mzk3NzA1fSx7XCJcInhcIlwiOjUuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjgyOTkyMjY3NjA4NjQyNTh9LHtcIlwieFwiXCI6Ni4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMzI2OTA5MDA1NjQxOTM3MjZ9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNjI3NDU0MzQwNDU3OTE2M30se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC44NDQxODU3MDk5NTMzMDgxfV19XSxcIlwiY2hhcnRPcHRpb25zXCJcIjp7XCJcInhBeGlzTmFtZVwiXCI6XCJcIkNvbmMuXCJcIixcIlwieUF4aXNOYW1lXCJcIjpcIlwiQWN0aXZpdHlcIlwiLFwiXCJ0aXRsZVwiXCI6XCJcIkRvc2UtUmVzcG9uc2UgY3VydmVzXCJcIn19XCIsdGV4dCwsXG5Sd2FuZGEsTVBOU0VQQVNMTEVMRk5TSUFUUUdFTFZSU0xLQUdOQVNLLENDKEMpQ2MxY2NjKGNjMSlDKEMpQyg9TylOMkNDQ0MyQyg9TylPQ0NPLDE0ODAwMjEsMzYuMzMxMzcxMzA3MzczMDUsOTk1MDM3MjQ3LFwiMTY4LTQ2IDkxU1QgQVZFLiwgMk5EIEZMUlwiLGh0dHBzOi8vZGF0YWdyb2suYWkvaW1nL3NsaWRlcy9hY2Nlc3MtZGItY29ubmVjdC5wbmcsaWQsRXJyb3JNZXNzYWdlLFwiQ09NUE5EIFxuQVRPTSBcbkVORFwiLGZsYWcsOSw5LDJCREosOSwxLjIzLDxjaGFydD48L2NoYXJ0PixcIntcIlwic2VyaWVzXCJcIjpbe1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRGdW5jdGlvblwiXCI6XCJcInNpZ21vaWRcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiMxZjc3YjRcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzMuODIwOTk3MjIwMjY1NDQ3NCwgMS4zNzc5MjE2NzE2NDQ4NTA2LCA1LjI5OTg4MjIyODQzOTY4NiwgMC4wNjA0MDY0NTUxOTA2OTYwOF0sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6My43ODIxMTA5Mjk0ODkxMzU3fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6My41NDI0MzMwMjM0NTI3NTl9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjMuNzAwODY3NDE0NDc0NDg3M30se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6My43MTczMDE2MDcxMzE5NTh9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo0LjAyNDQ1MjIwOTQ3MjY1Nn0se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjQuMDEzODk5MzI2MzI0NDYzfSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6My45NDUwOTQzNDcwMDAxMjJ9LHtcIlwieFwiXCI6My41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjg2NjYyMTk3MTEzMDM3MX0se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My43NDYxNjI2NTI5NjkzNjA0fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjozLjM0NTQ3NDAwNDc0NTQ4MzR9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjIuNjE5NDQzMTc4MTc2ODh9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuOTk5NDA1MDI2NDM1ODUyfSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjQ2MjU5NzkzNjM5MTgzMDQ0fSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjA1NDEzNDYxMTA0MDM1Mzc3NX0se1wiXCJ4XCJcIjo3LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4wNTcxMTE4NzQyMjI3NTU0M31dfSx7XCJcIm5hbWVcIlwiOlwiXCJSdW46MjAyMy0wOC0wOFwiXCIsXCJcImZpdExpbmVDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJwb2ludENvbG9yXCJcIjpcIlwiI2ZmYmI3OFwiXCIsXCJcInNob3dQb2ludHNcIlwiOlwiXCJwb2ludHNcIlwiLFwiXCJwYXJhbWV0ZXJzXCJcIjpbNS42MzE4MDc5NjU3NzI2MDM1LCAxLjg0OTU0OTM3NzAwMDA1OTUsIDUuMzkxNzkzMzEyNDcxMTE2LCAwLjE3MDYwNzA3NTg3MzQ4NDQyXSxcIlwicG9pbnRzXCJcIjpbe1wiXCJ4XCJcIjowLjEwMDAwMDAwMTQ5MDExNjEyLFwiXCJ5XCJcIjo1LjQ1ODA3OTgxNDkxMDg4OX0se1wiXCJ4XCJcIjowLjYwMDAwMDAyMzg0MTg1NzksXCJcInlcIlwiOjUuNTU0NDI3MTQ2OTExNjIxfSx7XCJcInhcIlwiOjEuMTAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjo1Ljc5OTk4MzAyNDU5NzE2OH0se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6NS4zNjQxNDAwMzM3MjE5MjR9LHtcIlwieFwiXCI6Mi4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjo1Ljg2NDQ4NTc0MDY2MTYyMX0se1wiXCJ4XCJcIjoyLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjUuNDUwOTgwNjYzMjk5NTYwNX0se1wiXCJ4XCJcIjozLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjUuNzAyNTc0NzI5OTE5NDM0fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6NS43MzE0NTM0MTg3MzE2ODk1fSx7XCJcInhcIlwiOjQuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo1LjUxMjM0NDM2MDM1MTU2MjV9LHtcIlwieFwiXCI6NC41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjUuNzI0Mzk1NzUxOTUzMTI1fSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjo0LjM1NDUwNjk2OTQ1MTkwNH0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS43MzA3NjY2NTQwMTQ1ODc0fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjYzMDU5MzY1NzQ5MzU5MTN9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMDM1MTgzNDM3MTY4NTk4MTc1fSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjc1NzUxNjkyMDU2NjU1ODh9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcblN3aXR6ZXJsYW5kLElSVlZHUllMSUVWV0tBQUdNRE1ES1ZMRkxXU1NERUksQ04xQ0NDKENDMSlPYzJjY2MoY2MyKUMoRikoRilGLDE0ODAwMjgsMzYuMzMxMzcxMzA3MzczMDUsOTk1MDQsOTItMTEgMTc5VEggUExBQ0UsaHR0cHM6Ly9kYXRhZ3Jvay5haS9pbWcvc2xpZGVzL2FjY2Vzcy1kYi1jb25uZWN0LnBuZyxpZCxFcnJvck1lc3NhZ2UsXCJDT01QTkQgXG5BVE9NIFxuRU5EXCIsZmxhZyw5LDEwLDFJQU4sMTAsMS4yMyw8Y2hhcnQ+PC9jaGFydD4sXCJ7XCJcInNlcmllc1wiXCI6W3tcIlwibmFtZVwiXCI6XCJcIlJ1bjoyMDIzLTA4LTA4XCJcIixcIlwiZml0RnVuY3Rpb25cIlwiOlwiXCJzaWdtb2lkXCJcIixcIlwiZml0TGluZUNvbG9yXCJcIjpcIlwiIzFmNzdiNFwiXCIsXCJcInBvaW50Q29sb3JcIlwiOlwiXCIjMWY3N2I0XCJcIixcIlwic2hvd1BvaW50c1wiXCI6XCJcInBvaW50c1wiXCIsXCJcInBhcmFtZXRlcnNcIlwiOlsxLjExOTAyNTU4NjUwOTc0NzEsIDIuMzE2Mzg5NTE2MTU0NDQzNywgNS40OTY4ODY2MTgyMjc5MTk1LCAwLjIwMzUyMDQwNDcyODkwNTJdLFwiXCJwb2ludHNcIlwiOlt7XCJcInhcIlwiOjAuMTAwMDAwMDAxNDkwMTE2MTIsXCJcInlcIlwiOjEuMTA1NzY4MzIyOTQ0NjQxMX0se1wiXCJ4XCJcIjowLjYwMDAwMDAyMzg0MTg1NzksXCJcInlcIlwiOjEuMTAxOTY5NzE4OTMzMTA1NX0se1wiXCJ4XCJcIjoxLjEwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6MS4wODE4NjA3ODA3MTU5NDI0fSx7XCJcInhcIlwiOjEuNjAwMDAwMDIzODQxODU4LFwiXCJ5XCJcIjoxLjA2Mjk5NzgxNzk5MzE2NH0se1wiXCJ4XCJcIjoyLjA5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjEuMDQ2NDQ3NTE1NDg3NjcxfSx7XCJcInhcIlwiOjIuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MS4xMjE3MjQ5NjMxODgxNzE0fSx7XCJcInhcIlwiOjMuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MS4yMTY2OTk2MDAyMTk3MjY2fSx7XCJcInhcIlwiOjMuNTk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6MS4yMTU0Nzc3MDUwMDE4MzF9LHtcIlwieFwiXCI6NC4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuMDU4MTg5MzkyMDg5ODQzOH0se1wiXCJ4XCJcIjo0LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MS4xNzQ3OTk1NjE1MDA1NDkzfSx7XCJcInhcIlwiOjUuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoxLjAxODExMjc3ODY2MzYzNTN9LHtcIlwieFwiXCI6NS41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuNTM0NDUyMzE5MTQ1MjAyNn0se1wiXCJ4XCJcIjo2LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4yNTY5NTI2NDMzOTQ0NzAyfSx7XCJcInhcIlwiOjYuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjE5MTIyMDczMDU0MzEzNjZ9LHtcIlwieFwiXCI6Ny4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMTUwNjA1MzgwNTM1MTI1NzN9XX0se1wiXCJuYW1lXCJcIjpcIlwiUnVuOjIwMjMtMDgtMDhcIlwiLFwiXCJmaXRMaW5lQ29sb3JcIlwiOlwiXCIjZmZiYjc4XCJcIixcIlwicG9pbnRDb2xvclwiXCI6XCJcIiNmZmJiNzhcIlwiLFwiXCJzaG93UG9pbnRzXCJcIjpcIlwicG9pbnRzXCJcIixcIlwicGFyYW1ldGVyc1wiXCI6WzMuMTAzODU4MTAyNTgwNTc4NSwgMi4wMDMyMjI0MjA0MTg1MjQ1LCA1LjA4NzYwMjgyNTk4OTE2MywgMC4xMzI3Nzk4ODUxMjQ5Mjc1M10sXCJcInBvaW50c1wiXCI6W3tcIlwieFwiXCI6MC4xMDAwMDAwMDE0OTAxMTYxMixcIlwieVwiXCI6My4wNDk4NTA5NDA3MDQzNDU3fSx7XCJcInhcIlwiOjAuNjAwMDAwMDIzODQxODU3OSxcIlwieVwiXCI6Mi44MDUyMTc3NDI5MTk5MjJ9LHtcIlwieFwiXCI6MS4xMDAwMDAwMjM4NDE4NTgsXCJcInlcIlwiOjMuMzQxNTI1MzE2MjM4NDAzM30se1wiXCJ4XCJcIjoxLjYwMDAwMDAyMzg0MTg1OCxcIlwieVwiXCI6My4wNTQ5ODQzMzExMzA5ODE0fSx7XCJcInhcIlwiOjIuMDk5OTk5OTA0NjMyNTY4NCxcIlwieVwiXCI6My4yNTAwNzQ4NjM0MzM4Mzh9LHtcIlwieFwiXCI6Mi41OTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjA0MzI1ODY2Njk5MjE4NzV9LHtcIlwieFwiXCI6My4wOTk5OTk5MDQ2MzI1Njg0LFwiXCJ5XCJcIjozLjI2NTg1MjQ1MTMyNDQ2M30se1wiXCJ4XCJcIjozLjU5OTk5OTkwNDYzMjU2ODQsXCJcInlcIlwiOjIuOTQ3NTcyNDY5NzExMzAzN30se1wiXCJ4XCJcIjo0LjA5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6My4xOTI5ODk4MjYyMDIzOTI2fSx7XCJcInhcIlwiOjQuNTk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjoyLjc0NjAwNjAxMTk2Mjg5MDZ9LHtcIlwieFwiXCI6NS4wOTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjEuNjE3NTg2MTM1ODY0MjU3OH0se1wiXCJ4XCJcIjo1LjU5OTk5OTkwNDYzMjU2OCxcIlwieVwiXCI6MC4zMDA2NjA4NDg2MTc1NTM3fSx7XCJcInhcIlwiOjYuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjM0NDQ4MDMwNTkxMDExMDV9LHtcIlwieFwiXCI6Ni41OTk5OTk5MDQ2MzI1NjgsXCJcInlcIlwiOjAuMDE1NTM3OTcxNjMwNjkyNDgyfSx7XCJcInhcIlwiOjcuMDk5OTk5OTA0NjMyNTY4LFwiXCJ5XCJcIjowLjU1MjczNTgwNTUxMTQ3NDZ9XX1dLFwiXCJjaGFydE9wdGlvbnNcIlwiOntcIlwieEF4aXNOYW1lXCJcIjpcIlwiQ29uYy5cIlwiLFwiXCJ5QXhpc05hbWVcIlwiOlwiXCJBY3Rpdml0eVwiXCIsXCJcInRpdGxlXCJcIjpcIlwiRG9zZS1SZXNwb25zZSBjdXJ2ZXNcIlwifX1cIix0ZXh0LCxcbiwsLCwsLCwsLCwsLCwsLCwsLCwsLGApO1xudGVzdERhdGEuY29sdW1ucy5hZGQoREcuQ29sdW1uLmZyb21MaXN0KERHLlRZUEUuQllURV9BUlJBWSwgJ0JpbmFyeUltYWdlJywgQXJyYXkuZnJvbShuZXcgVWludDhBcnJheSgxMSkpKSk7XG4iXX0=","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nimport * as grok from 'datagrok-api/grok';\nimport * as DG from 'datagrok-api/dg';\nimport { testData } from './dataframe-utils';\nimport { changeOptionsSaveLayout, filterAsync, loadLayout, selectFilterChangeCurrent, testViewerInternal } from './test-viewer-utils';\nconst STANDART_TIMEOUT = 30000;\nconst BENCHMARK_TIMEOUT = 10800000;\nconst stdLog = console.log.bind(console);\nconst stdInfo = console.info.bind(console);\nconst stdWarn = console.warn.bind(console);\nconst stdError = console.error.bind(console);\nexport const tests = {};\nconst autoTestsCatName = 'Auto Tests';\nconst demoCatName = 'Demo';\nconst detectorsCatName = 'Detectors';\nconst coreCatName = 'Core';\nconst wasRegistered = {};\nexport let currentCategory;\nexport var assure;\n(function (assure) {\n function notNull(value, name) {\n if (value == null)\n throw new Error(`${name == null ? 'Value' : name} not defined`);\n }\n assure.notNull = notNull;\n})(assure || (assure = {}));\nexport class TestContext {\n constructor(catchUnhandled, report) {\n this.catchUnhandled = true;\n this.report = false;\n if (catchUnhandled !== undefined)\n this.catchUnhandled = catchUnhandled;\n if (report !== undefined)\n this.report = report;\n }\n ;\n}\nexport class Test {\n constructor(category, name, test, options) {\n var _a;\n this.category = category;\n this.name = name;\n options !== null && options !== void 0 ? options : (options = {});\n (_a = options.timeout) !== null && _a !== void 0 ? _a : (options.timeout = STANDART_TIMEOUT);\n this.options = options;\n this.test = () => __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n let result = '';\n try {\n result = yield test();\n }\n catch (e) {\n reject(e);\n }\n resolve(result);\n }));\n });\n }\n}\nexport class Category {\n}\nexport class TestExecutionOptions {\n}\nexport function testEvent(event, handler, trigger, ms = 0, reason = `timeout`) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n const sub = event.subscribe((args) => {\n try {\n handler(args);\n resolve('OK');\n }\n catch (e) {\n reject(e);\n }\n finally {\n sub.unsubscribe();\n clearTimeout(timeout);\n }\n });\n const timeout = setTimeout(() => {\n sub.unsubscribe();\n // eslint-disable-next-line prefer-promise-reject-errors\n reject(reason);\n }, ms);\n trigger();\n });\n });\n}\nexport function testEventAsync(event, handler, trigger, ms = 0, reason = `timeout`) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n const sub = event.subscribe((args) => {\n handler(args).then(() => {\n resolve('OK');\n }).catch((e) => {\n reject(e);\n }).finally(() => {\n sub.unsubscribe();\n clearTimeout(timeout);\n });\n });\n const timeout = setTimeout(() => {\n sub.unsubscribe();\n // eslint-disable-next-line prefer-promise-reject-errors\n reject(reason);\n }, ms);\n trigger();\n });\n });\n}\nexport function test(name, test, options) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n if (tests[currentCategory].tests == undefined)\n tests[currentCategory].tests = [];\n tests[currentCategory].tests.push(new Test(currentCategory, name, test, options));\n}\n/* Tests two objects for equality, throws an exception if they are not equal. */\nexport function expect(actual, expected = true, error) {\n if (error)\n error = `${error}, `;\n else\n error = '';\n if (actual !== expected)\n throw new Error(`${error}Expected \"${expected}\", got \"${actual}\"`);\n}\nexport function expectFloat(actual, expected, tolerance = 0.001, error) {\n if ((actual === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) ||\n (actual === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) ||\n (actual === Number.NaN && expected === Number.NaN) || (isNaN(actual) && isNaN(expected)))\n return;\n const areEqual = Math.abs(actual - expected) < tolerance;\n expect(areEqual, true, `${error !== null && error !== void 0 ? error : ''} (tolerance = ${tolerance})`);\n if (!areEqual)\n throw new Error(`Expected ${expected}, got ${actual} (tolerance = ${tolerance})`);\n}\nexport function expectTable(actual, expected, error) {\n const expectedRowCount = expected.rowCount;\n const actualRowCount = actual.rowCount;\n expect(actualRowCount, expectedRowCount, `${error !== null && error !== void 0 ? error : ''}, row count`);\n for (const column of expected.columns) {\n const actualColumn = actual.columns.byName(column.name);\n if (actualColumn == null)\n throw new Error(`Column ${column.name} not found`);\n if (actualColumn.type != column.type)\n throw new Error(`Column ${column.name} type expected ${column.type} got ${actualColumn.type}`);\n for (let i = 0; i < expectedRowCount; i++) {\n const value = column.get(i);\n const actualValue = actualColumn.get(i);\n if (column.type == DG.TYPE.FLOAT)\n expectFloat(actualValue, value, 0.0001, error);\n else if (column.type == DG.TYPE.DATE_TIME)\n expect(actualValue.isSame(value), true, error);\n else\n expect(actualValue, value, error);\n }\n }\n}\nexport function expectObject(actual, expected) {\n for (const [expectedKey, expectedValue] of Object.entries(expected)) {\n if (!actual.hasOwnProperty(expectedKey))\n throw new Error(`Expected property \"${expectedKey}\" not found`);\n const actualValue = actual[expectedKey];\n if (actualValue instanceof Array && expectedValue instanceof Array)\n expectArray(actualValue, expectedValue);\n else if (actualValue instanceof Object && expectedValue instanceof Object)\n expectObject(actualValue, expectedValue);\n else if (Number.isFinite(actualValue) && Number.isFinite(expectedValue))\n expectFloat(actualValue, expectedValue);\n else if (actualValue != expectedValue)\n throw new Error(`Expected (${expectedValue}) for key '${expectedKey}', got (${actualValue})`);\n }\n}\nexport function expectArray(actual, expected) {\n const actualLength = actual.length;\n const expectedLength = expected.length;\n if (actualLength != expectedLength) {\n throw new Error(`Arrays are of different length: actual array length is ${actualLength} ` +\n `and expected array length is ${expectedLength}`);\n }\n for (let i = 0; i < actualLength; i++) {\n if (actual[i] instanceof Array && expected[i] instanceof Array)\n expectArray(actual[i], expected[i]);\n else if (actual[i] instanceof Object && expected[i] instanceof Object)\n expectObject(actual[i], expected[i]);\n else if (actual[i] != expected[i])\n throw new Error(`Expected ${expected[i]} at position ${i}, got ${actual[i]}`);\n }\n}\n/* Defines a test suite. */\nexport function category(category, tests_, options) {\n var _a;\n currentCategory = category;\n tests_();\n if (tests[currentCategory]) {\n tests[currentCategory].clear = (_a = options === null || options === void 0 ? void 0 : options.clear) !== null && _a !== void 0 ? _a : true;\n tests[currentCategory].timeout = options === null || options === void 0 ? void 0 : options.timeout;\n tests[currentCategory].benchmarks = options === null || options === void 0 ? void 0 : options.benchmarks;\n tests[currentCategory].stressTests = options === null || options === void 0 ? void 0 : options.stressTests;\n }\n}\n/* Defines a function to be executed before the tests in this category are executed. */\nexport function before(before) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n tests[currentCategory].before = before;\n}\n/* Defines a function to be executed after the tests in this category are executed. */\nexport function after(after) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n tests[currentCategory].after = after;\n}\nfunction addNamespace(s, f) {\n return s.replace(new RegExp(f.name, 'gi'), f.nqName);\n}\nexport function initAutoTests(package_, module) {\n var _a, _b, _c, _d;\n return __awaiter(this, void 0, void 0, function* () {\n const packageId = package_.id;\n if (wasRegistered[packageId])\n return;\n const moduleTests = module ? module.tests : tests;\n if (moduleTests[autoTestsCatName] !== undefined ||\n moduleTests[demoCatName] !== undefined ||\n Object.keys(moduleTests).find((c) => c.startsWith(autoTestsCatName) || c.startsWith(coreCatName))) {\n wasRegistered[packageId] = true;\n return;\n }\n if (package_.name === 'DevTools' || (!!module && module._package.name === 'DevTools')) {\n for (const f of window.dartTests) {\n const arr = f.name.split(/\\s*\\|\\s*!/g);\n let name = (_a = arr.pop()) !== null && _a !== void 0 ? _a : f.name;\n let cat = arr.length ? coreCatName + ': ' + arr.join(': ') : coreCatName;\n let fullName = name.split(' | ');\n name = fullName[fullName.length - 1];\n fullName.unshift(cat);\n fullName.pop();\n cat = fullName.join(': ');\n if (moduleTests[cat] === undefined)\n moduleTests[cat] = { tests: [], clear: true };\n moduleTests[cat].tests.push(new Test(cat, name, f.test, { isAggregated: false, timeout: (_c = (_b = f.options) === null || _b === void 0 ? void 0 : _b.timeout) !== null && _c !== void 0 ? _c : STANDART_TIMEOUT, skipReason: (_d = f.options) === null || _d === void 0 ? void 0 : _d.skipReason }));\n }\n }\n const moduleAutoTests = [];\n const moduleDemo = [];\n const moduleDetectors = [];\n const packFunctions = yield grok.dapi.functions.filter(`package.id = \"${packageId}\"`).list();\n const reg = new RegExp(/skip:\\s*([^,\\s]+)|wait:\\s*(\\d+)|cat:\\s*([^,\\s]+)|timeout:\\s*(\\d+)/g);\n for (const f of packFunctions) {\n const tests = f.options['test'];\n const demo = f.options['demoPath'];\n if ((tests && Array.isArray(tests) && tests.length)) {\n for (let i = 0; i < tests.length; i++) {\n const res = tests[i].matchAll(reg);\n const map = {};\n Array.from(res).forEach((arr) => {\n if (arr[0].startsWith('skip'))\n map['skip'] = arr[1];\n else if (arr[0].startsWith('wait'))\n map['wait'] = parseInt(arr[2]);\n else if (arr[0].startsWith('cat'))\n map['cat'] = arr[3];\n else if (arr[0].startsWith('timeout'))\n map['timeout'] = parseInt(arr[4]);\n });\n const test = new Test(autoTestsCatName, tests.length === 1 ? f.name : `${f.name} ${i + 1}`, () => __awaiter(this, void 0, void 0, function* () {\n const res = yield grok.functions.eval(addNamespace(tests[i], f));\n if (map.wait)\n yield delay(map.wait);\n // eslint-disable-next-line no-throw-literal\n if (typeof res === 'boolean' && !res)\n throw `Failed: ${tests[i]}, expected true, got ${res}`;\n }), { skipReason: map.skip, timeout: DG.Test.isInBenchmark ? map.benchmarkTimeout : map.timeout });\n if (map.cat) {\n const cat = autoTestsCatName + ': ' + map.cat;\n test.category = cat;\n if (moduleTests[cat] === undefined)\n moduleTests[cat] = { tests: [], clear: true };\n moduleTests[cat].tests.push(test);\n }\n else\n moduleAutoTests.push(test);\n }\n }\n if (demo) {\n const wait = f.options['demoWait'] ? parseInt(f.options['demoWait']) : undefined;\n const test = new Test(demoCatName, f.friendlyName, () => __awaiter(this, void 0, void 0, function* () {\n grok.shell.isInDemo = true;\n if (grok.shell.view(DG.View.BROWSE) === undefined)\n grok.shell.v = DG.View.createByType(DG.View.BROWSE);\n yield delay(300);\n grok.shell.clearLastError();\n yield f.apply();\n yield delay(wait ? wait : 2000);\n const unhandled = yield grok.shell.lastError;\n if (unhandled)\n throw new Error(unhandled);\n grok.shell.isInDemo = false;\n }), { skipReason: f.options['demoSkip'] });\n moduleDemo.push(test);\n }\n if (f.hasTag('semTypeDetector')) {\n const test = new Test(detectorsCatName, f.friendlyName, () => __awaiter(this, void 0, void 0, function* () {\n const arr = [];\n for (const col of testData.clone().columns) {\n const res = yield f.apply([col]);\n arr.push(res || col.semType);\n }\n expect(arr.filter((i) => i).length, 1);\n }), { skipReason: f.options['skipTest'] });\n moduleDetectors.push(test);\n }\n }\n wasRegistered[packageId] = true;\n if (moduleAutoTests.length)\n moduleTests[autoTestsCatName] = { tests: moduleAutoTests, clear: true };\n if (moduleDemo.length)\n moduleTests[demoCatName] = { tests: moduleDemo, clear: true };\n if (moduleDetectors.length)\n moduleTests[detectorsCatName] = { tests: moduleDetectors, clear: false };\n });\n}\nfunction redefineConsole() {\n const logs = [];\n console.log = (...args) => {\n logs.push(...args);\n stdLog(...args);\n };\n console.info = (...args) => {\n logs.push(...args);\n stdInfo(...args);\n };\n console.warn = (...args) => {\n logs.push(...args);\n stdWarn(...args);\n };\n console.error = (...args) => {\n logs.push(...args);\n stdError(...args);\n };\n return logs;\n}\nfunction resetConsole() {\n console.log = stdLog;\n console.info = stdInfo;\n console.warn = stdWarn;\n console.error = stdError;\n}\nexport function runTests(options) {\n var _a, _b, _c;\n var _d;\n return __awaiter(this, void 0, void 0, function* () {\n const package_ = (_b = (_a = grok.functions.getCurrentCall()) === null || _a === void 0 ? void 0 : _a.func) === null || _b === void 0 ? void 0 : _b.package;\n yield initAutoTests(package_);\n const results = [];\n console.log(`Running tests`);\n options !== null && options !== void 0 ? options : (options = {});\n (_c = (_d = options).testContext) !== null && _c !== void 0 ? _c : (_d.testContext = new TestContext());\n grok.shell.clearLastError();\n const categories = [];\n const logs = redefineConsole();\n if (options === null || options === void 0 ? void 0 : options.stressTest) {\n yield InvokeStressTests(options);\n }\n else {\n yield InvokeAllTests(tests, options);\n }\n for (let r of results) {\n r.result = r.result.toString().replace(/\"/g, '\\'');\n if (r.logs != undefined)\n r.logs = r.logs.toString().replace(/\"/g, '\\'');\n }\n return results;\n function InvokeCategoryMethod(method, category) {\n return __awaiter(this, void 0, void 0, function* () {\n var invokationResult = undefined;\n try {\n if (method !== undefined) {\n yield timeout(() => __awaiter(this, void 0, void 0, function* () {\n yield method();\n }), 100000, `before ${category}: timeout error`);\n }\n }\n catch (x) {\n invokationResult = yield getResult(x);\n }\n return invokationResult;\n });\n }\n function InvokeStressTests(options) {\n var _a, _b, _c, _d, _e, _f;\n return __awaiter(this, void 0, void 0, function* () {\n let testInvocationMap = [];\n for (const [key, value] of Object.entries(tests)) {\n let testsToInvoke = (_a = value.tests) === null || _a === void 0 ? void 0 : _a.filter((test) => { var _a; return (_a = test.options) === null || _a === void 0 ? void 0 : _a.stressTest; });\n if (value.stressTests) {\n testsToInvoke = (_b = value.tests) === null || _b === void 0 ? void 0 : _b.filter((test) => { var _a, _b; return ((_a = test.options) === null || _a === void 0 ? void 0 : _a.stressTest) === undefined || ((_b = test.options) === null || _b === void 0 ? void 0 : _b.stressTest) === true; });\n }\n const skipped = (_c = value.tests) === null || _c === void 0 ? void 0 : _c.every((t) => { var _a; return (_a = t.options) === null || _a === void 0 ? void 0 : _a.skipReason; });\n if (skipped)\n continue;\n for (let test of testsToInvoke !== null && testsToInvoke !== void 0 ? testsToInvoke : []) {\n if (((_d = test.options) === null || _d === void 0 ? void 0 : _d.skipReason) == null) {\n testInvocationMap.push({ test, value });\n }\n }\n }\n testInvocationMap = shuffle(testInvocationMap);\n const res = [];\n for (let testingObj of testInvocationMap) {\n yield InvokeCategoryMethod(testingObj.value.before, (_e = options.category) !== null && _e !== void 0 ? _e : '');\n let testRun = yield execTest(testingObj.test, options === null || options === void 0 ? void 0 : options.test, logs, DG.Test.isInBenchmark ? testingObj.value.benchmarkTimeout : testingObj.value.timeout, package_.name, options.verbose);\n if (testRun)\n res.push(testRun);\n console.log(`Test: ${test === null || test === void 0 ? void 0 : test.name}; result: ${testRun}`);\n yield InvokeCategoryMethod(testingObj.value.after, (_f = options.category) !== null && _f !== void 0 ? _f : '');\n }\n results.push(...res);\n });\n }\n function InvokeAllTests(categoriesToInvoke, options) {\n var _a, _b, _c, _d, _e, _f, _g;\n return __awaiter(this, void 0, void 0, function* () {\n try {\n for (const [key, value] of Object.entries(categoriesToInvoke)) {\n if ((!!(options === null || options === void 0 ? void 0 : options.category) && !key.toLowerCase().startsWith(options === null || options === void 0 ? void 0 : options.category.toLowerCase())) ||\n ((_a = options.exclude) === null || _a === void 0 ? void 0 : _a.some((c) => key.startsWith(c))))\n continue;\n stdLog(`Started ${key} category`);\n const skipped = (_b = value.tests) === null || _b === void 0 ? void 0 : _b.every((t) => { var _a; return (_a = t.options) === null || _a === void 0 ? void 0 : _a.skipReason; });\n if (!skipped)\n value.beforeStatus = yield InvokeCategoryMethod(value.before, (_c = options.category) !== null && _c !== void 0 ? _c : '');\n const t = (_d = value.tests) !== null && _d !== void 0 ? _d : [];\n const res = [];\n if (value.clear) {\n for (let i = 0; i < t.length; i++) {\n if (t[i].options) {\n if (((_e = t[i].options) === null || _e === void 0 ? void 0 : _e.benchmark) === undefined) {\n if (!t[i].options)\n t[i].options = {};\n t[i].options.benchmark = (_f = value.benchmarks) !== null && _f !== void 0 ? _f : false;\n }\n }\n let testRun = yield execTest(t[i], options === null || options === void 0 ? void 0 : options.test, logs, DG.Test.isInBenchmark ? value.benchmarkTimeout : value.timeout, package_.name, options.verbose);\n if (testRun)\n res.push(testRun);\n grok.shell.closeAll();\n DG.Balloon.closeAll();\n }\n }\n else {\n for (let i = 0; i < t.length; i++) {\n let testRun = yield execTest(t[i], options === null || options === void 0 ? void 0 : options.test, logs, DG.Test.isInBenchmark ? value.benchmarkTimeout : value.timeout, package_.name, options.verbose);\n if (testRun)\n res.push(testRun);\n }\n }\n const data = res.filter((d) => d.result != 'skipped');\n if (!skipped)\n value.afterStatus = yield InvokeCategoryMethod(value.after, (_g = options.category) !== null && _g !== void 0 ? _g : '');\n // Clear after category\n // grok.shell.closeAll();\n // DG.Balloon.closeAll();\n if (value.afterStatus)\n data.push({ date: new Date().toISOString(), logs: '', category: key, name: 'after', result: value.afterStatus, success: false, ms: 0, skipped: false });\n if (value.beforeStatus)\n data.push({ date: new Date().toISOString(), logs: '', category: key, name: 'before', result: value.beforeStatus, success: false, ms: 0, skipped: false });\n results.push(...data);\n }\n }\n finally {\n resetConsole();\n }\n if (options.testContext.catchUnhandled && (!DG.Test.isInBenchmark)) {\n yield delay(1000);\n const error = yield grok.shell.lastError;\n const params = {\n logs: '',\n date: new Date().toISOString(),\n category: 'Unhandled exceptions',\n name: 'Exception',\n result: error !== null && error !== void 0 ? error : '', success: !error, ms: 0, skipped: false\n };\n results.push(params);\n params.package = package_.name;\n if (grok.shell.reportTest != null)\n yield grok.shell.reportTest('package', params);\n else {\n yield fetch(`${grok.dapi.root}/log/tests/package`, {\n method: 'POST', headers: { 'Content-Type': 'application/json' },\n credentials: 'same-origin',\n body: JSON.stringify(params)\n });\n }\n }\n });\n }\n });\n}\nfunction getResult(x) {\n return __awaiter(this, void 0, void 0, function* () {\n return `${x.toString()}\\n${x.stack ? (yield DG.Logger.translateStackTrace(x.stack)) : ''}`;\n });\n}\nfunction execTest(t, predicate, logs, categoryTimeout, packageName, verbose) {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n return __awaiter(this, void 0, void 0, function* () {\n logs.length = 0;\n let r;\n let type = 'package';\n const filter = predicate != undefined && (t.name.toLowerCase() !== predicate.toLowerCase());\n let skip = ((_a = t.options) === null || _a === void 0 ? void 0 : _a.skipReason) || filter;\n let skipReason = filter ? 'skipped' : (_b = t.options) === null || _b === void 0 ? void 0 : _b.skipReason;\n if (DG.Test.isInBenchmark && !((_c = t.options) === null || _c === void 0 ? void 0 : _c.benchmark)) {\n stdLog(`SKIPPED: ${t.category} ${t.name} doesnt available in benchmark mode`);\n return undefined;\n }\n if (!skip)\n stdLog(`Started ${t.category} ${t.name}`);\n const start = Date.now();\n try {\n if (skip)\n r = { date: new Date().toISOString(), success: true, result: skipReason, ms: 0, skipped: true };\n else {\n let timeout_ = ((_d = t.options) === null || _d === void 0 ? void 0 : _d.timeout) === STANDART_TIMEOUT &&\n categoryTimeout ? categoryTimeout : (_e = t.options) === null || _e === void 0 ? void 0 : _e.timeout;\n timeout_ = (timeout_ === STANDART_TIMEOUT && DG.Test.isInBenchmark) ? BENCHMARK_TIMEOUT : timeout_;\n r = { date: new Date().toISOString(), success: true, result: (_f = yield timeout(t.test, timeout_)) !== null && _f !== void 0 ? _f : 'OK', ms: 0, skipped: false };\n }\n }\n catch (x) {\n stdError(x);\n r = { date: new Date().toISOString(), success: false, result: yield getResult(x), ms: 0, skipped: false };\n }\n if (((_g = t.options) === null || _g === void 0 ? void 0 : _g.isAggregated) && r.result.constructor === DG.DataFrame) {\n const col = r.result.col('success');\n if (col)\n r.success = col.stats.sum === col.length;\n if (!verbose) {\n const df = r.result;\n df.columns.remove('stack');\n df.rows.removeWhere((r) => r.get('success'));\n r.result = df;\n }\n r.result = r.result.toCsv();\n }\n r.logs = logs.join('\\n');\n r.ms = Date.now() - start;\n if (!skip)\n stdLog(`Finished ${t.category} ${t.name} for ${r.ms} ms`);\n r.category = t.category;\n r.name = t.name;\n if (!filter) {\n let params = {\n 'success': r.success, 'result': r.result, 'ms': r.ms,\n 'skipped': r.skipped, 'package': packageName, 'category': t.category, 'name': t.name, 'logs': r.logs,\n };\n if (r.result.constructor == Object) {\n const res = Object.keys(r.result).reduce((acc, k) => (Object.assign(Object.assign({}, acc), { ['result.' + k]: r.result[k] })), {});\n params = Object.assign(Object.assign({}, params), res);\n }\n if (params.result instanceof DG.DataFrame)\n params.result = JSON.stringify((_h = params.result) === null || _h === void 0 ? void 0 : _h.toJson()) || '';\n if (grok.shell.reportTest != null)\n yield grok.shell.reportTest(type, params);\n else {\n yield fetch(`${grok.dapi.root}/log/tests/${type}`, {\n method: 'POST', headers: { 'Content-Type': 'application/json' },\n credentials: 'same-origin',\n body: JSON.stringify(params)\n });\n }\n }\n return r;\n });\n}\nexport function shuffle(array) {\n const newArr = array.slice();\n newArr.sort(() => Math.random() - 0.5);\n return newArr;\n}\n;\n/* Waits [ms] milliseconds */\nexport function delay(ms) {\n return __awaiter(this, void 0, void 0, function* () {\n yield new Promise((r) => setTimeout(r, ms));\n });\n}\nexport function awaitCheck(checkHandler, error = 'Timeout exceeded', wait = 500, interval = 50) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n clearInterval(intervalId);\n reject(new Error(error));\n }, wait);\n // @ts-ignore\n const intervalId = setInterval(() => {\n if (checkHandler()) {\n clearInterval(intervalId);\n resolve();\n }\n }, interval);\n });\n });\n}\n// Returns test execution result or an error in case of timeout\nexport function timeout(func, testTimeout, timeoutReason = 'EXECUTION TIMEOUT') {\n return __awaiter(this, void 0, void 0, function* () {\n let timeout = null;\n const timeoutPromise = new Promise((_, reject) => {\n timeout = setTimeout(() => {\n // eslint-disable-next-line prefer-promise-reject-errors\n reject(timeoutReason);\n }, testTimeout);\n });\n try {\n return yield Promise.race([func(), timeoutPromise]);\n }\n finally {\n if (timeout)\n clearTimeout(timeout);\n }\n });\n}\nexport function isDialogPresent(dialogTitle) {\n const dialogs = DG.Dialog.getOpenDialogs();\n for (let i = 0; i < dialogs.length; i++) {\n if (dialogs[i].title == dialogTitle)\n return true;\n }\n return false;\n}\n/** Expects an asynchronous {@link action} to throw an exception. Use {@link check} to perform\n * deeper inspection of the exception if necessary.\n * @param {function(): Promise<void>} action\n * @param {function(any): boolean} check\n * @return {Promise<void>}\n */\nexport function expectExceptionAsync(action, check) {\n return __awaiter(this, void 0, void 0, function* () {\n let caught = false;\n let checked = false;\n try {\n yield action();\n }\n catch (e) {\n caught = true;\n checked = !check || check(e);\n }\n finally {\n if (!caught)\n throw new Error('An exception is expected but not thrown');\n if (!checked)\n throw new Error('An expected exception is thrown, but it does not satisfy the condition');\n }\n });\n}\nconst catDF = DG.DataFrame.fromColumns([DG.Column.fromStrings('col', ['val1', 'val2', 'val3'])]);\n/**\n * Universal test for viewers. It search viewers in DOM by tags: canvas, svg, img, input, h1, a\n * @param {string} v Viewer name\n * @param {DG.DataFrame} df Dataframe to use. Should have at least 3 rows\n * @param {boolean} options.detectSemanticTypes Specify whether to detect semantic types or not\n * @param {boolean} options.readOnly If set to true, the dataframe will not be modified during the test\n * @param {boolean} options.arbitraryDfTest If set to false, test on arbitrary dataframe\n * (one categorical column) will not be performed\n * @param {object} options List of options (optional)\n * @return {Promise<void>} The test is considered successful if it completes without errors\n */\nexport function testViewer(v, df, options) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n const packageName = (_a = options === null || options === void 0 ? void 0 : options.packageName) !== null && _a !== void 0 ? _a : '';\n if (options === null || options === void 0 ? void 0 : options.detectSemanticTypes)\n yield grok.data.detectSemanticTypes(df);\n const tv = grok.shell.addTableView(df);\n try {\n //1. Open, do nothing and close\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded);\n //in case viewer with async rendering - wait for render to complete\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, undefined, options.awaitViewer);\n //2. Open viewer, run selection, filter, etc. and close\n if (!(options === null || options === void 0 ? void 0 : options.readOnly)) {\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, selectFilterChangeCurrent);\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, selectFilterChangeCurrent, options.awaitViewer);\n }\n //2. Open viewer, change options, save layout and close\n let propsAndLayout = null;\n propsAndLayout = yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, changeOptionsSaveLayout);\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n propsAndLayout = yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, changeOptionsSaveLayout, options.awaitViewer);\n //3. Load layout\n yield testViewerInternal(tv, v, packageName, grok.events.onViewLayoutApplied, loadLayout, undefined, propsAndLayout === null || propsAndLayout === void 0 ? void 0 : propsAndLayout.layout, { savedProps: propsAndLayout === null || propsAndLayout === void 0 ? void 0 : propsAndLayout.savedProps });\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewLayoutApplied, loadLayout, options.awaitViewer, propsAndLayout === null || propsAndLayout === void 0 ? void 0 : propsAndLayout.layout, { savedProps: propsAndLayout === null || propsAndLayout === void 0 ? void 0 : propsAndLayout.savedProps });\n //4. Open viewer on arbitary dataset\n if ((options === null || options === void 0 ? void 0 : options.arbitraryDfTest) !== false) {\n tv.dataFrame = catDF;\n yield delay(50);\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded);\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, undefined, options.awaitViewer);\n }\n //5. Call postponed filtering\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, filterAsync);\n if (options === null || options === void 0 ? void 0 : options.awaitViewer)\n yield testViewerInternal(tv, v, packageName, grok.events.onViewerAdded, filterAsync, options.awaitViewer);\n }\n finally {\n // closeAll() is handling by common test workflow\n // grok.shell.closeAll();\n // DG.Balloon.closeAll();\n }\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXRDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU3QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSx5QkFBeUIsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXRJLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0FBQy9CLE1BQU0saUJBQWlCLEdBQUcsUUFBUSxDQUFDO0FBRW5DLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3pDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzNDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzNDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRTdDLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FFZCxFQUFFLENBQUM7QUFFUCxNQUFNLGdCQUFnQixHQUFHLFlBQVksQ0FBQztBQUN0QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUM7QUFDM0IsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUM7QUFDckMsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDO0FBQzNCLE1BQU0sYUFBYSxHQUErQixFQUFFLENBQUM7QUFDckQsTUFBTSxDQUFDLElBQUksZUFBdUIsQ0FBQztBQUVuQyxNQUFNLEtBQVcsTUFBTSxDQUt0QjtBQUxE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SyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNoQixNQUFNLGtCQUFrQixDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ3hFLElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFdBQVc7b0JBQ3RCLE1BQU0sa0JBQWtCLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLE9BQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUM1RztZQUVELDZCQUE2QjtZQUM3QixNQUFNLGtCQUFrQixDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ3JGLElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFdBQVc7Z0JBQ3RCLE1BQU0sa0JBQWtCLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLE9BQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUU5RztnQkFBUztZQUNSLGlEQUFpRDtZQUNqRCx5QkFBeUI7WUFDekIseUJBQXlCO1NBQzFCOztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGVzdERhdGEgfSBmcm9tICcuL2RhdGFmcmFtZS11dGlscyc7XG5pbXBvcnQgVGltZW91dCA9IE5vZGVKUy5UaW1lb3V0O1xuaW1wb3J0IHsgY2hhbmdlT3B0aW9uc1NhdmVMYXlvdXQsIGZpbHRlckFzeW5jLCBsb2FkTGF5b3V0LCBzZWxlY3RGaWx0ZXJDaGFuZ2VDdXJyZW50LCB0ZXN0Vmlld2VySW50ZXJuYWwgfSBmcm9tICcuL3Rlc3Qtdmlld2VyLXV0aWxzJztcblxuY29uc3QgU1RBTkRBUlRfVElNRU9VVCA9IDMwMDAwO1xuY29uc3QgQkVOQ0hNQVJLX1RJTUVPVVQgPSAxMDgwMDAwMDtcblxuY29uc3Qgc3RkTG9nID0gY29uc29sZS5sb2cuYmluZChjb25zb2xlKTtcbmNvbnN0IHN0ZEluZm8gPSBjb25zb2xlLmluZm8uYmluZChjb25zb2xlKTtcbmNvbnN0IHN0ZFdhcm4gPSBjb25zb2xlLndhcm4uYmluZChjb25zb2xlKTtcbmNvbnN0IHN0ZEVycm9yID0gY29uc29sZS5lcnJvci5iaW5kKGNvbnNvbGUpO1xuXG5leHBvcnQgY29uc3QgdGVzdHM6IHtcbiAgW2tleTogc3RyaW5nXTogQ2F0ZWdvcnlcbn0gPSB7fTtcblxuY29uc3QgYXV0b1Rlc3RzQ2F0TmFtZSA9ICdBdXRvIFRlc3RzJztcbmNvbnN0IGRlbW9DYXROYW1lID0gJ0RlbW8nO1xuY29uc3QgZGV0ZWN0b3JzQ2F0TmFtZSA9ICdEZXRlY3RvcnMnO1xuY29uc3QgY29yZUNhdE5hbWUgPSAnQ29yZSc7XG5jb25zdCB3YXNSZWdpc3RlcmVkOiB7IFtrZXk6IHN0cmluZ106IGJvb2xlYW4gfSA9IHt9O1xuZXhwb3J0IGxldCBjdXJyZW50Q2F0ZWdvcnk6IHN0cmluZztcblxuZXhwb3J0IG5hbWVzcGFjZSBhc3N1cmUge1xuICBleHBvcnQgZnVuY3Rpb24gbm90TnVsbCh2YWx1ZTogYW55LCBuYW1lPzogc3RyaW5nKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bmFtZSA9PSBudWxsID8gJ1ZhbHVlJyA6IG5hbWV9IG5vdCBkZWZpbmVkYCk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZXN0T3B0aW9ucyB7XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIGJlbmNobWFya1RpbWVvdXQ/OiBudW1iZXI7XG4gIHVuaGFuZGxlZEV4Y2VwdGlvblRpbWVvdXQ/OiBudW1iZXI7XG4gIHNraXBSZWFzb24/OiBzdHJpbmc7XG4gIGlzQWdncmVnYXRlZD86IGJvb2xlYW47XG4gIGJlbmNobWFyaz86IGJvb2xlYW47XG4gIHN0cmVzc1Rlc3Q/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhdGVnb3J5T3B0aW9ucyB7XG4gIGNsZWFyPzogYm9vbGVhbjtcbiAgdGltZW91dD86IG51bWJlcjtcbiAgYmVuY2htYXJrcz86IGJvb2xlYW47XG4gIHN0cmVzc1Rlc3RzPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFRlc3RDb250ZXh0IHtcbiAgc3RyZXNzVGVzdD86IGJvb2xlYW47XG4gIGNhdGNoVW5oYW5kbGVkID0gdHJ1ZTtcbiAgcmVwb3J0ID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoY2F0Y2hVbmhhbmRsZWQ/OiBib29sZWFuLCByZXBvcnQ/OiBib29sZWFuKSB7XG4gICAgaWYgKGNhdGNoVW5oYW5kbGVkICE9PSB1bmRlZmluZWQpIHRoaXMuY2F0Y2hVbmhhbmRsZWQgPSBjYXRjaFVuaGFuZGxlZDtcbiAgICBpZiAocmVwb3J0ICE9PSB1bmRlZmluZWQpIHRoaXMucmVwb3J0ID0gcmVwb3J0O1xuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgVGVzdCB7XG4gIHRlc3Q6ICgpID0+IFByb21pc2U8YW55PjtcbiAgbmFtZTogc3RyaW5nO1xuICBjYXRlZ29yeTogc3RyaW5nO1xuICBvcHRpb25zPzogVGVzdE9wdGlvbnM7XG5cbiAgY29uc3RydWN0b3IoY2F0ZWdvcnk6IHN0cmluZywgbmFtZTogc3RyaW5nLCB0ZXN0OiAoKSA9PiBQcm9taXNlPGFueT4sIG9wdGlvbnM/OiBUZXN0T3B0aW9ucykge1xuICAgIHRoaXMuY2F0ZWdvcnkgPSBjYXRlZ29yeTtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIG9wdGlvbnMgPz89IHt9O1xuICAgIG9wdGlvbnMudGltZW91dCA/Pz0gU1RBTkRBUlRfVElNRU9VVDtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMudGVzdCA9IGFzeW5jICgpOiBQcm9taXNlPGFueT4gPT4ge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9ICcnO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHRlc3QoKTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENhdGVnb3J5IHtcbiAgdGVzdHM/OiBUZXN0W107XG4gIGJlZm9yZT86ICgpID0+IFByb21pc2U8dm9pZD47XG4gIGFmdGVyPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblxuICBiZWZvcmVTdGF0dXM/OiBzdHJpbmc7XG4gIGFmdGVyU3RhdHVzPzogc3RyaW5nO1xuICBjbGVhcj86IGJvb2xlYW47XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIGJlbmNobWFya3M/OiBib29sZWFuO1xuICBiZW5jaG1hcmtUaW1lb3V0PzogbnVtYmVyO1xuICBzdHJlc3NUZXN0cz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBUZXN0RXhlY3V0aW9uT3B0aW9ucyB7XG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xuICB0ZXN0Pzogc3RyaW5nO1xuICB0ZXN0Q29udGV4dD86IFRlc3RDb250ZXh0O1xuICBleGNsdWRlPzogc3RyaW5nW107XG4gIHZlcmJvc2U/OiBib29sZWFuO1xuICBzdHJlc3NUZXN0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRlc3RFdmVudDxUPihldmVudDogT2JzZXJ2YWJsZTxUPixcbiAgaGFuZGxlcjogKGFyZ3M6IFQpID0+IHZvaWQsIHRyaWdnZXI6ICgpID0+IHZvaWQsIG1zOiBudW1iZXIgPSAwLCByZWFzb246IHN0cmluZyA9IGB0aW1lb3V0YFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdWIgPSBldmVudC5zdWJzY3JpYmUoKGFyZ3M6IFQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGhhbmRsZXIoYXJncyk7XG4gICAgICAgIHJlc29sdmUoJ09LJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9yc1xuICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgfSwgbXMpO1xuICAgIHRyaWdnZXIoKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZXN0RXZlbnRBc3luYzxUPihldmVudDogT2JzZXJ2YWJsZTxUPixcbiAgaGFuZGxlcjogKGFyZ3M6IFQpID0+IFByb21pc2U8dm9pZD4sIHRyaWdnZXI6ICgpID0+IHZvaWQsIG1zOiBudW1iZXIgPSAwLCByZWFzb246IHN0cmluZyA9IGB0aW1lb3V0YFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdWIgPSBldmVudC5zdWJzY3JpYmUoKGFyZ3M6IFQpID0+IHtcbiAgICAgIGhhbmRsZXIoYXJncykudGhlbigoKSA9PiB7XG4gICAgICAgIHJlc29sdmUoJ09LJyk7XG4gICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9KS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1wcm9taXNlLXJlamVjdC1lcnJvcnNcbiAgICAgIHJlamVjdChyZWFzb24pO1xuICAgIH0sIG1zKTtcbiAgICB0cmlnZ2VyKCk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGVzdChuYW1lOiBzdHJpbmcsIHRlc3Q6ICgpID0+IFByb21pc2U8YW55Piwgb3B0aW9ucz86IFRlc3RPcHRpb25zKTogdm9pZCB7XG4gIGlmICh0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldID09IHVuZGVmaW5lZClcbiAgICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldID0ge307XG4gIGlmICh0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLnRlc3RzID09IHVuZGVmaW5lZClcbiAgICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLnRlc3RzID0gW107XG4gIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMhLnB1c2gobmV3IFRlc3QoY3VycmVudENhdGVnb3J5LCBuYW1lLCB0ZXN0LCBvcHRpb25zKSk7XG59XG5cbi8qIFRlc3RzIHR3byBvYmplY3RzIGZvciBlcXVhbGl0eSwgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGV5IGFyZSBub3QgZXF1YWwuICovXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0KGFjdHVhbDogYW55LCBleHBlY3RlZDogYW55ID0gdHJ1ZSwgZXJyb3I/OiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKGVycm9yKVxuICAgIGVycm9yID0gYCR7ZXJyb3J9LCBgO1xuICBlbHNlIGVycm9yID0gJyc7XG4gIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKVxuICAgIHRocm93IG5ldyBFcnJvcihgJHtlcnJvcn1FeHBlY3RlZCBcIiR7ZXhwZWN0ZWR9XCIsIGdvdCBcIiR7YWN0dWFsfVwiYCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RGbG9hdChhY3R1YWw6IG51bWJlciwgZXhwZWN0ZWQ6IG51bWJlciwgdG9sZXJhbmNlID0gMC4wMDEsIGVycm9yPzogc3RyaW5nKTogdm9pZCB7XG4gIGlmICgoYWN0dWFsID09PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgJiYgZXhwZWN0ZWQgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSkgfHxcbiAgICAoYWN0dWFsID09PSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkgJiYgZXhwZWN0ZWQgPT09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSkgfHxcbiAgICAoYWN0dWFsID09PSBOdW1iZXIuTmFOICYmIGV4cGVjdGVkID09PSBOdW1iZXIuTmFOKSB8fCAoaXNOYU4oYWN0dWFsKSAmJiBpc05hTihleHBlY3RlZCkpKVxuICAgIHJldHVybjtcbiAgY29uc3QgYXJlRXF1YWwgPSBNYXRoLmFicyhhY3R1YWwgLSBleHBlY3RlZCkgPCB0b2xlcmFuY2U7XG4gIGV4cGVjdChhcmVFcXVhbCwgdHJ1ZSwgYCR7ZXJyb3IgPz8gJyd9ICh0b2xlcmFuY2UgPSAke3RvbGVyYW5jZX0pYCk7XG4gIGlmICghYXJlRXF1YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSwgZ290ICR7YWN0dWFsfSAodG9sZXJhbmNlID0gJHt0b2xlcmFuY2V9KWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0VGFibGUoYWN0dWFsOiBERy5EYXRhRnJhbWUsIGV4cGVjdGVkOiBERy5EYXRhRnJhbWUsIGVycm9yPzogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGV4cGVjdGVkUm93Q291bnQgPSBleHBlY3RlZC5yb3dDb3VudDtcbiAgY29uc3QgYWN0dWFsUm93Q291bnQgPSBhY3R1YWwucm93Q291bnQ7XG4gIGV4cGVjdChhY3R1YWxSb3dDb3VudCwgZXhwZWN0ZWRSb3dDb3VudCwgYCR7ZXJyb3IgPz8gJyd9LCByb3cgY291bnRgKTtcblxuICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBleHBlY3RlZC5jb2x1bW5zKSB7XG4gICAgY29uc3QgYWN0dWFsQ29sdW1uID0gYWN0dWFsLmNvbHVtbnMuYnlOYW1lKGNvbHVtbi5uYW1lKTtcbiAgICBpZiAoYWN0dWFsQ29sdW1uID09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiAke2NvbHVtbi5uYW1lfSBub3QgZm91bmRgKTtcbiAgICBpZiAoYWN0dWFsQ29sdW1uLnR5cGUgIT0gY29sdW1uLnR5cGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiAke2NvbHVtbi5uYW1lfSB0eXBlIGV4cGVjdGVkICR7Y29sdW1uLnR5cGV9IGdvdCAke2FjdHVhbENvbHVtbi50eXBlfWApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRSb3dDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbHVtbi5nZXQoaSk7XG4gICAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGFjdHVhbENvbHVtbi5nZXQoaSk7XG4gICAgICBpZiAoY29sdW1uLnR5cGUgPT0gREcuVFlQRS5GTE9BVClcbiAgICAgICAgZXhwZWN0RmxvYXQoYWN0dWFsVmFsdWUsIHZhbHVlLCAwLjAwMDEsIGVycm9yKTtcbiAgICAgIGVsc2UgaWYgKGNvbHVtbi50eXBlID09IERHLlRZUEUuREFURV9USU1FKVxuICAgICAgICBleHBlY3QoYWN0dWFsVmFsdWUuaXNTYW1lKHZhbHVlKSwgdHJ1ZSwgZXJyb3IpO1xuICAgICAgZWxzZVxuICAgICAgICBleHBlY3QoYWN0dWFsVmFsdWUsIHZhbHVlLCBlcnJvcik7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RPYmplY3QoYWN0dWFsOiB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBleHBlY3RlZDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkge1xuICBmb3IgKGNvbnN0IFtleHBlY3RlZEtleSwgZXhwZWN0ZWRWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKCFhY3R1YWwuaGFzT3duUHJvcGVydHkoZXhwZWN0ZWRLZXkpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBwcm9wZXJ0eSBcIiR7ZXhwZWN0ZWRLZXl9XCIgbm90IGZvdW5kYCk7XG5cbiAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGFjdHVhbFtleHBlY3RlZEtleV07XG4gICAgaWYgKGFjdHVhbFZhbHVlIGluc3RhbmNlb2YgQXJyYXkgJiYgZXhwZWN0ZWRWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KVxuICAgICAgZXhwZWN0QXJyYXkoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKGFjdHVhbFZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmIGV4cGVjdGVkVmFsdWUgaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgICBleHBlY3RPYmplY3QoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKE51bWJlci5pc0Zpbml0ZShhY3R1YWxWYWx1ZSkgJiYgTnVtYmVyLmlzRmluaXRlKGV4cGVjdGVkVmFsdWUpKVxuICAgICAgZXhwZWN0RmxvYXQoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKGFjdHVhbFZhbHVlICE9IGV4cGVjdGVkVmFsdWUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICgke2V4cGVjdGVkVmFsdWV9KSBmb3Iga2V5ICcke2V4cGVjdGVkS2V5fScsIGdvdCAoJHthY3R1YWxWYWx1ZX0pYCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGVjdEFycmF5KGFjdHVhbDogQXJyYXlMaWtlPGFueT4sIGV4cGVjdGVkOiBBcnJheUxpa2U8YW55Pikge1xuICBjb25zdCBhY3R1YWxMZW5ndGggPSBhY3R1YWwubGVuZ3RoO1xuICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDtcblxuICBpZiAoYWN0dWFsTGVuZ3RoICE9IGV4cGVjdGVkTGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBcnJheXMgYXJlIG9mIGRpZmZlcmVudCBsZW5ndGg6IGFjdHVhbCBhcnJheSBsZW5ndGggaXMgJHthY3R1YWxMZW5ndGh9IGAgK1xuICAgICAgYGFuZCBleHBlY3RlZCBhcnJheSBsZW5ndGggaXMgJHtleHBlY3RlZExlbmd0aH1gKTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0dWFsTGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoYWN0dWFsW2ldIGluc3RhbmNlb2YgQXJyYXkgJiYgZXhwZWN0ZWRbaV0gaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgIGV4cGVjdEFycmF5KGFjdHVhbFtpXSwgZXhwZWN0ZWRbaV0pO1xuICAgIGVsc2UgaWYgKGFjdHVhbFtpXSBpbnN0YW5jZW9mIE9iamVjdCAmJiBleHBlY3RlZFtpXSBpbnN0YW5jZW9mIE9iamVjdClcbiAgICAgIGV4cGVjdE9iamVjdChhY3R1YWxbaV0sIGV4cGVjdGVkW2ldKTtcbiAgICBlbHNlIGlmIChhY3R1YWxbaV0gIT0gZXhwZWN0ZWRbaV0pXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7ZXhwZWN0ZWRbaV19IGF0IHBvc2l0aW9uICR7aX0sIGdvdCAke2FjdHVhbFtpXX1gKTtcbiAgfVxufVxuXG4vKiBEZWZpbmVzIGEgdGVzdCBzdWl0ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYXRlZ29yeShjYXRlZ29yeTogc3RyaW5nLCB0ZXN0c186ICgpID0+IHZvaWQsIG9wdGlvbnM/OiBDYXRlZ29yeU9wdGlvbnMpOiB2b2lkIHtcbiAgY3VycmVudENhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gIHRlc3RzXygpO1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSkge1xuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0uY2xlYXIgPSBvcHRpb25zPy5jbGVhciA/PyB0cnVlO1xuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGltZW91dCA9IG9wdGlvbnM/LnRpbWVvdXQ7XG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XS5iZW5jaG1hcmtzID0gb3B0aW9ucz8uYmVuY2htYXJrcztcbiAgICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLnN0cmVzc1Rlc3RzID0gb3B0aW9ucz8uc3RyZXNzVGVzdHM7XG4gIH1cbn1cblxuLyogRGVmaW5lcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGJlZm9yZSB0aGUgdGVzdHMgaW4gdGhpcyBjYXRlZ29yeSBhcmUgZXhlY3V0ZWQuICovXG5leHBvcnQgZnVuY3Rpb24gYmVmb3JlKGJlZm9yZTogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSA9PSB1bmRlZmluZWQpXG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XSA9IHt9O1xuICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLmJlZm9yZSA9IGJlZm9yZTtcbn1cblxuLyogRGVmaW5lcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGFmdGVyIHRoZSB0ZXN0cyBpbiB0aGlzIGNhdGVnb3J5IGFyZSBleGVjdXRlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlcihhZnRlcjogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSA9PSB1bmRlZmluZWQpXG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XSA9IHt9O1xuICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLmFmdGVyID0gYWZ0ZXI7XG59XG5cbmZ1bmN0aW9uIGFkZE5hbWVzcGFjZShzOiBzdHJpbmcsIGY6IERHLkZ1bmMpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKG5ldyBSZWdFeHAoZi5uYW1lLCAnZ2knKSwgZi5ucU5hbWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5pdEF1dG9UZXN0cyhwYWNrYWdlXzogREcuUGFja2FnZSwgbW9kdWxlPzogYW55KSB7XG4gIGNvbnN0IHBhY2thZ2VJZCA9IHBhY2thZ2VfLmlkO1xuICBpZiAod2FzUmVnaXN0ZXJlZFtwYWNrYWdlSWRdKSByZXR1cm47XG4gIGNvbnN0IG1vZHVsZVRlc3RzID0gbW9kdWxlID8gbW9kdWxlLnRlc3RzIDogdGVzdHM7XG4gIGlmIChtb2R1bGVUZXN0c1thdXRvVGVzdHNDYXROYW1lXSAhPT0gdW5kZWZpbmVkIHx8XG4gICAgbW9kdWxlVGVzdHNbZGVtb0NhdE5hbWVdICE9PSB1bmRlZmluZWQgfHxcbiAgICBPYmplY3Qua2V5cyhtb2R1bGVUZXN0cykuZmluZCgoYykgPT4gYy5zdGFydHNXaXRoKGF1dG9UZXN0c0NhdE5hbWUpIHx8IGMuc3RhcnRzV2l0aChjb3JlQ2F0TmFtZSkpKSB7XG4gICAgd2FzUmVnaXN0ZXJlZFtwYWNrYWdlSWRdID0gdHJ1ZTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHBhY2thZ2VfLm5hbWUgPT09ICdEZXZUb29scycgfHwgKCEhbW9kdWxlICYmIG1vZHVsZS5fcGFja2FnZS5uYW1lID09PSAnRGV2VG9vbHMnKSkge1xuICAgIGZvciAoY29uc3QgZiBvZiAoPGFueT53aW5kb3cpLmRhcnRUZXN0cykge1xuICAgICAgY29uc3QgYXJyID0gZi5uYW1lLnNwbGl0KC9cXHMqXFx8XFxzKiEvZyk7XG4gICAgICBsZXQgbmFtZSA9IGFyci5wb3AoKSA/PyBmLm5hbWU7XG4gICAgICBsZXQgY2F0ID0gYXJyLmxlbmd0aCA/IGNvcmVDYXROYW1lICsgJzogJyArIGFyci5qb2luKCc6ICcpIDogY29yZUNhdE5hbWU7XG4gICAgICBsZXQgZnVsbE5hbWU6IHN0cmluZ1tdID0gbmFtZS5zcGxpdCgnIHwgJyk7XG4gICAgICBuYW1lID0gZnVsbE5hbWVbZnVsbE5hbWUubGVuZ3RoIC0gMV07XG4gICAgICBmdWxsTmFtZS51bnNoaWZ0KGNhdCk7XG4gICAgICBmdWxsTmFtZS5wb3AoKTtcbiAgICAgIGNhdCA9IGZ1bGxOYW1lLmpvaW4oJzogJyk7XG4gICAgICBpZiAobW9kdWxlVGVzdHNbY2F0XSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICBtb2R1bGVUZXN0c1tjYXRdID0geyB0ZXN0czogW10sIGNsZWFyOiB0cnVlIH07XG4gICAgICBtb2R1bGVUZXN0c1tjYXRdLnRlc3RzLnB1c2gobmV3IFRlc3QoY2F0LCBuYW1lLCBmLnRlc3QsIHsgaXNBZ2dyZWdhdGVkOiBmYWxzZSwgdGltZW91dDogZi5vcHRpb25zPy50aW1lb3V0ID8/IFNUQU5EQVJUX1RJTUVPVVQsIHNraXBSZWFzb246IGYub3B0aW9ucz8uc2tpcFJlYXNvbiB9KSk7XG4gICAgfVxuICB9XG4gIGNvbnN0IG1vZHVsZUF1dG9UZXN0cyA9IFtdO1xuICBjb25zdCBtb2R1bGVEZW1vID0gW107XG4gIGNvbnN0IG1vZHVsZURldGVjdG9ycyA9IFtdO1xuICBjb25zdCBwYWNrRnVuY3Rpb25zID0gYXdhaXQgZ3Jvay5kYXBpLmZ1bmN0aW9ucy5maWx0ZXIoYHBhY2thZ2UuaWQgPSBcIiR7cGFja2FnZUlkfVwiYCkubGlzdCgpO1xuICBjb25zdCByZWcgPSBuZXcgUmVnRXhwKC9za2lwOlxccyooW14sXFxzXSspfHdhaXQ6XFxzKihcXGQrKXxjYXQ6XFxzKihbXixcXHNdKyl8dGltZW91dDpcXHMqKFxcZCspL2cpO1xuICBmb3IgKGNvbnN0IGYgb2YgcGFja0Z1bmN0aW9ucykge1xuICAgIGNvbnN0IHRlc3RzID0gZi5vcHRpb25zWyd0ZXN0J107XG4gICAgY29uc3QgZGVtbyA9IGYub3B0aW9uc1snZGVtb1BhdGgnXTtcbiAgICBpZiAoKHRlc3RzICYmIEFycmF5LmlzQXJyYXkodGVzdHMpICYmIHRlc3RzLmxlbmd0aCkpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVzdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcmVzID0gKHRlc3RzW2ldIGFzIHN0cmluZykubWF0Y2hBbGwocmVnKTtcbiAgICAgICAgY29uc3QgbWFwOiB7IHNraXA/OiBzdHJpbmcsIHdhaXQ/OiBudW1iZXIsIGNhdD86IHN0cmluZywgdGltZW91dD86IG51bWJlciwgYmVuY2htYXJrVGltZW91dD86IG51bWJlciB9ID0ge307XG4gICAgICAgIEFycmF5LmZyb20ocmVzKS5mb3JFYWNoKChhcnIpID0+IHtcbiAgICAgICAgICBpZiAoYXJyWzBdLnN0YXJ0c1dpdGgoJ3NraXAnKSkgbWFwWydza2lwJ10gPSBhcnJbMV07XG4gICAgICAgICAgZWxzZSBpZiAoYXJyWzBdLnN0YXJ0c1dpdGgoJ3dhaXQnKSkgbWFwWyd3YWl0J10gPSBwYXJzZUludChhcnJbMl0pO1xuICAgICAgICAgIGVsc2UgaWYgKGFyclswXS5zdGFydHNXaXRoKCdjYXQnKSkgbWFwWydjYXQnXSA9IGFyclszXTtcbiAgICAgICAgICBlbHNlIGlmIChhcnJbMF0uc3RhcnRzV2l0aCgndGltZW91dCcpKSBtYXBbJ3RpbWVvdXQnXSA9IHBhcnNlSW50KGFycls0XSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB0ZXN0ID0gbmV3IFRlc3QoYXV0b1Rlc3RzQ2F0TmFtZSwgdGVzdHMubGVuZ3RoID09PSAxID8gZi5uYW1lIDogYCR7Zi5uYW1lfSAke2kgKyAxfWAsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBncm9rLmZ1bmN0aW9ucy5ldmFsKGFkZE5hbWVzcGFjZSh0ZXN0c1tpXSwgZikpO1xuICAgICAgICAgIGlmIChtYXAud2FpdCkgYXdhaXQgZGVsYXkobWFwLndhaXQpO1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gICAgICAgICAgaWYgKHR5cGVvZiByZXMgPT09ICdib29sZWFuJyAmJiAhcmVzKSB0aHJvdyBgRmFpbGVkOiAke3Rlc3RzW2ldfSwgZXhwZWN0ZWQgdHJ1ZSwgZ290ICR7cmVzfWA7XG4gICAgICAgIH0sIHsgc2tpcFJlYXNvbjogbWFwLnNraXAsIHRpbWVvdXQ6IERHLlRlc3QuaXNJbkJlbmNobWFyayA/IG1hcC5iZW5jaG1hcmtUaW1lb3V0IDogbWFwLnRpbWVvdXQgfSk7XG4gICAgICAgIGlmIChtYXAuY2F0KSB7XG4gICAgICAgICAgY29uc3QgY2F0OiBzdHJpbmcgPSBhdXRvVGVzdHNDYXROYW1lICsgJzogJyArIG1hcC5jYXQ7XG4gICAgICAgICAgdGVzdC5jYXRlZ29yeSA9IGNhdDtcbiAgICAgICAgICBpZiAobW9kdWxlVGVzdHNbY2F0XSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgbW9kdWxlVGVzdHNbY2F0XSA9IHsgdGVzdHM6IFtdLCBjbGVhcjogdHJ1ZSB9O1xuICAgICAgICAgIG1vZHVsZVRlc3RzW2NhdF0udGVzdHMucHVzaCh0ZXN0KTtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgbW9kdWxlQXV0b1Rlc3RzLnB1c2godGVzdCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChkZW1vKSB7XG4gICAgICBjb25zdCB3YWl0ID0gZi5vcHRpb25zWydkZW1vV2FpdCddID8gcGFyc2VJbnQoZi5vcHRpb25zWydkZW1vV2FpdCddKSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHRlc3QgPSBuZXcgVGVzdChkZW1vQ2F0TmFtZSwgZi5mcmllbmRseU5hbWUsIGFzeW5jICgpID0+IHtcbiAgICAgICAgZ3Jvay5zaGVsbC5pc0luRGVtbyA9IHRydWU7XG4gICAgICAgIGlmIChncm9rLnNoZWxsLnZpZXcoREcuVmlldy5CUk9XU0UpID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgZ3Jvay5zaGVsbC52ID0gREcuVmlldy5jcmVhdGVCeVR5cGUoREcuVmlldy5CUk9XU0UpO1xuICAgICAgICBhd2FpdCBkZWxheSgzMDApO1xuICAgICAgICBncm9rLnNoZWxsLmNsZWFyTGFzdEVycm9yKCk7XG4gICAgICAgIGF3YWl0IGYuYXBwbHkoKTtcbiAgICAgICAgYXdhaXQgZGVsYXkod2FpdCA/IHdhaXQgOiAyMDAwKTtcbiAgICAgICAgY29uc3QgdW5oYW5kbGVkID0gYXdhaXQgZ3Jvay5zaGVsbC5sYXN0RXJyb3I7XG4gICAgICAgIGlmICh1bmhhbmRsZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHVuaGFuZGxlZCk7XG4gICAgICAgIGdyb2suc2hlbGwuaXNJbkRlbW8gPSBmYWxzZTtcbiAgICAgIH0sIHsgc2tpcFJlYXNvbjogZi5vcHRpb25zWydkZW1vU2tpcCddIH0pO1xuICAgICAgbW9kdWxlRGVtby5wdXNoKHRlc3QpO1xuICAgIH1cbiAgICBpZiAoZi5oYXNUYWcoJ3NlbVR5cGVEZXRlY3RvcicpKSB7XG4gICAgICBjb25zdCB0ZXN0ID0gbmV3IFRlc3QoZGV0ZWN0b3JzQ2F0TmFtZSwgZi5mcmllbmRseU5hbWUsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYXJyID0gW107XG4gICAgICAgIGZvciAoY29uc3QgY29sIG9mIHRlc3REYXRhLmNsb25lKCkuY29sdW1ucykge1xuICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGYuYXBwbHkoW2NvbF0pO1xuICAgICAgICAgIGFyci5wdXNoKHJlcyB8fCBjb2wuc2VtVHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgZXhwZWN0KGFyci5maWx0ZXIoKGkpID0+IGkpLmxlbmd0aCwgMSk7XG4gICAgICB9LCB7IHNraXBSZWFzb246IGYub3B0aW9uc1snc2tpcFRlc3QnXSB9KTtcbiAgICAgIG1vZHVsZURldGVjdG9ycy5wdXNoKHRlc3QpO1xuICAgIH1cbiAgfVxuICB3YXNSZWdpc3RlcmVkW3BhY2thZ2VJZF0gPSB0cnVlO1xuICBpZiAobW9kdWxlQXV0b1Rlc3RzLmxlbmd0aClcbiAgICBtb2R1bGVUZXN0c1thdXRvVGVzdHNDYXROYW1lXSA9IHsgdGVzdHM6IG1vZHVsZUF1dG9UZXN0cywgY2xlYXI6IHRydWUgfTtcbiAgaWYgKG1vZHVsZURlbW8ubGVuZ3RoKVxuICAgIG1vZHVsZVRlc3RzW2RlbW9DYXROYW1lXSA9IHsgdGVzdHM6IG1vZHVsZURlbW8sIGNsZWFyOiB0cnVlIH07XG4gIGlmIChtb2R1bGVEZXRlY3RvcnMubGVuZ3RoKVxuICAgIG1vZHVsZVRlc3RzW2RldGVjdG9yc0NhdE5hbWVdID0geyB0ZXN0czogbW9kdWxlRGV0ZWN0b3JzLCBjbGVhcjogZmFsc2UgfTtcbn1cblxuZnVuY3Rpb24gcmVkZWZpbmVDb25zb2xlKCk6IGFueVtdIHtcbiAgY29uc3QgbG9nczogYW55W10gPSBbXTtcbiAgY29uc29sZS5sb2cgPSAoLi4uYXJncykgPT4ge1xuICAgIGxvZ3MucHVzaCguLi5hcmdzKTtcbiAgICBzdGRMb2coLi4uYXJncyk7XG4gIH07XG4gIGNvbnNvbGUuaW5mbyA9ICguLi5hcmdzKSA9PiB7XG4gICAgbG9ncy5wdXNoKC4uLmFyZ3MpO1xuICAgIHN0ZEluZm8oLi4uYXJncyk7XG4gIH07XG4gIGNvbnNvbGUud2FybiA9ICguLi5hcmdzKSA9PiB7XG4gICAgbG9ncy5wdXNoKC4uLmFyZ3MpO1xuICAgIHN0ZFdhcm4oLi4uYXJncyk7XG4gIH07XG4gIGNvbnNvbGUuZXJyb3IgPSAoLi4uYXJncykgPT4ge1xuICAgIGxvZ3MucHVzaCguLi5hcmdzKTtcbiAgICBzdGRFcnJvciguLi5hcmdzKTtcbiAgfTtcbiAgcmV0dXJuIGxvZ3M7XG59XG5cbmZ1bmN0aW9uIHJlc2V0Q29uc29sZSgpOiB2b2lkIHtcbiAgY29uc29sZS5sb2cgPSBzdGRMb2c7XG4gIGNvbnNvbGUuaW5mbyA9IHN0ZEluZm87XG4gIGNvbnNvbGUud2FybiA9IHN0ZFdhcm47XG4gIGNvbnNvbGUuZXJyb3IgPSBzdGRFcnJvcjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1blRlc3RzKG9wdGlvbnM/OiBUZXN0RXhlY3V0aW9uT3B0aW9ucykge1xuICBjb25zdCBwYWNrYWdlXyA9IGdyb2suZnVuY3Rpb25zLmdldEN1cnJlbnRDYWxsKCk/LmZ1bmM/LnBhY2thZ2U7XG4gIGF3YWl0IGluaXRBdXRvVGVzdHMocGFja2FnZV8pO1xuICBjb25zdCByZXN1bHRzOiB7XG4gICAgY2F0ZWdvcnk/OiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcsIHN1Y2Nlc3M6IGJvb2xlYW4sXG4gICAgcmVzdWx0OiBzdHJpbmcsIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4sIGxvZ3M/OiBzdHJpbmdcbiAgfVtdID0gW107XG4gIGNvbnNvbGUubG9nKGBSdW5uaW5nIHRlc3RzYCk7XG4gIG9wdGlvbnMgPz89IHt9O1xuICBvcHRpb25zIS50ZXN0Q29udGV4dCA/Pz0gbmV3IFRlc3RDb250ZXh0KCk7XG4gIGdyb2suc2hlbGwuY2xlYXJMYXN0RXJyb3IoKTtcbiAgY29uc3QgY2F0ZWdvcmllcyA9IFtdO1xuICBjb25zdCBsb2dzID0gcmVkZWZpbmVDb25zb2xlKCk7XG5cbiAgaWYgKG9wdGlvbnM/LnN0cmVzc1Rlc3QpIHtcbiAgICBhd2FpdCBJbnZva2VTdHJlc3NUZXN0cyhvcHRpb25zKTtcbiAgfVxuICBlbHNlIHtcbiAgICBhd2FpdCBJbnZva2VBbGxUZXN0cyh0ZXN0cywgb3B0aW9ucyk7XG4gIH1cbiAgZm9yIChsZXQgciBvZiByZXN1bHRzKSB7XG4gICAgci5yZXN1bHQgPSByLnJlc3VsdC50b1N0cmluZygpLnJlcGxhY2UoL1wiL2csICdcXCcnKTtcbiAgICBpZiAoci5sb2dzICE9IHVuZGVmaW5lZClcbiAgICAgIHIubG9ncyA9IHIubG9ncyEudG9TdHJpbmcoKS5yZXBsYWNlKC9cIi9nLCAnXFwnJyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG5cbiAgYXN5bmMgZnVuY3Rpb24gSW52b2tlQ2F0ZWdvcnlNZXRob2QobWV0aG9kOiAoKCkgPT4gUHJvbWlzZTx2b2lkPikgfCB1bmRlZmluZWQsIGNhdGVnb3J5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICAgIHZhciBpbnZva2F0aW9uUmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgIHRyeSB7XG4gICAgICBpZiAobWV0aG9kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXdhaXQgdGltZW91dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgbWV0aG9kKCk7XG4gICAgICAgIH0sIDEwMDAwMCwgYGJlZm9yZSAke2NhdGVnb3J5fTogdGltZW91dCBlcnJvcmApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKHg6IGFueSkge1xuICAgICAgaW52b2thdGlvblJlc3VsdCA9IGF3YWl0IGdldFJlc3VsdCh4KTtcbiAgICB9XG4gICAgcmV0dXJuIGludm9rYXRpb25SZXN1bHRcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIEludm9rZVN0cmVzc1Rlc3RzKG9wdGlvbnM6IFRlc3RFeGVjdXRpb25PcHRpb25zKSB7XG4gICAgbGV0IHRlc3RJbnZvY2F0aW9uTWFwOiBhbnlbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRlc3RzKSkge1xuICAgICAgbGV0IHRlc3RzVG9JbnZva2UgPSB2YWx1ZS50ZXN0cz8uZmlsdGVyKCh0ZXN0KSA9PiB0ZXN0Lm9wdGlvbnM/LnN0cmVzc1Rlc3QpO1xuICAgICAgaWYgKHZhbHVlLnN0cmVzc1Rlc3RzKSB7XG4gICAgICAgIHRlc3RzVG9JbnZva2UgPSB2YWx1ZS50ZXN0cz8uZmlsdGVyKCh0ZXN0KSA9PiB0ZXN0Lm9wdGlvbnM/LnN0cmVzc1Rlc3QgPT09IHVuZGVmaW5lZCB8fCB0ZXN0Lm9wdGlvbnM/LnN0cmVzc1Rlc3QgPT09IHRydWUpXG4gICAgICB9XG5cblxuICAgICAgY29uc3Qgc2tpcHBlZCA9IHZhbHVlLnRlc3RzPy5ldmVyeSgodCkgPT4gdC5vcHRpb25zPy5za2lwUmVhc29uKTtcbiAgICAgIGlmIChza2lwcGVkKVxuICAgICAgICBjb250aW51ZTtcblxuICAgICAgZm9yIChsZXQgdGVzdCBvZiB0ZXN0c1RvSW52b2tlID8/IFtdKSB7XG4gICAgICAgIGlmICh0ZXN0Lm9wdGlvbnM/LnNraXBSZWFzb24gPT0gbnVsbCkge1xuICAgICAgICAgIHRlc3RJbnZvY2F0aW9uTWFwLnB1c2goeyB0ZXN0LCB2YWx1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0ZXN0SW52b2NhdGlvbk1hcCA9IHNodWZmbGUodGVzdEludm9jYXRpb25NYXApO1xuXG4gICAgY29uc3QgcmVzID0gW107XG4gICAgZm9yIChsZXQgdGVzdGluZ09iaiBvZiB0ZXN0SW52b2NhdGlvbk1hcCkge1xuICAgICAgYXdhaXQgSW52b2tlQ2F0ZWdvcnlNZXRob2QodGVzdGluZ09iai52YWx1ZS5iZWZvcmUsIG9wdGlvbnMuY2F0ZWdvcnkgPz8gJycpXG4gICAgICBsZXQgdGVzdFJ1biA9IGF3YWl0IGV4ZWNUZXN0KHRlc3RpbmdPYmoudGVzdCwgb3B0aW9ucz8udGVzdCwgbG9ncywgREcuVGVzdC5pc0luQmVuY2htYXJrID8gdGVzdGluZ09iai52YWx1ZS5iZW5jaG1hcmtUaW1lb3V0IDogdGVzdGluZ09iai52YWx1ZS50aW1lb3V0LCBwYWNrYWdlXy5uYW1lLCBvcHRpb25zLnZlcmJvc2UpO1xuICAgICAgaWYgKHRlc3RSdW4pXG4gICAgICAgIHJlcy5wdXNoKHRlc3RSdW4pO1xuICAgICAgY29uc29sZS5sb2coYFRlc3Q6ICR7dGVzdD8ubmFtZX07IHJlc3VsdDogJHt0ZXN0UnVufWApO1xuICAgICAgYXdhaXQgSW52b2tlQ2F0ZWdvcnlNZXRob2QodGVzdGluZ09iai52YWx1ZS5hZnRlciwgb3B0aW9ucy5jYXRlZ29yeSA/PyAnJylcbiAgICB9XG5cbiAgICByZXN1bHRzLnB1c2goLi4ucmVzKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIEludm9rZUFsbFRlc3RzKGNhdGVnb3JpZXNUb0ludm9rZTogeyBba2V5OiBzdHJpbmddOiBDYXRlZ29yeSB9LCBvcHRpb25zOiBUZXN0RXhlY3V0aW9uT3B0aW9ucykge1xuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhjYXRlZ29yaWVzVG9JbnZva2UpKSB7XG4gICAgICAgIGlmICgoISFvcHRpb25zPy5jYXRlZ29yeSAmJiAha2V5LnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChvcHRpb25zPy5jYXRlZ29yeS50b0xvd2VyQ2FzZSgpKSkgfHxcbiAgICAgICAgICBvcHRpb25zLmV4Y2x1ZGU/LnNvbWUoKGMpID0+IGtleS5zdGFydHNXaXRoKGMpKSlcbiAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICBzdGRMb2coYFN0YXJ0ZWQgJHtrZXl9IGNhdGVnb3J5YCk7XG4gICAgICAgIGNvbnN0IHNraXBwZWQgPSB2YWx1ZS50ZXN0cz8uZXZlcnkoKHQpID0+IHQub3B0aW9ucz8uc2tpcFJlYXNvbik7XG4gICAgICAgIGlmICghc2tpcHBlZClcbiAgICAgICAgICB2YWx1ZS5iZWZvcmVTdGF0dXMgPSBhd2FpdCBJbnZva2VDYXRlZ29yeU1ldGhvZCh2YWx1ZS5iZWZvcmUsIG9wdGlvbnMuY2F0ZWdvcnkgPz8gJycpO1xuICAgICAgICBjb25zdCB0ID0gdmFsdWUudGVzdHMgPz8gW107XG4gICAgICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgICAgICBpZiAodmFsdWUuY2xlYXIpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0W2ldLm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgaWYgKHRbaV0ub3B0aW9ucz8uYmVuY2htYXJrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRbaV0ub3B0aW9ucylcbiAgICAgICAgICAgICAgICAgIHRbaV0ub3B0aW9ucyA9IHt9XG4gICAgICAgICAgICAgICAgdFtpXS5vcHRpb25zIS5iZW5jaG1hcmsgPSB2YWx1ZS5iZW5jaG1hcmtzID8/IGZhbHNlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgdGVzdFJ1biA9IGF3YWl0IGV4ZWNUZXN0KHRbaV0sIG9wdGlvbnM/LnRlc3QsIGxvZ3MsIERHLlRlc3QuaXNJbkJlbmNobWFyayA/IHZhbHVlLmJlbmNobWFya1RpbWVvdXQgOiB2YWx1ZS50aW1lb3V0LCBwYWNrYWdlXy5uYW1lLCBvcHRpb25zLnZlcmJvc2UpO1xuICAgICAgICAgICAgaWYgKHRlc3RSdW4pXG4gICAgICAgICAgICAgIHJlcy5wdXNoKHRlc3RSdW4pO1xuICAgICAgICAgICAgZ3Jvay5zaGVsbC5jbG9zZUFsbCgpO1xuICAgICAgICAgICAgREcuQmFsbG9vbi5jbG9zZUFsbCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB0ZXN0UnVuID0gYXdhaXQgZXhlY1Rlc3QodFtpXSwgb3B0aW9ucz8udGVzdCwgbG9ncywgREcuVGVzdC5pc0luQmVuY2htYXJrID8gdmFsdWUuYmVuY2htYXJrVGltZW91dCA6IHZhbHVlLnRpbWVvdXQsIHBhY2thZ2VfLm5hbWUsIG9wdGlvbnMudmVyYm9zZSk7XG4gICAgICAgICAgICBpZiAodGVzdFJ1bilcbiAgICAgICAgICAgICAgcmVzLnB1c2godGVzdFJ1bik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRhdGEgPSByZXMuZmlsdGVyKChkKSA9PiBkLnJlc3VsdCAhPSAnc2tpcHBlZCcpO1xuXG4gICAgICAgIGlmICghc2tpcHBlZClcbiAgICAgICAgICB2YWx1ZS5hZnRlclN0YXR1cyA9IGF3YWl0IEludm9rZUNhdGVnb3J5TWV0aG9kKHZhbHVlLmFmdGVyLCBvcHRpb25zLmNhdGVnb3J5ID8/ICcnKTtcblxuICAgICAgICAvLyBDbGVhciBhZnRlciBjYXRlZ29yeVxuICAgICAgICAvLyBncm9rLnNoZWxsLmNsb3NlQWxsKCk7XG4gICAgICAgIC8vIERHLkJhbGxvb24uY2xvc2VBbGwoKTtcbiAgICAgICAgaWYgKHZhbHVlLmFmdGVyU3RhdHVzKVxuICAgICAgICAgIGRhdGEucHVzaCh7IGRhdGU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwgbG9nczogJycsIGNhdGVnb3J5OiBrZXksIG5hbWU6ICdhZnRlcicsIHJlc3VsdDogdmFsdWUuYWZ0ZXJTdGF0dXMsIHN1Y2Nlc3M6IGZhbHNlLCBtczogMCwgc2tpcHBlZDogZmFsc2UgfSk7XG4gICAgICAgIGlmICh2YWx1ZS5iZWZvcmVTdGF0dXMpXG4gICAgICAgICAgZGF0YS5wdXNoKHsgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLCBsb2dzOiAnJywgY2F0ZWdvcnk6IGtleSwgbmFtZTogJ2JlZm9yZScsIHJlc3VsdDogdmFsdWUuYmVmb3JlU3RhdHVzLCBzdWNjZXNzOiBmYWxzZSwgbXM6IDAsIHNraXBwZWQ6IGZhbHNlIH0pO1xuICAgICAgICByZXN1bHRzLnB1c2goLi4uZGF0YSk7XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHJlc2V0Q29uc29sZSgpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy50ZXN0Q29udGV4dCEuY2F0Y2hVbmhhbmRsZWQgJiYgKCFERy5UZXN0LmlzSW5CZW5jaG1hcmspKSB7XG4gICAgICBhd2FpdCBkZWxheSgxMDAwKTtcbiAgICAgIGNvbnN0IGVycm9yID0gYXdhaXQgZ3Jvay5zaGVsbC5sYXN0RXJyb3I7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxvZ3M6ICcnLFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIGNhdGVnb3J5OiAnVW5oYW5kbGVkIGV4Y2VwdGlvbnMnLFxuICAgICAgICBuYW1lOiAnRXhjZXB0aW9uJyxcbiAgICAgICAgcmVzdWx0OiBlcnJvciA/PyAnJywgc3VjY2VzczogIWVycm9yLCBtczogMCwgc2tpcHBlZDogZmFsc2VcbiAgICAgIH07XG4gICAgICByZXN1bHRzLnB1c2gocGFyYW1zKTtcbiAgICAgICg8YW55PnBhcmFtcykucGFja2FnZSA9IHBhY2thZ2VfLm5hbWU7XG4gICAgICBpZiAoKDxhbnk+Z3Jvay5zaGVsbCkucmVwb3J0VGVzdCAhPSBudWxsKVxuICAgICAgICBhd2FpdCAoPGFueT5ncm9rLnNoZWxsKS5yZXBvcnRUZXN0KCdwYWNrYWdlJywgcGFyYW1zKTtcbiAgICAgIGVsc2Uge1xuICAgICAgICBhd2FpdCBmZXRjaChgJHtncm9rLmRhcGkucm9vdH0vbG9nL3Rlc3RzL3BhY2thZ2VgLCB7XG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICAgIGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nLFxuICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHBhcmFtcylcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFJlc3VsdCh4OiBhbnkpOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gYCR7eC50b1N0cmluZygpfVxcbiR7eC5zdGFjayA/IChhd2FpdCBERy5Mb2dnZXIudHJhbnNsYXRlU3RhY2tUcmFjZSh4LnN0YWNrKSkgOiAnJ31gO1xufVxuXG5hc3luYyBmdW5jdGlvbiBleGVjVGVzdCh0OiBUZXN0LCBwcmVkaWNhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCwgbG9nczogYW55W10sXG4gIGNhdGVnb3J5VGltZW91dD86IG51bWJlciwgcGFja2FnZU5hbWU/OiBzdHJpbmcsIHZlcmJvc2U/OiBib29sZWFuKTogUHJvbWlzZTxhbnk+IHtcbiAgbG9ncy5sZW5ndGggPSAwO1xuICBsZXQgcjogeyBkYXRlOiBzdHJpbmcsIGNhdGVnb3J5Pzogc3RyaW5nLCBuYW1lPzogc3RyaW5nLCBzdWNjZXNzOiBib29sZWFuLCByZXN1bHQ6IGFueSwgbXM6IG51bWJlciwgc2tpcHBlZDogYm9vbGVhbiwgbG9ncz86IHN0cmluZyB9O1xuICBsZXQgdHlwZTogc3RyaW5nID0gJ3BhY2thZ2UnO1xuICBjb25zdCBmaWx0ZXIgPSBwcmVkaWNhdGUgIT0gdW5kZWZpbmVkICYmICh0Lm5hbWUudG9Mb3dlckNhc2UoKSAhPT0gcHJlZGljYXRlLnRvTG93ZXJDYXNlKCkpO1xuICBsZXQgc2tpcCA9IHQub3B0aW9ucz8uc2tpcFJlYXNvbiB8fCBmaWx0ZXI7XG4gIGxldCBza2lwUmVhc29uID0gZmlsdGVyID8gJ3NraXBwZWQnIDogdC5vcHRpb25zPy5za2lwUmVhc29uO1xuXG4gIGlmIChERy5UZXN0LmlzSW5CZW5jaG1hcmsgJiYgIXQub3B0aW9ucz8uYmVuY2htYXJrKSB7XG4gICAgc3RkTG9nKGBTS0lQUEVEOiAke3QuY2F0ZWdvcnl9ICR7dC5uYW1lfSBkb2VzbnQgYXZhaWxhYmxlIGluIGJlbmNobWFyayBtb2RlYCk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICghc2tpcClcbiAgICBzdGRMb2coYFN0YXJ0ZWQgJHt0LmNhdGVnb3J5fSAke3QubmFtZX1gKTtcbiAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICB0cnkge1xuICAgIGlmIChza2lwKVxuICAgICAgciA9IHsgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLCBzdWNjZXNzOiB0cnVlLCByZXN1bHQ6IHNraXBSZWFzb24hLCBtczogMCwgc2tpcHBlZDogdHJ1ZSB9O1xuICAgIGVsc2Uge1xuICAgICAgbGV0IHRpbWVvdXRfID0gdC5vcHRpb25zPy50aW1lb3V0ID09PSBTVEFOREFSVF9USU1FT1VUICYmXG4gICAgICAgIGNhdGVnb3J5VGltZW91dCA/IGNhdGVnb3J5VGltZW91dCA6IHQub3B0aW9ucz8udGltZW91dCE7XG4gICAgICB0aW1lb3V0XyA9ICh0aW1lb3V0XyA9PT0gU1RBTkRBUlRfVElNRU9VVCAmJiBERy5UZXN0LmlzSW5CZW5jaG1hcmspID8gQkVOQ0hNQVJLX1RJTUVPVVQgOiB0aW1lb3V0XztcbiAgICAgIHIgPSB7IGRhdGU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwgc3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBhd2FpdCB0aW1lb3V0KHQudGVzdCwgdGltZW91dF8pID8/ICdPSycsIG1zOiAwLCBza2lwcGVkOiBmYWxzZSB9O1xuICAgIH1cbiAgfSBjYXRjaCAoeDogYW55KSB7XG4gICAgc3RkRXJyb3IoeCk7XG4gICAgciA9IHsgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLCBzdWNjZXNzOiBmYWxzZSwgcmVzdWx0OiBhd2FpdCBnZXRSZXN1bHQoeCksIG1zOiAwLCBza2lwcGVkOiBmYWxzZSB9O1xuICB9XG4gIGlmICh0Lm9wdGlvbnM/LmlzQWdncmVnYXRlZCAmJiByLnJlc3VsdC5jb25zdHJ1Y3RvciA9PT0gREcuRGF0YUZyYW1lKSB7XG4gICAgY29uc3QgY29sID0gci5yZXN1bHQuY29sKCdzdWNjZXNzJyk7XG4gICAgaWYgKGNvbClcbiAgICAgIHIuc3VjY2VzcyA9IGNvbC5zdGF0cy5zdW0gPT09IGNvbC5sZW5ndGg7XG4gICAgaWYgKCF2ZXJib3NlKSB7XG4gICAgICBjb25zdCBkZiA9IHIucmVzdWx0O1xuICAgICAgZGYuY29sdW1ucy5yZW1vdmUoJ3N0YWNrJyk7XG4gICAgICBkZi5yb3dzLnJlbW92ZVdoZXJlKChyKSA9PiByLmdldCgnc3VjY2VzcycpKTtcbiAgICAgIHIucmVzdWx0ID0gZGY7XG4gICAgfVxuICAgIHIucmVzdWx0ID0gci5yZXN1bHQudG9Dc3YoKTtcbiAgfVxuICByLmxvZ3MgPSBsb2dzLmpvaW4oJ1xcbicpO1xuICByLm1zID0gRGF0ZS5ub3coKSAtIHN0YXJ0O1xuICBpZiAoIXNraXApXG4gICAgc3RkTG9nKGBGaW5pc2hlZCAke3QuY2F0ZWdvcnl9ICR7dC5uYW1lfSBmb3IgJHtyLm1zfSBtc2ApO1xuICByLmNhdGVnb3J5ID0gdC5jYXRlZ29yeTtcbiAgci5uYW1lID0gdC5uYW1lO1xuICBpZiAoIWZpbHRlcikge1xuICAgIGxldCBwYXJhbXMgPSB7XG4gICAgICAnc3VjY2Vzcyc6IHIuc3VjY2VzcywgJ3Jlc3VsdCc6IHIucmVzdWx0LCAnbXMnOiByLm1zLFxuICAgICAgJ3NraXBwZWQnOiByLnNraXBwZWQsICdwYWNrYWdlJzogcGFja2FnZU5hbWUsICdjYXRlZ29yeSc6IHQuY2F0ZWdvcnksICduYW1lJzogdC5uYW1lLCAnbG9ncyc6IHIubG9ncyxcbiAgICB9O1xuICAgIGlmIChyLnJlc3VsdC5jb25zdHJ1Y3RvciA9PSBPYmplY3QpIHtcbiAgICAgIGNvbnN0IHJlcyA9IE9iamVjdC5rZXlzKHIucmVzdWx0KS5yZWR1Y2UoKGFjYywgaykgPT4gKHsgLi4uYWNjLCBbJ3Jlc3VsdC4nICsga106IHIucmVzdWx0W2tdIH0pLCB7fSk7XG4gICAgICBwYXJhbXMgPSB7IC4uLnBhcmFtcywgLi4ucmVzIH07XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5yZXN1bHQgaW5zdGFuY2VvZiBERy5EYXRhRnJhbWUpXG4gICAgICBwYXJhbXMucmVzdWx0ID0gSlNPTi5zdHJpbmdpZnkocGFyYW1zLnJlc3VsdD8udG9Kc29uKCkpIHx8ICcnO1xuXG4gICAgaWYgKCg8YW55Pmdyb2suc2hlbGwpLnJlcG9ydFRlc3QgIT0gbnVsbClcbiAgICAgIGF3YWl0ICg8YW55Pmdyb2suc2hlbGwpLnJlcG9ydFRlc3QodHlwZSwgcGFyYW1zKTtcbiAgICBlbHNlIHtcbiAgICAgIGF3YWl0IGZldGNoKGAke2dyb2suZGFwaS5yb290fS9sb2cvdGVzdHMvJHt0eXBlfWAsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICBjcmVkZW50aWFsczogJ3NhbWUtb3JpZ2luJyxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkocGFyYW1zKVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2h1ZmZsZShhcnJheTogYW55W10pOiBhbnlbXSB7XG4gIGNvbnN0IG5ld0FyciA9IGFycmF5LnNsaWNlKCk7XG4gIG5ld0Fyci5zb3J0KCgpID0+IE1hdGgucmFuZG9tKCkgLSAwLjUpO1xuICByZXR1cm4gbmV3QXJyO1xufTtcblxuLyogV2FpdHMgW21zXSBtaWxsaXNlY29uZHMgKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWxheShtczogbnVtYmVyKSB7XG4gIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIG1zKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhd2FpdENoZWNrKGNoZWNrSGFuZGxlcjogKCkgPT4gYm9vbGVhbixcbiAgZXJyb3I6IHN0cmluZyA9ICdUaW1lb3V0IGV4Y2VlZGVkJywgd2FpdDogbnVtYmVyID0gNTAwLCBpbnRlcnZhbDogbnVtYmVyID0gNTApOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG4gICAgICByZWplY3QobmV3IEVycm9yKGVycm9yKSk7XG4gICAgfSwgd2FpdCk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGludGVydmFsSWQ6IFRpbWVvdXQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBpZiAoY2hlY2tIYW5kbGVyKCkpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbElkKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0sIGludGVydmFsKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgdGVzdCBleGVjdXRpb24gcmVzdWx0IG9yIGFuIGVycm9yIGluIGNhc2Ugb2YgdGltZW91dFxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRpbWVvdXQoZnVuYzogKCkgPT4gUHJvbWlzZTxhbnk+LCB0ZXN0VGltZW91dDogbnVtYmVyLCB0aW1lb3V0UmVhc29uOiBzdHJpbmcgPSAnRVhFQ1VUSU9OIFRJTUVPVVQnKTogUHJvbWlzZTxhbnk+IHtcbiAgbGV0IHRpbWVvdXQ6IGFueSA9IG51bGw7XG4gIGNvbnN0IHRpbWVvdXRQcm9taXNlID0gbmV3IFByb21pc2U8YW55PigoXywgcmVqZWN0KSA9PiB7XG4gICAgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1wcm9taXNlLXJlamVjdC1lcnJvcnNcbiAgICAgIHJlamVjdCh0aW1lb3V0UmVhc29uKTtcbiAgICB9LCB0ZXN0VGltZW91dCk7XG4gIH0pO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBQcm9taXNlLnJhY2UoW2Z1bmMoKSwgdGltZW91dFByb21pc2VdKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAodGltZW91dClcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNEaWFsb2dQcmVzZW50KGRpYWxvZ1RpdGxlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgZGlhbG9ncyA9IERHLkRpYWxvZy5nZXRPcGVuRGlhbG9ncygpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpYWxvZ3MubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZGlhbG9nc1tpXS50aXRsZSA9PSBkaWFsb2dUaXRsZSlcbiAgICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqIEV4cGVjdHMgYW4gYXN5bmNocm9ub3VzIHtAbGluayBhY3Rpb259IHRvIHRocm93IGFuIGV4Y2VwdGlvbi4gVXNlIHtAbGluayBjaGVja30gdG8gcGVyZm9ybVxuICogZGVlcGVyIGluc3BlY3Rpb24gb2YgdGhlIGV4Y2VwdGlvbiBpZiBuZWNlc3NhcnkuXG4gKiBAcGFyYW0gIHtmdW5jdGlvbigpOiBQcm9taXNlPHZvaWQ+fSBhY3Rpb25cbiAqIEBwYXJhbSAge2Z1bmN0aW9uKGFueSk6IGJvb2xlYW59IGNoZWNrXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXhwZWN0RXhjZXB0aW9uQXN5bmMoYWN0aW9uOiAoKSA9PiBQcm9taXNlPHZvaWQ+LFxuICBjaGVjaz86IChleGNlcHRpb246IGFueSkgPT4gYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICBsZXQgY2F1Z2h0OiBib29sZWFuID0gZmFsc2U7XG4gIGxldCBjaGVja2VkOiBib29sZWFuID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgYXdhaXQgYWN0aW9uKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjYXVnaHQgPSB0cnVlO1xuICAgIGNoZWNrZWQgPSAhY2hlY2sgfHwgY2hlY2soZSk7XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKCFjYXVnaHQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FuIGV4Y2VwdGlvbiBpcyBleHBlY3RlZCBidXQgbm90IHRocm93bicpO1xuICAgIGlmICghY2hlY2tlZClcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW4gZXhwZWN0ZWQgZXhjZXB0aW9uIGlzIHRocm93biwgYnV0IGl0IGRvZXMgbm90IHNhdGlzZnkgdGhlIGNvbmRpdGlvbicpO1xuICB9XG59XG5cbmNvbnN0IGNhdERGID0gREcuRGF0YUZyYW1lLmZyb21Db2x1bW5zKFtERy5Db2x1bW4uZnJvbVN0cmluZ3MoJ2NvbCcsIFsndmFsMScsICd2YWwyJywgJ3ZhbDMnXSldKTtcblxuLyoqXG4gKiBVbml2ZXJzYWwgdGVzdCBmb3Igdmlld2Vycy4gSXQgc2VhcmNoIHZpZXdlcnMgaW4gRE9NIGJ5IHRhZ3M6IGNhbnZhcywgc3ZnLCBpbWcsIGlucHV0LCBoMSwgYVxuICogQHBhcmFtICB7c3RyaW5nfSB2IFZpZXdlciBuYW1lXG4gKiBAcGFyYW0gIHtERy5EYXRhRnJhbWV9IGRmIERhdGFmcmFtZSB0byB1c2UuIFNob3VsZCBoYXZlIGF0IGxlYXN0IDMgcm93c1xuICogQHBhcmFtICB7Ym9vbGVhbn0gb3B0aW9ucy5kZXRlY3RTZW1hbnRpY1R5cGVzIFNwZWNpZnkgd2hldGhlciB0byBkZXRlY3Qgc2VtYW50aWMgdHlwZXMgb3Igbm90XG4gKiBAcGFyYW0gIHtib29sZWFufSBvcHRpb25zLnJlYWRPbmx5IElmIHNldCB0byB0cnVlLCB0aGUgZGF0YWZyYW1lIHdpbGwgbm90IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgdGVzdFxuICogQHBhcmFtICB7Ym9vbGVhbn0gb3B0aW9ucy5hcmJpdHJhcnlEZlRlc3QgSWYgc2V0IHRvIGZhbHNlLCB0ZXN0IG9uIGFyYml0cmFyeSBkYXRhZnJhbWVcbiAqIChvbmUgY2F0ZWdvcmljYWwgY29sdW1uKSB3aWxsIG5vdCBiZSBwZXJmb3JtZWRcbiAqIEBwYXJhbSAge29iamVjdH0gb3B0aW9ucyBMaXN0IG9mIG9wdGlvbnMgKG9wdGlvbmFsKVxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gVGhlIHRlc3QgaXMgY29uc2lkZXJlZCBzdWNjZXNzZnVsIGlmIGl0IGNvbXBsZXRlcyB3aXRob3V0IGVycm9yc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdGVzdFZpZXdlcih2OiBzdHJpbmcsIGRmOiBERy5EYXRhRnJhbWUsIG9wdGlvbnM/OiB7XG4gIGRldGVjdFNlbWFudGljVHlwZXM/OiBib29sZWFuLCByZWFkT25seT86IGJvb2xlYW4sIGFyYml0cmFyeURmVGVzdD86IGJvb2xlYW4sXG4gIHBhY2thZ2VOYW1lPzogc3RyaW5nLCBhd2FpdFZpZXdlcj86ICh2aWV3ZXI6IERHLlZpZXdlcikgPT4gUHJvbWlzZTx2b2lkPlxufSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwYWNrYWdlTmFtZSA9IG9wdGlvbnM/LnBhY2thZ2VOYW1lID8/ICcnO1xuICBpZiAob3B0aW9ucz8uZGV0ZWN0U2VtYW50aWNUeXBlcylcbiAgICBhd2FpdCBncm9rLmRhdGEuZGV0ZWN0U2VtYW50aWNUeXBlcyhkZik7XG4gIGNvbnN0IHR2ID0gZ3Jvay5zaGVsbC5hZGRUYWJsZVZpZXcoZGYpO1xuXG4gIHRyeSB7XG4gICAgLy8xLiBPcGVuLCBkbyBub3RoaW5nIGFuZCBjbG9zZVxuICAgIGF3YWl0IHRlc3RWaWV3ZXJJbnRlcm5hbCh0diwgdiwgcGFja2FnZU5hbWUsIGdyb2suZXZlbnRzLm9uVmlld2VyQWRkZWQpO1xuICAgIC8vaW4gY2FzZSB2aWV3ZXIgd2l0aCBhc3luYyByZW5kZXJpbmcgLSB3YWl0IGZvciByZW5kZXIgdG8gY29tcGxldGVcbiAgICBpZiAob3B0aW9ucz8uYXdhaXRWaWV3ZXIpXG4gICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCB1bmRlZmluZWQsIG9wdGlvbnMhLmF3YWl0Vmlld2VyKTtcblxuICAgIC8vMi4gT3BlbiB2aWV3ZXIsIHJ1biBzZWxlY3Rpb24sIGZpbHRlciwgZXRjLiBhbmQgY2xvc2VcbiAgICBpZiAoIW9wdGlvbnM/LnJlYWRPbmx5KSB7XG4gICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCBzZWxlY3RGaWx0ZXJDaGFuZ2VDdXJyZW50KTtcbiAgICAgIGlmIChvcHRpb25zPy5hd2FpdFZpZXdlcilcbiAgICAgICAgYXdhaXQgdGVzdFZpZXdlckludGVybmFsKHR2LCB2LCBwYWNrYWdlTmFtZSwgZ3Jvay5ldmVudHMub25WaWV3ZXJBZGRlZCwgc2VsZWN0RmlsdGVyQ2hhbmdlQ3VycmVudCwgb3B0aW9ucyEuYXdhaXRWaWV3ZXIpO1xuICAgIH1cblxuICAgIC8vMi4gT3BlbiB2aWV3ZXIsIGNoYW5nZSBvcHRpb25zLCBzYXZlIGxheW91dCBhbmQgY2xvc2VcbiAgICBsZXQgcHJvcHNBbmRMYXlvdXQ6IHsgbGF5b3V0OiBhbnksIHNhdmVkUHJvcHM6IGFueSB9IHwgbnVsbCA9IG51bGw7XG4gICAgcHJvcHNBbmRMYXlvdXQgPSBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCBjaGFuZ2VPcHRpb25zU2F2ZUxheW91dCk7XG4gICAgaWYgKG9wdGlvbnM/LmF3YWl0Vmlld2VyKVxuICAgICAgcHJvcHNBbmRMYXlvdXQgPSBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLFxuICAgICAgICBjaGFuZ2VPcHRpb25zU2F2ZUxheW91dCwgb3B0aW9ucyEuYXdhaXRWaWV3ZXIpXG5cbiAgICAvLzMuIExvYWQgbGF5b3V0XG4gICAgYXdhaXQgdGVzdFZpZXdlckludGVybmFsKHR2LCB2LCBwYWNrYWdlTmFtZSwgZ3Jvay5ldmVudHMub25WaWV3TGF5b3V0QXBwbGllZCwgbG9hZExheW91dCwgdW5kZWZpbmVkLCBwcm9wc0FuZExheW91dD8ubGF5b3V0LFxuICAgICAgeyBzYXZlZFByb3BzOiBwcm9wc0FuZExheW91dD8uc2F2ZWRQcm9wcyB9KTtcbiAgICBpZiAob3B0aW9ucz8uYXdhaXRWaWV3ZXIpXG4gICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdMYXlvdXRBcHBsaWVkLCBsb2FkTGF5b3V0LCBvcHRpb25zIS5hd2FpdFZpZXdlcixcbiAgICAgICAgcHJvcHNBbmRMYXlvdXQ/LmxheW91dCwgeyBzYXZlZFByb3BzOiBwcm9wc0FuZExheW91dD8uc2F2ZWRQcm9wcyB9KTtcblxuICAgIC8vNC4gT3BlbiB2aWV3ZXIgb24gYXJiaXRhcnkgZGF0YXNldFxuICAgIGlmIChvcHRpb25zPy5hcmJpdHJhcnlEZlRlc3QgIT09IGZhbHNlKSB7XG4gICAgICB0di5kYXRhRnJhbWUgPSBjYXRERjtcbiAgICAgIGF3YWl0IGRlbGF5KDUwKTtcbiAgICAgIGF3YWl0IHRlc3RWaWV3ZXJJbnRlcm5hbCh0diwgdiwgcGFja2FnZU5hbWUsIGdyb2suZXZlbnRzLm9uVmlld2VyQWRkZWQpO1xuICAgICAgaWYgKG9wdGlvbnM/LmF3YWl0Vmlld2VyKVxuICAgICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCB1bmRlZmluZWQsIG9wdGlvbnMhLmF3YWl0Vmlld2VyKTtcbiAgICB9XG5cbiAgICAvLzUuIENhbGwgcG9zdHBvbmVkIGZpbHRlcmluZ1xuICAgIGF3YWl0IHRlc3RWaWV3ZXJJbnRlcm5hbCh0diwgdiwgcGFja2FnZU5hbWUsIGdyb2suZXZlbnRzLm9uVmlld2VyQWRkZWQsIGZpbHRlckFzeW5jKTtcbiAgICBpZiAob3B0aW9ucz8uYXdhaXRWaWV3ZXIpXG4gICAgICBhd2FpdCB0ZXN0Vmlld2VySW50ZXJuYWwodHYsIHYsIHBhY2thZ2VOYW1lLCBncm9rLmV2ZW50cy5vblZpZXdlckFkZGVkLCBmaWx0ZXJBc3luYywgb3B0aW9ucyEuYXdhaXRWaWV3ZXIpO1xuXG4gIH0gZmluYWxseSB7XG4gICAgLy8gY2xvc2VBbGwoKSBpcyBoYW5kbGluZyBieSBjb21tb24gdGVzdCB3b3JrZmxvd1xuICAgIC8vIGdyb2suc2hlbGwuY2xvc2VBbGwoKTtcbiAgICAvLyBERy5CYWxsb29uLmNsb3NlQWxsKCk7XG4gIH1cbn1cbiJdfQ==","export var DimReductionMethods;\n(function (DimReductionMethods) {\n DimReductionMethods[\"UMAP\"] = \"UMAP\";\n DimReductionMethods[\"T_SNE\"] = \"t-SNE\";\n})(DimReductionMethods || (DimReductionMethods = {}));\n;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSxtQkFHWDtBQUhELFdBQVksbUJBQW1CO0lBQzNCLG9DQUFhLENBQUE7SUFDYixzQ0FBZSxDQUFBO0FBQ25CLENBQUMsRUFIVyxtQkFBbUIsS0FBbkIsbUJBQW1CLFFBRzlCO0FBQUEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIERpbVJlZHVjdGlvbk1ldGhvZHN7XG4gICAgVU1BUCA9ICdVTUFQJyxcbiAgICBUX1NORSA9ICd0LVNORSdcbn07XG4iXX0=","export var StringMetricsNames;\n(function (StringMetricsNames) {\n StringMetricsNames[\"Levenshtein\"] = \"Levenshtein\";\n StringMetricsNames[\"JaroWinkler\"] = \"Jaro-Winkler\";\n StringMetricsNames[\"Manhattan\"] = \"Manhattan\";\n StringMetricsNames[\"Onehot\"] = \"One-Hot\";\n})(StringMetricsNames || (StringMetricsNames = {}));\nexport var VectorMetricsNames;\n(function (VectorMetricsNames) {\n VectorMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(VectorMetricsNames || (VectorMetricsNames = {}));\nexport var BitArrayMetricsNames;\n(function (BitArrayMetricsNames) {\n BitArrayMetricsNames[\"Tanimoto\"] = \"Tanimoto\";\n BitArrayMetricsNames[\"Dice\"] = \"Dice\";\n BitArrayMetricsNames[\"Asymmetric\"] = \"Asymmetric\";\n BitArrayMetricsNames[\"BraunBlanquet\"] = \"Braun-Blanquet\";\n BitArrayMetricsNames[\"Cosine\"] = \"Cosine\";\n BitArrayMetricsNames[\"Kulczynski\"] = \"Kulczynski\";\n BitArrayMetricsNames[\"McConnaughey\"] = \"Mc-Connaughey\";\n BitArrayMetricsNames[\"RogotGoldberg\"] = \"Rogot-Goldberg\";\n BitArrayMetricsNames[\"Russel\"] = \"Russel\";\n BitArrayMetricsNames[\"Sokal\"] = \"Sokal\";\n BitArrayMetricsNames[\"Hamming\"] = \"Hamming\";\n BitArrayMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(BitArrayMetricsNames || (BitArrayMetricsNames = {}));\nexport var IntArrayMetricsNames;\n(function (IntArrayMetricsNames) {\n IntArrayMetricsNames[\"TanimotoIntArray\"] = \"TanimotoIntArray\";\n})(IntArrayMetricsNames || (IntArrayMetricsNames = {}));\nexport var DistanceMetricsSubjects;\n(function (DistanceMetricsSubjects) {\n DistanceMetricsSubjects[\"Vector\"] = \"Vector\";\n DistanceMetricsSubjects[\"String\"] = \"String\";\n DistanceMetricsSubjects[\"BitArray\"] = \"BitArray\";\n DistanceMetricsSubjects[\"MacroMolecule\"] = \"MacroMolecule\";\n DistanceMetricsSubjects[\"Number\"] = \"Number\";\n DistanceMetricsSubjects[\"IntArray\"] = \"IntArray\";\n DistanceMetricsSubjects[\"NumberArray\"] = \"NumberArray\";\n})(DistanceMetricsSubjects || (DistanceMetricsSubjects = {}));\nexport var NumberMetricsNames;\n(function (NumberMetricsNames) {\n NumberMetricsNames[\"Difference\"] = \"Difference\";\n})(NumberMetricsNames || (NumberMetricsNames = {}));\nexport var NumberArrayMetricsNames;\n(function (NumberArrayMetricsNames) {\n NumberArrayMetricsNames[\"CommonItems\"] = \"Common Items\";\n})(NumberArrayMetricsNames || (NumberArrayMetricsNames = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBTixJQUFZLGtCQUtUO0FBTEgsV0FBWSxrQkFBa0I7SUFDMUIsaURBQTJCLENBQUE7SUFDM0Isa0RBQTRCLENBQUE7SUFDNUIsNkNBQXVCLENBQUE7SUFDdkIsd0NBQWtCLENBQUE7QUFDcEIsQ0FBQyxFQUxTLGtCQUFrQixLQUFsQixrQkFBa0IsUUFLM0I7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFVDtBQUZILFdBQVksa0JBQWtCO0lBQzFCLDZDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFGUyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTNCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBYVQ7QUFiSCxXQUFZLG9CQUFvQjtJQUM1Qiw2Q0FBcUIsQ0FBQTtJQUNyQixxQ0FBYSxDQUFBO0lBQ2IsaURBQXlCLENBQUE7SUFDekIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsaURBQXlCLENBQUE7SUFDekIsc0RBQThCLENBQUE7SUFDOUIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsdUNBQWUsQ0FBQTtJQUNmLDJDQUFtQixDQUFBO0lBQ25CLCtDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFiUyxvQkFBb0IsS0FBcEIsb0JBQW9CLFFBYTdCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBRVg7QUFGRCxXQUFZLG9CQUFvQjtJQUM5Qiw2REFBcUMsQ0FBQTtBQUN2QyxDQUFDLEVBRlcsb0JBQW9CLEtBQXBCLG9CQUFvQixRQUUvQjtBQUVELE1BQU0sQ0FBTixJQUFZLHVCQVFUO0FBUkgsV0FBWSx1QkFBdUI7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7SUFDckIsMERBQStCLENBQUE7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7SUFDckIsc0RBQTJCLENBQUE7QUFDN0IsQ0FBQyxFQVJTLHVCQUF1QixLQUF2Qix1QkFBdUIsUUFRaEM7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFWDtBQUZELFdBQVksa0JBQWtCO0lBQzVCLCtDQUF5QixDQUFBO0FBQzNCLENBQUMsRUFGVyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTdCO0FBRUQsTUFBTSxDQUFOLElBQVksdUJBRVg7QUFGRCxXQUFZLHVCQUF1QjtJQUNqQyx1REFBNEIsQ0FBQTtBQUM5QixDQUFDLEVBRlcsdUJBQXVCLEtBQXZCLHVCQUF1QixRQUVsQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIFN0cmluZ01ldHJpY3NOYW1lcyB7XG4gICAgTGV2ZW5zaHRlaW4gPSAnTGV2ZW5zaHRlaW4nLFxuICAgIEphcm9XaW5rbGVyID0gJ0phcm8tV2lua2xlcicsXG4gICAgTWFuaGF0dGFuID0gJ01hbmhhdHRhbicsXG4gICAgT25laG90ID0gJ09uZS1Ib3QnLFxuICB9XG5cbmV4cG9ydCBlbnVtIFZlY3Rvck1ldHJpY3NOYW1lcyB7XG4gICAgRXVjbGlkZWFuID0gJ0V1Y2xpZGVhbicsXG4gIH1cblxuZXhwb3J0IGVudW0gQml0QXJyYXlNZXRyaWNzTmFtZXMge1xuICAgIFRhbmltb3RvID0gJ1Rhbmltb3RvJyxcbiAgICBEaWNlID0gJ0RpY2UnLFxuICAgIEFzeW1tZXRyaWMgPSAnQXN5bW1ldHJpYycsXG4gICAgQnJhdW5CbGFucXVldCA9ICdCcmF1bi1CbGFucXVldCcsXG4gICAgQ29zaW5lID0gJ0Nvc2luZScsXG4gICAgS3VsY3p5bnNraSA9ICdLdWxjenluc2tpJyxcbiAgICBNY0Nvbm5hdWdoZXkgPSAnTWMtQ29ubmF1Z2hleScsXG4gICAgUm9nb3RHb2xkYmVyZyA9ICdSb2dvdC1Hb2xkYmVyZycsXG4gICAgUnVzc2VsID0gJ1J1c3NlbCcsXG4gICAgU29rYWwgPSAnU29rYWwnLFxuICAgIEhhbW1pbmcgPSAnSGFtbWluZycsXG4gICAgRXVjbGlkZWFuID0gJ0V1Y2xpZGVhbicsXG4gIH1cblxuZXhwb3J0IGVudW0gSW50QXJyYXlNZXRyaWNzTmFtZXMge1xuICBUYW5pbW90b0ludEFycmF5ID0gJ1Rhbmltb3RvSW50QXJyYXknLFxufVxuXG5leHBvcnQgZW51bSBEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cyB7XG4gICAgVmVjdG9yID0gJ1ZlY3RvcicsXG4gICAgU3RyaW5nID0gJ1N0cmluZycsXG4gICAgQml0QXJyYXkgPSAnQml0QXJyYXknLFxuICAgIE1hY3JvTW9sZWN1bGUgPSAnTWFjcm9Nb2xlY3VsZScsXG4gICAgTnVtYmVyID0gJ051bWJlcicsXG4gICAgSW50QXJyYXkgPSAnSW50QXJyYXknLFxuICAgIE51bWJlckFycmF5ID0gJ051bWJlckFycmF5JyxcbiAgfVxuXG5leHBvcnQgZW51bSBOdW1iZXJNZXRyaWNzTmFtZXMge1xuICBEaWZmZXJlbmNlID0gJ0RpZmZlcmVuY2UnLFxufVxuXG5leHBvcnQgZW51bSBOdW1iZXJBcnJheU1ldHJpY3NOYW1lcyB7XG4gIENvbW1vbkl0ZW1zID0gJ0NvbW1vbiBJdGVtcycsXG59XG4iXX0=","const peq = new Uint32Array(0x10000);\nconst myers_32 = (a, b) => {\n const n = a.length;\n const m = b.length;\n const lst = 1 << (n - 1);\n let pv = -1;\n let mv = 0;\n let sc = n;\n let i = n;\n while (i--) {\n peq[a.charCodeAt(i)] |= 1 << i;\n }\n for (i = 0; i < m; i++) {\n let eq = peq[b.charCodeAt(i)];\n const xv = eq | mv;\n eq |= ((eq & pv) + pv) ^ pv;\n mv |= ~(eq | pv);\n pv &= eq;\n if (mv & lst) {\n sc++;\n }\n if (pv & lst) {\n sc--;\n }\n mv = (mv << 1) | 1;\n pv = (pv << 1) | ~(xv | mv);\n mv &= xv;\n }\n i = n;\n while (i--) {\n peq[a.charCodeAt(i)] = 0;\n }\n return sc;\n};\nconst myers_x = (b, a) => {\n const n = a.length;\n const m = b.length;\n const mhc = [];\n const phc = [];\n const hsize = Math.ceil(n / 32);\n const vsize = Math.ceil(m / 32);\n for (let i = 0; i < hsize; i++) {\n phc[i] = -1;\n mhc[i] = 0;\n }\n let j = 0;\n for (; j < vsize - 1; j++) {\n let mv = 0;\n let pv = -1;\n const start = j * 32;\n const vlen = Math.min(32, m) + start;\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] |= 1 << k;\n }\n for (let i = 0; i < n; i++) {\n const eq = peq[a.charCodeAt(i)];\n const pb = (phc[(i / 32) | 0] >>> i) & 1;\n const mb = (mhc[(i / 32) | 0] >>> i) & 1;\n const xv = eq | mv;\n const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;\n let ph = mv | ~(xh | pv);\n let mh = pv & xh;\n if ((ph >>> 31) ^ pb) {\n phc[(i / 32) | 0] ^= 1 << i;\n }\n if ((mh >>> 31) ^ mb) {\n mhc[(i / 32) | 0] ^= 1 << i;\n }\n ph = (ph << 1) | pb;\n mh = (mh << 1) | mb;\n pv = mh | ~(xv | ph);\n mv = ph & xv;\n }\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] = 0;\n }\n }\n let mv = 0;\n let pv = -1;\n const start = j * 32;\n const vlen = Math.min(32, m - start) + start;\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] |= 1 << k;\n }\n let score = m;\n for (let i = 0; i < n; i++) {\n const eq = peq[a.charCodeAt(i)];\n const pb = (phc[(i / 32) | 0] >>> i) & 1;\n const mb = (mhc[(i / 32) | 0] >>> i) & 1;\n const xv = eq | mv;\n const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;\n let ph = mv | ~(xh | pv);\n let mh = pv & xh;\n score += (ph >>> (m - 1)) & 1;\n score -= (mh >>> (m - 1)) & 1;\n if ((ph >>> 31) ^ pb) {\n phc[(i / 32) | 0] ^= 1 << i;\n }\n if ((mh >>> 31) ^ mb) {\n mhc[(i / 32) | 0] ^= 1 << i;\n }\n ph = (ph << 1) | pb;\n mh = (mh << 1) | mb;\n pv = mh | ~(xv | ph);\n mv = ph & xv;\n }\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] = 0;\n }\n return score;\n};\nconst distance = (a, b) => {\n if (a.length < b.length) {\n const tmp = b;\n b = a;\n a = tmp;\n }\n if (b.length === 0) {\n return a.length;\n }\n if (a.length <= 32) {\n return myers_32(a, b);\n }\n return myers_x(a, b);\n};\nconst closest = (str, arr) => {\n let min_distance = Infinity;\n let min_index = 0;\n for (let i = 0; i < arr.length; i++) {\n const dist = distance(str, arr[i]);\n if (dist < min_distance) {\n min_distance = dist;\n min_index = i;\n }\n }\n return arr[min_index];\n};\nexport { closest, distance };\n","export default class BitArray {\n constructor(arg, defaultValue = false) {\n this._length = 0;\n this._version = 0;\n this._updateLevel = 0;\n this._selectedCount = 0;\n this._selectedCountVersion = -1;\n this._selectedIndexesVersion = -1;\n this._versionedName = '';\n this._versionedNameVersion = -1;\n this.SHRINK_THRESHOLD = 0x100;\n if (typeof arg === 'number') {\n const length = arg;\n const buff = BitArray._createBuffer(length);\n if (defaultValue) {\n for (let i = 0; i < buff.length; i++)\n buff[i] = -1;\n }\n this._data = buff;\n this._length = length;\n }\n else if (arg instanceof Uint32Array) {\n this._data = arg;\n this._length = defaultValue;\n }\n else {\n throw new Error('Invalid constructor');\n }\n }\n getRawData() { return this._data; }\n assureGoez(num, argName) {\n if (num < 0)\n throw new Error(`${argName} should be greater than zero`);\n }\n assureInRange(value, min, max, argName) {\n if ((value < min) || (value > max))\n throw new Error(`Argument ${argName} (${value}) out of range (${min}, ${max})`);\n }\n copy(src, dst, count) {\n for (let i = 0; i < count; i++)\n dst[i] = src[i];\n }\n copyFrom(other) {\n if (this._length != other._length)\n throw new Error(`Lengths differ (${this._length} != ${other._length})`);\n this.copy(other._data, this._data, this.lengthInInts);\n this._version++;\n }\n get length() {\n return this._length;\n }\n get buffer() {\n return this._data;\n }\n set buffer(data) {\n this._data = data;\n this._version++;\n }\n get version() {\n return this._version;\n }\n set version(value) {\n this._version = value;\n }\n incrementVersion(notify = true) {\n this._version++;\n }\n get lengthInInts() {\n return Math.floor((this._length + 0x1f) / 0x20);\n }\n get versionedName() {\n return this._version == this._versionedNameVersion ? this._versionedName : '';\n }\n set versionedName(name) {\n this._versionedName = name;\n this._versionedNameVersion = this._version;\n }\n get self() {\n return this;\n }\n setLength(value) {\n if (value < 0)\n throw new Error('should be >= 0');\n if (value == this._length)\n return;\n const nIntsNeeded = Math.floor((value + 0x1f) / 0x20);\n if ((nIntsNeeded > this._data.length) || ((nIntsNeeded + this.SHRINK_THRESHOLD) < this._data.length)) {\n const newData = new Uint32Array(nIntsNeeded);\n this.copy(this._data, newData, (nIntsNeeded > this._data.length) ? this._data.length : nIntsNeeded);\n this._data = newData;\n }\n if (value > this._length) {\n if (this._length % 0x20 > 0)\n this._data[this.lengthInInts - 1] &= (1 << ((this._length % 0x20) & 0x1f)) - 1;\n this._data.fill(0, this.lengthInInts, nIntsNeeded);\n }\n this._length = value;\n this._version++;\n }\n static fromAnd(set1, set2) {\n if (set1._length != set2._length)\n throw new Error(`Lengths differ (${set1._length} != ${set2._length})`);\n const temp = new BitArray(set1._length);\n temp._length = set1._length;\n temp._data = BitArray._createBuffer(temp._length);\n temp._version = 0;\n const len = set1.lengthInInts;\n for (let i = 0; i < len; i++)\n temp._data[i] = set1._data[i] & set2._data[i];\n return temp;\n }\n static _createBuffer(length) {\n return new Uint32Array(Math.floor((length + 0x1f) / 0x20));\n }\n static fromValues(values) {\n const temp = new BitArray(values.length);\n temp._version = 0;\n for (let i = 0; i < temp._length; i++) {\n if (values[i])\n temp._data[Math.floor(i / 0x20)] |= 1 << ((i % 0x20) & 0x1f);\n }\n return temp;\n }\n /// Constructs a [BitSet] of length [count], where idx-th bit is determined by a call to [flag] (idx).\n static fromSeq(count, flag) {\n const temp = new BitArray(count);\n for (let i = 0; i < count; ++i)\n temp.setBit(i, flag(i));\n temp._version = 0;\n return temp;\n }\n /// Constructs a [BitSet] from a string [s] containing '0' or '1'.\n static fromString(s) {\n return BitArray.fromSeq(s.length, (i) => s.charAt(i) == '1');\n }\n /// Constructs a [BitSet], based on length [_length] and byte array [_data].\n static fromUint32Array(_length, _data) {\n const temp = new BitArray(_length);\n temp._data = _data;\n return temp;\n }\n /// Deserializes a [BitSet] from [bytes].\n static fromBytes(bytes) {\n const len = bytes.length;\n const temp = new BitArray(len * 8);\n temp._data = new Uint32Array(Math.floor((len + 3) / 4));\n temp._length = len * 8;\n let num1 = 0;\n let num2 = 0;\n while ((len - num2) >= 4) {\n temp._data[num1++] = (((bytes[num2] & 0xff) | ((bytes[num2 + 1] & 0xff) << 8)) |\n ((bytes[num2 + 2] & 0xff) << 0x10)) | ((bytes[num2 + 3] & 0xff) << 0x18);\n num2 += 4;\n }\n if (len - num2 == 3)\n temp._data[num1] = (bytes[num2 + 2] & 0xff) << 0x10;\n if (len - num2 == 2)\n temp._data[num1] |= (bytes[num2 + 1] & 0xff) << 8;\n if (len - num2 == 1)\n temp._data[num1] |= bytes[num2] & 0xff;\n temp._version = 0;\n return temp;\n }\n toString() {\n return `${this._length} bits, ${this.countBits(true)} set`;\n }\n /// Performs deep comparison of two bitsets.\n equals(other) {\n if (this == other)\n return true;\n if (other == null)\n return false;\n if (this._length != other._length)\n return false;\n if (this._length == 0)\n return true;\n for (let i = 0; i < this._data.length - 1; i++)\n if (this._data[i] != other._data[i])\n return false;\n for (let i = (this._data.length - 1) * 8; i < this._length; i++) {\n if (this.getBit(i) != other.getBit(i))\n return false;\n }\n return true;\n }\n /** Clones a bitset. */\n clone() {\n const bitArray = new BitArray(0, false);\n bitArray._data = Uint32Array.from(this._data); // effective length: (lengthInInts)\n bitArray._length = this._length;\n bitArray._version = this._version;\n return bitArray;\n }\n /** Initializes a bitset. */\n init(flag, notify) {\n this.setAll(false, false);\n for (let i = 0; i < this._length; i++) {\n if (flag(i))\n this._data[Math.floor(i / 0x20)] |= 1 << ((i % 0x20) & 0x1f);\n }\n this.incrementVersion(notify);\n return this;\n }\n /// Inverts a bitset.\n invert(notify = true) {\n for (let i = 0; i < this._data.length; i++)\n this._data[i] ^= -1;\n this.incrementVersion(notify);\n }\n /// Sets all bits to [value], optionally suppressing notifications.\n setAll(value, notify = false) {\n const flags = value ? -1 : 0;\n const len = this.lengthInInts;\n for (let i = 0; i < len; i++) //todo: optimize\n this._data[i] = flags;\n this.incrementVersion(notify);\n }\n /// Sets bits at [indexes] position to [value].\n /// Clears the bitset if [clear] flag is true.\n /// Change notification is raised when [notify] is true.\n setIndexes(indexes, value = true, clear = true, notify = true) {\n if (clear)\n this.setAll(!value, false);\n for (const i of indexes)\n this.setFast(i, value);\n this.incrementVersion(notify);\n }\n everyIndex(indexes, value = true) {\n for (const index of indexes) {\n if (this.getBit(index) != value)\n return false;\n }\n return true;\n }\n anyIndex(indexes, value = true) {\n for (const index of indexes) {\n if (this.getBit(index) == value)\n return true;\n }\n return false;\n }\n setWhere(check, value = true, clear = true, notify = true, allowClear = true) {\n if (clear && allowClear)\n this.setAll(!value, false);\n if (allowClear) {\n for (let i = 0; i < this._length; i++) {\n if (check(i))\n this.setFast(i, value);\n }\n }\n else {\n for (let i = 0; i < this._length; i++)\n this.setFast(i, check(i) ? value : !value);\n }\n this.incrementVersion(notify);\n }\n getRange(from, to) {\n this.assureInRange(from, 0, this._length - 1, 'from');\n this.assureInRange(to, 0, this._length, 'to');\n const arr = [];\n for (let i = from; i < to; ++i)\n arr.push(this.getBit(i));\n return BitArray.fromValues(arr);\n }\n getRangeAsList(from, to) {\n this.assureInRange(from, 0, this._length - 1, 'from');\n this.assureInRange(to, 0, this._length, 'to');\n const arr = [];\n for (let i = from; i < to; ++i)\n arr.push(this.getBit(i));\n return arr;\n }\n setRange(from, to, value, notify = true) {\n this.assureInRange(from, 0, this._length - 1, 'from');\n this.assureInRange(to, 0, this._length - 1, 'to');\n const start = Math.min(from, to);\n const end = Math.max(from, to);\n //todo: optimize\n if (value) {\n for (let i = start; i <= end; i++)\n this.setTrue(i);\n }\n else {\n for (let i = start; i <= end; i++)\n this.setFalse(i);\n }\n this.incrementVersion(notify);\n return this;\n }\n /// Sets n randomly chosen bits to value, remaining bits to !value.\n setRandom(n, value, notify = true) {\n if (n < 0 || n > this._length)\n throw new Error('n must be >= 0 && <= Count');\n if (n > this._length / 2)\n this.setRandom(this._length - n, !value);\n this.setAll(!value);\n for (let k = 0; k < n;) {\n const i = Math.floor(Math.random() * this._length);\n if (this.getBit(i) == value)\n continue;\n this.setFast(i, value);\n k++;\n }\n this.incrementVersion(notify);\n }\n /// Modifies current bitset by performing the bitwise AND operation against the\n /// corresponding elements in the specified bitset.\n and(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] &= value._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Performs the bitwise AND NOT operation on the elements in the current bitset\n /// against the corresponding elements in the specified bitset.\n andNot(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n const len = this.lengthInInts;\n for (let num2 = 0; num2 < len; num2++)\n this._data[num2] &= ~value._data[num2];\n this.incrementVersion(notify);\n return this;\n }\n /// Performs the bitwise NOT AND operation on the elements in the current bitset\n /// against the corresponding elements in the specified bitset.\n notAnd(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] = (~this._data[i]) & value._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Inverts all bit values in the current bitset\n not(notify = true) {\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] = ~this._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Performs the bitwise OR operation on the elements in the current bitset\n /// against the corresponding elements in the specified bitset.\n or(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] |= value._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Performs the bitwise exclusive OR operation on the elements in the current bitset\n /// against the corresponding elements in the specified bitset.\n xor(value, notify = true) {\n if (this._length != value._length)\n throw new Error('Array lengths differ.');\n for (let i = 0, len = this.lengthInInts; i < len; i++)\n this._data[i] ^= value._data[i];\n this.incrementVersion(notify);\n return this;\n }\n /// Inserts n 0-bits at position pos, resizing self and shifting bits appropriately.\n insertAt(pos, n, flag = false) {\n this.assureInRange(pos, 0, this._length, 'pos');\n if (n == 0)\n return;\n //TODO: optimize\n //the most primitive implementation, optimize it later!\n // beginUpdate();\n const oldlength = this._length;\n this.setLength(this._length + n);\n //if (!contains(!flag)) return; // nothing to do\n for (let i = oldlength - 1; i >= pos; i--)\n this.setBit(i + n, this.getBit(i));\n for (let i = pos; i < pos + n; i++)\n this.setBit(i, flag);\n // endUpdate();\n }\n /// Deletes n bits beginning at position pos, resizing self and shifting remaining\n /// bits appropriately.\n removeAt(pos, n = 1) {\n // the most primitive implementation, optimize it later!\n if (n < 0)\n throw new Error('n cannot be negative');\n this.assureInRange(pos, 0, this._length - n, 'pos');\n if (this.contains(true)) {\n for (let i = pos; i < this._length - n; i++)\n this.setBit(i, this.getBit(i + n));\n }\n this.setLength(this._length - n);\n }\n removeByMask(mask, flag = true) {\n if (this._length != mask.length)\n throw new Error('length != mask.length');\n if (mask == this) { // no need to iterate\n this.setLength(mask.countBits(!flag));\n this.setAll(!flag);\n }\n else {\n let dstIdx = 0;\n for (let srcIdx = -1; (srcIdx = mask.findNext(srcIdx, !flag)) != -1;)\n this.setFast(dstIdx++, this.getBit(srcIdx));\n this._length = dstIdx;\n this._version++;\n }\n return this;\n }\n /// Similar to the [] operator.\n getBit(pos) {\n return (this._data[Math.floor(pos / 0x20)] & (1 << (pos & 0x1f))) != 0;\n }\n /// Similar to the [] operator.\n setBit(pos, bit, notify = true) {\n this.setFast(pos, bit);\n if (notify)\n this._version++;\n else\n this._version++;\n }\n /// Sets [i]-th bit to [value], does not check bounds, does not increment version\n setFast(i, value) {\n if (value)\n this._data[Math.floor(i / 0x20)] |= 1 << (i & 0x1f);\n else\n this._data[Math.floor(i / 0x20)] &= ~(1 << (i & 0x1f));\n }\n setTrue(pos) {\n this._data[Math.floor(pos / 0x20)] |= 1 << (pos & 0x1f);\n }\n setFalse(pos) {\n this._data[Math.floor(pos / 0x20)] &= ~(1 << (pos & 0x1f));\n }\n trueCount() {\n return this.countBits(true);\n }\n falseCount() {\n return this.countBits(false);\n }\n /// Counts bits of the specified value.\n countBits(value) {\n if (this._length == 0)\n return 0;\n if (this._selectedCountVersion != this._version) {\n this._selectedCount = 0;\n const len = this.lengthInInts;\n let i = 0;\n for (; i < len - 1; i++) {\n for (let k = this._data[i]; k != 0; k >>>= 8) { //todo: cast data[i] to uint\n this._selectedCount += BitArray._onBitCount[k & 0xff];\n }\n }\n // The last int.\n let k = this._data[i];\n const remainingBits = this._length & 0x1f;\n if (remainingBits != 0) /* if remainingBits == 0, the last int is fully used and ALL bits should be left as is */\n k &= ~((4294967295) << remainingBits);\n for (; k != 0; k >>>= 8)\n this._selectedCount += BitArray._onBitCount[k & 0xff];\n this._selectedCountVersion = this._version;\n }\n return (value ? this._selectedCount : this._length - this._selectedCount);\n }\n /// Returns a number of set bits where also [check] is true\n countWhere(check) {\n let result = 0;\n if (this.trueCount() == this._length) {\n for (let i = 0; i < this._length; i++)\n result += check(i) ? 1 : 0;\n }\n else {\n for (let i = -1; (i = this.findNext(i, true)) != -1;)\n result += check(i) ? 1 : 0;\n }\n return result;\n }\n /// Performs bit \"and\" and counts bits of the specified value, without bitset modification.\n andWithCountBits(second, value) {\n if (this._length == 0)\n return 0;\n let count = 0;\n const len = this.lengthInInts;\n let i = 0;\n for (; i < len - 1; i++) {\n for (let k = this._data[i] & second._data[i]; k != 0; k >>>= 8)\n count += BitArray._onBitCount[k & 0xff];\n }\n // The last int.\n let k = this._data[i] & second._data[i];\n const remainingBits = this._length & 0x1f;\n if (remainingBits != 0)\n k &= ~((4294967295) << remainingBits);\n for (; k != 0; k >>>= 8)\n count += BitArray._onBitCount[k & 0xff];\n return (value ? count : this._length - count);\n }\n clear() {\n this.setLength(0);\n }\n contains(value) {\n return this.findNext(-1, value) >= 0;\n }\n get allTrue() {\n return this.countBits(true) == this._length;\n }\n get allFalse() {\n return this.countBits(false) == this._length;\n }\n get anyTrue() {\n return this.countBits(true) > 0;\n }\n get anyFalse() {\n return this.countBits(false) > 0;\n }\n /// Returns the position of the next bit of the specified value, starting from the specified position.\n /// Returns -1, if there are no such bits.\n findNext(index, value = true) {\n this.assureInRange(index, -1, this._length, 'index');\n if (index >= this._length - 1)\n return -1;\n index = index < 0 ? 0 : index + 1; // skip start\n let unusedBits = index & 0x1f;\n const numInts = this.lengthInInts;\n for (let i = Math.floor(index / 32); i < numInts; i++) {\n let k = (value ? this._data[i] : ~this._data[i]); // uint cast\n if (unusedBits != 0) {\n k &= ((0xffffffff << unusedBits) & 0xffffffff);\n unusedBits = 0;\n }\n else if (!value && k == -4294967296) /* looking for false, all bits are set */ {\n continue;\n }\n for (let j = 0; k != 0; j += 8, k >>>= 8) {\n const p = BitArray._firstOnBit[k & 0xff];\n if (p >= 0) {\n index = p + (i * 32) + j;\n if (index >= this._length)\n return -1;\n return index;\n }\n }\n }\n return -1;\n }\n /// Finds previous bit of the specified value in the bitset.\n findPrev(index, value = true) {\n if (index == 0)\n return -1;\n this.assureInRange(index, -1, this._length, 'index');\n index = index < 0 ? this._length - 1 : index - 1; // skip start\n const lastIntIdx = Math.floor(index / 0x20);\n let remainingBits = (index + 1) & 0x1f;\n for (let i = lastIntIdx; i >= 0; i--) {\n let k = (value ? this._data[i] : ~this._data[i]); // cast\n if (remainingBits != 0) {\n k &= ~((4294967295) << remainingBits);\n remainingBits = 0;\n }\n for (let j = 24; k != 0; j -= 8, k <<= 8) {\n const p = BitArray._lastOnBit[k >>> 0x18];\n if (p >= 0)\n return p + (i * 32) + j;\n }\n }\n return -1;\n }\n}\nBitArray._onBitCount = Int8Array.from([\n 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,\n 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\n 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,\n 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,\n 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,\n 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,\n 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,\n 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8\n]);\nBitArray._firstOnBit = Int8Array.from([\n -1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0\n]);\nBitArray._lastOnBit = Int8Array.from([\n -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,\n 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\n 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7\n]);\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYml0LWFycmF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYml0LWFycmF5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxPQUFPLE9BQU8sUUFBUTtJQW9FM0IsWUFBWSxHQUF5QixFQUFFLGVBQWlDLEtBQUs7UUFackUsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUNaLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFDYixpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUNqQixtQkFBYyxHQUFHLENBQUMsQ0FBQztRQUNuQiwwQkFBcUIsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzQiw0QkFBdUIsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM3QixtQkFBYyxHQUFHLEVBQUUsQ0FBQztRQUNwQiwwQkFBcUIsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuQyxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFLdkIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7WUFDM0IsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDO1lBQ25CLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUMsSUFBSSxZQUFZLEVBQUU7Z0JBQ2hCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtvQkFDbEMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2FBQ2hCO1lBQ0QsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7WUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7U0FDdkI7YUFBTSxJQUFJLEdBQUcsWUFBWSxXQUFXLEVBQUU7WUFDckMsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFrQixDQUFDO1lBQ2hDLElBQUksQ0FBQyxPQUFPLEdBQUcsWUFBc0IsQ0FBQztTQUN2QzthQUFNO1lBQ0wsTUFBTSxJ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QUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Q0FBQyxDQUFDLENBQUM7QUFFNUMsb0JBQVcsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDO0lBQ2xDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUMvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztDQUFDLENBQUMsQ0FBQztBQUU1QyxtQkFBVSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUM7SUFDakMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQy9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDOUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0NBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgY2xhc3MgQml0QXJyYXkge1xuICBzdGF0aWMgX29uQml0Q291bnQgPSBJbnQ4QXJyYXkuZnJvbShbXG4gICAgMCwgMSwgMSwgMiwgMSwgMiwgMiwgMywgMSwgMiwgMiwgMywgMiwgMywgMywgNCxcbiAgICAxLCAyLCAyLCAzLCAyLCAzLCAzLCA0LCAyLCAzLCAzLCA0LCAzLCA0LCA0LCA1LFxuICAgIDEsIDIsIDIsIDMsIDIsIDMsIDMsIDQsIDIsIDMsIDMsIDQsIDMsIDQsIDQsIDUsXG4gICAgMiwgMywgMywgNCwgMywgNCwgNCwgNSwgMywgNCwgNCwgNSwgNCwgNSwgNSwgNixcbiAgICAxLCAyLCAyLCAzLCAyLCAzLCAzLCA0LCAyLCAzLCAzLCA0LCAzLCA0LCA0LCA1LFxuICAgIDIsIDMsIDMsIDQsIDMsIDQsIDQsIDUsIDMsIDQsIDQsIDUsIDQsIDUsIDUsIDYsXG4gICAgMiwgMywgMywgNCwgMywgNCwgNCwgNSwgMywgNCwgNCwgNSwgNCwgNSwgNSwgNixcbiAgICAzLCA0LCA0LCA1LCA0LCA1LCA1LCA2LCA0LCA1LCA1LCA2LCA1LCA2LCA2LCA3LFxuICAgIDEsIDIsIDIsIDMsIDIsIDMsIDMsIDQsIDIsIDMsIDMsIDQsIDMsIDQsIDQsIDUsXG4gICAgMiwgMywgMywgNCwgMywgNCwgNCwgNSwgMywgNCwgNCwgNSwgNCwgNSwgNSwgNixcbiAgICAyLCAzLCAzLCA0LCAzLCA0LCA0LCA1LCAzLCA0LCA0LCA1LCA0LCA1LCA1LCA2LFxuICAgIDMsIDQsIDQsIDUsIDQsIDUsIDUsIDYsIDQsIDUsIDUsIDYsIDUsIDYsIDYsIDcsXG4gICAgMiwgMywgMywgNCwgMywgNCwgNCwgNSwgMywgNCwgNCwgNSwgNCwgNSwgNSwgNixcbiAgICAzLCA0LCA0LCA1LCA0LCA1LCA1LCA2LCA0LCA1LCA1LCA2LCA1LCA2LCA2LCA3LFxuICAgIDMsIDQsIDQsIDUsIDQsIDUsIDUsIDYsIDQsIDUsIDUsIDYsIDUsIDYsIDYsIDcsXG4gICAgNCwgNSwgNSwgNiwgNSwgNiwgNiwgNywgNSwgNiwgNiwgNywgNiwgNywgNywgOF0pO1xuXG4gIHN0YXRpYyBfZmlyc3RPbkJpdCA9IEludDhBcnJheS5mcm9tKFtcbiAgICAtMSwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA0LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDUsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNCwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA2LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDQsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNSwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA0LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDcsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNCwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA1LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDQsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNiwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMCxcbiAgICA0LCAwLCAxLCAwLCAyLCAwLCAxLCAwLCAzLCAwLCAxLCAwLCAyLCAwLCAxLCAwLFxuICAgIDUsIDAsIDEsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDEsIDAsIDIsIDAsIDEsIDAsXG4gICAgNCwgMCwgMSwgMCwgMiwgMCwgMSwgMCwgMywgMCwgMSwgMCwgMiwgMCwgMSwgMF0pO1xuXG4gIHN0YXRpYyBfbGFzdE9uQml0ID0gSW50OEFycmF5LmZyb20oW1xuICAgIC0xLCAwLCAxLCAxLCAyLCAyLCAyLCAyLCAzLCAzLCAzLCAzLCAzLCAzLCAzLCAzLFxuICAgIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsIDQsXG4gICAgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSwgNSxcbiAgICA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LFxuICAgIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsXG4gICAgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNiwgNixcbiAgICA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LCA2LFxuICAgIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsIDYsXG4gICAgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNyxcbiAgICA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LFxuICAgIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsXG4gICAgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNyxcbiAgICA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LFxuICAgIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsIDcsXG4gICAgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNywgNyxcbiAgICA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3LCA3XSk7XG5cbiAgcHJpdmF0ZSBfZGF0YTogVWludDMyQXJyYXk7XG4gIHByaXZhdGUgX2xlbmd0aCA9IDA7XG4gIHByaXZhdGUgX3ZlcnNpb24gPSAwO1xuICBwcml2YXRlIF91cGRhdGVMZXZlbCA9IDA7XG4gIHByaXZhdGUgX3NlbGVjdGVkQ291bnQgPSAwO1xuICBwcml2YXRlIF9zZWxlY3RlZENvdW50VmVyc2lvbiA9IC0xO1xuICBwcml2YXRlIF9zZWxlY3RlZEluZGV4ZXNWZXJzaW9uID0gLTE7XG4gIHByaXZhdGUgX3ZlcnNpb25lZE5hbWUgPSAnJztcbiAgcHJpdmF0ZSBfdmVyc2lvbmVkTmFtZVZlcnNpb24gPSAtMTtcbiAgU0hSSU5LX1RIUkVTSE9MRCA9IDB4MTAwO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IFVpbnQzMkFycmF5LCBsZW5ndGg6IG51bWJlcilcbiAgY29uc3RydWN0b3IobGVuZ3RoOiBudW1iZXIsIGRlZmF1bHRWYWx1ZT86IGJvb2xlYW4pXG4gIGNvbnN0cnVjdG9yKGFyZzogbnVtYmVyIHwgVWludDMyQXJyYXksIGRlZmF1bHRWYWx1ZTogYm9vbGVhbiB8IG51bWJlciA9IGZhbHNlKSB7XG4gICAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSBhcmc7XG4gICAgICBjb25zdCBidWZmID0gQml0QXJyYXkuX2NyZWF0ZUJ1ZmZlcihsZW5ndGgpO1xuICAgICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmYubGVuZ3RoOyBpKyspXG4gICAgICAgICAgYnVmZltpXSA9IC0xO1xuICAgICAgfVxuICAgICAgdGhpcy5fZGF0YSA9IGJ1ZmY7XG4gICAgICB0aGlzLl9sZW5ndGggPSBsZW5ndGg7XG4gICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBVaW50MzJBcnJheSkge1xuICAgICAgdGhpcy5fZGF0YSA9IGFyZyBhcyBVaW50MzJBcnJheTtcbiAgICAgIHRoaXMuX2xlbmd0aCA9IGRlZmF1bHRWYWx1ZSBhcyBudW1iZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgfVxuXG5cbiAgZ2V0UmF3RGF0YSgpIHsgcmV0dXJuIHRoaXMuX2RhdGE7IH1cblxuICBhc3N1cmVHb2V6KG51bTogbnVtYmVyLCBhcmdOYW1lOiBTdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAobnVtIDwgMCkgdGhyb3cgbmV3IEVycm9yKGAke2FyZ05hbWV9IHNob3VsZCBiZSBncmVhdGVyIHRoYW4gemVyb2ApO1xuICB9XG5cbiAgYXNzdXJlSW5SYW5nZSh2YWx1ZTogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIGFyZ05hbWU6IFN0cmluZyk6IHZvaWQge1xuICAgIGlmICgodmFsdWUgPCBtaW4pIHx8ICh2YWx1ZSA+IG1heCkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEFyZ3VtZW50ICR7YXJnTmFtZX0gKCR7dmFsdWV9KSBvdXQgb2YgcmFuZ2UgKCR7bWlufSwgJHttYXh9KWApO1xuICB9XG5cbiAgY29weShzcmM6IFVpbnQzMkFycmF5LCBkc3Q6IFVpbnQzMkFycmF5LCBjb3VudDogbnVtYmVyKTogdm9pZCB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKVxuICAgICAgZHN0W2ldID0gc3JjW2ldO1xuICB9XG5cbiAgY29weUZyb20ob3RoZXI6IEJpdEFycmF5KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCAhPSBvdGhlci5fbGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMZW5ndGhzIGRpZmZlciAoJHt0aGlzLl9sZW5ndGh9ICE9ICR7b3RoZXIuX2xlbmd0aH0pYCk7XG4gICAgdGhpcy5jb3B5KG90aGVyLl9kYXRhLCB0aGlzLl9kYXRhLCB0aGlzLmxlbmd0aEluSW50cyk7XG4gICAgdGhpcy5fdmVyc2lvbisrO1xuICB9XG5cbiAgZ2V0IGxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGJ1ZmZlcigpIHtcbiAgICByZXR1cm4gdGhpcy5fZGF0YTtcbiAgfVxuXG4gIHNldCBidWZmZXIoZGF0YTogVWludDMyQXJyYXkpIHtcbiAgICB0aGlzLl9kYXRhID0gZGF0YTtcbiAgICB0aGlzLl92ZXJzaW9uKys7XG4gIH1cblxuICBnZXQgdmVyc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fdmVyc2lvbjtcbiAgfVxuXG4gIHNldCB2ZXJzaW9uKHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLl92ZXJzaW9uID0gdmFsdWU7XG4gIH1cblxuICBpbmNyZW1lbnRWZXJzaW9uKG5vdGlmeSA9IHRydWUpOiB2b2lkIHtcbiAgICB0aGlzLl92ZXJzaW9uKys7XG4gIH1cblxuICBnZXQgbGVuZ3RoSW5JbnRzKCkge1xuICAgIHJldHVybiBNYXRoLmZsb29yKCh0aGlzLl9sZW5ndGggKyAweDFmKSAvIDB4MjApO1xuICB9XG5cbiAgZ2V0IHZlcnNpb25lZE5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZlcnNpb24gPT0gdGhpcy5fdmVyc2lvbmVkTmFtZVZlcnNpb24gPyB0aGlzLl92ZXJzaW9uZWROYW1lIDogJyc7XG4gIH1cblxuICBzZXQgdmVyc2lvbmVkTmFtZShuYW1lOiBzdHJpbmcpIHtcbiAgICB0aGlzLl92ZXJzaW9uZWROYW1lID0gbmFtZTtcbiAgICB0aGlzLl92ZXJzaW9uZWROYW1lVmVyc2lvbiA9IHRoaXMuX3ZlcnNpb247XG4gIH1cblxuICBnZXQgc2VsZigpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHNldExlbmd0aCh2YWx1ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHZhbHVlIDwgMClcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2hvdWxkIGJlID49IDAnKTtcblxuICAgIGlmICh2YWx1ZSA9PSB0aGlzLl9sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBuSW50c05lZWRlZCA9IE1hdGguZmxvb3IoKHZhbHVlICsgMHgxZikgLyAweDIwKTtcbiAgICBpZiAoKG5JbnRzTmVlZGVkID4gdGhpcy5fZGF0YS5sZW5ndGgpIHx8ICgobkludHNOZWVkZWQgKyB0aGlzLlNIUklOS19USFJFU0hPTEQpIDwgdGhpcy5fZGF0YS5sZW5ndGgpKSB7XG4gICAgICBjb25zdCBuZXdEYXRhID0gbmV3IFVpbnQzMkFycmF5KG5JbnRzTmVlZGVkKTtcbiAgICAgIHRoaXMuY29weSh0aGlzLl9kYXRhLCBuZXdEYXRhLCAobkludHNOZWVkZWQgPiB0aGlzLl9kYXRhLmxlbmd0aCkgPyB0aGlzLl9kYXRhLmxlbmd0aCA6IG5JbnRzTmVlZGVkKTtcbiAgICAgIHRoaXMuX2RhdGEgPSBuZXdEYXRhO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSA+IHRoaXMuX2xlbmd0aCkge1xuICAgICAgaWYgKHRoaXMuX2xlbmd0aCAlIDB4MjAgPiAwKVxuICAgICAgICB0aGlzLl9kYXRhW3RoaXMubGVuZ3RoSW5JbnRzIC0gMV0gJj0gKDEgPDwgKCh0aGlzLl9sZW5ndGggJSAweDIwKSAmIDB4MWYpKSAtIDE7XG5cbiAgICAgIHRoaXMuX2RhdGEuZmlsbCgwLCB0aGlzLmxlbmd0aEluSW50cywgbkludHNOZWVkZWQpO1xuICAgIH1cbiAgICB0aGlzLl9sZW5ndGggPSB2YWx1ZTtcbiAgICB0aGlzLl92ZXJzaW9uKys7XG4gIH1cblxuICBzdGF0aWMgZnJvbUFuZChzZXQxOiBCaXRBcnJheSwgc2V0MjogQml0QXJyYXkpOiBCaXRBcnJheSB7XG4gICAgaWYgKHNldDEuX2xlbmd0aCAhPSBzZXQyLl9sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYExlbmd0aHMgZGlmZmVyICgke3NldDEuX2xlbmd0aH0gIT0gJHtzZXQyLl9sZW5ndGh9KWApO1xuXG4gICAgY29uc3QgdGVtcCA9IG5ldyBCaXRBcnJheShzZXQxLl9sZW5ndGgpO1xuICAgIHRlbXAuX2xlbmd0aCA9IHNldDEuX2xlbmd0aDtcbiAgICB0ZW1wLl9kYXRhID0gQml0QXJyYXkuX2NyZWF0ZUJ1ZmZlcih0ZW1wLl9sZW5ndGgpO1xuICAgIHRlbXAuX3ZlcnNpb24gPSAwO1xuXG4gICAgY29uc3QgbGVuID0gc2V0MS5sZW5ndGhJbkludHM7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIHRlbXAuX2RhdGFbaV0gPSBzZXQxLl9kYXRhW2ldICYgc2V0Mi5fZGF0YVtpXTtcblxuICAgIHJldHVybiB0ZW1wO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgX2NyZWF0ZUJ1ZmZlcihsZW5ndGg6IG51bWJlcik6IFVpbnQzMkFycmF5IHtcbiAgICByZXR1cm4gbmV3IFVpbnQzMkFycmF5KE1hdGguZmxvb3IoKGxlbmd0aCArIDB4MWYpIC8gMHgyMCkpO1xuICB9XG5cbiAgc3RhdGljIGZyb21WYWx1ZXModmFsdWVzOiBBcnJheTxib29sZWFuPik6IEJpdEFycmF5IHtcbiAgICBjb25zdCB0ZW1wID0gbmV3IEJpdEFycmF5KHZhbHVlcy5sZW5ndGgpO1xuICAgIHRlbXAuX3ZlcnNpb24gPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZW1wLl9sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHZhbHVlc1tpXSlcbiAgICAgICAgdGVtcC5fZGF0YVtNYXRoLmZsb29yKGkgLyAweDIwKV0gfD0gMSA8PCAoKGkgJSAweDIwKSAmIDB4MWYpO1xuICAgIH1cbiAgICByZXR1cm4gdGVtcDtcbiAgfVxuXG4gIC8vLyBDb25zdHJ1Y3RzIGEgW0JpdFNldF0gb2YgbGVuZ3RoIFtjb3VudF0sIHdoZXJlIGlkeC10aCBiaXQgaXMgZGV0ZXJtaW5lZCBieSBhIGNhbGwgdG8gW2ZsYWddIChpZHgpLlxuICBzdGF0aWMgZnJvbVNlcShjb3VudDogbnVtYmVyLCBmbGFnOiBGdW5jdGlvbik6IEJpdEFycmF5IHtcbiAgICBjb25zdCB0ZW1wID0gbmV3IEJpdEFycmF5KGNvdW50KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyArK2kpXG4gICAgICB0ZW1wLnNldEJpdChpLCBmbGFnKGkpKTtcblxuICAgIHRlbXAuX3ZlcnNpb24gPSAwO1xuICAgIHJldHVybiB0ZW1wO1xuICB9XG5cbiAgLy8vIENvbnN0cnVjdHMgYSBbQml0U2V0XSBmcm9tIGEgc3RyaW5nIFtzXSBjb250YWluaW5nICcwJyBvciAnMScuXG4gIHN0YXRpYyBmcm9tU3RyaW5nKHM6IHN0cmluZyk6IEJpdEFycmF5IHtcbiAgICByZXR1cm4gQml0QXJyYXkuZnJvbVNlcShzLmxlbmd0aCwgKGk6IG51bWJlcikgPT4gcy5jaGFyQXQoaSkgPT0gJzEnKTtcbiAgfVxuXG4gIC8vLyBDb25zdHJ1Y3RzIGEgW0JpdFNldF0sIGJhc2VkIG9uIGxlbmd0aCBbX2xlbmd0aF0gYW5kIGJ5dGUgYXJyYXkgW19kYXRhXS5cbiAgc3RhdGljIGZyb21VaW50MzJBcnJheShfbGVuZ3RoOiBudW1iZXIsIF9kYXRhOiBVaW50MzJBcnJheSk6IEJpdEFycmF5IHtcbiAgICBjb25zdCB0ZW1wID0gbmV3IEJpdEFycmF5KF9sZW5ndGgpO1xuICAgIHRlbXAuX2RhdGEgPSBfZGF0YTtcbiAgICByZXR1cm4gdGVtcDtcbiAgfVxuXG4gIC8vLyBEZXNlcmlhbGl6ZXMgYSBbQml0U2V0XSBmcm9tIFtieXRlc10uXG4gIHN0YXRpYyBmcm9tQnl0ZXMoYnl0ZXM6IFVpbnQ4QXJyYXkpOiBCaXRBcnJheSB7XG4gICAgY29uc3QgbGVuID0gYnl0ZXMubGVuZ3RoO1xuICAgIGNvbnN0IHRlbXAgPSBuZXcgQml0QXJyYXkobGVuICogOCk7XG4gICAgdGVtcC5fZGF0YSA9IG5ldyBVaW50MzJBcnJheShNYXRoLmZsb29yKChsZW4gKyAzKSAvIDQpKTtcbiAgICB0ZW1wLl9sZW5ndGggPSBsZW4gKiA4O1xuICAgIGxldCBudW0xID0gMDtcbiAgICBsZXQgbnVtMiA9IDA7XG5cbiAgICB3aGlsZSAoKGxlbiAtIG51bTIpID49IDQpIHtcbiAgICAgIHRlbXAuX2RhdGFbbnVtMSsrXSA9IChcbiAgICAgICAgKChieXRlc1tudW0yXSAmIDB4ZmYpIHwgKChieXRlc1tudW0yICsgMV0gJiAweGZmKSA8PCA4KSkgfFxuICAgICAgICAoKGJ5dGVzW251bTIgKyAyXSAmIDB4ZmYpIDw8IDB4MTApXG4gICAgICApIHwgKChieXRlc1tudW0yICsgM10gJiAweGZmKSA8PCAweDE4KTtcblxuICAgICAgbnVtMiArPSA0O1xuICAgIH1cblxuICAgIGlmIChsZW4gLSBudW0yID09IDMpXG4gICAgICB0ZW1wLl9kYXRhW251bTFdID0gKGJ5dGVzW251bTIgKyAyXSAmIDB4ZmYpIDw8IDB4MTA7XG5cbiAgICBpZiAobGVuIC0gbnVtMiA9PSAyKVxuICAgICAgdGVtcC5fZGF0YVtudW0xXSB8PSAoYnl0ZXNbbnVtMiArIDFdICYgMHhmZikgPDwgODtcblxuICAgIGlmIChsZW4gLSBudW0yID09IDEpXG4gICAgICB0ZW1wLl9kYXRhW251bTFdIHw9IGJ5dGVzW251bTJdICYgMHhmZjtcblxuICAgIHRlbXAuX3ZlcnNpb24gPSAwO1xuICAgIHJldHVybiB0ZW1wO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy5fbGVuZ3RofSBiaXRzLCAke3RoaXMuY291bnRCaXRzKHRydWUpfSBzZXRgO1xuICB9XG5cbiAgLy8vIFBlcmZvcm1zIGRlZXAgY29tcGFyaXNvbiBvZiB0d28gYml0c2V0cy5cbiAgZXF1YWxzKG90aGVyOiBCaXRBcnJheSk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzID09IG90aGVyKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAob3RoZXIgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICh0aGlzLl9sZW5ndGggIT0gb3RoZXIuX2xlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICh0aGlzLl9sZW5ndGggPT0gMCkgcmV0dXJuIHRydWU7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoIC0gMTsgaSsrKVxuICAgICAgaWYgKHRoaXMuX2RhdGFbaV0gIT0gb3RoZXIuX2RhdGFbaV0pIHJldHVybiBmYWxzZTtcblxuICAgIGZvciAobGV0IGkgPSAodGhpcy5fZGF0YS5sZW5ndGggLSAxKSAqIDg7IGkgPCB0aGlzLl9sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHRoaXMuZ2V0Qml0KGkpICE9IG90aGVyLmdldEJpdChpKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBDbG9uZXMgYSBiaXRzZXQuICovXG4gIGNsb25lKCk6IEJpdEFycmF5IHtcbiAgICBjb25zdCBiaXRBcnJheSA9IG5ldyBCaXRBcnJheSgwLCBmYWxzZSk7XG4gICAgYml0QXJyYXkuX2RhdGEgPSBVaW50MzJBcnJheS5mcm9tKHRoaXMuX2RhdGEpOyAvLyBlZmZlY3RpdmUgbGVuZ3RoOiAobGVuZ3RoSW5JbnRzKVxuICAgIGJpdEFycmF5Ll9sZW5ndGggPSB0aGlzLl9sZW5ndGg7XG4gICAgYml0QXJyYXkuX3ZlcnNpb24gPSB0aGlzLl92ZXJzaW9uO1xuICAgIHJldHVybiBiaXRBcnJheTtcbiAgfVxuXG4gIC8qKiBJbml0aWFsaXplcyBhIGJpdHNldC4gKi9cbiAgaW5pdChmbGFnOiBGdW5jdGlvbiwgbm90aWZ5OiBib29sZWFuKTogQml0QXJyYXkge1xuICAgIHRoaXMuc2V0QWxsKGZhbHNlLCBmYWxzZSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2xlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoZmxhZyhpKSlcbiAgICAgICAgdGhpcy5fZGF0YVtNYXRoLmZsb29yKGkgLyAweDIwKV0gfD0gMSA8PCAoKGkgJSAweDIwKSAmIDB4MWYpO1xuICAgIH1cblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8vIEludmVydHMgYSBiaXRzZXQuXG4gIGludmVydChub3RpZnkgPSB0cnVlKTogdm9pZCB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9kYXRhLmxlbmd0aDsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSBePSAtMTtcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICB9XG5cbiAgLy8vIFNldHMgYWxsIGJpdHMgdG8gW3ZhbHVlXSwgb3B0aW9uYWxseSBzdXBwcmVzc2luZyBub3RpZmljYXRpb25zLlxuICBzZXRBbGwodmFsdWU6IGJvb2xlYW4sIG5vdGlmeSA9IGZhbHNlKTogdm9pZCB7XG4gICAgY29uc3QgZmxhZ3MgPSB2YWx1ZSA/IC0xIDogMDtcbiAgICBjb25zdCBsZW4gPSB0aGlzLmxlbmd0aEluSW50cztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIC8vdG9kbzogb3B0aW1pemVcbiAgICAgIHRoaXMuX2RhdGFbaV0gPSBmbGFncztcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICB9XG5cbiAgLy8vIFNldHMgYml0cyBhdCBbaW5kZXhlc10gcG9zaXRpb24gdG8gW3ZhbHVlXS5cbiAgLy8vIENsZWFycyB0aGUgYml0c2V0IGlmIFtjbGVhcl0gZmxhZyBpcyB0cnVlLlxuICAvLy8gQ2hhbmdlIG5vdGlmaWNhdGlvbiBpcyByYWlzZWQgd2hlbiBbbm90aWZ5XSBpcyB0cnVlLlxuICBzZXRJbmRleGVzKGluZGV4ZXM6IEFycmF5PG51bWJlcj4sIHZhbHVlID0gdHJ1ZSwgY2xlYXIgPSB0cnVlLCBub3RpZnkgPSB0cnVlKTogdm9pZCB7XG4gICAgaWYgKGNsZWFyKVxuICAgICAgdGhpcy5zZXRBbGwoIXZhbHVlLCBmYWxzZSk7XG5cbiAgICBmb3IgKGNvbnN0IGkgb2YgaW5kZXhlcylcbiAgICAgIHRoaXMuc2V0RmFzdChpLCB2YWx1ZSk7XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgfVxuXG4gIGV2ZXJ5SW5kZXgoaW5kZXhlczogQXJyYXk8bnVtYmVyPiwgdmFsdWUgPSB0cnVlKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBpbmRleGVzKSB7XG4gICAgICBpZiAodGhpcy5nZXRCaXQoaW5kZXgpICE9IHZhbHVlKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgYW55SW5kZXgoaW5kZXhlczogQXJyYXk8bnVtYmVyPiwgdmFsdWUgPSB0cnVlKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBpbmRleGVzKSB7XG4gICAgICBpZiAodGhpcy5nZXRCaXQoaW5kZXgpID09IHZhbHVlKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc2V0V2hlcmUoY2hlY2s6IEZ1bmN0aW9uLCB2YWx1ZSA9IHRydWUsIGNsZWFyID0gdHJ1ZSwgbm90aWZ5ID0gdHJ1ZSwgYWxsb3dDbGVhciA9IHRydWUpOiB2b2lkIHtcbiAgICBpZiAoY2xlYXIgJiYgYWxsb3dDbGVhcilcbiAgICAgIHRoaXMuc2V0QWxsKCF2YWx1ZSwgZmFsc2UpO1xuXG4gICAgaWYgKGFsbG93Q2xlYXIpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGNoZWNrKGkpKVxuICAgICAgICAgIHRoaXMuc2V0RmFzdChpLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbGVuZ3RoOyBpKyspXG4gICAgICAgIHRoaXMuc2V0RmFzdChpLCBjaGVjayhpKSA/IHZhbHVlIDogIXZhbHVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgfVxuXG4gIGdldFJhbmdlKGZyb206IG51bWJlciwgdG86IG51bWJlcik6IEJpdEFycmF5IHtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UoZnJvbSwgMCwgdGhpcy5fbGVuZ3RoIC0gMSwgJ2Zyb20nKTtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UodG8sIDAsIHRoaXMuX2xlbmd0aCwgJ3RvJyk7XG4gICAgY29uc3QgYXJyOiBBcnJheTxib29sZWFuPiA9IFtdO1xuICAgIGZvciAobGV0IGkgPSBmcm9tOyBpIDwgdG87ICsraSlcbiAgICAgIGFyci5wdXNoKHRoaXMuZ2V0Qml0KGkpKTtcbiAgICByZXR1cm4gQml0QXJyYXkuZnJvbVZhbHVlcyhhcnIpO1xuICB9XG5cbiAgZ2V0UmFuZ2VBc0xpc3QoZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyKTogYm9vbGVhbltdIHtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UoZnJvbSwgMCwgdGhpcy5fbGVuZ3RoIC0gMSwgJ2Zyb20nKTtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UodG8sIDAsIHRoaXMuX2xlbmd0aCwgJ3RvJyk7XG4gICAgY29uc3QgYXJyOiBib29sZWFuW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gZnJvbTsgaSA8IHRvOyArK2kpXG4gICAgICBhcnIucHVzaCh0aGlzLmdldEJpdChpKSk7XG4gICAgcmV0dXJuIGFycjtcbiAgfVxuXG5cbiAgc2V0UmFuZ2UoZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyLCB2YWx1ZTogYm9vbGVhbiwgbm90aWZ5ID0gdHJ1ZSk6IEJpdEFycmF5IHtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UoZnJvbSwgMCwgdGhpcy5fbGVuZ3RoIC0gMSwgJ2Zyb20nKTtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UodG8sIDAsIHRoaXMuX2xlbmd0aCAtIDEsICd0bycpO1xuXG4gICAgY29uc3Qgc3RhcnQgPSBNYXRoLm1pbihmcm9tLCB0byk7XG4gICAgY29uc3QgZW5kID0gTWF0aC5tYXgoZnJvbSwgdG8pO1xuXG4gICAgLy90b2RvOiBvcHRpbWl6ZVxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgaSsrKVxuICAgICAgICB0aGlzLnNldFRydWUoaSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8PSBlbmQ7IGkrKylcbiAgICAgICAgdGhpcy5zZXRGYWxzZShpKTtcbiAgICB9XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vLyBTZXRzIG4gcmFuZG9tbHkgY2hvc2VuIGJpdHMgdG8gdmFsdWUsIHJlbWFpbmluZyBiaXRzIHRvICF2YWx1ZS5cbiAgc2V0UmFuZG9tKG46IG51bWJlciwgdmFsdWU6IGJvb2xlYW4sIG5vdGlmeSA9IHRydWUpOiB2b2lkIHtcbiAgICBpZiAobiA8IDAgfHwgbiA+IHRoaXMuX2xlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcignbiBtdXN0IGJlID49IDAgJiYgPD0gQ291bnQnKTtcblxuICAgIGlmIChuID4gdGhpcy5fbGVuZ3RoIC8gMilcbiAgICAgIHRoaXMuc2V0UmFuZG9tKHRoaXMuX2xlbmd0aCAtIG4sICF2YWx1ZSk7XG5cbiAgICB0aGlzLnNldEFsbCghdmFsdWUpO1xuXG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBuOykge1xuICAgICAgY29uc3QgaSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHRoaXMuX2xlbmd0aCk7XG4gICAgICBpZiAodGhpcy5nZXRCaXQoaSkgPT0gdmFsdWUpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5zZXRGYXN0KGksIHZhbHVlKTtcbiAgICAgIGsrKztcbiAgICB9XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgfVxuXG4gIC8vLyBNb2RpZmllcyBjdXJyZW50IGJpdHNldCBieSBwZXJmb3JtaW5nIHRoZSBiaXR3aXNlIEFORCBvcGVyYXRpb24gYWdhaW5zdCB0aGVcbiAgLy8vIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIGFuZCh2YWx1ZTogQml0QXJyYXksIG5vdGlmeSA9IHRydWUpOiBCaXRBcnJheSB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCAhPSB2YWx1ZS5fbGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBsZW5ndGhzIGRpZmZlci4nKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0aGlzLmxlbmd0aEluSW50czsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSAmPSB2YWx1ZS5fZGF0YVtpXTtcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8vIFBlcmZvcm1zIHRoZSBiaXR3aXNlIEFORCBOT1Qgb3BlcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBiaXRzZXRcbiAgLy8vIGFnYWluc3QgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIGFuZE5vdCh2YWx1ZTogQml0QXJyYXksIG5vdGlmeSA9IHRydWUpOiBCaXRBcnJheSB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCAhPSB2YWx1ZS5fbGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBsZW5ndGhzIGRpZmZlci4nKTtcblxuICAgIGNvbnN0IGxlbiA9IHRoaXMubGVuZ3RoSW5JbnRzO1xuICAgIGZvciAobGV0IG51bTIgPSAwOyBudW0yIDwgbGVuOyBudW0yKyspXG4gICAgICB0aGlzLl9kYXRhW251bTJdICY9IH52YWx1ZS5fZGF0YVtudW0yXTtcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8vIFBlcmZvcm1zIHRoZSBiaXR3aXNlIE5PVCBBTkQgb3BlcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBiaXRzZXRcbiAgLy8vIGFnYWluc3QgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIG5vdEFuZCh2YWx1ZTogQml0QXJyYXksIG5vdGlmeSA9IHRydWUpOiBCaXRBcnJheSB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCAhPSB2YWx1ZS5fbGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBsZW5ndGhzIGRpZmZlci4nKTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0aGlzLmxlbmd0aEluSW50czsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSA9ICh+dGhpcy5fZGF0YVtpXSkgJiB2YWx1ZS5fZGF0YVtpXTtcblxuICAgIHRoaXMuaW5jcmVtZW50VmVyc2lvbihub3RpZnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8vIEludmVydHMgYWxsIGJpdCB2YWx1ZXMgaW4gdGhlIGN1cnJlbnQgYml0c2V0XG4gIG5vdChub3RpZnkgPSB0cnVlKTogQml0QXJyYXkge1xuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB0aGlzLmxlbmd0aEluSW50czsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSA9IH50aGlzLl9kYXRhW2ldO1xuXG4gICAgdGhpcy5pbmNyZW1lbnRWZXJzaW9uKG5vdGlmeSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLy8gUGVyZm9ybXMgdGhlIGJpdHdpc2UgT1Igb3BlcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBiaXRzZXRcbiAgLy8vIGFnYWluc3QgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIG9yKHZhbHVlOiBCaXRBcnJheSwgbm90aWZ5ID0gdHJ1ZSkge1xuICAgIGlmICh0aGlzLl9sZW5ndGggIT0gdmFsdWUuX2xlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXJyYXkgbGVuZ3RocyBkaWZmZXIuJyk7XG5cbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gdGhpcy5sZW5ndGhJbkludHM7IGkgPCBsZW47IGkrKylcbiAgICAgIHRoaXMuX2RhdGFbaV0gfD0gdmFsdWUuX2RhdGFbaV07XG5cbiAgICB0aGlzLmluY3JlbWVudFZlcnNpb24obm90aWZ5KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vLyBQZXJmb3JtcyB0aGUgYml0d2lzZSBleGNsdXNpdmUgT1Igb3BlcmF0aW9uIG9uIHRoZSBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBiaXRzZXRcbiAgLy8vIGFnYWluc3QgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBiaXRzZXQuXG4gIHhvcih2YWx1ZTogQml0QXJyYXksIG5vdGlmeSA9IHRydWUpIHtcbiAgICBpZiAodGhpcy5fbGVuZ3RoICE9IHZhbHVlLl9sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FycmF5IGxlbmd0aHMgZGlmZmVyLicpO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHRoaXMubGVuZ3RoSW5JbnRzOyBpIDwgbGVuOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldIF49IHZhbHVlLl9kYXRhW2ldO1xuXG4gICAgdGhpcy5pbmNyZW1lbnRWZXJzaW9uKG5vdGlmeSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLy8gSW5zZXJ0cyBuIDAtYml0cyBhdCBwb3NpdGlvbiBwb3MsIHJlc2l6aW5nIHNlbGYgYW5kIHNoaWZ0aW5nIGJpdHMgYXBwcm9wcmlhdGVseS5cbiAgaW5zZXJ0QXQocG9zOiBudW1iZXIsIG46IG51bWJlciwgZmxhZyA9IGZhbHNlKTogdm9pZCB7XG4gICAgdGhpcy5hc3N1cmVJblJhbmdlKHBvcywgMCwgdGhpcy5fbGVuZ3RoLCAncG9zJyk7XG5cbiAgICBpZiAobiA9PSAwKSByZXR1cm47XG5cbiAgICAvL1RPRE86IG9wdGltaXplXG4gICAgLy90aGUgbW9zdCBwcmltaXRpdmUgaW1wbGVtZW50YXRpb24sIG9wdGltaXplIGl0IGxhdGVyIVxuXG4gICAgLy8gYmVnaW5VcGRhdGUoKTtcbiAgICBjb25zdCBvbGRsZW5ndGggPSB0aGlzLl9sZW5ndGg7XG4gICAgdGhpcy5zZXRMZW5ndGgodGhpcy5fbGVuZ3RoICsgbik7XG5cbiAgICAvL2lmICghY29udGFpbnMoIWZsYWcpKSByZXR1cm47IC8vIG5vdGhpbmcgdG8gZG9cblxuICAgIGZvciAobGV0IGkgPSBvbGRsZW5ndGggLSAxOyBpID49IHBvczsgaS0tKVxuICAgICAgdGhpcy5zZXRCaXQoaSArIG4sIHRoaXMuZ2V0Qml0KGkpKTtcblxuICAgIGZvciAobGV0IGkgPSBwb3M7IGkgPCBwb3MgKyBuOyBpKyspXG4gICAgICB0aGlzLnNldEJpdChpLCBmbGFnKTtcblxuICAgIC8vIGVuZFVwZGF0ZSgpO1xuICB9XG5cbiAgLy8vIERlbGV0ZXMgbiBiaXRzIGJlZ2lubmluZyBhdCBwb3NpdGlvbiBwb3MsIHJlc2l6aW5nIHNlbGYgYW5kIHNoaWZ0aW5nIHJlbWFpbmluZ1xuICAvLy8gYml0cyBhcHByb3ByaWF0ZWx5LlxuICByZW1vdmVBdChwb3M6IG51bWJlciwgbiA9IDEpOiB2b2lkIHtcbiAgICAvLyB0aGUgbW9zdCBwcmltaXRpdmUgaW1wbGVtZW50YXRpb24sIG9wdGltaXplIGl0IGxhdGVyIVxuICAgIGlmIChuIDwgMClcbiAgICAgIHRocm93IG5ldyBFcnJvcignbiBjYW5ub3QgYmUgbmVnYXRpdmUnKTtcblxuICAgIHRoaXMuYXNzdXJlSW5SYW5nZShwb3MsIDAsIHRoaXMuX2xlbmd0aCAtIG4sICdwb3MnKTtcblxuICAgIGlmICh0aGlzLmNvbnRhaW5zKHRydWUpKSB7XG4gICAgICBmb3IgKGxldCBpID0gcG9zOyBpIDwgdGhpcy5fbGVuZ3RoIC0gbjsgaSsrKVxuICAgICAgICB0aGlzLnNldEJpdChpLCB0aGlzLmdldEJpdChpICsgbikpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0TGVuZ3RoKHRoaXMuX2xlbmd0aCAtIG4pO1xuICB9XG5cbiAgcmVtb3ZlQnlNYXNrKG1hc2s6IEJpdEFycmF5LCBmbGFnID0gdHJ1ZSk6IEJpdEFycmF5IHtcbiAgICBpZiAodGhpcy5fbGVuZ3RoICE9IG1hc2subGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggIT0gbWFzay5sZW5ndGgnKTtcblxuICAgIGlmIChtYXNrID09IHRoaXMpIHsgLy8gbm8gbmVlZCB0byBpdGVyYXRlXG4gICAgICB0aGlzLnNldExlbmd0aChtYXNrLmNvdW50Qml0cyghZmxhZykpO1xuICAgICAgdGhpcy5zZXRBbGwoIWZsYWcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgZHN0SWR4ID0gMDtcblxuICAgICAgZm9yIChsZXQgc3JjSWR4ID0gLTE7IChzcmNJZHggPSBtYXNrLmZpbmROZXh0KHNyY0lkeCwgIWZsYWcpKSAhPSAtMTspXG4gICAgICAgIHRoaXMuc2V0RmFzdChkc3RJZHgrKywgdGhpcy5nZXRCaXQoc3JjSWR4KSk7XG5cbiAgICAgIHRoaXMuX2xlbmd0aCA9IGRzdElkeDtcbiAgICAgIHRoaXMuX3ZlcnNpb24rKztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vLyBTaW1pbGFyIHRvIHRoZSBbXSBvcGVyYXRvci5cbiAgZ2V0Qml0KHBvczogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLl9kYXRhW01hdGguZmxvb3IocG9zIC8gMHgyMCldICYgKDEgPDwgKHBvcyAmIDB4MWYpKSkgIT0gMDtcbiAgfVxuXG4gIC8vLyBTaW1pbGFyIHRvIHRoZSBbXSBvcGVyYXRvci5cbiAgc2V0Qml0KHBvczogbnVtYmVyLCBiaXQ6IGJvb2xlYW4sIG5vdGlmeSA9IHRydWUpIHtcbiAgICB0aGlzLnNldEZhc3QocG9zLCBiaXQpO1xuICAgIGlmIChub3RpZnkpXG4gICAgICB0aGlzLl92ZXJzaW9uKys7XG4gICAgZWxzZVxuICAgICAgdGhpcy5fdmVyc2lvbisrO1xuICB9XG5cbiAgLy8vIFNldHMgW2ldLXRoIGJpdCB0byBbdmFsdWVdLCBkb2VzIG5vdCBjaGVjayBib3VuZHMsIGRvZXMgbm90IGluY3JlbWVudCB2ZXJzaW9uXG4gIHNldEZhc3QoaTogbnVtYmVyLCB2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh2YWx1ZSlcbiAgICAgIHRoaXMuX2RhdGFbTWF0aC5mbG9vcihpIC8gMHgyMCldIHw9IDEgPDwgKGkgJiAweDFmKTtcbiAgICBlbHNlXG4gICAgICB0aGlzLl9kYXRhW01hdGguZmxvb3IoaSAvIDB4MjApXSAmPSB+KDEgPDwgKGkgJiAweDFmKSk7XG4gIH1cblxuICBzZXRUcnVlKHBvczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5fZGF0YVtNYXRoLmZsb29yKHBvcyAvIDB4MjApXSB8PSAxIDw8IChwb3MgJiAweDFmKTtcbiAgfVxuXG4gIHNldEZhbHNlKHBvczogbnVtYmVyKSB7XG4gICAgdGhpcy5fZGF0YVtNYXRoLmZsb29yKHBvcyAvIDB4MjApXSAmPSB+KDEgPDwgKHBvcyAmIDB4MWYpKTtcbiAgfVxuXG4gIHRydWVDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNvdW50Qml0cyh0cnVlKTtcbiAgfVxuXG4gIGZhbHNlQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jb3VudEJpdHMoZmFsc2UpO1xuICB9XG5cbiAgLy8vIENvdW50cyBiaXRzIG9mIHRoZSBzcGVjaWZpZWQgdmFsdWUuXG4gIGNvdW50Qml0cyh2YWx1ZTogYm9vbGVhbik6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuX2xlbmd0aCA9PSAwKSByZXR1cm4gMDtcblxuICAgIGlmICh0aGlzLl9zZWxlY3RlZENvdW50VmVyc2lvbiAhPSB0aGlzLl92ZXJzaW9uKSB7XG4gICAgICB0aGlzLl9zZWxlY3RlZENvdW50ID0gMDtcbiAgICAgIGNvbnN0IGxlbiA9IHRoaXMubGVuZ3RoSW5JbnRzO1xuICAgICAgbGV0IGkgPSAwO1xuICAgICAgZm9yICg7IGkgPCBsZW4gLSAxOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgayA9IHRoaXMuX2RhdGFbaV07IGsgIT0gMDsgayA+Pj49IDgpIHsgLy90b2RvOiBjYXN0IGRhdGFbaV0gdG8gdWludFxuICAgICAgICAgIHRoaXMuX3NlbGVjdGVkQ291bnQgKz0gQml0QXJyYXkuX29uQml0Q291bnRbayAmIDB4ZmZdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSBsYXN0IGludC5cbiAgICAgIGxldCBrID0gdGhpcy5fZGF0YVtpXTtcbiAgICAgIGNvbnN0IHJlbWFpbmluZ0JpdHMgPSB0aGlzLl9sZW5ndGggJiAweDFmO1xuICAgICAgaWYgKHJlbWFpbmluZ0JpdHMgIT0gMCkgLyogaWYgcmVtYWluaW5nQml0cyA9PSAwLCB0aGUgbGFzdCBpbnQgaXMgZnVsbHkgdXNlZCBhbmQgQUxMIGJpdHMgc2hvdWxkIGJlIGxlZnQgYXMgaXMgKi9cbiAgICAgICAgayAmPSB+KCg0Mjk0OTY3Mjk1KSA8PCByZW1haW5pbmdCaXRzKTtcblxuICAgICAgZm9yICg7IGsgIT0gMDsgayA+Pj49IDgpXG4gICAgICAgIHRoaXMuX3NlbGVjdGVkQ291bnQgKz0gQml0QXJyYXkuX29uQml0Q291bnRbayAmIDB4ZmZdO1xuXG4gICAgICB0aGlzLl9zZWxlY3RlZENvdW50VmVyc2lvbiA9IHRoaXMuX3ZlcnNpb247XG4gICAgfVxuXG4gICAgcmV0dXJuICh2YWx1ZSA/IHRoaXMuX3NlbGVjdGVkQ291bnQgOiB0aGlzLl9sZW5ndGggLSB0aGlzLl9zZWxlY3RlZENvdW50KTtcbiAgfVxuXG4gIC8vLyBSZXR1cm5zIGEgbnVtYmVyIG9mIHNldCBiaXRzIHdoZXJlIGFsc28gW2NoZWNrXSBpcyB0cnVlXG4gIGNvdW50V2hlcmUoY2hlY2s6IEZ1bmN0aW9uKTogbnVtYmVyIHtcbiAgICBsZXQgcmVzdWx0ID0gMDtcbiAgICBpZiAodGhpcy50cnVlQ291bnQoKSA9PSB0aGlzLl9sZW5ndGgpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbGVuZ3RoOyBpKyspXG4gICAgICAgIHJlc3VsdCArPSBjaGVjayhpKSA/IDEgOiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBpID0gLTE7IChpID0gdGhpcy5maW5kTmV4dChpLCB0cnVlKSkgIT0gLTE7KVxuICAgICAgICByZXN1bHQgKz0gY2hlY2soaSkgPyAxIDogMDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vLyBQZXJmb3JtcyBiaXQgXCJhbmRcIiBhbmQgY291bnRzIGJpdHMgb2YgdGhlIHNwZWNpZmllZCB2YWx1ZSwgd2l0aG91dCBiaXRzZXQgbW9kaWZpY2F0aW9uLlxuICBhbmRXaXRoQ291bnRCaXRzKHNlY29uZDogQml0QXJyYXksIHZhbHVlOiBib29sZWFuKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5fbGVuZ3RoID09IDApIHJldHVybiAwO1xuXG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBjb25zdCBsZW4gPSB0aGlzLmxlbmd0aEluSW50cztcbiAgICBsZXQgaSA9IDA7XG4gICAgZm9yICg7IGkgPCBsZW4gLSAxOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGsgPSB0aGlzLl9kYXRhW2ldICYgc2Vjb25kLl9kYXRhW2ldOyBrICE9IDA7IGsgPj4+PSA4KVxuICAgICAgICBjb3VudCArPSBCaXRBcnJheS5fb25CaXRDb3VudFtrICYgMHhmZl07XG4gICAgfVxuXG4gICAgLy8gVGhlIGxhc3QgaW50LlxuICAgIGxldCBrID0gdGhpcy5fZGF0YVtpXSAmIHNlY29uZC5fZGF0YVtpXTtcbiAgICBjb25zdCByZW1haW5pbmdCaXRzID0gdGhpcy5fbGVuZ3RoICYgMHgxZjtcbiAgICBpZiAocmVtYWluaW5nQml0cyAhPSAwKVxuICAgICAgayAmPSB+KCg0Mjk0OTY3Mjk1KSA8PCByZW1haW5pbmdCaXRzKTtcbiAgICBmb3IgKDsgayAhPSAwOyBrID4+Pj0gOClcbiAgICAgIGNvdW50ICs9IEJpdEFycmF5Ll9vbkJpdENvdW50W2sgJiAweGZmXTtcblxuICAgIHJldHVybiAodmFsdWUgPyBjb3VudCA6IHRoaXMuX2xlbmd0aCAtIGNvdW50KTtcbiAgfVxuXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuc2V0TGVuZ3RoKDApO1xuICB9XG5cbiAgY29udGFpbnModmFsdWU6IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5maW5kTmV4dCgtMSwgdmFsdWUpID49IDA7XG4gIH1cblxuICBnZXQgYWxsVHJ1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb3VudEJpdHModHJ1ZSkgPT0gdGhpcy5fbGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGFsbEZhbHNlKCkge1xuICAgIHJldHVybiB0aGlzLmNvdW50Qml0cyhmYWxzZSkgPT0gdGhpcy5fbGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGFueVRydWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuY291bnRCaXRzKHRydWUpID4gMDtcbiAgfVxuXG4gIGdldCBhbnlGYWxzZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb3VudEJpdHMoZmFsc2UpID4gMDtcbiAgfVxuXG4gIC8vLyBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgbmV4dCBiaXQgb2YgdGhlIHNwZWNpZmllZCB2YWx1ZSwgc3RhcnRpbmcgZnJvbSB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLlxuICAvLy8gUmV0dXJucyAtMSwgaWYgdGhlcmUgYXJlIG5vIHN1Y2ggYml0cy5cbiAgZmluZE5leHQoaW5kZXg6IG51bWJlciwgdmFsdWUgPSB0cnVlKTogbnVtYmVyIHtcbiAgICB0aGlzLmFzc3VyZUluUmFuZ2UoaW5kZXgsIC0xLCB0aGlzLl9sZW5ndGgsICdpbmRleCcpO1xuXG4gICAgaWYgKGluZGV4ID49IHRoaXMuX2xlbmd0aCAtIDEpIHJldHVybiAtMTtcbiAgICBpbmRleCA9IGluZGV4IDwgMCA/IDAgOiBpbmRleCArIDE7IC8vIHNraXAgc3RhcnRcbiAgICBsZXQgdW51c2VkQml0cyA9IGluZGV4ICYgMHgxZjtcbiAgICBjb25zdCBudW1JbnRzID0gdGhpcy5sZW5ndGhJbkludHM7XG5cbiAgICBmb3IgKGxldCBpID0gTWF0aC5mbG9vcihpbmRleCAvIDMyKTsgaSA8IG51bUludHM7IGkrKykge1xuICAgICAgbGV0IGsgPSAodmFsdWUgPyB0aGlzLl9kYXRhW2ldIDogfnRoaXMuX2RhdGFbaV0pOyAvLyB1aW50IGNhc3RcbiAgICAgIGlmICh1bnVzZWRCaXRzICE9IDApIHtcbiAgICAgICAgayAmPSAoKDB4ZmZmZmZmZmYgPDwgdW51c2VkQml0cykgJiAweGZmZmZmZmZmKTtcbiAgICAgICAgdW51c2VkQml0cyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKCF2YWx1ZSAmJiBrID09IC00Mjk0OTY3Mjk2KSAvKiBsb29raW5nIGZvciBmYWxzZSwgYWxsIGJpdHMgYXJlIHNldCAqL3tcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBrICE9IDA7IGogKz0gOCwgayA+Pj49IDgpIHtcbiAgICAgICAgY29uc3QgcCA9IEJpdEFycmF5Ll9maXJzdE9uQml0W2sgJiAweGZmXTtcbiAgICAgICAgaWYgKHAgPj0gMCkge1xuICAgICAgICAgIGluZGV4ID0gcCArIChpICogMzIpICsgajtcbiAgICAgICAgICBpZiAoaW5kZXggPj0gdGhpcy5fbGVuZ3RoKSByZXR1cm4gLTE7XG4gICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIC8vLyBGaW5kcyBwcmV2aW91cyBiaXQgb2YgdGhlIHNwZWNpZmllZCB2YWx1ZSBpbiB0aGUgYml0c2V0LlxuICBmaW5kUHJldihpbmRleDogbnVtYmVyLCB2YWx1ZSA9IHRydWUpOiBudW1iZXIge1xuICAgIGlmIChpbmRleCA9PSAwKSByZXR1cm4gLTE7XG4gICAgdGhpcy5hc3N1cmVJblJhbmdlKGluZGV4LCAtMSwgdGhpcy5fbGVuZ3RoLCAnaW5kZXgnKTtcblxuICAgIGluZGV4ID0gaW5kZXggPCAwID8gdGhpcy5fbGVuZ3RoIC0gMSA6IGluZGV4IC0gMTsgLy8gc2tpcCBzdGFydFxuXG4gICAgY29uc3QgbGFzdEludElkeCA9IE1hdGguZmxvb3IoaW5kZXggLyAweDIwKTtcbiAgICBsZXQgcmVtYWluaW5nQml0cyA9IChpbmRleCArIDEpICYgMHgxZjtcblxuICAgIGZvciAobGV0IGkgPSBsYXN0SW50SWR4OyBpID49IDA7IGktLSkge1xuICAgICAgbGV0IGsgPSAodmFsdWUgPyB0aGlzLl9kYXRhW2ldIDogfnRoaXMuX2RhdGFbaV0pOyAvLyBjYXN0XG4gICAgICBpZiAocmVtYWluaW5nQml0cyAhPSAwKSB7XG4gICAgICAgIGsgJj0gfigoNDI5NDk2NzI5NSkgPDwgcmVtYWluaW5nQml0cyk7XG4gICAgICAgIHJlbWFpbmluZ0JpdHMgPSAwO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaiA9IDI0OyBrICE9IDA7IGogLT0gOCwgayA8PD0gOCkge1xuICAgICAgICBjb25zdCBwID0gQml0QXJyYXkuX2xhc3RPbkJpdFtrID4+PiAweDE4XTtcbiAgICAgICAgaWYgKHAgPj0gMClcbiAgICAgICAgICByZXR1cm4gcCArIChpICogMzIpICsgajtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG59XG4iXX0=","export function hamming(args = {}) {\n function getDistanceF() {\n if (!args || !args.scoringMatrix || !args.alphabetIndexes)\n return (a, b) => a === b ? 0 : 1;\n if (args.scoringMatrix.length !== Object.keys(args.alphabetIndexes).length)\n throw new Error('Scoring matrix and alphabet indexes should have the same length');\n const indexes = args.alphabetIndexes;\n const matrix = args.scoringMatrix;\n //const matrixMap = new Map<string, Map<string, number>>();\n //const map2: any = {};\n const minCharCode = Math.min(...Object.keys(indexes).map((k) => k.charCodeAt(0))) + 1;\n const scorringArray = new Float32Array((matrix.length + minCharCode) * (matrix.length + minCharCode));\n Object.entries(indexes).forEach(([key, index]) => {\n //matrixMap.set(key, new Map<string, number>());\n //map2[key] = {};\n const matrixRow = matrix[index];\n Object.entries(indexes).forEach(([key2, index2]) => {\n //matrixMap.get(key)!.set(key2, matrixRow[index2]);\n scorringArray[key.charCodeAt(0) * matrix.length + key2.charCodeAt(0)] = matrixRow[index2];\n //map2[key][key2] = matrixRow[index2];\n });\n });\n return (a, b) => {\n return 1 - scorringArray[a.charCodeAt(0) * matrix.length + b.charCodeAt(0)];\n };\n }\n const distanceF = getDistanceF();\n const threshold = args?.threshold ?? 0;\n return (seq1, seq2) => {\n // hamming distance should only be used with same size strings,\n // but still, lets add a check and if they are not same length add the difference to the result\n let diff = 0;\n const s1l = seq1.length;\n const s2l = seq2.length;\n const thresholdLimit = Math.ceil(Math.max(s1l, s2l) * (1 - threshold));\n if (s1l !== s2l)\n diff = Math.abs(s1l - s2l);\n let result = 0;\n for (let i = 0; i < Math.min(s1l, s2l); i++) {\n if (seq1[i] !== seq2[i]) {\n result += distanceF(seq1[i], seq2[i]);\n if (result > thresholdLimit)\n return 1;\n }\n }\n result += diff;\n result /= Math.max(s1l, s2l);\n return result;\n };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFtbWluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhhbW1pbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxVQUFVLE9BQU8sQ0FBQyxPQUF3QyxFQUFFO0lBQ2hFLFNBQVMsWUFBWTtRQUNuQixJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlO1lBQ3ZELE9BQU8sQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLE1BQU07WUFDeEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpRUFBaUUsQ0FBQyxDQUFDO1FBQ3JGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUNsQywyREFBMkQ7UUFDM0QsdUJBQXVCO1FBQ3ZCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXRGLE1BQU0sYUFBYSxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUN0RyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDL0MsZ0RBQWdEO1lBQ2hELGlCQUFpQjtZQUNqQixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsRUFBRSxFQUFFO2dCQUNqRCxtREFBbUQ7Z0JBQ25ELGFBQWEsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDMUYsc0NBQXNDO1lBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxFQUFFO1lBQzlCLE9BQU8sQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlFLENBQUMsQ0FBQztJQUNKLENBQUM7SUFDRCxNQUFNLFNBQVMsR0FBRyxZQUFZLEVBQUUsQ0FBQztJQUVqQyxNQUFNLFNBQVMsR0FBRyxJQUFJLEVBQUUsU0FBUyxJQUFJLENBQUMsQ0FBQztJQUV2QyxPQUFPLENBQUMsSUFBWSxFQUFFLElBQVksRUFBRSxFQUFFO1FBQ3BDLCtEQUErRDtRQUMvRCwrRkFBK0Y7UUFDL0YsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUN4QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3hCLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUN2RSxJQUFJLEdBQUcsS0FBSyxHQUFHO1lBQ2IsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBRTdCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNmLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzVDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUN4QixNQUFNLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEMsSUFBSSxNQUFNLEdBQUcsY0FBYztvQkFDekIsT0FBTyxDQUFDLENBQUM7WUFDYixDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sSUFBSSxJQUFJLENBQUM7UUFDZixNQUFNLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDN0IsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7bW1EaXN0YW5jZUZ1bmN0aW9uQXJncywgbW1EaXN0YW5jZUZ1bmN0aW9uVHlwZX0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW1taW5nKGFyZ3M6IFBhcnRpYWw8bW1EaXN0YW5jZUZ1bmN0aW9uQXJncz4gPSB7fSk6IG1tRGlzdGFuY2VGdW5jdGlvblR5cGUge1xuICBmdW5jdGlvbiBnZXREaXN0YW5jZUYoKTogKGE6IHN0cmluZywgYjogc3RyaW5nKSA9PiBudW1iZXIge1xuICAgIGlmICghYXJncyB8fCAhYXJncy5zY29yaW5nTWF0cml4IHx8ICFhcmdzLmFscGhhYmV0SW5kZXhlcylcbiAgICAgIHJldHVybiAoYTogc3RyaW5nLCBiOiBzdHJpbmcpID0+IGEgPT09IGIgPyAwIDogMTtcbiAgICBpZiAoYXJncy5zY29yaW5nTWF0cml4Lmxlbmd0aCAhPT0gT2JqZWN0LmtleXMoYXJncy5hbHBoYWJldEluZGV4ZXMpLmxlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2NvcmluZyBtYXRyaXggYW5kIGFscGhhYmV0IGluZGV4ZXMgc2hvdWxkIGhhdmUgdGhlIHNhbWUgbGVuZ3RoJyk7XG4gICAgY29uc3QgaW5kZXhlcyA9IGFyZ3MuYWxwaGFiZXRJbmRleGVzO1xuICAgIGNvbnN0IG1hdHJpeCA9IGFyZ3Muc2NvcmluZ01hdHJpeDtcbiAgICAvL2NvbnN0IG1hdHJpeE1hcCA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBudW1iZXI+PigpO1xuICAgIC8vY29uc3QgbWFwMjogYW55ID0ge307XG4gICAgY29uc3QgbWluQ2hhckNvZGUgPSBNYXRoLm1pbiguLi5PYmplY3Qua2V5cyhpbmRleGVzKS5tYXAoKGspID0+IGsuY2hhckNvZGVBdCgwKSkpICsgMTtcblxuICAgIGNvbnN0IHNjb3JyaW5nQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KChtYXRyaXgubGVuZ3RoICsgbWluQ2hhckNvZGUpICogKG1hdHJpeC5sZW5ndGggKyBtaW5DaGFyQ29kZSkpO1xuICAgIE9iamVjdC5lbnRyaWVzKGluZGV4ZXMpLmZvckVhY2goKFtrZXksIGluZGV4XSkgPT4ge1xuICAgICAgLy9tYXRyaXhNYXAuc2V0KGtleSwgbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKSk7XG4gICAgICAvL21hcDJba2V5XSA9IHt9O1xuICAgICAgY29uc3QgbWF0cml4Um93ID0gbWF0cml4W2luZGV4XTtcbiAgICAgIE9iamVjdC5lbnRyaWVzKGluZGV4ZXMpLmZvckVhY2goKFtrZXkyLCBpbmRleDJdKSA9PiB7XG4gICAgICAgIC8vbWF0cml4TWFwLmdldChrZXkpIS5zZXQoa2V5MiwgbWF0cml4Um93W2luZGV4Ml0pO1xuICAgICAgICBzY29ycmluZ0FycmF5W2tleS5jaGFyQ29kZUF0KDApICogbWF0cml4Lmxlbmd0aCArIGtleTIuY2hhckNvZGVBdCgwKV0gPSBtYXRyaXhSb3dbaW5kZXgyXTtcbiAgICAgICAgLy9tYXAyW2tleV1ba2V5Ml0gPSBtYXRyaXhSb3dbaW5kZXgyXTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiAoYTogc3RyaW5nLCBiOiBzdHJpbmcpID0+IHtcbiAgICAgIHJldHVybiAxIC0gc2NvcnJpbmdBcnJheVthLmNoYXJDb2RlQXQoMCkgKiBtYXRyaXgubGVuZ3RoICsgYi5jaGFyQ29kZUF0KDApXTtcbiAgICB9O1xuICB9XG4gIGNvbnN0IGRpc3RhbmNlRiA9IGdldERpc3RhbmNlRigpO1xuXG4gIGNvbnN0IHRocmVzaG9sZCA9IGFyZ3M/LnRocmVzaG9sZCA/PyAwO1xuXG4gIHJldHVybiAoc2VxMTogc3RyaW5nLCBzZXEyOiBzdHJpbmcpID0+IHtcbiAgICAvLyBoYW1taW5nIGRpc3RhbmNlIHNob3VsZCBvbmx5IGJlIHVzZWQgd2l0aCBzYW1lIHNpemUgc3RyaW5ncyxcbiAgICAvLyBidXQgc3RpbGwsIGxldHMgYWRkIGEgY2hlY2sgYW5kIGlmIHRoZXkgYXJlIG5vdCBzYW1lIGxlbmd0aCBhZGQgdGhlIGRpZmZlcmVuY2UgdG8gdGhlIHJlc3VsdFxuICAgIGxldCBkaWZmID0gMDtcbiAgICBjb25zdCBzMWwgPSBzZXExLmxlbmd0aDtcbiAgICBjb25zdCBzMmwgPSBzZXEyLmxlbmd0aDtcbiAgICBjb25zdCB0aHJlc2hvbGRMaW1pdCA9IE1hdGguY2VpbChNYXRoLm1heChzMWwsIHMybCkgKiAoMSAtIHRocmVzaG9sZCkpO1xuICAgIGlmIChzMWwgIT09IHMybClcbiAgICAgIGRpZmYgPSBNYXRoLmFicyhzMWwgLSBzMmwpO1xuXG4gICAgbGV0IHJlc3VsdCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNYXRoLm1pbihzMWwsIHMybCk7IGkrKykge1xuICAgICAgaWYgKHNlcTFbaV0gIT09IHNlcTJbaV0pIHtcbiAgICAgICAgcmVzdWx0ICs9IGRpc3RhbmNlRihzZXExW2ldLCBzZXEyW2ldKTtcbiAgICAgICAgaWYgKHJlc3VsdCA+IHRocmVzaG9sZExpbWl0KVxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQgKz0gZGlmZjtcbiAgICByZXN1bHQgLz0gTWF0aC5tYXgoczFsLCBzMmwpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59XG4iXX0=","// Blosum 62 matrix for protein sequences\nconst BLOSUM62 = [[4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3, -2, 0, -2, -1, 0, -4],\n [-1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3, -2, -3, -1, 0, -1, -4],\n [-2, 0, 6, 1, -3, 0, 0, 0, 1, -3, -3, 0, -2, -3, -2, 1, 0, -4, -2, -3, 3, 0, -1, -4],\n [-2, -2, 1, 6, -3, 0, 2, -1, -1, -3, -4, -1, -3, -3, -1, 0, -1, -4, -3, -3, 4, 1, -1, -4],\n [0, -3, -3, -3, 9, -3, -4, -3, -3, -1, -1, -3, -1, -2, -3, -1, -1, -2, -2, -1, -3, -3, -2, -4],\n [-1, 1, 0, 0, -3, 5, 2, -2, 0, -3, -2, 1, 0, -3, -1, 0, -1, -2, -1, -2, 0, 3, -1, -4],\n [-1, 0, 0, 2, -4, 2, 5, -2, 0, -3, -3, 1, -2, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1, -4],\n [0, -2, 0, -1, -3, -2, -2, 6, -2, -4, -4, -2, -3, -3, -2, 0, -2, -2, -3, -3, -1, -2, -1, -4],\n [-2, 0, 1, -1, -3, 0, 0, -2, 8, -3, -3, -1, -2, -1, -2, -1, -2, -2, 2, -3, 0, 0, -1, -4],\n [-1, -3, -3, -3, -1, -3, -3, -4, -3, 4, 2, -3, 1, 0, -3, -2, -1, -3, -1, 3, -3, -3, -1, -4],\n [-1, -2, -3, -4, -1, -2, -3, -4, -3, 2, 4, -2, 2, 0, -3, -2, -1, -2, -1, 1, -4, -3, -1, -4],\n [-1, 2, 0, -1, -3, 1, 1, -2, -1, -3, -2, 5, -1, -3, -1, 0, -1, -3, -2, -2, 0, 1, -1, -4],\n [-1, -1, -2, -3, -1, 0, -2, -3, -2, 1, 2, -1, 5, 0, -2, -1, -1, -1, -1, 1, -3, -1, -1, -4],\n [-2, -3, -3, -3, -2, -3, -3, -3, -1, 0, 0, -3, 0, 6, -4, -2, -2, 1, 3, -1, -3, -3, -1, -4],\n [-1, -2, -2, -1, -3, -1, -1, -2, -2, -3, -3, -1, -2, -4, 7, -1, -1, -4, -3, -2, -2, -1, -2, -4],\n [1, -1, 1, 0, -1, 0, 0, 0, -1, -2, -2, 0, -1, -2, -1, 4, 1, -3, -2, -2, 0, 0, 0, -4],\n [0, -1, 0, -1, -1, -1, -1, -2, -2, -1, -1, -1, -1, -2, -1, 1, 5, -2, -2, 0, -1, -1, 0, -4],\n [-3, -3, -4, -4, -2, -2, -3, -2, -2, -3, -2, -3, -1, 1, -4, -3, -2, 11, 2, -3, -4, -3, -2, -4],\n [-2, -2, -2, -3, -2, -1, -2, -3, 2, -1, -1, -2, -1, 3, -3, -2, -2, 2, 7, -1, -3, -2, -1, -4],\n [0, -3, -3, -3, -1, -2, -2, -3, -3, 3, 1, -2, 1, -1, -2, -2, 0, -3, -1, 4, -3, -2, -1, -4],\n [-2, -1, 3, 4, -3, 0, 1, -1, 0, -3, -4, 0, -3, -3, -2, 0, -1, -4, -3, -3, 4, 1, -1, -4],\n [-1, 0, 0, 1, -3, 3, 4, -2, 0, -3, -3, 1, -1, -3, -1, 0, -1, -3, -2, -2, 1, 4, -1, -4],\n [0, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, 0, 0, -2, -1, -1, -1, -1, -1, -4],\n [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 1]];\n// Protein indexes for BLOSUM matrix\nconst ProtIndexes = {\n 'A': 0, 'R': 1, 'N': 2, 'D': 3, 'C': 4, 'Q': 5, 'E': 6, 'G': 7, 'H': 8,\n 'I': 9, 'L': 10, 'K': 11, 'M': 12, 'F': 13, 'P': 14, 'S': 15, 'T': 16,\n 'W': 17, 'Y': 18, 'V': 19, 'B': 20, 'Z': 21, 'X': 22, '*': 23\n};\nconst defaultArgs = {\n gapOpen: 1,\n gapExtend: 0.6,\n scoringMatrix: BLOSUM62,\n alphabetIndexes: ProtIndexes\n};\n/** Returns a function that calculates the distance between two sequences based on gap penalty and matrix\n * @param {Partial<NeedlemanWunschArgs>}args - arguments for Needleman-Wunsch algorithm like gap penalty, Scoring matrix..\n * @return {mmDistanceFunctionType} - function that calculates the distance between two sequences\n*/\nexport function needlemanWunsch(args) {\n const maxLen = 10000;\n const charCodeArray = new Uint16Array(0x10000);\n const { gapOpen, gapExtend, scoringMatrix, alphabetIndexes } = { ...defaultArgs, ...args };\n Object.entries(alphabetIndexes).forEach(([k, v]) => charCodeArray[k.charCodeAt(0)] = v);\n // As we don't need traceback, no need to store the whole matrix\n // Instead, we will store only the last two rows\n const matrix = [\n new Float32Array(maxLen),\n new Float32Array(maxLen)\n ];\n return (seq1, seq2) => {\n // similarly, we need to keep track of what operation led to the current cell\n // i.e. whether we came from the left, top or diagonal to assign gap open/gap extend penalty\n const verticalGaps = new Array(seq1.length + 1).fill(false);\n const horizontalGaps = new Array(seq1.length + 1).fill(false);\n //variables to keep track which row we are in\n // they will swap places on each iteration\n let prevRow = 0;\n let currRow = 1;\n // Initialize first row\n for (let i = 1; i < seq1.length + 1; i++) {\n matrix[0][i] = -gapExtend - (i - 1) * gapExtend;\n matrix[1][i] = 0;\n }\n matrix[0][0] = 0;\n // Calculate the rest of the matrix\n for (let i = 1; i < seq2.length + 1; i++) {\n matrix[currRow][0] = -gapExtend - (i - 1) * gapExtend;\n for (let j = 1; j < seq1.length + 1; j++) {\n const diagonal = matrix[prevRow][j - 1] +\n scoringMatrix[charCodeArray[seq1.charCodeAt(j - 1)]][charCodeArray[seq2.charCodeAt(i - 1)]];\n const top = matrix[prevRow][j] - (verticalGaps[j] || i === 1 || i === seq2.length ? gapExtend : gapOpen);\n const left = matrix[currRow][j - 1] - (horizontalGaps[j - 1] || j === 1 || j === seq1.length ? gapExtend : gapOpen);\n matrix[currRow][j] = Math.max(diagonal, left, top);\n // update gap arrays\n if (matrix[currRow][j] === diagonal) {\n verticalGaps[j] = false;\n horizontalGaps[j] = false;\n }\n else if (matrix[currRow][j] === left) {\n verticalGaps[j] = false;\n horizontalGaps[j] = true;\n }\n else {\n verticalGaps[j] = true;\n horizontalGaps[j] = false;\n }\n }\n // Swap rows\n prevRow = currRow;\n currRow = (currRow + 1) % 2;\n }\n // as the matrix is the similarity matrix, but we are interested in distance,\n // we need compare it to perfect match score to get reasonable distance\n // const perfectMatchSeq1 = seq1.split('').map((c) => scoringMatrix[alphabetIndexes[c]][alphabetIndexes[c]])\n // .reduce((a, b) => a + b, 0);\n // const perfectMatchSeq2 = seq2.split('').map((c) => scoringMatrix[alphabetIndexes[c]][alphabetIndexes[c]])\n // .reduce((a, b) => a + b, 0);\n // const maxScore = Math.max(perfectMatchSeq1, perfectMatchSeq2);\n const maxScore = Math.min(seq1.length, seq2.length);\n return (maxScore - matrix[prevRow][seq1.length]) / maxScore;\n };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVlZGxlbWFuLXd1bnNjaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm5lZWRsZW1hbi13dW5zY2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EseUNBQXlDO0FBQ3pDLE1BQU0sUUFBUSxHQUNkLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNwRixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6RixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3JGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RGLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzVGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN4RixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDM0YsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzNGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN4RixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzFGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDL0YsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNwRixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzFGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUYsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUYsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RGLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0YsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFD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QUNELDZFQUE2RTtRQUM3RSx1RUFBdUU7UUFDdkUsNEdBQTRHO1FBQzVHLGlDQUFpQztRQUNqQyw0R0FBNEc7UUFDNUcsaUNBQWlDO1FBQ2pDLGlFQUFpRTtRQUNqRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BELE9BQU8sQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQztJQUM5RCxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25BcmdzLCBtbURpc3RhbmNlRnVuY3Rpb25UeXBlfSBmcm9tICcuL3R5cGVzJztcblxuLy8gQmxvc3VtIDYyIG1hdHJpeCBmb3IgcHJvdGVpbiBzZXF1ZW5jZXNcbmNvbnN0IEJMT1NVTTYyOkFycmF5PEFycmF5PG51bWJlcj4+ID1cbltbNCwgLTEsIC0yLCAtMiwgMCwgLTEsIC0xLCAwLCAtMiwgLTEsIC0xLCAtMSwgLTEsIC0yLCAtMSwgMSwgMCwgLTMsIC0yLCAwLCAtMiwgLTEsIDAsIC00XSxcbiAgWy0xLCA1LCAwLCAtMiwgLTMsIDEsIDAsIC0yLCAwLCAtMywgLTIsIDIsIC0xLCAtMywgLTIsIC0xLCAtMSwgLTMsIC0yLCAtMywgLTEsIDAsIC0xLCAtNF0sXG4gIFstMiwgMCwgNiwgMSwgLTMsIDAsIDAsIDAsIDEsIC0zLCAtMywgMCwgLTIsIC0zLCAtMiwgMSwgMCwgLTQsIC0yLCAtMywgMywgMCwgLTEsIC00XSxcbiAgWy0yLCAtMiwgMSwgNiwgLTMsIDAsIDIsIC0xLCAtMSwgLTMsIC00LCAtMSwgLTMsIC0zLCAtMSwgMCwgLTEsIC00LCAtMywgLTMsIDQsIDEsIC0xLCAtNF0sXG4gIFswLCAtMywgLTMsIC0zLCA5LCAtMywgLTQsIC0zLCAtMywgLTEsIC0xLCAtMywgLTEsIC0yLCAtMywgLTEsIC0xLCAtMiwgLTIsIC0xLCAtMywgLTMsIC0yLCAtNF0sXG4gIFstMSwgMSwgMCwgMCwgLTMsIDUsIDIsIC0yLCAwLCAtMywgLTIsIDEsIDAsIC0zLCAtMSwgMCwgLTEsIC0yLCAtMSwgLTIsIDAsIDMsIC0xLCAtNF0sXG4gIFstMSwgMCwgMCwgMiwgLTQsIDIsIDUsIC0yLCAwLCAtMywgLTMsIDEsIC0yLCAtMywgLTEsIDAsIC0xLCAtMywgLTIsIC0yLCAxLCA0LCAtMSwgLTRdLFxuICBbMCwgLTIsIDAsIC0xLCAtMywgLTIsIC0yLCA2LCAtMiwgLTQsIC00LCAtMiwgLTMsIC0zLCAtMiwgMCwgLTIsIC0yLCAtMywgLTMsIC0xLCAtMiwgLTEsIC00XSxcbiAgWy0yLCAwLCAxLCAtMSwgLTMsIDAsIDAsIC0yLCA4LCAtMywgLTMsIC0xLCAtMiwgLTEsIC0yLCAtMSwgLTIsIC0yLCAyLCAtMywgMCwgMCwgLTEsIC00XSxcbiAgWy0xLCAtMywgLTMsIC0zLCAtMSwgLTMsIC0zLCAtNCwgLTMsIDQsIDIsIC0zLCAxLCAwLCAtMywgLTIsIC0xLCAtMywgLTEsIDMsIC0zLCAtMywgLTEsIC00XSxcbiAgWy0xLCAtMiwgLTMsIC00LCAtMSwgLTIsIC0zLCAtNCwgLTMsIDIsIDQsIC0yLCAyLCAwLCAtMywgLTIsIC0xLCAtMiwgLTEsIDEsIC00LCAtMywgLTEsIC00XSxcbiAgWy0xLCAyLCAwLCAtMSwgLTMsIDEsIDEsIC0yLCAtMSwgLTMsIC0yLCA1LCAtMSwgLTMsIC0xLCAwLCAtMSwgLTMsIC0yLCAtMiwgMCwgMSwgLTEsIC00XSxcbiAgWy0xLCAtMSwgLTIsIC0zLCAtMSwgMCwgLTIsIC0zLCAtMiwgMSwgMiwgLTEsIDUsIDAsIC0yLCAtMSwgLTEsIC0xLCAtMSwgMSwgLTMsIC0xLCAtMSwgLTRdLFxuICBbLTIsIC0zLCAtMywgLTMsIC0yLCAtMywgLTMsIC0zLCAtMSwgMCwgMCwgLTMsIDAsIDYsIC00LCAtMiwgLTIsIDEsIDMsIC0xLCAtMywgLTMsIC0xLCAtNF0sXG4gIFstMSwgLTIsIC0yLCAtMSwgLTMsIC0xLCAtMSwgLTIsIC0yLCAtMywgLTMsIC0xLCAtMiwgLTQsIDcsIC0xLCAtMSwgLTQsIC0zLCAtMiwgLTIsIC0xLCAtMiwgLTRdLFxuICBbMSwgLTEsIDEsIDAsIC0xLCAwLCAwLCAwLCAtMSwgLTIsIC0yLCAwLCAtMSwgLTIsIC0xLCA0LCAxLCAtMywgLTIsIC0yLCAwLCAwLCAwLCAtNF0sXG4gIFswLCAtMSwgMCwgLTEsIC0xLCAtMSwgLTEsIC0yLCAtMiwgLTEsIC0xLCAtMSwgLTEsIC0yLCAtMSwgMSwgNSwgLTIsIC0yLCAwLCAtMSwgLTEsIDAsIC00XSxcbiAgWy0zLCAtMywgLTQsIC00LCAtMiwgLTIsIC0zLCAtMiwgLTIsIC0zLCAtMiwgLTMsIC0xLCAxLCAtNCwgLTMsIC0yLCAxMSwgMiwgLTMsIC00LCAtMywgLTIsIC00XSxcbiAgWy0yLCAtMiwgLTIsIC0zLCAtMiwgLTEsIC0yLCAtMywgMiwgLTEsIC0xLCAtMiwgLTEsIDMsIC0zLCAtMiwgLTIsIDIsIDcsIC0xLCAtMywgLTIsIC0xLCAtNF0sXG4gIFswLCAtMywgLTMsIC0zLCAtMSwgLTIsIC0yLCAtMywgLTMsIDMsIDEsIC0yLCAxLCAtMSwgLTIsIC0yLCAwLCAtMywgLTEsIDQsIC0zLCAtMiwgLTEsIC00XSxcbiAgWy0yLCAtMSwgMywgNCwgLTMsIDAsIDEsIC0xLCAwLCAtMywgLTQsIDAsIC0zLCAtMywgLTIsIDAsIC0xLCAtNCwgLTMsIC0zLCA0LCAxLCAtMSwgLTRdLFxuICBbLTEsIDAsIDAsIDEsIC0zLCAzLCA0LCAtMiwgMCwgLTMsIC0zLCAxLCAtMSwgLTMsIC0xLCAwLCAtMSwgLTMsIC0yLCAtMiwgMSwgNCwgLTEsIC00XSxcbiAgWzAsIC0xLCAtMSwgLTEsIC0yLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMiwgMCwgMCwgLTIsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTRdLFxuICBbLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAtNCwgLTQsIC00LCAxXV07XG5cbi8vIFByb3RlaW4gaW5kZXhlcyBmb3IgQkxPU1VNIG1hdHJpeFxuY29uc3QgUHJvdEluZGV4ZXM6IHtbaWQ6c3RyaW5nXTpudW1iZXJ9ID0ge1xuICAnQSc6IDAsICdSJzogMSwgJ04nOiAyLCAnRCc6IDMsICdDJzogNCwgJ1EnOiA1LCAnRSc6IDYsICdHJzogNywgJ0gnOiA4LFxuICAnSSc6IDksICdMJzogMTAsICdLJzogMTEsICdNJzogMTIsICdGJzogMTMsICdQJzogMTQsICdTJzogMTUsICdUJzogMTYsXG4gICdXJzogMTcsICdZJzogMTgsICdWJzogMTksICdCJzogMjAsICdaJzogMjEsICdYJzogMjIsICcqJzogMjNcbn07XG5cbnR5cGUgTmVlZGxlbWFuV3Vuc2NoQXJncyA9IG1tRGlzdGFuY2VGdW5jdGlvbkFyZ3MgJiB7XG4gIGdhcE9wZW46IG51bWJlcjtcbiAgZ2FwRXh0ZW5kOiBudW1iZXI7XG59XG5cbmNvbnN0IGRlZmF1bHRBcmdzOiBOZWVkbGVtYW5XdW5zY2hBcmdzID0ge1xuICBnYXBPcGVuOiAxLFxuICBnYXBFeHRlbmQ6IDAuNixcbiAgc2NvcmluZ01hdHJpeDogQkxPU1VNNjIsXG4gIGFscGhhYmV0SW5kZXhlczogUHJvdEluZGV4ZXNcbn07XG5cbi8qKiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBjYWxjdWxhdGVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byBzZXF1ZW5jZXMgYmFzZWQgb24gZ2FwIHBlbmFsdHkgYW5kIG1hdHJpeFxuICogQHBhcmFtIHtQYXJ0aWFsPE5lZWRsZW1hbld1bnNjaEFyZ3M+fWFyZ3MgLSBhcmd1bWVudHMgZm9yIE5lZWRsZW1hbi1XdW5zY2ggYWxnb3JpdGhtIGxpa2UgZ2FwIHBlbmFsdHksIFNjb3JpbmcgbWF0cml4Li5cbiAqIEByZXR1cm4ge21tRGlzdGFuY2VGdW5jdGlvblR5cGV9IC0gZnVuY3Rpb24gdGhhdCBjYWxjdWxhdGVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byBzZXF1ZW5jZXNcbiovXG5leHBvcnQgZnVuY3Rpb24gbmVlZGxlbWFuV3Vuc2NoKGFyZ3M6IFBhcnRpYWw8TmVlZGxlbWFuV3Vuc2NoQXJncz4pOiBtbURpc3RhbmNlRnVuY3Rpb25UeXBlIHtcbiAgY29uc3QgbWF4TGVuID0gMTAwMDA7XG4gIGNvbnN0IGNoYXJDb2RlQXJyYXkgPSBuZXcgVWludDE2QXJyYXkoMHgxMDAwMCk7XG5cbiAgY29uc3Qge2dhcE9wZW4sIGdhcEV4dGVuZCwgc2NvcmluZ01hdHJpeCwgYWxwaGFiZXRJbmRleGVzfSA9IHsuLi5kZWZhdWx0QXJncywgLi4uYXJnc307XG4gIE9iamVjdC5lbnRyaWVzKGFscGhhYmV0SW5kZXhlcykuZm9yRWFjaCgoW2ssIHZdKSA9PiBjaGFyQ29kZUFycmF5W2suY2hhckNvZGVBdCgwKV0gPSB2KTtcbiAgLy8gQXMgd2UgZG9uJ3QgbmVlZCB0cmFjZWJhY2ssIG5vIG5lZWQgdG8gc3RvcmUgdGhlIHdob2xlIG1hdHJpeFxuICAvLyBJbnN0ZWFkLCB3ZSB3aWxsIHN0b3JlIG9ubHkgdGhlIGxhc3QgdHdvIHJvd3NcbiAgY29uc3QgbWF0cml4OiBBcnJheTxGbG9hdDMyQXJyYXk+ID0gW1xuICAgIG5ldyBGbG9hdDMyQXJyYXkobWF4TGVuKSxcbiAgICBuZXcgRmxvYXQzMkFycmF5KG1heExlbilcbiAgXTtcbiAgcmV0dXJuIChzZXExOiBzdHJpbmcsIHNlcTI6IHN0cmluZykgOiBudW1iZXIgPT4ge1xuICAgIC8vIHNpbWlsYXJseSwgd2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIHdoYXQgb3BlcmF0aW9uIGxlZCB0byB0aGUgY3VycmVudCBjZWxsXG4gICAgLy8gaS5lLiB3aGV0aGVyIHdlIGNhbWUgZnJvbSB0aGUgbGVmdCwgdG9wIG9yIGRpYWdvbmFsIHRvIGFzc2lnbiBnYXAgb3Blbi9nYXAgZXh0ZW5kIHBlbmFsdHlcblxuICAgIGNvbnN0IHZlcnRpY2FsR2FwczogYm9vbGVhbltdID0gbmV3IEFycmF5PGJvb2xlYW4+KHNlcTEubGVuZ3RoICsxKS5maWxsKGZhbHNlKTtcbiAgICBjb25zdCBob3Jpem9udGFsR2FwczogYm9vbGVhbltdID0gbmV3IEFycmF5PGJvb2xlYW4+KHNlcTEubGVuZ3RoICsxKS5maWxsKGZhbHNlKTtcbiAgICAvL3ZhcmlhYmxlcyB0byBrZWVwIHRyYWNrIHdoaWNoIHJvdyB3ZSBhcmUgaW5cbiAgICAvLyB0aGV5IHdpbGwgc3dhcCBwbGFjZXMgb24gZWFjaCBpdGVyYXRpb25cbiAgICBsZXQgcHJldlJvdyA9IDA7XG4gICAgbGV0IGN1cnJSb3cgPSAxO1xuICAgIC8vIEluaXRpYWxpemUgZmlyc3Qgcm93XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBzZXExLmxlbmd0aCArIDE7IGkrKykge1xuICAgICAgbWF0cml4WzBdW2ldID0gLWdhcEV4dGVuZCAtIChpIC0gMSkgKiBnYXBFeHRlbmQ7XG4gICAgICBtYXRyaXhbMV1baV0gPSAwO1xuICAgIH1cbiAgICBtYXRyaXhbMF1bMF0gPSAwO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHRoZSByZXN0IG9mIHRoZSBtYXRyaXhcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHNlcTIubGVuZ3RoICsgMTsgaSsrKSB7XG4gICAgICBtYXRyaXhbY3VyclJvd11bMF0gPSAtZ2FwRXh0ZW5kIC0gKGkgLSAxKSAqIGdhcEV4dGVuZDtcbiAgICAgIGZvciAobGV0IGogPSAxOyBqIDwgc2VxMS5sZW5ndGggKyAxOyBqKyspIHtcbiAgICAgICAgY29uc3QgZGlhZ29uYWwgPVxuICAgICAgICAgIG1hdHJpeFtwcmV2Um93XVtqIC0gMV0gK1xuICAgICAgICAgICAgc2NvcmluZ01hdHJpeFtjaGFyQ29kZUFycmF5W3NlcTEuY2hhckNvZGVBdChqIC0gMSldXVtjaGFyQ29kZUFycmF5W3NlcTIuY2hhckNvZGVBdChpIC0gMSldXTtcbiAgICAgICAgY29uc3QgdG9wID0gbWF0cml4W3ByZXZSb3ddW2pdIC0gKHZlcnRpY2FsR2Fwc1tqXSB8fCBpID09PSAxIHx8IGkgPT09IHNlcTIubGVuZ3RoID8gZ2FwRXh0ZW5kIDogZ2FwT3BlbiApO1xuICAgICAgICBjb25zdCBsZWZ0ID0gbWF0cml4W2N1cnJSb3ddW2ogLSAxXSAtIChob3Jpem9udGFsR2Fwc1tqIC0gMV0gfHwgaiA9PT0gMSB8fCBqID09PSBzZXExLmxlbmd0aCA/IGdhcEV4dGVuZCA6IGdhcE9wZW4pO1xuICAgICAgICBtYXRyaXhbY3VyclJvd11bal0gPSBNYXRoLm1heChcbiAgICAgICAgICBkaWFnb25hbCwgbGVmdCwgdG9wXG4gICAgICAgICk7XG4gICAgICAgIC8vIHVwZGF0ZSBnYXAgYXJyYXlzXG4gICAgICAgIGlmIChtYXRyaXhbY3VyclJvd11bal0gPT09IGRpYWdvbmFsKSB7XG4gICAgICAgICAgdmVydGljYWxHYXBzW2pdID0gZmFsc2U7XG4gICAgICAgICAgaG9yaXpvbnRhbEdhcHNbal0gPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmIChtYXRyaXhbY3VyclJvd11bal0gPT09IGxlZnQpIHtcbiAgICAgICAgICB2ZXJ0aWNhbEdhcHNbal0gPSBmYWxzZTtcbiAgICAgICAgICBob3Jpem9udGFsR2Fwc1tqXSA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmVydGljYWxHYXBzW2pdID0gdHJ1ZTtcbiAgICAgICAgICBob3Jpem9udGFsR2Fwc1tqXSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBTd2FwIHJvd3NcbiAgICAgIHByZXZSb3cgPSBjdXJyUm93O1xuICAgICAgY3VyclJvdyA9IChjdXJyUm93ICsgMSkgJSAyO1xuICAgIH1cbiAgICAvLyBhcyB0aGUgbWF0cml4IGlzIHRoZSBzaW1pbGFyaXR5IG1hdHJpeCwgYnV0IHdlIGFyZSBpbnRlcmVzdGVkIGluIGRpc3RhbmNlLFxuICAgIC8vIHdlIG5lZWQgY29tcGFyZSBpdCB0byBwZXJmZWN0IG1hdGNoIHNjb3JlIHRvIGdldCByZWFzb25hYmxlIGRpc3RhbmNlXG4gICAgLy8gY29uc3QgcGVyZmVjdE1hdGNoU2VxMSA9IHNlcTEuc3BsaXQoJycpLm1hcCgoYykgPT4gc2NvcmluZ01hdHJpeFthbHBoYWJldEluZGV4ZXNbY11dW2FscGhhYmV0SW5kZXhlc1tjXV0pXG4gICAgLy8gICAucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCk7XG4gICAgLy8gY29uc3QgcGVyZmVjdE1hdGNoU2VxMiA9IHNlcTIuc3BsaXQoJycpLm1hcCgoYykgPT4gc2NvcmluZ01hdHJpeFthbHBoYWJldEluZGV4ZXNbY11dW2FscGhhYmV0SW5kZXhlc1tjXV0pXG4gICAgLy8gICAucmVkdWNlKChhLCBiKSA9PiBhICsgYiwgMCk7XG4gICAgLy8gY29uc3QgbWF4U2NvcmUgPSBNYXRoLm1heChwZXJmZWN0TWF0Y2hTZXExLCBwZXJmZWN0TWF0Y2hTZXEyKTtcbiAgICBjb25zdCBtYXhTY29yZSA9IE1hdGgubWluKHNlcTEubGVuZ3RoLCBzZXEyLmxlbmd0aCk7XG4gICAgcmV0dXJuIChtYXhTY29yZSAtIG1hdHJpeFtwcmV2Um93XVtzZXExLmxlbmd0aF0pIC8gbWF4U2NvcmU7XG4gIH07XG59XG4iXX0=","import { hamming } from './hamming';\nimport { levenstein } from './levenstein';\nimport { needlemanWunsch } from './needleman-wunsch';\n/** Enum containing currently supported macromolecule distance functions\n * Hamming distance will be used if the sequences are already aligned\n * Needleman distance will be used for protein sequences with known BLOSUM62 matrix\n * Levenshtein distance will be used for nucleotide sequences as for them substitution matrix is same as identity matrix\n */\nexport var MmDistanceFunctionsNames;\n(function (MmDistanceFunctionsNames) {\n MmDistanceFunctionsNames[\"HAMMING\"] = \"Hamming\";\n MmDistanceFunctionsNames[\"LEVENSHTEIN\"] = \"Levenshtein\";\n MmDistanceFunctionsNames[\"NEEDLEMANN_WUNSCH\"] = \"Needlemann-Wunsch\";\n MmDistanceFunctionsNames[\"MONOMER_CHEMICAL_DISTANCE\"] = \"Monomer chemical distance\";\n})(MmDistanceFunctionsNames || (MmDistanceFunctionsNames = {}));\n;\nexport const mmDistanceFunctions = {\n [MmDistanceFunctionsNames.HAMMING]: hamming,\n [MmDistanceFunctionsNames.LEVENSHTEIN]: levenstein,\n [MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH]: needlemanWunsch,\n [MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE]: hamming\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjcm9tb2xlY3VsZS1kaXN0YW5jZS1mdW5jdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNyb21vbGVjdWxlLWRpc3RhbmNlLWZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBR25EOzs7O0dBSUc7QUFDSCxNQUFNLENBQU4sSUFBWSx3QkFLWDtBQUxELFdBQVksd0JBQXdCO0lBQ2xDLCtDQUFtQixDQUFBO0lBQ25CLHVEQUEyQixDQUFBO0lBQzNCLG1FQUF1QyxDQUFBO0lBQ3ZDLG1GQUF1RCxDQUFBO0FBQ3pELENBQUMsRUFMVyx3QkFBd0IsS0FBeEIsd0JBQXdCLFFBS25DO0FBQUEsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUE4RTtJQUM1RyxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU87SUFDM0MsQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxVQUFVO0lBQ2xELENBQUMsd0JBQXdCLENBQUMsaUJBQWlCLENBQUMsRUFBRSxlQUFlO0lBQzdELENBQUMsd0JBQXdCLENBQUMseUJBQXlCLENBQUMsRUFBRSxPQUFPO0NBQzlELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2hhbW1pbmd9IGZyb20gJy4vaGFtbWluZyc7XG5pbXBvcnQge2xldmVuc3RlaW59IGZyb20gJy4vbGV2ZW5zdGVpbic7XG5pbXBvcnQge25lZWRsZW1hbld1bnNjaH0gZnJvbSAnLi9uZWVkbGVtYW4td3Vuc2NoJztcbmltcG9ydCB7bW1EaXN0YW5jZUZ1bmN0aW9uVHlwZX0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKiBFbnVtIGNvbnRhaW5pbmcgY3VycmVudGx5IHN1cHBvcnRlZCBtYWNyb21vbGVjdWxlIGRpc3RhbmNlIGZ1bmN0aW9uc1xuICogSGFtbWluZyBkaXN0YW5jZSB3aWxsIGJlIHVzZWQgaWYgdGhlIHNlcXVlbmNlcyBhcmUgYWxyZWFkeSBhbGlnbmVkXG4gKiBOZWVkbGVtYW4gZGlzdGFuY2Ugd2lsbCBiZSB1c2VkIGZvciBwcm90ZWluIHNlcXVlbmNlcyB3aXRoIGtub3duIEJMT1NVTTYyIG1hdHJpeFxuICogTGV2ZW5zaHRlaW4gZGlzdGFuY2Ugd2lsbCBiZSB1c2VkIGZvciBudWNsZW90aWRlIHNlcXVlbmNlcyBhcyBmb3IgdGhlbSBzdWJzdGl0dXRpb24gbWF0cml4IGlzIHNhbWUgYXMgaWRlbnRpdHkgbWF0cml4XG4gKi9cbmV4cG9ydCBlbnVtIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB7XG4gIEhBTU1JTkcgPSAnSGFtbWluZycsXG4gIExFVkVOU0hURUlOID0gJ0xldmVuc2h0ZWluJyxcbiAgTkVFRExFTUFOTl9XVU5TQ0ggPSAnTmVlZGxlbWFubi1XdW5zY2gnLFxuICBNT05PTUVSX0NIRU1JQ0FMX0RJU1RBTkNFID0gJ01vbm9tZXIgY2hlbWljYWwgZGlzdGFuY2UnXG59O1xuXG5leHBvcnQgY29uc3QgbW1EaXN0YW5jZUZ1bmN0aW9uczogUmVjb3JkPE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcywgKHZhbHVlPzogYW55KSA9PiBtbURpc3RhbmNlRnVuY3Rpb25UeXBlPiA9IHtcbiAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5IQU1NSU5HXTogaGFtbWluZyxcbiAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5MRVZFTlNIVEVJTl06IGxldmVuc3RlaW4sXG4gIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTkVFRExFTUFOTl9XVU5TQ0hdOiBuZWVkbGVtYW5XdW5zY2gsXG4gIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTU9OT01FUl9DSEVNSUNBTF9ESVNUQU5DRV06IGhhbW1pbmdcbn07XG4iXX0=","import { distance } from 'fastest-levenshtein';\nexport function levenstein() {\n return (seq1, seq2) => {\n return distance(seq1, seq2) / Math.max(seq1.length, seq2.length);\n };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGV2ZW5zdGVpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxldmVuc3RlaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRzdDLE1BQU0sVUFBVSxVQUFVO0lBQ3hCLE9BQU8sQ0FBQyxJQUFZLEVBQUUsSUFBWSxFQUFFLEVBQUU7UUFDcEMsT0FBTyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkUsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7ZGlzdGFuY2V9IGZyb20gJ2Zhc3Rlc3QtbGV2ZW5zaHRlaW4nO1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25UeXBlfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGxldmVuc3RlaW4oKTogbW1EaXN0YW5jZUZ1bmN0aW9uVHlwZSB7XG4gIHJldHVybiAoc2VxMTogc3RyaW5nLCBzZXEyOiBzdHJpbmcpID0+IHtcbiAgICByZXR1cm4gZGlzdGFuY2Uoc2VxMSwgc2VxMikgLyBNYXRoLm1heChzZXExLmxlbmd0aCwgc2VxMi5sZW5ndGgpO1xuICB9O1xufVxuIl19","import BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport { BitArrayMetricsNames } from './typed-metrics/consts';\nimport { MmDistanceFunctionsNames } from './macromolecule-distance-functions';\nexport const similarityMetric = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoSimilarity,\n [BitArrayMetricsNames.Dice]: diceSimilarity,\n [BitArrayMetricsNames.Asymmetric]: asymmetricSimilarity,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetSimilarity,\n [BitArrayMetricsNames.Cosine]: cosineSimilarity,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiSimilarity,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheySimilarity,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergSimilarity,\n [BitArrayMetricsNames.Russel]: russelSimilarity,\n [BitArrayMetricsNames.Sokal]: sokalSimilarity,\n [BitArrayMetricsNames.Hamming]: hammingSimilarity,\n [BitArrayMetricsNames.Euclidean]: euclideanSimilarity,\n};\nexport const distanceMetrics = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoDistance,\n [BitArrayMetricsNames.Dice]: diceDistance,\n [BitArrayMetricsNames.Asymmetric]: asymmetricDistance,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetDistance,\n [BitArrayMetricsNames.Cosine]: cosineDistance,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiDistance,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheyDistance,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergDistance,\n [BitArrayMetricsNames.Russel]: russelDistance,\n [BitArrayMetricsNames.Sokal]: sokalDistance,\n [BitArrayMetricsNames.Hamming]: hammingDistance,\n [BitArrayMetricsNames.Euclidean]: euclideanDistance,\n};\nexport const CHEM_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Dice,\n BitArrayMetricsNames.Cosine\n];\nexport const SEQ_SPACE_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Asymmetric,\n BitArrayMetricsNames.Cosine,\n BitArrayMetricsNames.Sokal\n];\nexport const MACROMOLECULE_SIMILARITY_METRICS = [\n MmDistanceFunctionsNames.HAMMING,\n MmDistanceFunctionsNames.LEVENSHTEIN,\n MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE,\n MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH\n];\nexport function tanimotoSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 1.0;\n const common = x.andWithCountBits(y, true);\n return common / (total - common);\n}\nexport function tanimotoDistance(x, y) {\n return 1 - tanimotoSimilarity(x, y);\n}\nexport function tanimotoDistanceIntArray(x, y) {\n const xb = new BitArray(x, x.length * 32);\n const yb = new BitArray(y, y.length * 32);\n return getDistanceFromSimilarity(tanimotoSimilarity(xb, yb));\n}\nexport function diceSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return 2 * common / total;\n}\nexport function diceDistance(x, y) {\n return 1 - diceSimilarity(x, y);\n}\nexport function cosineSimilarity(x, y) {\n const total = x.trueCount() * y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / Math.sqrt(total);\n}\nexport function cosineDistance(x, y) {\n return 1 - cosineSimilarity(x, y);\n}\nexport function euclideanSimilarity(x, y) {\n return getSimilarityFromDistance(euclideanDistance(x, y));\n}\nexport function euclideanDistance(x, y) {\n return Math.sqrt(x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true));\n}\nexport function hammingSimilarity(x, y) {\n return getSimilarityFromDistance(hammingDistance(x, y));\n}\nexport function hammingDistance(x, y) {\n return x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true);\n}\nexport function sokalSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const common = x.andWithCountBits(y, true);\n return common / (2 * total - 3 * common);\n}\nexport function sokalDistance(x, y) {\n return 1 - sokalSimilarity(x, y);\n}\nexport function kulczynskiSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total) / (2 * totalProd);\n}\nexport function kulczynskiDistance(x, y) {\n return getDistanceFromSimilarity(kulczynskiSimilarity(x, y));\n}\nexport function mcConnaugheySimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total - totalProd) / totalProd;\n}\nexport function mcConnaugheyDistance(x, y) {\n return getDistanceFromSimilarity(mcConnaugheySimilarity(x, y));\n}\nexport function asymmetricSimilarity(x, y) {\n const min = Math.min(x.trueCount(), y.trueCount());\n if (min == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / min;\n}\nexport function asymmetricDistance(x, y) {\n return 1 - asymmetricSimilarity(x, y);\n}\nexport function braunBlanquetSimilarity(x, y) {\n const max = Math.max(x.trueCount(), y.trueCount());\n if (max == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / max;\n}\nexport function braunBlanquetDistance(x, y) {\n return getDistanceFromSimilarity(braunBlanquetSimilarity(x, y));\n}\nexport function russelSimilarity(x, y) {\n if (x.length == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / x.length;\n}\nexport function russelDistance(x, y) {\n return getDistanceFromSimilarity(russelSimilarity(x, y));\n}\nexport function rogotGoldbergSimilarity(x, y) {\n const common = x.andWithCountBits(y, true);\n const total = x.countBits(true) + y.countBits(true);\n const len = x.length;\n const diff = len - total + common;\n if ((common == len) || (diff == len))\n return 1.0;\n else\n return common / total + diff / (2 * len - total);\n}\nexport function rogotGoldbergDistance(x, y) {\n return getDistanceFromSimilarity(rogotGoldbergSimilarity(x, y));\n}\nexport function getSimilarityFromDistance(distance) {\n return 1 / (1 + distance);\n}\nexport function getDistanceFromSimilarity(similarity) {\n return similarity === 0 ? 3.402823E+38 : (1 / similarity) - 1;\n}\nexport function numericDistance(args) {\n if (args && args.range != undefined && args.range > 0) {\n const range = args.range;\n return (a, b) => Math.abs(a - b) / range;\n }\n return (a, b) => Math.abs(a - b);\n}\nexport function commonItemsCount(args) {\n const mostCommon = args?.mostCommon ?? new Set();\n return (arr1, arr2) => {\n const len1 = arr1.length;\n const len2 = arr2.length;\n let count = 0;\n let i1 = 0;\n let i2 = 0;\n while ((i1 < len1) && (i2 < len2)) {\n if (arr1[i1] === arr2[i2]) {\n if (!mostCommon?.has(arr1[i1]))\n ++count;\n ++i1;\n ++i2;\n }\n else if (arr1[i1] < arr2[i2]) {\n ++i1;\n }\n else {\n ++i2;\n }\n }\n return count;\n };\n}\nexport function inverseCommonItemsCount(args) {\n const f = commonItemsCount(args);\n return (arr1, arr2) => {\n if (arr2.length === 0 || arr1.length === 0)\n return 10000;\n return Math.min(arr1.length, arr2.length) / (f(arr1, arr2) + 0.0001);\n };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sUUFBUSxNQUFNLHlDQUF5QyxDQUFDO0FBQy9ELE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBRTVFLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUE2RDtJQUN4RixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFLGtCQUFrQjtJQUNuRCxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFLGNBQWM7SUFDM0MsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxvQkFBb0I7SUFDdkQsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsRUFBRSx1QkFBdUI7SUFDN0QsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxnQkFBZ0I7SUFDL0MsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxvQkFBb0I7SUFDdkQsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsRUFBRSxzQkFBc0I7SUFDM0QsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsRUFBRSx1QkFBdUI7SUFDN0QsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxnQkFBZ0I7SUFDL0MsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFlO0lBQzdDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLEVBQUUsaUJBQWlCO0lBQ2pELENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLEVBQUUsbUJBQW1CO0NBQ3RELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQTZEO0lBQ3ZGLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLEVB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QkFDVixFQUFFLEVBQUUsQ0FBQztnQkFDTCxFQUFFLEVBQUUsQ0FBQztZQUNQLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQUMsRUFBRSxFQUFFLENBQUM7WUFBQyxDQUFDO2lCQUFNLENBQUM7Z0JBQUMsRUFBRSxFQUFFLENBQUM7WUFBQyxDQUFDO1FBQzFELENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsdUJBQXVCLENBQUMsSUFBaUM7SUFDdkUsTUFBTSxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsT0FBTyxDQUFDLElBQXVCLEVBQUUsSUFBdUIsRUFBRSxFQUFFO1FBQzFELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQ3hDLE9BQU8sS0FBSyxDQUFDO1FBRWYsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQztJQUN2RSxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQge0JpdEFycmF5TWV0cmljc05hbWVzfSBmcm9tICcuL3R5cGVkLW1ldHJpY3MvY29uc3RzJztcbmltcG9ydCB7TW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzfSBmcm9tICcuL21hY3JvbW9sZWN1bGUtZGlzdGFuY2UtZnVuY3Rpb25zJztcblxuZXhwb3J0IGNvbnN0IHNpbWlsYXJpdHlNZXRyaWM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9dOiB0YW5pbW90b1NpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXTogZGljZVNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXTogYXN5bW1ldHJpY1NpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XTogYnJhdW5CbGFucXVldFNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdOiBjb3NpbmVTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV06IGt1bGN6eW5za2lTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuTWNDb25uYXVnaGV5XTogbWNDb25uYXVnaGV5U2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddOiByb2dvdEdvbGRiZXJnU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJ1c3NlbF06IHJ1c3NlbFNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF06IHNva2FsU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkhhbW1pbmddOiBoYW1taW5nU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGV1Y2xpZGVhblNpbWlsYXJpdHksXG59O1xuXG5leHBvcnQgY29uc3QgZGlzdGFuY2VNZXRyaWNzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KSA9PiBudW1iZXIgfSA9IHtcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXTogdGFuaW1vdG9EaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkRpY2VdOiBkaWNlRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXTogYXN5bW1ldHJpY0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQnJhdW5CbGFucXVldF06IGJyYXVuQmxhbnF1ZXREaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV06IGNvc2luZURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV06IGt1bGN6eW5za2lEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLk1jQ29ubmF1Z2hleV06IG1jQ29ubmF1Z2hleURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUm9nb3RHb2xkYmVyZ106IHJvZ290R29sZGJlcmdEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJ1c3NlbF06IHJ1c3NlbERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdOiBzb2thbERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuSGFtbWluZ106IGhhbW1pbmdEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGV1Y2xpZGVhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IENIRU1fU0lNSUxBUklUWV9NRVRSSUNTID0gW1xuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90byxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZSxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTtcbmV4cG9ydCBjb25zdCBTRVFfU1BBQ0VfU0lNSUxBUklUWV9NRVRSSUNTID0gW1xuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90byxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpYyxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF07XG5leHBvcnQgY29uc3QgTUFDUk9NT0xFQ1VMRV9TSU1JTEFSSVRZX01FVFJJQ1MgPSBbXG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5IQU1NSU5HLFxuICBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU4sXG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5NT05PTUVSX0NIRU1JQ0FMX0RJU1RBTkNFLFxuICBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTkVFRExFTUFOTl9XVU5TQ0hcbl07XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHRhbmltb3RvU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWwgPT0gMCkgcmV0dXJuIDEuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gKHRvdGFsIC0gY29tbW9uKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRhbmltb3RvRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIDEgLSB0YW5pbW90b1NpbWlsYXJpdHkoeCwgeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0YW5pbW90b0Rpc3RhbmNlSW50QXJyYXkoeDogVWludDMyQXJyYXksIHk6IFVpbnQzMkFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgeGIgPSBuZXcgQml0QXJyYXkoeCwgeC5sZW5ndGggKiAzMik7XG4gIGNvbnN0IHliID0gbmV3IEJpdEFycmF5KHksIHkubGVuZ3RoICogMzIpO1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eSh0YW5pbW90b1NpbWlsYXJpdHkoeGIsIHliKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWNlU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWwgPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gMiAqIGNvbW1vbiAvIHRvdGFsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGljZURpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiAxIC0gZGljZVNpbWlsYXJpdHkoeCwgeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmVTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSAqIHkudHJ1ZUNvdW50KCk7XG4gIGlmICh0b3RhbCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyBNYXRoLnNxcnQodG90YWwpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29zaW5lRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIDEgLSBjb3NpbmVTaW1pbGFyaXR5KHgsIHkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXVjbGlkZWFuU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZShldWNsaWRlYW5EaXN0YW5jZSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldWNsaWRlYW5EaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5zcXJ0KHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpIC0gMiAqIHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW1taW5nU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZShoYW1taW5nRGlzdGFuY2UoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFtbWluZ0Rpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKSAtIDIgKiB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzb2thbFNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgdG90YWwgPSB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKTtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gKDIgKiB0b3RhbCAtIDMgKiBjb21tb24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc29rYWxEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gMSAtIHNva2FsU2ltaWxhcml0eSh4LCB5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGt1bGN6eW5za2lTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCk7XG4gIGNvbnN0IHRvdGFsUHJvZCA9IHgudHJ1ZUNvdW50KCkgKiB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWxQcm9kID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIChjb21tb24gKiB0b3RhbCkgLyAoMiAqIHRvdGFsUHJvZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBrdWxjenluc2tpRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoa3VsY3p5bnNraVNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWNDb25uYXVnaGV5U2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBjb25zdCB0b3RhbFByb2QgPSB4LnRydWVDb3VudCgpICogeS50cnVlQ291bnQoKTtcbiAgaWYgKHRvdGFsUHJvZCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiAoY29tbW9uICogdG90YWwgLSB0b3RhbFByb2QpIC8gdG90YWxQcm9kO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWNDb25uYXVnaGV5RGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkobWNDb25uYXVnaGV5U2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3ltbWV0cmljU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCBtaW4gPSBNYXRoLm1pbih4LnRydWVDb3VudCgpLCB5LnRydWVDb3VudCgpKTtcbiAgaWYgKG1pbiA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyBtaW47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3ltbWV0cmljRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIDEgLSBhc3ltbWV0cmljU2ltaWxhcml0eSh4LCB5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJyYXVuQmxhbnF1ZXRTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IG1heCA9IE1hdGgubWF4KHgudHJ1ZUNvdW50KCksIHkudHJ1ZUNvdW50KCkpO1xuICBpZiAobWF4ID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvIG1heDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJyYXVuQmxhbnF1ZXREaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShicmF1bkJsYW5xdWV0U2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydXNzZWxTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGlmICh4Lmxlbmd0aCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyB4Lmxlbmd0aDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1c3NlbERpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KHJ1c3NlbFNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcm9nb3RHb2xkYmVyZ1NpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICBjb25zdCB0b3RhbCA9IHguY291bnRCaXRzKHRydWUpICsgeS5jb3VudEJpdHModHJ1ZSk7XG4gIGNvbnN0IGxlbiA9IHgubGVuZ3RoO1xuICBjb25zdCBkaWZmID0gbGVuIC0gdG90YWwgKyBjb21tb247XG4gIGlmICgoY29tbW9uID09IGxlbikgfHwgKGRpZmYgPT0gbGVuKSkgcmV0dXJuIDEuMDtcbiAgZWxzZSByZXR1cm4gY29tbW9uIC8gdG90YWwgKyBkaWZmIC8gKDIgKiBsZW4gLSB0b3RhbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByb2dvdEdvbGRiZXJnRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkocm9nb3RHb2xkYmVyZ1NpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZShkaXN0YW5jZTogbnVtYmVyKSB7XG4gIHJldHVybiAxIC8gKDEgKyBkaXN0YW5jZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KHNpbWlsYXJpdHk6IG51bWJlcikgeyAvL2luIGNhc2Ugc2ltaWxhcml0eSBpcyAwLCB1c2UgbWF4IG51bWJlciBmb3IgZmxvYXQzMlxuICByZXR1cm4gc2ltaWxhcml0eSA9PT0gMCA/IDMuNDAyODIzRSszOCA6ICgxIC8gc2ltaWxhcml0eSkgLSAxO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbnVtZXJpY0Rpc3RhbmNlKGFyZ3M/OiB7cmFuZ2U/OiBudW1iZXJ9KSB7XG4gIGlmIChhcmdzICYmIGFyZ3MucmFuZ2UgIT0gdW5kZWZpbmVkICYmIGFyZ3MucmFuZ2UgPiAwKSB7XG4gICAgY29uc3QgcmFuZ2UgPSBhcmdzLnJhbmdlO1xuICAgIHJldHVybiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IE1hdGguYWJzKGEgLSBiKSAvIHJhbmdlO1xuICB9XG5cbiAgcmV0dXJuIChhOiBudW1iZXIsIGI6IG51bWJlcikgPT4gTWF0aC5hYnMoYSAtIGIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tbW9uSXRlbXNDb3VudChhcmdzPzoge21vc3RDb21tb24/OiBTZXQ8bnVtYmVyPn0pIHtcbiAgY29uc3QgbW9zdENvbW1vbiA9IGFyZ3M/Lm1vc3RDb21tb24gPz8gbmV3IFNldDxudW1iZXI+KCk7XG4gIHJldHVybiAoYXJyMTogQXJyYXlMaWtlPG51bWJlcj4sIGFycjI6IEFycmF5TGlrZTxudW1iZXI+KSA9PiB7XG4gICAgY29uc3QgbGVuMSA9IGFycjEubGVuZ3RoO1xuICAgIGNvbnN0IGxlbjIgPSBhcnIyLmxlbmd0aDtcbiAgICBsZXQgY291bnQgPSAwO1xuICAgIGxldCBpMSA9IDA7XG4gICAgbGV0IGkyID0gMDtcblxuICAgIHdoaWxlICgoaTEgPCBsZW4xKSAmJiAoaTIgPCBsZW4yKSkge1xuICAgICAgaWYgKGFycjFbaTFdID09PSBhcnIyW2kyXSkge1xuICAgICAgICBpZiAoIW1vc3RDb21tb24/LmhhcyhhcnIxW2kxXSkpXG4gICAgICAgICAgKytjb3VudDtcbiAgICAgICAgKytpMTtcbiAgICAgICAgKytpMjtcbiAgICAgIH0gZWxzZSBpZiAoYXJyMVtpMV0gPCBhcnIyW2kyXSkgeyArK2kxOyB9IGVsc2UgeyArK2kyOyB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvdW50O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW52ZXJzZUNvbW1vbkl0ZW1zQ291bnQoYXJncz86IHttb3N0Q29tbW9uPzogU2V0PG51bWJlcj59KSB7XG4gIGNvbnN0IGYgPSBjb21tb25JdGVtc0NvdW50KGFyZ3MpO1xuICByZXR1cm4gKGFycjE6IEFycmF5TGlrZTxudW1iZXI+LCBhcnIyOiBBcnJheUxpa2U8bnVtYmVyPikgPT4ge1xuICAgIGlmIChhcnIyLmxlbmd0aCA9PT0gMCB8fCBhcnIxLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiAxMDAwMDtcblxuICAgIHJldHVybiBNYXRoLm1pbihhcnIxLmxlbmd0aCwgYXJyMi5sZW5ndGgpIC8gKGYoYXJyMSwgYXJyMikgKyAwLjAwMDEpO1xuICB9O1xufVxuIl19","import * as fl from 'fastest-levenshtein';\nimport { jaroWinkler } from 'jaro-winkler-typescript';\nimport { asymmetricDistance, braunBlanquetDistance, cosineDistance, diceDistance, euclideanDistance, hammingDistance, kulczynskiDistance, mcConnaugheyDistance, rogotGoldbergDistance, russelDistance, sokalDistance, tanimotoDistance, numericDistance, tanimotoDistanceIntArray, inverseCommonItemsCount, } from '../distance-metrics-methods';\nimport { calculateEuclideanDistance } from '@datagrok-libraries/utils/src/vector-operations';\nimport { mmDistanceFunctions, MmDistanceFunctionsNames } from '../macromolecule-distance-functions';\nimport { DistanceMetricsSubjects, BitArrayMetricsNames, StringMetricsNames, VectorMetricsNames, NumberMetricsNames, IntArrayMetricsNames, NumberArrayMetricsNames } from './consts';\nexport const vectorDistanceMetricsMethods = {\n [VectorMetricsNames.Euclidean]: calculateEuclideanDistance,\n};\nexport const stringDistanceMetricsMethods = {\n [StringMetricsNames.Levenshtein]: fl.distance,\n [StringMetricsNames.JaroWinkler]: jaroWinkler,\n [StringMetricsNames.Manhattan]: manhattanDistance,\n [StringMetricsNames.Onehot]: categoricalDistance,\n};\nexport const bitArrayDistanceMetricsMethods = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoDistance,\n [BitArrayMetricsNames.Dice]: diceDistance,\n [BitArrayMetricsNames.Asymmetric]: asymmetricDistance,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetDistance,\n [BitArrayMetricsNames.Cosine]: cosineDistance,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiDistance,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheyDistance,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergDistance,\n [BitArrayMetricsNames.Russel]: russelDistance,\n [BitArrayMetricsNames.Sokal]: sokalDistance,\n [BitArrayMetricsNames.Hamming]: hammingDistance,\n [BitArrayMetricsNames.Euclidean]: euclideanDistance,\n};\nexport const intArrayDistanceMetricsMethods = {\n [IntArrayMetricsNames.TanimotoIntArray]: tanimotoDistanceIntArray,\n};\nexport const numberDistanceMetricsMethods = {\n [NumberMetricsNames.Difference]: numericDistance,\n};\nexport const numberArrayDistanceMetrics = {\n [NumberArrayMetricsNames.CommonItems]: inverseCommonItemsCount,\n};\nexport const AvailableMetrics = {\n [DistanceMetricsSubjects.Vector]: {\n [VectorMetricsNames.Euclidean]: vectorDistanceMetricsMethods[VectorMetricsNames.Euclidean],\n },\n [DistanceMetricsSubjects.String]: {\n [StringMetricsNames.Levenshtein]: stringDistanceMetricsMethods[StringMetricsNames.Levenshtein],\n [StringMetricsNames.JaroWinkler]: stringDistanceMetricsMethods[StringMetricsNames.JaroWinkler],\n [StringMetricsNames.Manhattan]: stringDistanceMetricsMethods[StringMetricsNames.Manhattan],\n [StringMetricsNames.Onehot]: stringDistanceMetricsMethods[StringMetricsNames.Onehot],\n },\n [DistanceMetricsSubjects.BitArray]: {\n [BitArrayMetricsNames.Tanimoto]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Tanimoto],\n [BitArrayMetricsNames.Dice]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Dice],\n [BitArrayMetricsNames.Asymmetric]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Asymmetric],\n [BitArrayMetricsNames.BraunBlanquet]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.BraunBlanquet],\n [BitArrayMetricsNames.Cosine]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Cosine],\n [BitArrayMetricsNames.Kulczynski]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Kulczynski],\n [BitArrayMetricsNames.McConnaughey]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.McConnaughey],\n [BitArrayMetricsNames.RogotGoldberg]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.RogotGoldberg],\n [BitArrayMetricsNames.Russel]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Russel],\n [BitArrayMetricsNames.Sokal]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Sokal],\n },\n [DistanceMetricsSubjects.MacroMolecule]: {\n [MmDistanceFunctionsNames.HAMMING]: mmDistanceFunctions[MmDistanceFunctionsNames.HAMMING],\n [MmDistanceFunctionsNames.LEVENSHTEIN]: mmDistanceFunctions[MmDistanceFunctionsNames.LEVENSHTEIN],\n [MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH]: mmDistanceFunctions[MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH],\n [MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE]: mmDistanceFunctions[MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE],\n },\n [DistanceMetricsSubjects.Number]: {\n [NumberMetricsNames.Difference]: numberDistanceMetricsMethods[NumberMetricsNames.Difference],\n },\n [DistanceMetricsSubjects.IntArray]: {\n [IntArrayMetricsNames.TanimotoIntArray]: intArrayDistanceMetricsMethods[IntArrayMetricsNames.TanimotoIntArray],\n },\n [DistanceMetricsSubjects.NumberArray]: {\n [NumberArrayMetricsNames.CommonItems]: numberArrayDistanceMetrics[NumberArrayMetricsNames.CommonItems],\n },\n};\nexport const MetricToDataType = Object.keys(AvailableMetrics)\n .reduce((ret, key) => {\n for (const val of Object.keys(AvailableMetrics[key]))\n ret[val] = key;\n return ret;\n}, {});\nexport function isStringMetric(name) {\n return MetricToDataType[name] == 'String';\n}\nexport function isBitArrayMetric(name) {\n return MetricToDataType[name] == 'BitArray';\n}\nexport function isVectorMetric(name) {\n return MetricToDataType[name] == 'Vector';\n}\nexport function isMacroMoleculeMetric(name) {\n return MetricToDataType[name] == DistanceMetricsSubjects.MacroMolecule.toString();\n}\nexport function isNumericMetric(name) {\n return MetricToDataType[name] == DistanceMetricsSubjects.Number.toString();\n}\nexport function isNumberArrayMetric(name) {\n return MetricToDataType[name] == DistanceMetricsSubjects.NumberArray.toString();\n}\n/** Manhattan distance between two sequences (match - 0, mismatch - 1) normalized for length. */\nexport function manhattanDistance(s1, s2) {\n if (s1.length !== s2.length) {\n return 1;\n }\n else {\n let dist = 0;\n for (let i = 1; i < s1.length; i++)\n dist += s1[i] == s2[i] ? 0 : 1;\n return dist / s1.length;\n }\n}\nexport function categoricalDistance(s1, s2) {\n return s1 === s2 ? 0 : 1;\n}\n/** Unified class implementing different string measures. */\nexport class Measure {\n /**\n * Creates an instance of Measure with .\n * @param {string} method Method to calculate distance between strings.\n * @memberof Measurer\n */\n constructor(method) {\n this.method = method;\n this.dataType = MetricToDataType[method];\n }\n /**\n * Returns true if the metric needs arguments to be calculated.\n * @param {KnownMetrics} method Metric to check if it needs arguments.\n * @return {boolean} True if the metric needs arguments.\n * @memberof Measure\n */\n metricNeedsArgs(method) {\n return isMacroMoleculeMetric(method) || isNumericMetric(method) || isNumberArrayMetric(method);\n }\n /**\n * Returns custom string distance function specified.\n * @param {opts} opts Options for the measure. used for macromolecule distances\n * @return {DistanceMetric} Callback of the measure chosen.\n * @memberof Measurer\n */\n getMeasure(opts) {\n const dict = AvailableMetrics;\n if (!dict.hasOwnProperty(this.dataType) || !dict[this.dataType].hasOwnProperty(this.method))\n throw new Error(`Unknown measure ${this.method} for data type ${this.dataType}`);\n return this.metricNeedsArgs(this.method) ?\n dict[this.dataType][this.method](opts) :\n dict[this.dataType][this.method];\n }\n /**\n * Returns custom string distance by the given data type.\n * @param {AvailableDataTypes} dataType Metric's data type\n * @return {string[]} Metric names which expects the given data type\n * @memberof Measurer\n */\n static getMetricByDataType(dataType) {\n return Object.keys(AvailableMetrics[dataType]);\n }\n /** Returns metric names available.\n * @memberof Measurer\n */\n static get availableMeasures() {\n return Object.keys(AvailableMetrics);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWQtbWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInR5cGVkLW1ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxQyxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFcEQsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixxQkFBcUIsRUFDckIsY0FBYyxFQUNkLFlBQVksRUFDWixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZix3QkFBd0IsRUFDeEIsdUJBQXVCLEdBQ3hCLE1BQU0sNkJBQTZCLENBQUM7QUFFckMsT0FBTyxFQUFDLDBCQUEwQixFQUFDLE1BQU0saURBQWlELENBQUM7QUFHM0YsT0FBTyxFQUFDLG1CQUFtQixFQUFFLHdCQUF3QixFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDbEcsT0FBTyxFQUFDLHVCQUF1QixFQUFFLG9CQUFvQixFQUNuRCxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxvQkFBb0IsRUFDaEYsdUJBQXVCLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFHM0MsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQXlEO0lBQ2hHLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsMEJBQTBCO0NBQzNELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBeUQ7SUFDaEcsQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUTtJQUM3QyxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxFQUFFLFdBQVc7SUFDN0MsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxpQkFBaUI7SUFDakQsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxtQkFBbUI7Q0FDakQsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUE2RDtJQUN0RyxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFLGdCQUFnQjtJQUNqRCxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFLFlBQVk7SUFDekMsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxrQkFBa0I7SUFDckQsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsRUFBRSxxQkFBcUI7SUFDM0QsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxjQUFjO0lBQzdDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsa0JBQWtCO0lBQ3JELENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLEVBQUUsb0JBQW9CO0lBQ3pELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUscUJBQXFCO0lBQzNELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsY0FBYztJQUM3QyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxFQUFFLGFBQWE7SUFDM0MsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxlQUFlO0lBQy9DLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLEVBQUUsaUJBQWlCO0NBQ3BELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBbUU7SUFDNUcsQ0FBQyxvQkFBb0IsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLHdCQUF3QjtDQUNsRSxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQXdFO0lBQy9HLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLEVBQUUsZUFBZTtDQUNqRCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQ3FEO0lBQzFGLENBQUMsdUJBQXVCLENBQUMsV0FBVyxDQUFDLEVBQUUsdUJBQXVCO0NBQy9ELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRztJQUM5QixDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQ2hDLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDO0tBQzNGO0lBQ0QsQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUNoQyxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxFQUFFLDRCQUE0QixDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQztRQUM5RixDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxFQUFFLDRCQUE0QixDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQztRQUM5RixDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLDRCQUE0QixDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQztRQUMxRixDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxFQUFFLDRCQUE0QixDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQztLQUNyRjtJQUNELENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDbEMsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUM7UUFDOUYsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUM7UUFDdEYsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUM7UUFDbEcsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUM7UUFDeEcsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7UUFDMUYsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUM7UUFDbEcsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUM7UUFDdEcsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUM7UUFDeEcsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7UUFDMUYsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSw4QkFBOEIsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUM7S0FDekY7SUFDRCxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FBQyxFQUFFO1FBQ3ZDLENBQUMsd0JBQXdCLENBQUMsT0FBTyxDQUFDLEVBQUUsbUJBQW1CLENBQUMsd0JBQXdCLENBQUMsT0FBTyxDQUFDO1FBQ3pGLENBQUMsd0JBQXdCLENBQUMsV0FBVyxDQUFDLEVBQUUsbUJBQW1CLENBQUMsd0JBQXdCLENBQUMsV0FBVyxDQUFDO1FBQ2pHLENBQUMsd0JBQXdCLENBQUMsaUJBQWlCLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyx3QkFBd0IsQ0FBQyxpQkFBaUIsQ0FBQztRQUM3RyxDQUFDLHdCQUF3QixDQUFDLHlCQUF5QixDQUFDLEVBQ2xELG1CQUFtQixDQUFDLHdCQUF3QixDQUFDLHlCQUF5QixDQUFDO0tBQzFFO0lBQ0QsQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUNoQyxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxFQUFFLDRCQUE0QixDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQztLQUM3RjtJQUNELENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDbEMsQ0FBQyxvQkFBb0IsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLGdCQUFnQixDQUFDO0tBQy9HO0lBQ0QsQ0FBQyx1QkFBdUIsQ0FBQyxXQUFXLENBQUMsRUFBRTtRQUNyQyxDQUFDLHVCQUF1QixDQUFDLFdBQVcsQ0FBQyxFQUFFLDBCQUEwQixDQUFDLHVCQUF1QixDQUFDLFdBQVcsQ0FBQztLQUN2RztDQUNGLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBcUIsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztLQUM1RSxNQUFNLENBQUMsQ0FBQyxHQUFxQixFQUFFLEdBQUcsRUFBRSxFQUFFO0lBQ3JDLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUF5QixDQUFDLENBQUM7UUFDeEUsR0FBRyxDQUFDLEdBQXlCLENBQUMsR0FBRyxHQUFHLENBQUM7SUFFdkMsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFrQlQsTUFBTSxVQUFVLGNBQWMsQ0FBQyxJQUFrQjtJQUMvQyxPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLFFBQVEsQ0FBQztBQUM1QyxDQUFDO0FBRUQsTUFBTSxVQUFVLGdCQUFnQixDQUFDLElBQWtCO0lBQ2pELE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDO0FBQzlDLENBQUM7QUFFRCxNQUFNLFVBQVUsY0FBYyxDQUFDLElBQWtCO0lBQy9DLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksUUFBUSxDQUFDO0FBQzVDLENBQUM7QUFFRCxNQUFNLFVBQVUscUJBQXFCLENBQUMsSUFBa0I7SUFDdEQsT0FBTyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDcEYsQ0FBQztBQUVELE1BQU0sVUFBVSxlQUFlLENBQUMsSUFBa0I7SUFDaEQsT0FBTyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDN0UsQ0FBQztBQUVELE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxJQUFrQjtJQUNwRCxPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLHVCQUF1QixDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUNsRixDQUFDO0FBRUQsZ0dBQWdHO0FBQ2hHLE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxFQUFVLEVBQUUsRUFBVTtJQUN0RCxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQztTQUFNLENBQUM7UUFDTixJQUFJLElBQUksR0FBVyxDQUFDLENBQUM7UUFDckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFO1lBQ2hDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQyxPQUFPLElBQUksR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQzFCLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEVBQVUsRUFBRSxFQUFVO0lBQ3hELE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQUVELDREQUE0RDtBQUM1RCxNQUFNLE9BQU8sT0FBTztJQUlsQjs7OztPQUlHO0lBQ0gsWUFBWSxNQUFvQjtRQUM5QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBdUIsQ0FBQztJQUNqRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxlQUFlLENBQUMsTUFBb0I7UUFDekMsT0FBTyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakcsQ0FBQztJQUNEOzs7OztPQUtHO0lBQ0ksVUFBVSxDQUFDLElBQVU7UUFDMUIsTUFBTSxJQUFJLEdBRU4sZ0JBQWdCLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUN6RixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixJQUFJLENBQUMsTUFBTSxrQkFBa0IsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDbkYsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBcUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzdFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBbUIsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsbUJBQW1CLENBQUMsUUFBNEI7UUFDNUQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxLQUFLLGlCQUFpQjtRQUMxQixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmbCBmcm9tICdmYXN0ZXN0LWxldmVuc2h0ZWluJztcbmltcG9ydCB7amFyb1dpbmtsZXJ9IGZyb20gJ2phcm8td2lua2xlci10eXBlc2NyaXB0JztcbmltcG9ydCB7RGlzdGFuY2VNZXRyaWN9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7XG4gIGFzeW1tZXRyaWNEaXN0YW5jZSxcbiAgYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBjb3NpbmVEaXN0YW5jZSxcbiAgZGljZURpc3RhbmNlLFxuICBldWNsaWRlYW5EaXN0YW5jZSxcbiAgaGFtbWluZ0Rpc3RhbmNlLFxuICBrdWxjenluc2tpRGlzdGFuY2UsXG4gIG1jQ29ubmF1Z2hleURpc3RhbmNlLFxuICByb2dvdEdvbGRiZXJnRGlzdGFuY2UsXG4gIHJ1c3NlbERpc3RhbmNlLFxuICBzb2thbERpc3RhbmNlLFxuICB0YW5pbW90b0Rpc3RhbmNlLFxuICBudW1lcmljRGlzdGFuY2UsXG4gIHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSxcbiAgaW52ZXJzZUNvbW1vbkl0ZW1zQ291bnQsXG59IGZyb20gJy4uL2Rpc3RhbmNlLW1ldHJpY3MtbWV0aG9kcyc7XG5cbmltcG9ydCB7Y2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2V9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3ZlY3Rvci1vcGVyYXRpb25zJztcbmltcG9ydCBCaXRBcnJheSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy9iaXQtYXJyYXknO1xuaW1wb3J0IHtWZWN0b3IsIFN0cmluZ0RpY3Rpb25hcnl9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7bW1EaXN0YW5jZUZ1bmN0aW9ucywgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzfSBmcm9tICcuLi9tYWNyb21vbGVjdWxlLWRpc3RhbmNlLWZ1bmN0aW9ucyc7XG5pbXBvcnQge0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLCBCaXRBcnJheU1ldHJpY3NOYW1lcyxcbiAgU3RyaW5nTWV0cmljc05hbWVzLCBWZWN0b3JNZXRyaWNzTmFtZXMsIE51bWJlck1ldHJpY3NOYW1lcywgSW50QXJyYXlNZXRyaWNzTmFtZXMsXG4gIE51bWJlckFycmF5TWV0cmljc05hbWVzfSBmcm9tICcuL2NvbnN0cyc7XG5cblxuZXhwb3J0IGNvbnN0IHZlY3RvckRpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBWZWN0b3IsIHk6IFZlY3RvcikgPT4gbnVtYmVyIH0gPSB7XG4gIFtWZWN0b3JNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogY2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2UsXG59O1xuXG5leHBvcnQgY29uc3Qgc3RyaW5nRGlzdGFuY2VNZXRyaWNzTWV0aG9kczogeyBbbmFtZTogc3RyaW5nXTogKHg6IHN0cmluZywgeTogc3RyaW5nKSA9PiBudW1iZXIgfSA9IHtcbiAgW1N0cmluZ01ldHJpY3NOYW1lcy5MZXZlbnNodGVpbl06IGZsLmRpc3RhbmNlLFxuICBbU3RyaW5nTWV0cmljc05hbWVzLkphcm9XaW5rbGVyXTogamFyb1dpbmtsZXIsXG4gIFtTdHJpbmdNZXRyaWNzTmFtZXMuTWFuaGF0dGFuXTogbWFuaGF0dGFuRGlzdGFuY2UsXG4gIFtTdHJpbmdNZXRyaWNzTmFtZXMuT25laG90XTogY2F0ZWdvcmljYWxEaXN0YW5jZSxcbn07XG5cbmV4cG9ydCBjb25zdCBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9dOiB0YW5pbW90b0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV06IGRpY2VEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkFzeW1tZXRyaWNdOiBhc3ltbWV0cmljRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XTogYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTogY29zaW5lRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5LdWxjenluc2tpXToga3VsY3p5bnNraURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuTWNDb25uYXVnaGV5XTogbWNDb25uYXVnaGV5RGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXTogcm9nb3RHb2xkYmVyZ0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXTogcnVzc2VsRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF06IHNva2FsRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5IYW1taW5nXTogaGFtbWluZ0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogZXVjbGlkZWFuRGlzdGFuY2UsXG59O1xuXG5leHBvcnQgY29uc3QgaW50QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogVWludDMyQXJyYXksIHk6IFVpbnQzMkFycmF5KSA9PiBudW1iZXIgfSA9IHtcbiAgW0ludEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvSW50QXJyYXldOiB0YW5pbW90b0Rpc3RhbmNlSW50QXJyYXksXG59O1xuXG5leHBvcnQgY29uc3QgbnVtYmVyRGlzdGFuY2VNZXRyaWNzTWV0aG9kczogeyBbbmFtZTogc3RyaW5nXTogKGFyZ3M6IGFueSkgPT4gKHg6IG51bWJlciwgeTogbnVtYmVyKSA9PiBudW1iZXIgfSA9IHtcbiAgW051bWJlck1ldHJpY3NOYW1lcy5EaWZmZXJlbmNlXTogbnVtZXJpY0Rpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IG51bWJlckFycmF5RGlzdGFuY2VNZXRyaWNzOlxueyBbbmFtZTogc3RyaW5nXTogKGFyZ3M6IGFueSkgPT4gKHg6IEFycmF5TGlrZTxudW1iZXI+LCB5OiBBcnJheUxpa2U8bnVtYmVyPikgPT4gbnVtYmVyIH0gPSB7XG4gIFtOdW1iZXJBcnJheU1ldHJpY3NOYW1lcy5Db21tb25JdGVtc106IGludmVyc2VDb21tb25JdGVtc0NvdW50LFxufTtcblxuZXhwb3J0IGNvbnN0IEF2YWlsYWJsZU1ldHJpY3MgPSB7XG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5WZWN0b3JdOiB7XG4gICAgW1ZlY3Rvck1ldHJpY3NOYW1lcy5FdWNsaWRlYW5dOiB2ZWN0b3JEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1ZlY3Rvck1ldHJpY3NOYW1lcy5FdWNsaWRlYW5dLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuU3RyaW5nXToge1xuICAgIFtTdHJpbmdNZXRyaWNzTmFtZXMuTGV2ZW5zaHRlaW5dOiBzdHJpbmdEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1N0cmluZ01ldHJpY3NOYW1lcy5MZXZlbnNodGVpbl0sXG4gICAgW1N0cmluZ01ldHJpY3NOYW1lcy5KYXJvV2lua2xlcl06IHN0cmluZ0Rpc3RhbmNlTWV0cmljc01ldGhvZHNbU3RyaW5nTWV0cmljc05hbWVzLkphcm9XaW5rbGVyXSxcbiAgICBbU3RyaW5nTWV0cmljc05hbWVzLk1hbmhhdHRhbl06IHN0cmluZ0Rpc3RhbmNlTWV0cmljc01ldGhvZHNbU3RyaW5nTWV0cmljc05hbWVzLk1hbmhhdHRhbl0sXG4gICAgW1N0cmluZ01ldHJpY3NOYW1lcy5PbmVob3RdOiBzdHJpbmdEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1N0cmluZ01ldHJpY3NOYW1lcy5PbmVob3RdLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuQml0QXJyYXldOiB7XG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpY106IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQnJhdW5CbGFucXVldF06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLkt1bGN6eW5za2ldOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLk1jQ29ubmF1Z2hleV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5SdXNzZWxdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuTWFjcm9Nb2xlY3VsZV06IHsgLy8gb3B0aW9uYWwgYXJncyBuZWVkZWQgZm9yIG1hY3JvbW9sZWN1bGUgZnVuY3Rpb25zIHdoaWNoIGluaXRpYWxpemUgdGhlbVxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuSEFNTUlOR106IG1tRGlzdGFuY2VGdW5jdGlvbnNbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkddLFxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU5dOiBtbURpc3RhbmNlRnVuY3Rpb25zW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5MRVZFTlNIVEVJTl0sXG4gICAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5ORUVETEVNQU5OX1dVTlNDSF06IG1tRGlzdGFuY2VGdW5jdGlvbnNbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk5FRURMRU1BTk5fV1VOU0NIXSxcbiAgICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk1PTk9NRVJfQ0hFTUlDQUxfRElTVEFOQ0VdOlxuICAgICAgbW1EaXN0YW5jZUZ1bmN0aW9uc1tNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTU9OT01FUl9DSEVNSUNBTF9ESVNUQU5DRV0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5OdW1iZXJdOiB7XG4gICAgW051bWJlck1ldHJpY3NOYW1lcy5EaWZmZXJlbmNlXTogbnVtYmVyRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tOdW1iZXJNZXRyaWNzTmFtZXMuRGlmZmVyZW5jZV0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5JbnRBcnJheV06IHtcbiAgICBbSW50QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9JbnRBcnJheV06IGludEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tJbnRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b0ludEFycmF5XSxcbiAgfSxcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLk51bWJlckFycmF5XToge1xuICAgIFtOdW1iZXJBcnJheU1ldHJpY3NOYW1lcy5Db21tb25JdGVtc106IG51bWJlckFycmF5RGlzdGFuY2VNZXRyaWNzW051bWJlckFycmF5TWV0cmljc05hbWVzLkNvbW1vbkl0ZW1zXSxcbiAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBNZXRyaWNUb0RhdGFUeXBlOiBTdHJpbmdEaWN0aW9uYXJ5ID0gT2JqZWN0LmtleXMoQXZhaWxhYmxlTWV0cmljcylcbiAgLnJlZHVjZSgocmV0OiBTdHJpbmdEaWN0aW9uYXJ5LCBrZXkpID0+IHtcbiAgICBmb3IgKGNvbnN0IHZhbCBvZiBPYmplY3Qua2V5cyhBdmFpbGFibGVNZXRyaWNzW2tleSBhcyBBdmFpbGFibGVEYXRhVHlwZXNdKSlcbiAgICAgIHJldFt2YWwgYXMgQXZhaWxhYmxlRGF0YVR5cGVzXSA9IGtleTtcblxuICAgIHJldHVybiByZXQ7XG4gIH0sIHt9KTtcblxuZXhwb3J0IHR5cGUgQXZhaWxhYmxlRGF0YVR5cGVzID0ga2V5b2YgdHlwZW9mIEF2YWlsYWJsZU1ldHJpY3M7XG5leHBvcnQgdHlwZSBWZWN0b3JNZXRyaWNzID0ga2V5b2YgdHlwZW9mIEF2YWlsYWJsZU1ldHJpY3NbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuVmVjdG9yXTtcbmV4cG9ydCB0eXBlIFN0cmluZ01ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5TdHJpbmddO1xuZXhwb3J0IHR5cGUgQml0QXJyYXlNZXRyaWNzID0ga2V5b2YgdHlwZW9mIEF2YWlsYWJsZU1ldHJpY3NbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuQml0QXJyYXldO1xuZXhwb3J0IHR5cGUgTnVtYmVyTWV0cmljcyA9IGtleW9mIHR5cGVvZiBBdmFpbGFibGVNZXRyaWNzW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLk51bWJlcl07XG5leHBvcnQgdHlwZSBJbnRBcnJheU1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5JbnRBcnJheV07XG5leHBvcnQgdHlwZSBOdW1iZXJBcnJheU1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5OdW1iZXJBcnJheV07XG5leHBvcnQgdHlwZSBLbm93bk1ldHJpY3MgPSBTdHJpbmdNZXRyaWNzIHwgQml0QXJyYXlNZXRyaWNzIHwgVmVjdG9yTWV0cmljcyB8XG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB8IE51bWJlck1ldHJpY3NOYW1lcyB8IEludEFycmF5TWV0cmljc05hbWVzIHwgTnVtYmVyQXJyYXlNZXRyaWNzTmFtZXM7XG5cbmV4cG9ydCB0eXBlIFZhbGlkVHlwZXMgPVxuICB7IGRhdGE6IHN0cmluZ1tdLCBtZXRyaWM6IFN0cmluZ01ldHJpY3MgfCBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMgfSB8XG4gIHsgZGF0YTogVmVjdG9yW10sIG1ldHJpYzogVmVjdG9yTWV0cmljcyB9IHxcbiAgeyBkYXRhOiBCaXRBcnJheVtdLCBtZXRyaWM6IEJpdEFycmF5TWV0cmljcyB9IHxcbiAgeyBkYXRhOiBudW1iZXJbXSwgbWV0cmljOiBOdW1iZXJNZXRyaWNzTmFtZXMgfTtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nTWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSAnU3RyaW5nJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQml0QXJyYXlNZXRyaWMobmFtZTogS25vd25NZXRyaWNzKSB7XG4gIHJldHVybiBNZXRyaWNUb0RhdGFUeXBlW25hbWVdID09ICdCaXRBcnJheSc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlY3Rvck1ldHJpYyhuYW1lOiBLbm93bk1ldHJpY3MpIHtcbiAgcmV0dXJuIE1ldHJpY1RvRGF0YVR5cGVbbmFtZV0gPT0gJ1ZlY3Rvcic7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc01hY3JvTW9sZWN1bGVNZXRyaWMobmFtZTogS25vd25NZXRyaWNzKSB7XG4gIHJldHVybiBNZXRyaWNUb0RhdGFUeXBlW25hbWVdID09IERpc3RhbmNlTWV0cmljc1N1YmplY3RzLk1hY3JvTW9sZWN1bGUudG9TdHJpbmcoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtZXJpY01ldHJpYyhuYW1lOiBLbm93bk1ldHJpY3MpIHtcbiAgcmV0dXJuIE1ldHJpY1RvRGF0YVR5cGVbbmFtZV0gPT0gRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuTnVtYmVyLnRvU3RyaW5nKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlckFycmF5TWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSBEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5OdW1iZXJBcnJheS50b1N0cmluZygpO1xufVxuXG4vKiogTWFuaGF0dGFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHNlcXVlbmNlcyAobWF0Y2ggLSAwLCBtaXNtYXRjaCAtIDEpIG5vcm1hbGl6ZWQgZm9yIGxlbmd0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYW5oYXR0YW5EaXN0YW5jZShzMTogc3RyaW5nLCBzMjogc3RyaW5nKTogbnVtYmVyIHtcbiAgaWYgKHMxLmxlbmd0aCAhPT0gczIubGVuZ3RoKSB7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgbGV0IGRpc3Q6IG51bWJlciA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBzMS5sZW5ndGg7IGkrKylcbiAgICAgIGRpc3QgKz0gczFbaV0gPT0gczJbaV0gPyAwIDogMTtcbiAgICByZXR1cm4gZGlzdCAvIHMxLmxlbmd0aDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2F0ZWdvcmljYWxEaXN0YW5jZShzMTogc3RyaW5nLCBzMjogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIHMxID09PSBzMiA/IDAgOiAxO1xufVxuXG4vKiogVW5pZmllZCBjbGFzcyBpbXBsZW1lbnRpbmcgZGlmZmVyZW50IHN0cmluZyBtZWFzdXJlcy4gKi9cbmV4cG9ydCBjbGFzcyBNZWFzdXJlIHtcbiAgcHJvdGVjdGVkIG1ldGhvZDogS25vd25NZXRyaWNzO1xuICBwcm90ZWN0ZWQgZGF0YVR5cGU6IEF2YWlsYWJsZURhdGFUeXBlcztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBNZWFzdXJlIHdpdGggLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kIE1ldGhvZCB0byBjYWxjdWxhdGUgZGlzdGFuY2UgYmV0d2VlbiBzdHJpbmdzLlxuICAgKiBAbWVtYmVyb2YgTWVhc3VyZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1ldGhvZDogS25vd25NZXRyaWNzKSB7XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gICAgdGhpcy5kYXRhVHlwZSA9IE1ldHJpY1RvRGF0YVR5cGVbbWV0aG9kXSBhcyBBdmFpbGFibGVEYXRhVHlwZXM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBtZXRyaWMgbmVlZHMgYXJndW1lbnRzIHRvIGJlIGNhbGN1bGF0ZWQuXG4gICAqIEBwYXJhbSB7S25vd25NZXRyaWNzfSBtZXRob2QgTWV0cmljIHRvIGNoZWNrIGlmIGl0IG5lZWRzIGFyZ3VtZW50cy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWV0cmljIG5lZWRzIGFyZ3VtZW50cy5cbiAgICogQG1lbWJlcm9mIE1lYXN1cmVcbiAgICovXG4gIHB1YmxpYyBtZXRyaWNOZWVkc0FyZ3MobWV0aG9kOiBLbm93bk1ldHJpY3MpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNNYWNyb01vbGVjdWxlTWV0cmljKG1ldGhvZCkgfHwgaXNOdW1lcmljTWV0cmljKG1ldGhvZCkgfHwgaXNOdW1iZXJBcnJheU1ldHJpYyhtZXRob2QpO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIGN1c3RvbSBzdHJpbmcgZGlzdGFuY2UgZnVuY3Rpb24gc3BlY2lmaWVkLlxuICAgKiBAcGFyYW0ge29wdHN9IG9wdHMgT3B0aW9ucyBmb3IgdGhlIG1lYXN1cmUuIHVzZWQgZm9yIG1hY3JvbW9sZWN1bGUgZGlzdGFuY2VzXG4gICAqIEByZXR1cm4ge0Rpc3RhbmNlTWV0cmljfSBDYWxsYmFjayBvZiB0aGUgbWVhc3VyZSBjaG9zZW4uXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgcHVibGljIGdldE1lYXN1cmUob3B0cz86IGFueSk6IERpc3RhbmNlTWV0cmljIHtcbiAgICBjb25zdCBkaWN0OiB7IFtrZXk6IHN0cmluZ106XG4gICAgICB7W2tleTI6IHN0cmluZ106IERpc3RhbmNlTWV0cmljIHwgKChvcHRzOiBhbnkpID0+IERpc3RhbmNlTWV0cmljKX1cbiAgICB9ID0gQXZhaWxhYmxlTWV0cmljcztcbiAgICBpZiAoIWRpY3QuaGFzT3duUHJvcGVydHkodGhpcy5kYXRhVHlwZSkgfHwgIWRpY3RbdGhpcy5kYXRhVHlwZV0uaGFzT3duUHJvcGVydHkodGhpcy5tZXRob2QpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIG1lYXN1cmUgJHt0aGlzLm1ldGhvZH0gZm9yIGRhdGEgdHlwZSAke3RoaXMuZGF0YVR5cGV9YCk7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljTmVlZHNBcmdzKHRoaXMubWV0aG9kKSA/XG4gICAgICAoZGljdFt0aGlzLmRhdGFUeXBlXVt0aGlzLm1ldGhvZF0gYXMgKChvcHRzOiBhbnkpID0+IERpc3RhbmNlTWV0cmljKSkob3B0cykgOlxuICAgICAgZGljdFt0aGlzLmRhdGFUeXBlXVt0aGlzLm1ldGhvZF0gYXMgRGlzdGFuY2VNZXRyaWM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBjdXN0b20gc3RyaW5nIGRpc3RhbmNlIGJ5IHRoZSBnaXZlbiBkYXRhIHR5cGUuXG4gICAqIEBwYXJhbSB7QXZhaWxhYmxlRGF0YVR5cGVzfSBkYXRhVHlwZSBNZXRyaWMncyBkYXRhIHR5cGVcbiAgICogQHJldHVybiB7c3RyaW5nW119IE1ldHJpYyBuYW1lcyB3aGljaCBleHBlY3RzIHRoZSBnaXZlbiBkYXRhIHR5cGVcbiAgICogQG1lbWJlcm9mIE1lYXN1cmVyXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdldE1ldHJpY0J5RGF0YVR5cGUoZGF0YVR5cGU6IEF2YWlsYWJsZURhdGFUeXBlcyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoQXZhaWxhYmxlTWV0cmljc1tkYXRhVHlwZV0pO1xuICB9XG5cbiAgLyoqIFJldHVybnMgbWV0cmljIG5hbWVzIGF2YWlsYWJsZS5cbiAgICogQG1lbWJlcm9mIE1lYXN1cmVyXG4gICAqL1xuICBzdGF0aWMgZ2V0IGF2YWlsYWJsZU1lYXN1cmVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoQXZhaWxhYmxlTWV0cmljcyk7XG4gIH1cbn1cbiJdfQ==","import { Vector } from './type-declarations';\nimport { randomFloat, randomInt } from './random';\n/**\n * Asserts a condition by throwing an Error.\n *\n * @export\n * @param {boolean} [condition=false] Condition to assert.\n * @param {string} [message='Assertion error.'] Message to output.\n * @throws {Error}\n */\nexport function assert(condition = false, message = 'Assertion error.') {\n if (!condition)\n throw new Error(message);\n}\n/**\n * Creates new two-dimensional array and fills it with the value given.\n *\n * @param {number} dimension1 The first dimension of the coordinates (number of rows).\n * @param {number} dimension2 The second dimension of the coordinates (number of columns).\n * @param {number} [fill=0] A value to fill the coordinates with.\n * @return {Coordinates} A two-dimensional filled with the value given.\n * @todo Might be slow since used Array.map. Probably needs performance revision.\n */\nexport function initCoordinates(dimension1, dimension2, fill = 0) {\n return new Array(dimension1).fill(fill).map(() => (new Vector(dimension2).fill(fill)));\n}\n/**\n * Transpose matrix.\n *\n * @export\n * @param {Matrix} matrix The matrix to be transposed.\n * @return {Matrix} Transposed matrix.\n * @todo Might be slow since used Array.map. Probably needs performance revision.\n */\nexport function transposeMatrix(matrix) {\n return new Array(matrix[0].length).fill(0)\n .map((_, i) => (new Vector(matrix.length).fill(0).map((_, j) => (matrix[j][i]))));\n}\n/**\n * Adds two vectors with the second one to be multiplied by the given ratio.\n *\n * @export\n * @param {Vector} p The first vector to add.\n * @param {Vector} q The second vector to add.\n * @param {number} [multiplier=1] A multiplier to be used before the second vector is added.\n * @return {Vector} New vector contained the result of operation p+multiplier*q.\n */\nexport function vectorAdd(p, q, multiplier = 1) {\n const nItems = p.length;\n assert(nItems == q.length, 'Vector lengths do not match.');\n const total = new Vector(nItems);\n for (let i = 0; i < p.length; ++i)\n total[i] = p[i] + multiplier * q[i];\n return total;\n}\n/**\n * Sums the vector's items.\n *\n * @param {Vector} v The vector to be summed.\n * @return {number} The vector's items sum.\n */\nfunction itemsSum(v) {\n let total = 0;\n for (let i = 0; i < v.length; ++i)\n total += v[i];\n return total;\n}\n/**\n * Suqares the vector's items.\n *\n * @param {Vector} v The vector to square.\n * @return {Vector} A new vector containing the original's items squared.\n */\nfunction vectorSquare(v) {\n const nItems = v.length;\n const total = new Vector(nItems);\n for (let i = 0; i < v.length; ++i)\n total[i] = v[i] * v[i];\n return total;\n}\nexport function vectorLength(v) {\n let sqrSum = 0;\n for (let i = 0; i < v.length; i++)\n sqrSum += v[i] * v[i];\n return Math.sqrt(sqrSum);\n}\nexport function vectorDotProduct(v1, v2) {\n if (v1.length != v2.length)\n throw new Error('The dimensionality of the vectors must match');\n let prod = 0;\n for (let i = 0; i < v1.length; i++)\n prod += v1[i] * v2[i];\n return prod;\n}\n/**\n * Creates a matrix filled with random floating point values.\n *\n * @export\n * @param {number} dimension1 The first dimension of the matrix.\n * @param {number} dimension2 The second dimension of the matrix.\n * @param {number} [scale=1.] Max value given by random generator.\n * @return {Matrix} A new matrix filled with random floating point values.\n */\nexport function fillRandomMatrix(dimension1, dimension2, scale = 1.) {\n const matrix = initCoordinates(dimension1, dimension2);\n for (let i = 0; i < dimension1; ++i) {\n for (let j = 0; j < dimension2; ++j)\n matrix[i][j] = randomFloat(scale);\n }\n return matrix;\n}\n/**\n * Calculates Euclidean distance between two vectors.\n *\n * @export\n * @param {Vector} p The first vector.\n * @param {Vector} q The second vector.\n * @return {number} Euclidean distance between the given vectors.\n */\nexport function calculateEuclideanDistance(p, q) {\n let result = 0;\n const len = p.length;\n if (len !== q.length)\n throw new Error('The dimensionality of the vectors must match');\n for (let i = 0; i < len; ++i)\n result += Math.pow((p[i] - q[i]), 2);\n return Math.sqrt(result);\n}\n/**\n * Creates a distance matrix using a custom distance function.\n *\n * @export\n * @param {Vectors} data Input vectors to calculate distances.\n * @param {DistanceMetric} distance Custom distance function.\n * @return {Matrix} Calculated custom distance matrix.\n */\nexport function calcDistanceMatrix(data, distance) {\n const nItems = data.length;\n const matrix = initCoordinates(nItems, nItems, 0);\n for (let i = 0; i < nItems; ++i) {\n for (let j = i + 1; j < nItems; ++j) {\n const d = (data[i] == null) || (data[j] == null) ? 0 : distance(data[i], data[j]);\n matrix[i][j] = matrix[j][i] = d;\n }\n }\n return matrix;\n}\n/**\n * Creates a distance matrix using a custom distance function.\n *\n * @export\n * @param {Vectors} data Input vectors to calculate distances.\n * @param {DistanceMetric} distance Custom distance function.\n * @return {Matrix} Calculated custom distance matrix.\n */\nexport function calcNormalizedDistanceMatrix(data, distance) {\n const nItems = data.length;\n const matrix = initCoordinates(nItems, nItems, 0);\n let max = Number.MIN_VALUE;\n let min = Number.MAX_VALUE;\n for (let i = 0; i < nItems; ++i) {\n for (let j = i; j < nItems; ++j) {\n const d = (data[i] == null) || (data[j] == null || i === j) ? 0 : distance(data[i], data[j]);\n matrix[i][j] = matrix[j][i] = d;\n if (d > max)\n max = d;\n if (d < min)\n min = d;\n }\n }\n for (let i = 0; i < nItems; ++i) {\n for (let j = i + 1; j < nItems; ++j)\n matrix[i][j] = matrix[j][i] = (matrix[i][j] - min) / (max - min);\n }\n return matrix;\n}\n/** Generates array from a range [begin; end] or [begin; end) if endExclusive. **/\nexport function genRange(begin, end, endExclusive = false) {\n const nItems = end - begin + (endExclusive ? 0 : 1);\n const series = new Int32Array(nItems);\n for (let i = 0; i < nItems; ++i)\n series[i] = begin + i;\n return series;\n}\n/**\n * Returns order of values as if they are sorted.\n *\n * @export\n * @param {any[]} values Input array.\n * @param {boolean} [reverse=false] Whether to return reversed order.\n * @return {number[]} The order computed.\n */\nexport function argSort(values, reverse = false) {\n const sortfn = reverse ? (a, b) => (b[0] - a[0]) : (a, b) => (a[0] - b[0]);\n const decor = (v, i) => [v, i]; // set index to value\n const undecor = (a) => a[1]; // leave only index\n const _argsort = (arr) => arr.map(decor).sort(sortfn).map(undecor);\n return _argsort(values);\n}\n/**\n * Returns the indexes of the most diverse objects according to the dist function\n * @param {number} length total number of objects\n * @param {number} n number of diverse elements to find\n * @param {(i1: number, i2: number) => number} dist a function which calculates distance between\n * two objects using their indexes\n * @returns {number[]} The indexes of the most diverse objects\n */\nexport function getDiverseSubset(length, n, dist) {\n function maxBy(values, orderBy) {\n let maxValue = null;\n let maxOrderBy = null;\n for (const element of values) {\n const elementOrderBy = orderBy(element);\n if (maxOrderBy == null || elementOrderBy > maxOrderBy) {\n maxValue = element;\n maxOrderBy = elementOrderBy;\n }\n }\n return maxValue;\n }\n const subset = [randomInt(length - 1)];\n const complement = new Set();\n for (let i = 0; i < length; ++i) {\n if (!subset.includes(i))\n complement.add(i);\n }\n while (subset.length < n) {\n const idx = maxBy(complement.values(), (i) => Math.min.apply(Math, subset.map(function (val, index) {\n return dist(i, val);\n })));\n if (idx) {\n subset.push(idx);\n complement.delete(idx);\n }\n }\n return subset;\n}\n/**\n * Returns normalized vector.\n *\n * @export\n * @param {Vector} data numerical array\n */\nexport function normalize(data) {\n const len = data.length;\n let sum = 0;\n let sumOfSquares = 0;\n for (let i = 0; i < len; ++i) {\n sum += data[i];\n sumOfSquares += Math.pow(data[i], 2);\n }\n const mean = sum / len;\n const stdDevInverse = 1.0 / Math.sqrt(sumOfSquares / len - Math.pow(mean, 2));\n for (let i = 0; i < len; ++i)\n data[i] = (data[i] - mean) * stdDevInverse;\n return data;\n}\n/**\n * Finds set difference between two lists.\n * @param {any[]} a The first list.\n * @param {any[]} b The second list.\n * @return {any[]}\n */\nexport function setDifference(a, b) {\n const bSet = new Set(b);\n return Array.from(new Set(a.filter((x) => !bSet.has(x))).values());\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yLW9wZXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ2ZWN0b3Itb3BlcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVMsTUFBTSxFQUF1QyxNQUFNLHFCQUFxQixDQUFDO0FBQ3pGLE9BQU8sRUFBQyxXQUFXLEVBQUUsU0FBUyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBRWhEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLFlBQXFCLEtBQUssRUFBRSxVQUFrQixrQkFBa0I7SUFDckYsSUFBSSxDQUFDLFNBQVM7UUFDWixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsVUFBa0IsRUFBRSxVQUFrQixFQUFFLE9BQWUsQ0FBQztJQUN0RixPQUFPLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxNQUFjO0lBQzVDLE9BQU8sSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDdkMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENB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QUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztBQUNyRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtNYXRyaXgsIFZlY3RvciwgQ29vcmRpbmF0ZXMsIFZlY3RvcnMsIERpc3RhbmNlTWV0cmljfSBmcm9tICcuL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7cmFuZG9tRmxvYXQsIHJhbmRvbUludH0gZnJvbSAnLi9yYW5kb20nO1xuXG4vKipcbiAqIEFzc2VydHMgYSBjb25kaXRpb24gYnkgdGhyb3dpbmcgYW4gRXJyb3IuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtib29sZWFufSBbY29uZGl0aW9uPWZhbHNlXSBDb25kaXRpb24gdG8gYXNzZXJ0LlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlPSdBc3NlcnRpb24gZXJyb3IuJ10gTWVzc2FnZSB0byBvdXRwdXQuXG4gKiBAdGhyb3dzIHtFcnJvcn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChjb25kaXRpb246IGJvb2xlYW4gPSBmYWxzZSwgbWVzc2FnZTogc3RyaW5nID0gJ0Fzc2VydGlvbiBlcnJvci4nKSB7XG4gIGlmICghY29uZGl0aW9uKVxuICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIG5ldyB0d28tZGltZW5zaW9uYWwgYXJyYXkgYW5kIGZpbGxzIGl0IHdpdGggdGhlIHZhbHVlIGdpdmVuLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBkaW1lbnNpb24xIFRoZSBmaXJzdCBkaW1lbnNpb24gb2YgdGhlIGNvb3JkaW5hdGVzIChudW1iZXIgb2Ygcm93cykuXG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMiBUaGUgc2Vjb25kIGRpbWVuc2lvbiBvZiB0aGUgY29vcmRpbmF0ZXMgKG51bWJlciBvZiBjb2x1bW5zKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZmlsbD0wXSBBIHZhbHVlIHRvIGZpbGwgdGhlIGNvb3JkaW5hdGVzIHdpdGguXG4gKiBAcmV0dXJuIHtDb29yZGluYXRlc30gQSB0d28tZGltZW5zaW9uYWwgZmlsbGVkIHdpdGggdGhlIHZhbHVlIGdpdmVuLlxuICogQHRvZG8gTWlnaHQgYmUgc2xvdyBzaW5jZSB1c2VkIEFycmF5Lm1hcC4gUHJvYmFibHkgbmVlZHMgcGVyZm9ybWFuY2UgcmV2aXNpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0Q29vcmRpbmF0ZXMoZGltZW5zaW9uMTogbnVtYmVyLCBkaW1lbnNpb24yOiBudW1iZXIsIGZpbGw6IG51bWJlciA9IDApOiBDb29yZGluYXRlcyB7XG4gIHJldHVybiBuZXcgQXJyYXkoZGltZW5zaW9uMSkuZmlsbChmaWxsKS5tYXAoKCkgPT4gKG5ldyBWZWN0b3IoZGltZW5zaW9uMikuZmlsbChmaWxsKSkpO1xufVxuXG4vKipcbiAqIFRyYW5zcG9zZSBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtNYXRyaXh9IG1hdHJpeCBUaGUgbWF0cml4IHRvIGJlIHRyYW5zcG9zZWQuXG4gKiBAcmV0dXJuIHtNYXRyaXh9IFRyYW5zcG9zZWQgbWF0cml4LlxuICogQHRvZG8gTWlnaHQgYmUgc2xvdyBzaW5jZSB1c2VkIEFycmF5Lm1hcC4gUHJvYmFibHkgbmVlZHMgcGVyZm9ybWFuY2UgcmV2aXNpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2VNYXRyaXgobWF0cml4OiBNYXRyaXgpOiBNYXRyaXgge1xuICByZXR1cm4gbmV3IEFycmF5KG1hdHJpeFswXS5sZW5ndGgpLmZpbGwoMClcbiAgICAubWFwKChfLCBpKSA9PiAobmV3IFZlY3RvcihtYXRyaXgubGVuZ3RoKS5maWxsKDApLm1hcCgoXywgaikgPT4gKG1hdHJpeFtqXVtpXSkpKSk7XG59XG5cbi8qKlxuICogQWRkcyB0d28gdmVjdG9ycyB3aXRoIHRoZSBzZWNvbmQgb25lIHRvIGJlIG11bHRpcGxpZWQgYnkgdGhlIGdpdmVuIHJhdGlvLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7VmVjdG9yfSBwIFRoZSBmaXJzdCB2ZWN0b3IgdG8gYWRkLlxuICogQHBhcmFtIHtWZWN0b3J9IHEgVGhlIHNlY29uZCB2ZWN0b3IgdG8gYWRkLlxuICogQHBhcmFtIHtudW1iZXJ9IFttdWx0aXBsaWVyPTFdIEEgbXVsdGlwbGllciB0byBiZSB1c2VkIGJlZm9yZSB0aGUgc2Vjb25kIHZlY3RvciBpcyBhZGRlZC5cbiAqIEByZXR1cm4ge1ZlY3Rvcn0gTmV3IHZlY3RvciBjb250YWluZWQgdGhlIHJlc3VsdCBvZiBvcGVyYXRpb24gcCttdWx0aXBsaWVyKnEuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZWN0b3JBZGQocDogVmVjdG9yLCBxOiBWZWN0b3IsIG11bHRpcGxpZXI6IG51bWJlciA9IDEpOiBWZWN0b3Ige1xuICBjb25zdCBuSXRlbXMgPSBwLmxlbmd0aDtcblxuICBhc3NlcnQobkl0ZW1zID09IHEubGVuZ3RoLCAnVmVjdG9yIGxlbmd0aHMgZG8gbm90IG1hdGNoLicpO1xuXG4gIGNvbnN0IHRvdGFsID0gbmV3IFZlY3RvcihuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcC5sZW5ndGg7ICsraSlcbiAgICB0b3RhbFtpXSA9IHBbaV0gKyBtdWx0aXBsaWVyICogcVtpXTtcblxuICByZXR1cm4gdG90YWw7XG59XG5cbi8qKlxuICogU3VtcyB0aGUgdmVjdG9yJ3MgaXRlbXMuXG4gKlxuICogQHBhcmFtIHtWZWN0b3J9IHYgVGhlIHZlY3RvciB0byBiZSBzdW1tZWQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSB2ZWN0b3IncyBpdGVtcyBzdW0uXG4gKi9cbmZ1bmN0aW9uIGl0ZW1zU3VtKHY6IFZlY3Rvcik6IG51bWJlciB7XG4gIGxldCB0b3RhbCA9IDA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2Lmxlbmd0aDsgKytpKVxuICAgIHRvdGFsICs9IHZbaV07XG5cbiAgcmV0dXJuIHRvdGFsO1xufVxuXG4vKipcbiAqIFN1cWFyZXMgdGhlIHZlY3RvcidzIGl0ZW1zLlxuICpcbiAqIEBwYXJhbSB7VmVjdG9yfSB2IFRoZSB2ZWN0b3IgdG8gc3F1YXJlLlxuICogQHJldHVybiB7VmVjdG9yfSBBIG5ldyB2ZWN0b3IgY29udGFpbmluZyB0aGUgb3JpZ2luYWwncyBpdGVtcyBzcXVhcmVkLlxuICovXG5mdW5jdGlvbiB2ZWN0b3JTcXVhcmUodjogVmVjdG9yKTogVmVjdG9yIHtcbiAgY29uc3Qgbkl0ZW1zID0gdi5sZW5ndGg7XG4gIGNvbnN0IHRvdGFsID0gbmV3IFZlY3RvcihuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdi5sZW5ndGg7ICsraSlcbiAgICB0b3RhbFtpXSA9IHZbaV0gKiB2W2ldO1xuXG4gIHJldHVybiB0b3RhbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZlY3Rvckxlbmd0aCh2OiBWZWN0b3IpOiBudW1iZXIge1xuICBsZXQgc3FyU3VtOiBudW1iZXIgPSAwO1xuICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgdi5sZW5ndGg7IGkrKylcbiAgICBzcXJTdW0gKz0gdltpXSAqIHZbaV07XG4gIHJldHVybiBNYXRoLnNxcnQoc3FyU3VtKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZlY3RvckRvdFByb2R1Y3QodjE6IFZlY3RvciwgdjI6IFZlY3Rvcik6IG51bWJlciB7XG4gIGlmICh2MS5sZW5ndGggIT0gdjIubGVuZ3RoKVxuICAgIHRocm93IG5ldyBFcnJvcignVGhlIGRpbWVuc2lvbmFsaXR5IG9mIHRoZSB2ZWN0b3JzIG11c3QgbWF0Y2gnKTtcbiAgbGV0IHByb2Q6IG51bWJlciA9IDA7XG4gIGZvciAobGV0IGk6IG51bWJlciA9IDA7IGkgPCB2MS5sZW5ndGg7IGkrKylcbiAgICBwcm9kICs9IHYxW2ldICogdjJbaV07XG4gIHJldHVybiBwcm9kO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZmlsbGVkIHdpdGggcmFuZG9tIGZsb2F0aW5nIHBvaW50IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMSBUaGUgZmlyc3QgZGltZW5zaW9uIG9mIHRoZSBtYXRyaXguXG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMiBUaGUgc2Vjb25kIGRpbWVuc2lvbiBvZiB0aGUgbWF0cml4LlxuICogQHBhcmFtIHtudW1iZXJ9IFtzY2FsZT0xLl0gTWF4IHZhbHVlIGdpdmVuIGJ5IHJhbmRvbSBnZW5lcmF0b3IuXG4gKiBAcmV0dXJuIHtNYXRyaXh9IEEgbmV3IG1hdHJpeCBmaWxsZWQgd2l0aCByYW5kb20gZmxvYXRpbmcgcG9pbnQgIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGxSYW5kb21NYXRyaXgoZGltZW5zaW9uMTogbnVtYmVyLCBkaW1lbnNpb24yOiBudW1iZXIsIHNjYWxlOiBudW1iZXIgPSAxLik6IE1hdHJpeCB7XG4gIGNvbnN0IG1hdHJpeCA9IGluaXRDb29yZGluYXRlcyhkaW1lbnNpb24xLCBkaW1lbnNpb24yKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbWVuc2lvbjE7ICsraSkge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgZGltZW5zaW9uMjsgKytqKVxuICAgICAgbWF0cml4W2ldW2pdID0gcmFuZG9tRmxvYXQoc2NhbGUpO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyBFdWNsaWRlYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjdG9ycy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3Rvcn0gcCBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHtWZWN0b3J9IHEgVGhlIHNlY29uZCB2ZWN0b3IuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEV1Y2xpZGVhbiBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBnaXZlbiB2ZWN0b3JzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2UocDogVmVjdG9yLCBxOiBWZWN0b3IpOiBudW1iZXIge1xuICBsZXQgcmVzdWx0ID0gMDtcbiAgY29uc3QgbGVuID0gcC5sZW5ndGg7XG5cbiAgaWYgKGxlbiAhPT0gcS5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGltZW5zaW9uYWxpdHkgb2YgdGhlIHZlY3RvcnMgbXVzdCBtYXRjaCcpO1xuICBcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICByZXN1bHQgKz0gKHBbaV0gLSBxW2ldKSAqKiAyO1xuICBcbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkaXN0YW5jZSBtYXRyaXggdXNpbmcgYSBjdXN0b20gZGlzdGFuY2UgZnVuY3Rpb24uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3JzfSBkYXRhIElucHV0IHZlY3RvcnMgdG8gY2FsY3VsYXRlIGRpc3RhbmNlcy5cbiAqIEBwYXJhbSB7RGlzdGFuY2VNZXRyaWN9IGRpc3RhbmNlIEN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge01hdHJpeH0gQ2FsY3VsYXRlZCBjdXN0b20gZGlzdGFuY2UgbWF0cml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY0Rpc3RhbmNlTWF0cml4KGRhdGE6IFZlY3RvcnMsIGRpc3RhbmNlOiBEaXN0YW5jZU1ldHJpYyk6IE1hdHJpeCB7XG4gIGNvbnN0IG5JdGVtcyA9IGRhdGEubGVuZ3RoO1xuICBjb25zdCBtYXRyaXggPSBpbml0Q29vcmRpbmF0ZXMobkl0ZW1zLCBuSXRlbXMsIDApO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBuSXRlbXM7ICsraikge1xuICAgICAgY29uc3QgZDogbnVtYmVyID0gKGRhdGFbaV0gPT0gbnVsbCkgfHwgKGRhdGFbal0gPT0gbnVsbCkgPyAwIDogZGlzdGFuY2UoZGF0YVtpXSwgZGF0YVtqXSk7XG4gICAgICBtYXRyaXhbaV1bal0gPSBtYXRyaXhbal1baV0gPSBkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWF0cml4O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkaXN0YW5jZSBtYXRyaXggdXNpbmcgYSBjdXN0b20gZGlzdGFuY2UgZnVuY3Rpb24uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3JzfSBkYXRhIElucHV0IHZlY3RvcnMgdG8gY2FsY3VsYXRlIGRpc3RhbmNlcy5cbiAqIEBwYXJhbSB7RGlzdGFuY2VNZXRyaWN9IGRpc3RhbmNlIEN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge01hdHJpeH0gQ2FsY3VsYXRlZCBjdXN0b20gZGlzdGFuY2UgbWF0cml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY05vcm1hbGl6ZWREaXN0YW5jZU1hdHJpeChkYXRhOiBWZWN0b3JzLCBkaXN0YW5jZTogRGlzdGFuY2VNZXRyaWMpOiBNYXRyaXgge1xuICBjb25zdCBuSXRlbXMgPSBkYXRhLmxlbmd0aDtcbiAgY29uc3QgbWF0cml4ID0gaW5pdENvb3JkaW5hdGVzKG5JdGVtcywgbkl0ZW1zLCAwKTtcbiAgbGV0IG1heCA9IE51bWJlci5NSU5fVkFMVUU7XG4gIGxldCBtaW4gPSBOdW1iZXIuTUFYX1ZBTFVFO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5JdGVtczsgKytpKSB7XG4gICAgZm9yIChsZXQgaiA9IGk7IGogPCBuSXRlbXM7ICsraikge1xuICAgICAgY29uc3QgZDogbnVtYmVyID0gKGRhdGFbaV0gPT0gbnVsbCkgfHwgKGRhdGFbal0gPT0gbnVsbCB8fCBpID09PSBqKSA/IDAgOiBkaXN0YW5jZShkYXRhW2ldLCBkYXRhW2pdKTtcbiAgICAgIG1hdHJpeFtpXVtqXSA9IG1hdHJpeFtqXVtpXSA9IGQ7XG4gICAgICBpZiAoZCA+IG1heCkgbWF4ID0gZDtcbiAgICAgIGlmIChkIDwgbWluKSBtaW4gPSBkO1xuICAgIH1cbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IG5JdGVtczsgKytpKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgbkl0ZW1zOyArK2opXG4gICAgICBtYXRyaXhbaV1bal0gPSBtYXRyaXhbal1baV0gPSAobWF0cml4W2ldW2pdIC0gbWluKSAvIChtYXggLSBtaW4pO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKiBHZW5lcmF0ZXMgYXJyYXkgZnJvbSBhIHJhbmdlIFtiZWdpbjsgZW5kXSBvciBbYmVnaW47IGVuZCkgaWYgZW5kRXhjbHVzaXZlLiAqKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5SYW5nZShiZWdpbjogbnVtYmVyLCBlbmQ6IG51bWJlciwgZW5kRXhjbHVzaXZlID0gZmFsc2UpOiBJbnQzMkFycmF5IHtcbiAgY29uc3Qgbkl0ZW1zID0gZW5kIC0gYmVnaW4gKyAoZW5kRXhjbHVzaXZlID8gMCA6IDEpO1xuICBjb25zdCBzZXJpZXMgPSBuZXcgSW50MzJBcnJheShuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpXG4gICAgc2VyaWVzW2ldID0gYmVnaW4gKyBpO1xuXG4gIHJldHVybiBzZXJpZXM7XG59XG5cbi8qKlxuICogUmV0dXJucyBvcmRlciBvZiB2YWx1ZXMgYXMgaWYgdGhleSBhcmUgc29ydGVkLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7YW55W119IHZhbHVlcyBJbnB1dCBhcnJheS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldmVyc2U9ZmFsc2VdIFdoZXRoZXIgdG8gcmV0dXJuIHJldmVyc2VkIG9yZGVyLlxuICogQHJldHVybiB7bnVtYmVyW119IFRoZSBvcmRlciBjb21wdXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFyZ1NvcnQodmFsdWVzOiBhbnlbXSwgcmV2ZXJzZSA9IGZhbHNlKTogbnVtYmVyW10ge1xuICBjb25zdCBzb3J0Zm4gPSByZXZlcnNlID8gKGE6IGFueVtdLCBiOiBhbnlbXSkgPT4gKGJbMF0gLSBhWzBdKSA6IChhOiBhbnlbXSwgYjogYW55W10pID0+IChhWzBdIC0gYlswXSk7XG4gIGNvbnN0IGRlY29yID0gKHY6IGFueSwgaTogbnVtYmVyKSA9PiBbdiwgaV07IC8vIHNldCBpbmRleCB0byB2YWx1ZVxuICBjb25zdCB1bmRlY29yID0gKGE6IGFueVtdKSA9PiBhWzFdOyAvLyBsZWF2ZSBvbmx5IGluZGV4XG4gIGNvbnN0IF9hcmdzb3J0ID0gKGFycjogYW55W10pID0+IGFyci5tYXAoZGVjb3IpLnNvcnQoc29ydGZuKS5tYXAodW5kZWNvcik7XG4gIHJldHVybiBfYXJnc29ydCh2YWx1ZXMpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGluZGV4ZXMgb2YgdGhlIG1vc3QgZGl2ZXJzZSBvYmplY3RzIGFjY29yZGluZyB0byB0aGUgZGlzdCBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCB0b3RhbCBudW1iZXIgb2Ygb2JqZWN0c1xuICogQHBhcmFtIHtudW1iZXJ9IG4gbnVtYmVyIG9mIGRpdmVyc2UgZWxlbWVudHMgdG8gZmluZFxuICogQHBhcmFtIHsoaTE6IG51bWJlciwgaTI6IG51bWJlcikgPT4gbnVtYmVyfSBkaXN0IGEgZnVuY3Rpb24gd2hpY2ggY2FsY3VsYXRlcyBkaXN0YW5jZSBiZXR3ZWVuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHdvIG9iamVjdHMgdXNpbmcgdGhlaXIgaW5kZXhlc1xuICogQHJldHVybnMge251bWJlcltdfSBUaGUgaW5kZXhlcyBvZiB0aGUgbW9zdCBkaXZlcnNlIG9iamVjdHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERpdmVyc2VTdWJzZXQobGVuZ3RoOiBudW1iZXIsIG46IG51bWJlciwgZGlzdDogKGkxOiBudW1iZXIsIGkyOiBudW1iZXIpID0+IG51bWJlcik6IG51bWJlcltdIHtcbiAgZnVuY3Rpb24gbWF4QnkodmFsdWVzOiBJdGVyYWJsZUl0ZXJhdG9yPG51bWJlcj4sIG9yZGVyQnk6IChpOiBudW1iZXIpID0+IG51bWJlcikge1xuICAgIGxldCBtYXhWYWx1ZSA9IG51bGw7XG4gICAgbGV0IG1heE9yZGVyQnkgPSBudWxsO1xuXG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHZhbHVlcykge1xuICAgICAgY29uc3QgZWxlbWVudE9yZGVyQnkgPSBvcmRlckJ5KGVsZW1lbnQpO1xuICAgICAgaWYgKG1heE9yZGVyQnkgPT0gbnVsbCB8fCBlbGVtZW50T3JkZXJCeSA+IG1heE9yZGVyQnkpIHtcbiAgICAgICAgbWF4VmFsdWUgPSBlbGVtZW50O1xuICAgICAgICBtYXhPcmRlckJ5ID0gZWxlbWVudE9yZGVyQnk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXhWYWx1ZTtcbiAgfVxuXG4gIGNvbnN0IHN1YnNldCA9IFtyYW5kb21JbnQobGVuZ3RoIC0gMSldO1xuICBjb25zdCBjb21wbGVtZW50ID0gbmV3IFNldCgpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoIXN1YnNldC5pbmNsdWRlcyhpKSlcbiAgICAgIGNvbXBsZW1lbnQuYWRkKGkpO1xuICB9XG5cbiAgd2hpbGUgKHN1YnNldC5sZW5ndGggPCBuKSB7XG4gICAgY29uc3QgaWR4ID0gbWF4QnkoXG4gICAgICBjb21wbGVtZW50LnZhbHVlcygpIGFzIEl0ZXJhYmxlSXRlcmF0b3I8bnVtYmVyPixcbiAgICAgIChpKSA9PiBNYXRoLm1pbi5hcHBseShNYXRoLCBzdWJzZXQubWFwKGZ1bmN0aW9uKHZhbCwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGRpc3QoaSwgdmFsKTtcbiAgICAgIH0pKSk7XG4gICAgaWYgKGlkeCkge1xuICAgICAgc3Vic2V0LnB1c2goaWR4KTtcbiAgICAgIGNvbXBsZW1lbnQuZGVsZXRlKGlkeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdWJzZXQ7XG59XG5cbi8qKlxuICogUmV0dXJucyBub3JtYWxpemVkIHZlY3Rvci5cbiAqIFxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3J9IGRhdGEgbnVtZXJpY2FsIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUoZGF0YTogVmVjdG9yKTogVmVjdG9yIHtcbiAgY29uc3QgbGVuID0gZGF0YS5sZW5ndGg7XG4gIGxldCBzdW0gPSAwO1xuICBsZXQgc3VtT2ZTcXVhcmVzID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgc3VtICs9IGRhdGFbaV07XG4gICAgc3VtT2ZTcXVhcmVzICs9IGRhdGFbaV0gKiogMjtcbiAgfVxuXG4gIGNvbnN0IG1lYW4gPSBzdW0gLyBsZW47XG4gIGNvbnN0IHN0ZERldkludmVyc2UgPSAxLjAgLyBNYXRoLnNxcnQoc3VtT2ZTcXVhcmVzIC8gbGVuIC0gbWVhbiAqKiAyKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgIGRhdGFbaV0gPSAoZGF0YVtpXSAtIG1lYW4pICogc3RkRGV2SW52ZXJzZTtcblxuICByZXR1cm4gZGF0YTtcbn1cblxuLyoqXG4gKiBGaW5kcyBzZXQgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBsaXN0cy5cbiAqIEBwYXJhbSB7YW55W119IGEgVGhlIGZpcnN0IGxpc3QuXG4gKiBAcGFyYW0ge2FueVtdfSBiIFRoZSBzZWNvbmQgbGlzdC5cbiAqIEByZXR1cm4ge2FueVtdfVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0RGlmZmVyZW5jZShhOiBhbnlbXSwgYjogYW55W10pOiBhbnlbXSB7XG4gIGNvbnN0IGJTZXQgPSBuZXcgU2V0KGIpO1xuICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KGEuZmlsdGVyKCh4KSA9PiAhYlNldC5oYXMoeCkpKS52YWx1ZXMoKSk7XG59XG4iXX0=","const __WEBPACK_NAMESPACE_OBJECT__ = ui;","export const DIM_RED_PREPROCESSING_FUNCTION_TAG = 'dim-red-preprocessing-function';\nexport const DIM_RED_POSTPROCESSING_FUNCTION_TAG = 'dim-red-postprocessing-function';\nexport const DIM_RED_DEFAULT_POSTPROCESSING_FUNCTION_META = 'defaultPostProcessingFunction';\nexport const SUPPORTED_SEMTYPES_TAG = 'supportedSemTypes';\nexport const SUPPORTED_TYPES_TAG = 'supportedTypes';\nexport const SUPPORTED_UNITS_TAG = 'supportedUnits';\nexport const SUPPORTED_DISTANCE_FUNCTIONS_TAG = 'supportedDistanceFunctions';\nexport const BYPASS_LARGE_DATA_WARNING = 'bypassLargeDataWarning';\nexport const SHOW_SCATTERPLOT_PROGRESS = 'show-scatterplot-progress';\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLGdDQUFnQyxDQUFDO0FBQ25GLE1BQU0sQ0FBQyxNQUFNLG1DQUFtQyxHQUFHLGlDQUFpQyxDQUFDO0FBQ3JGLE1BQU0sQ0FBQyxNQUFNLDRDQUE0QyxHQUFHLCtCQUErQixDQUFDO0FBQzVGLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLG1CQUFtQixDQUFDO0FBQzFELE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDO0FBQ3BELE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDO0FBQ3BELE1BQU0sQ0FBQyxNQUFNLGdDQUFnQyxHQUFHLDRCQUE0QixDQUFDO0FBQzdFLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLHdCQUF3QixDQUFDO0FBQ2xFLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLDJCQUEyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IERJTV9SRURfUFJFUFJPQ0VTU0lOR19GVU5DVElPTl9UQUcgPSAnZGltLXJlZC1wcmVwcm9jZXNzaW5nLWZ1bmN0aW9uJztcbmV4cG9ydCBjb25zdCBESU1fUkVEX1BPU1RQUk9DRVNTSU5HX0ZVTkNUSU9OX1RBRyA9ICdkaW0tcmVkLXBvc3Rwcm9jZXNzaW5nLWZ1bmN0aW9uJztcbmV4cG9ydCBjb25zdCBESU1fUkVEX0RFRkFVTFRfUE9TVFBST0NFU1NJTkdfRlVOQ1RJT05fTUVUQSA9ICdkZWZhdWx0UG9zdFByb2Nlc3NpbmdGdW5jdGlvbic7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX1NFTVRZUEVTX1RBRyA9ICdzdXBwb3J0ZWRTZW1UeXBlcyc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX1RZUEVTX1RBRyA9ICdzdXBwb3J0ZWRUeXBlcyc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX1VOSVRTX1RBRyA9ICdzdXBwb3J0ZWRVbml0cyc7XG5leHBvcnQgY29uc3QgU1VQUE9SVEVEX0RJU1RBTkNFX0ZVTkNUSU9OU19UQUcgPSAnc3VwcG9ydGVkRGlzdGFuY2VGdW5jdGlvbnMnO1xuZXhwb3J0IGNvbnN0IEJZUEFTU19MQVJHRV9EQVRBX1dBUk5JTkcgPSAnYnlwYXNzTGFyZ2VEYXRhV2FybmluZyc7XG5leHBvcnQgY29uc3QgU0hPV19TQ0FUVEVSUExPVF9QUk9HUkVTUyA9ICdzaG93LXNjYXR0ZXJwbG90LXByb2dyZXNzJztcbiJdfQ==","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n/** Calculates Clusters based on dbscan algorithm in wasm.\n * @param embedX - embeddings x location.\n * @param embedY - embeddings y location.\n * @param minPts - minimum number of points in a cluster.\n * @param epsilon - epsilon.\n * @returns array with cluster indexes.\n */\nexport function getDbscanWorker(embedX, embedY, epsilon, minPts) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise(function (resolve, reject) {\n const worker = new Worker(new URL('./clustering-worker', import.meta.url));\n worker.postMessage({ embedX, embedY, minPts, epsilon });\n worker.onmessage = ({ data: { error, clusters } }) => {\n worker.terminate();\n error ? reject(error) : resolve(clusters);\n };\n });\n });\n}\n//# sourceMappingURL=dbscan-worker-creator.js.map","function euclideanAggregationWgsl(arraySize) {\n return `\n var sum = 0.0;\n for (var i = 0u; i < ${arraySize}; i = i + 1u) {\n sum = sum + distances[i] * distances[i] * computeInfo.weights[i] * computeInfo.weights[i];\n }\n return sqrt(sum);\n `;\n}\n;\nfunction manhattanAggregationWgsl(arraySize) {\n return `\n var sum = 0.0;\n for (var i = 0u; i < ${arraySize}; i = i + 1u) {\n sum = sum + abs(distances[i]) * computeInfo.weights[i];\n }\n return sum;\n `;\n}\nexport var WEBGSLAGGREGATION;\n(function (WEBGSLAGGREGATION) {\n WEBGSLAGGREGATION[\"EUCLIDEAN\"] = \"EUCLIDEAN\";\n WEBGSLAGGREGATION[\"MANHATTAN\"] = \"MANHATTAN\";\n})(WEBGSLAGGREGATION || (WEBGSLAGGREGATION = {}));\nexport const WEBGSLAGGREGATIONFUNCTIONS = {\n [WEBGSLAGGREGATION.EUCLIDEAN]: euclideanAggregationWgsl,\n [WEBGSLAGGREGATION.MANHATTAN]: manhattanAggregationWgsl\n};\n//# sourceMappingURL=webGPU-aggregation.js.map","/* eslint-disable max-len */\n// in all the functions below, the variables a and b are assumed to be arrays of uint32/f32\n//values which are infered from the code this chunk is injected into\n// also, we have access to computeInfo struct, which contains the following fields:\n// computeInfo.entrySizes: array of arrays of u32 containing the sizes of the entries\n// other fields are specific to the distance function should be injected from the main script that calls this function,\n// and should be available in the supplementaryInfo struct\n// like the similarity matrix for monomer chemical distance.\n// the getProcessInfo function should return correct buffer allocation mechanism for the supplementaryInfo,\n// for every entry list\n// the maxDistance variable is also assumed to be available in the\n// scope of the function, in case of knn it is the distance in the last postion of knn on this index,\n// in case of sparse matrix, it can be just the threshold for the distance.\n// hamming distance for sequnences of uint32 arrays of max length ${maxArraySize}\nexport function webGPUHamming(_maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n let sizeDiff: u32 = maxLength - minLength;\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength)) - f32(sizeDiff);\n\n var diff: f32 = 0.0;\n for (var i = 0u; i < ${_maxArraySize}; i = i + 1u) {\n diff = diff + f32(a[i] != b[i]);\n if (diff > maxIntDistance) {\n return 1.0;\n }\n }\n diff += f32(sizeDiff);\n return diff / ${_maxArraySize};\n `;\n}\nexport function webGPUMonomerChemicalDistance(_maxArraySize, entryIndex) {\n // it is assumet that suppInfo struct contains correct matrix called similarityMatrix${entryIndex}, (similarityMatrix0, similarityMatrix1, etc)\n // this should be guaranteed by the getProcessInfo function.\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n let sizeDiff: u32 = maxLength - minLength;\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength)) - f32(sizeDiff);\n\n let simMatrix = &(suppInfo.similarityMatrix${entryIndex}); // using pointers make things faster\n var diff: f32 = 0.0;\n for (var i = 0u; i < ${_maxArraySize}; i = i + 1u) {\n diff = diff + 1.0 - (*simMatrix)[u32(a[i])][u32(b[i])];\n if (diff > maxIntDistance) {\n return 1.0;\n }\n }\n diff += f32(sizeDiff);\n return diff / ${_maxArraySize};\n `;\n}\nexport function webGPULevenstein(maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n\n let maxIntDistance = ceil(maxDistance * f32(maxLength));\n\n // we will store two arrays as matrix and swap the working indices per pass.\n // this way we can reduce memory usage per computation to just O(aLength)\n // the grid will have aLength + 1 columns and bLength + 1 rows\n // this will be guaranteed by iteration, but the array sizes must be known at compile time, so we will use a fixed size of maxArraySize\n var dynamicPassMat: array<array<f32, ${maxArraySize + 1}u>, 2>; // initialize to 0\n \n var prevIndex: u32 = 0;\n var curIndex: u32 = 1; // we will swap these indices per pass\n\n // initialize the first row\n for (var i = 0u; i <= aLength; i = i + 1u) {\n dynamicPassMat[prevIndex][i] = f32(i);\n }\n\n // iterate over the rows\n for (var i = 1u; i <= bLength; i = i + 1u) {\n dynamicPassMat[curIndex][0] = f32(i);\n var minEntry: f32 = f32(maxLength);\n let prevRow = &dynamicPassMat[prevIndex];\n let curRow = &dynamicPassMat[curIndex];\n let bMon = u32(b[i - 1]);\n for (var j = 1u; j <= aLength; j = j + 1u) {\n var cost: f32 = f32(a[j - 1] != bMon);\n var res: f32 = min(\n min(\n (*prevRow)[j] + 1.0, // deletion\n (*curRow)[j - 1] + 1.0, // insertion\n ),\n (*prevRow)[j - 1] + cost // substitution\n );\n (*curRow)[j] = res;\n if (res < minEntry) {\n minEntry = res;\n }\n }\n // swap the indices\n let temp: u32 = prevIndex;\n prevIndex = curIndex;\n curIndex = temp;\n if (minEntry > maxIntDistance) {\n return 1.0;\n }\n }\n\n return dynamicPassMat[prevIndex][aLength] / f32(maxLength);\n `;\n}\nexport function webGPUNeedlemanWunsch(maxArraySize, entryIndex) {\n // version of the levenshtain where the cost of substitution is customizable\n // it is assumet that suppInfo struct contains correct matrix called similarityMatrix${entryIndex}, (similarityMatrix0, similarityMatrix1, etc)\n // and gapOpenPenalty, gapExtensionPenalty\n // this should be guaranteed by the getProcessInfo function.\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength));\n // we will store two arrays as matrix and swap the working indices per pass.\n // this way we can reduce memory usage per computation to just O(aLength)\n // the grid will have aLength + 1 columns and bLength + 1 rows\n // this will be guaranteed by iteration, but the array sizes must be known at compile time, so we will use a fixed size of maxArraySize\n var dynamicPassMat: array<array<f32, ${maxArraySize + 1}u>, 2>; // initialize to 0\n \n // we need to keep track of which operation led to the current cell\n // i.e. whether we came from the left, top or diagonal to assign gap open/gap extend penalty\n var verticalGaps: array<u32, ${maxArraySize + 1}u>;\n var horizontalGaps: array<u32, ${maxArraySize + 1}u>;\n\n let gapOpenPenalty: f32 = suppInfo.gapOpenPenalty${entryIndex};\n let gapExtensionPenalty: f32 = suppInfo.gapExtensionPenalty${entryIndex};\n var prevIndex: u32 = 0;\n var curIndex: u32 = 1; // we will swap these indices per pass\n // initialize the first row\n for (var i = 0u; i <= aLength; i = i + 1u) {\n dynamicPassMat[prevIndex][i] = gapExtensionPenalty + f32(i - 1) * gapExtensionPenalty; // accounting for the fact that left and right gaps are less costly\n dynamicPassMat[curIndex][i] = 0.0;\n }\n dynamicPassMat[0][0] = 0.0;\n\n let simMatrix = &suppInfo.similarityMatrix${entryIndex}; // using pointers make things faster\n // iterate over the rows\n for (var i = 1u; i <= bLength; i = i + 1u) {\n let prevRow = &dynamicPassMat[prevIndex];\n let curRow = &dynamicPassMat[curIndex];\n (*curRow)[0] = gapExtensionPenalty + f32(i - 1) * gapExtensionPenalty;\n var minEntry: f32 = f32(maxLength);\n let monB = u32(b[i - 1]);\n for (var j = 1u; j <= aLength; j = j + 1u) {\n let monA = u32(a[j - 1]);\n \n let cost: f32 = (*prevRow)[j - 1] + 1f - (*simMatrix)[monA][monB];\n var top = (*prevRow)[j]; // deletion\n if (verticalGaps[j] > 0 || i == 1 || i == bLength) {\n top = top + gapExtensionPenalty;\n } else {\n top = top + gapOpenPenalty;\n }\n var left = (*curRow)[j - 1]; // insertion\n if (horizontalGaps[j - 1] > 0 || j == 1 || j == aLength) {\n left = left + gapExtensionPenalty;\n } else {\n left = left + gapOpenPenalty;\n }\n var res: f32 = min(\n min(\n top, // deletion\n left, // insertion\n ),\n cost // substitution\n );\n (*curRow)[j] = res;\n if (res < minEntry) {\n minEntry = res;\n }\n // update the horizontal and vertical gaps\n if (res == cost) {\n verticalGaps[j] = 0;\n horizontalGaps[j] = 0;\n } else if (res == left) {\n verticalGaps[j] = 0;\n horizontalGaps[j] = 1;\n } else {\n verticalGaps[j] = 1;\n horizontalGaps[j] = 0;\n }\n }\n // swap the indices\n let temp: u32 = prevIndex;\n prevIndex = curIndex;\n curIndex = temp;\n if (minEntry > maxIntDistance) {\n return 1.0;\n }\n }\n return dynamicPassMat[prevIndex][aLength] / f32(minLength);\n\n `;\n}\nexport function webGPUEuclidean(maxArraySize, _entryIndex) {\n return `\n var dist: f32 = 0.0;\n for (var i = 0u; i < ${maxArraySize}; i = i + 1u) {\n dist = dist + f32(a[i] - b[i]) * f32(a[i] - b[i]);\n }\n return sqrt(dist);\n `;\n}\nexport function webGPUManhattan(maxArraySize, _entryIndex) {\n return `\n var dist: f32 = 0.0;\n for (var i = 0u; i < ${maxArraySize}; i = i + 1u) {\n dist = dist + abs(f32(a[i] - b[i]));\n }\n return dist;\n `;\n}\nexport function webGPUOneHotDistance(_maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n if (aLength != bLength) {\n return 1.0;\n }\n for (var i = 0u; i < aLength; i = i + 1u) {\n if(a[i] != b[i]) {\n return 1.0;\n }\n }\n return 0.0;\n `;\n}\nexport function webGPUNumericDistance(_maxArraySize, entryIndex) {\n // we assume that range${entryIndex} is available in the supplementaryInfo struct\n return `\n let range = suppInfo.range${entryIndex};\n return f32(abs(f32(a[0]) - f32(b[0])) / range);\n `;\n}\n// tanimoto distance for uint32 arrays of length ${maxArraySize}\nexport function webGPUTanimotoBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n\n if (onBitsa == 0u && onBitsb == 0u) {\n return 0.0;\n }\n\n let totalOnBits = onBitsa + onBitsb;\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n\n return 1.0 - f32(commonBits) / f32(totalOnBits - commonBits);\n `;\n}\nexport function webGPUAsymmetricBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let min = min(onBitsa, onBitsb);\n if (min == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / f32(min);\n `;\n}\nexport function webGPUCosineBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let total = onBitsa * onBitsb; // p.s. here total is taken by multiplying\n if (total == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / sqrt(f32(total));\n `;\n}\nexport function webGPUSokalBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let total = onBitsa + onBitsb;\n if (total == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / f32(total * 2 - commonBits * 3);\n `;\n}\nexport var WEBGPUDISTANCE;\n(function (WEBGPUDISTANCE) {\n WEBGPUDISTANCE[\"HAMMING\"] = \"Hamming\";\n WEBGPUDISTANCE[\"EUCLIDEAN\"] = \"Euclidean\";\n WEBGPUDISTANCE[\"MANHATTAN\"] = \"Manhattan\";\n WEBGPUDISTANCE[\"TANIMOTO\"] = \"Tanimoto\";\n WEBGPUDISTANCE[\"LEVENSTEIN\"] = \"Levenshtein\";\n WEBGPUDISTANCE[\"NEEDLEMAN_WUNSCH\"] = \"Needlemann-Wunsch\";\n WEBGPUDISTANCE[\"MONOMER_CHEMICAL_DISTANCE\"] = \"Monomer chemical distance\";\n WEBGPUDISTANCE[\"SOKAL\"] = \"Sokal\";\n WEBGPUDISTANCE[\"COSINE\"] = \"Cosine\";\n WEBGPUDISTANCE[\"ASYMMETRIC\"] = \"Asymmetric\";\n WEBGPUDISTANCE[\"Difference\"] = \"Difference\";\n WEBGPUDISTANCE[\"OneHot\"] = \"One-Hot\";\n})(WEBGPUDISTANCE || (WEBGPUDISTANCE = {}));\nexport const webGPUFunctions = {\n [WEBGPUDISTANCE.HAMMING]: webGPUHamming,\n [WEBGPUDISTANCE.EUCLIDEAN]: webGPUEuclidean,\n [WEBGPUDISTANCE.MANHATTAN]: webGPUManhattan,\n [WEBGPUDISTANCE.TANIMOTO]: webGPUTanimotoBitArray,\n [WEBGPUDISTANCE.LEVENSTEIN]: webGPULevenstein,\n [WEBGPUDISTANCE.NEEDLEMAN_WUNSCH]: webGPUNeedlemanWunsch,\n [WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE]: webGPUMonomerChemicalDistance,\n [WEBGPUDISTANCE.SOKAL]: webGPUSokalBitArray,\n [WEBGPUDISTANCE.COSINE]: webGPUCosineBitArray,\n [WEBGPUDISTANCE.ASYMMETRIC]: webGPUAsymmetricBitArray,\n [WEBGPUDISTANCE.Difference]: webGPUNumericDistance,\n [WEBGPUDISTANCE.OneHot]: webGPUOneHotDistance\n};\nexport const distanceFunctionComplexity = {\n [WEBGPUDISTANCE.HAMMING]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.EUCLIDEAN]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.MANHATTAN]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.TANIMOTO]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.SOKAL]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.COSINE]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.ASYMMETRIC]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.LEVENSTEIN]: (maxEntrySize) => Math.ceil(maxEntrySize * maxEntrySize / 60),\n [WEBGPUDISTANCE.NEEDLEMAN_WUNSCH]: (maxEntrySize) => Math.ceil(maxEntrySize * maxEntrySize / 60),\n [WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE]: (maxEntrySize) => Math.ceil(maxEntrySize / 25),\n [WEBGPUDISTANCE.Difference]: (_maxEntrySize) => 1,\n [WEBGPUDISTANCE.OneHot]: (_maxEntrySize) => Math.ceil(_maxEntrySize / 40),\n};\nexport const TypeSupportedDistances = {\n [\"STRING\" /* WGPUENTRYTYPE.STRING */]: new Set([WEBGPUDISTANCE.HAMMING, WEBGPUDISTANCE.LEVENSTEIN, WEBGPUDISTANCE.NEEDLEMAN_WUNSCH, WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE, WEBGPUDISTANCE.OneHot]),\n [\"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */]: new Set([WEBGPUDISTANCE.HAMMING, WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE, WEBGPUDISTANCE.LEVENSTEIN, WEBGPUDISTANCE.NEEDLEMAN_WUNSCH, WEBGPUDISTANCE.TANIMOTO, WEBGPUDISTANCE.COSINE, WEBGPUDISTANCE.SOKAL, WEBGPUDISTANCE.ASYMMETRIC, WEBGPUDISTANCE.OneHot, WEBGPUDISTANCE.Difference]),\n [\"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.OneHot, WEBGPUDISTANCE.Difference]),\n [\"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.Difference]),\n [\"NUMBER\" /* WGPUENTRYTYPE.NUMBER */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.Difference]),\n [\"BITARRAY\" /* WGPUENTRYTYPE.BITARRAY */]: new Set([WEBGPUDISTANCE.TANIMOTO, WEBGPUDISTANCE.COSINE, WEBGPUDISTANCE.SOKAL, WEBGPUDISTANCE.ASYMMETRIC])\n};\n//# sourceMappingURL=webGPU-multicol-distances.js.map","export var MatrixMatrixOpType;\n(function (MatrixMatrixOpType) {\n MatrixMatrixOpType[\"ADD\"] = \"ADD\";\n MatrixMatrixOpType[\"SUB\"] = \"SUB\";\n MatrixMatrixOpType[\"MULT\"] = \"MULT\";\n})(MatrixMatrixOpType || (MatrixMatrixOpType = {}));\nexport var MatrixOpType;\n(function (MatrixOpType) {\n MatrixOpType[\"SQUARE\"] = \"SQUARE\";\n MatrixOpType[\"INVERSE\"] = \"INVERSE\";\n MatrixOpType[\"TRANSPOSE\"] = \"TRANSPOSE\";\n MatrixOpType[\"NORM\"] = \"NORM\";\n MatrixOpType[\"COLUMN_NORM\"] = \"COLUMN_NORM\";\n})(MatrixOpType || (MatrixOpType = {}));\nexport var MatrixScalarOpType;\n(function (MatrixScalarOpType) {\n MatrixScalarOpType[\"SCALARMULT\"] = \"SCALARMULT\";\n MatrixScalarOpType[\"SCALARADD\"] = \"SCALARADD\";\n MatrixScalarOpType[\"SCALARPOW\"] = \"SCALARPOW\";\n})(MatrixScalarOpType || (MatrixScalarOpType = {}));\n//# sourceMappingURL=types.js.map","// eslint-disable-next-line @typescript-eslint/unbound-method\nconst toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array, except those that contain bigint values).\n *\n * @param value - Object to check.\n * @returns True if the object is an array or a typed array.\n */\nexport function isAnyArray(value) {\n const tag = toString.call(value);\n return tag.endsWith('Array]') && !tag.includes('Big');\n}\n//# sourceMappingURL=index.js.map","export const DIMENSIONALITY_REDUCER_TERMINATE_EVENT = 'dimensionality-reducer-terminate-event';\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxNQUFNLHNDQUFzQyxHQUFHLHdDQUF3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IERJTUVOU0lPTkFMSVRZX1JFRFVDRVJfVEVSTUlOQVRFX0VWRU5UID0gJ2RpbWVuc2lvbmFsaXR5LXJlZHVjZXItdGVybWluYXRlLWV2ZW50JztcbiJdfQ==","export var DistanceAggregationMethods;\n(function (DistanceAggregationMethods) {\n DistanceAggregationMethods[\"EUCLIDEAN\"] = \"EUCLIDEAN\";\n DistanceAggregationMethods[\"MANHATTAN\"] = \"MANHATTAN\";\n})(DistanceAggregationMethods || (DistanceAggregationMethods = {}));\n;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSwwQkFHVDtBQUhILFdBQVksMEJBQTBCO0lBQ2xDLHFEQUF1QixDQUFBO0lBQ3ZCLHFEQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFIUywwQkFBMEIsS0FBMUIsMEJBQTBCLFFBR25DO0FBQUEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIERpc3RhbmNlQWdncmVnYXRpb25NZXRob2RzIHtcbiAgICBFVUNMSURFQU4gPSAnRVVDTElERUFOJyxcbiAgICBNQU5IQVRUQU4gPSAnTUFOSEFUVEFOJyxcbiAgfTtcblxuZXhwb3J0IHR5cGUgRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCA9IGtleW9mIHR5cGVvZiBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kcztcbiJdfQ==","import { DistanceAggregationMethods } from './types';\nexport const isNil = (x) => x === null || x === undefined;\nexport function insertSmaller(distancesAr, indexes, num, index) {\n if (num > distancesAr[distancesAr.length - 1])\n return;\n const newPosition = distancesAr.findIndex((v) => num < v);\n distancesAr.pop();\n distancesAr.splice(newPosition, 0, num);\n indexes.pop();\n indexes.splice(newPosition, 0, index);\n}\nexport function insertLarger(distancesAr, indexes, num, index) {\n if (num < distancesAr[distancesAr.length - 1])\n return;\n const newPosition = distancesAr.findIndex((v) => num > v);\n distancesAr.pop();\n distancesAr.splice(newPosition, 0, num);\n indexes.pop();\n indexes.splice(newPosition, 0, index);\n}\nexport function getAggregationFunction(aggregationMethod, weights) {\n switch (aggregationMethod) {\n case DistanceAggregationMethods.MANHATTAN:\n return (vs) => vs.reduce((acc, val, idx) => acc + val * weights[idx], 0);\n default:\n return (vs) => {\n // euclidean\n const sum = vs.reduce((acc, val, idx) => acc + (val * weights[idx]) ** 2, 0);\n return Math.sqrt(sum);\n };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTRCLDBCQUEwQixFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRTlFLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssU0FBUyxDQUFDO0FBRS9ELE1BQU0sVUFBVSxhQUFhLENBQUMsV0FBcUIsRUFBRSxPQUFpQixFQUFFLEdBQVcsRUFBRSxLQUFhO0lBQ2hHLElBQUksR0FBRyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQztRQUN6QyxPQUFPO0lBRVQsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzFELFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNsQixXQUFXLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDeEMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ2QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFFRCxNQUFNLFVBQVUsWUFBWSxDQUFDLFdBQXFCLEVBQUUsT0FBaUIsRUFBRSxHQUFXLEVBQUUsS0FBYTtJQUMvRixJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUM7UUFDekMsT0FBTztJQUVULE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMxRCxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDbEIsV0FBVyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3hDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNkLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQsTUFBTSxVQUFVLHNCQUFzQixDQUNwQyxpQkFBNEMsRUFBRSxPQUFpQjtJQUUvRCxRQUFRLGlCQUFpQixFQUFFLENBQUM7UUFDMUIsS0FBSywwQkFBMEIsQ0FBQyxTQUFTO1lBQ3ZDLE9BQU8sQ0FBQyxFQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckY7WUFDRSxPQUFPLENBQUMsRUFBWSxFQUFFLEVBQUU7Z0JBQ3RCLFlBQVk7Z0JBQ1osTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUM3RSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEIsQ0FBQyxDQUFDO0lBQ04sQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0Rpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsIERpc3RhbmNlQWdncmVnYXRpb25NZXRob2RzfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGlzTmlsID0gKHg6IGFueSkgPT4geCA9PT0gbnVsbCB8fCB4ID09PSB1bmRlZmluZWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRTbWFsbGVyKGRpc3RhbmNlc0FyOiBudW1iZXJbXSwgaW5kZXhlczogbnVtYmVyW10sIG51bTogbnVtYmVyLCBpbmRleDogbnVtYmVyKSB7XG4gIGlmIChudW0gPiBkaXN0YW5jZXNBcltkaXN0YW5jZXNBci5sZW5ndGgtMV0pXG4gICAgcmV0dXJuO1xuXG4gIGNvbnN0IG5ld1Bvc2l0aW9uID0gZGlzdGFuY2VzQXIuZmluZEluZGV4KCh2KSA9PiBudW0gPCB2KTtcbiAgZGlzdGFuY2VzQXIucG9wKCk7XG4gIGRpc3RhbmNlc0FyLnNwbGljZShuZXdQb3NpdGlvbiwgMCwgbnVtKTtcbiAgaW5kZXhlcy5wb3AoKTtcbiAgaW5kZXhlcy5zcGxpY2UobmV3UG9zaXRpb24sIDAsIGluZGV4KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydExhcmdlcihkaXN0YW5jZXNBcjogbnVtYmVyW10sIGluZGV4ZXM6IG51bWJlcltdLCBudW06IG51bWJlciwgaW5kZXg6IG51bWJlcikge1xuICBpZiAobnVtIDwgZGlzdGFuY2VzQXJbZGlzdGFuY2VzQXIubGVuZ3RoLTFdKVxuICAgIHJldHVybjtcblxuICBjb25zdCBuZXdQb3NpdGlvbiA9IGRpc3RhbmNlc0FyLmZpbmRJbmRleCgodikgPT4gbnVtID4gdik7XG4gIGRpc3RhbmNlc0FyLnBvcCgpO1xuICBkaXN0YW5jZXNBci5zcGxpY2UobmV3UG9zaXRpb24sIDAsIG51bSk7XG4gIGluZGV4ZXMucG9wKCk7XG4gIGluZGV4ZXMuc3BsaWNlKG5ld1Bvc2l0aW9uLCAwLCBpbmRleCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBZ2dyZWdhdGlvbkZ1bmN0aW9uKFxuICBhZ2dyZWdhdGlvbk1ldGhvZDogRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCwgd2VpZ2h0czogbnVtYmVyW11cbik6ICh2YWx1ZXM6IG51bWJlcltdKSA9PiBudW1iZXIge1xuICBzd2l0Y2ggKGFnZ3JlZ2F0aW9uTWV0aG9kKSB7XG4gICAgY2FzZSBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kcy5NQU5IQVRUQU46XG4gICAgICByZXR1cm4gKHZzOiBudW1iZXJbXSkgPT4gdnMucmVkdWNlKChhY2MsIHZhbCwgaWR4KSA9PiBhY2MgKyB2YWwgKiB3ZWlnaHRzW2lkeF0sIDApO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gKHZzOiBudW1iZXJbXSkgPT4ge1xuICAgICAgICAvLyBldWNsaWRlYW5cbiAgICAgICAgY29uc3Qgc3VtID0gdnMucmVkdWNlKChhY2MsIHZhbCwgaWR4KSA9PiBhY2MgKyAodmFsICogd2VpZ2h0c1tpZHhdKSAqKiAyLCAwKTtcbiAgICAgICAgcmV0dXJuIE1hdGguc3FydChzdW0pO1xuICAgICAgfTtcbiAgfVxufVxuIl19","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport { BYPASS_LARGE_DATA_WARNING, SHOW_SCATTERPLOT_PROGRESS } from '../functionEditors/consts';\nimport { getDbscanWorker } from '@datagrok-libraries/math';\nimport { DIMENSIONALITY_REDUCER_TERMINATE_EVENT } from './consts';\nimport { getNormalizedEmbeddings } from './embeddings-space';\nexport function getEmbeddingColsNames(df) {\n const axes = ['Embed_X', 'Embed_Y'];\n const colNameInd = df.columns.names().filter((it) => it.includes(axes[0])).length + 1;\n return axes.map((it) => `${it}_${colNameInd}`);\n}\nexport function getEmbeddingViewerName(columns, method) {\n const colNames = columns.length > 4 ? `${columns.length} columns` : columns.map((it) => it.name).join(', ');\n return `${method} (${colNames})`;\n}\nexport async function multiColReduceDimensionality(table, columns, method, metrics, weights, preprocessingFunctions, aggregationMethod, plotEmbeddings = true, clusterEmbeddings = false, dimRedOptions = { preprocessingFuncArgs: [] }, uiOptions = {}, postProcessingFunc = null, postProcFuncArgs = {}) {\n const scatterPlotProps = {\n showXAxis: false,\n showYAxis: false,\n showXSelector: false,\n showYSelector: false,\n };\n if (columns.length !== metrics.length || columns.length !== preprocessingFunctions.length ||\n columns.length !== weights.length || columns.length !== dimRedOptions.preprocessingFuncArgs.length) {\n throw new Error('columns, metrics and preprocessing functions, weights and function arguments' +\n 'must have the same length');\n }\n const tv = plotEmbeddings ? (uiOptions.tableView ?? grok.shell.tableView(table.name) ?? grok.shell.addTableView(table)) : null;\n const doReduce = async () => {\n const pg = DG.TaskBarProgressIndicator.create(`Initializing ${uiOptions.scatterPlotName ?? 'dimensionality reduction'} ...`);\n let scatterPlot = undefined;\n try {\n const embedColsNames = getEmbeddingColsNames(table);\n function progressFunc(_nEpoch, epochsLength, embeddings) {\n let embedXCol = null;\n let embedYCol = null;\n if (!table.columns.names().includes(embedColsNames[0])) {\n embedXCol = table.columns.add(DG.Column.float(embedColsNames[0], table.rowCount));\n embedYCol = table.columns.add(DG.Column.float(embedColsNames[1], table.rowCount));\n if (plotEmbeddings && !scatterPlot) {\n scatterPlot = tv\n .scatterPlot({ ...scatterPlotProps, x: embedColsNames[0], y: embedColsNames[1],\n title: uiOptions.scatterPlotName ?? getEmbeddingViewerName(columns, method) });\n }\n }\n else {\n embedXCol = table.columns.byName(embedColsNames[0]);\n embedYCol = table.columns.byName(embedColsNames[1]);\n }\n if (uiOptions[SHOW_SCATTERPLOT_PROGRESS]) {\n scatterPlot?.root && ui.setUpdateIndicator(scatterPlot.root, false);\n embedXCol.init((i) => embeddings[0] ? embeddings[0][i] : undefined);\n embedYCol.init((i) => embeddings[1] ? embeddings[1][i] : undefined);\n }\n const progress = (_nEpoch / epochsLength * 100);\n pg.update(progress, `Running ${uiOptions.scatterPlotName ?? 'dimensionality reduction'}... ${progress.toFixed(0)}%`);\n }\n async function getDimRed() {\n table.columns.add(DG.Column.float(embedColsNames[0], table.rowCount));\n table.columns.add(DG.Column.float(embedColsNames[1], table.rowCount));\n let resolveF = null;\n if (plotEmbeddings) {\n scatterPlot = tv\n .scatterPlot({ ...scatterPlotProps, x: embedColsNames[0], y: embedColsNames[1],\n title: uiOptions.scatterPlotName ?? getEmbeddingViewerName(columns, method) });\n ui.setUpdateIndicator(scatterPlot.root, true);\n }\n const sub = grok.events.onViewerClosed.subscribe((args) => {\n const v = args.args.viewer;\n if (v?.getOptions()?.look?.title && scatterPlot?.getOptions()?.look?.title &&\n v?.getOptions()?.look?.title === scatterPlot?.getOptions()?.look?.title) {\n grok.events.fireCustomEvent(DIMENSIONALITY_REDUCER_TERMINATE_EVENT, {});\n sub.unsubscribe();\n resolveF?.();\n pg.close();\n }\n });\n const dimRedResPromise = new Promise(async (resolve, reject) => {\n try {\n resolveF = resolve;\n const encodedColEntries = [];\n for (let i = 0; i < preprocessingFunctions.length; ++i) {\n const pf = preprocessingFunctions[i];\n if (!dimRedOptions.distanceFnArgs)\n dimRedOptions.distanceFnArgs = [];\n if (pf) {\n const colInputName = pf.inputs[0].name;\n const metricInputName = pf.inputs[1].name;\n const { entries, options } = await pf.apply({ [colInputName]: columns[i], [metricInputName]: metrics[i],\n ...(dimRedOptions.preprocessingFuncArgs[i] ?? {}) });\n encodedColEntries.push({ entries, options });\n dimRedOptions.distanceFnArgs.push(options);\n }\n else {\n const entries = columns[i].toList();\n const options = {};\n encodedColEntries.push({ entries, options });\n dimRedOptions.distanceFnArgs.push(options);\n }\n }\n const res = await getNormalizedEmbeddings(encodedColEntries.map((it) => it.entries), method, metrics, weights, aggregationMethod, dimRedOptions, uiOptions[BYPASS_LARGE_DATA_WARNING] ? undefined : progressFunc);\n resolve(res);\n }\n catch (e) {\n reject(e);\n }\n });\n const res = await dimRedResPromise;\n pg.close();\n sub.unsubscribe();\n return res;\n }\n const res = await getDimRed();\n if (clusterEmbeddings && res) {\n const clusterPg = DG.TaskBarProgressIndicator.create(`Clustering embeddings ...`);\n try {\n const clusterRes = await getDbscanWorker(res[0], res[1], dimRedOptions.dbScanEpsilon ?? 0.01, dimRedOptions.dbScanMinPts ?? 4);\n const clusterColName = table.columns.getUnusedName('Cluster (DBSCAN)');\n const clusterCol = table.columns.addNewString(clusterColName);\n clusterCol.init((i) => clusterRes[i].toString());\n if (scatterPlot)\n scatterPlot.props.colorColumnName = clusterColName;\n }\n catch (e) {\n grok.shell.error('Clustering embeddings failed');\n console.error(e);\n }\n finally {\n clusterPg.close();\n }\n }\n if (res) {\n const embedXCol = table.columns.byName(embedColsNames[0]);\n const embedYCol = table.columns.byName(embedColsNames[1]);\n embedXCol.init((i) => res[0][i]);\n embedYCol.init((i) => res[1][i]);\n if (postProcessingFunc) {\n try {\n const col1InputName = postProcessingFunc.inputs[0].name;\n const col2InputName = postProcessingFunc.inputs[1].name;\n await postProcessingFunc\n .prepare({ [col1InputName]: embedXCol, [col2InputName]: embedYCol, ...postProcFuncArgs })\n .call(true);\n }\n catch (e) {\n grok.shell.error('Post-processing failed');\n console.error(e);\n }\n }\n if (scatterPlot) {\n ui.setUpdateIndicator(scatterPlot.root, false);\n scatterPlot.helpUrl = '/help/compute/sequence-space';\n return scatterPlot;\n }\n }\n }\n catch (e) {\n grok.shell.error('Dimensionality reduction failed');\n console.error(e);\n pg.close();\n if (scatterPlot)\n ui.setUpdateIndicator(scatterPlot.root, false);\n }\n };\n return new Promise(async (resolve, reject) => {\n try {\n if (uiOptions.fastRowCount && table.rowCount > uiOptions.fastRowCount && !uiOptions[BYPASS_LARGE_DATA_WARNING]) {\n ui.dialog()\n .add(ui.divText('Analysis might take several minutes. Do you want to continue?'))\n .onOK(async () => {\n try {\n const res = await doReduce();\n resolve(res);\n }\n catch (e) {\n reject(e);\n }\n })\n .onCancel(() => resolve(undefined))\n .show();\n }\n else {\n const res = await doReduce();\n resolve(res);\n }\n }\n catch (e) {\n reject(e);\n }\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlLWRpbWVuc2lvbmFsaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVkdWNlLWRpbWVuc2lvbmFsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sbUJBQW1CLENBQUM7QUFDMUMsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXRDLE9BQU8sRUFBQyx5QkFBeUIsRUFBRSx5QkFBeUIsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBRS9GLE9BQU8sRUFBaUIsZUFBZSxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDekUsT0FBTyxFQUFDLHNDQUFzQyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBRWhFLE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBYTNELE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxFQUFnQjtJQUNwRCxNQUFNLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNwQyxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQVUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDOUYsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0FBQ2pELENBQUM7QUFFRCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsT0FBb0IsRUFBRSxNQUEyQjtJQUN0RixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMs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QUMsQ0FBQyxDQUFDLENBQUM7b0JBQ1osQ0FBQztnQkFDSCxDQUFDLENBQUM7cUJBQ0QsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDbEMsSUFBSSxFQUFFLENBQUM7WUFDWixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxHQUFHLEdBQUcsTUFBTSxRQUFRLEVBQUUsQ0FBQztnQkFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ1osQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuaW1wb3J0ICogYXMgdWkgZnJvbSAnZGF0YWdyb2stYXBpL3VpJztcbmltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5pbXBvcnQge0tub3duTWV0cmljc30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQge0JZUEFTU19MQVJHRV9EQVRBX1dBUk5JTkcsIFNIT1dfU0NBVFRFUlBMT1RfUFJPR1JFU1N9IGZyb20gJy4uL2Z1bmN0aW9uRWRpdG9ycy9jb25zdHMnO1xuaW1wb3J0IHtNYXRyaXgsIE9wdGlvbnN9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7SURCU2Nhbk9wdGlvbnMsIGdldERic2Nhbldvcmtlcn0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy9tYXRoJztcbmltcG9ydCB7RElNRU5TSU9OQUxJVFlfUkVEVUNFUl9URVJNSU5BVEVfRVZFTlR9IGZyb20gJy4vY29uc3RzJztcbmltcG9ydCB7UHJlcHJvY2Vzc0Z1bmN0aW9uUmV0dXJuVHlwZX0gZnJvbSAnLi4vZnVuY3Rpb25FZGl0b3JzL2RpbWVuc2lvbmFsaXR5LXJlZHVjdGlvbi1lZGl0b3InO1xuaW1wb3J0IHtnZXROb3JtYWxpemVkRW1iZWRkaW5nc30gZnJvbSAnLi9lbWJlZGRpbmdzLXNwYWNlJztcbmltcG9ydCB7RGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZH0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3R5cGVzJztcbmltcG9ydCB7SVRTTkVPcHRpb25zLCBJVU1BUE9wdGlvbnN9IGZyb20gJy4vbXVsdGktY29sdW1uLWRpbS1yZWR1Y2VyJztcbmltcG9ydCB7RGltUmVkdWN0aW9uTWV0aG9kc30gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCB0eXBlIERpbVJlZFVpT3B0aW9ucyA9IHtcbiAgW0JZUEFTU19MQVJHRV9EQVRBX1dBUk5JTkddPzogYm9vbGVhbixcbiAgW1NIT1dfU0NBVFRFUlBMT1RfUFJPR1JFU1NdPzogYm9vbGVhbixcbiAgZmFzdFJvd0NvdW50PzogbnVtYmVyLFxuICBzY2F0dGVyUGxvdE5hbWU/OiBzdHJpbmcsXG4gIHRhYmxlVmlldz86IERHLlRhYmxlVmlldyxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVtYmVkZGluZ0NvbHNOYW1lcyhkZjogREcuRGF0YUZyYW1lKSB7XG4gIGNvbnN0IGF4ZXMgPSBbJ0VtYmVkX1gnLCAnRW1iZWRfWSddO1xuICBjb25zdCBjb2xOYW1lSW5kID0gZGYuY29sdW1ucy5uYW1lcygpLmZpbHRlcigoaXQ6IHN0cmluZykgPT4gaXQuaW5jbHVkZXMoYXhlc1swXSkpLmxlbmd0aCArIDE7XG4gIHJldHVybiBheGVzLm1hcCgoaXQpID0+IGAke2l0fV8ke2NvbE5hbWVJbmR9YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbWJlZGRpbmdWaWV3ZXJOYW1lKGNvbHVtbnM6IERHLkNvbHVtbltdLCBtZXRob2Q6IERpbVJlZHVjdGlvbk1ldGhvZHMpIHtcbiAgY29uc3QgY29sTmFtZXMgPSBjb2x1bW5zLmxlbmd0aCA+IDQgPyBgJHtjb2x1bW5zLmxlbmd0aH0gY29sdW1uc2AgOiBjb2x1bW5zLm1hcCgoaXQpID0+IGl0Lm5hbWUpLmpvaW4oJywgJyk7XG4gIHJldHVybiBgJHttZXRob2R9ICgke2NvbE5hbWVzfSlgO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbXVsdGlDb2xSZWR1Y2VEaW1lbnNpb25hbGl0eSh0YWJsZTogREcuRGF0YUZyYW1lLCBjb2x1bW5zOiBERy5Db2x1bW5bXSxcbiAgbWV0aG9kOiBEaW1SZWR1Y3Rpb25NZXRob2RzLCBtZXRyaWNzOiBLbm93bk1ldHJpY3NbXSwgd2VpZ2h0czogbnVtYmVyW10sXG4gIHByZXByb2Nlc3NpbmdGdW5jdGlvbnM6IChERy5GdW5jIHwgbnVsbCB8IHVuZGVmaW5lZClbXSxcbiAgYWdncmVnYXRpb25NZXRob2Q6IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsIHBsb3RFbWJlZGRpbmdzOiBib29sZWFuID0gdHJ1ZSwgY2x1c3RlckVtYmVkZGluZ3M6IGJvb2xlYW4gPSBmYWxzZSxcbiAgZGltUmVkT3B0aW9uczogKElVTUFQT3B0aW9ucyB8IElUU05FT3B0aW9ucykgJiBQYXJ0aWFsPElEQlNjYW5PcHRpb25zPiAmIHtwcmVwcm9jZXNzaW5nRnVuY0FyZ3M6IE9wdGlvbnNbXX0gJlxuICAgIE9wdGlvbnMgPSB7cHJlcHJvY2Vzc2luZ0Z1bmNBcmdzOiBbXX0sXG4gIHVpT3B0aW9uczogRGltUmVkVWlPcHRpb25zID0ge30sIHBvc3RQcm9jZXNzaW5nRnVuYzogREcuRnVuYyB8IG51bGwgPSBudWxsLCBwb3N0UHJvY0Z1bmNBcmdzOiBPcHRpb25zID0ge31cbik6IFByb21pc2U8REcuU2NhdHRlclBsb3RWaWV3ZXIgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3Qgc2NhdHRlclBsb3RQcm9wcyA9IHtcbiAgICBzaG93WEF4aXM6IGZhbHNlLFxuICAgIHNob3dZQXhpczogZmFsc2UsXG4gICAgc2hvd1hTZWxlY3RvcjogZmFsc2UsXG4gICAgc2hvd1lTZWxlY3RvcjogZmFsc2UsXG4gIH07XG4gIGlmIChjb2x1bW5zLmxlbmd0aCAhPT0gbWV0cmljcy5sZW5ndGggfHwgY29sdW1ucy5sZW5ndGggIT09IHByZXByb2Nlc3NpbmdGdW5jdGlvbnMubGVuZ3RoIHx8XG4gICAgY29sdW1ucy5sZW5ndGggIT09IHdlaWdodHMubGVuZ3RoIHx8IGNvbHVtbnMubGVuZ3RoICE9PSBkaW1SZWRPcHRpb25zLnByZXByb2Nlc3NpbmdGdW5jQXJncy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbHVtbnMsIG1ldHJpY3MgYW5kIHByZXByb2Nlc3NpbmcgZnVuY3Rpb25zLCB3ZWlnaHRzIGFuZCBmdW5jdGlvbiBhcmd1bWVudHMnICtcbiAgICAgICdtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoJyk7XG4gIH1cblxuICBjb25zdCB0diA9IHBsb3RFbWJlZGRpbmdzID8gKHVpT3B0aW9ucy50YWJsZVZpZXcgPz8gZ3Jvay5zaGVsbC50YWJsZVZpZXcodGFibGUubmFtZSkgPz8gZ3Jvay5zaGVsbC5hZGRUYWJsZVZpZXcodGFibGUpKSA6IG51bGw7XG5cbiAgY29uc3QgZG9SZWR1Y2UgPSBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGcgPSBERy5UYXNrQmFyUHJvZ3Jlc3NJbmRpY2F0b3IuY3JlYXRlKFxuICAgICAgYEluaXRpYWxpemluZyAke3VpT3B0aW9ucy5zY2F0dGVyUGxvdE5hbWUgPz8gJ2RpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbid9IC4uLmApO1xuICAgIGxldCBzY2F0dGVyUGxvdDogREcuU2NhdHRlclBsb3RWaWV3ZXIgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGVtYmVkQ29sc05hbWVzID0gZ2V0RW1iZWRkaW5nQ29sc05hbWVzKHRhYmxlKTtcbiAgICAgIGZ1bmN0aW9uIHByb2dyZXNzRnVuYyhfbkVwb2NoOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmdzOiBudW1iZXJbXVtdKSB7XG4gICAgICAgIGxldCBlbWJlZFhDb2w6IERHLkNvbHVtbiB8IG51bGwgPSBudWxsO1xuICAgICAgICBsZXQgZW1iZWRZQ29sOiBERy5Db2x1bW4gfCBudWxsID0gbnVsbDtcbiAgICAgICAgaWYgKCF0YWJsZS5jb2x1bW5zLm5hbWVzKCkuaW5jbHVkZXMoZW1iZWRDb2xzTmFtZXNbMF0pKSB7XG4gICAgICAgICAgZW1iZWRYQ29sID0gdGFibGUuY29sdW1ucy5hZGQoREcuQ29sdW1uLmZsb2F0KGVtYmVkQ29sc05hbWVzWzBdLCB0YWJsZS5yb3dDb3VudCkpO1xuICAgICAgICAgIGVtYmVkWUNvbCA9IHRhYmxlLmNvbHVtbnMuYWRkKERHLkNvbHVtbi5mbG9hdChlbWJlZENvbHNOYW1lc1sxXSwgdGFibGUucm93Q291bnQpKTtcbiAgICAgICAgICBpZiAocGxvdEVtYmVkZGluZ3MgJiYgIXNjYXR0ZXJQbG90KSB7XG4gICAgICAgICAgICBzY2F0dGVyUGxvdCA9IHR2IVxuICAgICAgICAgICAgICAuc2NhdHRlclBsb3Qoey4uLnNjYXR0ZXJQbG90UHJvcHMsIHg6IGVtYmVkQ29sc05hbWVzWzBdLCB5OiBlbWJlZENvbHNOYW1lc1sxXSxcbiAgICAgICAgICAgICAgICB0aXRsZTogdWlPcHRpb25zLnNjYXR0ZXJQbG90TmFtZSA/PyBnZXRFbWJlZGRpbmdWaWV3ZXJOYW1lKGNvbHVtbnMsIG1ldGhvZCl9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW1iZWRYQ29sID0gdGFibGUuY29sdW1ucy5ieU5hbWUoZW1iZWRDb2xzTmFtZXNbMF0pO1xuICAgICAgICAgIGVtYmVkWUNvbCA9IHRhYmxlLmNvbHVtbnMuYnlOYW1lKGVtYmVkQ29sc05hbWVzWzFdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1aU9wdGlvbnNbU0hPV19TQ0FUVEVSUExPVF9QUk9HUkVTU10pIHtcbiAgICAgICAgICBzY2F0dGVyUGxvdD8ucm9vdCAmJiB1aS5zZXRVcGRhdGVJbmRpY2F0b3Ioc2NhdHRlclBsb3QhLnJvb3QsIGZhbHNlKTtcbiAgICAgICAgICBlbWJlZFhDb2wuaW5pdCgoaSkgPT4gZW1iZWRkaW5nc1swXSA/IGVtYmVkZGluZ3NbMF1baV0gOiB1bmRlZmluZWQpO1xuICAgICAgICAgIGVtYmVkWUNvbC5pbml0KChpKSA9PiBlbWJlZGRpbmdzWzFdID8gZW1iZWRkaW5nc1sxXVtpXSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvZ3Jlc3MgPSAoX25FcG9jaCAvIGVwb2Noc0xlbmd0aCAqIDEwMCk7XG4gICAgICAgIHBnLnVwZGF0ZShwcm9ncmVzcyxcbiAgICAgICAgICBgUnVubmluZyAke3VpT3B0aW9ucy5zY2F0dGVyUGxvdE5hbWUgPz8gJ2RpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbid9Li4uICR7cHJvZ3Jlc3MudG9GaXhlZCgwKX0lYCk7XG4gICAgICB9XG4gICAgICBhc3luYyBmdW5jdGlvbiBnZXREaW1SZWQoKSB7XG4gICAgICAgIHRhYmxlLmNvbHVtbnMuYWRkKERHLkNvbHVtbi5mbG9hdChlbWJlZENvbHNOYW1lc1swXSwgdGFibGUucm93Q291bnQpKTtcbiAgICAgICAgdGFibGUuY29sdW1ucy5hZGQoREcuQ29sdW1uLmZsb2F0KGVtYmVkQ29sc05hbWVzWzFdLCB0YWJsZS5yb3dDb3VudCkpO1xuICAgICAgICBsZXQgcmVzb2x2ZUY6IEZ1bmN0aW9uIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGlmIChwbG90RW1iZWRkaW5ncykge1xuICAgICAgICAgIHNjYXR0ZXJQbG90ID0gdHYhXG4gICAgICAgICAgICAuc2NhdHRlclBsb3Qoey4uLnNjYXR0ZXJQbG90UHJvcHMsIHg6IGVtYmVkQ29sc05hbWVzWzBdLCB5OiBlbWJlZENvbHNOYW1lc1sxXSxcbiAgICAgICAgICAgICAgdGl0bGU6IHVpT3B0aW9ucy5zY2F0dGVyUGxvdE5hbWUgPz8gZ2V0RW1iZWRkaW5nVmlld2VyTmFtZShjb2x1bW5zLCBtZXRob2QpfSk7XG4gICAgICAgICAgdWkuc2V0VXBkYXRlSW5kaWNhdG9yKHNjYXR0ZXJQbG90LnJvb3QsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3ViID0gZ3Jvay5ldmVudHMub25WaWV3ZXJDbG9zZWQuc3Vic2NyaWJlKChhcmdzKSA9PiB7XG4gICAgICAgICAgY29uc3QgdiA9IGFyZ3MuYXJncy52aWV3ZXIgYXMgdW5rbm93biBhcyBERy5WaWV3ZXI8YW55PjtcbiAgICAgICAgICBpZiAodj8uZ2V0T3B0aW9ucygpPy5sb29rPy50aXRsZSAmJiBzY2F0dGVyUGxvdD8uZ2V0T3B0aW9ucygpPy5sb29rPy50aXRsZSAmJlxuICAgICAgICAgICAgdj8uZ2V0T3B0aW9ucygpPy5sb29rPy50aXRsZSA9PT0gc2NhdHRlclBsb3Q/LmdldE9wdGlvbnMoKT8ubG9vaz8udGl0bGUpIHtcbiAgICAgICAgICAgIGdyb2suZXZlbnRzLmZpcmVDdXN0b21FdmVudChESU1FTlNJT05BTElUWV9SRURVQ0VSX1RFUk1JTkFURV9FVkVOVCwge30pO1xuICAgICAgICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICByZXNvbHZlRj8uKCk7XG4gICAgICAgICAgICBwZy5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZGltUmVkUmVzUHJvbWlzZSA9IG5ldyBQcm9taXNlPE1hdHJpeCB8IHVuZGVmaW5lZD4oYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNvbHZlRiA9IHJlc29sdmU7XG4gICAgICAgICAgICBjb25zdCBlbmNvZGVkQ29sRW50cmllczogUHJlcHJvY2Vzc0Z1bmN0aW9uUmV0dXJuVHlwZVtdID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXByb2Nlc3NpbmdGdW5jdGlvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgY29uc3QgcGYgPSBwcmVwcm9jZXNzaW5nRnVuY3Rpb25zW2ldO1xuICAgICAgICAgICAgICBpZiAoIWRpbVJlZE9wdGlvbnMuZGlzdGFuY2VGbkFyZ3MpXG4gICAgICAgICAgICAgICAgZGltUmVkT3B0aW9ucy5kaXN0YW5jZUZuQXJncyA9IFtdO1xuICAgICAgICAgICAgICBpZiAocGYpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xJbnB1dE5hbWUgPSBwZi5pbnB1dHNbMF0ubmFtZTtcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRyaWNJbnB1dE5hbWUgPSBwZi5pbnB1dHNbMV0ubmFtZTtcbiAgICAgICAgICAgICAgICBjb25zdCB7ZW50cmllcywgb3B0aW9uc306IFByZXByb2Nlc3NGdW5jdGlvblJldHVyblR5cGUgPVxuICAgICAgICAgICAgICAgIGF3YWl0IHBmLmFwcGx5KHtbY29sSW5wdXROYW1lXTogY29sdW1uc1tpXSwgW21ldHJpY0lucHV0TmFtZV06IG1ldHJpY3NbaV0sXG4gICAgICAgICAgICAgICAgICAuLi4oZGltUmVkT3B0aW9ucy5wcmVwcm9jZXNzaW5nRnVuY0FyZ3NbaV0gPz8ge30pfSk7XG4gICAgICAgICAgICAgICAgZW5jb2RlZENvbEVudHJpZXMucHVzaCh7ZW50cmllcywgb3B0aW9uc30pO1xuICAgICAgICAgICAgICAgIGRpbVJlZE9wdGlvbnMuZGlzdGFuY2VGbkFyZ3MucHVzaChvcHRpb25zKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRyaWVzID0gY29sdW1uc1tpXS50b0xpc3QoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgICAgICAgICAgICAgZW5jb2RlZENvbEVudHJpZXMucHVzaCh7ZW50cmllcywgb3B0aW9uc30pO1xuICAgICAgICAgICAgICAgIGRpbVJlZE9wdGlvbnMuZGlzdGFuY2VGbkFyZ3MucHVzaChvcHRpb25zKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2V0Tm9ybWFsaXplZEVtYmVkZGluZ3MoZW5jb2RlZENvbEVudHJpZXMubWFwKChpdCkgPT4gaXQuZW50cmllcyksIG1ldGhvZCxcbiAgICAgICAgICAgICAgbWV0cmljcywgd2VpZ2h0cywgYWdncmVnYXRpb25NZXRob2QsIGRpbVJlZE9wdGlvbnMsXG4gICAgICAgICAgICAgIHVpT3B0aW9uc1tCWVBBU1NfTEFSR0VfREFUQV9XQVJOSU5HXSA/IHVuZGVmaW5lZCA6IHByb2dyZXNzRnVuYyk7XG4gICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGRpbVJlZFJlc1Byb21pc2U7XG4gICAgICAgIHBnLmNsb3NlKCk7XG4gICAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2V0RGltUmVkKCk7XG5cbiAgICAgIGlmIChjbHVzdGVyRW1iZWRkaW5ncyAmJiByZXMpIHtcbiAgICAgICAgY29uc3QgY2x1c3RlclBnID0gREcuVGFza0JhclByb2dyZXNzSW5kaWNhdG9yLmNyZWF0ZShgQ2x1c3RlcmluZyBlbWJlZGRpbmdzIC4uLmApO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGNsdXN0ZXJSZXMgPSBhd2FpdCBnZXREYnNjYW5Xb3JrZXIocmVzWzBdLCByZXNbMV0sXG4gICAgICAgICAgICBkaW1SZWRPcHRpb25zLmRiU2NhbkVwc2lsb24gPz8gMC4wMSwgZGltUmVkT3B0aW9ucy5kYlNjYW5NaW5QdHMgPz8gNCk7XG4gICAgICAgICAgY29uc3QgY2x1c3RlckNvbE5hbWUgPSB0YWJsZS5jb2x1bW5zLmdldFVudXNlZE5hbWUoJ0NsdXN0ZXIgKERCU0NBTiknKTtcbiAgICAgICAgICBjb25zdCBjbHVzdGVyQ29sID0gdGFibGUuY29sdW1ucy5hZGROZXdTdHJpbmcoY2x1c3RlckNvbE5hbWUpO1xuICAgICAgICAgIGNsdXN0ZXJDb2wuaW5pdCgoaSkgPT4gY2x1c3RlclJlc1tpXS50b1N0cmluZygpKTtcbiAgICAgICAgICBpZiAoc2NhdHRlclBsb3QpXG4gICAgICAgICAgICAoc2NhdHRlclBsb3QgYXMgREcuU2NhdHRlclBsb3RWaWV3ZXIpLnByb3BzLmNvbG9yQ29sdW1uTmFtZSA9IGNsdXN0ZXJDb2xOYW1lO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgZ3Jvay5zaGVsbC5lcnJvcignQ2x1c3RlcmluZyBlbWJlZGRpbmdzIGZhaWxlZCcpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgY2x1c3RlclBnLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgY29uc3QgZW1iZWRYQ29sID0gdGFibGUuY29sdW1ucy5ieU5hbWUoZW1iZWRDb2xzTmFtZXNbMF0pO1xuICAgICAgICBjb25zdCBlbWJlZFlDb2wgPSB0YWJsZS5jb2x1bW5zLmJ5TmFtZShlbWJlZENvbHNOYW1lc1sxXSk7XG4gICAgICAgIGVtYmVkWENvbC5pbml0KChpKSA9PiByZXNbMF1baV0pO1xuICAgICAgICBlbWJlZFlDb2wuaW5pdCgoaSkgPT4gcmVzWzFdW2ldKTtcbiAgICAgICAgaWYgKHBvc3RQcm9jZXNzaW5nRnVuYykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjb2wxSW5wdXROYW1lID0gcG9zdFByb2Nlc3NpbmdGdW5jLmlucHV0c1swXS5uYW1lO1xuICAgICAgICAgICAgY29uc3QgY29sMklucHV0TmFtZSA9IHBvc3RQcm9jZXNzaW5nRnVuYy5pbnB1dHNbMV0ubmFtZTtcbiAgICAgICAgICAgIGF3YWl0IHBvc3RQcm9jZXNzaW5nRnVuY1xuICAgICAgICAgICAgICAucHJlcGFyZSh7W2NvbDFJbnB1dE5hbWVdOiBlbWJlZFhDb2wsIFtjb2wySW5wdXROYW1lXTogZW1iZWRZQ29sLCAuLi5wb3N0UHJvY0Z1bmNBcmdzfSlcbiAgICAgICAgICAgICAgLmNhbGwodHJ1ZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZ3Jvay5zaGVsbC5lcnJvcignUG9zdC1wcm9jZXNzaW5nIGZhaWxlZCcpO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNjYXR0ZXJQbG90KSB7XG4gICAgICAgICAgdWkuc2V0VXBkYXRlSW5kaWNhdG9yKChzY2F0dGVyUGxvdCBhcyBERy5TY2F0dGVyUGxvdFZpZXdlcikucm9vdCwgZmFsc2UpO1xuICAgICAgICAgIChzY2F0dGVyUGxvdCBhcyBERy5TY2F0dGVyUGxvdFZpZXdlcikuaGVscFVybCA9ICcvaGVscC9jb21wdXRlL3NlcXVlbmNlLXNwYWNlJztcbiAgICAgICAgICByZXR1cm4gc2NhdHRlclBsb3QgYXMgREcuU2NhdHRlclBsb3RWaWV3ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBncm9rLnNoZWxsLmVycm9yKCdEaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gZmFpbGVkJyk7XG4gICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgcGcuY2xvc2UoKTtcbiAgICAgIGlmIChzY2F0dGVyUGxvdClcbiAgICAgICAgdWkuc2V0VXBkYXRlSW5kaWNhdG9yKChzY2F0dGVyUGxvdCBhcyBERy5TY2F0dGVyUGxvdFZpZXdlcikucm9vdCwgZmFsc2UpO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPERHLlNjYXR0ZXJQbG90Vmlld2VyIHwgdW5kZWZpbmVkPihhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh1aU9wdGlvbnMuZmFzdFJvd0NvdW50ICYmIHRhYmxlLnJvd0NvdW50ID4gdWlPcHRpb25zLmZhc3RSb3dDb3VudCAmJiAhdWlPcHRpb25zW0JZUEFTU19MQVJHRV9EQVRBX1dBUk5JTkddKSB7XG4gICAgICAgIHVpLmRpYWxvZygpXG4gICAgICAgICAgLmFkZCh1aS5kaXZUZXh0KCdBbmFseXNpcyBtaWdodCB0YWtlIHNldmVyYWwgbWludXRlcy4gRG8geW91IHdhbnQgdG8gY29udGludWU/JykpXG4gICAgICAgICAgLm9uT0soYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZG9SZWR1Y2UoKTtcbiAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgICAub25DYW5jZWwoKCkgPT4gcmVzb2x2ZSh1bmRlZmluZWQpKVxuICAgICAgICAgIC5zaG93KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBkb1JlZHVjZSgpO1xuICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmVqZWN0KGUpO1xuICAgIH1cbiAgfSk7XG59XG4iXX0=","import { createMultiDimRedWorker } from './multi-dim-red-worker-creator';\nimport { normalize } from '@datagrok-libraries/utils/src/vector-operations';\nexport async function getNormalizedEmbeddings(dataCols, methodName, distanceMetrics, weights, distanceAggregation, options, progressFunc) {\n let dimensionalityReduceRes = await createMultiDimRedWorker(dataCols, distanceMetrics, methodName, weights, distanceAggregation, options, progressFunc);\n dimensionalityReduceRes = dimensionalityReduceRes.map((it) => normalize(it));\n return dimensionalityReduceRes;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1iZWRkaW5ncy1zcGFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImVtYmVkZGluZ3Mtc3BhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sZ0NBQWdDLENBQUM7QUFFdkUsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGlEQUFpRCxDQUFDO0FBSTFFLE1BQU0sQ0FBQyxLQUFLLFVBQVUsdUJBQXVCLENBQzNDLFFBQXNCLEVBQ3RCLFVBQStCLEVBQy9CLGVBQStCLEVBQy9CLE9BQWlCLEVBQ2pCLG1CQUE4QyxFQUM5QyxPQUFZLEVBQUUsWUFBbUY7SUFFakcsSUFBSSx1QkFBdUIsR0FDbkIsTUFBTSx1QkFBdUIsQ0FDM0IsUUFBUSxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE9BQU8sRUFBRSxZQUFZLENBQzNGLENBQUM7SUFFVix1QkFBdUIsR0FBRyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdFLE9BQU8sdUJBQXVCLENBQUM7QUFDakMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TWF0cml4fSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge0tub3duTWV0cmljc30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQge2NyZWF0ZU11bHRpRGltUmVkV29ya2VyfSBmcm9tICcuL211bHRpLWRpbS1yZWQtd29ya2VyLWNyZWF0b3InO1xuaW1wb3J0IHtEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kfSBmcm9tICcuLi9kaXN0YW5jZS1tYXRyaXgvdHlwZXMnO1xuaW1wb3J0IHtub3JtYWxpemV9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3ZlY3Rvci1vcGVyYXRpb25zJztcbmltcG9ydCB7RGltUmVkdWN0aW9uTWV0aG9kc30gZnJvbSAnLi90eXBlcyc7XG5cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldE5vcm1hbGl6ZWRFbWJlZGRpbmdzKFxuICBkYXRhQ29sczogQXJyYXk8YW55W10+LFxuICBtZXRob2ROYW1lOiBEaW1SZWR1Y3Rpb25NZXRob2RzLFxuICBkaXN0YW5jZU1ldHJpY3M6IEtub3duTWV0cmljc1tdLFxuICB3ZWlnaHRzOiBudW1iZXJbXSxcbiAgZGlzdGFuY2VBZ2dyZWdhdGlvbjogRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCxcbiAgb3B0aW9uczogYW55LCBwcm9ncmVzc0Z1bmM/OiAoZXBvY2g6IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZzogbnVtYmVyW11bXSkgPT4gdm9pZFxuKTogUHJvbWlzZTxNYXRyaXg+IHtcbiAgbGV0IGRpbWVuc2lvbmFsaXR5UmVkdWNlUmVzOiBNYXRyaXggPVxuICAgICAgICAgIGF3YWl0IGNyZWF0ZU11bHRpRGltUmVkV29ya2VyKFxuICAgICAgICAgICAgZGF0YUNvbHMsIGRpc3RhbmNlTWV0cmljcywgbWV0aG9kTmFtZSwgd2VpZ2h0cywgZGlzdGFuY2VBZ2dyZWdhdGlvbiwgb3B0aW9ucywgcHJvZ3Jlc3NGdW5jXG4gICAgICAgICAgKTtcblxuICBkaW1lbnNpb25hbGl0eVJlZHVjZVJlcyA9IGRpbWVuc2lvbmFsaXR5UmVkdWNlUmVzLm1hcCgoaXQpID0+IG5vcm1hbGl6ZShpdCkpO1xuICByZXR1cm4gZGltZW5zaW9uYWxpdHlSZWR1Y2VSZXM7XG59XG5cbiJdfQ==","import * as grok from 'datagrok-api/grok';\nimport { DIMENSIONALITY_REDUCER_TERMINATE_EVENT } from './consts';\nimport { isNil } from '../distance-matrix/utils';\nexport async function createMultiDimRedWorker(data, metrics, method, weights, aggregationMethod, options, progressFunc) {\n if (!options.distanceFnArgs)\n throw new Error('options.distanceFnArgs must be defined');\n if (data.length !== metrics.length || data.length !== options.distanceFnArgs.length || data.length !== weights.length)\n throw new Error('data, metrics and options and weights must have the same length');\n return new Promise(function (resolve, reject) {\n const worker = new Worker(new URL('./mulit-column-dim-reducer-worker', import.meta.url));\n worker.postMessage({\n columnsData: data,\n distanceMetrics: metrics,\n method: method,\n options: options,\n weights: weights,\n aggregationMethod: aggregationMethod,\n });\n const terminateSub = grok.events.onCustomEvent(DIMENSIONALITY_REDUCER_TERMINATE_EVENT).subscribe(() => {\n try {\n worker?.terminate();\n }\n finally {\n terminateSub.unsubscribe();\n }\n });\n worker.onmessage = ({ data: { error, embedding, epochNum, epochsLength } }) => {\n if (!isNil(epochNum) && !isNil(epochsLength)) {\n progressFunc && progressFunc(epochNum, epochsLength, embedding);\n return;\n }\n terminateSub.unsubscribe();\n if (error)\n reject(error);\n else\n resolve(embedding);\n // terminate the worker after some time. immidiate termination causes crashes.\n setTimeout(() => worker.terminate(), 100);\n };\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktZGltLXJlZC13b3JrZXItY3JlYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm11bHRpLWRpbS1yZWQtd29ya2VyLWNyZWF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEVBQUMsc0NBQXNDLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFJaEUsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBRS9DLE1BQU0sQ0FBQyxLQUFLLFVBQVUsdUJBQXVCLENBQUMsSUFBa0IsRUFBRSxPQUF1QixFQUFFLE1BQTJCLEVBQ3BILE9BQWlCLEVBQUUsaUJBQTRDLEVBQy9ELE9BQVksRUFBRSxZQUFtRjtJQUVqRyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWM7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0lBQzVELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsTUFBTTtRQUNuSCxNQUFNLElBQUksS0FBSyxDQUFDLGlFQUFpRSxDQUFDLENBQUM7SUFDckYsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFTLE9BQU8sRUFBRSxNQUFNO1FBQ3pDLE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLG1DQUFtQyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN6RixNQUFNLENBQUMsV0FBVyxDQUFDO1lBQ2pCLFdBQVcsRUFBRSxJQUFJO1lBQ2pCLGVBQWUsRUFBRSxPQUFPO1lBQ3hCLE1BQU0sRUFBRSxNQUFNO1lBQ2QsT0FBTyxFQUFFLE9BQU87WUFDaEIsT0FBTyxFQUFFLE9BQU87WUFDaEIsaUJBQWlCLEVBQUUsaUJBQWlCO1NBQ3JDLENBQUMsQ0FBQztRQUNILE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLHNDQUFzQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNwRyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDO1lBQ3RCLENBQUM7b0JBQVMsQ0FBQztnQkFDVCxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDN0IsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUMsSUFBSSxFQUFFLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFDLEVBQUMsRUFBRSxFQUFFO1lBQ3hFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztnQkFDN0MsWUFBWSxJQUFJLFlBQVksQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUNoRSxPQUFPO1lBQ1QsQ0FBQztZQUNELFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQixJQUFJLEtBQUs7Z0JBQ1AsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDOztnQkFFZCxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDckIsOEVBQThFO1lBQzlFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtLbm93bk1ldHJpY3N9IGZyb20gJy4uL3R5cGVkLW1ldHJpY3MvdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcbmltcG9ydCB7RElNRU5TSU9OQUxJVFlfUkVEVUNFUl9URVJNSU5BVEVfRVZFTlR9IGZyb20gJy4vY29uc3RzJztcbmltcG9ydCB7TWF0cml4fSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge0RpbVJlZHVjdGlvbk1ldGhvZHN9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kfSBmcm9tICcuLi9kaXN0YW5jZS1tYXRyaXgvdHlwZXMnO1xuaW1wb3J0IHtpc05pbH0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3V0aWxzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU11bHRpRGltUmVkV29ya2VyKGRhdGE6IEFycmF5PGFueVtdPiwgbWV0cmljczogS25vd25NZXRyaWNzW10sIG1ldGhvZDogRGltUmVkdWN0aW9uTWV0aG9kcyxcbiAgd2VpZ2h0czogbnVtYmVyW10sIGFnZ3JlZ2F0aW9uTWV0aG9kOiBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kLFxuICBvcHRpb25zOiBhbnksIHByb2dyZXNzRnVuYz86IChlcG9jaDogbnVtYmVyLCBlcG9jaHNMZW5ndGg6IG51bWJlciwgZW1iZWRkaW5nOiBudW1iZXJbXVtdKSA9PiB2b2lkXG4pOiBQcm9taXNlPE1hdHJpeD4ge1xuICBpZiAoIW9wdGlvbnMuZGlzdGFuY2VGbkFyZ3MpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdvcHRpb25zLmRpc3RhbmNlRm5BcmdzIG11c3QgYmUgZGVmaW5lZCcpO1xuICBpZiAoZGF0YS5sZW5ndGggIT09IG1ldHJpY3MubGVuZ3RoIHx8IGRhdGEubGVuZ3RoICE9PSBvcHRpb25zLmRpc3RhbmNlRm5BcmdzLmxlbmd0aCB8fCBkYXRhLmxlbmd0aCAhPT0gd2VpZ2h0cy5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhLCBtZXRyaWNzIGFuZCBvcHRpb25zIGFuZCB3ZWlnaHRzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGgnKTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGNvbnN0IHdvcmtlciA9IG5ldyBXb3JrZXIobmV3IFVSTCgnLi9tdWxpdC1jb2x1bW4tZGltLXJlZHVjZXItd29ya2VyJywgaW1wb3J0Lm1ldGEudXJsKSk7XG4gICAgd29ya2VyLnBvc3RNZXNzYWdlKHtcbiAgICAgIGNvbHVtbnNEYXRhOiBkYXRhLFxuICAgICAgZGlzdGFuY2VNZXRyaWNzOiBtZXRyaWNzLFxuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBvcHRpb25zOiBvcHRpb25zLFxuICAgICAgd2VpZ2h0czogd2VpZ2h0cyxcbiAgICAgIGFnZ3JlZ2F0aW9uTWV0aG9kOiBhZ2dyZWdhdGlvbk1ldGhvZCxcbiAgICB9KTtcbiAgICBjb25zdCB0ZXJtaW5hdGVTdWIgPSBncm9rLmV2ZW50cy5vbkN1c3RvbUV2ZW50KERJTUVOU0lPTkFMSVRZX1JFRFVDRVJfVEVSTUlOQVRFX0VWRU5UKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgd29ya2VyPy50ZXJtaW5hdGUoKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRlcm1pbmF0ZVN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHdvcmtlci5vbm1lc3NhZ2UgPSAoe2RhdGE6IHtlcnJvciwgZW1iZWRkaW5nLCBlcG9jaE51bSwgZXBvY2hzTGVuZ3RofX0pID0+IHtcbiAgICAgIGlmICghaXNOaWwoZXBvY2hOdW0pICYmICFpc05pbChlcG9jaHNMZW5ndGgpKSB7XG4gICAgICAgIHByb2dyZXNzRnVuYyAmJiBwcm9ncmVzc0Z1bmMoZXBvY2hOdW0sIGVwb2Noc0xlbmd0aCwgZW1iZWRkaW5nKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGVybWluYXRlU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICBpZiAoZXJyb3IpXG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICBlbHNlXG4gICAgICAgIHJlc29sdmUoZW1iZWRkaW5nKTtcbiAgICAgIC8vIHRlcm1pbmF0ZSB0aGUgd29ya2VyIGFmdGVyIHNvbWUgdGltZS4gaW1taWRpYXRlIHRlcm1pbmF0aW9uIGNhdXNlcyBjcmFzaGVzLlxuICAgICAgc2V0VGltZW91dCgoKSA9PiB3b3JrZXIudGVybWluYXRlKCksIDEwMCk7XG4gICAgfTtcbiAgfSk7XG59XG4iXX0=","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {_package} from '../package-test';\n\n// tests for dimensionality reduction\n\nimport {category, expect, test} from '@datagrok-libraries/utils/src/test';\nimport {DimReductionMethods} from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/types';\nimport {KnownMetrics, NumberMetricsNames, StringMetricsNames} from '@datagrok-libraries/ml/src/typed-metrics';\nimport {multiColReduceDimensionality}\n from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/reduce-dimensionality';\n\nconst DEMOG_COLNAMES = {\n SUBJ: 'subj',\n STUDY: 'study',\n SITE: 'site',\n AGE: 'age',\n SEX: 'sex',\n RACE: 'race',\n DISEASE: 'disease',\n WEIGHT: 'weight',\n HEIGHT: 'height',\n} as const;\ncategory('Dimensionality reduction: UMAP', () => {\n test('Numeric column', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.AGE], DimReductionMethods.UMAP, [NumberMetricsNames.Difference]);\n }, {timeout: 30000});\n\n test('String column', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.SEX], DimReductionMethods.UMAP, [StringMetricsNames.Onehot]);\n }, {timeout: 30000});\n\n test('Numeric and string columns', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.SEX, DEMOG_COLNAMES.AGE], DimReductionMethods.UMAP,\n [StringMetricsNames.Onehot, NumberMetricsNames.Difference]);\n });\n\n test('All demog columns', async () => {\n const allDemogCols = grok.data.demo.demog(10).columns.toList()\n .filter((col) => Object.values(DEMOG_COLNAMES).includes(col.name as any)); ;\n const distFuncs = allDemogCols.map((col) => col.type === DG.COLUMN_TYPE.STRING ?\n StringMetricsNames.Onehot : NumberMetricsNames.Difference);\n const colNames = allDemogCols.map((col) => col.name);\n await testDimensionalityReductionUI( colNames, DimReductionMethods.UMAP, distFuncs);\n });\n});\n\ncategory('Dimensionality reduction: T-SNE', () => {\n test('Numeric column', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.AGE], DimReductionMethods.T_SNE, [NumberMetricsNames.Difference]);\n }, {timeout: 30000});\n\n test('String column', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.SEX], DimReductionMethods.T_SNE, [StringMetricsNames.Onehot]);\n }, {timeout: 30000});\n\n test('Numeric and string columns', async () => {\n await testDimensionalityReductionUI(\n [DEMOG_COLNAMES.SEX, DEMOG_COLNAMES.AGE], DimReductionMethods.T_SNE,\n [StringMetricsNames.Onehot, NumberMetricsNames.Difference]);\n });\n\n test('All demog columns', async () => {\n const allDemogCols = grok.data.demo.demog(10).columns.toList()\n .filter((col) => Object.values(DEMOG_COLNAMES).includes(col.name as any));\n const distFuncs = allDemogCols.map((col) => col.type === DG.COLUMN_TYPE.STRING ?\n StringMetricsNames.Onehot : NumberMetricsNames.Difference);\n const colNames = allDemogCols.map((col) => col.name);\n await testDimensionalityReductionUI(colNames, DimReductionMethods.T_SNE, distFuncs);\n });\n});\n\nasync function testDimensionalityReductionUI(\n columns: string[], methodName: DimReductionMethods, metrics: KnownMetrics[],\n) {\n const df = grok.data.demo.demog(100);\n const _tv = grok.shell.addTableView(df);\n const dimRedResult = await multiColReduceDimensionality(\n df, columns.map((c) => df.col(c)!), methodName, metrics,\n columns.map(() => 1), columns.map(() => undefined),\n 'EUCLIDEAN', true, true, {preprocessingFuncArgs: columns.map(() => ({}))});\n expect(!!dimRedResult, true, 'No scatterplot returned');\n const addedEmbeddingsCols = df.columns.names().filter((c) => c.toLowerCase().startsWith('embed'));\n expect(addedEmbeddingsCols.length, 2, 'Wrong number of embeddings added');\n const clusterColName = df.columns.names().find((c) => c.toLowerCase().startsWith('cluster'));\n expect(!!clusterColName, true, 'No cluster column added');\n for (const embedColName of addedEmbeddingsCols) {\n const c = df.col(embedColName)!;\n expect(new Array(c.length).fill(null).every((_, i) => !c.isNone(i) && !isNaN(c.get(i))), true,\n 'Embedding column has null-ish values');\n }\n await new Promise((resolve) => setTimeout(resolve, 500));\n}\n","// Runtime system for exported C/C++-functions call.\n// It was previousely developed and does NOT provide call wasm-functions in WebWorkers.\n\n// type-to-heap correspondence\nconst heapMap = {'i32': 'HEAP32', // Int32Array\n 'f32': 'HEAPF32', // Float32Array\n};\n\n// type signature to typed array ,app\nconst typeMap = {'i32': Int32Array, // Int32Array\n 'f32': Float32Array, // Float32Array\n};\n\n// type-to-shift map\nconst shiftMap = {'i32': 2, // Int32Array\n 'f32': 2, // Float32Array\n};\n\n// type-to-column_creator map\nconst typeToColumnCreatorMap = {'i32': DG.Column.fromInt32Array,\n 'f32': DG.Column.fromFloat32Array};\n\n\n// CLASSES THAT ARE USED BY CPP-WRAPPER\n\n// simple argument: a number\nclass Arg {\n constructor(data) {\n this.data = data;\n }\n\n complementArrOfParams(arrOfParams) {\n arrOfParams.push(this.data);\n }\n\n complementArrOfTypes(arrOfTypes) {\n arrOfTypes.push('number');\n }\n\n allocateMemoryForBuffer(module) {}\n\n isMemoryForBufferAllocated() {\n return true;\n }\n\n putDataToBuffer(module) {}\n\n getDataFromBuffer(module) {}\n\n freeBuffer(module) {}\n}\n\n// column argument\nclass ArgColumn extends Arg {\n constructor(data, targetType, toUpdate = false) {\n super(data);\n this.type = targetType;\n this.toUpdate = toUpdate;\n this.buf = 0;\n this.numOfRows = data.length;\n }\n\n complementArrOfParams(arrOfParams) {\n arrOfParams.push(this.buf);\n arrOfParams.push(this.numOfRows);\n }\n\n complementArrOfTypes(arrOfTypes) {\n arrOfTypes.push('number');\n arrOfTypes.push('number');\n }\n\n allocateMemoryForBuffer(module) {\n this.buf = module._malloc(this.numOfRows * typeMap[this.type].BYTES_PER_ELEMENT);\n }\n\n isMemoryForBufferAllocated() {\n return (this.buf != 0);\n }\n\n putDataToBuffer(module) {\n if (this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const shift = shiftMap[type];\n const heap = module[heapMap[type]];\n let array = null;\n const col = this.data;\n\n if (((col.type == 'int') && (type == 'i32')) ||\n ((col.type == 'double') && (type == 'f32')))\n array = col.getRawData();\n else\n array = new typeMap[type](col.getRawData());\n\n if (array)\n heap.set(array, this.buf >> shift);\n }\n }\n\n getDataFromBuffer(module) {\n if (this.toUpdate && this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const heap = module[heapMap[type]];\n const buffer = this.buf;\n const bytes = typeMap[type].BYTES_PER_ELEMENT;\n const array = this.data.getRawData();\n\n for (let i = 0; i < this.numOfRows; i++)\n array[i] = heap[buffer / bytes + i];\n }\n }\n\n freeBuffer(module) {\n if (this.isMemoryForBufferAllocated()) {\n module._free(this.buf);\n this.buf = 0;\n }\n }\n}\n\n// new column argument: a new column is created\nclass ArgNewColumn extends ArgColumn {\n constructor(targetType, numOfRows) {\n super([], targetType, true);\n this.numOfRows = numOfRows;\n }\n\n putDataToBuffer(module) {}\n\n getDataFromBuffer(module) {\n if (this.toUpdate && this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const heap = module[heapMap[type]];\n const buf = this.buf;\n\n const columnCreator = typeToColumnCreatorMap[type];\n\n const arr = new typeMap[type](this.numOfRows);\n\n for (let i = 0; i < arr.length; i++)\n arr[i] = heap[buf / arr.BYTES_PER_ELEMENT + i];\n\n this.data = columnCreator('name', arr);\n\n //console.log(arr);\n\n // This makes mistake, when this.numOfRows = 5 (TODO: investigate why)\n //this.data = columnCreator('name', new typeMap[type](heap.buffer, this.buf, this.numOfRows));\n\n //console.log(this.data.getRawData());\n }\n }\n}\n\n// an array of columns argument\nclass ArgColumns extends Arg {\n constructor(data, targetType, toUpdate = false) {\n super(data);\n this.type = targetType;\n this.toUpdate = toUpdate;\n this.buf = 0;\n this.numOfColumns = data.length;\n this.numOfRows = data[0].length;\n }\n\n complementArrOfParams(arrOfParams) {\n arrOfParams.push(this.buf);\n arrOfParams.push(this.numOfRows);\n arrOfParams.push(this.numOfColumns);\n }\n\n complementArrOfTypes(arrOfTypes) {\n arrOfTypes.push('number');\n arrOfTypes.push('number');\n arrOfTypes.push('number');\n }\n\n allocateMemoryForBuffer(module) {\n this.buf = module._malloc(this.numOfRows * this.numOfColumns *\n typeMap[this.type].BYTES_PER_ELEMENT);\n }\n\n isMemoryForBufferAllocated() {\n return (this.buf != 0);\n }\n\n putDataToBuffer(module) {\n if (this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const shift = shiftMap[type];\n const heap = module[heapMap[type]];\n const numOfBytes = typeMap[type].BYTES_PER_ELEMENT;\n\n // put columns data to buffer\n for (let i = 0; i < this.numOfColumns; i++) {\n let array = null;\n const col = this.data[i];\n\n if (((col.type == 'int') && (type == 'i32')) ||\n ((col.type == 'double') && (type == 'f32')))\n array = col.getRawData();\n else\n array = new typeMap[type](col.getRawData());\n\n // check data array\n if (array != null)\n heap.set(array, (this.buf + i * this.numOfRows * numOfBytes) >> shift);\n }\n }\n }\n\n getDataFromBuffer(module) {\n if (this.toUpdate && this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const heap = module[heapMap[type]];\n const numOfRows = this.numOfRows;\n const numOfCols = this.numOfColumns;\n const arr = new typeMap[type](heap.buffer, this.buf, numOfRows * numOfCols);\n\n for (let i = 0; i < numOfCols; i++) {\n const colData = this.data[i].getRawData();\n for (let j = 0; j < numOfRows; j++)\n colData[j] = arr[j + i * numOfRows];\n }\n }\n }\n\n freeBuffer(module) {\n if (this.isMemoryForBufferAllocated()) {\n module._free(this.buf);\n this.buf = 0;\n }\n }\n}\n\n// an array of new columns: new columns are created\nclass ArgNewColumns extends ArgColumns {\n constructor(targetType, numOfRows, numOfColumns) {\n super([[]], targetType, true);\n this.data = [];\n this.numOfColumns = numOfColumns;\n this.numOfRows = numOfRows;\n }\n\n putDataToBuffer(module) { }\n\n getDataFromBuffer(module) {\n if (this.toUpdate && this.isMemoryForBufferAllocated()) {\n const type = this.type;\n const heap = module[heapMap[type]];\n const numOfRows = this.numOfRows;\n const numOfCols = this.numOfColumns;\n const numOfBytes = typeMap[type].BYTES_PER_ELEMENT;\n const columnCreator = typeToColumnCreatorMap[type];\n const buf = this.buf;\n\n for (let i = 0; i < numOfCols; i++) {\n const arr = new typeMap[type](numOfRows);\n\n for (let j = 0; j < numOfRows; j++)\n arr[j] = heap[buf / numOfBytes + j + i * numOfRows];\n\n this.data.push(columnCreator((i + 1).toString(), arr));\n }\n\n // create columns: here, may be a problem when numOfRows = 5\n /*for(let i = 0; i < numOfCols; i++)\n this.data.push(columnCreator((i + 1).toString(), new typeMap[type](heap.buffer,\n this.buf + i * numOfRows * numOfBytes, numOfRows)));*/\n }\n }\n}\n\n// a wrapper for exported C/C++-function call\nfunction cppFuncWrapper(module, cFuncName, returnType, args) {\n let result;\n\n // allocate memory for buffers\n for (const arg of args)\n arg.allocateMemoryForBuffer(module);\n\n let isEnoughOfMemoryAllocated = true;\n\n // check memory allocation\n for (const arg of args)\n isEnoughOfMemoryAllocated &= arg.isMemoryForBufferAllocated();\n\n // run exported function if enough of memory is allocated\n if (isEnoughOfMemoryAllocated) {\n const params = []; // arguments that are put to the exported function\n const types = []; // their types\n\n // prepare data that is put to exported function\n for (const arg of args) {\n arg.complementArrOfParams(params);\n arg.complementArrOfTypes(types);\n arg.putDataToBuffer(module);\n }\n\n const extendedTypeOfReturn = (returnType == 'num') ? 'number' : null;\n\n // call exported function\n if (extendedTypeOfReturn)\n result = module.ccall(cFuncName, extendedTypeOfReturn, types, params);\n else\n result = module.ccall(cFuncName, extendedTypeOfReturn, types, params);\n\n // update and get data from buffers if required\n for (const arg of args)\n arg.getDataFromBuffer(module);\n }\n\n // clear buffers\n for (const arg of args)\n arg.freeBuffer(module);\n\n if (result != undefined)\n return result;\n} // cppFuncWrapper\n\n\n// A LAYER BETWEEN JS AND CPP-WRAPPER\n\n// Parameters creator\nconst Param = {\n intColumn(column) {\n return new ArgColumn(column, 'i32');\n },\n\n newIntColumn(numOfRows) {\n return new ArgNewColumn('i32', numOfRows);\n },\n\n intColumns(columns) {\n return new ArgColumns(columns.toList(), 'i32');\n },\n\n newIntColumns(numOfRows, numOfColumns) {\n return new ArgNewColumns('i32', numOfRows, numOfColumns);\n },\n\n floatColumn(column) {\n return new ArgColumn(column, 'f32');\n },\n\n newFloatColumn(numOfRows) {\n return new ArgNewColumn('f32', numOfRows);\n },\n\n floatColumns(columns) {\n return new ArgColumns(columns.toList(), 'f32');\n },\n\n newFloatColumns(numOfRows, numOfColumns) {\n return new ArgNewColumns('f32', numOfRows, numOfColumns);\n },\n\n int(number) {\n return new Arg(number);\n },\n\n num(number) {\n return new Arg(number);\n },\n};\n\n// Return value creator\nconst Return = {\n tableFromColumns(argColumns) {\n return DG.DataFrame.fromColumns(argColumns.data);\n },\n\n num(number) {\n return number;\n },\n\n int(number) {\n return number;\n },\n\n double(number) {\n return number;\n },\n\n column(argColumn) {\n return argColumn.data;\n },\n};\n\n// The main tool that combines all together\nexport function callWasm(module, funcName, inputs) {\n // get specification of exported C/C++-function\n const funcSpecification = module[funcName];\n\n // get argumnets\n const args = funcSpecification.arguments;\n\n // array of arguments that further are used by cpp-wrapper\n const cppFuncInput = [];\n\n // complete an input for cpp\n let i = 0;\n for (const key in args) {\n const arg = args[key];\n\n // skip auxiliry element\n if (key == '_callResult')\n continue;\n\n // create an argument\n switch (arg.type) {\n case 'floatColumns':\n case 'int':\n case 'num':\n case 'floatColumn':\n case 'intColumn':\n case 'intColumns':\n arg.data = Param[arg.type](inputs[i]);\n i++;\n break;\n case 'newFloatColumns':\n case 'newIntColumns':\n const val1 = args[arg['numOfRows']['ref']].data[arg['numOfRows']['value']];\n const val2 = args[arg['numOfColumns']['ref']].data[arg['numOfColumns']['value']];\n arg.data = Param[arg.type](val1, val2);\n break;\n case 'newFloatColumn':\n case 'newIntColumn':\n const val = args[arg['numOfRows']['ref']].data[arg['numOfRows']['value']];\n arg.data = Param[arg.type](val);\n break;\n } // switch\n\n cppFuncInput.push(args[key].data);\n } // for key\n\n // CALL EXPORTED CPP-FUNCTION\n const callResult = cppFuncWrapper(module, funcName, 'num', cppFuncInput);\n\n // store result that is returned by exported cpp-function\n args._callResult = Param.num(callResult);\n\n // create output\n const output = funcSpecification.output;\n\n // if a single object must be returned\n if (output['type'] != 'objects')\n return Return[output['type']](args[output['source']].data);\n\n const arrayToReturn = [];\n\n // push data of the required arguments\n for (const name of output['source'])\n arrayToReturn.push(args[name].data.data);\n\n return arrayToReturn;\n} // callWasm\n","// Utilities for calling wasm-functions via webworker.\n\n// We use an approach that is well described here:\n// https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97\n// It has been modified for usage in DATAGROK.\n\n// Constants for wasm-functions in webworkers runtime system\nconst TYPE = 'type';\nconst NUM_TYPE = 'num';\nconst FLOAT_COLUMN_TYPE = 'floatColumn';\nconst INT_COLUMN_TYPE = 'intColumn';\nconst FLOAT_COLUMNS_TYPE = 'floatColumns';\nconst NEW_FLOAT_COLUMNS_TYPE = 'newFloatColumns';\nconst INT_COLUMNS_TYPE = 'intColumns';\nconst NEW_INT_COLUMNS_TYPE = 'newIntColumns';\nconst NEW_FLOAT_COLUMN_TYPE = 'newFloatColumn';\nconst NEW_INT_COLUMN_TYPE = 'newIntColumn';\nconst COLUMN = 'column';\nconst CALL_RESULT = '_callResult';\nconst NUM_OF_ROWS = 'numOfRows';\nconst NUM_OF_COLUMNS = 'numOfColumns';\nconst REF = 'ref';\nconst VALUE = 'value';\nconst TABLE_OF_COLUMNS = 'tableFromColumns';\nconst OBJECTS = 'objects';\nconst INT_TYPE = 'int';\nconst DOUBLE_TYPE = 'double';\nconst NUMBER = 'number';\n\n// Type-to-heap correspondence.\n// It is required for JS-module generated by Emscripten,\n// and it is used, when passing array data to/from wasm-functions.\n// More info can be found at the following link:\n// https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97\nconst heapMap = {\n 'intColumn': \"HEAP32\",\n 'floatColumn': \"HEAPF32\",\n 'floatColumns': \"HEAPF32\",\n 'newFloatColumns': \"HEAPF32\",\n 'intColumns': \"HEAP32\",\n 'newIntColumns': \"HEAP32\",\n 'newFloatColumn': \"HEAPF32\",\n 'newIntColumn': \"HEAP32\"\n };\n\n// Type signature to typed array map.\n// It is used, when manipulating column(s).\nconst typeMap = {\n 'intColumn': Int32Array,\n 'floatColumn': Float32Array,\n 'floatColumns': Float32Array,\n 'newFloatColumns': Float32Array,\n 'intColumns': Int32Array, \n 'newIntColumns': Int32Array,\n 'newFloatColumn': Float32Array,\n 'newIntColumn': Int32Array\n }; \n\n// Type-to-shift map.\n// It is used, when passing array to/from wasm-functions.\n// More info can be found at the following link:\n// https://becominghuman.ai/passing-and-returning-webassembly-array-parameters-a0f572c65d97 \nconst shiftMap = {'intColumn': 2, \n 'floatColumn': 2, \n 'floatColumns': 2, \n 'newFloatColumns': 2, \n 'intColumns': 2, \n 'newIntColumns': 2,\n 'newFloatColumn': 2,\n 'newIntColumn': 2\n }; \n\n// Get input for C++-function.\n// This function takes specification of arguments (argsSpecification) & input data (inputVals)\n// and returns input that will be further used in cpp/wasm-function.\nexport function getCppInput(argsSpecification, inputVals) {\n let cppFuncInput = [];\n let ref;\n\n // complete an input for cpp\n let i = 0;\n for(const key in argsSpecification) {\n const arg = argsSpecification[key]; \n const type = arg.type;\n \n // skip auxiliry element\n if(key === CALL_RESULT) \n continue;\n\n // here, we consider each type of input\n switch(type) { \n \n // numbers\n case NUM_TYPE: \n case INT_TYPE:\n case DOUBLE_TYPE:\n arg.data = inputVals[i];\n i++;\n break;\n\n // column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n\n let array;\n\n // this is OK if type of column and target type coinside\n //array = inputVals[i].getRawData();\n\n const col = inputVals[i];\n const len = col.length;\n\n // here, we check types and perform an appropriate transform\n if( ( (col.type === INT_TYPE) && (type === INT_COLUMN_TYPE) ) \n || ( (col.type === DOUBLE_TYPE) && (type === FLOAT_COLUMN_TYPE) ) )\n array = col.getRawData().slice(0, len);\n else\n array = new typeMap[type](col.getRawData().slice(0, len));\n\n /*if(((col.type == 'int') && (type == INT_COLUMN_TYPE)) \n || ((col.type == 'double') && (type == FLOAT_COLUMN_TYPE)))\n array = col.getRawData();\n else\n array = new typeMap[type](col.getRawData());*/\n\n // check types\n arg.data = { 'array': array,\n 'numOfRows': len}; \n \n i++;\n break;\n\n // new column \n case NEW_INT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n let val = 0; \n\n ref = arg[NUM_OF_ROWS][REF];\n\n if (argsSpecification[ref].type === NUM_TYPE)\n val = argsSpecification[ref].data;\n else\n val = argsSpecification[ref].data[arg[NUM_OF_ROWS][VALUE]]; \n\n arg.data = {'numOfRows': val};\n\n i++;\n break;\n\n // columns or column_list\n case INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE: \n let arrays = []; \n\n // this is OK if type of columns and target type coinside\n //for(let col of inputVals[i].toList())\n // arrays.push(col.getRawData());\n\n const rowCount = inputVals[i].byIndex(0).length;\n\n // here, we check types and perform an appropriate transform\n for(const col of inputVals[i].toList())\n if( ( (col.type === INT_TYPE) && (type === INT_COLUMN_TYPE) ) \n || ( (col.type === DOUBLE_TYPE) && (type === FLOAT_COLUMN_TYPE) ) )\n arrays.push(col.getRawData().slice(0, rowCount));\n else\n arrays.push(new typeMap[type](col.getRawData().slice(0, rowCount)));\n \n /*for(let col of inputVals[i].toList())\n if(((col.type == 'int') && (type == INT_COLUMN_TYPE)) \n || ((col.type == 'double') && (type == FLOAT_COLUMN_TYPE)))\n arrays.push(col.getRawData());\n else\n arrays.push(new typeMap[type](col.getRawData()));*/\n\n arg.data = { 'arrays': arrays,\n 'numOfRows': rowCount,\n 'numOfColumns': arrays.length};\n\n i++; \n break;\n\n // new columns or new column_list\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n let val1 = 0;\n let val2 = 0;\n\n ref = arg[NUM_OF_ROWS][REF];\n\n if (argsSpecification[ref].type === NUM_TYPE)\n val1 = argsSpecification[ref].data;\n else\n val1 = argsSpecification[ref].data[arg[NUM_OF_ROWS][VALUE]];\n\n ref = arg[NUM_OF_COLUMNS][REF];\n\n //console.log('Ref:');\n //console.log(ref);\n //console.log(argsSpecification[ref].data);\n\n if (argsSpecification[ref].type === NUM_TYPE)\n val2 = argsSpecification[ref].data;\n else\n val2 = argsSpecification[ref].data[arg[NUM_OF_COLUMNS][VALUE]]; \n\n arg.data = {'numOfRows': val1,\n 'numOfColumns': val2};\n\n i++;\n break; \n\n default: \n return; // TODO: specify behaviour \n } // switch \n\n cppFuncInput.push(arg);\n } // for key\n\n //console.log('cppFuncInput:');\n //console.log(cppFuncInput);\n\n return cppFuncInput;\n} // getCppInput\n\n// Allocate memory for buffers for array data\nfunction allocateMemoryForBuffer(module, inputs) {\n for(const arg of inputs) { \n const type = arg.type;\n\n switch(type) { // Process each type of input\n\n // numbers\n case NUM_TYPE: \n case INT_TYPE:\n case DOUBLE_TYPE:\n break;\n\n // column & new column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n arg.data.buf = module._malloc(arg.data.numOfRows * typeMap[type].BYTES_PER_ELEMENT);\n break;\n\n // columns & new columns\n case INT_COLUMNS_TYPE: \n case NEW_INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE: \n case NEW_FLOAT_COLUMNS_TYPE: // allocation memory for columns that are created\n arg.data.buf = module._malloc(arg.data.numOfRows * arg.data.numOfColumns \n * typeMap[type].BYTES_PER_ELEMENT);\n break;\n\n // TODO: process other cases and mistakes\n default:\n break; \n } \n }\n \n //console.log('inputs after memory allocation:');\n //console.log(inputs);\n} // allocateMemoryForBuffer\n\n// Get array of values that are put to wasm-function.\nfunction getArrOfWasmParams(inputs) {\n let params = [];\n\n // Process each type of input\n for(const arg of inputs) {\n switch (arg.type) {\n\n // numbers\n case NUM_TYPE: \n case INT_TYPE:\n case DOUBLE_TYPE:\n params.push(arg.data);\n break;\n\n // column & new column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n params.push(arg.data.buf); \n params.push(arg.data.numOfRows);\n break;\n \n // columns & new columns\n case INT_COLUMNS_TYPE:\n case NEW_INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE: \n params.push(arg.data.buf);\n params.push(arg.data.numOfRows);\n params.push(arg.data.numOfColumns);\n break;\n \n // TODO: process other cases and mistakes\n default:\n break;\n }\n }\n\n return params;\n} // getArrOfWasmParams\n\n// Get array of types that are put to wasm-function.\nfunction getArrOfWasmTypes(inputs) {\n let types = [];\n\n for(const arg of inputs) {\n switch (arg.type) { // Process each type of input\n\n // numbers\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n types.push(NUMBER);\n break;\n\n // column & new column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n types.push(NUMBER); \n types.push(NUMBER);\n break;\n \n // columns & new columns\n case INT_COLUMNS_TYPE:\n case NEW_INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n types.push(NUMBER);\n types.push(NUMBER);\n types.push(NUMBER);\n break;\n\n // TODO: process other cases and mistakes\n default:\n break;\n }\n }\n\n return types;\n} // getArrOfWasmTypes\n\n// Put array data to buffer\nfunction putDataToBuffer(module, inputs) {\n let shift;\n let heap; \n \n for(const arg of inputs) {\n const type = arg.type;\n\n switch (type) { // Process each type of input\n\n // numbers\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE: \n break;\n \n // column\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE: \n shift = shiftMap[type];\n heap = module[heapMap[type]]; \n heap.set(arg.data.array, arg.data.buf >> shift);\n break;\n \n // columns\n case INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n shift = shiftMap[type];\n heap = module[heapMap[type]];\n let numOfBytes = typeMap[type].BYTES_PER_ELEMENT;\n let buf = arg.data.buf;\n let numOfColumns = arg.data.numOfColumns;\n let numOfRows = arg.data.numOfRows;\n let arrays = arg.data.arrays;\n\n for(let i = 0; i < numOfColumns; i++)\n heap.set(arrays[i], (buf + i * numOfRows * numOfBytes) >> shift);\n \n break;\n\n // new column(s)\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE: \n break;\n\n // TODO: process other cases and mistakes\n default:\n break;\n }\n }\n} // putDataToBuffer\n\n// Get array data from buffer.\nfunction getDataFromBuffer(module, inputs) {\n\n let heap;\n let numOfRows;\n let numOfCols;\n let numOfBytes; \n let buf;\n\n for(const arg of inputs) {\n const type = arg.type;\n\n switch (type) { // Process each type of input\n \n // number\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n break;\n\n // column(s)\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case FLOAT_COLUMNS_TYPE: \n case INT_COLUMNS_TYPE: \n break;\n\n // new column\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n heap = module[heapMap[type]];\n numOfRows = arg.data.numOfRows;\n numOfBytes = typeMap[type].BYTES_PER_ELEMENT; \n buf = arg.data.buf;\n let array = new typeMap[type](numOfRows);\n\n for(let j = 0; j < numOfRows; j++)\n array[j] = heap[buf / numOfBytes + j];\n\n arg.array = array;\n\n break;\n\n // new columns\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE: \n heap = module[heapMap[type]];\n numOfRows = arg.data.numOfRows;\n numOfCols = arg.data.numOfColumns;\n numOfBytes = typeMap[type].BYTES_PER_ELEMENT; \n buf = arg.data.buf;\n let arrays = [];\n\n for(let i = 0; i < numOfCols; i++) {\n let arr = new typeMap[type](numOfRows);\n\n for(let j = 0; j < numOfRows; j++)\n arr[j] = heap[buf / numOfBytes + j + i * numOfRows]; \n \n arrays.push(arr);\n }\n\n arg.arrays = arrays;\n \n break;\n \n // TODO: process other cases and mistakes\n default:\n break;\n }\n } \n} // getDataFromBuffer\n\n// Clear memory allocated for array data\nfunction clearMemoryForBuffer(module, inputs) {\n for(const arg of inputs) \n switch(arg.type) { // process each type of input\n\n // number\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n break;\n\n // each non-number case\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE: \n case INT_COLUMNS_TYPE:\n case NEW_INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n module._free(arg.data.buf);\n break;\n\n // TODO: process other cases and mistakes\n default:\n break; \n } \n} // clearMemoryForBuffer\n\n// Extract newly created data: new column(s) are created\nfunction extractNewlyCreatedData(funcSpecificationArgs, argsAfterWasmCall) {\n // type-to-column_creator map\n const typeToColumnCreatorMap = {'newFloatColumns': DG.Column.fromFloat32Array,\n 'newIntColumns': DG.Column.fromInt32Array,\n 'newFloatColumn': DG.Column.fromFloat32Array,\n 'newIntColumn': DG.Column.fromInt32Array};\n\n let i = 0;\n\n for(const key in funcSpecificationArgs) \n {\n const arg = funcSpecificationArgs[key];\n\n switch(arg.type){ // Process each type\n\n // number\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n break;\n\n // column(s)\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE:\n case FLOAT_COLUMNS_TYPE:\n case INT_COLUMNS_TYPE:\n break;\n\n // new column\n case NEW_FLOAT_COLUMN_TYPE:\n case NEW_INT_COLUMN_TYPE:\n let name;\n\n // specify name for column\n if(arg.name == undefined)\n name = (0).toString();\n else \n names = arg.name;\n\n arg.column = typeToColumnCreatorMap[arg.type](name,\n argsAfterWasmCall[i].array);\n break;\n\n // new columns\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n let columns = [];\n let length = argsAfterWasmCall[i].arrays.length;\n\n let names = [];\n\n // specify name for column\n if(arg.names == undefined)\n for(let k = 1; k <= length; k++)\n names.push((k).toString());\n else names = arg.names;\n\n for(let j = 0; j < length; j++)\n columns.push(typeToColumnCreatorMap[arg.type](names[j],\n argsAfterWasmCall[i].arrays[j]));\n\n arg.columns = columns;\n \n break;\n\n // TODO: process other cases and mistakes\n default:\n break;\n }\n\n i++;\n }\n} // extractNewlyCreatedData\n\n// Get output data: overall output is created\nfunction getOutput(funcSpecification) { \n let output = funcSpecification.output;\n \n const typeToDataFieldMap = {'newFloatColumns': 'columns',\n 'newIntColumns': 'columns',\n 'newFloatColumn': 'column',\n 'newIntColumn': 'column'};\n\n switch(output.type) {\n\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n return funcSpecification.arguments[output.source];\n break;\n\n case COLUMN:\n return funcSpecification.arguments[output.source].column;\n break;\n\n case TABLE_OF_COLUMNS:\n return DG.DataFrame.fromColumns(funcSpecification.arguments[output.source].columns);\n break;\n\n case OBJECTS:\n let arrayToReturn = [];\n \n // push data of the required arguments\n for(let name of output.source) {\n let arg = funcSpecification.arguments[name];\n arrayToReturn.push(arg[typeToDataFieldMap[arg.type]]);\n } \n\n return arrayToReturn;\n break;\n\n // TODO: process other cases and mistakes\n default:\n break;\n }\n\n} // getOutput\n\n// Clear newly created data fields (new column(s))\nfunction clearNewlyCreatedData(funcSpecificationArgs) { \n for(const key in funcSpecificationArgs) {\n const arg = funcSpecificationArgs[key];\n\n switch (arg.type) {\n case NUM_TYPE:\n case INT_TYPE:\n case DOUBLE_TYPE:\n case INT_COLUMN_TYPE:\n case FLOAT_COLUMN_TYPE: \n case INT_COLUMNS_TYPE:\n case FLOAT_COLUMNS_TYPE:\n break;\n\n case NEW_INT_COLUMN_TYPE:\n case NEW_FLOAT_COLUMN_TYPE:\n arg.column = null; \n break;\n\n case NEW_INT_COLUMNS_TYPE:\n case NEW_FLOAT_COLUMNS_TYPE:\n arg.columns = null;\n break;\n \n // TODO: process other cases and mistakes\n default:\n break;\n }\n }\n} // clearNewlyCreatedData\n\n// THE MAIN FUNCTION: a wrapper for C++-function call\nexport function cppWrapper(module, args, cppFuncName, returnType) {\n // allocate memory for arrays that are passed to C++-function\n allocateMemoryForBuffer(module, args);\n\n // put data (just column(s)) to allocated buffers\n putDataToBuffer(module, args);\n\n // create array of parameters that are passed to C++-function\n let params = getArrOfWasmParams(args);\n\n //console.log('params:');\n //console.log(params);\n\n // create array of parameters' types that are passed to C++-function\n let types = getArrOfWasmTypes(args);\n \n //console.log('types:');\n //console.log(types);\n\n // call wasm-function\n let result = module.ccall(cppFuncName, returnType, types, params);\n \n //console.log(result);\n\n // get data from buffers (just column(s))\n getDataFromBuffer(module, args); \n\n // clear memory that was previousely allocated\n clearMemoryForBuffer(module, args);\n\n //console.log('done');\n\n return result;\n}\n\n// Get the required output.\n// It takes a specification of the function and the data computed\n// and extracts the required results.\nexport function getResult(funcSpecification, dataFromWebWorker) {\n funcSpecification.arguments._callResult = dataFromWebWorker.callResult; \n\n extractNewlyCreatedData(funcSpecification.arguments, dataFromWebWorker.args); \n\n let outPut = getOutput(funcSpecification);\n\n // Below, we remove newly created column(s), which are created at the extraction-step.\n // It is especially required, when multiple call of wasm-functions in webworker.\n clearNewlyCreatedData(funcSpecification.arguments);\n\n return outPut;\n}","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\n// Inputs correctness check tools\n\n//Limitation constants\nconst COMP_MIN = 1;\nconst SAMPLES_COUNT_MIN = 1;\nconst FEATURES_COUNT_MIN = 1;\nconst PERCENTAGE_MIN = 0;\nconst PERCENTAGE_MAX = 100;\nconst MAX_ELEMENTS_COUNT = 100000000;\n\n// Error messages\nconst COMP_POSITVE_MES = 'components must be positive.';\nconst COMP_EXCESS = 'components must not be greater than features count.';\nconst INCORERRECT_MIN_MAX_MES = 'min must be less than max.';\nconst INCORERRECT_FEATURES_MES = 'features must be positive.';\nconst INCORERRECT_SAMPLES_MES = 'samples must be positive.';\nconst INCORERRECT_PERCENTAGE_MES = 'violators percentage must be from the range from 0 to 100.';\nconst DATAFRAME_IS_TOO_BIG_MES = 'dataframe is too big.';\nconst UNSUPPORTED_COLUMN_TYPE_MES = 'unsupported column type: ';\nconst INCORRECT_MIN_DIST_MES = 'min distance must be positive.';\nconst INCORRECT_SPREAD_MES = 'spread must be positive.';\nconst INCORRECT_EPOCH_MES = 'number of epoch must be at least 1.';\nconst INCORRECT_NEIBORS_MES = 'number of neibors must be at least 2 and not greater than samples count.';\nconst INCORRECT_ITERATIONS_MES = 'number of iterations must be at least 1.';\nconst INCORRECT_LEARNING_RATE_MES = 'learning rate must be positive.';\nconst INCORRECT_PERPLEXITY_MES = 'perplexity must be at least 2 and not greater than samples count.';\nconst INCORRECT_STEPS_MES = 'steps must be non-negative.';\nconst INCORRECT_CYCLES_MES = 'cycles must be positive.';\nconst INCORRECT_CUTOFF_MES = 'cutoff must be non-negative.';\n\n/** Check column type */\nexport function checkColumnType(col: DG.Column): void {\n if ((col.type != DG.COLUMN_TYPE.FLOAT) && (col.type != DG.COLUMN_TYPE.INT))\n throw new Error(UNSUPPORTED_COLUMN_TYPE_MES + col.type);\n}\n\n/** Check missing values */\nexport function checkMissingVals(col: DG.Column): void {\n if (col.stats.missingValueCount > 0 )\n throw new Error(`The column '${col.name}' has missing values.`);\n}\n\n// Check dimension reducer inputs\nexport function checkDimensionReducerInputs(features: DG.ColumnList, components: number): void {\n if (components < COMP_MIN)\n throw new Error(COMP_POSITVE_MES);\n\n if (components > features.length)\n throw new Error(COMP_EXCESS);\n\n for (const col of features) {\n checkColumnType(col);\n checkMissingVals(col);\n }\n}\n\n// Check UMAP inputs\nexport function checkUMAPinputs(features: DG.ColumnList, components: number, epochs: number,\n neighbors: number, minDist: number, spread: number): void {\n // General dim reducer checks\n checkDimensionReducerInputs(features, components);\n\n // Check data total size\n if (features.length * features.byIndex(0).length > MAX_ELEMENTS_COUNT)\n throw new Error(DATAFRAME_IS_TOO_BIG_MES);\n\n // UMAP specific checks\n\n if (minDist <= 0)\n throw new Error(INCORRECT_MIN_DIST_MES);\n\n if (spread <= 0)\n throw new Error(INCORRECT_SPREAD_MES);\n\n if (epochs < 1)\n throw new Error(INCORRECT_EPOCH_MES);\n\n if ((neighbors < 2) || (neighbors > features.byIndex(0).length))\n throw new Error(INCORRECT_NEIBORS_MES);\n}\n\n// Check t-SNE inputs\nexport function checkTSNEinputs(features: DG.ColumnList, components: number,\n learningRate: number, perplexity: number, iterations: number): void {\n // General dim reducer checks\n checkDimensionReducerInputs(features, components);\n\n // Check data total size\n if (features.length * features.byIndex(0).length > MAX_ELEMENTS_COUNT)\n throw new Error(DATAFRAME_IS_TOO_BIG_MES);\n\n // t-SNE specific checks\n\n if (learningRate < 0)\n throw new Error(INCORRECT_LEARNING_RATE_MES);\n\n if (iterations < 1)\n throw new Error(INCORRECT_ITERATIONS_MES);\n\n if ((perplexity < 2) || (perplexity > features.byIndex(0).length))\n throw new Error(INCORRECT_PERPLEXITY_MES);\n}\n\n// Check SPE inputs\nexport function checkSPEinputs(features: DG.ColumnList, dimension: number,\n steps: number, cycles: number, cutoff: number, lambda: number): void {\n // General dim reducer checks\n checkDimensionReducerInputs(features, dimension);\n\n // Check data total size\n if (features.length * features.byIndex(0).length > MAX_ELEMENTS_COUNT)\n throw new Error(DATAFRAME_IS_TOO_BIG_MES);\n\n // SPE specific checks\n\n if (steps < 0)\n throw new Error(INCORRECT_STEPS_MES);\n\n if (cycles <= 0)\n throw new Error(INCORRECT_CYCLES_MES);\n\n if (cutoff < 0)\n throw new Error(INCORRECT_CUTOFF_MES);\n\n if (lambda <= 0)\n throw new Error(INCORRECT_LEARNING_RATE_MES);\n}\n\n// Check wasm dimension reducer inputs\nexport function checkWasmDimensionReducerInputs(features: DG.ColumnList, components: number): void {\n // General dim reducer checks\n checkDimensionReducerInputs(features, components);\n\n // Check data total size\n if (features.length * features.byIndex(0).length > MAX_ELEMENTS_COUNT)\n throw new Error(DATAFRAME_IS_TOO_BIG_MES);\n}\n\n// Check inputs of data for SVM testing generator\nexport function checkGeneratorSVMinputs(samplesCount: number, featuresCount: number,\n min: number, max: number, violatorsPercentage: number): void {\n if (min >= max)\n throw new Error(INCORERRECT_MIN_MAX_MES);\n\n if (featuresCount < FEATURES_COUNT_MIN)\n throw new Error(INCORERRECT_FEATURES_MES);\n\n if (samplesCount < SAMPLES_COUNT_MIN)\n throw new Error(INCORERRECT_SAMPLES_MES);\n\n if ((violatorsPercentage < PERCENTAGE_MIN) || (violatorsPercentage > PERCENTAGE_MAX))\n throw new Error(INCORERRECT_PERCENTAGE_MES);\n}\n\n// Returns rows of column data\nexport function getRowsOfNumericalColumnns(columnList: DG.ColumnList): any[][] {\n const columns = columnList.toList();\n const rowCount = columns[0].length;\n const colCount = columns.length;\n\n const output = [] as any[][];\n\n for (let i = 0; i < rowCount; ++i)\n output.push(Array(colCount));\n\n for (let j = 0; j < colCount; ++j) {\n const col = columns[j];\n\n checkColumnType(col);\n\n const array = col.getRawData();\n\n for (let i = 0; i < rowCount; ++i)\n output[i][j] = array[i];\n }\n\n return output;\n}\n","// PLS specific constants\n\n/** Types of analysis using PLS */\nexport enum PLS_ANALYSIS {\n COMPUTE_COMPONENTS,\n PERFORM_MVA,\n DEMO,\n}\n\n/** Errors & warnings */\nexport enum ERROR_MSG {\n NO_DF = 'No dataframe is opened',\n NO_COLS = 'No numeric columns without missing values',\n ONE_COL = 'No columns to be used as features (just one numeric columns without missing values)',\n EMPTY_DF = 'Dataframe is empty',\n}\n\n/** Widget titles */\nexport enum TITLE {\n PREDICT = 'Predict',\n USING = 'Using',\n COMPONENTS = 'Components',\n PLS = 'PLS',\n MVA = 'Multivariate Analysis (PLS)',\n RUN = 'RUN',\n NAMES = 'Names',\n MODEL = 'Observed vs. Predicted',\n FEATURE = 'Feature',\n REGR_COEFS = 'Regression Coefficients',\n XLOADING = 'x.loading.p',\n LOADINGS = 'Loadings',\n XSCORE = 'x.score.t',\n YSCORE = 'y.score.u',\n SCORES = 'Scores',\n EXPL_VAR = 'Explained Variance',\n EXPLORE = 'Explore',\n FEATURES = 'Feature names',\n BROWSE = 'Browse',\n}\n\n/** Tooltips */\nexport enum HINT {\n PREDICT = 'Column with the response variable',\n FEATURES = 'Predictors (features)',\n COMPONENTS = 'Number of PLS components',\n PLS = 'Compute PLS components',\n MVA = 'Perform multivariate analysis',\n NAMES = 'Names of data samples',\n}\n\n/** Links to help */\nexport enum LINK {\n PLS = 'https://datagrok.ai/help/explore/multivariate-analysis/pls#pls-components',\n MVA = 'https://datagrok.ai/help/explore/multivariate-analysis/pls',\n MODEL = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/predicted-vs-reference',\n COEFFS = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/regression-coefficients',\n LOADINGS = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/loadings',\n EXPL_VARS = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/explained-variance',\n SCORES = 'https://datagrok.ai/help/explore/multivariate-analysis/plots/scores',\n}\n\n/** Components consts */\nexport enum COMPONENTS {\n DEFAULT = 3,\n MIN = 1,\n}\n\n/** Items used for naming results */\nexport enum RESULT_NAMES {\n PREFIX = 'PLS',\n SUFFIX = '(predicted)',\n COMP = 'component',\n COMPS = 'components',\n}\n\n/** Indeces of wasm-computation output */\nexport enum WASM_OUTPUT_IDX {\n PREDICTION = 0,\n REGR_COEFFS = 1,\n T_SCORES = 2,\n U_SCORES = 3,\n X_LOADINGS = 4,\n Y_LOADINGS = 5,\n}\n\nexport const INT = 'Int';\nexport const TIMEOUT = 6;\nexport const RADIUS = [0.49, 0.79, 0.99];\nexport const LINE_WIDTH = 1;\nexport const X_COORD = 200;\nexport const Y_COORD = 200;\nexport const DELAY = 2000;\n\n/** Curves colors */\nexport enum COLOR {\n AXIS = '#838383',\n CIRCLE = '#0000FF',\n};\n\n/** Intro markdown for demo app */\nexport const DEMO_INTRO_MD = `# Data\nEach car has many features - patterns extraction is complicated.\n\n# Model\nPredict car price by its other features.\n\n# Try\nPress 'RUN' to perform multivariate analysis using partial least squares\n([PLS](https://en.wikipedia.org/wiki/Partial_least_squares_regression)) regression.\n\n# Essence\nThe method finds the latent factors that\n\n* capture the maximum variance in the features\n* maximize correlation with the response variable`;\n\n/** Description of demo results: wizard components */\nexport const DEMO_RESULTS = [\n {\n caption: TITLE.MODEL,\n text: 'Closer to the line means better price prediction.',\n },\n {\n caption: TITLE.SCORES,\n text: 'The latent factor values for each sample reflect the similarities and dissimilarities among observations.',\n },\n {\n caption: TITLE.LOADINGS,\n text: 'The impact of each feature on the latent factors: higher loading means stronger influence.',\n },\n {\n caption: TITLE.REGR_COEFS,\n text: 'Parameters of the obtained linear model: features make different contribution to the prediction.',\n },\n {\n caption: TITLE.EXPL_VAR,\n text: 'How well the latent components fit source data: closer to one means better fit.',\n },\n];\n\n/** Form results markdown for demo app */\nexport const DEMO_RESULTS_MD = DEMO_RESULTS.map((item) => `# ${item.caption}\\n\\n${item.text}`)\n .join('\\n\\n') + `\\n\\n# Learn more\n \n * [Multivariate analysis](${LINK.MVA}),\n * [ANOVA](https://datagrok.ai/help/explore/anova)`;\n","// Exploratory data analysis (EDA) tools\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {_principalComponentAnalysisInWebWorker,\n _partialLeastSquareRegressionInWebWorker} from '../wasm/EDAAPI';\n\nimport {checkWasmDimensionReducerInputs, checkUMAPinputs, checkTSNEinputs,\n getRowsOfNumericalColumnns} from './utils';\n\n// Principal components analysis (PCA)\nexport async function computePCA(table: DG.DataFrame, features: DG.ColumnList, components: number,\n center: boolean, scale: boolean): Promise<DG.DataFrame> {\n checkWasmDimensionReducerInputs(features, components);\n\n const centerNum = center ? 1 : 0;\n const scaleNum = scale ? 1 : 0;\n\n return await _principalComponentAnalysisInWebWorker(table, features, components, centerNum, scaleNum);\n}\n\n// Partial least square regression (PLS): TO REMOVE\nexport async function computePLS(\n table: DG.DataFrame, features: DG.ColumnList, predict: DG.Column, components: number,\n): Promise<any> {\n // Inputs are checked in the same manner as in PCA, since the same computations are applied.\n checkWasmDimensionReducerInputs(features, components);\n\n return await _partialLeastSquareRegressionInWebWorker(table, features, predict, components);\n}\n\n// Uniform Manifold Approximation and Projection (UMAP)\nexport async function computeUMAP(features: DG.ColumnList, components: number, epochs: number,\n neighbors: number, minDist: number, spread: number): Promise<DG.DataFrame> {\n // check inputs\n checkUMAPinputs(features, components, epochs, neighbors, minDist, spread);\n\n // get row-by-row data\n const data = getRowsOfNumericalColumnns(features);\n\n let workerOutput: any;\n\n // UMAP in webworker\n const promise = new Promise((resolve, _reject) => {\n const worker = new Worker(new URL('workers/umap-worker.ts', import.meta.url));\n\n worker.postMessage({\n data: data,\n options: {\n nComponents: components,\n nEpochs: epochs,\n nNeighbors: neighbors,\n minDist: minDist,\n spread: spread,\n }});\n\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(e.data.embeddings);\n };\n });\n\n await promise.then(\n (result) => {workerOutput = result;},\n (_error) => {throw new Error('applying UMAP fails.');},\n );\n\n const embeddings = workerOutput as number[][];\n const rowCount = embeddings.length;\n const range = [...Array(components).keys()];\n\n // Create output\n\n // columns data\n const umapColumnsData = range.map((_) => new Float32Array(rowCount));\n\n // perform transponation\n for (let i = 0; i < rowCount; ++i) {\n for (let j = 0; j < components; ++j)\n umapColumnsData[j][i] = embeddings[i][j];\n }\n\n return DG.DataFrame.fromColumns(range.map((i) =>\n DG.Column.fromFloat32Array('UMAP' + i.toString(), umapColumnsData[i]),\n ));\n} // computeUMAP\n\n// t-distributed stochastic neighbor embedding (t-SNE)\nexport async function computeTSNE(features: DG.ColumnList, components: number,\n learningRate: number, perplexity: number, iterations: number): Promise<DG.DataFrame> {\n // check inputs\n checkTSNEinputs(features, components, learningRate, perplexity, iterations);\n\n // get row-by-row data\n const data = getRowsOfNumericalColumnns(features);\n\n let workerOutput: any;\n\n // t-SNE in webworker\n const promise = new Promise((resolve, _reject) => {\n const worker = new Worker(new URL('workers/tsne-worker.ts', import.meta.url));\n\n worker.postMessage({\n data: data,\n options: {\n learningRate: learningRate,\n perplexity: perplexity,\n components: components,\n iterations: iterations,\n }});\n\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(e.data.embeddings);\n };\n });\n\n await promise.then(\n (result) => {workerOutput = result;},\n (_error) => {throw new Error('applying t-SNE fails.');},\n );\n\n const embeddings = workerOutput as any[];\n\n const rowCount = embeddings.length;\n const range = [...Array(components).keys()];\n\n // Create output\n\n // columns data\n const umapColumnsData = range.map((_) => new Float32Array(rowCount));\n\n // perform transponation\n for (let i = 0; i < rowCount; ++i) {\n for (let j = 0; j < components; ++j)\n umapColumnsData[j][i] = embeddings[i][j];\n }\n\n return DG.DataFrame.fromColumns(range.map((i) =>\n DG.Column.fromFloat32Array('tSNE' + i.toString(), umapColumnsData[i]),\n ));\n} // computeTSNE\n","// The following code is generated automatically.\n// JavaScript API for call wasm-functions from the module EDA\n\n// Imports for call wasm runtime-system: in the main stream and in webworkers\nimport {callWasm} from '../wasm/callWasm';\nimport {getCppInput, getResult} from '../wasm/callWasmForWebWorker';\n\nexport async function _initEDAAPI() {\n await initEDA();\n}\n\nexport function _principalComponentAnalysis(table, columns, componentsCount, centerNum, scaleNum) {\n return callWasm(EDA, 'principalComponentAnalysis', [columns, componentsCount, centerNum, scaleNum]);\n}\n\nexport async function _principalComponentAnalysisInWebWorker(table, columns, componentsCount, centerNum, scaleNum) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/principalComponentAnalysisWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['principalComponentAnalysis'].arguments,[columns, componentsCount, centerNum, scaleNum]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['principalComponentAnalysis'], e.data));\n }\n });\n}\n\nexport function _error(df, col1, col2) {\n return callWasm(EDA, 'error', [col1, col2]);\n}\n\nexport async function _errorInWebWorker(df, col1, col2) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/errorWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['error'].arguments,[col1, col2]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['error'], e.data));\n }\n });\n}\n\nexport function _partialLeastSquareRegression(table, features, predict, componentsCount) {\n return callWasm(EDA, 'partialLeastSquareRegression', [features, predict, componentsCount]);\n}\n\nexport async function _partialLeastSquareRegressionInWebWorker(table, features, predict, componentsCount) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/partialLeastSquareRegressionWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['partialLeastSquareRegression'].arguments,[features, predict, componentsCount]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['partialLeastSquareRegression'], e.data));\n }\n });\n}\n\nexport function _generateDataset(kernel, kernelParams, samplesCount, featuresCount, min, max, violatorsPercentage) {\n return callWasm(EDA, 'generateDataset', [kernel, kernelParams, samplesCount, featuresCount, min, max, violatorsPercentage]);\n}\n\nexport async function _generateDatasetInWebWorker(kernel, kernelParams, samplesCount, featuresCount, min, max, violatorsPercentage) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/generateDatasetWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['generateDataset'].arguments,[kernel, kernelParams, samplesCount, featuresCount, min, max, violatorsPercentage]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['generateDataset'], e.data));\n }\n });\n}\n\nexport function _normalizeDataset(data) {\n return callWasm(EDA, 'normalizeDataset', [data]);\n}\n\nexport async function _normalizeDatasetInWebWorker(data) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/normalizeDatasetWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['normalizeDataset'].arguments,[data]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['normalizeDataset'], e.data));\n }\n });\n}\n\nexport function _trainLSSVM(gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, dataset, labels) {\n return callWasm(EDA, 'trainLSSVM', [gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, dataset, labels]);\n}\n\nexport async function _trainLSSVMInWebWorker(gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, dataset, labels) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/trainLSSVMWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['trainLSSVM'].arguments,[gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, dataset, labels]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['trainLSSVM'], e.data));\n }\n });\n}\n\nexport function _predictByLSSVM(kernel, kernelParams, normalizedData, labels, means, stdDevs, modelParams, precomputedWeights, targetData) {\n return callWasm(EDA, 'predictByLSSVM', [kernel, kernelParams, normalizedData, labels, means, stdDevs, modelParams, precomputedWeights, targetData]);\n}\n\nexport async function _predictByLSSVMInWebWorker(kernel, kernelParams, normalizedData, labels, means, stdDevs, modelParams, precomputedWeights, targetData) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/predictByLSSVMWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['predictByLSSVM'].arguments,[kernel, kernelParams, normalizedData, labels, means, stdDevs, modelParams, precomputedWeights, targetData]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['predictByLSSVM'], e.data));\n }\n });\n}\n\nexport function _trainAndAnalyzeLSSVM(gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, confusionMatrixElementsCount, dataset, labels) {\n return callWasm(EDA, 'trainAndAnalyzeLSSVM', [gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, confusionMatrixElementsCount, dataset, labels]);\n}\n\nexport async function _trainAndAnalyzeLSSVMInWebWorker(gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, confusionMatrixElementsCount, dataset, labels) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/trainAndAnalyzeLSSVMWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['trainAndAnalyzeLSSVM'].arguments,[gamma, kernel, kernelParams, modelParamsCount, precomputedWeightsCount, confusionMatrixElementsCount, dataset, labels]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['trainAndAnalyzeLSSVM'], e.data));\n }\n });\n}\n\nexport function _fitLinearRegressionParamsWithDataNormalizing(features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, paramsCount) {\n return callWasm(EDA, 'fitLinearRegressionParamsWithDataNormalizing', [features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, paramsCount]);\n}\n\nexport async function _fitLinearRegressionParamsWithDataNormalizingInWebWorker(features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, paramsCount) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/fitLinearRegressionParamsWithDataNormalizingWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['fitLinearRegressionParamsWithDataNormalizing'].arguments,[features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, paramsCount]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['fitLinearRegressionParamsWithDataNormalizing'], e.data));\n }\n });\n}\n\nexport function _fitLinearRegressionParams(features, targets, paramsCount) {\n return callWasm(EDA, 'fitLinearRegressionParams', [features, targets, paramsCount]);\n}\n\nexport async function _fitLinearRegressionParamsInWebWorker(features, targets, paramsCount) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/fitLinearRegressionParamsWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['fitLinearRegressionParams'].arguments,[features, targets, paramsCount]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['fitLinearRegressionParams'], e.data));\n }\n });\n}\n\nexport function _fitSoftmax(features, featureAvgs, featureStdDevs, targets, classesCount, iterCount, learningRate, penalty, tolerance, paramsRows, paramsCols) {\n return callWasm(EDA, 'fitSoftmax', [features, featureAvgs, featureStdDevs, targets, classesCount, iterCount, learningRate, penalty, tolerance, paramsRows, paramsCols]);\n}\n\nexport async function _fitSoftmaxInWebWorker(features, featureAvgs, featureStdDevs, targets, classesCount, iterCount, learningRate, penalty, tolerance, paramsRows, paramsCols) {\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('../wasm/workers/fitSoftmaxWorker.js', import.meta.url));\n worker.postMessage(getCppInput(EDA['fitSoftmax'].arguments,[features, featureAvgs, featureStdDevs, targets, classesCount, iterCount, learningRate, penalty, tolerance, paramsRows, paramsCols]));\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(getResult(EDA['fitSoftmax'], e.data));\n }\n });\n}\n\n","// Tools for multivariate analysis by PLS\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {PLS_ANALYSIS, ERROR_MSG, TITLE, HINT, LINK, COMPONENTS, INT, TIMEOUT,\n RESULT_NAMES, WASM_OUTPUT_IDX, RADIUS, LINE_WIDTH, COLOR, X_COORD, Y_COORD,\n DEMO_INTRO_MD, DEMO_RESULTS_MD, DEMO_RESULTS} from './pls-constants';\nimport {checkWasmDimensionReducerInputs, checkColumnType, checkMissingVals} from '../utils';\nimport {_partialLeastSquareRegressionInWebWorker} from '../../wasm/EDAAPI';\nimport {carsDataframe} from '../data-generators';\n\nconst min = Math.min;\nconst max = Math.max;\n\n/** PLS analysis results */\nexport type PlsOutput = {\n prediction: DG.Column<DG.COLUMN_TYPE.FLOAT>,\n regressionCoefficients: DG.Column<DG.COLUMN_TYPE.FLOAT>,\n tScores: DG.Column<DG.COLUMN_TYPE.FLOAT>[],\n uScores: DG.Column<DG.COLUMN_TYPE.FLOAT>[],\n xLoadings: DG.Column<DG.COLUMN_TYPE.FLOAT>[],\n yLoadings: DG.Column<DG.COLUMN_TYPE.FLOAT>,\n};\n\n/** PLS analysis input */\nexport type PlsInput = {\n table: DG.DataFrame,\n features: DG.ColumnList,\n predict: DG.Column,\n components: number,\n names : DG.Column | undefined,\n};\n\n/** Return lines */\nexport function getLines(names: string[]): DG.FormulaLine[] {\n const lines: DG.FormulaLine[] = [];\n\n const addLine = (formula: string, radius: number) => {\n lines.push({\n type: 'line',\n formula: formula,\n width: LINE_WIDTH,\n visible: true,\n title: ' ',\n min: -radius,\n max: radius,\n color: COLOR.CIRCLE,\n });\n };\n\n names.forEach((xName) => {\n const x = '${' + xName + '}';\n lines.push({type: 'line', formula: `${x} = 0`, width: LINE_WIDTH, visible: true, title: ' ', color: COLOR.AXIS});\n\n names.forEach((yName) => {\n const y = '${' + yName + '}';\n\n RADIUS.forEach((r) => {\n addLine(y + ` = sqrt(${r*r} - ${x} * ${x})`, r);\n addLine(y + ` = -sqrt(${r*r} - ${x} * ${x})`, r);\n });\n });\n });\n\n return lines;\n}\n\n/** Partial least square regression (PLS) */\nexport async function getPlsAnalysis(input: PlsInput): Promise<PlsOutput> {\n checkWasmDimensionReducerInputs(input.features, input.components);\n\n // Check the responce column\n checkColumnType(input.predict);\n checkMissingVals(input.predict);\n\n const result = await _partialLeastSquareRegressionInWebWorker(\n input.table,\n input.features,\n input.predict,\n input.components,\n );\n\n return {\n prediction: result[WASM_OUTPUT_IDX.PREDICTION],\n regressionCoefficients: result[WASM_OUTPUT_IDX.REGR_COEFFS],\n tScores: result[WASM_OUTPUT_IDX.T_SCORES],\n uScores: result[WASM_OUTPUT_IDX.U_SCORES],\n xLoadings: result[WASM_OUTPUT_IDX.X_LOADINGS],\n yLoadings: result[WASM_OUTPUT_IDX.Y_LOADINGS],\n };\n}\n\n/** Return debiased predction by PLS regression */\nfunction debiasedPrediction(features: DG.ColumnList, params: DG.Column,\n target: DG.Column, biasedPrediction: DG.Column): DG.Column {\n const samples = target.length;\n const dim = features.length;\n const rawParams = params.getRawData();\n const debiased = new Float32Array(samples);\n const biased = biasedPrediction.getRawData();\n\n // Compute bias\n let bias = target.stats.avg;\n for (let i = 0; i < dim; ++i)\n bias -= rawParams[i] * features.byIndex(i).stats.avg;\n\n // Compute debiased prediction\n for (let i = 0; i < samples; ++i)\n debiased[i] = bias + biased[i];\n\n return DG.Column.fromFloat32Array('Debiased', debiased, samples);\n}\n\n/** Perform multivariate analysis using the PLS regression */\nasync function performMVA(input: PlsInput, analysisType: PLS_ANALYSIS): Promise<void> {\n const result = await getPlsAnalysis(input);\n\n const plsCols = result.tScores;\n const cols = input.table.columns;\n const features = input.features;\n const featuresNames = features.names();\n const prefix = (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS) ? RESULT_NAMES.PREFIX : TITLE.XSCORE;\n\n // add PLS components to the table\n plsCols.forEach((col, idx) => {\n col.name = cols.getUnusedName(`${prefix}${idx + 1}`);\n cols.add(col);\n });\n\n if (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS)\n return;\n\n //const view = grok.shell.tableView(input.table.name);\n\n const view = (analysisType === PLS_ANALYSIS.DEMO) ?\n (grok.shell.view(TITLE.BROWSE) as DG.BrowseView).preview as DG.TableView :\n grok.shell.tableView(input.table.name);\n\n // 0.1 Buffer table\n const buffer = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLE.FEATURE, featuresNames),\n result.regressionCoefficients,\n ]);\n\n // 0.2. Add X-Loadings\n result.xLoadings.forEach((col, idx) => {\n col.name = buffer.columns.getUnusedName(`${TITLE.XLOADING}${idx + 1}`);\n buffer.columns.add(col);\n });\n\n // 1. Predicted vs Reference scatter plot\n // Debias prediction (since PLS center data)\n const pred = debiasedPrediction(features, result.regressionCoefficients, input.predict, result.prediction);\n pred.name = cols.getUnusedName(`${input.predict.name} ${RESULT_NAMES.SUFFIX}`);\n cols.add(pred);\n const predictVsReferScatter = view.addViewer(DG.Viewer.scatterPlot(input.table, {\n title: TITLE.MODEL,\n xColumnName: input.predict.name,\n yColumnName: pred.name,\n showRegressionLine: true,\n markerType: DG.MARKER_TYPE.CIRCLE,\n labels: input.names?.name,\n help: LINK.MODEL,\n }));\n\n // 2. Regression Coefficients Bar Chart\n result.regressionCoefficients.name = TITLE.REGR_COEFS;\n const regrCoeffsBar = view.addViewer(DG.Viewer.barChart(buffer, {\n title: TITLE.REGR_COEFS,\n splitColumnName: TITLE.FEATURE,\n valueColumnName: result.regressionCoefficients.name,\n valueAggrType: DG.AGG.AVG,\n help: LINK.COEFFS,\n showValueSelector: false,\n showStackSelector: false,\n }));\n\n // 3. Loadings Scatter Plot\n result.xLoadings.forEach((col, idx) => col.name = `${TITLE.XLOADING}${idx + 1}`);\n const loadingsScatter = view.addViewer(DG.Viewer.scatterPlot(buffer, {\n title: TITLE.LOADINGS,\n xColumnName: `${TITLE.XLOADING}1`,\n yColumnName: `${TITLE.XLOADING}${result.xLoadings.length > 1 ? '2' : '1'}`,\n markerType: DG.MARKER_TYPE.CIRCLE,\n labels: TITLE.FEATURE,\n help: LINK.LOADINGS,\n }));\n\n // 4. Scores Scatter Plot\n\n // 4.1) data\n const scoreNames = plsCols.map((col) => col.name);\n result.uScores.forEach((col, idx) => {\n col.name = cols.getUnusedName(`${TITLE.YSCORE}${idx + 1}`);\n cols.add(col);\n scoreNames.push(col.name);\n });\n\n // 4.2) create scatter\n const scoresScatter = DG.Viewer.scatterPlot(input.table, {\n title: TITLE.SCORES,\n xColumnName: plsCols[0].name,\n yColumnName: (plsCols.length > 1) ? plsCols[1].name : result.uScores[0].name,\n markerType: DG.MARKER_TYPE.CIRCLE,\n labels: input.names?.name,\n help: LINK.SCORES,\n showViewerFormulaLines: true,\n });\n\n // 4.3) create lines & circles\n scoresScatter.meta.formulaLines.addAll(getLines(scoreNames));\n view.addViewer(scoresScatter);\n\n // 5. Explained Variances\n\n // 5.1) computation, source: the paper https://doi.org/10.1002/cem.2589\n // here, we use notations from this paper\n const q = result.yLoadings.getRawData();\n const p = result.xLoadings.map((col) => col.getRawData());\n const n = input.table.rowCount;\n const m = featuresNames.length;\n const A = input.components;\n const yExplVars = new Float32Array(A);\n const compNames = [] as string[];\n const xExplVars: Float32Array[] = [];\n for (let i = 0; i < m; ++i)\n xExplVars.push(new Float32Array(A));\n\n yExplVars[0] = q[0]**2 / n;\n compNames.push(`1 ${RESULT_NAMES.COMP}`);\n xExplVars.forEach((arr, idx) => {arr[0] = p[0][idx]**2 / n;});\n\n for (let comp = 1; comp < A; ++comp) {\n yExplVars[comp] = yExplVars[comp - 1] + q[comp]**2 / n;\n xExplVars.forEach((arr, idx) => arr[comp] = arr[comp - 1] + p[comp][idx]**2 / n);\n compNames.push(`${comp + 1} ${RESULT_NAMES.COMPS}`);\n }\n\n // 5.2) create df\n const explVarsDF = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLE.COMPONENTS, compNames),\n DG.Column.fromFloat32Array(input.predict.name, yExplVars),\n ]);\n\n xExplVars.forEach((arr, idx) => explVarsDF.columns.add(DG.Column.fromFloat32Array(featuresNames[idx], arr)));\n\n // 5.3) bar chart\n const explVarsBar = view.addViewer(DG.Viewer.barChart(explVarsDF, {\n title: TITLE.EXPL_VAR,\n splitColumnName: TITLE.COMPONENTS,\n valueColumnName: input.predict.name,\n valueAggrType: DG.AGG.AVG,\n help: LINK.EXPL_VARS,\n showCategorySelector: false,\n showStackSelector: false,\n }));\n\n // emphasize viewers in the demo case\n if (analysisType === PLS_ANALYSIS.DEMO) {\n const pages = [predictVsReferScatter, scoresScatter, loadingsScatter, regrCoeffsBar, explVarsBar]\n .map((viewer, idx) => {\n return {\n text: DEMO_RESULTS[idx].text,\n showNextTo: viewer.root,\n };\n });\n\n const wizard = ui.hints.addTextHint({title: TITLE.EXPLORE, pages: pages});\n wizard.helpUrl = LINK.MVA;\n grok.shell.windows.help.showHelp(ui.markdown(DEMO_RESULTS_MD));\n }\n} // performMVA\n\n/** Run multivariate analysis (PLS) */\nexport async function runMVA(analysisType: PLS_ANALYSIS): Promise<void> {\n const table = (analysisType === PLS_ANALYSIS.DEMO) ?\n ((grok.shell.view(TITLE.BROWSE) as DG.BrowseView).preview as DG.TableView).table :\n grok.shell.t;\n\n if (table === null) {\n grok.shell.warning(ERROR_MSG.NO_DF);\n return;\n }\n\n if (table.rowCount === 0) {\n grok.shell.warning(ERROR_MSG.EMPTY_DF);\n return;\n }\n\n const numColNames = [] as string[];\n const numCols = [] as DG.Column[];\n const strCols = [] as DG.Column[];\n\n const isValidNumeric = (col: DG.Column) =>\n ((col.type === DG.COLUMN_TYPE.INT) || (col.type === DG.COLUMN_TYPE.FLOAT)) &&\n (col.stats.missingValueCount === 0);\n\n table.columns.toList().forEach((col) => {\n if (isValidNumeric(col)) {\n numColNames.push(col.name);\n numCols.push(col);\n } else if (col.type === DG.COLUMN_TYPE.STRING)\n strCols.push(col);\n });\n\n if (numColNames.length === 0) {\n grok.shell.warning(ERROR_MSG.NO_COLS);\n return;\n }\n\n if (numColNames.length === 1) {\n grok.shell.warning(ERROR_MSG.ONE_COL);\n return;\n }\n\n // responce (to predict)\n let predict = numCols[numCols.length - 1];\n const predictInput = ui.input.column(TITLE.PREDICT, {table: table, value: predict, onValueChanged: (value) => {\n predict = value;\n updateIputs();\n }, filter: (col: DG.Column) => isValidNumeric(col)},\n );\n predictInput.setTooltip(HINT.PREDICT);\n\n // predictors (features)\n let features: DG.Column[];\n const featuresInput = ui.input.columns(TITLE.USING, {table: table, available: numColNames});\n featuresInput.onInput.subscribe(() => updateIputs());\n featuresInput.setTooltip(HINT.FEATURES);\n\n // components count\n let components = min(numColNames.length - 1, COMPONENTS.DEFAULT as number);\n const componentsInput = ui.input.forProperty(DG.Property.fromOptions({\n name: TITLE.COMPONENTS,\n inputType: INT,\n defaultValue: components,\n //@ts-ignore\n showPlusMinus: true,\n min: COMPONENTS.MIN,\n }));\n componentsInput.onInput.subscribe(() => updateIputs());\n componentsInput.setTooltip(HINT.COMPONENTS);\n\n let dlgTitle: string;\n let dlgHelpUrl: string;\n let dlgRunBtnTooltip: string;\n\n if (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS) {\n dlgTitle = TITLE.PLS;\n dlgHelpUrl = LINK.PLS;\n dlgRunBtnTooltip = HINT.PLS;\n } else {\n dlgTitle = TITLE.MVA;\n dlgHelpUrl = LINK.MVA;\n dlgRunBtnTooltip = HINT.MVA;\n }\n\n const updateIputs = () => {\n featuresInput.value = featuresInput.value.filter((col) => col !== predict);\n features = featuresInput.value;\n\n componentsInput.value = min(max(componentsInput.value ?? components, COMPONENTS.MIN), features.length);\n components = componentsInput.value;\n\n dlg.getButton(TITLE.RUN).disabled = (features.length === 0) || (components <= 0);\n };\n\n // names of samples\n let names = (strCols.length > 0) ? strCols[0] : undefined;\n const namesInputs = ui.input.column(TITLE.NAMES, {\n table: table,\n value: names,\n onValueChanged: () => names = predictInput.value ?? undefined,\n filter: (col: DG.Column) => col.type === DG.COLUMN_TYPE.STRING},\n );\n namesInputs.setTooltip(HINT.NAMES);\n namesInputs.root.hidden = (strCols.length === 0) || (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS);\n\n const dlg = ui.dialog({title: dlgTitle, helpUrl: dlgHelpUrl})\n .add(ui.form([predictInput, featuresInput, componentsInput, namesInputs]))\n .addButton(TITLE.RUN, async () => {\n dlg.close();\n\n await performMVA({\n table: table,\n features: DG.DataFrame.fromColumns(features).columns,\n predict: predict,\n components: components,\n names: names,\n }, analysisType);\n }, undefined, dlgRunBtnTooltip)\n .show({x: X_COORD, y: Y_COORD});\n\n // the following delay provides correct styles (see https://reddata.atlassian.net/browse/GROK-15196)\n setTimeout(() => {\n featuresInput.value = numCols.filter((col) => col !== predict);\n features = featuresInput.value;\n }, TIMEOUT);\n\n grok.shell.v.append(dlg.root);\n} // runMVA\n\n/** Run multivariate analysis demo */\nexport async function runDemoMVA(): Promise<void> {\n grok.shell.addTableView(carsDataframe());\n grok.shell.windows.help.visible = true;\n grok.shell.windows.help.showHelp(ui.markdown(DEMO_INTRO_MD));\n grok.shell.windows.showContextPanel = false;\n grok.shell.windows.showProperties = false;\n\n await runMVA(PLS_ANALYSIS.DEMO);\n}\n","// Regression tools\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {_fitLinearRegressionParamsWithDataNormalizing} from '../wasm/EDAAPI';\nimport {getPlsAnalysis} from './pls/pls-tools';\n\n// Default PLS components count\nconst PLS_COMPONENTS_COUNT = 10;\n\n/** Compute coefficients of linear regression */\nexport async function getLinearRegressionParams(features: DG.ColumnList, targets: DG.Column): Promise<Float32Array> {\n const featuresCount = features.length;\n const samplesCount = targets.length;\n\n const yAvg = targets.stats.avg;\n const yStdev = targets.stats.stdev;\n\n const params = new Float32Array(featuresCount + 1).fill(0);\n params[featuresCount] = yAvg;\n\n // The trivial case\n if ((yStdev === 0) || (samplesCount === 1))\n return params;\n\n try {\n // Analyze inputs sizes\n\n // Non-constant columns data\n const nonConstFeatureColsIndeces: number[] = [];\n const nonConstFeatureCols: DG.Column[] = [];\n const nonConstFeatureAvgs = new Float32Array(featuresCount);\n const nonConstFeatureStdevs = new Float32Array(featuresCount);\n\n let idx = 0;\n let nonConstFeaturesCount = 0;\n\n // Extract non-constant columns data\n for (const col of features) {\n const stats = col.stats;\n\n if (stats.stdev > 0) {\n nonConstFeatureColsIndeces.push(idx);\n nonConstFeatureCols.push(col);\n nonConstFeatureAvgs[nonConstFeaturesCount] = stats.avg;\n nonConstFeatureStdevs[nonConstFeaturesCount] = stats.stdev;\n ++nonConstFeaturesCount;\n }\n\n ++idx;\n }\n\n // The trivial case\n if (nonConstFeaturesCount === 0)\n return params;\n\n // Compute parameters of linear regression\n const tempParams = _fitLinearRegressionParamsWithDataNormalizing(\n DG.DataFrame.fromColumns(nonConstFeatureCols).columns,\n DG.Column.fromFloat32Array('xAvgs', nonConstFeatureAvgs, nonConstFeaturesCount),\n DG.Column.fromFloat32Array('xStdevs', nonConstFeatureStdevs, nonConstFeaturesCount),\n targets,\n yAvg,\n yStdev,\n nonConstFeaturesCount + 1,\n ).getRawData();\n\n // Extract params taking into account non-constant columns\n for (let i = 0; i < nonConstFeaturesCount; ++i)\n params[nonConstFeatureColsIndeces[i]] = tempParams[i];\n\n params[featuresCount] = tempParams[nonConstFeaturesCount];\n } catch (e) {\n // Apply PLS regression if regular linear regression failed\n const paramsByPLS = await getLinearRegressionParamsUsingPLS(\n features,\n targets,\n componentsCount(features.length, targets.length),\n );\n\n let tmpSum = 0;\n\n // Compute bias (due to the centering feature of PLS)\n for (let i = 0; i < featuresCount; ++i) {\n params[i] = paramsByPLS[i];\n tmpSum += paramsByPLS[i] * features.byIndex(i).stats.avg;\n }\n\n params[featuresCount] -= tmpSum;\n }\n\n return params;\n} // computeLinRegressionCoefs\n\n/** Return prediction of linear regression model */\nexport function getPredictionByLinearRegression(features: DG.ColumnList, params: Float32Array): DG.Column {\n const featuresCount = features.length;\n if (featuresCount !== params.length - 1)\n throw new Error('Incorrect parameters count');\n\n const col = features.byIndex(0);\n const samplesCount = col.length;\n const prediction = new Float32Array(samplesCount);\n\n let rawData = col.getRawData();\n const bias = params[featuresCount];\n let weight = params[0];\n\n for (let i = 0; i < samplesCount; ++i)\n prediction[i] = bias + weight * rawData[i];\n\n for (let j = 1; j < featuresCount; ++j) {\n rawData = features.byIndex(j).getRawData();\n weight = params[j];\n\n for (let i = 0; i < samplesCount; ++i)\n prediction[i] += weight * rawData[i];\n }\n\n return DG.Column.fromFloat32Array(\n features.getUnusedName('prediction'),\n prediction,\n samplesCount,\n );\n} // getPredictionByLinearRegression\n\n/** Generate test dataset */\nexport function getTestDatasetForLinearRegression(rowCount: number, colCount: number,\n featuresScale: number, featuresBias: number, paramsScale: number, paramsBias: number): DG.DataFrame {\n const df = grok.data.demo.randomWalk(rowCount, colCount + 1);\n const cols = df.columns;\n const noiseCol = cols.byIndex(colCount);\n noiseCol.name = 'y (noisy)';\n const yNoisy = noiseCol.getRawData();\n const y = new Float32Array(rowCount).fill(paramsBias);\n\n let idx = 0;\n let scale = 0;\n let bias = 0;\n let weight = 0;\n\n for (const col of cols) {\n col.name = `x${idx}`;\n scale = Math.random() * featuresScale;\n bias = Math.random() * featuresBias;\n const arr = col.getRawData();\n weight = Math.random() * paramsScale;\n\n for (let j = 0; j < rowCount; ++j) {\n arr[j] = scale * arr[j] + bias;\n y[j] += arr[j] * weight;\n }\n\n ++idx;\n\n if (idx === colCount)\n break;\n }\n\n scale = Math.random() * featuresScale;\n bias = Math.random() * featuresBias;\n\n for (let j = 0; j < rowCount; ++j)\n yNoisy[j] = scale * yNoisy[j] + y[j];\n\n cols.add(DG.Column.fromFloat32Array('y', y, rowCount));\n\n return df;\n} // getTestDatasetForLinearRegression\n\n/** Reteurn linear regression params using the PLS method */\nasync function getLinearRegressionParamsUsingPLS(features: DG.ColumnList,\n targets: DG.Column, components: number): Promise<Float32Array> {\n const plsAnalysis = await getPlsAnalysis({\n table: DG.DataFrame.fromColumns([targets]),\n features: features,\n predict: targets,\n components: components,\n names: undefined,\n });\n\n return plsAnalysis.regressionCoefficients.getRawData() as Float32Array;\n}\n\n/** Return number of PLS components to be used */\nconst componentsCount = (featuresCount: number, samplesCount: number) => {\n if (samplesCount <= featuresCount)\n return Math.min(PLS_COMPONENTS_COUNT, samplesCount);\n\n return Math.min(PLS_COMPONENTS_COUNT, featuresCount);\n};\n","// Predicitve tools based on the PLS method\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {TITLE, RESULT_NAMES} from './pls-constants';\nimport {getPlsAnalysis, PlsOutput, getLines} from './pls-tools';\nimport {LINK} from './pls-constants';\nimport {getPredictionByLinearRegression} from '../regression';\n\n// PLS ML specific constants\nconst EXTRA_ROWS = 1;\nconst SHIFT = 2;\nconst MIN_LOADINGS = 1;\nconst MIN_COLS_COUNT = SHIFT + MIN_LOADINGS;\nconst SIZE_ARR_LEN = 2;\nconst MODEL_IDX = 0;\nconst SCORES_IDX = 1;\nconst BYTES_PER_SIZES = SIZE_ARR_LEN * 4;\nconst BLOCK_SIZE = 64;\n\n/** Interactivity tresholds */\nenum INTERACTIVITY {\n MAX_SAMLPES = 100000,\n MAX_FEATURES = 1000,\n};\n\n/** Model specification */\ntype PlsModelSpecification = {\n params: Float32Array,\n names: string[],\n loadings: Float32Array[],\n dim: number,\n components: number,\n scores: DG.DataFrame,\n}\n\n/** PLS regression modeling tool */\nexport class PlsModel {\n /** Check applicability */\n static isApplicable(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n for (const col of features) {\n if (!col.matches('numerical'))\n return false;\n }\n if (!predictColumn.matches('numerical'))\n return false;\n\n return true;\n }\n\n /** Check interactivity */\n static isInteractive(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n return (features.length <= INTERACTIVITY.MAX_FEATURES) &&\n (predictColumn.length <= INTERACTIVITY.MAX_SAMLPES);\n }\n\n /** Specification of the PLS model */\n private specn: PlsModelSpecification | null = null;\n\n constructor(packedModel?: Uint8Array) {\n if (packedModel) {\n try {\n // Extract model's bytes count\n const sizeArr = new Uint32Array(packedModel.buffer, 0, SIZE_ARR_LEN); // 1-st element is a size of model bytes\n const modelDfBytesCount = sizeArr[MODEL_IDX];\n const scoresDfBytesCount = sizeArr[SCORES_IDX];\n\n // Model's bytes\n const modelBytes = new Uint8Array(packedModel.buffer, BYTES_PER_SIZES, modelDfBytesCount);\n\n // Model as dataframe\n const modelDf = DG.DataFrame.fromByteArray(modelBytes);\n const rowCount = modelDf.rowCount;\n const columns = modelDf.columns;\n const colsCount = columns.length;\n\n // Scores\n const scoresBytes = new Uint8Array(packedModel.buffer, BYTES_PER_SIZES + modelDfBytesCount, scoresDfBytesCount);\n const scores = DG.DataFrame.fromByteArray(scoresBytes);\n\n if (colsCount < MIN_COLS_COUNT)\n throw new Error('incorrect columns count');\n\n // Extract names of features\n const featureNames = columns.byName(TITLE.FEATURES).toList();\n\n // Extract parameters of the linear model\n const params = new Float32Array(rowCount);\n params.set(columns.byName(TITLE.REGR_COEFS).getRawData());\n\n // Extract loadings\n const components = colsCount - SHIFT;\n const loadings = new Array<Float32Array>(components);\n\n for (let i = 0; i < components; ++i) {\n loadings[i] = new Float32Array(rowCount);\n loadings[i].set(columns.byIndex(i + SHIFT).getRawData());\n }\n\n this.specn = {\n params: params,\n loadings: loadings,\n names: featureNames,\n dim: rowCount - EXTRA_ROWS,\n components: colsCount - SHIFT,\n scores: scores,\n };\n } catch (error) {\n throw new Error(`Failed to load model: ${(error instanceof Error ? error.message : 'the platform issue')}`);\n }\n }\n }\n\n /** Train model */\n public async fit(features: DG.ColumnList, target: DG.Column, components: number) {\n const analysis = await getPlsAnalysis({\n table: DG.DataFrame.fromColumns([target]),\n features: features,\n predict: target,\n components: components,\n names: undefined,\n });\n\n // 1. Names of features\n const featureNames = features.names();\n featureNames.push('_'); // add extra item\n\n // 2. Regression coefficients\n const params = this.getRegrCoeffs(features, target, analysis.regressionCoefficients);\n\n // 3. Loadings\n const loadings = this.getLoadings(components, analysis.xLoadings);\n\n // 4. Model specification\n this.specn = {\n names: featureNames,\n params: params,\n loadings: loadings,\n components: components,\n dim: features.length,\n scores: this.getScoresDf(analysis),\n };\n\n // 4. Compute explained variances\n this.computeExplVars(target.length, components, analysis.yLoadings);\n } // fit\n\n /** Return x-loadings with extra items reserved for explained variances */\n private getLoadings(components: number, loadingsCols: DG.Column[]): Float32Array[] {\n const res = Array<Float32Array>(components);\n const len = loadingsCols[0].length + EXTRA_ROWS;\n\n for (let i = 0; i < components; ++i) {\n res[i] = new Float32Array(len);\n res[i].set(loadingsCols[i].getRawData());\n }\n\n return res;\n }\n\n /** Return regression coefficients */\n private getRegrCoeffs(features: DG.ColumnList, target: DG.Column, regrCoefsCol: DG.Column): Float32Array {\n const dim = features.length;\n const params = new Float32Array(dim + EXTRA_ROWS);\n const paramsByPLS = regrCoefsCol.getRawData();\n\n let tmpSum = 0;\n\n for (let i = 0; i < dim; ++i) {\n params[i] = paramsByPLS[i];\n tmpSum += paramsByPLS[i] * features.byIndex(i).stats.avg;\n }\n\n // compute bias\n params[dim] = target.stats.avg - tmpSum;\n\n return params;\n }\n\n /** Return explained variances */\n private computeExplVars(samplesCount: number, components: number, yLoadings: DG.Column) {\n if (this.specn === null)\n throw new Error('Failed to compute explained variances');\n\n const raw = yLoadings.getRawData();\n const dim = this.specn.loadings[0].length - EXTRA_ROWS;\n\n // Compute, source: the paper https://doi.org/10.1002/cem.2589\n let explVar = raw[0]**2 / samplesCount;\n\n this.specn.loadings[0][dim] = explVar;\n\n for (let comp = 1; comp < components; ++comp) {\n explVar += raw[comp]**2 / samplesCount;\n this.specn.loadings[comp][dim] = explVar;\n }\n }\n\n /** Return packed model */\n public toBytes(): Uint8Array {\n if (this.specn === null)\n throw new Error('Failed to pack untrained model');\n\n // 1. Store model params in dataframe\n const modelDf = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLE.FEATURES, this.specn.names),\n DG.Column.fromFloat32Array(TITLE.REGR_COEFS, this.specn.params),\n ]);\n\n this.specn.loadings.forEach((array, idx) => modelDf.columns.add(DG.Column.fromFloat32Array(\n `${TITLE.XLOADING}${idx + 1}`,\n array,\n )));\n\n // 2. Pack model dataframe\n const modelDfBytes = modelDf.toByteArray();\n const modelDfBytesCount = modelDfBytes.length;\n\n const scoresBytes = this.specn.scores.toByteArray();\n const scoresBytesCount = scoresBytes.length;\n\n const requiredBytes = modelDfBytesCount + scoresBytesCount + BYTES_PER_SIZES;\n\n const packedModel = new Uint8Array((Math.ceil(requiredBytes / BLOCK_SIZE) + 1) * BLOCK_SIZE);\n\n // 4 bytes for storing model's bytes count\n const sizeArr = new Uint32Array(packedModel.buffer, 0, SIZE_ARR_LEN);\n sizeArr[MODEL_IDX] = modelDfBytesCount;\n sizeArr[SCORES_IDX] = scoresBytesCount;\n\n // Store model's bytes\n packedModel.set(modelDfBytes, BYTES_PER_SIZES);\n\n // Store scores bytes\n packedModel.set(scoresBytes, BYTES_PER_SIZES + modelDfBytesCount);\n\n return packedModel;\n } // toBytes\n\n /** Return prediction */\n public predict(features: DG.ColumnList): DG.Column {\n if (this.specn === null)\n throw new Error('Predicting failed: model is not trained');\n\n return getPredictionByLinearRegression(features, this.specn.params);\n }\n\n /** Return loadings and regression coefficients viewers */\n private loadingsParamsViewers(): DG.Viewer[] {\n if (this.specn === null)\n throw new Error('Failed to create loadings and parameters viewers: untrained model');\n\n const viewers: DG.Viewer[] = [];\n\n const dim = this.specn.dim;\n\n // Parameters and loadings dataframe\n const loadingsDf = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLE.FEATURES, this.specn.names.slice(0, -1)),\n DG.Column.fromFloat32Array(TITLE.REGR_COEFS, this.specn.params, dim),\n ]);\n\n const columns = loadingsDf.columns;\n const shift = columns.length;\n const components = this.specn.components;\n\n this.specn.loadings.forEach((arr, idx) => loadingsDf.columns.add(\n DG.Column.fromFloat32Array(`${TITLE.XLOADING}${idx + 1}`, arr, dim),\n ));\n\n // Loading scatterplot\n viewers.push(DG.Viewer.scatterPlot(loadingsDf, {\n title: TITLE.LOADINGS,\n xColumnName: columns.byIndex(shift).name,\n yColumnName: columns.byIndex(shift + (components > 1 ? 1 : 0)).name,\n markerType: DG.MARKER_TYPE.CIRCLE,\n labels: TITLE.FEATURES,\n help: LINK.LOADINGS,\n }));\n\n // Regression coefficients barchart\n viewers.push(DG.Viewer.barChart(loadingsDf, {\n title: TITLE.REGR_COEFS,\n splitColumnName: TITLE.FEATURES,\n valueColumnName: TITLE.REGR_COEFS,\n valueAggrType: DG.AGG.AVG,\n help: LINK.COEFFS,\n showValueSelector: false,\n showStackSelector: false,\n }));\n\n return viewers;\n } // getLoadingsParamsViewers\n\n /** Return explained variances viewer */\n private explVarsViewer(): DG.Viewer {\n if (this.specn === null)\n throw new Error('Failed to create exaplained variances viewer: untrained model');\n\n const components = this.specn.components;\n const dim = this.specn.dim;\n\n const compNames = new Array<string>(components);\n const explVars = new Float32Array(components);\n\n compNames[0] = `${RESULT_NAMES.COMP} 1`;\n explVars[0] = this.specn.loadings[0][dim];\n\n for (let i = 1; i < components; ++i) {\n compNames[i] = `${RESULT_NAMES.COMPS} ${i + 1}`;\n explVars[i] = this.specn.loadings[i][dim];\n }\n\n return DG.Viewer.barChart(DG.DataFrame.fromColumns([\n DG.Column.fromStrings(RESULT_NAMES.COMPS, compNames),\n DG.Column.fromFloat32Array(TITLE.EXPL_VAR, explVars),\n ]), {\n title: TITLE.EXPL_VAR,\n splitColumnName: RESULT_NAMES.COMPS,\n valueColumnName: TITLE.EXPL_VAR,\n valueAggrType: DG.AGG.AVG,\n help: LINK.EXPL_VARS,\n showCategorySelector: false,\n showStackSelector: false,\n showValueSelector: false,\n });\n }\n\n /** Returns viewers */\n public viewers(): DG.Viewer[] {\n if (this.specn === null)\n throw new Error('Failed to create viewers: untrained model');\n\n const viewers = this.loadingsParamsViewers();\n viewers.push(\n this.explVarsViewer(),\n this.getScoresScatter(),\n );\n\n return viewers;\n }\n\n /** Return dataframe with scores */\n private getScoresDf(analysis: PlsOutput): DG.DataFrame {\n const tScores = analysis.tScores;\n const uScores = analysis.uScores;\n\n tScores.forEach((col, idx) => col.name = `${TITLE.XSCORE}${idx + 1}`);\n uScores.forEach((col, idx) => col.name = `${TITLE.YSCORE}${idx + 1}`);\n\n return DG.DataFrame.fromColumns(tScores.concat(uScores));\n }\n\n /** Return scores scatter */\n private getScoresScatter(): DG.Viewer {\n if (this.specn === null)\n throw new Error('Failed to create scores scatter: untrained model');\n\n const names = this.specn.scores.columns.names();\n\n const scatter = DG.Viewer.scatterPlot(this.specn.scores, {\n title: TITLE.SCORES,\n xColumnName: names[0],\n yColumnName: names[1],\n markerType: DG.MARKER_TYPE.CIRCLE,\n help: LINK.SCORES,\n showViewerFormulaLines: true,\n });\n\n scatter.meta.formulaLines.addAll(getLines(names));\n\n return scatter;\n }\n};\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nconst TRESHOLD = 0.5;\nconst SHIFT = 1;\nconst LIMIT = 2;\n\nconst MAX_INT = 10;\nconst MAX_FLOAT = 10;\nconst CATEGORIES = ['Alpha', 'Beta', 'Gamma', 'Delta'];\n\n/** Check lengths of columns */\nfunction checkLen(target: DG.Column, prediction: DG.Column): void {\n if (target.length !== prediction.length)\n throw new Error(`Non-equal elements count: ${target.length} vs. ${prediction.length}`);\n}\n\n/** Return dataframe for testing regression & linear methods */\nexport function regressionDataset(samples: number, features: number, dependent: number): DG.DataFrame {\n // create main features\n const df = grok.data.demo.randomWalk(samples, features);\n const cols = df.columns;\n\n const coefs = new Float32Array(features);\n\n // main features raw data\n const raw = new Array<Float32Array>(features);\n for (let j = 0; j < features; ++j)\n raw[j] = cols.byIndex(j).getRawData() as Float32Array;\n\n // dependent features raw data\n for (let j = 0; j < dependent; ++j) {\n const arr = new Float32Array(samples);\n\n // generate coefficients\n for (let k = 0; k < features; ++k)\n coefs[k] = Math.random();\n\n for (let i = 0; i < samples; ++i) {\n for (let k = 0; k < features; ++k)\n arr[i] += coefs[k] * raw[k][i];\n }\n\n cols.add(DG.Column.fromFloat32Array(`y${j}`, arr));\n }\n\n return df;\n} // pcaTestDf\n\n/** Max absolute deviation of the column */\nexport function madNorm(col: DG.Column): number {\n let mad = 0;\n const rows = col.length;\n const raw = col.getRawData();\n\n for (let i = 0; i < rows; ++i)\n mad = Math.max(mad, Math.abs(raw[i]));\n\n return mad;\n}\n\n/** Max absolute deviation error */\nexport function madError(target: DG.Column, prediction: DG.Column): number {\n checkLen(target, prediction);\n\n let mad = 0;\n const rows = target.length;\n const raw1 = target.getRawData();\n const raw2 = prediction.getRawData();\n\n for (let i = 0; i < rows; ++i)\n mad = Math.max(mad, Math.abs(raw1[i] - raw2[i]));\n\n return mad;\n}\n\n/** Return dataframe for testing classifiers */\nexport function classificationDataset(samples: number, features: number, useShift: boolean): DG.DataFrame {\n const labels = new Array<string>(samples);\n const raw = new Array<Float32Array>(features);\n\n for (let j = 0; j < features; ++j) {\n const arr = new Float32Array(samples);\n\n for (let i = 0; i < samples; ++i)\n arr[i] = Math.random();\n\n raw[j] = arr;\n }\n\n const df = DG.DataFrame.fromColumns(raw.map((arr, idx) => DG.Column.fromFloat32Array(`#${idx}`, arr)));\n\n for (let i = 0; i < samples; ++i)\n labels[i] = raw.slice(0, LIMIT).map((arr) => (arr[i] > TRESHOLD) ? 'A' : 'B').join('');\n\n df.columns.add(DG.Column.fromStrings('Labels', labels));\n\n if (useShift) {\n for (let j = 0; j < features; ++j) {\n for (let i = 0; i < samples; ++i)\n raw[j][i] += (raw[j][i] > 0 ? 1 : -1) * SHIFT;\n }\n }\n\n return df;\n} // classificationDataset\n\n/** Return accuracy */\nexport function accuracy(target: DG.Column, prediction: DG.Column): number {\n checkLen(target, prediction);\n\n let correctPredictions = 0;\n const rows = target.length;\n\n if (rows < 1)\n return 1;\n\n for (let i = 0; i < rows; ++i) {\n if (target.get(i) === prediction.get(i))\n ++correctPredictions;\n }\n\n return correctPredictions / rows;\n}\n\n/** Return dataframe with missing values */\nexport function dataWithMissingVals(rows: number, intCols: number, floatCols: number,\n strCols: number, misValCount: number): {df: DG.DataFrame, misValsIds: Map<string, number[]>} {\n const catsCount = CATEGORIES.length;\n const cols = [];\n let idx = 0;\n\n const misValsIds = new Map<string, number[]>();\n\n for (let j = 0; j < intCols; ++j) {\n const arr = new Int32Array(rows);\n const name = `int #${j + 1}`;\n const indeces: number[] = [];\n\n for (let i = 0; i < rows; ++i)\n arr[i] = Math.floor(Math.random() * MAX_INT);\n\n for (let k = 0; k < misValCount; ++k) {\n idx = Math.floor(rows * Math.random());\n arr[idx] = DG.INT_NULL;\n indeces.push(idx);\n }\n\n cols.push(DG.Column.fromInt32Array(name, arr));\n misValsIds.set(name, indeces);\n }\n\n for (let j = 0; j < floatCols; ++j) {\n const arr = new Float32Array(rows);\n const name = `float #${j + 1}`;\n const indeces: number[] = [];\n\n for (let i = 0; i < rows; ++i)\n arr[i] = Math.random() * MAX_FLOAT;\n\n for (let k = 0; k < misValCount; ++k) {\n idx = Math.floor(rows * Math.random());\n arr[idx] = DG.FLOAT_NULL;\n indeces.push(idx);\n }\n\n cols.push(DG.Column.fromFloat32Array(name, arr));\n misValsIds.set(name, indeces);\n }\n\n for (let j = 0; j < strCols; ++j) {\n const arr = new Array<string>(rows);\n const name = `str #${j + 1}`;\n const indeces: number[] = [];\n\n for (let i = 0; i < rows; ++i)\n arr[i] = CATEGORIES[Math.floor(Math.random() * catsCount)];\n\n const col = DG.Column.fromStrings(name, arr);\n\n for (let k = 0; k < misValCount; ++k) {\n idx = Math.floor(rows * Math.random());\n col.set(idx, null);\n indeces.push(idx);\n }\n\n cols.push(col);\n misValsIds.set(name, indeces);\n }\n\n return {\n df: DG.DataFrame.fromColumns(cols),\n misValsIds: misValsIds,\n };\n} // tableWithMissingVals\n","// Tests for PCA, PLS & linear regression\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {_package} from '../package-test';\n\nimport {category, expect, test} from '@datagrok-libraries/utils/src/test';\nimport {computePCA} from '../eda-tools';\nimport {getPlsAnalysis} from '../pls/pls-tools';\nimport {PlsModel} from '../pls/pls-ml';\nimport {getLinearRegressionParams, getPredictionByLinearRegression} from '../regression';\nimport {regressionDataset, madNorm, madError} from './utils';\n\nconst ROWS = 100;\nconst ROWS_K = 100;\nconst COLS = 100;\nconst COMPONENTS = 3;\nconst TIMEOUT = 4000;\nconst INDEP_COLS = 2;\nconst DEP_COLS = 5;\nconst ERROR = 0.1;\n\ncategory('Principal component analysis', () => {\n test(`Performance: ${ROWS_K}K rows, ${COLS} cols, ${COMPONENTS} components`, async () => {\n const df = grok.data.demo.randomWalk(ROWS_K * 1000, COLS);\n await computePCA(df, df.columns, COMPONENTS, false, false);\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Data\n const df = regressionDataset(ROWS, COMPONENTS, DEP_COLS);\n\n // Apply\n const pca = await computePCA(df, df.columns, COMPONENTS + 1, false, false);\n\n // Check\n const lastPca = pca.columns.byIndex(COMPONENTS);\n const norm = madNorm(lastPca);\n\n // the last PCA component must be small due to df construction\n expect((norm < ERROR), true, 'Incorrect PCA computations');\n }, {timeout: TIMEOUT});\n}); // PCA\n\ncategory('Partial least squares regression', () => {\n test(`Performance: ${ROWS_K}K rows, ${COLS} cols, ${COMPONENTS} components`, async () => {\n // Data\n const df = grok.data.demo.randomWalk(ROWS_K * 1000, COLS);\n const cols = df.columns;\n\n // Apply\n await getPlsAnalysis({\n table: df,\n features: cols,\n predict: cols.byIndex(COLS - 1),\n components: COMPONENTS,\n names: undefined,\n });\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Data\n const df = regressionDataset(ROWS_K, COMPONENTS, DEP_COLS);\n const cols = df.columns;\n const target = cols.byIndex(COMPONENTS + DEP_COLS - 1);\n\n // Apply\n const plsRes = await getPlsAnalysis({\n table: df,\n features: cols,\n predict: target,\n components: COMPONENTS,\n names: undefined,\n });\n\n // Check deviation\n const deviation = madError(target, plsRes.prediction);\n expect(\n (deviation < ERROR),\n true,\n `Incorrect PLS computations, error is too big: ${deviation}; expected: < ${ERROR}`,\n );\n }, {timeout: TIMEOUT});\n\n test(`Predictive modeling: ${ROWS_K}K samples, ${COLS} features, ${COMPONENTS} components`, async () => {\n // Prepare data\n const df = regressionDataset(ROWS_K * 1000, COMPONENTS, COLS - COMPONENTS + 1);\n const features = df.columns;\n const target = features.byIndex(COLS);\n features.remove(target.name);\n\n // Train & pack model\n const model = new PlsModel();\n await model.fit(features, target, COMPONENTS);\n const packed = model.toBytes();\n\n // Unpack model & predict\n const unpackedModel = new PlsModel(packed);\n const prediction = unpackedModel.predict(features);\n\n // Check deviation\n const deviation = madError(target, prediction);\n expect(\n (deviation < ERROR),\n true,\n `Incorrect PLS (ML) computations, error is too big: ${deviation}; expected: < ${ERROR}`,\n );\n }, {timeout: TIMEOUT, benchmark: true});\n}); // PLS\n\ncategory('Linear regression', () => {\n test(`Performance: ${ROWS_K}K samples, ${COLS} features`, async () => {\n // Prepare data\n const df = regressionDataset(ROWS_K * 1000, COLS, 1);\n const features = df.columns;\n const target = features.byIndex(COLS);\n\n // Train & pack model\n const params = await getLinearRegressionParams(features, target);\n const packed = new Uint8Array(params.buffer);\n\n // Unpack & apply model\n const unpackedParams = new Float32Array(packed.buffer);\n getPredictionByLinearRegression(features, unpackedParams);\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Prepare data\n const df = regressionDataset(ROWS, INDEP_COLS, 1);\n const features = df.columns;\n const target = features.byIndex(INDEP_COLS);\n\n // Train & pack model\n const params = await getLinearRegressionParams(features, target);\n const packed = new Uint8Array(params.buffer);\n\n // Unpack & apply model\n const unpackedParams = new Float32Array(packed.buffer);\n const prediction = getPredictionByLinearRegression(features, unpackedParams);\n\n // Evaluate model\n const error = madError(prediction, prediction);\n expect(\n error < ERROR,\n true,\n `Incorrect linear regression computations, error is too big: ${error}; expected: < ${ERROR}`,\n );\n }, {timeout: TIMEOUT});\n}); // Linear regression\n","// Softmax classifier (multinomial logistic regression): https://en.wikipedia.org/wiki/Multinomial_logistic_regression\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {_fitSoftmax} from '../wasm/EDAAPI';\n\nconst ROWS_EXTRA = 1;\nconst COLS_EXTRA = 2;\nconst MIN_COLS_COUNT = 1 + COLS_EXTRA;\nconst AVGS_NAME = 'Avg-s';\nconst STDEVS_NAME = 'Stddev-s';\nconst PRED_NAME = 'predicted';\nconst DEFAULT_LEARNING_RATE = 1;\nconst DEFAULT_ITER_COUNT = 100;\nconst DEFAULT_PENALTY = 0.1;\nconst DEFAULT_TOLERANCE = 0.001;\nconst BYTES_PER_MODEL_SIZE = 4;\n\n/** Train data sizes */\ntype DataSpecification = {\n classesCount: number,\n featuresCount: number,\n};\n\n/** Target labels specification */\ntype TargetLabelsData = {\n oneHot: Array<Uint8Array>,\n weights: Uint32Array,\n};\n\n/** Interactivity tresholds */\nenum INTERACTIVITY {\n MAX_SAMLPES = 50000,\n MAX_FEATURES = 100,\n};\n\n/** Softmax classifier */\nexport class SoftmaxClassifier {\n /** Check applicability */\n static isApplicable(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n for (const col of features) {\n if (!col.matches('numerical'))\n return false;\n }\n\n return (predictColumn.type === DG.COLUMN_TYPE.STRING);\n }\n\n /** Check interactivity */\n static isInteractive(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n return (features.length <= INTERACTIVITY.MAX_FEATURES) &&\n (predictColumn.length <= INTERACTIVITY.MAX_SAMLPES);\n }\n\n private avgs: Float32Array;\n private stdevs: Float32Array;\n private categories: string[];\n private params: Float32Array[] | undefined = undefined;\n private classesCount = 1;\n private featuresCount = 1;\n\n constructor(specification?: DataSpecification, packedModel?: Uint8Array) {\n if (specification !== undefined) { // Create empty model\n /** features count */\n const n = specification.featuresCount;\n\n /** classes count */\n const c = specification.classesCount;\n\n if (n < 1)\n throw new Error('Incorrect features count');\n\n if (c < 1)\n throw new Error('Incorrect classes count');\n\n /** length of arrays */\n const len = n + ROWS_EXTRA;\n\n // Init model routine\n this.avgs = new Float32Array(len);\n this.stdevs = new Float32Array(len);\n this.categories = new Array<string>(len);\n this.featuresCount = n;\n this.classesCount = c;\n } else if (packedModel !== undefined) { // Get classifier from packed model (bytes)\n try {\n // Extract model's bytes count\n const sizeArr = new Uint32Array(packedModel.buffer, 0, 1);\n const bytesCount = sizeArr[0];\n\n // Model's bytes\n const modelBytes = new Uint8Array(packedModel.buffer, BYTES_PER_MODEL_SIZE, bytesCount);\n\n const modelDf = DG.DataFrame.fromByteArray(modelBytes);\n const columns = modelDf.columns;\n const colsCount = columns.length;\n\n if (colsCount < MIN_COLS_COUNT)\n throw new Error('incorrect columns count');\n\n this.classesCount = colsCount - COLS_EXTRA;\n this.featuresCount = modelDf.rowCount - ROWS_EXTRA;\n\n const c = this.classesCount;\n\n // extract params & categories\n this.params = new Array<Float32Array>(c);\n this.categories = new Array<string>(modelDf.rowCount);\n\n for (let i = 0; i < c; ++i) {\n const col = columns.byIndex(i);\n this.categories[i] = col.name;\n\n if (col.type !== DG.COLUMN_TYPE.FLOAT)\n throw new Error(`Incorrect input column type. Expected: float, passed: ${col.type}`);\n\n this.params[i] = col.getRawData() as Float32Array;\n }\n\n // extract averages\n const avgsCol = columns.byName(AVGS_NAME);\n if (avgsCol.type !== DG.COLUMN_TYPE.FLOAT)\n throw new Error('incorrect average values column type');\n this.avgs = avgsCol.getRawData() as Float32Array;\n\n // extract stdevs\n const stdevsCol = columns.byName(STDEVS_NAME);\n if (stdevsCol.type !== DG.COLUMN_TYPE.FLOAT)\n throw new Error('incorrect standard deviations column type');\n this.stdevs = stdevsCol.getRawData() as Float32Array;\n } catch (e) {\n throw new Error(`Failed to load model: ${(e instanceof Error ? e.message : 'the platform issue')}`);\n }\n } else\n throw new Error('Softmax classifier not initialized');\n }; // constructor\n\n /** Return packed softmax classifier */\n public toBytes(): Uint8Array {\n if (this.params === undefined)\n throw new Error('Non-trained model');\n\n const c = this.classesCount;\n const columns = new Array<DG.Column>(c + COLS_EXTRA);\n\n // params columns\n for (let i = 0; i < c; ++i)\n columns[i] = DG.Column.fromFloat32Array(this.categories[i], this.params[i]);\n\n // averages\n columns[c] = DG.Column.fromFloat32Array(AVGS_NAME, this.avgs);\n\n // stdevs\n columns[c + 1] = DG.Column.fromFloat32Array(STDEVS_NAME, this.stdevs);\n\n const modelDf = DG.DataFrame.fromColumns(columns);\n\n const modelBytes = modelDf.toByteArray();\n const bytesCount = modelBytes.length;\n\n // Packed model bytes, including bytes count\n const packedModel = new Uint8Array(bytesCount + BYTES_PER_MODEL_SIZE);\n\n // 4 bytes for storing model's bytes count\n const sizeArr = new Uint32Array(packedModel.buffer, 0, 1);\n sizeArr[0] = bytesCount;\n\n // Store model's bytes\n packedModel.set(modelBytes, BYTES_PER_MODEL_SIZE);\n\n return packedModel;\n } // toBytes\n\n /** Train classifier */\n public async fit(features: DG.ColumnList, target: DG.Column, rate: number = DEFAULT_LEARNING_RATE,\n iterations: number = DEFAULT_ITER_COUNT, penalty: number = DEFAULT_PENALTY, tolerance: number = DEFAULT_TOLERANCE) {\n if (features.length !== this.featuresCount)\n throw new Error('Training failes - incorrect features count');\n\n if ((rate <= 0) || (iterations < 1) || (penalty <= 0) || (tolerance <= 0))\n throw new Error('Training failes - incorrect fitting hyperparameters');\n\n // Extract statistics & categories\n this.extractStats(features);\n const rowsCount = target.length;\n const classesCount = target.categories.length;\n const cats = target.categories;\n for (let i = 0; i < classesCount; ++i)\n this.categories[i] = cats[i];\n\n try {\n // call wasm-computations\n const paramCols = _fitSoftmax(\n features,\n DG.Column.fromFloat32Array('avgs', this.avgs, this.featuresCount),\n DG.Column.fromFloat32Array('stdevs', this.stdevs, this.featuresCount),\n DG.Column.fromInt32Array('targets', target.getRawData() as Int32Array, rowsCount),\n classesCount,\n iterations, rate, penalty, tolerance,\n this.featuresCount + 1, classesCount,\n ).columns as DG.ColumnList;\n\n this.params = new Array<Float32Array>(classesCount);\n for (let i = 0; i < classesCount; ++i)\n this.params[i] = paramCols.byIndex(i).getRawData() as Float32Array;\n } catch (error) {\n try { // call fitting TS-computations (if wasm failed)\n this.params = await this.fitSoftmaxParams(\n features,\n target,\n iterations,\n rate,\n penalty,\n tolerance,\n ) as Float32Array[];\n } catch (error) {\n throw new Error('Training failes');\n }\n }\n\n if (this.params === undefined)\n throw new Error('Training failes');\n }; // fit\n\n /** Extract features' stats */\n private extractStats(features: DG.ColumnList): void {\n let j = 0;\n\n for (const col of features) {\n if ((col.type !== DG.COLUMN_TYPE.INT) && (col.type !== DG.COLUMN_TYPE.FLOAT))\n throw new Error('Training failes - incorrect features type');\n\n this.avgs[j] = col.stats.avg;\n this.stdevs[j] = col.stats.stdev;\n\n ++j;\n }\n } // extractStats\n\n /** Retrun normalized features */\n private normalized(features: DG.ColumnList): Array<Float32Array> {\n const m = features.byIndex(0).length;\n\n const X = new Array<Float32Array>(m);\n\n for (let i = 0; i < m; ++i)\n X[i] = new Float32Array(this.featuresCount);\n\n let j = 0;\n for (const col of features) {\n if ((col.type !== DG.COLUMN_TYPE.INT) && (col.type !== DG.COLUMN_TYPE.FLOAT))\n throw new Error('Training failes - incorrect features type');\n\n const raw = col.getRawData();\n const avg = this.avgs[j];\n const stdev = this.stdevs[j];\n\n if (stdev > 0) {\n for (let i = 0; i < m; ++i)\n X[i][j] = (raw[i] - avg) / stdev;\n } else {\n for (let i = 0; i < m; ++i)\n X[i][j] = 0;\n }\n\n ++j;\n }\n\n return X;\n } // normalized\n\n /** Retrun normalized & transposed features */\n private transposed(features: DG.ColumnList): Array<Float32Array> {\n const m = features.byIndex(0).length;\n const n = this.featuresCount;\n\n const X = new Array<Float32Array>(n);\n\n for (let i = 0; i < n; ++i)\n X[i] = new Float32Array(m);\n\n let j = 0;\n for (const col of features) {\n if ((col.type !== DG.COLUMN_TYPE.INT) && (col.type !== DG.COLUMN_TYPE.FLOAT))\n throw new Error('Training failes - incorrect features type');\n\n const raw = col.getRawData();\n const avg = this.avgs[j];\n const stdev = this.stdevs[j];\n\n if (stdev > 0) {\n for (let i = 0; i < m; ++i)\n X[j][i] = (raw[i] - avg) / stdev;\n } else {\n for (let i = 0; i < m; ++i)\n X[j][i] = 0;\n }\n\n ++j;\n }\n\n return X;\n } // transposed\n\n /** Return one-hot vectors and classes weights */\n private preprocessedTargets(target: DG.Column): TargetLabelsData {\n if (target.type !== DG.COLUMN_TYPE.STRING)\n throw new Error('Training failes - incorrect target type');\n\n const c = this.classesCount;\n const m = target.length;\n const raw = target.getRawData();\n\n const Y = new Array<Uint8Array>(m);\n const weights = new Uint32Array(c).fill(0);\n\n for (let i = 0; i < m; ++i)\n Y[i] = new Uint8Array(c).fill(0);\n\n for (let i = 0; i < m; ++i) {\n Y[i][raw[i]] = 1;\n ++weights[raw[i]];\n }\n\n return {\n oneHot: Y,\n weights: weights,\n };\n } // getOneHot\n\n /** Return prediction column */\n public predict(features: DG.ColumnList): DG.Column {\n if (this.params === undefined)\n throw new Error('Non-trained model');\n\n if (features.length !== this.featuresCount)\n throw new Error('Predcition fails: incorrect features count');\n\n // Normalize features\n const X = this.normalized(features);\n\n // Routine items\n const m = X.length;\n const n = this.featuresCount;\n const c = this.classesCount;\n let xBuf: Float32Array;\n let wBuf: Float32Array;\n const Z = new Float32Array(c);\n let sum: number;\n let max: number;\n let argMax: number;\n const predClass = new Array<string>(m);\n\n // get prediction for each sample\n for (let j = 0; j < m; ++j) {\n xBuf = X[j];\n sum = 0;\n\n for (let i = 0; i < c; ++i) {\n wBuf = this.params[i];\n sum = wBuf[n];\n\n for (let k = 0; k < n; ++k)\n sum += wBuf[k] * xBuf[k];\n\n Z[i] = Math.exp(sum);\n }\n\n max = Z[0];\n argMax = 0;\n\n for (let k = 1; k < c; ++k) {\n if (max < Z[k]) {\n max = Z[k];\n argMax = k;\n }\n }\n\n predClass[j] = this.categories[argMax];\n }\n\n return DG.Column.fromStrings(PRED_NAME, predClass);\n }\n\n /** Fit params in the webworker */\n private async fitSoftmaxParams(features: DG.ColumnList, target: DG.Column,\n iterations: number, rate: number, penalty: number, tolerance: number) {\n const targetData = this.preprocessedTargets(target);\n\n return new Promise((resolve, reject) => {\n const worker = new Worker(new URL('./workers/softmax-worker.ts', import.meta.url));\n worker.postMessage({\n features: this.normalized(features),\n transposed: this.transposed(features),\n oneHot: targetData.oneHot,\n classesWeights: targetData.weights,\n targetRaw: target.getRawData(),\n iterations: iterations,\n rate: rate,\n penalty: penalty,\n tolerance: tolerance,\n });\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(e.data.params);\n console.log(`Loss: ${e.data.loss}`);\n };\n });\n }\n}; // SoftmaxClassifier\n","// XGBooster modeling tools\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {predict, fitInWebWorker} from '../wasm/xgbooster';\n\n/** Default hyperparameters */\nenum DEFAULT {\n ITERATIONS = 20,\n ETA = 0.3,\n MAX_DEPTH = 6,\n LAMBDA = 1,\n ALPHA = 0,\n};\n\n/** Interactivity tresholds */\nenum INTERACTIVITY {\n SAMLPES_HIGH = 100000,\n SAMLPES_MID = 50000,\n SAMPLES_LOW = 10000,\n FEATURES_HIGH = 10,\n FEATURES_MID = 20,\n FEATURES_LOW = 100,\n};\n\n/** Reserve sizes */\nenum RESERVED {\n MODEL = 10000000,\n UTILS = 1,\n PACK = 128,\n SIZE = 4,\n};\n\n/** XGBoost specific constants */\nconst MISSING_VALUE = DG.FLOAT_NULL;\nconst ALIGN_VAL = 4;\nconst BLOCK_SIZE = 64;\n\nenum TITLES {\n PREDICT = 'Prediction',\n TYPE = 'Type',\n PARAMS = 'Params count',\n CATS = 'Categories',\n CATS_SIZE = 'Categories size',\n}\n\n/** XGBoost modeling */\nexport class XGBooster {\n /** Check applicability */\n static isApplicable(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n for (const col of features) {\n if (!col.matches('numerical'))\n return false;\n }\n if (!predictColumn.matches('numerical') && !predictColumn.matches('string'))\n return false;\n\n return true;\n }\n\n /** Check interactivity */\n static isInteractive(features: DG.ColumnList, predictColumn: DG.Column): boolean {\n const featuresCount = features.length;\n const samplesCount = predictColumn.length;\n\n if (samplesCount <= INTERACTIVITY.SAMPLES_LOW)\n return featuresCount <= INTERACTIVITY.FEATURES_LOW;\n\n if (samplesCount <= INTERACTIVITY.SAMLPES_MID)\n return featuresCount <= INTERACTIVITY.FEATURES_MID;\n\n if (samplesCount <= INTERACTIVITY.SAMLPES_HIGH)\n return featuresCount <= INTERACTIVITY.FEATURES_HIGH;\n\n return false;\n }\n\n private modelParams: Int32Array | undefined = undefined;\n private targetType: string | undefined = undefined;\n private targetCategories: string[] | undefined = undefined;\n\n constructor(packedModel?: Uint8Array) {\n if (packedModel) {\n try {\n let offset = 0;\n\n // Unpack header size\n const headArr = new Uint32Array(packedModel.buffer, offset, 1);\n const headerBytesSize = headArr[0];\n offset += RESERVED.SIZE;\n\n // Unpack header\n const headerDf = DG.DataFrame.fromByteArray(new Uint8Array(packedModel.buffer, offset, headerBytesSize));\n offset += headerBytesSize;\n\n // Extract model specification\n this.targetType = headerDf.get(TITLES.TYPE, 0) as string;\n const modelParamsCount = headerDf.get(TITLES.PARAMS, 0) as number;\n const categoriesBytesSize = headerDf.get(TITLES.CATS_SIZE, 0) as number;\n\n // Unpack categories\n if (categoriesBytesSize > 0) {\n const categoriesDf = DG.DataFrame.fromByteArray(\n new Uint8Array(packedModel.buffer, offset, categoriesBytesSize),\n );\n\n this.targetCategories = categoriesDf.col(TITLES.CATS)?.toList();\n }\n offset += categoriesBytesSize;\n\n offset = Math.ceil(offset / ALIGN_VAL) * ALIGN_VAL;\n\n // Unpack model params\n this.modelParams = new Int32Array(packedModel.buffer, offset, modelParamsCount);\n } catch (error) {\n throw new Error(`Failed to load model: ${(error instanceof Error ? error.message : 'the platform issue')}`);\n }\n }\n }\n\n /** Fit model */\n public async fit(features: DG.ColumnList, target: DG.Column, iterations: number = DEFAULT.ITERATIONS,\n eta: number = DEFAULT.ETA, maxDepth: number = DEFAULT.MAX_DEPTH, lambda: number = DEFAULT.LAMBDA,\n alpha: number = DEFAULT.ALPHA) {\n // Type of the target\n this.targetType = target.type;\n\n // Store categories of string target\n if (this.targetType === DG.COLUMN_TYPE.STRING)\n this.targetCategories = target.categories;\n\n // Train model params\n this.modelParams = await fitInWebWorker(features, target, MISSING_VALUE,\n iterations, eta, maxDepth, lambda, alpha, RESERVED.MODEL, RESERVED.UTILS,\n );\n }\n\n /** Predict using trained model */\n public predict(features: DG.ColumnList): DG.Column {\n if (this.modelParams === undefined)\n throw new Error('Failed to apply non-trained model');\n\n // Get prediction\n const prediction = predict(features, MISSING_VALUE, this.modelParams);\n\n // Create an appropriate column\n switch (this.targetType) {\n case DG.COLUMN_TYPE.STRING:\n return this.stringColPrediction(prediction);\n\n case DG.COLUMN_TYPE.INT:\n return this.intColPrediction(prediction);\n\n case DG.COLUMN_TYPE.BIG_INT:\n return this.bigIntColPrediction(prediction);\n\n default:\n return DG.Column.fromFloat32Array(TITLES.PREDICT, prediction);\n }\n }\n\n /** Return packed model */\n public toBytes(): Uint8Array {\n if ((this.modelParams === undefined) || (this.targetType === undefined))\n throw new Error('Failed to pack non-trained model');\n\n // Categories bytes\n const categoriesBytes = (this.targetCategories !== undefined) ? DG.DataFrame.fromColumns([\n DG.Column.fromList(DG.COLUMN_TYPE.STRING, TITLES.CATS, this.targetCategories),\n ]).toByteArray(): undefined;\n\n const categoriesBytesSize = (categoriesBytes !== undefined) ? categoriesBytes.length : 0;\n\n const modelParamsBytesSize = this.modelParams.length * this.modelParams.BYTES_PER_ELEMENT;\n\n // Header with model specification\n const headerDf = DG.DataFrame.fromColumns([\n DG.Column.fromStrings(TITLES.TYPE, [this.targetType]),\n DG.Column.fromInt32Array(TITLES.PARAMS, new Int32Array([this.modelParams.length])),\n DG.Column.fromInt32Array(TITLES.CATS_SIZE, new Int32Array([categoriesBytesSize])),\n ]);\n\n // Header bytes\n const headerBytes = headerDf.toByteArray();\n const headerBytesSize = headerBytes.length;\n\n // Packed model\n const reservedSize = Math.ceil((RESERVED.SIZE +\n headerBytesSize + categoriesBytesSize + modelParamsBytesSize + RESERVED.PACK) / BLOCK_SIZE) * BLOCK_SIZE;\n\n const packedModel = new Uint8Array(reservedSize);\n\n let offset = 0;\n\n // Pack header size\n const headArr = new Uint32Array(packedModel.buffer, offset, 1);\n headArr[0] = headerBytesSize;\n offset += RESERVED.SIZE;\n\n // Pack header\n packedModel.set(headerBytes, offset);\n offset += headerBytesSize;\n\n // Pack categories\n if (categoriesBytesSize > 0)\n packedModel.set(categoriesBytes!, offset);\n offset += categoriesBytesSize;\n\n offset = Math.ceil(offset / ALIGN_VAL) * ALIGN_VAL;\n\n // Pack model params\n packedModel.set(new Uint8Array(this.modelParams.buffer), offset);\n\n return packedModel;\n } // toBytes\n\n /** Return predicted string column */\n private stringColPrediction(prediction: Float32Array): DG.Column {\n const samplesCount = prediction.length;\n\n if (this.targetCategories === undefined)\n throw new Error('Predicting fails: undefined categories');\n\n const predClass = new Array<string>(samplesCount);\n\n const maxCategory = this.targetCategories.length - 1;\n const categoryIdx = (val: number) => Math.max(0, Math.min(val, maxCategory));\n\n for (let i = 0; i < samplesCount; ++i)\n predClass[i] = this.targetCategories[categoryIdx(Math.round(prediction[i]))];\n\n return DG.Column.fromList(DG.COLUMN_TYPE.STRING, TITLES.PREDICT, predClass);\n }\n\n /** Return predicted int column */\n private intColPrediction(prediction: Float32Array): DG.Column {\n const samplesCount = prediction.length;\n\n const rawInts = new Int32Array(samplesCount);\n\n for (let i = 0; i < samplesCount; ++i)\n rawInts[i] = Math.round(prediction[i]);\n\n return DG.Column.fromInt32Array(TITLES.PREDICT, rawInts, samplesCount);\n }\n\n /** Return predicted bigint column */\n private bigIntColPrediction(prediction: Float32Array): DG.Column {\n const samplesCount = prediction.length;\n\n const rawInts = new BigInt64Array(samplesCount);\n\n for (let i = 0; i < samplesCount; ++i)\n rawInts[i] = BigInt(Math.round(prediction[i]));\n\n return DG.Column.fromBigInt64Array(TITLES.PREDICT, rawInts);\n }\n}\n","// JavaScript API for call wasm-functions from the XGBoostAPI module\n\n// Data constants\nconst INT_BYTES = 4;\nconst FLOAT_BYTES = 4;\nconst SIZE_IDX = 0;\n\nexport async function initXgboost() {\n await initXGBoostModule();\n}\n\n/** Fit and return model params */\nexport function fit(features, target, missingValue, iterations, eta, maxDepth, lambda, alpha,\n modelReserve, utilsLength) {\n // Data size\n const samplesCount = target.length;\n const featuresCount = features.length;\n\n // Allocate memory\n const featuresBuf = XGBoostModule._malloc(samplesCount * featuresCount * FLOAT_BYTES);\n const targetBuf = XGBoostModule._malloc(samplesCount * FLOAT_BYTES);\n const modelBuf = XGBoostModule._malloc(modelReserve * INT_BYTES);\n const utilsBuf = XGBoostModule._malloc(utilsLength * INT_BYTES);\n\n // Wasm buffer routine\n const floatHeap = XGBoostModule.HEAPF32;\n let intHeap = XGBoostModule.HEAP32;\n let raw;\n\n // Put features to wasm buffer\n for (let j = 0; j < featuresCount; ++j) {\n raw = features.byIndex(j).getRawData();\n\n for (let i = 0; i < samplesCount; ++i)\n floatHeap[featuresBuf / FLOAT_BYTES + i + j * samplesCount] = raw[i];\n }\n\n // Put targets to wasm buffer\n raw = target.getRawData();\n for (let i = 0; i < samplesCount; ++i)\n floatHeap[targetBuf / FLOAT_BYTES + i] = raw[i];\n\n // Train model\n XGBoostModule._train(\n featuresBuf, samplesCount, featuresCount, missingValue, // features data\n targetBuf, samplesCount, // target data\n iterations, eta, maxDepth, lambda, alpha, // hyperparameters\n utilsBuf, utilsLength, // utils\n modelBuf, modelReserve, // model params to be trained\n );\n\n // Extract model params from wasm buffer\n intHeap = XGBoostModule.HEAP32;\n const paramsCount = intHeap[utilsBuf / INT_BYTES + SIZE_IDX];\n const params = new Int32Array(paramsCount);\n\n for (let i = 0; i < paramsCount; ++i)\n params[i] = intHeap[modelBuf / INT_BYTES + i];\n\n // Free allocated memory\n XGBoostModule._free(featuresBuf);\n XGBoostModule._free(targetBuf);\n XGBoostModule._free(utilsBuf);\n XGBoostModule._free(modelBuf);\n\n return params;\n} // fit\n\n/** Fit and return model params in webworker */\nexport async function fitInWebWorker(features, target, missingValue, iterations, eta, maxDepth, lambda, alpha,\n modelReserve, utilsLength) {\n return new Promise((resolve, reject) => {\n // Data size\n const samplesCount = target.length;\n const featuresCount = features.length;\n\n // Features raw data\n const featuresRaw = new Float32Array(samplesCount * featuresCount);\n let shift;\n let raw;\n for (let j = 0; j < featuresCount; ++j) {\n raw = features.byIndex(j).getRawData();\n shift = j * samplesCount;\n\n for (let i = 0; i < samplesCount; ++i)\n featuresRaw[i + shift] = raw[i];\n }\n\n const worker = new Worker(new URL('../wasm/workers/xgboostWorker.js', import.meta.url));\n\n worker.postMessage({\n features: featuresRaw,\n target: target.getRawData(),\n samplesCount: samplesCount,\n featuresCount: featuresCount,\n modelReserve: modelReserve,\n utilsLength: utilsLength,\n iterations: iterations,\n eta: eta,\n maxDepth: maxDepth,\n lambda: lambda,\n alpha: alpha,\n missingValue: missingValue,\n });\n\n worker.onmessage = function(e) {\n worker.terminate();\n resolve(e.data.params);\n };\n });\n} // fitInWebWorker\n\n/** Return prediction by trained model */\nexport function predict(features, missingValue, params) {\n // Data & model sizes\n const samplesCount = features.byIndex(0).length;\n const featuresCount = features.length;\n const paramsCount = params.length;\n\n // Wasm buffer routine\n let floatHeap = XGBoostModule.HEAPF32;\n const intHeap = XGBoostModule.HEAP32;\n\n // Allocate memory\n const featuresBuf = XGBoostModule._malloc(samplesCount * featuresCount * FLOAT_BYTES);\n const targetBuf = XGBoostModule._malloc(samplesCount * FLOAT_BYTES);\n const modelBuf = XGBoostModule._malloc(paramsCount * INT_BYTES);\n\n // Put features to wasm buffer\n for (let j = 0; j < featuresCount; ++j) {\n const raw = features.byIndex(j).getRawData();\n\n for (let i = 0; i < samplesCount; ++i)\n floatHeap[featuresBuf / FLOAT_BYTES + i + j * samplesCount] = raw[i];\n }\n\n // Put model to wasm bufffer\n for (let i = 0; i < paramsCount; ++i)\n intHeap[modelBuf / INT_BYTES + i] = params[i];\n\n // Compute predictions\n XGBoostModule._predict(\n featuresBuf, samplesCount, featuresCount, missingValue, // features\n modelBuf, paramsCount, // model params\n targetBuf, samplesCount, // target to be predicted\n );\n\n // Extract predictions from wasm buffer\n floatHeap = XGBoostModule.HEAPF32;\n const prediction = new Float32Array(samplesCount);\n\n for (let i = 0; i < samplesCount; ++i)\n prediction[i] = floatHeap[targetBuf / FLOAT_BYTES + i];\n\n // Free allocated memory\n XGBoostModule._free(featuresBuf);\n XGBoostModule._free(targetBuf);\n XGBoostModule._free(modelBuf);\n\n return prediction;\n} // predict\n","// Tests for classifiers\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {_package} from '../package-test';\n\nimport {category, expect, test} from '@datagrok-libraries/utils/src/test';\n\nimport {classificationDataset, accuracy} from './utils';\nimport {SoftmaxClassifier} from '../softmax-classifier';\nimport {XGBooster} from '../xgbooster';\n\nconst ROWS_K = 50;\nconst MIN_COLS = 2;\nconst COLS = 100;\nconst TIMEOUT = 8000;\nconst MIN_ACCURACY = 0.9;\n\ncategory('Softmax', () => {\n test(`Performance: ${ROWS_K}K samples, ${COLS} features`, async () => {\n // Data\n const df = classificationDataset(ROWS_K * 1000, COLS, false);\n const features = df.columns;\n const target = features.byIndex(COLS);\n features.remove(target.name);\n\n // Fit & pack trained model\n const model = new SoftmaxClassifier({\n classesCount: target.categories.length,\n featuresCount: features.length,\n });\n await model.fit(features, target);\n const modelBytes = model.toBytes();\n\n // Unpack & apply model\n const unpackedModel = new SoftmaxClassifier(undefined, modelBytes);\n unpackedModel.predict(features);\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Prepare data\n const df = classificationDataset(ROWS_K, MIN_COLS, true);\n const features = df.columns;\n const target = features.byIndex(MIN_COLS);\n features.remove(target.name);\n\n // Fit & pack trained model\n const model = new SoftmaxClassifier({\n classesCount: target.categories.length,\n featuresCount: features.length,\n });\n\n await model.fit(features, target);\n const modelBytes = model.toBytes();\n\n // Unpack & apply model\n const unpackedModel = new SoftmaxClassifier(undefined, modelBytes);\n const prediction = unpackedModel.predict(features);\n\n // Evaluate accuracy\n const acc = accuracy(target, prediction);\n expect(\n acc > MIN_ACCURACY,\n true,\n `Softmax failed, too small accuracy: ${acc}; expected: <= ${MIN_ACCURACY}`,\n );\n }, {timeout: TIMEOUT});\n}); // Softmax\n\ncategory('XGBoost', () => {\n test(`Performance: ${ROWS_K}K samples, ${COLS} features`, async () => {\n // Data\n const df = classificationDataset(ROWS_K * 1000, COLS, false);\n const features = df.columns;\n const target = features.byIndex(COLS);\n features.remove(target.name);\n\n // Fit & pack trained model\n const model = new XGBooster();\n await model.fit(features, target);\n const modelBytes = model.toBytes();\n\n // Unpack & apply model\n const unpackedModel = new XGBooster(modelBytes);\n unpackedModel.predict(features);\n }, {timeout: TIMEOUT, benchmark: true});\n\n test('Correctness', async () => {\n // Prepare data\n const df = classificationDataset(ROWS_K, MIN_COLS, true);\n const features = df.columns;\n const target = features.byIndex(MIN_COLS);\n features.remove(target.name);\n\n // Fit & pack trained model\n const model = new XGBooster();\n\n await model.fit(features, target);\n const modelBytes = model.toBytes();\n\n // Unpack & apply model\n const unpackedModel = new XGBooster(modelBytes);\n const prediction = unpackedModel.predict(features);\n\n // Evaluate accuracy\n const acc = accuracy(target, prediction);\n expect(\n acc > MIN_ACCURACY,\n true,\n `XGBoost failed, too small accuracy: ${acc}; expected: <= ${MIN_ACCURACY}`,\n );\n }, {timeout: TIMEOUT});\n}); // XGBoost\n","/** Error & info messages */\nexport enum ERROR_MSG {\n NO_DATAFRAME = 'No dataframe is opened',\n NO_MISSING_VALUES = 'No missing values',\n ONE_AVAILABLE_FEATURE = 'Not enough of feature columns to apply imputation using the KNN method',\n ONE_FEATURE_SELECTED = 'Imputation cannot be applied to',\n UNSUPPORTED_COLUMN_TYPE = 'Unsupported column type',\n UNSUPPORTED_IMPUTATION_STRATEGY = 'Unsupported imputation strategy',\n KNN_CANNOT_BE_APPLIED = 'KNN imputer cannot be applied: no columns to be used as features',\n KNN_NO_TARGET_COLUMNS = 'KNN imputer cannot be applied: no columns with missing values',\n KNN_NO_FEATURE_COLUMNS = 'KNN imputer cannot be applied: no feature columns',\n KNN_NOT_ENOUGH_OF_ROWS = 'KNN imputer cannot be applied: not enough of rows',\n KNN_IMPOSSIBLE_IMPUTATION = 'Imputation is impossible, no features can be used',\n INCORRECT_NEIGHBORS = 'Incorrect number of neighbors',\n KNN_FAILS = 'KNN IMPUTATION FAILS',\n CORE_ISSUE = 'Core issue',\n FAILED_TO_IMPUTE = 'Failed to impute',\n UNSUPPORTED_FILL_VALUE_TYPE = 'Unsupported fill value type',\n EMPTY_COLUMN = 'Column contains just null values',\n FAILS_TO_PREDICT_IMPUTATION_FAILS = 'Failed to predict imputation fails',\n WRONG_PREDICTIONS = 'wrong evaluation of KNN imputation fails',\n};\n\n/** Suffix used for column copy */\nexport const COPY_SUFFIX = 'copy';\n\n/** UI titles */\nexport enum TITLE {\n KNN_IMPUTER = 'Impute',\n TABLE = 'Table',\n IN_PLACE = 'In-place',\n COLUMNS = 'Impute',\n FEATURES = 'Using',\n CANCEL = 'CANCEL',\n RUN = 'RUN',\n OK = 'OK',\n NEIGHBORS = 'Neighbors',\n DISTANCE = 'Distance',\n FILL = 'Fill',\n MARK = 'Mark',\n SIMPLE_IMPUTER = 'Simple impute',\n SETTINGS = 'Settings',\n KEEP_EMPTY = 'Keep empty',\n};\n\n/** Help links */\nexport const KNN_IMPUTER = '/help/explore/missing-values-imputation';\n\n/** Tooltips */\nexport enum HINT {\n TARGET = 'Columns with missing values that must be filled',\n FEATURES = \"Columns with features to be used for determining the 'nearest' elements in the KNN method\",\n IN_PLACE = 'Defines whether to use in-place imputation or add a new column without missing values',\n METRIC = 'Type of metric between the feature values',\n WEIGHT = 'Weight',\n NEIGHBORS = 'Neighbors count used in the KNN method',\n DISTANCE = 'Type of distance between elements with the specified features',\n METRIC_SETTINGS = 'Show additional options',\n FILL_FAILED_ITEMS = 'Impute missing values using a simple approach: mean, median or most frequent',\n MARK_FAILED_ITEMS = 'Mark missing values cells with a color',\n FILL_VALUE = 'Fill value',\n IMPUTATION_SETTINGS = 'Simple imputation settings',\n KEEP_EMPTY = 'Defines whether to keep empty missing values failed to be imputed OR fill them using simple imputation',\n};\n","// Tools for missing values imputation using the k-nearest neighbors method\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {ERROR_MSG, COPY_SUFFIX} from './ui-constants';\n\n/** Column types supported by the missing values imputer */\nexport const SUPPORTED_COLUMN_TYPES = [\n DG.COLUMN_TYPE.INT,\n DG.COLUMN_TYPE.FLOAT,\n DG.COLUMN_TYPE.STRING,\n DG.COLUMN_TYPE.DATE_TIME,\n DG.COLUMN_TYPE.QNUM,\n] as string[];\n\n/** Return null value with respect to the column type */\nexport function getNullValue(col: DG.Column): number {\n switch (col.type) {\n case DG.COLUMN_TYPE.INT:\n return DG.INT_NULL;\n\n case DG.COLUMN_TYPE.FLOAT:\n return DG.FLOAT_NULL;\n\n case DG.COLUMN_TYPE.QNUM:\n return DG.FLOAT_NULL;\n\n case DG.COLUMN_TYPE.DATE_TIME:\n return DG.FLOAT_NULL;\n\n case DG.COLUMN_TYPE.STRING:\n return col.max;\n\n default:\n throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);\n }\n}\n\n/** Metric types (between column elements) */\nexport enum METRIC_TYPE {\n ONE_HOT = 'One-hot',\n DIFFERENCE = 'Difference',\n};\n\n/** Distance types (over several columns). */\nexport enum DISTANCE_TYPE {\n EUCLIDEAN = 'Euclidean',\n MANHATTAN = 'Manhattan',\n};\n\n/** Metric specification. */\nexport type MetricInfo = {\n weight: number,\n type: METRIC_TYPE,\n};\n\n/** Default values */\nexport enum DEFAULT {\n WEIGHT = 1,\n NEIGHBORS = 4,\n IN_PLACE = 1,\n SELECTED = 1,\n KEEP_EMPTY = 0,\n};\n\n/** Min number of neighbors for KNN */\nexport const MIN_NEIGHBORS = 1;\n\n/** Dataframe item: index - number of row, dist - distance to the target element */\ntype Item = {\n index: number,\n dist: number,\n};\n\n/** Impute missing values using the KNN method and returns an array of items for which an imputation fails */\nexport function impute(df: DG.DataFrame, targetColNames: string[], featuresMetrics: Map<string, MetricInfo>,\n missingValsIndices: Map<string, number[]>, distance: DISTANCE_TYPE, neighbors: number,\n inPlace: boolean): Map<string, number[]> {\n // 1. Check inputs completness\n\n if (neighbors < MIN_NEIGHBORS)\n throw new Error(ERROR_MSG.INCORRECT_NEIGHBORS);\n\n if (df.rowCount < 2)\n throw new Error(ERROR_MSG.KNN_NOT_ENOUGH_OF_ROWS);\n\n if (targetColNames.length === 0)\n throw new Error(ERROR_MSG.KNN_NO_TARGET_COLUMNS);\n\n if (featuresMetrics.size === 0)\n throw new Error(ERROR_MSG.KNN_NO_FEATURE_COLUMNS);\n\n if (featuresMetrics.size === 1) {\n targetColNames.forEach((name) => {\n if (featuresMetrics.has(name))\n throw new Error(`${ERROR_MSG.KNN_NO_FEATURE_COLUMNS} can be used for the column '${name}'`);\n });\n }\n\n targetColNames.forEach((name) => {\n if (!missingValsIndices.has(name))\n throw new Error(`${ERROR_MSG.KNN_FAILS}: ${ERROR_MSG.WRONG_PREDICTIONS}`);\n });\n\n const columns = df.columns;\n\n // 2. Imputation\n\n targetColNames.forEach((name) => {\n if (!SUPPORTED_COLUMN_TYPES.includes(columns.byName(name).type))\n throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);\n });\n\n featuresMetrics.forEach((val, name) => {\n if (!SUPPORTED_COLUMN_TYPES.includes(df.getCol(name).type))\n throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);\n });\n\n /** Failed to impute items */\n const failedToImpute = new Map<string, number[]>();\n\n // 2. Missing values imputation in each target column\n targetColNames.forEach((name) => {\n const col = columns.byName(name);\n const nullValue = getNullValue(col);\n const len = col.length;\n const source = col.getRawData();\n const frequencies = new Uint16Array(col.categories.length);\n\n const featureSource = [] as Array<Int32Array | Uint32Array | Float32Array | Float64Array>;\n const featureNullVal = [] as number[];\n const metricFunc = [] as ((a: number, b: number) => number)[];\n\n const failedToImputeIndices = [] as number[];\n\n // create features tools\n featuresMetrics.forEach((metricInfo, name) => {\n if (name !== col.name) {\n const feature = columns.byName(name);\n featureSource.push(feature.getRawData());\n featureNullVal.push(getNullValue(feature));\n\n switch (metricInfo.type) {\n case METRIC_TYPE.DIFFERENCE:\n metricFunc.push((a: number, b: number) => metricInfo.weight * Math.abs(a - b));\n break;\n\n case METRIC_TYPE.ONE_HOT:\n metricFunc.push((a: number, b: number) => metricInfo.weight * ((a === b) ? 0 : 1));\n break;\n\n default:\n break;\n }\n }\n });\n\n const featuresCount = featureSource.length;\n const properIndices = new Uint32Array(featureSource.length);\n const bufferVector = new Float32Array(featureSource.length);\n let properIndicesCount = 0;\n\n // closest items\n const nearestItems = new Array<Item>(neighbors);\n let nearestItemsCount = 0;\n\n // auxiliry variables\n let maxInd = 0;\n let maxDist = 0;\n let sum = 0;\n let fillValue = 0;\n\n /** Obtain proper indices for KNN: features with missing vals are skipped */\n const getProperIndeces = (idx: number) => {\n properIndicesCount = 0;\n\n for (let i = 0; i < featuresCount; ++i) {\n if (featureSource[i][idx] !== featureNullVal[i]) {\n properIndices[properIndicesCount] = i;\n ++properIndicesCount;\n }\n }\n };\n\n /** Compute buffer vector */\n const computeBufferVector = (idx: number, cur: number) => {\n properIndices.forEach((properIndex, k) => {\n bufferVector[k] = metricFunc[properIndex](featureSource[properIndex][idx], featureSource[properIndex][cur]);\n });\n };\n\n /** Euclidean distance function */\n const euclideanDistFunc = () => {\n let sum = 0;\n\n for (let i = 0; i < properIndicesCount; ++i)\n sum +=bufferVector[i] * bufferVector[i];\n\n return Math.sqrt(sum);\n };\n\n /** Manhattan distance function */\n const manhattanDistFunc = () => {\n let sum = 0;\n\n for (let i = 0; i < properIndicesCount; ++i)\n sum += Math.abs(bufferVector[i]);\n\n return Math.sqrt(sum);\n };\n\n /** Return norm of the buffer vector (distance between i-th & j-th elements) */\n const dist = (distance === DISTANCE_TYPE.EUCLIDEAN) ? euclideanDistFunc : manhattanDistFunc;\n\n /** Check if the current item (i.e. table row) can be used */\n const canItemBeUsed = (cur: number) => {\n if (source[cur] === nullValue)\n return false;\n\n for (let i = 0; i < properIndicesCount; ++i) {\n if (featureSource[properIndices[i]][cur] === featureNullVal[properIndices[i]])\n return false;\n }\n\n return true;\n };\n\n /** Return the most frequent of the nearest items (for categorial data) */\n const mostFrequentOfTheNearestItems = () => {\n frequencies.forEach((v, i, arr) => arr[i] = 0);\n let i = 0;\n\n for (i = 0; i < nearestItemsCount; ++i)\n ++frequencies[source[nearestItems[i].index]];\n\n let maxFreq = frequencies[0];\n let maxFreqIdx = 0;\n\n frequencies.forEach((v, i) => {\n if (v > maxFreq) {\n maxFreq = v;\n maxFreqIdx = i;\n }\n });\n\n return maxFreqIdx;\n };\n\n /** Get imputation value */\n const getFillValue = (idx: number) => {\n getProperIndeces(idx);\n\n // check available features\n if (properIndicesCount === 0)\n throw new Error(`${ERROR_MSG.KNN_IMPOSSIBLE_IMPUTATION}: the column \"${col.name}\", row ${idx + 1}`);\n\n nearestItemsCount = 0;\n\n // search for the closest items\n for (let cur = 0; cur < len; ++cur) {\n if (canItemBeUsed(cur) && (cur !== idx)) {\n // 1) compute distance between cur-th and idx-th items\n computeBufferVector(idx, cur);\n const curDist = dist();\n\n // 2) insert the current item\n if (nearestItemsCount < neighbors) {\n nearestItems[nearestItemsCount] = {index: cur, dist: curDist};\n ++nearestItemsCount;\n } else {\n // 2.1) find the farest\n maxInd = 0;\n maxDist = nearestItems[0].dist;\n\n for (let i = 1; i < nearestItemsCount; ++i) {\n if (maxDist < nearestItems[i].dist) {\n maxDist = nearestItems[i].dist;\n maxInd = i;\n }\n }\n\n // 2.2) replace\n if (curDist < maxDist)\n nearestItems[maxInd] = {index: cur, dist: curDist};\n } // else\n }\n } // for cur\n\n // check found nearest items\n if (nearestItemsCount === 0)\n throw new Error(`${ERROR_MSG.KNN_IMPOSSIBLE_IMPUTATION}: the column \"${col.name}\", row ${idx + 1}`);\n\n if (col.type === DG.COLUMN_TYPE.STRING)\n return mostFrequentOfTheNearestItems();\n\n // compute fill value\n sum = 0;\n for (let i = 0; i < nearestItemsCount; ++i)\n sum += source[nearestItems[i].index];\n\n fillValue = sum / nearestItemsCount;\n\n if (col.type === DG.COLUMN_TYPE.INT)\n return Math.round(fillValue);\n\n return fillValue;\n }; // getFillValue\n\n if (inPlace) {\n // use indices found previousely\n for (const i of missingValsIndices.get(name)!) {\n try {\n source[i] = getFillValue(i);\n } catch (err) {\n failedToImputeIndices.push(i);\n\n if (!(err instanceof Error))\n grok.shell.error(ERROR_MSG.CORE_ISSUE);\n }\n }\n\n if (failedToImputeIndices.length > 0)\n failedToImpute.set(name, failedToImputeIndices);\n\n // to reset view\n col.set(0, col.get(0));\n } else {\n //@ts-ignore\n const copy = col.clone();\n\n let i = 1;\n let copyName = `${name}(${COPY_SUFFIX})`;\n\n // find an appropriate name\n while (df.columns.contains(copyName)) {\n copyName = `${name}(${COPY_SUFFIX} ${i})`;\n ++i;\n }\n\n copy.name = copyName;\n\n const copySource = copy.getRawData();\n\n // use indices found previousely\n for (const i of missingValsIndices.get(name)!) {\n try {\n copySource[i] = getFillValue(i);\n } catch (err) {\n failedToImputeIndices.push(i);\n\n if (!(err instanceof Error))\n grok.shell.error(ERROR_MSG.CORE_ISSUE);\n }\n }\n\n if (failedToImputeIndices.length > 0)\n failedToImpute.set(copyName, failedToImputeIndices);\n\n copy.set(0, copy.get(0));\n\n df.columns.add(copy);\n } // else\n });\n\n return failedToImpute;\n} // impute\n\n/** Return indices of missing values for each column */\nexport function getMissingValsIndices(columns: DG.Column[]): Map<string, number[]> {\n const misValsInds = new Map<string, number[]>();\n\n for (const col of columns) {\n if (!SUPPORTED_COLUMN_TYPES.includes(col.type))\n throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);\n\n if (col.stats.missingValueCount === 0)\n continue;\n\n const indices = [] as number[];\n const nullValue = getNullValue(col);\n\n col.getRawData().forEach((val, idx) => {\n if (val === nullValue)\n indices.push(idx);\n });\n\n misValsInds.set(col.name, indices);\n }\n\n return misValsInds;\n}\n\n/** Predict existence of missing values imputation fails */\nexport function areThereFails(targetColNames: string[], featureColNames: string[],\n misValsInds: Map<string, number[]>): boolean {\n // check feature columns\n for (const name of featureColNames) {\n if (!misValsInds.has(name))\n return false;\n }\n\n // check target columns\n for (const target of targetColNames) {\n const indices = misValsInds.get(target);\n\n if (indices === undefined)\n throw new Error(ERROR_MSG.FAILS_TO_PREDICT_IMPUTATION_FAILS);\n\n for (const idx of indices) {\n let failToImpute = true;\n\n for (const feature of featureColNames) {\n const featureInds = misValsInds.get(feature);\n\n if (featureInds === undefined)\n throw new Error(ERROR_MSG.FAILS_TO_PREDICT_IMPUTATION_FAILS);\n\n if (!featureInds.includes(idx)) {\n failToImpute = false;\n break;\n }\n }\n\n if (failToImpute)\n return true;\n }\n }\n\n return false;\n} // predictFails\n\n/** Returns first non-null value */\nfunction getFirstNonNull<T>(col: DG.Column<T>): T {\n const nullValue = getNullValue(col);\n const raw = col.getRawData();\n const len = raw.length;\n\n for (let i = 0; i < len; ++i) {\n if (raw[i] !== nullValue)\n return col.get(i)!;\n }\n\n throw new Error(ERROR_MSG.EMPTY_COLUMN);\n}\n\n/** Return default fill value with respect to the column type */\nfunction getDefaultFillValue<T>(col: DG.Column<T>): T {\n switch (col.type) {\n case DG.COLUMN_TYPE.STRING:\n case DG.COLUMN_TYPE.DATE_TIME:\n return getFirstNonNull(col); // TODO: replace by most frequent\n\n case DG.COLUMN_TYPE.INT:\n case DG.COLUMN_TYPE.FLOAT:\n case DG.COLUMN_TYPE.QNUM:\n return col.stats.avg as T;\n\n default:\n throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);\n }\n}\n\n/** Perform missing values imputation using the simple approach */\nexport function imputeFailed(df: DG.DataFrame, failedToImpute: Map<string, number[]>): void {\n failedToImpute.forEach((indices, colName) => {\n const col = df.col(colName);\n if (col !== null) {\n if (!SUPPORTED_COLUMN_TYPES.includes(col.type))\n throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);\n\n const fillVal = getDefaultFillValue(col);\n indices.forEach((idx) => col.set(idx, fillVal));\n }\n });\n}\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {TITLE, KNN_IMPUTER, ERROR_MSG, HINT} from './ui-constants';\nimport {SUPPORTED_COLUMN_TYPES, METRIC_TYPE, DISTANCE_TYPE, MetricInfo, DEFAULT, MIN_NEIGHBORS,\n impute, getMissingValsIndices, areThereFails, imputeFailed} from './knn-imputer';\n\n/** Setting of the feature metric inputs */\ntype FeatureInputSettings = {\n defaultWeight: number,\n defaultMetric: METRIC_TYPE,\n availableMetrics: METRIC_TYPE[],\n};\n\n/** Return default setting of the feature metric inputs */\nexport function getFeatureInputSettings(type: DG.COLUMN_TYPE): FeatureInputSettings {\n switch (type) {\n case DG.COLUMN_TYPE.STRING:\n case DG.COLUMN_TYPE.DATE_TIME:\n return {\n defaultWeight: DEFAULT.WEIGHT,\n defaultMetric: METRIC_TYPE.ONE_HOT,\n availableMetrics: [METRIC_TYPE.ONE_HOT],\n };\n\n case DG.COLUMN_TYPE.INT:\n case DG.COLUMN_TYPE.FLOAT:\n case DG.COLUMN_TYPE.QNUM:\n return {\n defaultWeight: DEFAULT.WEIGHT,\n defaultMetric: METRIC_TYPE.DIFFERENCE,\n availableMetrics: [METRIC_TYPE.DIFFERENCE, METRIC_TYPE.ONE_HOT],\n };\n\n default:\n throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);\n }\n}\n\n/** Run the KNN missing values imputer */\nexport async function runKNNImputer(df?: DG.DataFrame): Promise<void> {\n /** current dataframe */\n df ??= grok.shell.t;\n\n if (df === null) {\n grok.shell.warning(ERROR_MSG.NO_DATAFRAME);\n return;\n }\n\n /** columns with missing values */\n const colsWithMissingVals = [] as DG.Column[];\n\n /** names of columns with missing values */\n const availableTargetColsNames = [] as string[];\n\n /** names of columns that can be used as features */\n const availableFeatureColsNames = [] as string[];\n\n // get columns with missing vals & available feature cols\n df.columns.toList()\n .filter((col) => SUPPORTED_COLUMN_TYPES.includes(col.type))\n .forEach((col) => {\n const misValsCount = col.stats.missingValueCount;\n if (misValsCount === col.length)\n return;\n\n availableFeatureColsNames.push(col.name);\n\n if (misValsCount > 0) {\n colsWithMissingVals.push(col);\n availableTargetColsNames.push(col.name);\n }\n });\n\n // get indices of missing values: col name -> array of indices\n const misValsInds = getMissingValsIndices(colsWithMissingVals);\n\n if (colsWithMissingVals.length === 0) {\n grok.shell.info(ERROR_MSG.NO_MISSING_VALUES);\n return;\n }\n\n if (availableFeatureColsNames.length === 1) {\n grok.shell.error(ERROR_MSG.ONE_AVAILABLE_FEATURE);\n return;\n }\n\n // In-place components\n let inPlace = DEFAULT.IN_PLACE > 0;\n const inPlaceInput = ui.input.bool(TITLE.IN_PLACE, {value: inPlace,\n onValueChanged: (value) => {inPlace = value ?? false;}});\n inPlaceInput.setTooltip(HINT.IN_PLACE);\n\n // Keep empty feature\n let keepEmpty = DEFAULT.KEEP_EMPTY > 0;\n const keepEmptyInput = ui.input.bool(TITLE.KEEP_EMPTY, {value: keepEmpty,\n onValueChanged: (value) => {keepEmpty = value ?? false;}});\n keepEmptyInput.setTooltip(HINT.KEEP_EMPTY);\n\n // Neighbors components\n let neighbors = DEFAULT.NEIGHBORS;\n const neighborsInput = ui.input.int(TITLE.NEIGHBORS, {\n value: neighbors,\n showPlusMinus: true,\n min: MIN_NEIGHBORS,\n nullable: false,\n onValueChanged: (value) => {\n if ((value !== null) && (value >= MIN_NEIGHBORS))\n neighbors = value;\n checkApplicability();\n },\n });\n neighborsInput.setTooltip(HINT.NEIGHBORS);\n\n // Distance components\n let distType = DISTANCE_TYPE.EUCLIDEAN;\n const distTypeInput: DG.ChoiceInput<DISTANCE_TYPE> = ui.input.choice(TITLE.DISTANCE, {\n value: distType,\n items: [DISTANCE_TYPE.EUCLIDEAN, DISTANCE_TYPE.MANHATTAN],\n onValueChanged: (value) => distType = value ?? DISTANCE_TYPE.EUCLIDEAN}) as DG.ChoiceInput<DISTANCE_TYPE>;\n distTypeInput.setTooltip(HINT.DISTANCE);\n\n // Target columns components (cols with missing values to be imputed)\n let targetColNames = colsWithMissingVals.map((col) => col.name);\n const targetColInput = ui.input.columns(TITLE.COLUMNS, {\n table: df,\n value: df.columns.byNames(availableTargetColsNames),\n onValueChanged: (value) => {\n targetColNames = value.map((col) => col.name);\n checkApplicability();\n },\n available: availableTargetColsNames,\n });\n targetColInput.setTooltip(HINT.TARGET);\n\n // Feature columns components\n let selectedFeatureColNames = availableFeatureColsNames as string[];\n const featuresInput = ui.input.columns(TITLE.FEATURES, {\n value: df.columns.byNames(availableFeatureColsNames),\n table: df, onValueChanged: (value) => {\n selectedFeatureColNames = value.map((col) => col.name);\n\n if (selectedFeatureColNames.length > 0) {\n checkApplicability();\n metricInfoInputs.forEach((div, name) => div.hidden = !selectedFeatureColNames.includes(name));\n } else\n hideWidgets();\n },\n available: availableFeatureColsNames,\n });\n featuresInput.setTooltip(HINT.FEATURES);\n\n /** Hide widgets (use if run is not applicable) */\n const hideWidgets = () => {\n dlg.getButton(TITLE.RUN).disabled = true;\n inPlaceInput.root.hidden = true;\n keepEmptyInput.root.hidden = true;\n neighborsInput.root.hidden = true;\n distDiv.hidden = true;\n metricsDiv.hidden = true;\n };\n\n /** Show widgets (use if run is applicable) */\n const showWidgets = () => {\n dlg.getButton(TITLE.RUN).disabled = (neighborsInput.value === null) || (neighborsInput.value < MIN_NEIGHBORS);\n distDiv.hidden = false;\n inPlaceInput.root.hidden = false;\n neighborsInput.root.hidden = false;\n distTypeInput.root.hidden = false;\n keepEmptyInput.root.hidden = !areThereFails(targetColNames, selectedFeatureColNames, misValsInds);\n };\n\n /** Check applicability of the imputation */\n const checkApplicability = () => {\n showWidgets();\n\n if (selectedFeatureColNames.length === 1) {\n targetColNames.forEach((name) => {\n if (selectedFeatureColNames[0] === name) {\n hideWidgets();\n grok.shell.warning(`${ERROR_MSG.ONE_FEATURE_SELECTED} the column '${name}'`);\n }\n });\n }\n\n if (targetColNames.length < 1)\n hideWidgets();\n };\n\n // Metrics components\n const featuresMetrics = new Map<string, MetricInfo>();\n const metricInfoInputs = new Map<string, HTMLDivElement>();\n const metricsDiv = ui.divV([]);\n metricsDiv.style.overflow = 'auto';\n\n // Create metrics UI\n availableFeatureColsNames.forEach((name) => {\n // initialization\n const type = df!.col(name)!.type as DG.COLUMN_TYPE;\n const settings = getFeatureInputSettings(type);\n featuresMetrics.set(name, {weight: settings.defaultWeight, type: settings.defaultMetric});\n\n // distance input\n const distTypeInput = ui.input.choice(name, {value: settings.defaultMetric,\n items: settings.availableMetrics, onValueChanged: (value) => {\n const distInfo = featuresMetrics.get(name) ?? {weight: settings.defaultWeight, type: settings.defaultMetric};\n distInfo.type = value ?? settings.defaultMetric;\n featuresMetrics.set(name, distInfo);\n }});\n distTypeInput.root.style.width = '50%';\n distTypeInput.setTooltip(HINT.METRIC);\n distTypeInput.root.hidden = true; // this input will be used further\n\n // The following should provide a slider (see th bug https://reddata.atlassian.net/browse/GROK-14431)\n const prop = DG.Property.fromOptions({\n 'name': name,\n 'inputType': 'Float',\n 'min': 0,\n 'max': 10,\n // @ts-ignore\n 'showSlider': true,\n 'step': 1,\n });\n const weightInput = ui.input.forProperty(prop);\n weightInput.value = settings.defaultWeight;\n weightInput.onChanged.subscribe((value) => {\n const distInfo = featuresMetrics.get(name) ?? {weight: settings.defaultWeight, type: settings.defaultMetric};\n distInfo.weight = value ?? settings.defaultWeight;\n featuresMetrics.set(name, distInfo);\n });\n weightInput.setTooltip(HINT.WEIGHT);\n\n const div = ui.divH([distTypeInput.root, weightInput.root]);\n metricInfoInputs.set(name, div);\n metricsDiv.append(div);\n });\n\n // The main dialog\n const dlg = ui.dialog({title: TITLE.KNN_IMPUTER, helpUrl: KNN_IMPUTER});\n grok.shell.v.root.appendChild(dlg.root);\n\n metricsDiv.hidden = true;\n keepEmptyInput.root.hidden = !areThereFails(targetColNames, selectedFeatureColNames, misValsInds);\n\n // Icon showing/hiding metrics UI\n const settingsIcon = ui.icons.settings(() => {metricsDiv.hidden = !metricsDiv.hidden;}, HINT.METRIC_SETTINGS);\n\n const distDiv = ui.divH([distTypeInput.root, settingsIcon]);\n\n let resolve: (value: void | PromiseLike<void>) => void;\n let reject: (reason?: any) => void;\n let okClicked = false;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n dlg.addButton(TITLE.RUN, () => {\n okClicked = true;\n dlg.close();\n availableFeatureColsNames.filter((name) => !selectedFeatureColNames.includes(name))\n .forEach((name) => featuresMetrics.delete(name));\n\n try {\n const failedToImpute = impute(df!, targetColNames, featuresMetrics, misValsInds, distType, neighbors, inPlace);\n\n if (!keepEmpty)\n imputeFailed(df!, failedToImpute);\n resolve();\n } catch (err) {\n if (err instanceof Error)\n grok.shell.error(`${ERROR_MSG.KNN_FAILS}: ${err.message}`);\n else\n grok.shell.error(`${ERROR_MSG.KNN_FAILS}: ${ERROR_MSG.CORE_ISSUE}`);\n reject(err);\n }\n });\n\n dlg.add(targetColInput)\n .add(featuresInput)\n .add(distDiv)\n .add(metricsDiv)\n .add(neighborsInput)\n .add(inPlaceInput)\n .add(keepEmptyInput)\n .show()\n .onClose.subscribe(() => !okClicked && resolve());\n\n return promise;\n} // runKNNImputer\n","// Tests for missing values imputation\n\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {_package} from '../package-test';\n\nimport {category, expect, test} from '@datagrok-libraries/utils/src/test';\n\nimport {MetricInfo, DISTANCE_TYPE, impute} from '../missing-values-imputation/knn-imputer';\nimport {getFeatureInputSettings} from '../missing-values-imputation/ui';\nimport {dataWithMissingVals} from './utils';\n\nconst ROWS_K = 100;\nconst K = 1000;\nconst INT_COLS = 5;\nconst FLOAT_COLS = 5;\nconst STRING_COLS = 5;\nconst MIS_VALS_COUNT = 5;\nconst NEIGHBORS = 5;\nconst TIMEOUT = 10000;\nconst TOTAL_COLS = INT_COLS + FLOAT_COLS + STRING_COLS;\n\nconst testKNN = (dist: DISTANCE_TYPE) => {\n test(`${dist} dist, ${ROWS_K}K rows, ${TOTAL_COLS} cols, ${MIS_VALS_COUNT * TOTAL_COLS} missing vals`, async () => {\n // Data\n const data = dataWithMissingVals(ROWS_K * K, INT_COLS, FLOAT_COLS, STRING_COLS, MIS_VALS_COUNT);\n const df = data.df;\n const cols = df.columns;\n\n // Inputs for kNN imputer\n const targetColNames = cols.names();\n const featuresMetrics = new Map<string, MetricInfo>();\n const missingValsIndices = data.misValsIds;\n\n // Imputation settings\n for (const col of df.columns) {\n const settings = getFeatureInputSettings(col.type as DG.COLUMN_TYPE);\n featuresMetrics.set(col.name, {\n weight: settings.defaultWeight,\n type: settings.defaultMetric,\n });\n }\n\n // Impute missing values & get fails\n const failedToImput = impute(df, targetColNames, featuresMetrics, missingValsIndices, dist, NEIGHBORS, true);\n\n // Check fails\n let fails = 0;\n failedToImput.forEach((inds, _) => fails += inds.length);\n expect(fails, 0, `Failed to impute ${fails} missing values`);\n }, {timeout: TIMEOUT, benchmark: true});\n};\n\ncategory(`Missing values imputation`, () => {\n testKNN(DISTANCE_TYPE.EUCLIDEAN);\n testKNN(DISTANCE_TYPE.MANHATTAN);\n});\n","import * as DG from 'datagrok-api/dg';\nimport {runTests, tests, TestContext} from '@datagrok-libraries/utils/src/test';\nimport './tests/dim-reduction-tests';\nimport './tests/linear-methods-tests';\nimport './tests/classifiers-tests';\nimport './tests/mis-vals-imputation-tests';\nexport const _package = new DG.Package();\nexport {tests};\n\n//name: test\n//input: string category {optional: true}\n//input: string test {optional: true}\n//input: object testContext {optional: true}\n//output: dataframe result\nexport async function test(category: string, test: string, testContext: TestContext): Promise<DG.DataFrame> {\n const data = await runTests({category, test, testContext});\n return DG.DataFrame.fromObjects(data)!;\n}\n"],"names":["_scriptDir","exportCppDbscanLib","document","currentScript","src","undefined","readyPromiseResolve","readyPromiseReject","Module","Promise","resolve","reject","readBinary","moduleOverrides","Object","assign","ENVIRONMENT_IS_WEB","window","ENVIRONMENT_IS_WORKER","importScripts","scriptDirectory","process","versions","node","self","location","href","indexOf","substr","replace","lastIndexOf","url","xhr","XMLHttpRequest","open","responseType","send","Uint8Array","console","log","bind","wasmBinary","wasmMemory","err","warn","WebAssembly","abort","HEAP8","HEAPU8","HEAPU32","ABORT","updateMemoryViews","b","buffer","Int8Array","Int16Array","Int32Array","Uint16Array","Uint32Array","Float32Array","Float64Array","__ATPRERUN__","__ATINIT__","__ATPOSTRUN__","runDependencies","runDependencyWatcher","dependenciesFulfilled","what","e","RuntimeError","wasmBinaryFile","path","isDataURI","filename","startsWith","getBinary","file","instantiateArrayBuffer","binaryFile","imports","receiver","fetch","then","credentials","response","catch","getBinaryPromise","binary","instantiate","instance","reason","callRuntimeCallbacks","callbacks","length","shift","ExceptionInfo","excPtr","this","ptr","set_type","type","get_type","set_destructor","destructor","get_destructor","set_caught","caught","get_caught","set_rethrown","rethrown","get_rethrown","init","set_adjusted_ptr","adjustedPtr","get_adjusted_ptr","get_exception_ptr","___cxa_is_pointer_type","adjusted","emscripten_realloc_buffer","size","grow","byteLength","getCFunc","ident","UTF8Decoder","TextDecoder","ccall","returnType","argTypes","args","opts","toC","str","ret","len","i","c","charCodeAt","lengthBytesUTF8","stackAlloc","outPtr","maxBytesToWrite","heap","outIdx","endIdx","u","stringToUTF8Array","stringToUTF8","stringToUTF8OnStack","arr","array","set","func","cArgs","stack","converter","stackSave","apply","stackRestore","heapOrArray","idx","maxBytesToRead","endPtr","decode","subarray","u0","u1","u2","String","fromCharCode","ch","UTF8ArrayToString","Boolean","convertReturnValue","onDone","calledRun","wasmImports","dest","num","copyWithin","requestedSize","x","oldSize","maxHeapSize","cutDown","overGrownHeapSize","Math","min","max","callback","info","receiveInstance","module","cb","exports","unshift","clearInterval","removeRunDependency","result","instantiateStreaming","createWasm","arguments","run","doRun","postRun","preRun","setTimeout","numericArgs","every","runCaller","pop","ready","define","__esModule","digestLength","blockSize","K","hashBlocks","w","v","p","pos","a","d","f","g","h","j","t1","t2","Hash","state","temp","bufferLength","bytesHashed","finished","reset","prototype","clean","update","data","dataLength","Error","dataPos","finish","out","left","bitLenHi","bitLenLo","padLength","digest","_saveState","_restoreState","from","HMAC","key","inner","outer","pad","istate","ostate","hash","hmac","fillBuffer","counter","hkdfSalt","hkdf","salt","okm","hmac_","bufpos","fill","pbkdf2","password","iterations","dkLen","prf","ctr","t","dk","k","factory","sha256","str1","str2","options","jaroDist","caseSensitive","toUpperCase","m","len1","len2","floor","str1Hash","Array","str2Hash","point","charAt","jaro","prefix","minIndex","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","id","loaded","__webpack_modules__","call","amdO","definition","o","defineProperty","enumerable","get","chunkId","globalThis","Function","hmd","create","children","obj","prop","hasOwnProperty","r","Symbol","toStringTag","value","scriptUrl","scripts","getElementsByTagName","test","baseURI","DG","grok","testData","fromCsv","columns","add","fromList","BYTE_ARRAY","thisArg","_arguments","P","generator","fulfilled","step","next","rejected","done","STANDART_TIMEOUT","BENCHMARK_TIMEOUT","stdLog","stdInfo","stdWarn","stdError","error","tests","autoTestsCatName","demoCatName","detectorsCatName","coreCatName","wasRegistered","currentCategory","assure","DimReductionMethods","StringMetricsNames","VectorMetricsNames","BitArrayMetricsNames","IntArrayMetricsNames","NumberMetricsNames","NumberArrayMetricsNames","DistanceMetricsSubjects","notNull","name","TestContext","constructor","catchUnhandled","report","Test","category","_a","timeout","push","actual","expected","tests_","clear","benchmarks","stressTests","addNamespace","s","RegExp","nqName","runTests","_b","_c","_d","package_","getCurrentCall","package","packageId","moduleTests","keys","find","dartTests","split","cat","join","fullName","isAggregated","skipReason","moduleAutoTests","moduleDemo","moduleDetectors","packFunctions","functions","filter","list","reg","demo","isArray","res","matchAll","map","forEach","parseInt","eval","wait","skip","isInBenchmark","benchmarkTimeout","friendlyName","isInDemo","view","BROWSE","createByType","clearLastError","unhandled","lastError","hasTag","col","clone","semType","initAutoTests","results","testContext","logs","redefineConsole","stressTest","_e","_f","testInvocationMap","entries","testsToInvoke","skipped","newArr","slice","sort","random","shuffle","testingObj","InvokeCategoryMethod","before","testRun","execTest","verbose","after","InvokeStressTests","categoriesToInvoke","_g","toLowerCase","exclude","some","beforeStatus","benchmark","closeAll","afterStatus","date","Date","toISOString","success","ms","params","reportTest","root","method","headers","body","JSON","stringify","InvokeAllTests","toString","invokationResult","translateStackTrace","predicate","categoryTimeout","packageName","_h","start","now","timeout_","stats","sum","df","remove","rows","removeWhere","toCsv","reduce","acc","toJson","testTimeout","timeoutReason","timeoutPromise","_","race","clearTimeout","fromColumns","fromStrings","peq","distance","tmp","n","lst","pv","mv","sc","eq","xv","myers_32","mhc","phc","hsize","ceil","vsize","vlen","pb","mb","xh","ph","mh","score","myers_x","BitArray","arg","defaultValue","_length","_version","_updateLevel","_selectedCount","_selectedCountVersion","_selectedIndexesVersion","_versionedName","_versionedNameVersion","SHRINK_THRESHOLD","buff","_createBuffer","_data","getRawData","assureGoez","argName","assureInRange","copy","dst","count","copyFrom","other","lengthInInts","version","incrementVersion","notify","versionedName","setLength","nIntsNeeded","newData","fromAnd","set1","set2","fromValues","values","fromSeq","flag","setBit","fromString","fromUint32Array","fromBytes","bytes","num1","num2","countBits","equals","getBit","bitArray","setAll","invert","flags","setIndexes","indexes","setFast","everyIndex","index","anyIndex","setWhere","check","allowClear","getRange","to","getRangeAsList","setRange","end","setTrue","setFalse","setRandom","and","andNot","notAnd","not","or","xor","insertAt","oldlength","removeAt","contains","removeByMask","mask","dstIdx","srcIdx","findNext","bit","trueCount","falseCount","_onBitCount","remainingBits","countWhere","andWithCountBits","second","allTrue","allFalse","anyTrue","anyFalse","unusedBits","numInts","_firstOnBit","findPrev","_lastOnBit","hamming","distanceF","scoringMatrix","alphabetIndexes","matrix","minCharCode","scorringArray","matrixRow","key2","index2","getDistanceF","threshold","seq1","seq2","diff","s1l","s2l","thresholdLimit","abs","defaultArgs","gapOpen","gapExtend","MmDistanceFunctionsNames","mmDistanceFunctions","HAMMING","LEVENSHTEIN","NEEDLEMANN_WUNSCH","charCodeArray","verticalGaps","horizontalGaps","prevRow","currRow","diagonal","top","maxScore","MONOMER_CHEMICAL_DISTANCE","tanimotoSimilarity","y","total","common","getDistanceFromSimilarity","similarity","Tanimoto","Dice","Asymmetric","BraunBlanquet","Cosine","Kulczynski","McConnaughey","RogotGoldberg","Russel","Sokal","Hamming","Euclidean","vectorDistanceMetricsMethods","q","pow","sqrt","stringDistanceMetricsMethods","Levenshtein","JaroWinkler","Manhattan","s1","s2","dist","Onehot","bitArrayDistanceMetricsMethods","diceSimilarity","asymmetricSimilarity","braunBlanquetSimilarity","cosineSimilarity","totalProd","kulczynskiSimilarity","mcConnaugheySimilarity","rogotGoldbergSimilarity","russelSimilarity","sokalSimilarity","intArrayDistanceMetricsMethods","TanimotoIntArray","numberDistanceMetricsMethods","Difference","range","numberArrayDistanceMetrics","CommonItems","mostCommon","Set","arr1","arr2","i1","i2","has","commonItemsCount","AvailableMetrics","Vector","MacroMolecule","Number","IntArray","NumberArray","val","ui","BYPASS_LARGE_DATA_WARNING","SHOW_SCATTERPLOT_PROGRESS","WEBGSLAGGREGATION","WEBGPUDISTANCE","MatrixMatrixOpType","MatrixOpType","MatrixScalarOpType","EUCLIDEAN","MANHATTAN","TANIMOTO","LEVENSTEIN","NEEDLEMAN_WUNSCH","SOKAL","COSINE","ASYMMETRIC","OneHot","DIMENSIONALITY_REDUCER_TERMINATE_EVENT","DistanceAggregationMethods","isNil","getEmbeddingViewerName","it","async","multiColReduceDimensionality","table","metrics","weights","preprocessingFunctions","aggregationMethod","plotEmbeddings","clusterEmbeddings","dimRedOptions","preprocessingFuncArgs","uiOptions","postProcessingFunc","postProcFuncArgs","scatterPlotProps","showXAxis","showYAxis","showXSelector","showYSelector","tv","tableView","addTableView","doReduce","pg","scatterPlotName","scatterPlot","embedColsNames","axes","colNameInd","names","includes","getEmbeddingColsNames","progressFunc","_nEpoch","epochsLength","embeddings","embedXCol","embedYCol","byName","float","rowCount","title","progress","toFixed","getDimRed","resolveF","sub","onViewerClosed","subscribe","viewer","getOptions","look","fireCustomEvent","unsubscribe","close","dimRedResPromise","encodedColEntries","pf","distanceFnArgs","colInputName","inputs","metricInputName","toList","dataCols","methodName","distanceMetrics","distanceAggregation","dimensionalityReduceRes","worker","Worker","URL","postMessage","columnsData","terminateSub","onCustomEvent","terminate","onmessage","embedding","epochNum","createMultiDimRedWorker","sumOfSquares","mean","stdDevInverse","normalize","getNormalizedEmbeddings","clusterPg","clusterRes","embedX","embedY","epsilon","minPts","clusters","getDbscanWorker","dbScanEpsilon","dbScanMinPts","clusterColName","getUnusedName","addNewString","props","colorColumnName","col1InputName","col2InputName","prepare","helpUrl","fastRowCount","onOK","onCancel","show","DEMOG_COLNAMES","SUBJ","STUDY","SITE","AGE","SEX","RACE","DISEASE","WEIGHT","HEIGHT","testDimensionalityReductionUI","demog","addedEmbeddingsCols","embedColName","isNone","isNaN","UMAP","allDemogCols","distFuncs","STRING","colNames","T_SNE","heapMap","typeMap","shiftMap","typeToColumnCreatorMap","Column","fromInt32Array","fromFloat32Array","Arg","complementArrOfParams","arrOfParams","complementArrOfTypes","arrOfTypes","allocateMemoryForBuffer","isMemoryForBufferAllocated","putDataToBuffer","getDataFromBuffer","freeBuffer","ArgColumn","targetType","toUpdate","super","buf","numOfRows","_malloc","BYTES_PER_ELEMENT","_free","ArgNewColumn","columnCreator","ArgColumns","numOfColumns","numOfBytes","numOfCols","colData","ArgNewColumns","Param","intColumn","column","newIntColumn","intColumns","newIntColumns","floatColumn","newFloatColumn","floatColumns","newFloatColumns","int","number","Return","tableFromColumns","argColumns","DataFrame","double","argColumn","funcName","funcSpecification","cppFuncInput","val1","val2","callResult","cFuncName","isEnoughOfMemoryAllocated","types","extendedTypeOfReturn","cppFuncWrapper","_callResult","output","arrayToReturn","NUM_TYPE","FLOAT_COLUMN_TYPE","INT_COLUMN_TYPE","FLOAT_COLUMNS_TYPE","NEW_FLOAT_COLUMNS_TYPE","INT_COLUMNS_TYPE","NEW_INT_COLUMNS_TYPE","NEW_FLOAT_COLUMN_TYPE","NEW_INT_COLUMN_TYPE","COLUMN","CALL_RESULT","NUM_OF_ROWS","NUM_OF_COLUMNS","REF","VALUE","TABLE_OF_COLUMNS","OBJECTS","INT_TYPE","DOUBLE_TYPE","argsSpecification","inputVals","ref","arrays","byIndex","dataFromWebWorker","funcSpecificationArgs","argsAfterWasmCall","extractNewlyCreatedData","outPut","typeToDataFieldMap","source","getOutput","clearNewlyCreatedData","COMP_MIN","MAX_ELEMENTS_COUNT","COMP_POSITVE_MES","COMP_EXCESS","DATAFRAME_IS_TOO_BIG_MES","UNSUPPORTED_COLUMN_TYPE_MES","checkColumnType","FLOAT","INT","checkMissingVals","missingValueCount","features","components","checkDimensionReducerInputs","WASM_OUTPUT_IDX","RESULT_NAMES","COMPONENTS","LINK","HINT","TITLE","ERROR_MSG","PLS_ANALYSIS","computePCA","center","scale","centerNum","scaleNum","componentsCount","EDA","_principalComponentAnalysisInWebWorker","RADIUS","COLOR","caption","MODEL","text","SCORES","LOADINGS","REGR_COEFS","EXPL_VAR","item","MVA","getPlsAnalysis","input","predict","prediction","PREDICTION","regressionCoefficients","REGR_COEFFS","tScores","T_SCORES","uScores","U_SCORES","xLoadings","X_LOADINGS","yLoadings","Y_LOADINGS","getLinearRegressionParams","targets","featuresCount","samplesCount","yAvg","avg","yStdev","stdev","nonConstFeatureColsIndeces","nonConstFeatureCols","nonConstFeatureAvgs","nonConstFeatureStdevs","nonConstFeaturesCount","tempParams","featureAvgs","featureStdDevs","targetsAvg","targetsStdDev","paramsCount","_fitLinearRegressionParamsWithDataNormalizing","paramsByPLS","getLinearRegressionParamsUsingPLS","tmpSum","getPredictionByLinearRegression","rawData","bias","weight","INTERACTIVITY","PlsModel","isApplicable","predictColumn","matches","isInteractive","MAX_FEATURES","MAX_SAMLPES","packedModel","specn","sizeArr","modelDfBytesCount","scoresDfBytesCount","modelBytes","SIZE_ARR_LEN","modelDf","fromByteArray","colsCount","scoresBytes","scores","SHIFT","featureNames","FEATURES","loadings","dim","message","fit","target","analysis","getRegrCoeffs","getLoadings","getScoresDf","computeExplVars","loadingsCols","regrCoefsCol","raw","explVar","comp","toBytes","XLOADING","modelDfBytes","toByteArray","scoresBytesCount","requiredBytes","loadingsParamsViewers","viewers","loadingsDf","xColumnName","yColumnName","markerType","CIRCLE","labels","help","barChart","splitColumnName","valueColumnName","valueAggrType","AVG","COEFFS","showValueSelector","showStackSelector","explVarsViewer","compNames","explVars","COMP","COMPS","EXPL_VARS","showCategorySelector","getScoresScatter","XSCORE","YSCORE","concat","scatter","showViewerFormulaLines","meta","formulaLines","addAll","lines","addLine","formula","radius","width","visible","color","xName","AXIS","yName","getLines","CATEGORIES","checkLen","regressionDataset","samples","dependent","randomWalk","cols","coefs","madError","mad","raw1","raw2","classificationDataset","useShift","accuracy","correctPredictions","COLS","ERROR","ROWS_K","madNorm","deviation","model","packed","AVGS_NAME","STDEVS_NAME","SoftmaxClassifier","specification","classesCount","avgs","stdevs","categories","bytesCount","avgsCol","stdevsCol","rate","penalty","tolerance","extractStats","rowsCount","cats","paramCols","iterCount","learningRate","paramsRows","paramsCols","_fitSoftmax","fitSoftmaxParams","normalized","X","transposed","preprocessedTargets","Y","oneHot","xBuf","wBuf","Z","argMax","predClass","exp","targetData","classesWeights","targetRaw","loss","RESERVED","DEFAULT","MISSING_VALUE","TITLES","XGBooster","SAMPLES_LOW","FEATURES_LOW","SAMLPES_MID","FEATURES_MID","SAMLPES_HIGH","FEATURES_HIGH","modelParams","targetCategories","offset","headerBytesSize","SIZE","headerDf","TYPE","modelParamsCount","PARAMS","categoriesBytesSize","CATS_SIZE","categoriesDf","CATS","ITERATIONS","eta","ETA","maxDepth","MAX_DEPTH","lambda","LAMBDA","alpha","ALPHA","missingValue","modelReserve","utilsLength","featuresRaw","fitInWebWorker","UTILS","floatHeap","XGBoostModule","HEAPF32","intHeap","HEAP32","featuresBuf","targetBuf","modelBuf","_predict","stringColPrediction","intColPrediction","BIG_INT","bigIntColPrediction","PREDICT","categoriesBytes","modelParamsBytesSize","headerBytes","reservedSize","PACK","maxCategory","round","rawInts","BigInt64Array","BigInt","fromBigInt64Array","COPY_SUFFIX","DATE_TIME","QNUM","getNullValue","UNSUPPORTED_COLUMN_TYPE","METRIC_TYPE","DISTANCE_TYPE","getFeatureInputSettings","defaultWeight","defaultMetric","ONE_HOT","availableMetrics","DIFFERENCE","testKNN","catsCount","misValsIds","Map","indeces","dataWithMissingVals","targetColNames","featuresMetrics","missingValsIndices","settings","failedToImput","neighbors","inPlace","INCORRECT_NEIGHBORS","KNN_NOT_ENOUGH_OF_ROWS","KNN_NO_TARGET_COLUMNS","KNN_NO_FEATURE_COLUMNS","KNN_FAILS","WRONG_PREDICTIONS","getCol","failedToImpute","nullValue","frequencies","featureSource","featureNullVal","metricFunc","failedToImputeIndices","metricInfo","feature","properIndices","bufferVector","properIndicesCount","nearestItems","nearestItemsCount","maxInd","maxDist","fillValue","computeBufferVector","cur","properIndex","canItemBeUsed","getFillValue","getProperIndeces","KNN_IMPOSSIBLE_IMPUTATION","curDist","maxFreq","maxFreqIdx","mostFrequentOfTheNearestItems","CORE_ISSUE","copyName","copySource","fails","inds","_package","fromObjects"],"sourceRoot":""}