@datagrok/eda 1.2.8 → 1.3.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.
- package/dist/738.js.map +1 -1
- package/dist/980.js.map +1 -1
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +95 -94
- package/src/package.ts +14 -25
- package/src/pls/pls-tools.ts +4 -3
- package/test-console-output-1.log +330 -0
- package/test-record-1.mp4 +0 -0
package/dist/738.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"738.js","mappings":"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","sources":["webpack://eda/./node_modules/@datagrok-libraries/math/src/dbscan/wasm/wasmDbscan.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/utils.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/type-declarations.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/vector-operations.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/typed-metrics/typed-metrics.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/distance-matrix-service.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/utils.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/heap.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/matrix.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/tree.js","webpack://eda/./node_modules/@datagrok-libraries/ml/node_modules/is-any-array/src/index.js","webpack://eda/./node_modules/@datagrok-libraries/ml/node_modules/ml-levenberg-marquardt/src/errorCalculation.js","webpack://eda/./node_modules/@datagrok-libraries/ml/node_modules/ml-levenberg-marquardt/src/step.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/umap.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/nn_descent.js","webpack://eda/./node_modules/@datagrok-libraries/ml/node_modules/ml-levenberg-marquardt/src/index.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/t-sne/t-sne.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/proxy.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/getGPUDevice.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/multi-col-knn/multiCol-KNN.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/types.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/preprocessing/webGPU-process-info.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/knn-sparse-info.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/pairwise-sparse-ops.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/errorCalculation.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/step.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/gradientFunction.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/utils.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/index.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/checkOptions.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/fuzzy-simplical-set.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/wgsl/knn-sparse-info.wgsl.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/smooth-knn-distance.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/wgsl/smooth-knn-distance.wgsl.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/WEBGPU-UMAP.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/optimization-loop.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/wgsl/optimization-loop.wgsl.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/membership-strengths.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/wgsl/membership-strengths.wgsl.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/simplical-set-embedding.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/multi-column-dim-reducer.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/mulit-column-dim-reducer-worker.js","webpack://eda/./node_modules/seedrandom/index.js","webpack://eda/./node_modules/seedrandom/lib/alea.js","webpack://eda/./node_modules/seedrandom/lib/tychei.js","webpack://eda/./node_modules/seedrandom/lib/xor128.js","webpack://eda/./node_modules/seedrandom/lib/xor4096.js","webpack://eda/./node_modules/seedrandom/lib/xorshift7.js","webpack://eda/./node_modules/seedrandom/lib/xorwow.js","webpack://eda/./node_modules/seedrandom/seedrandom.js"],"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","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","/**\n * Denotes a vector of floating poit values.\n *\n * @export\n * @class Vector\n * @extends {Float32Array}\n */\nexport class Vector extends Float32Array {\n}\n/**\n * Denotes a two-dimensional matrix.\n *\n * @export\n * @class Matrix\n * @extends {Array<Vector>}\n */\nexport class Matrix extends Array {\n}\n/**\n * Denotes cartesian coordinates.\n *\n * @export\n * @class Coordinates\n * @extends {Matrix}\n */\nexport class Coordinates extends Matrix {\n}\n/**\n * Denotes an array of arbitrary-typed vectors.\n *\n * @export\n * @class Vectors\n * @extends {Array<any>}\n */\nexport class Vectors extends Array {\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1kZWNsYXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlLWRlY2xhcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLFlBQVk7Q0FBRztBQUUzQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLEtBQWE7Q0FBRztBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sV0FBWSxTQUFRLE1BQU07Q0FBRztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sT0FBUSxTQUFRLEtBQVU7Q0FBRyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cbi8qKlxuICogRGVub3RlcyBhIHZlY3RvciBvZiBmbG9hdGluZyBwb2l0IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgVmVjdG9yXG4gKiBAZXh0ZW5kcyB7RmxvYXQzMkFycmF5fVxuICovXG5leHBvcnQgY2xhc3MgVmVjdG9yIGV4dGVuZHMgRmxvYXQzMkFycmF5IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIHR3by1kaW1lbnNpb25hbCBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE1hdHJpeFxuICogQGV4dGVuZHMge0FycmF5PFZlY3Rvcj59XG4gKi9cbmV4cG9ydCBjbGFzcyBNYXRyaXggZXh0ZW5kcyBBcnJheTxWZWN0b3I+IHt9XG5cbi8qKlxuICogRGVub3RlcyBjYXJ0ZXNpYW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIENvb3JkaW5hdGVzXG4gKiBAZXh0ZW5kcyB7TWF0cml4fVxuICovXG5leHBvcnQgY2xhc3MgQ29vcmRpbmF0ZXMgZXh0ZW5kcyBNYXRyaXgge31cblxuLyoqXG4gKiBEZW5vdGVzIGFuIGFycmF5IG9mIGFyYml0cmFyeS10eXBlZCB2ZWN0b3JzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBWZWN0b3JzXG4gKiBAZXh0ZW5kcyB7QXJyYXk8YW55Pn1cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY3RvcnMgZXh0ZW5kcyBBcnJheTxhbnk+IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIGRpY3Rpb25hcnkgY29udGFpbmluZyBmdW5jdGlvbiBvcHRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEB0eXBlIE9wdGlvbnNcbiAqL1xuZXhwb3J0IHR5cGUgT3B0aW9ucyA9IHtbbmFtZTogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBEZW5vdGVzIGN1c3RvbSBkaXN0YW5jZSBtZXRyaWMgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHR5cGUgRGlzdGFuY2VNZXRyaWNcbiAqIEBwYXJhbSB7YW55fSB2MSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHthbnl9IHYyIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICovXG5leHBvcnQgdHlwZSBEaXN0YW5jZU1ldHJpYyA9ICh2MTogYW55LCB2MjogYW55KSA9PiAobnVtYmVyKTtcblxuLyoqXG4gKiBEZW5vdGVzIGEgc2ltcGxlIHN0cmluZyB0byBzdHJpbmcgZGljdGlvbmFyeS5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAdHlwZSBTdHJpbmdEaWN0aW9uYXJ5XG4gKi9cbmV4cG9ydCB0eXBlIFN0cmluZ0RpY3Rpb25hcnkgPSB7W2tleTogc3RyaW5nXTogc3RyaW5nfTtcblxuXG5leHBvcnQgdHlwZSBDb2x1bW5JbnB1dE9wdGlvbnMgPSB7XG4gICAgZmlsdGVyPzogKGNvbDogREcuQ29sdW1uKSA9PiBib29sZWFuIHwgbnVsbDtcbn07XG4iXX0=","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=","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 { DistanceAggregationMethods } from './types';\nexport class DistanceMatrixService {\n constructor(useConcurrentWorkers = true, terminateOnComplete = true) {\n const threadCount = navigator.hardwareConcurrency;\n this._workerCount = useConcurrentWorkers ? Math.max(threadCount - 2, 1) : 1;\n this._workers = new Array(this._workerCount).fill(null)\n .map(() => new Worker(new URL('./distance-matrix-worker', import.meta.url)));\n this._terminateOnComplete = terminateOnComplete;\n }\n ;\n async calc(values, fnName, normalize = true, opts) {\n return await this.calcMulti([values], [fnName], normalize, [opts ?? {}], [1], DistanceAggregationMethods.MANHATTAN);\n }\n async calcMulti(values, fnNames, normalize = true, opts = [{}], weights = [1], aggregationMethod = DistanceAggregationMethods.MANHATTAN) {\n if (values.length < 1)\n throw new Error('values must contain at least one array');\n if (fnNames.length !== values.length || opts.length !== values.length || weights.length !== values.length)\n throw new Error('values, fnNames, weights and opts must have the same length');\n return new Promise(async (resolve, reject) => {\n try {\n const len = values[0].length;\n const promises = new Array(this._workerCount);\n const totalLength = len * (len - 1) / 2; // size of reduced distance matrix\n this._workerCount = Math.min(this._workerCount, totalLength);\n const chunkSize = totalLength / this._workerCount;\n const distanceMatrix = new Float32Array(totalLength);\n let endRow = 0;\n let endCol = 1;\n // minmax for normalization\n let lmin = 0;\n let lmax = Number.MIN_VALUE;\n for (let i = 0; i < this._workerCount; i++) {\n const start = Math.floor(i * chunkSize);\n const end = (i === this._workerCount - 1) ? totalLength : Math.floor((i + 1) * chunkSize);\n const startRow = endRow;\n const startCol = endCol;\n if (i !== this._workerCount - 1) {\n // These formulas map the linear index to the upper triangular matrix indices\n endRow = len - 2 - Math.floor(Math.sqrt(-8 * end + 4 * len * (len - 1) - 7) / 2 - 0.5);\n endCol = end - len * endRow + Math.floor((endRow + 1) * (endRow + 2) / 2);\n }\n this._workers[i].postMessage({ values, fnNames, startRow, startCol, chunckSize: end - start, opts, weights, aggregationMethod });\n promises[i] = new Promise((resolveWorker, rejectWorker) => {\n this._workers[i].onmessage = ({ data: { error, distanceMatrixData, min, max } }) => {\n this._terminateOnComplete && setTimeout(() => this._workers[i].terminate());\n if (error) {\n rejectWorker(error);\n }\n else {\n distanceMatrix.set(distanceMatrixData, start);\n if (min < lmin)\n lmin = min;\n if (max > lmax)\n lmax = max;\n resolveWorker();\n }\n };\n });\n }\n await Promise.all(promises);\n if (normalize)\n distanceMatrix.forEach((value, index) => { distanceMatrix[index] = (value - lmin) / (lmax - lmin); });\n resolve(distanceMatrix);\n }\n catch (e) {\n reject(e);\n }\n });\n }\n terminate() {\n this._workers.forEach((worker) => worker.terminate());\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWF0cml4LXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkaXN0YW5jZS1tYXRyaXgtc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQTRCLDBCQUEwQixFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRTlFLE1BQU0sT0FBTyxxQkFBcUI7SUFJOUIsWUFBbUIsb0JBQW9CLEdBQUcsSUFBSSxFQUFFLG1CQUFtQixHQUFHLElBQUk7UUFDeEUsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLG1CQUFtQixDQUFDO1FBQ2xELElBQUksQ0FBQyxZQUFZLEdBQUcsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDcEQsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLDBCQUEwQixFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9FLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxtQkFBbUIsQ0FBQztJQUNsRCxDQUFDO0lBQUEsQ0FBQztJQUVLLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBc0IsRUFBRSxNQUFvQixFQUM1RCxTQUFTLEdBQUcsSUFBSSxFQUFFLElBQXlCO1FBQzNDLE9BQU8sTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFTLEVBQ3ZELENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsMEJBQTBCLENBQUMs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QUFJLFNBQVM7b0JBQ1gsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4RyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDMUIsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ1osQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFNBQVM7UUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtLbm93bk1ldHJpY3N9IGZyb20gJy4uL3R5cGVkLW1ldHJpY3MnO1xuaW1wb3J0IHtEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kLCBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kc30gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBEaXN0YW5jZU1hdHJpeFNlcnZpY2Uge1xuICAgIHByaXZhdGUgX3dvcmtlcnM6IFdvcmtlcltdO1xuICAgIHByaXZhdGUgX3dvcmtlckNvdW50OiBudW1iZXI7XG4gICAgcHJpdmF0ZSBfdGVybWluYXRlT25Db21wbGV0ZTogYm9vbGVhbjtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IodXNlQ29uY3VycmVudFdvcmtlcnMgPSB0cnVlLCB0ZXJtaW5hdGVPbkNvbXBsZXRlID0gdHJ1ZSkge1xuICAgICAgY29uc3QgdGhyZWFkQ291bnQgPSBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeTtcbiAgICAgIHRoaXMuX3dvcmtlckNvdW50ID0gdXNlQ29uY3VycmVudFdvcmtlcnMgPyBNYXRoLm1heCh0aHJlYWRDb3VudCAtIDIsIDEpIDogMTtcbiAgICAgIHRoaXMuX3dvcmtlcnMgPSBuZXcgQXJyYXkodGhpcy5fd29ya2VyQ291bnQpLmZpbGwobnVsbClcbiAgICAgICAgLm1hcCgoKSA9PiBuZXcgV29ya2VyKG5ldyBVUkwoJy4vZGlzdGFuY2UtbWF0cml4LXdvcmtlcicsIGltcG9ydC5tZXRhLnVybCkpKTtcbiAgICAgIHRoaXMuX3Rlcm1pbmF0ZU9uQ29tcGxldGUgPSB0ZXJtaW5hdGVPbkNvbXBsZXRlO1xuICAgIH07XG5cbiAgICBwdWJsaWMgYXN5bmMgY2FsYyh2YWx1ZXM6IEFycmF5TGlrZTxhbnk+LCBmbk5hbWU6IEtub3duTWV0cmljcyxcbiAgICAgIG5vcm1hbGl6ZSA9IHRydWUsIG9wdHM/OiB7W186IHN0cmluZ106IGFueX0pOiBQcm9taXNlPEZsb2F0MzJBcnJheT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2FsY011bHRpKFt2YWx1ZXNdLCBbZm5OYW1lXSwgbm9ybWFsaXplLFxuICAgICAgICBbb3B0cyA/PyB7fV0sIFsxXSwgRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZHMuTUFOSEFUVEFOKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgY2FsY011bHRpKFxuICAgICAgdmFsdWVzOiBBcnJheUxpa2U8YW55PltdLCBmbk5hbWVzOiBLbm93bk1ldHJpY3NbXSxcbiAgICAgIG5vcm1hbGl6ZSA9IHRydWUsIG9wdHM6IHtbXzogc3RyaW5nXTogYW55fVtdID0gW3t9XSxcbiAgICAgIHdlaWdodHM6IG51bWJlcltdID0gWzFdLCBhZ2dyZWdhdGlvbk1ldGhvZDogRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCA9IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2RzLk1BTkhBVFRBTlxuICAgICk6IFByb21pc2U8RmxvYXQzMkFycmF5PiB7XG4gICAgICBpZiAodmFsdWVzLmxlbmd0aCA8IDEpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndmFsdWVzIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgYXJyYXknKTtcbiAgICAgIGlmIChmbk5hbWVzLmxlbmd0aCAhPT0gdmFsdWVzLmxlbmd0aCB8fCBvcHRzLmxlbmd0aCAhPT0gdmFsdWVzLmxlbmd0aCB8fCB3ZWlnaHRzLmxlbmd0aCAhPT0gdmFsdWVzLmxlbmd0aClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd2YWx1ZXMsIGZuTmFtZXMsIHdlaWdodHMgYW5kIG9wdHMgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aCcpO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBsZW4gPSB2YWx1ZXNbMF0ubGVuZ3RoO1xuICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dm9pZD4+KHRoaXMuX3dvcmtlckNvdW50KTtcbiAgICAgICAgICBjb25zdCB0b3RhbExlbmd0aCA9IGxlbiAqIChsZW4gLSAxKSAvIDI7IC8vIHNpemUgb2YgcmVkdWNlZCBkaXN0YW5jZSBtYXRyaXhcbiAgICAgICAgICB0aGlzLl93b3JrZXJDb3VudCA9IE1hdGgubWluKHRoaXMuX3dvcmtlckNvdW50LCB0b3RhbExlbmd0aCk7XG4gICAgICAgICAgY29uc3QgY2h1bmtTaXplID0gdG90YWxMZW5ndGggLyB0aGlzLl93b3JrZXJDb3VudDtcbiAgICAgICAgICBjb25zdCBkaXN0YW5jZU1hdHJpeCA9IG5ldyBGbG9hdDMyQXJyYXkodG90YWxMZW5ndGgpO1xuICAgICAgICAgIGxldCBlbmRSb3cgPSAwO1xuICAgICAgICAgIGxldCBlbmRDb2wgPSAxO1xuICAgICAgICAgIC8vIG1pbm1heCBmb3Igbm9ybWFsaXphdGlvblxuICAgICAgICAgIGxldCBsbWluID0gMDtcbiAgICAgICAgICBsZXQgbG1heCA9IE51bWJlci5NSU5fVkFMVUU7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl93b3JrZXJDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IE1hdGguZmxvb3IoaSAqIGNodW5rU2l6ZSk7XG4gICAgICAgICAgICBjb25zdCBlbmQgPSAoaSA9PT0gdGhpcy5fd29ya2VyQ291bnQgLSAxKSA/IHRvdGFsTGVuZ3RoIDogTWF0aC5mbG9vcigoaSArIDEpICogY2h1bmtTaXplKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0Um93ID0gZW5kUm93O1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRDb2wgPSBlbmRDb2w7XG4gICAgICAgICAgICBpZiAoaSAhPT0gdGhpcy5fd29ya2VyQ291bnQgLSAxKSB7XG4gICAgICAgICAgICAgIC8vIFRoZXNlIGZvcm11bGFzIG1hcCB0aGUgbGluZWFyIGluZGV4IHRvIHRoZSB1cHBlciB0cmlhbmd1bGFyIG1hdHJpeCBpbmRpY2VzXG4gICAgICAgICAgICAgIGVuZFJvdyA9IGxlbiAtIDIgLSBNYXRoLmZsb29yKE1hdGguc3FydCgtOCAqIGVuZCArIDQgKiBsZW4gKiAobGVuIC0gMSkgLSA3KSAvIDIgLSAwLjUpO1xuICAgICAgICAgICAgICBlbmRDb2wgPSBlbmQgLSBsZW4gKiBlbmRSb3cgKyBNYXRoLmZsb29yKChlbmRSb3cgKyAxKSAqIChlbmRSb3cgKyAyKSAvIDIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fd29ya2Vyc1tpXS5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAge3ZhbHVlcywgZm5OYW1lcywgc3RhcnRSb3csIHN0YXJ0Q29sLCBjaHVuY2tTaXplOiBlbmQgLSBzdGFydCwgb3B0cywgd2VpZ2h0cywgYWdncmVnYXRpb25NZXRob2R9XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcHJvbWlzZXNbaV0gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZVdvcmtlciwgcmVqZWN0V29ya2VyKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuX3dvcmtlcnNbaV0ub25tZXNzYWdlID0gKHtkYXRhOiB7ZXJyb3IsIGRpc3RhbmNlTWF0cml4RGF0YSwgbWluLCBtYXh9fSk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Rlcm1pbmF0ZU9uQ29tcGxldGUgJiYgc2V0VGltZW91dCgoKSA9PiB0aGlzLl93b3JrZXJzW2ldLnRlcm1pbmF0ZSgpKTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIHJlamVjdFdvcmtlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGRpc3RhbmNlTWF0cml4LnNldChkaXN0YW5jZU1hdHJpeERhdGEsIHN0YXJ0KTtcbiAgICAgICAgICAgICAgICAgIGlmIChtaW4gPCBsbWluKVxuICAgICAgICAgICAgICAgICAgICBsbWluID0gbWluO1xuICAgICAgICAgICAgICAgICAgaWYgKG1heCA+IGxtYXgpXG4gICAgICAgICAgICAgICAgICAgIGxtYXggPSBtYXg7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlV29ya2VyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgICBpZiAobm9ybWFsaXplKVxuICAgICAgICAgICAgZGlzdGFuY2VNYXRyaXguZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7IGRpc3RhbmNlTWF0cml4W2luZGV4XSA9ICh2YWx1ZSAtIGxtaW4pIC8gKGxtYXggLSBsbWluKTsgfSk7XG4gICAgICAgICAgcmVzb2x2ZShkaXN0YW5jZU1hdHJpeCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyB0ZXJtaW5hdGUoKTogdm9pZCB7XG4gICAgICB0aGlzLl93b3JrZXJzLmZvckVhY2goKHdvcmtlcikgPT4gd29ya2VyLnRlcm1pbmF0ZSgpKTtcbiAgICB9XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * Simple random integer function\n */\nexport function tauRandInt(n, random) {\n return Math.floor(random() * n);\n}\n/**\n * Simple random float function\n */\nexport function tauRand(random) {\n return random();\n}\n/**\n * Compute the (standard l2) norm of a vector.\n */\nexport function norm(vec) {\n let result = 0;\n for (const item of vec)\n result += item ** 2;\n return Math.sqrt(result);\n}\n/**\n * Creates an empty array (filled with undefined)\n */\nexport function empty(n) {\n const output = [];\n for (let i = 0; i < n; i++)\n output.push(undefined);\n return output;\n}\n/**\n * Creates an array filled with index values\n */\nexport function range(n) {\n return empty(n).map((_, i) => i);\n}\n/**\n * Creates an array filled with a specific value\n */\nexport function filled(n, v) {\n return empty(n).map(() => v);\n}\n/**\n * Creates an array filled with zeros\n */\nexport function zeros(n) {\n return filled(n, 0);\n}\n/**\n * Creates an array filled with ones\n */\nexport function ones(n) {\n return filled(n, 1);\n}\n/**\n * Creates an array from a to b, of length len, inclusive\n */\nexport function linear(a, b, len) {\n return empty(len).map((_, i) => {\n return a + i * ((b - a) / (len - 1));\n });\n}\n/**\n * Returns the sum of an array\n */\nexport function sum(input) {\n return input.reduce((sum, val) => sum + val);\n}\n/**\n * Returns the mean of an array\n */\nexport function mean(input) {\n return sum(input) / input.length;\n}\n/**\n * Returns the maximum value of an array\n */\nexport function max(input) {\n let max = 0;\n for (let i = 0; i < input.length; i++)\n max = input[i] > max ? input[i] : max;\n return max;\n}\n/**\n * Returns the maximum value of a 2d array\n */\nexport function max2d(input) {\n let max = 0;\n for (let i = 0; i < input.length; i++) {\n for (let j = 0; j < input[i].length; j++)\n max = input[i][j] > max ? input[i][j] : max;\n }\n return max;\n}\n/**\n * Generate nSamples many integers from 0 to poolSize such that no\n * integer is selected twice. The duplication constraint is achieved via\n * rejection sampling.\n */\nexport function rejectionSample(nSamples, poolSize, random) {\n const result = zeros(nSamples);\n for (let i = 0; i < nSamples; i++) {\n let rejectSample = true;\n while (rejectSample) {\n const j = tauRandInt(poolSize, random);\n let broken = false;\n for (let k = 0; k < i; k++) {\n if (j === result[k]) {\n broken = true;\n break;\n }\n }\n if (!broken)\n rejectSample = false;\n result[i] = j;\n }\n }\n return result;\n}\n/**\n * Reshapes a 1d array into a 2D of given dimensions.\n */\nexport function reshape2d(x, a, b) {\n const rows = [];\n // let count = 0;\n let index = 0;\n if (x.length !== a * b)\n throw new Error('Array dimensions must match input length.');\n for (let i = 0; i < a; i++) {\n const col = [];\n for (let j = 0; j < b; j++) {\n col.push(x[index]);\n index += 1;\n }\n rows.push(col);\n // count += 1;\n }\n return rows;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFJSDs7R0FFRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsQ0FBUyxFQUFFLE1BQWdCO0lBQ3BELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLE1BQWdCO0lBQ3RDLE9BQU8sTUFBTSxFQUFFLENBQUM7QUFDbEIsQ0FBQztBQUNEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FBQyxHQUFhO0lBQ2hDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNmLEtBQUssTUFBTSxJQUFJLElBQUksR0FBRztRQUNwQixNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQztJQUV0QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLEtBQUssQ0FBQyxDQUFTO0lBQzdCLE1BQU0sTUFBTSxHQUFnQixFQUFFLENBQUM7SUFDL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUU7UUFDeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV6QixPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsS0FBSyxDQUFDLENBQVM7SUFDN0IsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxV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QztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDZixjQUFjO0lBQ2hCLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQge1JhbmRvbUZufSBmcm9tICcuL3VtYXAnO1xuXG4vKipcbiAqIFNpbXBsZSByYW5kb20gaW50ZWdlciBmdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdGF1UmFuZEludChuOiBudW1iZXIsIHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IocmFuZG9tKCkgKiBuKTtcbn1cblxuLyoqXG4gKiBTaW1wbGUgcmFuZG9tIGZsb2F0IGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0YXVSYW5kKHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIHJhbmRvbSgpO1xufVxuLyoqXG4gKiBDb21wdXRlIHRoZSAoc3RhbmRhcmQgbDIpIG5vcm0gb2YgYSB2ZWN0b3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtKHZlYzogbnVtYmVyW10pIHtcbiAgbGV0IHJlc3VsdCA9IDA7XG4gIGZvciAoY29uc3QgaXRlbSBvZiB2ZWMpXG4gICAgcmVzdWx0ICs9IGl0ZW0gKiogMjtcblxuICByZXR1cm4gTWF0aC5zcXJ0KHJlc3VsdCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBlbXB0eSBhcnJheSAoZmlsbGVkIHdpdGggdW5kZWZpbmVkKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZW1wdHkobjogbnVtYmVyKTogdW5kZWZpbmVkW10ge1xuICBjb25zdCBvdXRwdXQ6IHVuZGVmaW5lZFtdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKVxuICAgIG91dHB1dC5wdXNoKHVuZGVmaW5lZCk7XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGluZGV4IHZhbHVlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2UobjogbnVtYmVyKTogbnVtYmVyW10ge1xuICByZXR1cm4gZW1wdHkobikubWFwKChfLCBpKSA9PiBpKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGEgc3BlY2lmaWMgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGxlZChuOiBudW1iZXIsIHY6IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGVtcHR5KG4pLm1hcCgoKSA9PiB2KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIHplcm9zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvcyhuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBmaWxsZWQobiwgMCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBmaWxsZWQgd2l0aCBvbmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVzKG46IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGZpbGxlZChuLCAxKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZyb20gYSB0byBiLCBvZiBsZW5ndGggbGVuLCBpbmNsdXNpdmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhcihhOiBudW1iZXIsIGI6IG51bWJlciwgbGVuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBlbXB0eShsZW4pLm1hcCgoXywgaSkgPT4ge1xuICAgIHJldHVybiBhICsgaSAqICgoYiAtIGEpIC8gKGxlbiAtIDEpKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3VtIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdW0oaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgcmV0dXJuIGlucHV0LnJlZHVjZSgoc3VtLCB2YWwpID0+IHN1bSArIHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWVhbiBvZiBhbiBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVhbihpbnB1dDogbnVtYmVyW10pOiBudW1iZXIge1xuICByZXR1cm4gc3VtKGlucHV0KSAvIGlucHV0Lmxlbmd0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgoaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgbGV0IG1heCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspXG4gICAgbWF4ID0gaW5wdXRbaV0gPiBtYXggPyBpbnB1dFtpXSA6IG1heDtcblxuICByZXR1cm4gbWF4O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUgb2YgYSAyZCBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF4MmQoaW5wdXQ6IG51bWJlcltdW10pOiBudW1iZXIge1xuICBsZXQgbWF4ID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRbaV0ubGVuZ3RoOyBqKyspXG4gICAgICBtYXggPSBpbnB1dFtpXVtqXSA+IG1heCA/IGlucHV0W2ldW2pdIDogbWF4O1xuICB9XG4gIHJldHVybiBtYXg7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgblNhbXBsZXMgbWFueSBpbnRlZ2VycyBmcm9tIDAgdG8gcG9vbFNpemUgc3VjaCB0aGF0IG5vXG4gKiBpbnRlZ2VyIGlzIHNlbGVjdGVkIHR3aWNlLiBUaGUgZHVwbGljYXRpb24gY29uc3RyYWludCBpcyBhY2hpZXZlZCB2aWFcbiAqIHJlamVjdGlvbiBzYW1wbGluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlamVjdGlvblNhbXBsZShcbiAgblNhbXBsZXM6IG51bWJlcixcbiAgcG9vbFNpemU6IG51bWJlcixcbiAgcmFuZG9tOiBSYW5kb21GblxuKTogbnVtYmVyW10ge1xuICBjb25zdCByZXN1bHQgPSB6ZXJvcyhuU2FtcGxlcyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgblNhbXBsZXM7IGkrKykge1xuICAgIGxldCByZWplY3RTYW1wbGUgPSB0cnVlO1xuICAgIHdoaWxlIChyZWplY3RTYW1wbGUpIHtcbiAgICAgIGNvbnN0IGogPSB0YXVSYW5kSW50KHBvb2xTaXplLCByYW5kb20pO1xuICAgICAgbGV0IGJyb2tlbiA9IGZhbHNlO1xuICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBpOyBrKyspIHtcbiAgICAgICAgaWYgKGogPT09IHJlc3VsdFtrXSkge1xuICAgICAgICAgIGJyb2tlbiA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghYnJva2VuKVxuICAgICAgICByZWplY3RTYW1wbGUgPSBmYWxzZTtcblxuICAgICAgcmVzdWx0W2ldID0gajtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBSZXNoYXBlcyBhIDFkIGFycmF5IGludG8gYSAyRCBvZiBnaXZlbiBkaW1lbnNpb25zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzaGFwZTJkPFQ+KHg6IFRbXSwgYTogbnVtYmVyLCBiOiBudW1iZXIpOiBUW11bXSB7XG4gIGNvbnN0IHJvd3M6IFRbXVtdID0gW107XG4gIC8vIGxldCBjb3VudCA9IDA7XG4gIGxldCBpbmRleCA9IDA7XG5cbiAgaWYgKHgubGVuZ3RoICE9PSBhICogYilcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FycmF5IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCBpbnB1dCBsZW5ndGguJyk7XG5cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGE7IGkrKykge1xuICAgIGNvbnN0IGNvbDogVFtdID0gW107XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBiOyBqKyspIHtcbiAgICAgIGNvbC5wdXNoKHhbaW5kZXhdKTtcbiAgICAgIGluZGV4ICs9IDE7XG4gICAgfVxuICAgIHJvd3MucHVzaChjb2wpO1xuICAgIC8vIGNvdW50ICs9IDE7XG4gIH1cbiAgcmV0dXJuIHJvd3M7XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\nimport * as utils from './utils';\n/**\n * Constructor for the heap objects. The heaps are used\n * for approximate nearest neighbor search, maintaining a list of potential\n * neighbors sorted by their distance. We also flag if potential neighbors\n * are newly added to the list or not. Internally this is stored as\n * a single array; the first axis determines whether we are looking at the\n * array of candidate indices, the array of distances, or the flag array for\n * whether elements are new or not. Each of these arrays are of shape\n * (``nPoints``, ``size``)\n */\nexport function makeHeap(nPoints, size) {\n const makeArrays = (fillValue) => {\n return utils.empty(nPoints).map(() => {\n return utils.filled(size, fillValue);\n });\n };\n const heap = [];\n heap.push(makeArrays(-1));\n heap.push(makeArrays(Infinity));\n heap.push(makeArrays(0));\n return heap;\n}\n/**\n * Generate n_samples many integers from 0 to pool_size such that no\n * integer is selected twice. The duplication constraint is achieved via\n * rejection sampling.\n */\nexport function rejectionSample(nSamples, poolSize, random) {\n const result = utils.zeros(nSamples);\n for (let i = 0; i < nSamples; i++) {\n let rejectSample = true;\n let j = 0;\n while (rejectSample) {\n j = utils.tauRandInt(poolSize, random);\n let broken = false;\n for (let k = 0; k < i; k++) {\n if (j === result[k]) {\n broken = true;\n break;\n }\n }\n if (!broken)\n rejectSample = false;\n }\n result[i] = j;\n }\n return result;\n}\n/**\n * Push a new element onto the heap. The heap stores potential neighbors\n * for each data point. The ``row`` parameter determines which data point we\n * are addressing, the ``weight`` determines the distance (for heap sorting),\n * the ``index`` is the element to add, and the flag determines whether this\n * is to be considered a new addition.\n */\nexport function heapPush(heap, row, weight, index, flag) {\n row = Math.floor(row);\n const indices = heap[0][row];\n const weights = heap[1][row];\n //const isNew = heap[2][row];\n if (weight >= weights[0])\n return 0;\n // Break if we already have this element.\n for (let i = 0; i < indices.length; i++) {\n if (index === indices[i])\n return 0;\n }\n return uncheckedHeapPush(heap, row, weight, index, flag);\n}\n/**\n * Push a new element onto the heap. The heap stores potential neighbors\n * for each data point. The ``row`` parameter determines which data point we\n * are addressing, the ``weight`` determines the distance (for heap sorting),\n * the ``index`` is the element to add, and the flag determines whether this\n * is to be considered a new addition.\n */\nexport function uncheckedHeapPush(heap, row, weight, index, flag) {\n const indices = heap[0][row];\n const weights = heap[1][row];\n const isNew = heap[2][row];\n if (weight >= weights[0])\n return 0;\n // Insert val at position zero\n weights[0] = weight;\n indices[0] = index;\n isNew[0] = flag;\n // Descend the heap, swapping values until the max heap criterion is met\n let i = 0;\n let iSwap = 0;\n while (true) {\n const ic1 = 2 * i + 1;\n const ic2 = ic1 + 1;\n const heapShape2 = heap[0][0].length;\n if (ic1 >= heapShape2) {\n break;\n }\n else if (ic2 >= heapShape2) {\n if (weights[ic1] > weight)\n iSwap = ic1;\n else\n break;\n }\n else if (weights[ic1] >= weights[ic2]) {\n if (weight < weights[ic1])\n iSwap = ic1;\n else\n break;\n }\n else {\n if (weight < weights[ic2])\n iSwap = ic2;\n else\n break;\n }\n weights[i] = weights[iSwap];\n indices[i] = indices[iSwap];\n isNew[i] = isNew[iSwap];\n i = iSwap;\n }\n weights[i] = weight;\n indices[i] = index;\n isNew[i] = flag;\n return 1;\n}\n/**\n * Build a heap of candidate neighbors for nearest neighbor descent. For\n * each vertex the candidate neighbors are any current neighbors, and any\n * vertices that have the vertex as one of their nearest neighbors.\n */\nexport function buildCandidates(currentGraph, nVertices, nNeighbors, maxCandidates, random) {\n const candidateNeighbors = makeHeap(nVertices, maxCandidates);\n for (let i = 0; i < nVertices; i++) {\n for (let j = 0; j < nNeighbors; j++) {\n if (currentGraph[0][i][j] < 0)\n continue;\n const idx = currentGraph[0][i][j];\n const isn = currentGraph[2][i][j];\n const d = utils.tauRand(random);\n heapPush(candidateNeighbors, i, d, idx, isn);\n heapPush(candidateNeighbors, idx, d, i, isn);\n currentGraph[2][i][j] = 0;\n }\n }\n return candidateNeighbors;\n}\n/**\n * Given an array of heaps (of indices and weights), unpack the heap\n * out to give and array of sorted lists of indices and weights by increasing\n * weight. This is effectively just the second half of heap sort (the first\n * half not being required since we already have the data in a heap).\n */\nexport function deheapSort(heap) {\n const indices = heap[0];\n const weights = heap[1];\n for (let i = 0; i < indices.length; i++) {\n const indHeap = indices[i];\n const distHeap = weights[i];\n for (let j = 0; j < indHeap.length - 1; j++) {\n const indHeapIndex = indHeap.length - j - 1;\n const distHeapIndex = distHeap.length - j - 1;\n const temp1 = indHeap[0];\n indHeap[0] = indHeap[indHeapIndex];\n indHeap[indHeapIndex] = temp1;\n const temp2 = distHeap[0];\n distHeap[0] = distHeap[distHeapIndex];\n distHeap[distHeapIndex] = temp2;\n siftDown(distHeap, indHeap, distHeapIndex, 0);\n }\n }\n return { indices, weights };\n}\n/**\n * Restore the heap property for a heap with an out of place element\n * at position ``elt``. This works with a heap pair where heap1 carries\n * the weights and heap2 holds the corresponding elements.\n */\nfunction siftDown(heap1, heap2, ceiling, elt) {\n while (elt * 2 + 1 < ceiling) {\n const leftChild = elt * 2 + 1;\n const rightChild = leftChild + 1;\n let swap = elt;\n if (heap1[swap] < heap1[leftChild])\n swap = leftChild;\n if (rightChild < ceiling && heap1[swap] < heap1[rightChild])\n swap = rightChild;\n if (swap === elt) {\n break;\n }\n else {\n const temp1 = heap1[elt];\n heap1[elt] = heap1[swap];\n heap1[swap] = temp1;\n const temp2 = heap2[elt];\n heap2[elt] = heap2[swap];\n heap2[swap] = temp2;\n elt = swap;\n }\n }\n}\n/**\n * Search the heap for the smallest element that is still flagged.\n */\nexport function smallestFlagged(heap, row) {\n const ind = heap[0][row];\n const dist = heap[1][row];\n const flag = heap[2][row];\n let minDist = Infinity;\n let resultIndex = -1;\n for (let i = 0; i > ind.length; i++) {\n if (flag[i] === 1 && dist[i] < minDist) {\n minDist = dist[i];\n resultIndex = i;\n }\n }\n if (resultIndex >= 0) {\n flag[resultIndex] = 0;\n return Math.floor(ind[resultIndex]);\n }\n else {\n return -1;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhlYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBMkNILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsT0FBZSxFQUFFLElBQVk7SUFDcEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxTQUFpQixFQUFFLEVBQUU7UUFDdkMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDbkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztJQUVGLE1BQU0sSUFBSSxHQUFTLEVBQUUsQ0FBQztJQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUM3QixRQUFnQixFQUNoQixRQUFnQixFQUNoQixNQUFnQjtJQUVoQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNsQyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDeEIsSUFBSSxDQUFDLEdBQUcs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SUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUxQixJQUFJLE9BQU8sR0FBRyxRQUFRLENBQUM7SUFDdkIsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNwQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO1lBQ3ZDLE9BQU8sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEIsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksV0FBVyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7U0FBTSxDQUFDO1FBQ04sT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNaLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgSmF2YVNjcmlwdCByZWltcGxlbWVudGF0aW9uIG9mIFVNQVAgKG9yaWdpbmFsIGxpY2Vuc2UgYmVsb3cpLCBmcm9tXG4gKiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9sbWNpbm5lcy91bWFwLlxuICpcbiAqIEBhdXRob3IgYW5keWNvZW5lbkBnb29nbGUuY29tIChBbmR5IENvZW5lbilcbiAqL1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBCU0QgMy1DbGF1c2UgTGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNywgTGVsYW5kIE1jSW5uZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4gKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcbiAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXG4gKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcbiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuaW1wb3J0IHtSYW5kb21Gbn0gZnJvbSAnLi91bWFwJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgdHlwZSBIZWFwID0gbnVtYmVyW11bXVtdO1xuXG4vKipcbiAqICBDb25zdHJ1Y3RvciBmb3IgdGhlIGhlYXAgb2JqZWN0cy4gVGhlIGhlYXBzIGFyZSB1c2VkXG4gKiBmb3IgYXBwcm94aW1hdGUgbmVhcmVzdCBuZWlnaGJvciBzZWFyY2gsIG1haW50YWluaW5nIGEgbGlzdCBvZiBwb3RlbnRpYWxcbiAqIG5laWdoYm9ycyBzb3J0ZWQgYnkgdGhlaXIgZGlzdGFuY2UuIFdlIGFsc28gZmxhZyBpZiBwb3RlbnRpYWwgbmVpZ2hib3JzXG4gKiBhcmUgbmV3bHkgYWRkZWQgdG8gdGhlIGxpc3Qgb3Igbm90LiBJbnRlcm5hbGx5IHRoaXMgaXMgc3RvcmVkIGFzXG4gKiBhIHNpbmdsZSBhcnJheTsgdGhlIGZpcnN0IGF4aXMgZGV0ZXJtaW5lcyB3aGV0aGVyIHdlIGFyZSBsb29raW5nIGF0IHRoZVxuICogYXJyYXkgb2YgY2FuZGlkYXRlIGluZGljZXMsIHRoZSBhcnJheSBvZiBkaXN0YW5jZXMsIG9yIHRoZSBmbGFnIGFycmF5IGZvclxuICogd2hldGhlciBlbGVtZW50cyBhcmUgbmV3IG9yIG5vdC4gRWFjaCBvZiB0aGVzZSBhcnJheXMgYXJlIG9mIHNoYXBlXG4gKiAoYGBuUG9pbnRzYGAsIGBgc2l6ZWBgKVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFrZUhlYXAoblBvaW50czogbnVtYmVyLCBzaXplOiBudW1iZXIpOiBIZWFwIHtcbiAgY29uc3QgbWFrZUFycmF5cyA9IChmaWxsVmFsdWU6IG51bWJlcikgPT4ge1xuICAgIHJldHVybiB1dGlscy5lbXB0eShuUG9pbnRzKS5tYXAoKCkgPT4ge1xuICAgICAgcmV0dXJuIHV0aWxzLmZpbGxlZChzaXplLCBmaWxsVmFsdWUpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGhlYXA6IEhlYXAgPSBbXTtcbiAgaGVhcC5wdXNoKG1ha2VBcnJheXMoLTEpKTtcbiAgaGVhcC5wdXNoKG1ha2VBcnJheXMoSW5maW5pdHkpKTtcbiAgaGVhcC5wdXNoKG1ha2VBcnJheXMoMCkpO1xuICByZXR1cm4gaGVhcDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBuX3NhbXBsZXMgbWFueSBpbnRlZ2VycyBmcm9tIDAgdG8gcG9vbF9zaXplIHN1Y2ggdGhhdCBub1xuICogaW50ZWdlciBpcyBzZWxlY3RlZCB0d2ljZS4gVGhlIGR1cGxpY2F0aW9uIGNvbnN0cmFpbnQgaXMgYWNoaWV2ZWQgdmlhXG4gKiByZWplY3Rpb24gc2FtcGxpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWplY3Rpb25TYW1wbGUoXG4gIG5TYW1wbGVzOiBudW1iZXIsXG4gIHBvb2xTaXplOiBudW1iZXIsXG4gIHJhbmRvbTogUmFuZG9tRm5cbikge1xuICBjb25zdCByZXN1bHQgPSB1dGlscy56ZXJvcyhuU2FtcGxlcyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgblNhbXBsZXM7IGkrKykge1xuICAgIGxldCByZWplY3RTYW1wbGUgPSB0cnVlO1xuICAgIGxldCBqID0gMDtcbiAgICB3aGlsZSAocmVqZWN0U2FtcGxlKSB7XG4gICAgICBqID0gdXRpbHMudGF1UmFuZEludChwb29sU2l6ZSwgcmFuZG9tKTtcbiAgICAgIGxldCBicm9rZW4gPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaTsgaysrKSB7XG4gICAgICAgIGlmIChqID09PSByZXN1bHRba10pIHtcbiAgICAgICAgICBicm9rZW4gPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWJyb2tlbikgcmVqZWN0U2FtcGxlID0gZmFsc2U7XG4gICAgfVxuICAgIHJlc3VsdFtpXSA9IGo7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBQdXNoIGEgbmV3IGVsZW1lbnQgb250byB0aGUgaGVhcC4gVGhlIGhlYXAgc3RvcmVzIHBvdGVudGlhbCBuZWlnaGJvcnNcbiAqIGZvciBlYWNoIGRhdGEgcG9pbnQuIFRoZSBgYHJvd2BgIHBhcmFtZXRlciBkZXRlcm1pbmVzIHdoaWNoIGRhdGEgcG9pbnQgd2VcbiAqIGFyZSBhZGRyZXNzaW5nLCB0aGUgYGB3ZWlnaHRgYCBkZXRlcm1pbmVzIHRoZSBkaXN0YW5jZSAoZm9yIGhlYXAgc29ydGluZyksXG4gKiB0aGUgYGBpbmRleGBgIGlzIHRoZSBlbGVtZW50IHRvIGFkZCwgYW5kIHRoZSBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGlzXG4gKiBpcyB0byBiZSBjb25zaWRlcmVkIGEgbmV3IGFkZGl0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGVhcFB1c2goXG4gIGhlYXA6IEhlYXAsXG4gIHJvdzogbnVtYmVyLFxuICB3ZWlnaHQ6IG51bWJlcixcbiAgaW5kZXg6IG51bWJlcixcbiAgZmxhZzogbnVtYmVyXG4pOiBudW1iZXIge1xuICByb3cgPSBNYXRoLmZsb29yKHJvdyk7XG4gIGNvbnN0IGluZGljZXMgPSBoZWFwWzBdW3Jvd107XG4gIGNvbnN0IHdlaWdodHMgPSBoZWFwWzFdW3Jvd107XG4gIC8vY29uc3QgaXNOZXcgPSBoZWFwWzJdW3Jvd107XG5cbiAgaWYgKHdlaWdodCA+PSB3ZWlnaHRzWzBdKVxuICAgIHJldHVybiAwO1xuXG5cbiAgLy8gQnJlYWsgaWYgd2UgYWxyZWFkeSBoYXZlIHRoaXMgZWxlbWVudC5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGluZGV4ID09PSBpbmRpY2VzW2ldKVxuICAgICAgcmV0dXJuIDA7XG4gIH1cblxuICByZXR1cm4gdW5jaGVja2VkSGVhcFB1c2goaGVhcCwgcm93LCB3ZWlnaHQsIGluZGV4LCBmbGFnKTtcbn1cblxuLyoqXG4gKiBQdXNoIGEgbmV3IGVsZW1lbnQgb250byB0aGUgaGVhcC4gVGhlIGhlYXAgc3RvcmVzIHBvdGVudGlhbCBuZWlnaGJvcnNcbiAqIGZvciBlYWNoIGRhdGEgcG9pbnQuIFRoZSBgYHJvd2BgIHBhcmFtZXRlciBkZXRlcm1pbmVzIHdoaWNoIGRhdGEgcG9pbnQgd2VcbiAqIGFyZSBhZGRyZXNzaW5nLCB0aGUgYGB3ZWlnaHRgYCBkZXRlcm1pbmVzIHRoZSBkaXN0YW5jZSAoZm9yIGhlYXAgc29ydGluZyksXG4gKiB0aGUgYGBpbmRleGBgIGlzIHRoZSBlbGVtZW50IHRvIGFkZCwgYW5kIHRoZSBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGlzXG4gKiBpcyB0byBiZSBjb25zaWRlcmVkIGEgbmV3IGFkZGl0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5jaGVja2VkSGVhcFB1c2goXG4gIGhlYXA6IEhlYXAsXG4gIHJvdzogbnVtYmVyLFxuICB3ZWlnaHQ6IG51bWJlcixcbiAgaW5kZXg6IG51bWJlcixcbiAgZmxhZzogbnVtYmVyXG4pOiBudW1iZXIge1xuICBjb25zdCBpbmRpY2VzID0gaGVhcFswXVtyb3ddO1xuICBjb25zdCB3ZWlnaHRzID0gaGVhcFsxXVtyb3ddO1xuICBjb25zdCBpc05ldyA9IGhlYXBbMl1bcm93XTtcblxuICBpZiAod2VpZ2h0ID49IHdlaWdodHNbMF0pXG4gICAgcmV0dXJuIDA7XG5cblxuICAvLyBJbnNlcnQgdmFsIGF0IHBvc2l0aW9uIHplcm9cbiAgd2VpZ2h0c1swXSA9IHdlaWdodDtcbiAgaW5kaWNlc1swXSA9IGluZGV4O1xuICBpc05ld1swXSA9IGZsYWc7XG5cbiAgLy8gRGVzY2VuZCB0aGUgaGVhcCwgc3dhcHBpbmcgdmFsdWVzIHVudGlsIHRoZSBtYXggaGVhcCBjcml0ZXJpb24gaXMgbWV0XG4gIGxldCBpID0gMDtcbiAgbGV0IGlTd2FwID0gMDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCBpYzEgPSAyICogaSArIDE7XG4gICAgY29uc3QgaWMyID0gaWMxICsgMTtcblxuICAgIGNvbnN0IGhlYXBTaGFwZTIgPSBoZWFwWzBdWzBdLmxlbmd0aDtcbiAgICBpZiAoaWMxID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoaWMyID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGlmICh3ZWlnaHRzW2ljMV0gPiB3ZWlnaHQpXG4gICAgICAgIGlTd2FwID0gaWMxO1xuICAgICAgZWxzZVxuICAgICAgICBicmVhaztcbiAgICB9IGVsc2UgaWYgKHdlaWdodHNbaWMxXSA+PSB3ZWlnaHRzW2ljMl0pIHtcbiAgICAgIGlmICh3ZWlnaHQgPCB3ZWlnaHRzW2ljMV0pXG4gICAgICAgIGlTd2FwID0gaWMxO1xuICAgICAgZWxzZVxuICAgICAgICBicmVhaztcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHdlaWdodCA8IHdlaWdodHNbaWMyXSlcbiAgICAgICAgaVN3YXAgPSBpYzI7XG4gICAgICBlbHNlXG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHdlaWdodHNbaV0gPSB3ZWlnaHRzW2lTd2FwXTtcbiAgICBpbmRpY2VzW2ldID0gaW5kaWNlc1tpU3dhcF07XG4gICAgaXNOZXdbaV0gPSBpc05ld1tpU3dhcF07XG5cbiAgICBpID0gaVN3YXA7XG4gIH1cblxuICB3ZWlnaHRzW2ldID0gd2VpZ2h0O1xuICBpbmRpY2VzW2ldID0gaW5kZXg7XG4gIGlzTmV3W2ldID0gZmxhZztcbiAgcmV0dXJuIDE7XG59XG5cbi8qKlxuICogQnVpbGQgYSBoZWFwIG9mIGNhbmRpZGF0ZSBuZWlnaGJvcnMgZm9yIG5lYXJlc3QgbmVpZ2hib3IgZGVzY2VudC4gRm9yXG4gKiBlYWNoIHZlcnRleCB0aGUgY2FuZGlkYXRlIG5laWdoYm9ycyBhcmUgYW55IGN1cnJlbnQgbmVpZ2hib3JzLCBhbmQgYW55XG4gKiB2ZXJ0aWNlcyB0aGF0IGhhdmUgdGhlIHZlcnRleCBhcyBvbmUgb2YgdGhlaXIgbmVhcmVzdCBuZWlnaGJvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENhbmRpZGF0ZXMoXG4gIGN1cnJlbnRHcmFwaDogSGVhcCxcbiAgblZlcnRpY2VzOiBudW1iZXIsXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgbWF4Q2FuZGlkYXRlczogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgY29uc3QgY2FuZGlkYXRlTmVpZ2hib3JzID0gbWFrZUhlYXAoblZlcnRpY2VzLCBtYXhDYW5kaWRhdGVzKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuVmVydGljZXM7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICBpZiAoY3VycmVudEdyYXBoWzBdW2ldW2pdIDwgMClcbiAgICAgICAgY29udGludWU7XG5cbiAgICAgIGNvbnN0IGlkeCA9IGN1cnJlbnRHcmFwaFswXVtpXVtqXTtcbiAgICAgIGNvbnN0IGlzbiA9IGN1cnJlbnRHcmFwaFsyXVtpXVtqXTtcbiAgICAgIGNvbnN0IGQgPSB1dGlscy50YXVSYW5kKHJhbmRvbSk7XG4gICAgICBoZWFwUHVzaChjYW5kaWRhdGVOZWlnaGJvcnMsIGksIGQsIGlkeCwgaXNuKTtcbiAgICAgIGhlYXBQdXNoKGNhbmRpZGF0ZU5laWdoYm9ycywgaWR4LCBkLCBpLCBpc24pO1xuICAgICAgY3VycmVudEdyYXBoWzJdW2ldW2pdID0gMDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNhbmRpZGF0ZU5laWdoYm9ycztcbn1cblxuLyoqXG4gKiBHaXZlbiBhbiBhcnJheSBvZiBoZWFwcyAob2YgaW5kaWNlcyBhbmQgd2VpZ2h0cyksIHVucGFjayB0aGUgaGVhcFxuICogb3V0IHRvIGdpdmUgYW5kIGFycmF5IG9mIHNvcnRlZCBsaXN0cyBvZiBpbmRpY2VzIGFuZCB3ZWlnaHRzIGJ5IGluY3JlYXNpbmdcbiAqIHdlaWdodC4gVGhpcyBpcyBlZmZlY3RpdmVseSBqdXN0IHRoZSBzZWNvbmQgaGFsZiBvZiBoZWFwIHNvcnQgKHRoZSBmaXJzdFxuICogaGFsZiBub3QgYmVpbmcgcmVxdWlyZWQgc2luY2Ugd2UgYWxyZWFkeSBoYXZlIHRoZSBkYXRhIGluIGEgaGVhcCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWhlYXBTb3J0KGhlYXA6IEhlYXApIHtcbiAgY29uc3QgaW5kaWNlcyA9IGhlYXBbMF07XG4gIGNvbnN0IHdlaWdodHMgPSBoZWFwWzFdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGluZEhlYXAgPSBpbmRpY2VzW2ldO1xuICAgIGNvbnN0IGRpc3RIZWFwID0gd2VpZ2h0c1tpXTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kSGVhcC5sZW5ndGggLSAxOyBqKyspIHtcbiAgICAgIGNvbnN0IGluZEhlYXBJbmRleCA9IGluZEhlYXAubGVuZ3RoIC0gaiAtIDE7XG4gICAgICBjb25zdCBkaXN0SGVhcEluZGV4ID0gZGlzdEhlYXAubGVuZ3RoIC0gaiAtIDE7XG5cbiAgICAgIGNvbnN0IHRlbXAxID0gaW5kSGVhcFswXTtcbiAgICAgIGluZEhlYXBbMF0gPSBpbmRIZWFwW2luZEhlYXBJbmRleF07XG4gICAgICBpbmRIZWFwW2luZEhlYXBJbmRleF0gPSB0ZW1wMTtcblxuICAgICAgY29uc3QgdGVtcDIgPSBkaXN0SGVhcFswXTtcbiAgICAgIGRpc3RIZWFwWzBdID0gZGlzdEhlYXBbZGlzdEhlYXBJbmRleF07XG4gICAgICBkaXN0SGVhcFtkaXN0SGVhcEluZGV4XSA9IHRlbXAyO1xuXG4gICAgICBzaWZ0RG93bihkaXN0SGVhcCwgaW5kSGVhcCwgZGlzdEhlYXBJbmRleCwgMCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7aW5kaWNlcywgd2VpZ2h0c307XG59XG5cbi8qKlxuICogUmVzdG9yZSB0aGUgaGVhcCBwcm9wZXJ0eSBmb3IgYSBoZWFwIHdpdGggYW4gb3V0IG9mIHBsYWNlIGVsZW1lbnRcbiAqIGF0IHBvc2l0aW9uIGBgZWx0YGAuIFRoaXMgd29ya3Mgd2l0aCBhIGhlYXAgcGFpciB3aGVyZSBoZWFwMSBjYXJyaWVzXG4gKiB0aGUgd2VpZ2h0cyBhbmQgaGVhcDIgaG9sZHMgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMuXG4gKi9cbmZ1bmN0aW9uIHNpZnREb3duKFxuICBoZWFwMTogbnVtYmVyW10sXG4gIGhlYXAyOiBudW1iZXJbXSxcbiAgY2VpbGluZzogbnVtYmVyLFxuICBlbHQ6IG51bWJlclxuKSB7XG4gIHdoaWxlIChlbHQgKiAyICsgMSA8IGNlaWxpbmcpIHtcbiAgICBjb25zdCBsZWZ0Q2hpbGQgPSBlbHQgKiAyICsgMTtcbiAgICBjb25zdCByaWdodENoaWxkID0gbGVmdENoaWxkICsgMTtcbiAgICBsZXQgc3dhcCA9IGVsdDtcblxuICAgIGlmIChoZWFwMVtzd2FwXSA8IGhlYXAxW2xlZnRDaGlsZF0pXG4gICAgICBzd2FwID0gbGVmdENoaWxkO1xuXG4gICAgaWYgKHJpZ2h0Q2hpbGQgPCBjZWlsaW5nICYmIGhlYXAxW3N3YXBdIDwgaGVhcDFbcmlnaHRDaGlsZF0pXG4gICAgICBzd2FwID0gcmlnaHRDaGlsZDtcblxuXG4gICAgaWYgKHN3YXAgPT09IGVsdCkge1xuICAgICAgYnJlYWs7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRlbXAxID0gaGVhcDFbZWx0XTtcbiAgICAgIGhlYXAxW2VsdF0gPSBoZWFwMVtzd2FwXTtcbiAgICAgIGhlYXAxW3N3YXBdID0gdGVtcDE7XG5cbiAgICAgIGNvbnN0IHRlbXAyID0gaGVhcDJbZWx0XTtcbiAgICAgIGhlYXAyW2VsdF0gPSBoZWFwMltzd2FwXTtcbiAgICAgIGhlYXAyW3N3YXBdID0gdGVtcDI7XG4gICAgICBlbHQgPSBzd2FwO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNlYXJjaCB0aGUgaGVhcCBmb3IgdGhlIHNtYWxsZXN0IGVsZW1lbnQgdGhhdCBpcyBzdGlsbCBmbGFnZ2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc21hbGxlc3RGbGFnZ2VkKGhlYXA6IEhlYXAsIHJvdzogbnVtYmVyKSB7XG4gIGNvbnN0IGluZCA9IGhlYXBbMF1bcm93XTtcbiAgY29uc3QgZGlzdCA9IGhlYXBbMV1bcm93XTtcbiAgY29uc3QgZmxhZyA9IGhlYXBbMl1bcm93XTtcblxuICBsZXQgbWluRGlzdCA9IEluZmluaXR5O1xuICBsZXQgcmVzdWx0SW5kZXggPSAtMTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA+IGluZC5sZW5ndGg7IGkrKykge1xuICAgIGlmIChmbGFnW2ldID09PSAxICYmIGRpc3RbaV0gPCBtaW5EaXN0KSB7XG4gICAgICBtaW5EaXN0ID0gZGlzdFtpXTtcbiAgICAgIHJlc3VsdEluZGV4ID0gaTtcbiAgICB9XG4gIH1cblxuICBpZiAocmVzdWx0SW5kZXggPj0gMCkge1xuICAgIGZsYWdbcmVzdWx0SW5kZXhdID0gMDtcbiAgICByZXR1cm4gTWF0aC5mbG9vcihpbmRbcmVzdWx0SW5kZXhdKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbn1cbiJdfQ==","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\nimport * as utils from './utils';\n/**\n * Internal 2-dimensional sparse matrix class\n */\nexport class SparseMatrix {\n constructor(rows, cols, values, dims) {\n this.entries = new Map();\n this.nRows = 0;\n this.nCols = 0;\n if (rows.length !== cols.length || rows.length !== values.length) {\n throw new Error('rows, cols and values arrays must all have the same length');\n }\n // TODO: Assert that dims are legit.\n this.nRows = dims[0];\n this.nCols = dims[1];\n for (let i = 0; i < values.length; i++) {\n const row = rows[i];\n const col = cols[i];\n this.checkDims(row, col);\n const key = this.makeKey(row, col);\n this.entries.set(key, { value: values[i], row, col });\n }\n }\n makeKey(row, col) {\n return `${row}:${col}`;\n }\n checkDims(row, col) {\n const withinBounds = row < this.nRows && col < this.nCols;\n if (!withinBounds)\n throw new Error('row and/or col specified outside of matrix dimensions');\n }\n set(row, col, value) {\n this.checkDims(row, col);\n const key = this.makeKey(row, col);\n if (!this.entries.has(key))\n this.entries.set(key, { value, row, col });\n else\n this.entries.get(key).value = value;\n }\n get(row, col, defaultValue = 0) {\n //this.checkDims(row, col);\n const key = this.makeKey(row, col);\n if (this.entries.has(key))\n return this.entries.get(key).value;\n else\n return defaultValue;\n }\n getAll(ordered = true) {\n const rowColValues = new Array(this.entries.size).fill(null);\n let i = 0;\n this.entries.forEach((value) => {\n rowColValues[i++] = value;\n });\n if (ordered) {\n // Ordering the result isn't required for processing but it does make it easier to write tests\n rowColValues.sort((a, b) => {\n if (a.row === b.row)\n return a.col - b.col;\n else\n return a.row - b.row;\n });\n }\n return rowColValues;\n }\n getDims() {\n return [this.nRows, this.nCols];\n }\n getRows() {\n return Array.from(this.entries, ([_key, value]) => value.row);\n // return this.rows as unknown as number[];\n }\n getCols() {\n return Array.from(this.entries, ([_key, value]) => value.col);\n // return this.cols as unknown as number[];\n }\n getValues() {\n return Array.from(this.entries, ([_key, value]) => value.value);\n //return this.values as unknown as number[];\n }\n forEach(fn) {\n this.entries.forEach((value) => fn(value.value, value.row, value.col));\n }\n map(fn) {\n const vals = new Float32Array(this.entries.size);\n let i = 0;\n this.entries.forEach((value) => {\n vals[i++] = fn(value.value, value.row, value.col);\n });\n const dims = [this.nRows, this.nCols];\n return new SparseMatrix(this.getRows(), this.getCols(), vals, dims);\n }\n toArray() {\n const rows = utils.empty(this.nRows);\n const output = rows.map(() => {\n return utils.zeros(this.nCols);\n });\n this.entries.forEach((value) => {\n output[value.row][value.col] = value.value;\n });\n return output;\n }\n}\n/**\n * Transpose a sparse matrix\n */\nexport function transpose(matrix) {\n const oldRows = matrix.getRows();\n const oldCols = matrix.getCols();\n const oldVals = matrix.getValues();\n const matlen = oldCols.length;\n const cols = new Int32Array(matlen);\n const rows = new Int32Array(matlen);\n const vals = new Float32Array(matlen);\n cols.set(oldRows);\n rows.set(oldCols);\n vals.set(oldVals);\n const dims = [matrix.nCols, matrix.nRows];\n return new SparseMatrix(rows, cols, vals, dims);\n}\n/**\n * Construct a sparse identity matrix\n */\nexport function identity(size) {\n const [rows] = size;\n const matrix = new SparseMatrix([], [], [], size);\n for (let i = 0; i < rows; i++)\n matrix.set(i, i, 1);\n return matrix;\n}\n/**\n * Element-wise multiplication of two matrices\n */\nexport function pairwiseMultiply(a, b) {\n return elementWise(a, b, (x, y) => x * y);\n}\n/**\n * Element-wise addition of two matrices\n */\nexport function add(a, b) {\n return elementWise(a, b, (x, y) => x + y);\n}\n/**\n * Element-wise subtraction of two matrices\n */\nexport function subtract(a, b) {\n return elementWise(a, b, (x, y) => x - y);\n}\n/**\n * Element-wise maximum of two matrices\n */\nexport function maximum(a, b) {\n return elementWise(a, b, (x, y) => (x > y ? x : y));\n}\n/**\n * Scalar multiplication of two matrices\n */\nexport function multiplyScalar(a, scalar) {\n return a.map((value) => {\n return value * scalar;\n });\n}\n/**\n * Returns a new matrix with zero entries removed.\n */\nexport function eliminateZeros(m) {\n const zeroIndices = new Set();\n const values = m.getValues();\n const rows = m.getRows();\n const cols = m.getCols();\n for (let i = 0; i < values.length; i++) {\n if (values[i] === 0)\n zeroIndices.add(i);\n }\n const removeByZeroIndex = (_, index) => !zeroIndices.has(index);\n const nextValues = values.filter(removeByZeroIndex);\n const nextRows = rows.filter(removeByZeroIndex);\n const nextCols = cols.filter(removeByZeroIndex);\n return new SparseMatrix(nextRows, nextCols, nextValues, m.getDims());\n}\n/**\n * Normalization of a sparse matrix.\n */\nexport function normalize(m, normType = \"l2\" /* NormType.l2 */) {\n const normFn = normFns[normType];\n const colsByRow = new Map();\n m.forEach((_, row, col) => {\n const cols = colsByRow.get(row) || [];\n cols.push(col);\n colsByRow.set(row, cols);\n });\n const nextMatrix = new SparseMatrix([], [], [], m.getDims());\n for (const row of colsByRow.keys()) {\n const cols = colsByRow.get(row).sort();\n const vals = cols.map((col) => m.get(row, col));\n const norm = normFn(vals);\n for (let i = 0; i < norm.length; i++)\n nextMatrix.set(row, cols[i], norm[i]);\n }\n return nextMatrix;\n}\nconst normFns = {\n [\"max\" /* NormType.max */]: (xs) => {\n let max = -Infinity;\n for (let i = 0; i < xs.length; i++)\n max = xs[i] > max ? xs[i] : max;\n return xs.map((x) => x / max);\n },\n [\"l1\" /* NormType.l1 */]: (xs) => {\n let sum = 0;\n for (let i = 0; i < xs.length; i++)\n sum += xs[i];\n return xs.map((x) => x / sum);\n },\n [\"l2\" /* NormType.l2 */]: (xs) => {\n let sum = 0;\n for (let i = 0; i < xs.length; i++)\n sum += xs[i] ** 2;\n return xs.map((x) => Math.sqrt(x ** 2 / sum));\n },\n};\n/**\n * Helper function for element-wise operations.\n */\nfunction elementWise(a, b, op) {\n const visited = new Set();\n const rows = [];\n const cols = [];\n const vals = [];\n const operate = (row, col) => {\n rows.push(row);\n cols.push(col);\n const nextValue = op(a.get(row, col), b.get(row, col));\n vals.push(nextValue);\n };\n const valuesA = a.getValues();\n const rowsA = a.getRows();\n const colsA = a.getCols();\n for (let i = 0; i < valuesA.length; i++) {\n const row = rowsA[i];\n const col = colsA[i];\n const key = `${row}:${col}`;\n visited.add(key);\n operate(row, col);\n }\n const valuesB = b.getValues();\n const rowsB = b.getRows();\n const colsB = b.getCols();\n for (let i = 0; i < valuesB.length; i++) {\n const row = rowsB[i];\n const col = colsB[i];\n const key = `${row}:${col}`;\n if (visited.has(key))\n continue;\n operate(row, col);\n }\n const dims = [a.nRows, a.nCols];\n return new SparseMatrix(rows, cols, vals, dims);\n}\n/**\n * Helper function for getting data, indices, and inptr arrays from a sparse\n * matrix to follow csr matrix conventions. Super inefficient (and kind of\n * defeats the purpose of this convention) but a lot of the ported python tree\n * search logic depends on this data format.\n */\nexport function getCSR(x) {\n const entries = [];\n x.forEach((value, row, col) => {\n entries.push({ value, row, col });\n });\n entries.sort((a, b) => {\n if (a.row === b.row)\n return a.col - b.col;\n else\n return a.row - b.row;\n });\n const indices = [];\n const values = [];\n const indptr = [];\n let currentRow = -1;\n for (let i = 0; i < entries.length; i++) {\n const { row, col, value } = entries[i];\n if (row !== currentRow) {\n currentRow = row;\n indptr.push(i);\n }\n indices.push(col);\n values.push(value);\n }\n return { indices, values, indptr };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0cml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibWF0cml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFNdkIsWUFDRSxJQUEyQixFQUMzQixJQUEyQixFQUMzQixNQUErQixFQUMvQixJQUFjO1FBVFIsWUFBTyxHQUFHLElBQUksR0FBRyxFQUFpQixDQUFDO1FBRWxDLFVBQUssR0FBVyxDQUFDLENBQUM7UUFDbEIsVUFBSyxHQUFXLENBQUMsQ0FBQztRQVF6QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqRSxNQUFNLElBQUksS0FBSyxDQUNiLDREQUE0RCxDQUM3RCxDQUFDO1FBQ0osQ0FBQztRQUVELG9DQUFvQztRQUNwQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbkMsSUFBSSxD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TUFBTSxHQUFhLEVBQUUsQ0FBQztJQUM1QixNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFFNUIsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDcEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN4QyxNQUFNLEVBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsSUFBSSxHQUFHLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDdkIsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pCLENBQUM7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckIsQ0FBQztJQUVELE9BQU8sRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBQyxDQUFDO0FBQ25DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcblxudHlwZSBFbnRyeSA9IHsgdmFsdWU6IG51bWJlcjsgcm93OiBudW1iZXI7IGNvbDogbnVtYmVyIH07XG5cbi8qKlxuICogSW50ZXJuYWwgMi1kaW1lbnNpb25hbCBzcGFyc2UgbWF0cml4IGNsYXNzXG4gKi9cbmV4cG9ydCBjbGFzcyBTcGFyc2VNYXRyaXgge1xuICBwcml2YXRlIGVudHJpZXMgPSBuZXcgTWFwPHN0cmluZywgRW50cnk+KCk7XG5cbiAgcmVhZG9ubHkgblJvd3M6IG51bWJlciA9IDA7XG4gIHJlYWRvbmx5IG5Db2xzOiBudW1iZXIgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJvd3M6IG51bWJlcltdIHwgSW50MzJBcnJheSxcbiAgICBjb2xzOiBudW1iZXJbXSB8IEludDMyQXJyYXksXG4gICAgdmFsdWVzOiBudW1iZXJbXSB8IEZsb2F0MzJBcnJheSxcbiAgICBkaW1zOiBudW1iZXJbXVxuICApIHtcbiAgICBpZiAocm93cy5sZW5ndGggIT09IGNvbHMubGVuZ3RoIHx8IHJvd3MubGVuZ3RoICE9PSB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdyb3dzLCBjb2xzIGFuZCB2YWx1ZXMgYXJyYXlzIG11c3QgYWxsIGhhdmUgdGhlIHNhbWUgbGVuZ3RoJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBBc3NlcnQgdGhhdCBkaW1zIGFyZSBsZWdpdC5cbiAgICB0aGlzLm5Sb3dzID0gZGltc1swXTtcbiAgICB0aGlzLm5Db2xzID0gZGltc1sxXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgcm93ID0gcm93c1tpXTtcbiAgICAgIGNvbnN0IGNvbCA9IGNvbHNbaV07XG4gICAgICB0aGlzLmNoZWNrRGltcyhyb3csIGNvbCk7XG4gICAgICBjb25zdCBrZXkgPSB0aGlzLm1ha2VLZXkocm93LCBjb2wpO1xuICAgICAgdGhpcy5lbnRyaWVzLnNldChrZXksIHt2YWx1ZTogdmFsdWVzW2ldLCByb3csIGNvbH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWFrZUtleShyb3c6IG51bWJlciwgY29sOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtyb3d9OiR7Y29sfWA7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrRGltcyhyb3c6IG51bWJlciwgY29sOiBudW1iZXIpIHtcbiAgICBjb25zdCB3aXRoaW5Cb3VuZHMgPSByb3cgPCB0aGlzLm5Sb3dzICYmIGNvbCA8IHRoaXMubkNvbHM7XG4gICAgaWYgKCF3aXRoaW5Cb3VuZHMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3JvdyBhbmQvb3IgY29sIHNwZWNpZmllZCBvdXRzaWRlIG9mIG1hdHJpeCBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBzZXQocm93OiBudW1iZXIsIGNvbDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5jaGVja0RpbXMocm93LCBjb2wpO1xuICAgIGNvbnN0IGtleSA9IHRoaXMubWFrZUtleShyb3csIGNvbCk7XG4gICAgaWYgKCF0aGlzLmVudHJpZXMuaGFzKGtleSkpXG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwge3ZhbHVlLCByb3csIGNvbH0pO1xuICAgIGVsc2VcbiAgICAgIHRoaXMuZW50cmllcy5nZXQoa2V5KSEudmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldChyb3c6IG51bWJlciwgY29sOiBudW1iZXIsIGRlZmF1bHRWYWx1ZSA9IDApIHtcbiAgICAvL3RoaXMuY2hlY2tEaW1zKHJvdywgY29sKTtcbiAgICBjb25zdCBrZXkgPSB0aGlzLm1ha2VLZXkocm93LCBjb2wpO1xuICAgIGlmICh0aGlzLmVudHJpZXMuaGFzKGtleSkpXG4gICAgICByZXR1cm4gdGhpcy5lbnRyaWVzLmdldChrZXkpIS52YWx1ZTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICB9XG5cbiAgZ2V0QWxsKG9yZGVyZWQgPSB0cnVlKTogeyB2YWx1ZTogbnVtYmVyOyByb3c6IG51bWJlcjsgY29sOiBudW1iZXIgfVtdIHtcbiAgICBjb25zdCByb3dDb2xWYWx1ZXM6IEVudHJ5W10gPSBuZXcgQXJyYXkodGhpcy5lbnRyaWVzLnNpemUpLmZpbGwobnVsbCk7XG4gICAgbGV0IGkgPSAwO1xuICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgcm93Q29sVmFsdWVzW2krK10gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICBpZiAob3JkZXJlZCkge1xuICAgICAgLy8gT3JkZXJpbmcgdGhlIHJlc3VsdCBpc24ndCByZXF1aXJlZCBmb3IgcHJvY2Vzc2luZyBidXQgaXQgZG9lcyBtYWtlIGl0IGVhc2llciB0byB3cml0ZSB0ZXN0c1xuICAgICAgcm93Q29sVmFsdWVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgaWYgKGEucm93ID09PSBiLnJvdylcbiAgICAgICAgICByZXR1cm4gYS5jb2wgLSBiLmNvbDtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHJldHVybiBhLnJvdyAtIGIucm93O1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByb3dDb2xWYWx1ZXM7XG4gIH1cblxuICBnZXREaW1zKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gW3RoaXMublJvd3MsIHRoaXMubkNvbHNdO1xuICB9XG5cbiAgZ2V0Um93cygpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5lbnRyaWVzLCAoW19rZXksIHZhbHVlXSkgPT4gdmFsdWUucm93KTtcbiAgICAvLyByZXR1cm4gdGhpcy5yb3dzIGFzIHVua25vd24gYXMgbnVtYmVyW107XG4gIH1cblxuICBnZXRDb2xzKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMsIChbX2tleSwgdmFsdWVdKSA9PiB2YWx1ZS5jb2wpO1xuICAgIC8vIHJldHVybiB0aGlzLmNvbHMgYXMgdW5rbm93biBhcyBudW1iZXJbXTtcbiAgfVxuXG4gIGdldFZhbHVlcygpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5lbnRyaWVzLCAoW19rZXksIHZhbHVlXSkgPT4gdmFsdWUudmFsdWUpO1xuICAvL3JldHVybiB0aGlzLnZhbHVlcyBhcyB1bmtub3duIGFzIG51bWJlcltdO1xuICB9XG5cbiAgZm9yRWFjaChmbjogKHZhbHVlOiBudW1iZXIsIHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKCh2YWx1ZSkgPT4gZm4odmFsdWUudmFsdWUsIHZhbHVlLnJvdywgdmFsdWUuY29sKSk7XG4gIH1cblxuICBtYXAoZm46ICh2YWx1ZTogbnVtYmVyLCByb3c6IG51bWJlciwgY29sOiBudW1iZXIpID0+IG51bWJlcik6IFNwYXJzZU1hdHJpeCB7XG4gICAgY29uc3QgdmFscyA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5lbnRyaWVzLnNpemUpO1xuICAgIGxldCBpID0gMDtcbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgIHZhbHNbaSsrXSA9IGZuKHZhbHVlLnZhbHVlLCB2YWx1ZS5yb3csIHZhbHVlLmNvbCk7XG4gICAgfSk7XG4gICAgY29uc3QgZGltcyA9IFt0aGlzLm5Sb3dzLCB0aGlzLm5Db2xzXTtcbiAgICByZXR1cm4gbmV3IFNwYXJzZU1hdHJpeCh0aGlzLmdldFJvd3MoKSwgdGhpcy5nZXRDb2xzKCksIHZhbHMgYXMgdW5rbm93biBhcyBudW1iZXJbXSwgZGltcyk7XG4gIH1cblxuICB0b0FycmF5KCkge1xuICAgIGNvbnN0IHJvd3M6IHVuZGVmaW5lZFtdID0gdXRpbHMuZW1wdHkodGhpcy5uUm93cyk7XG4gICAgY29uc3Qgb3V0cHV0ID0gcm93cy5tYXAoKCkgPT4ge1xuICAgICAgcmV0dXJuIHV0aWxzLnplcm9zKHRoaXMubkNvbHMpO1xuICAgIH0pO1xuICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgb3V0cHV0W3ZhbHVlLnJvd11bdmFsdWUuY29sXSA9IHZhbHVlLnZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn1cblxuLyoqXG4gKiBUcmFuc3Bvc2UgYSBzcGFyc2UgbWF0cml4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2UobWF0cml4OiBTcGFyc2VNYXRyaXgpOiBTcGFyc2VNYXRyaXgge1xuICBjb25zdCBvbGRSb3dzID0gbWF0cml4LmdldFJvd3MoKTtcbiAgY29uc3Qgb2xkQ29scyA9IG1hdHJpeC5nZXRDb2xzKCk7XG4gIGNvbnN0IG9sZFZhbHMgPSBtYXRyaXguZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IG1hdGxlbiA9IG9sZENvbHMubGVuZ3RoO1xuICBjb25zdCBjb2xzID0gbmV3IEludDMyQXJyYXkobWF0bGVuKTtcbiAgY29uc3Qgcm93cyA9IG5ldyBJbnQzMkFycmF5KG1hdGxlbik7XG4gIGNvbnN0IHZhbHMgPSBuZXcgRmxvYXQzMkFycmF5KG1hdGxlbik7XG5cbiAgY29scy5zZXQob2xkUm93cyk7XG4gIHJvd3Muc2V0KG9sZENvbHMpO1xuICB2YWxzLnNldChvbGRWYWxzKTtcbiAgY29uc3QgZGltcyA9IFttYXRyaXgubkNvbHMsIG1hdHJpeC5uUm93c107XG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIGRpbXMpO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHNwYXJzZSBpZGVudGl0eSBtYXRyaXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KHNpemU6IG51bWJlcltdKTogU3BhcnNlTWF0cml4IHtcbiAgY29uc3QgW3Jvd3NdID0gc2l6ZTtcbiAgY29uc3QgbWF0cml4ID0gbmV3IFNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBzaXplKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspXG4gICAgbWF0cml4LnNldChpLCBpLCAxKTtcblxuICByZXR1cm4gbWF0cml4O1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBtdWx0aXBsaWNhdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhaXJ3aXNlTXVsdGlwbHkoXG4gIGE6IFNwYXJzZU1hdHJpeCxcbiAgYjogU3BhcnNlTWF0cml4XG4pOiBTcGFyc2VNYXRyaXgge1xuICByZXR1cm4gZWxlbWVudFdpc2UoYSwgYiwgKHgsIHkpID0+IHggKiB5KTtcbn1cblxuLyoqXG4gKiBFbGVtZW50LXdpc2UgYWRkaXRpb24gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGQoYTogU3BhcnNlTWF0cml4LCBiOiBTcGFyc2VNYXRyaXgpOiBTcGFyc2VNYXRyaXgge1xuICByZXR1cm4gZWxlbWVudFdpc2UoYSwgYiwgKHgsIHkpID0+IHggKyB5KTtcbn1cblxuLyoqXG4gKiBFbGVtZW50LXdpc2Ugc3VidHJhY3Rpb24gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdWJ0cmFjdChhOiBTcGFyc2VNYXRyaXgsIGI6IFNwYXJzZU1hdHJpeCk6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4geCAtIHkpO1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBtYXhpbXVtIG9mIHR3byBtYXRyaWNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWF4aW11bShhOiBTcGFyc2VNYXRyaXgsIGI6IFNwYXJzZU1hdHJpeCk6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4gKHggPiB5ID8geCA6IHkpKTtcbn1cblxuLyoqXG4gKiBTY2FsYXIgbXVsdGlwbGljYXRpb24gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtdWx0aXBseVNjYWxhcihhOiBTcGFyc2VNYXRyaXgsIHNjYWxhcjogbnVtYmVyKTogU3BhcnNlTWF0cml4IHtcbiAgcmV0dXJuIGEubWFwKCh2YWx1ZTogbnVtYmVyKSA9PiB7XG4gICAgcmV0dXJuIHZhbHVlICogc2NhbGFyO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IG1hdHJpeCB3aXRoIHplcm8gZW50cmllcyByZW1vdmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZWxpbWluYXRlWmVyb3MobTogU3BhcnNlTWF0cml4KSB7XG4gIGNvbnN0IHplcm9JbmRpY2VzID0gbmV3IFNldCgpO1xuICBjb25zdCB2YWx1ZXMgPSBtLmdldFZhbHVlcygpO1xuICBjb25zdCByb3dzID0gbS5nZXRSb3dzKCk7XG4gIGNvbnN0IGNvbHMgPSBtLmdldENvbHMoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodmFsdWVzW2ldID09PSAwKVxuICAgICAgemVyb0luZGljZXMuYWRkKGkpO1xuICB9XG4gIGNvbnN0IHJlbW92ZUJ5WmVyb0luZGV4ID0gKF86IGFueSwgaW5kZXg6IG51bWJlcikgPT4gIXplcm9JbmRpY2VzLmhhcyhpbmRleCk7XG4gIGNvbnN0IG5leHRWYWx1ZXMgPSB2YWx1ZXMuZmlsdGVyKHJlbW92ZUJ5WmVyb0luZGV4KTtcbiAgY29uc3QgbmV4dFJvd3MgPSByb3dzLmZpbHRlcihyZW1vdmVCeVplcm9JbmRleCk7XG4gIGNvbnN0IG5leHRDb2xzID0gY29scy5maWx0ZXIocmVtb3ZlQnlaZXJvSW5kZXgpO1xuXG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KG5leHRSb3dzLCBuZXh0Q29scywgbmV4dFZhbHVlcywgbS5nZXREaW1zKCkpO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6YXRpb24gb2YgYSBzcGFyc2UgbWF0cml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKG06IFNwYXJzZU1hdHJpeCwgbm9ybVR5cGUgPSBOb3JtVHlwZS5sMikge1xuICBjb25zdCBub3JtRm4gPSBub3JtRm5zW25vcm1UeXBlXTtcblxuICBjb25zdCBjb2xzQnlSb3cgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyW10+KCk7XG4gIG0uZm9yRWFjaCgoXywgcm93LCBjb2wpID0+IHtcbiAgICBjb25zdCBjb2xzID0gY29sc0J5Um93LmdldChyb3cpIHx8IFtdO1xuICAgIGNvbHMucHVzaChjb2wpO1xuICAgIGNvbHNCeVJvdy5zZXQocm93LCBjb2xzKTtcbiAgfSk7XG5cbiAgY29uc3QgbmV4dE1hdHJpeCA9IG5ldyBTcGFyc2VNYXRyaXgoW10sIFtdLCBbXSwgbS5nZXREaW1zKCkpO1xuXG4gIGZvciAoY29uc3Qgcm93IG9mIGNvbHNCeVJvdy5rZXlzKCkpIHtcbiAgICBjb25zdCBjb2xzID0gY29sc0J5Um93LmdldChyb3cpIS5zb3J0KCk7XG5cbiAgICBjb25zdCB2YWxzID0gY29scy5tYXAoKGNvbCkgPT4gbS5nZXQocm93LCBjb2wpKTtcbiAgICBjb25zdCBub3JtID0gbm9ybUZuKHZhbHMpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9ybS5sZW5ndGg7IGkrKylcbiAgICAgIG5leHRNYXRyaXguc2V0KHJvdywgY29sc1tpXSwgbm9ybVtpXSk7XG4gIH1cblxuICByZXR1cm4gbmV4dE1hdHJpeDtcbn1cblxuLyoqXG4gKiBWZWN0b3Igbm9ybWFsaXphdGlvbiBmdW5jdGlvbnNcbiAqL1xudHlwZSBOb3JtRm5zID0geyBba2V5IGluIE5vcm1UeXBlXTogKHY6IG51bWJlcltdKSA9PiBudW1iZXJbXSB9O1xuY29uc3Qgbm9ybUZuczogTm9ybUZucyA9IHtcbiAgW05vcm1UeXBlLm1heF06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgbWF4ID0gLUluZmluaXR5O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspXG4gICAgICBtYXggPSB4c1tpXSA+IG1heCA/IHhzW2ldIDogbWF4O1xuXG4gICAgcmV0dXJuIHhzLm1hcCgoeCkgPT4geCAvIG1heCk7XG4gIH0sXG4gIFtOb3JtVHlwZS5sMV06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKVxuICAgICAgc3VtICs9IHhzW2ldO1xuXG4gICAgcmV0dXJuIHhzLm1hcCgoeCkgPT4geCAvIHN1bSk7XG4gIH0sXG4gIFtOb3JtVHlwZS5sMl06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKVxuICAgICAgc3VtICs9IHhzW2ldICoqIDI7XG5cbiAgICByZXR1cm4geHMubWFwKCh4KSA9PiBNYXRoLnNxcnQoeCAqKiAyIC8gc3VtKSk7XG4gIH0sXG59O1xuXG5leHBvcnQgY29uc3QgZW51bSBOb3JtVHlwZSB7XG4gIG1heCA9ICdtYXgnLFxuICBsMSA9ICdsMScsXG4gIGwyID0gJ2wyJyxcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGVsZW1lbnQtd2lzZSBvcGVyYXRpb25zLlxuICovXG5mdW5jdGlvbiBlbGVtZW50V2lzZShcbiAgYTogU3BhcnNlTWF0cml4LFxuICBiOiBTcGFyc2VNYXRyaXgsXG4gIG9wOiAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IG51bWJlclxuKTogU3BhcnNlTWF0cml4IHtcbiAgY29uc3QgdmlzaXRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCByb3dzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBjb2xzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCB2YWxzOiBudW1iZXJbXSA9IFtdO1xuXG4gIGNvbnN0IG9wZXJhdGUgPSAocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKSA9PiB7XG4gICAgcm93cy5wdXNoKHJvdyk7XG4gICAgY29scy5wdXNoKGNvbCk7XG4gICAgY29uc3QgbmV4dFZhbHVlID0gb3AoYS5nZXQocm93LCBjb2wpLCBiLmdldChyb3csIGNvbCkpO1xuICAgIHZhbHMucHVzaChuZXh0VmFsdWUpO1xuICB9O1xuICBjb25zdCB2YWx1ZXNBID0gYS5nZXRWYWx1ZXMoKTtcbiAgY29uc3Qgcm93c0EgPSBhLmdldFJvd3MoKTtcbiAgY29uc3QgY29sc0EgPSBhLmdldENvbHMoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXNBLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgcm93ID0gcm93c0FbaV07XG4gICAgY29uc3QgY29sID0gY29sc0FbaV07XG4gICAgY29uc3Qga2V5ID0gYCR7cm93fToke2NvbH1gO1xuICAgIHZpc2l0ZWQuYWRkKGtleSk7XG4gICAgb3BlcmF0ZShyb3csIGNvbCk7XG4gIH1cblxuICBjb25zdCB2YWx1ZXNCID0gYi5nZXRWYWx1ZXMoKTtcbiAgY29uc3Qgcm93c0IgPSBiLmdldFJvd3MoKTtcbiAgY29uc3QgY29sc0IgPSBiLmdldENvbHMoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXNCLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgcm93ID0gcm93c0JbaV07XG4gICAgY29uc3QgY29sID0gY29sc0JbaV07XG4gICAgY29uc3Qga2V5ID0gYCR7cm93fToke2NvbH1gO1xuICAgIGlmICh2aXNpdGVkLmhhcyhrZXkpKSBjb250aW51ZTtcbiAgICBvcGVyYXRlKHJvdywgY29sKTtcbiAgfVxuXG4gIGNvbnN0IGRpbXMgPSBbYS5uUm93cywgYS5uQ29sc107XG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIGRpbXMpO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiBmb3IgZ2V0dGluZyBkYXRhLCBpbmRpY2VzLCBhbmQgaW5wdHIgYXJyYXlzIGZyb20gYSBzcGFyc2VcbiAqIG1hdHJpeCB0byBmb2xsb3cgY3NyIG1hdHJpeCBjb252ZW50aW9ucy4gU3VwZXIgaW5lZmZpY2llbnQgKGFuZCBraW5kIG9mXG4gKiBkZWZlYXRzIHRoZSBwdXJwb3NlIG9mIHRoaXMgY29udmVudGlvbikgYnV0IGEgbG90IG9mIHRoZSBwb3J0ZWQgcHl0aG9uIHRyZWVcbiAqIHNlYXJjaCBsb2dpYyBkZXBlbmRzIG9uIHRoaXMgZGF0YSBmb3JtYXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDU1IoeDogU3BhcnNlTWF0cml4KSB7XG4gIGNvbnN0IGVudHJpZXM6IEVudHJ5W10gPSBbXTtcblxuICB4LmZvckVhY2goKHZhbHVlLCByb3csIGNvbCkgPT4ge1xuICAgIGVudHJpZXMucHVzaCh7dmFsdWUsIHJvdywgY29sfSk7XG4gIH0pO1xuXG4gIGVudHJpZXMuc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhLnJvdyA9PT0gYi5yb3cpXG4gICAgICByZXR1cm4gYS5jb2wgLSBiLmNvbDtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gYS5yb3cgLSBiLnJvdztcbiAgfSk7XG5cbiAgY29uc3QgaW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgdmFsdWVzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBpbmRwdHI6IG51bWJlcltdID0gW107XG5cbiAgbGV0IGN1cnJlbnRSb3cgPSAtMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbnRyaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qge3JvdywgY29sLCB2YWx1ZX0gPSBlbnRyaWVzW2ldO1xuICAgIGlmIChyb3cgIT09IGN1cnJlbnRSb3cpIHtcbiAgICAgIGN1cnJlbnRSb3cgPSByb3c7XG4gICAgICBpbmRwdHIucHVzaChpKTtcbiAgICB9XG4gICAgaW5kaWNlcy5wdXNoKGNvbCk7XG4gICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHtpbmRpY2VzLCB2YWx1ZXMsIGluZHB0cn07XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as utils from './utils';\nexport class FlatTree {\n constructor(hyperplanes, offsets, children, indices) {\n this.hyperplanes = hyperplanes;\n this.offsets = offsets;\n this.children = children;\n this.indices = indices;\n }\n}\n/**\n * Build a random projection forest with ``nTrees``.\n */\nexport function makeForest(data, nNeighbors, nTrees, random) {\n const leafSize = Math.max(10, nNeighbors);\n const trees = utils\n .range(nTrees)\n .map((_, i) => makeTree(data, leafSize, i, random));\n const forest = trees.map((tree) => flattenTree(tree, leafSize));\n return forest;\n}\n/**\n * Construct a random projection tree based on ``data`` with leaves\n * of size at most ``leafSize``\n */\nfunction makeTree(data, leafSize = 30, n, random) {\n const indices = utils.range(data.length);\n const tree = makeEuclideanTree(data, indices, leafSize, n, random);\n return tree;\n}\nfunction makeEuclideanTree(data, indices, leafSize = 30, q, random) {\n if (indices.length > leafSize) {\n const splitResults = euclideanRandomProjectionSplit(data, indices, random);\n const { indicesLeft, indicesRight, hyperplane, offset } = splitResults;\n const leftChild = makeEuclideanTree(data, indicesLeft, leafSize, q + 1, random);\n const rightChild = makeEuclideanTree(data, indicesRight, leafSize, q + 1, random);\n const node = { leftChild, rightChild, isLeaf: false, hyperplane, offset };\n return node;\n }\n else {\n const node = { indices, isLeaf: true };\n return node;\n }\n}\n/**\n * Given a set of ``indices`` for data points from ``data``, create\n * a random hyperplane to split the data, returning two arrays indices\n * that fall on either side of the hyperplane. This is the basis for a\n * random projection tree, which simply uses this splitting recursively.\n * This particular split uses euclidean distance to determine the hyperplane\n * and which side each data sample falls on.\n */\nfunction euclideanRandomProjectionSplit(data, indices, random) {\n //const dim = 1;\n // Select two random points, set the hyperplane between them\n const leftIndex = utils.tauRandInt(indices.length, random);\n let rightIndex = utils.tauRandInt(indices.length, random);\n rightIndex += leftIndex === rightIndex ? 1 : 0;\n rightIndex = rightIndex % indices.length;\n const left = indices[leftIndex];\n const right = indices[rightIndex];\n // Compute the normal vector to the hyperplane (the vector between the two\n // points) and the offset from the origin\n let hyperplaneOffset = 0;\n let hyperplaneVector = 0;\n hyperplaneVector = data[left] - data[right];\n hyperplaneOffset -=\n (hyperplaneVector * (data[left] + data[right])) / 2.0;\n // For each point compute the margin (project into normal vector)\n // If we are on lower side of the hyperplane put in one pile, otherwise\n // put it in the other pile (if we hit hyperplane on the nose, flip a coin)\n let nLeft = 0;\n let nRight = 0;\n const side = utils.zeros(indices.length);\n for (let i = 0; i < indices.length; i++) {\n let margin = hyperplaneOffset;\n margin += hyperplaneVector * data[indices[i]];\n if (margin === 0) {\n side[i] = utils.tauRandInt(2, random);\n if (side[i] === 0)\n nLeft += 1;\n else\n nRight += 1;\n }\n else if (margin > 0) {\n side[i] = 0;\n nLeft += 1;\n }\n else {\n side[i] = 1;\n nRight += 1;\n }\n }\n // Now that we have the counts, allocate arrays\n const indicesLeft = utils.zeros(nLeft);\n const indicesRight = utils.zeros(nRight);\n // Populate the arrays with indices according to which side they fell on\n nLeft = 0;\n nRight = 0;\n for (let i = 0; i < side.length; i++) {\n if (side[i] === 0) {\n indicesLeft[nLeft] = indices[i];\n nLeft += 1;\n }\n else {\n indicesRight[nRight] = indices[i];\n nRight += 1;\n }\n }\n return {\n indicesLeft,\n indicesRight,\n hyperplane: hyperplaneVector,\n offset: hyperplaneOffset,\n };\n}\nfunction flattenTree(tree, leafSize) {\n const nNodes = numNodes(tree);\n const nLeaves = numLeaves(tree);\n // TODO: Verify that sparse code is not relevant...\n const hyperplanes = utils\n .range(nNodes)\n .map(() => tree.hyperplane ? 1 : 0);\n const offsets = utils.zeros(nNodes);\n const children = utils.range(nNodes).map(() => [-1, -1]);\n const indices = utils\n .range(nLeaves)\n .map(() => utils.range(leafSize).map(() => -1));\n recursiveFlatten(tree, hyperplanes, offsets, children, indices, 0, 0);\n return new FlatTree(hyperplanes, offsets, children, indices);\n}\nfunction recursiveFlatten(tree, hyperplanes, offsets, children, indices, nodeNum, leafNum) {\n if (tree.isLeaf) {\n children[nodeNum][0] = -leafNum;\n // TODO: Triple check this operation corresponds to\n // indices[leafNum : tree.indices.shape[0]] = tree.indices\n indices[leafNum].splice(0, tree.indices.length, ...tree.indices);\n leafNum += 1;\n return { nodeNum, leafNum };\n }\n else {\n hyperplanes[nodeNum] = tree.hyperplane;\n offsets[nodeNum] = tree.offset;\n children[nodeNum][0] = nodeNum + 1;\n const oldNodeNum = nodeNum;\n let res = recursiveFlatten(tree.leftChild, hyperplanes, offsets, children, indices, nodeNum + 1, leafNum);\n nodeNum = res.nodeNum;\n leafNum = res.leafNum;\n children[oldNodeNum][1] = nodeNum + 1;\n res = recursiveFlatten(tree.rightChild, hyperplanes, offsets, children, indices, nodeNum + 1, leafNum);\n return { nodeNum: res.nodeNum, leafNum: res.leafNum };\n }\n}\nfunction numNodes(tree) {\n if (tree.isLeaf)\n return 1;\n else\n return 1 + numNodes(tree.leftChild) + numNodes(tree.rightChild);\n}\nfunction numLeaves(tree) {\n if (tree.isLeaf)\n return 1;\n else\n return numLeaves(tree.leftChild) + numLeaves(tree.rightChild);\n}\n/**\n * Generate an array of sets of candidate nearest neighbors by\n * constructing a random projection forest and taking the leaves of all the\n * trees. Any given tree has leaves that are a set of potential nearest\n * neighbors. Given enough trees the set of all such leaves gives a good\n * likelihood of getting a good set of nearest neighbors in composite. Since\n * such a random projection forest is inexpensive to compute, this can be a\n * useful means of seeding other nearest neighbor algorithms.\n */\nexport function makeLeafArray(rpForest) {\n if (rpForest.length > 0) {\n const output = [];\n for (const tree of rpForest)\n output.push(...tree.indices);\n return output;\n }\n else {\n return [[-1]];\n }\n}\n/**\n * Selects the side of the tree to search during flat tree search.\n */\nfunction selectSide(hyperplane, offset, point, random) {\n let margin = offset;\n margin += hyperplane * point;\n if (margin === 0) {\n const side = utils.tauRandInt(2, random);\n return side;\n }\n else if (margin > 0) {\n return 0;\n }\n else {\n return 1;\n }\n}\n/**\n * Searches a flattened rp-tree for a point.\n */\nexport function searchFlatTree(point, tree, random) {\n let node = 0;\n while (tree.children[node][0] > 0) {\n const side = selectSide(tree.hyperplanes[node], tree.offsets[node], point, random);\n if (side === 0)\n node = tree.children[node][0];\n else\n node = tree.children[node][1];\n }\n const index = -1 * tree.children[node][0];\n return tree.indices[index];\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBZWpDLE1BQU0sT0FBTyxRQUFRO0lBQ25CLFlBQ1MsV0FBcUIsRUFDckIsT0FBaUIsRUFDakIsUUFBb0IsRUFDcEIsT0FBbUI7UUFIbkIsZ0JBQVcsR0FBWCxXQUFXLENBQVU7UUFDckIsWUFBTyxHQUFQLE9BQU8sQ0FBVTtRQUNqQixhQUFRLEdBQVIsUUFBUSxDQUFZO1FBQ3BCLFlBQU8sR0FBUCxPQUFPLENBQVk7SUFDekIsQ0FBQztDQUNMO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUN4QixJQUFZLEVBQ1osVUFBa0IsRUFDbEIsTUFBYyxFQUNkLE1BQWdCO0lBRWhCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRTFDLE1BQU0sS0FBSyxHQUFHLEtBQUs7U0FDaEIsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUNiLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUVoRSxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxRQUFRLENBQ2YsSUFBWSxFQUNaLFFBQVEsR0FBRyxFQUFF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SSxJQUFJLEtBQUssQ0FBQztZQUNaLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOztZQUU5QixJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbi8qKlxuICogVGhpcyBpcyBhIEphdmFTY3JpcHQgcmVpbXBsZW1lbnRhdGlvbiBvZiBVTUFQIChvcmlnaW5hbCBsaWNlbnNlIGJlbG93KSwgZnJvbVxuICogdGhlIHB5dGhvbiBpbXBsZW1lbnRhdGlvbiBmb3VuZCBhdCBodHRwczovL2dpdGh1Yi5jb20vbG1jaW5uZXMvdW1hcC5cbiAqXG4gKiBAYXV0aG9yIGFuZHljb2VuZW5AZ29vZ2xlLmNvbSAoQW5keSBDb2VuZW4pXG4gKi9cblxuLyoqXG4gKiBAbGljZW5zZVxuICogQlNEIDMtQ2xhdXNlIExpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTcsIExlbGFuZCBNY0lubmVzXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiAqICAgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAqICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBjb3B5cmlnaHQgaG9sZGVyIG5vciB0aGUgbmFtZXMgb2YgaXRzXG4gKiAgIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tXG4gKiAgIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRVxuICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUxcbiAqIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SXG4gKiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUlxuICogQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSxcbiAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFXG4gKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHtSYW5kb21GbiwgVmVjdG9yfSBmcm9tICcuL3VtYXAnO1xuXG4vKipcbiAqIFRyZWUgZnVuY3Rpb25hbGl0eSBmb3IgYXBwcm94aW1hdGluZyBuZWFyZXN0IG5laWdoYm9yc1xuICovXG5pbnRlcmZhY2UgUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlIHtcbiAgaXNMZWFmOiBib29sZWFuO1xuICBpbmRpY2VzPzogbnVtYmVyW107XG4gIGxlZnRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgcmlnaHRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgaHlwZXJwbGFuZT86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgRmxhdFRyZWUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgaHlwZXJwbGFuZXM6IG51bWJlcltdLFxuICAgIHB1YmxpYyBvZmZzZXRzOiBudW1iZXJbXSxcbiAgICBwdWJsaWMgY2hpbGRyZW46IG51bWJlcltdW10sXG4gICAgcHVibGljIGluZGljZXM6IG51bWJlcltdW11cbiAgKSB7fVxufVxuXG4vKipcbiAqIEJ1aWxkIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IHdpdGggYGBuVHJlZXNgYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VGb3Jlc3QoXG4gIGRhdGE6IFZlY3RvcixcbiAgbk5laWdoYm9yczogbnVtYmVyLFxuICBuVHJlZXM6IG51bWJlcixcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IGxlYWZTaXplID0gTWF0aC5tYXgoMTAsIG5OZWlnaGJvcnMpO1xuXG4gIGNvbnN0IHRyZWVzID0gdXRpbHNcbiAgICAucmFuZ2UoblRyZWVzKVxuICAgIC5tYXAoKF8sIGkpID0+IG1ha2VUcmVlKGRhdGEsIGxlYWZTaXplLCBpLCByYW5kb20pKTtcbiAgY29uc3QgZm9yZXN0ID0gdHJlZXMubWFwKCh0cmVlKSA9PiBmbGF0dGVuVHJlZSh0cmVlLCBsZWFmU2l6ZSkpO1xuXG4gIHJldHVybiBmb3Jlc3Q7XG59XG5cbi8qKlxuICogQ29uc3RydWN0IGEgcmFuZG9tIHByb2plY3Rpb24gdHJlZSBiYXNlZCBvbiBgYGRhdGFgYCB3aXRoIGxlYXZlc1xuICogb2Ygc2l6ZSBhdCBtb3N0IGBgbGVhZlNpemVgYFxuICovXG5mdW5jdGlvbiBtYWtlVHJlZShcbiAgZGF0YTogVmVjdG9yLFxuICBsZWFmU2l6ZSA9IDMwLFxuICBuOiBudW1iZXIsXG4gIHJhbmRvbTogUmFuZG9tRm5cbik6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSB7XG4gIGNvbnN0IGluZGljZXMgPSB1dGlscy5yYW5nZShkYXRhLmxlbmd0aCk7XG4gIGNvbnN0IHRyZWUgPSBtYWtlRXVjbGlkZWFuVHJlZShkYXRhLCBpbmRpY2VzLCBsZWFmU2l6ZSwgbiwgcmFuZG9tKTtcbiAgcmV0dXJuIHRyZWU7XG59XG5cbmZ1bmN0aW9uIG1ha2VFdWNsaWRlYW5UcmVlKFxuICBkYXRhOiBWZWN0b3IsXG4gIGluZGljZXM6IG51bWJlcltdLFxuICBsZWFmU2l6ZSA9IDMwLFxuICBxOiBudW1iZXIsXG4gIHJhbmRvbTogUmFuZG9tRm5cbik6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSB7XG4gIGlmIChpbmRpY2VzLmxlbmd0aCA+IGxlYWZTaXplKSB7XG4gICAgY29uc3Qgc3BsaXRSZXN1bHRzID0gZXVjbGlkZWFuUmFuZG9tUHJvamVjdGlvblNwbGl0KGRhdGEsIGluZGljZXMsIHJhbmRvbSk7XG4gICAgY29uc3Qge2luZGljZXNMZWZ0LCBpbmRpY2VzUmlnaHQsIGh5cGVycGxhbmUsIG9mZnNldH0gPSBzcGxpdFJlc3VsdHM7XG5cbiAgICBjb25zdCBsZWZ0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzTGVmdCxcbiAgICAgIGxlYWZTaXplLFxuICAgICAgcSArIDEsXG4gICAgICByYW5kb21cbiAgICApO1xuICAgIGNvbnN0IHJpZ2h0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzUmlnaHQsXG4gICAgICBsZWFmU2l6ZSxcbiAgICAgIHEgKyAxLFxuICAgICAgcmFuZG9tXG4gICAgKTtcblxuICAgIGNvbnN0IG5vZGUgPSB7bGVmdENoaWxkLCByaWdodENoaWxkLCBpc0xlYWY6IGZhbHNlLCBoeXBlcnBsYW5lLCBvZmZzZXR9O1xuICAgIHJldHVybiBub2RlO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IG5vZGUgPSB7aW5kaWNlcywgaXNMZWFmOiB0cnVlfTtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxufVxuXG4vKipcbiAqIEdpdmVuIGEgc2V0IG9mIGBgaW5kaWNlc2BgIGZvciBkYXRhIHBvaW50cyBmcm9tIGBgZGF0YWBgLCBjcmVhdGVcbiAqIGEgcmFuZG9tIGh5cGVycGxhbmUgdG8gc3BsaXQgdGhlIGRhdGEsIHJldHVybmluZyB0d28gYXJyYXlzIGluZGljZXNcbiAqIHRoYXQgZmFsbCBvbiBlaXRoZXIgc2lkZSBvZiB0aGUgaHlwZXJwbGFuZS4gVGhpcyBpcyB0aGUgYmFzaXMgZm9yIGFcbiAqIHJhbmRvbSBwcm9qZWN0aW9uIHRyZWUsIHdoaWNoIHNpbXBseSB1c2VzIHRoaXMgc3BsaXR0aW5nIHJlY3Vyc2l2ZWx5LlxuICogVGhpcyBwYXJ0aWN1bGFyIHNwbGl0IHVzZXMgZXVjbGlkZWFuIGRpc3RhbmNlIHRvIGRldGVybWluZSB0aGUgaHlwZXJwbGFuZVxuICogYW5kIHdoaWNoIHNpZGUgZWFjaCBkYXRhIHNhbXBsZSBmYWxscyBvbi5cbiAqL1xuZnVuY3Rpb24gZXVjbGlkZWFuUmFuZG9tUHJvamVjdGlvblNwbGl0KFxuICBkYXRhOiBWZWN0b3IsXG4gIGluZGljZXM6IG51bWJlcltdLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgLy9jb25zdCBkaW0gPSAxO1xuXG4gIC8vIFNlbGVjdCB0d28gcmFuZG9tIHBvaW50cywgc2V0IHRoZSBoeXBlcnBsYW5lIGJldHdlZW4gdGhlbVxuICBjb25zdCBsZWZ0SW5kZXggPSB1dGlscy50YXVSYW5kSW50KGluZGljZXMubGVuZ3RoLCByYW5kb20pO1xuICBsZXQgcmlnaHRJbmRleCA9IHV0aWxzLnRhdVJhbmRJbnQoaW5kaWNlcy5sZW5ndGgsIHJhbmRvbSk7XG4gIHJpZ2h0SW5kZXggKz0gbGVmdEluZGV4ID09PSByaWdodEluZGV4ID8gMSA6IDA7XG4gIHJpZ2h0SW5kZXggPSByaWdodEluZGV4ICUgaW5kaWNlcy5sZW5ndGg7XG4gIGNvbnN0IGxlZnQgPSBpbmRpY2VzW2xlZnRJbmRleF07XG4gIGNvbnN0IHJpZ2h0ID0gaW5kaWNlc1tyaWdodEluZGV4XTtcblxuICAvLyBDb21wdXRlIHRoZSBub3JtYWwgdmVjdG9yIHRvIHRoZSBoeXBlcnBsYW5lICh0aGUgdmVjdG9yIGJldHdlZW4gdGhlIHR3b1xuICAvLyBwb2ludHMpIGFuZCB0aGUgb2Zmc2V0IGZyb20gdGhlIG9yaWdpblxuICBsZXQgaHlwZXJwbGFuZU9mZnNldCA9IDA7XG4gIGxldCBoeXBlcnBsYW5lVmVjdG9yID0gMDtcblxuXG4gIGh5cGVycGxhbmVWZWN0b3IgPSBkYXRhW2xlZnRdIC0gZGF0YVtyaWdodF07XG4gIGh5cGVycGxhbmVPZmZzZXQgLT1cbiAgICAoaHlwZXJwbGFuZVZlY3RvciAqIChkYXRhW2xlZnRdICsgZGF0YVtyaWdodF0pKSAvIDIuMDtcblxuXG4gIC8vIEZvciBlYWNoIHBvaW50IGNvbXB1dGUgdGhlIG1hcmdpbiAocHJvamVjdCBpbnRvIG5vcm1hbCB2ZWN0b3IpXG4gIC8vIElmIHdlIGFyZSBvbiBsb3dlciBzaWRlIG9mIHRoZSBoeXBlcnBsYW5lIHB1dCBpbiBvbmUgcGlsZSwgb3RoZXJ3aXNlXG4gIC8vIHB1dCBpdCBpbiB0aGUgb3RoZXIgcGlsZSAoaWYgd2UgaGl0IGh5cGVycGxhbmUgb24gdGhlIG5vc2UsIGZsaXAgYSBjb2luKVxuICBsZXQgbkxlZnQgPSAwO1xuICBsZXQgblJpZ2h0ID0gMDtcbiAgY29uc3Qgc2lkZSA9IHV0aWxzLnplcm9zKGluZGljZXMubGVuZ3RoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IG1hcmdpbiA9IGh5cGVycGxhbmVPZmZzZXQ7XG5cbiAgICBtYXJnaW4gKz0gaHlwZXJwbGFuZVZlY3RvciAqIGRhdGFbaW5kaWNlc1tpXV07XG5cbiAgICBpZiAobWFyZ2luID09PSAwKSB7XG4gICAgICBzaWRlW2ldID0gdXRpbHMudGF1UmFuZEludCgyLCByYW5kb20pO1xuICAgICAgaWYgKHNpZGVbaV0gPT09IDApXG4gICAgICAgIG5MZWZ0ICs9IDE7XG4gICAgICBlbHNlXG4gICAgICAgIG5SaWdodCArPSAxO1xuICAgIH0gZWxzZSBpZiAobWFyZ2luID4gMCkge1xuICAgICAgc2lkZVtpXSA9IDA7XG4gICAgICBuTGVmdCArPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaWRlW2ldID0gMTtcbiAgICAgIG5SaWdodCArPSAxO1xuICAgIH1cbiAgfVxuXG4gIC8vIE5vdyB0aGF0IHdlIGhhdmUgdGhlIGNvdW50cywgYWxsb2NhdGUgYXJyYXlzXG4gIGNvbnN0IGluZGljZXNMZWZ0ID0gdXRpbHMuemVyb3MobkxlZnQpO1xuICBjb25zdCBpbmRpY2VzUmlnaHQgPSB1dGlscy56ZXJvcyhuUmlnaHQpO1xuXG4gIC8vIFBvcHVsYXRlIHRoZSBhcnJheXMgd2l0aCBpbmRpY2VzIGFjY29yZGluZyB0byB3aGljaCBzaWRlIHRoZXkgZmVsbCBvblxuICBuTGVmdCA9IDA7XG4gIG5SaWdodCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2lkZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChzaWRlW2ldID09PSAwKSB7XG4gICAgICBpbmRpY2VzTGVmdFtuTGVmdF0gPSBpbmRpY2VzW2ldO1xuICAgICAgbkxlZnQgKz0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5kaWNlc1JpZ2h0W25SaWdodF0gPSBpbmRpY2VzW2ldO1xuICAgICAgblJpZ2h0ICs9IDE7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBpbmRpY2VzTGVmdCxcbiAgICBpbmRpY2VzUmlnaHQsXG4gICAgaHlwZXJwbGFuZTogaHlwZXJwbGFuZVZlY3RvcixcbiAgICBvZmZzZXQ6IGh5cGVycGxhbmVPZmZzZXQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGZsYXR0ZW5UcmVlKHRyZWU6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSwgbGVhZlNpemU6IG51bWJlcikge1xuICBjb25zdCBuTm9kZXMgPSBudW1Ob2Rlcyh0cmVlKTtcbiAgY29uc3QgbkxlYXZlcyA9IG51bUxlYXZlcyh0cmVlKTtcblxuICAvLyBUT0RPOiBWZXJpZnkgdGhhdCBzcGFyc2UgY29kZSBpcyBub3QgcmVsZXZhbnQuLi5cbiAgY29uc3QgaHlwZXJwbGFuZXMgPSB1dGlsc1xuICAgIC5yYW5nZShuTm9kZXMpXG4gICAgLm1hcCgoKSA9PiB0cmVlLmh5cGVycGxhbmUgPyAxIDogMCk7XG5cbiAgY29uc3Qgb2Zmc2V0cyA9IHV0aWxzLnplcm9zKG5Ob2Rlcyk7XG4gIGNvbnN0IGNoaWxkcmVuID0gdXRpbHMucmFuZ2Uobk5vZGVzKS5tYXAoKCkgPT4gWy0xLCAtMV0pO1xuICBjb25zdCBpbmRpY2VzID0gdXRpbHNcbiAgICAucmFuZ2UobkxlYXZlcylcbiAgICAubWFwKCgpID0+IHV0aWxzLnJhbmdlKGxlYWZTaXplKS5tYXAoKCkgPT4gLTEpKTtcbiAgcmVjdXJzaXZlRmxhdHRlbih0cmVlLCBoeXBlcnBsYW5lcywgb2Zmc2V0cywgY2hpbGRyZW4sIGluZGljZXMsIDAsIDApO1xuICByZXR1cm4gbmV3IEZsYXRUcmVlKGh5cGVycGxhbmVzLCBvZmZzZXRzLCBjaGlsZHJlbiwgaW5kaWNlcyk7XG59XG5cbmZ1bmN0aW9uIHJlY3Vyc2l2ZUZsYXR0ZW4oXG4gIHRyZWU6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSxcbiAgaHlwZXJwbGFuZXM6IG51bWJlcltdLFxuICBvZmZzZXRzOiBudW1iZXJbXSxcbiAgY2hpbGRyZW46IG51bWJlcltdW10sXG4gIGluZGljZXM6IG51bWJlcltdW10sXG4gIG5vZGVOdW06IG51bWJlcixcbiAgbGVhZk51bTogbnVtYmVyXG4pOiB7IG5vZGVOdW06IG51bWJlcjsgbGVhZk51bTogbnVtYmVyIH0ge1xuICBpZiAodHJlZS5pc0xlYWYpIHtcbiAgICBjaGlsZHJlbltub2RlTnVtXVswXSA9IC1sZWFmTnVtO1xuXG4gICAgLy8gVE9ETzogVHJpcGxlIGNoZWNrIHRoaXMgb3BlcmF0aW9uIGNvcnJlc3BvbmRzIHRvXG4gICAgLy8gaW5kaWNlc1tsZWFmTnVtIDogdHJlZS5pbmRpY2VzLnNoYXBlWzBdXSA9IHRyZWUuaW5kaWNlc1xuICAgIGluZGljZXNbbGVhZk51bV0uc3BsaWNlKDAsIHRyZWUuaW5kaWNlcyEubGVuZ3RoLCAuLi50cmVlLmluZGljZXMhKTtcbiAgICBsZWFmTnVtICs9IDE7XG4gICAgcmV0dXJuIHtub2RlTnVtLCBsZWFmTnVtfTtcbiAgfSBlbHNlIHtcbiAgICBoeXBlcnBsYW5lc1tub2RlTnVtXSA9IHRyZWUuaHlwZXJwbGFuZSE7XG4gICAgb2Zmc2V0c1tub2RlTnVtXSA9IHRyZWUub2Zmc2V0ITtcbiAgICBjaGlsZHJlbltub2RlTnVtXVswXSA9IG5vZGVOdW0gKyAxO1xuICAgIGNvbnN0IG9sZE5vZGVOdW0gPSBub2RlTnVtO1xuXG4gICAgbGV0IHJlcyA9IHJlY3Vyc2l2ZUZsYXR0ZW4oXG4gICAgICB0cmVlLmxlZnRDaGlsZCEsXG4gICAgICBoeXBlcnBsYW5lcyxcbiAgICAgIG9mZnNldHMsXG4gICAgICBjaGlsZHJlbixcbiAgICAgIGluZGljZXMsXG4gICAgICBub2RlTnVtICsgMSxcbiAgICAgIGxlYWZOdW1cbiAgICApO1xuICAgIG5vZGVOdW0gPSByZXMubm9kZU51bTtcbiAgICBsZWFmTnVtID0gcmVzLmxlYWZOdW07XG5cbiAgICBjaGlsZHJlbltvbGROb2RlTnVtXVsxXSA9IG5vZGVOdW0gKyAxO1xuXG4gICAgcmVzID0gcmVjdXJzaXZlRmxhdHRlbihcbiAgICAgIHRyZWUucmlnaHRDaGlsZCEsXG4gICAgICBoeXBlcnBsYW5lcyxcbiAgICAgIG9mZnNldHMsXG4gICAgICBjaGlsZHJlbixcbiAgICAgIGluZGljZXMsXG4gICAgICBub2RlTnVtICsgMSxcbiAgICAgIGxlYWZOdW1cbiAgICApO1xuICAgIHJldHVybiB7bm9kZU51bTogcmVzLm5vZGVOdW0sIGxlYWZOdW06IHJlcy5sZWFmTnVtfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1Ob2Rlcyh0cmVlOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUpOiBudW1iZXIge1xuICBpZiAodHJlZS5pc0xlYWYpXG4gICAgcmV0dXJuIDE7XG4gIGVsc2VcbiAgICByZXR1cm4gMSArIG51bU5vZGVzKHRyZWUubGVmdENoaWxkISkgKyBudW1Ob2Rlcyh0cmVlLnJpZ2h0Q2hpbGQhKTtcbn1cblxuZnVuY3Rpb24gbnVtTGVhdmVzKHRyZWU6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSk6IG51bWJlciB7XG4gIGlmICh0cmVlLmlzTGVhZilcbiAgICByZXR1cm4gMTtcbiAgZWxzZVxuICAgIHJldHVybiBudW1MZWF2ZXModHJlZS5sZWZ0Q2hpbGQhKSArIG51bUxlYXZlcyh0cmVlLnJpZ2h0Q2hpbGQhKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhbiBhcnJheSBvZiBzZXRzIG9mIGNhbmRpZGF0ZSBuZWFyZXN0IG5laWdoYm9ycyBieVxuICogY29uc3RydWN0aW5nIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IGFuZCB0YWtpbmcgdGhlIGxlYXZlcyBvZiBhbGwgdGhlXG4gKiB0cmVlcy4gQW55IGdpdmVuIHRyZWUgaGFzIGxlYXZlcyB0aGF0IGFyZSBhIHNldCBvZiBwb3RlbnRpYWwgbmVhcmVzdFxuICogbmVpZ2hib3JzLiBHaXZlbiBlbm91Z2ggdHJlZXMgdGhlIHNldCBvZiBhbGwgc3VjaCBsZWF2ZXMgZ2l2ZXMgYSBnb29kXG4gKiBsaWtlbGlob29kIG9mIGdldHRpbmcgYSBnb29kIHNldCBvZiBuZWFyZXN0IG5laWdoYm9ycyBpbiBjb21wb3NpdGUuIFNpbmNlXG4gKiBzdWNoIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IGlzIGluZXhwZW5zaXZlIHRvIGNvbXB1dGUsIHRoaXMgY2FuIGJlIGFcbiAqIHVzZWZ1bCBtZWFucyBvZiBzZWVkaW5nIG90aGVyIG5lYXJlc3QgbmVpZ2hib3IgYWxnb3JpdGhtcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VMZWFmQXJyYXkocnBGb3Jlc3Q6IEZsYXRUcmVlW10pOiBudW1iZXJbXVtdIHtcbiAgaWYgKHJwRm9yZXN0Lmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBvdXRwdXQ6IG51bWJlcltdW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRyZWUgb2YgcnBGb3Jlc3QpXG4gICAgICBvdXRwdXQucHVzaCguLi50cmVlLmluZGljZXMhKTtcblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtbLTFdXTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbGVjdHMgdGhlIHNpZGUgb2YgdGhlIHRyZWUgdG8gc2VhcmNoIGR1cmluZyBmbGF0IHRyZWUgc2VhcmNoLlxuICovXG5mdW5jdGlvbiBzZWxlY3RTaWRlKFxuICBoeXBlcnBsYW5lOiBudW1iZXIsXG4gIG9mZnNldDogbnVtYmVyLFxuICBwb2ludDogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgbGV0IG1hcmdpbiA9IG9mZnNldDtcblxuICBtYXJnaW4gKz0gaHlwZXJwbGFuZSAqIHBvaW50O1xuXG5cbiAgaWYgKG1hcmdpbiA9PT0gMCkge1xuICAgIGNvbnN0IHNpZGUgPSB1dGlscy50YXVSYW5kSW50KDIsIHJhbmRvbSk7XG4gICAgcmV0dXJuIHNpZGU7XG4gIH0gZWxzZSBpZiAobWFyZ2luID4gMCkge1xuICAgIHJldHVybiAwO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAxO1xuICB9XG59XG5cbi8qKlxuICogU2VhcmNoZXMgYSBmbGF0dGVuZWQgcnAtdHJlZSBmb3IgYSBwb2ludC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlYXJjaEZsYXRUcmVlKFxuICBwb2ludDogbnVtYmVyLFxuICB0cmVlOiBGbGF0VHJlZSxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGxldCBub2RlID0gMDtcbiAgd2hpbGUgKHRyZWUuY2hpbGRyZW5bbm9kZV1bMF0gPiAwKSB7XG4gICAgY29uc3Qgc2lkZSA9IHNlbGVjdFNpZGUoXG4gICAgICB0cmVlLmh5cGVycGxhbmVzW25vZGVdLFxuICAgICAgdHJlZS5vZmZzZXRzW25vZGVdLFxuICAgICAgcG9pbnQsXG4gICAgICByYW5kb21cbiAgICApO1xuICAgIGlmIChzaWRlID09PSAwKVxuICAgICAgbm9kZSA9IHRyZWUuY2hpbGRyZW5bbm9kZV1bMF07XG4gICAgZWxzZVxuICAgICAgbm9kZSA9IHRyZWUuY2hpbGRyZW5bbm9kZV1bMV07XG4gIH1cblxuICBjb25zdCBpbmRleCA9IC0xICogdHJlZS5jaGlsZHJlbltub2RlXVswXTtcbiAgcmV0dXJuIHRyZWUuaW5kaWNlc1tpbmRleF07XG59XG4iXX0=","const toString = Object.prototype.toString;\n\nexport default function isAnyArray(object) {\n return toString.call(object).endsWith('Array]');\n}\n","/**\n * Calculate current error\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} parameters - Array of current parameter values\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {number}\n */\nexport default function errorCalculation(\n data,\n parameters,\n parameterizedFunction,\n) {\n let error = 0;\n const func = parameterizedFunction(parameters);\n\n for (let i = 0; i < data.x.length; i++) {\n error += Math.abs(data.y[i] - func(data.x[i]));\n }\n\n return error;\n}\n","import { inverse, Matrix } from 'ml-matrix';\n\n/**\n * Difference of the matrix function over the parameters\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} evaluatedData - Array of previous evaluated function values\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number} gradientDifference - Adjustment for decrease the damping parameter\n * @param {function} paramFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {Matrix}\n */\nfunction gradientFunction(\n data,\n evaluatedData,\n params,\n gradientDifference,\n paramFunction,\n) {\n const n = params.length;\n const m = data.x.length;\n\n let ans = new Array(n);\n\n for (let param = 0; param < n; param++) {\n ans[param] = new Array(m);\n let auxParams = params.slice();\n auxParams[param] += gradientDifference;\n let funcParam = paramFunction(auxParams);\n\n for (let point = 0; point < m; point++) {\n ans[param][point] = evaluatedData[point] - funcParam(data.x[point]);\n }\n }\n return new Matrix(ans);\n}\n\n/**\n * Matrix function over the samples\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} evaluatedData - Array of previous evaluated function values\n * @return {Matrix}\n */\nfunction matrixFunction(data, evaluatedData) {\n const m = data.x.length;\n\n let ans = new Array(m);\n\n for (let point = 0; point < m; point++) {\n ans[point] = [data.y[point] - evaluatedData[point]];\n }\n\n return new Matrix(ans);\n}\n\n/**\n * Iteration for Levenberg-Marquardt\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number} damping - Levenberg-Marquardt parameter\n * @param {number} gradientDifference - Adjustment for decrease the damping parameter\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {Array<number>}\n */\nexport default function step(\n data,\n params,\n damping,\n gradientDifference,\n parameterizedFunction,\n) {\n let value = damping * gradientDifference * gradientDifference;\n let identity = Matrix.eye(params.length, params.length, value);\n\n const func = parameterizedFunction(params);\n\n let evaluatedData = new Float64Array(data.x.length);\n for (let i = 0; i < data.x.length; i++) {\n evaluatedData[i] = func(data.x[i]);\n }\n\n let gradientFunc = gradientFunction(\n data,\n evaluatedData,\n params,\n gradientDifference,\n parameterizedFunction,\n );\n let matrixFunc = matrixFunction(data, evaluatedData);\n let inverseMatrix = inverse(\n identity.add(gradientFunc.mmul(gradientFunc.transpose())),\n );\n\n params = new Matrix([params]);\n params = params.sub(\n inverseMatrix\n .mmul(gradientFunc)\n .mmul(matrixFunc)\n .mul(gradientDifference)\n .transpose(),\n );\n\n return params.to1DArray();\n}\n","/* eslint-disable max-len */\n/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as heap from './heap';\nimport * as matrix from './matrix';\nimport * as nnDescent from './nn_descent';\nimport * as tree from './tree';\nimport * as utils from './utils';\nimport LM from 'ml-levenberg-marquardt';\nconst SMOOTH_K_TOLERANCE = 1e-5;\nconst MIN_K_DIST_SCALE = 1e-3;\n/**\n * UMAP projection system, based on the python implementation from McInnes, L,\n * Healy, J, UMAP: Uniform Manifold Approximation and Projection for Dimension\n * Reduction (https://github.com/lmcinnes/umap).\n *\n * This implementation differs in a few regards:\n * a) The initialization of the embedding for optimization is not computed using\n * a spectral method, rather it is initialized randomly. This avoids some\n * computationally intensive matrix eigen computations that aren't easily\n * ported to JavaScript.\n * b) A lot of \"extra\" functionality has been omitted from this implementation,\n * most notably a great deal of alternate distance functions.\n *\n * This implementation provides three methods of reducing dimensionality:\n * 1) fit: fit the data synchronously\n * 2) fitAsync: fit the data asynchronously, with a callback function provided\n * that is invoked on each optimization step.\n * 3) initializeFit / step: manually initialize the algorithm then explictly\n * step through each epoch of the SGD optimization\n */\nexport class UMAP {\n get neighbors() {\n return this.nNeighbors;\n }\n constructor(params = {}) {\n this.learningRate = 1.0;\n this.localConnectivity = 1.0;\n this.minDist = 0.1;\n this.nComponents = 2;\n this.nEpochs = 0;\n this.nNeighbors = 15;\n this.negativeSampleRate = 5;\n this.random = Math.random;\n this.repulsionStrength = 1.0;\n this.setOpMixRatio = 1.0;\n this.spread = 1.0;\n this.transformQueueSize = 4.0;\n // Supervised projection params\n this.targetMetric = \"categorical\" /* TargetMetric.categorical */;\n this.targetWeight = 0.5;\n this.targetNNeighbors = 15;\n this.distanceFn = numeric;\n this.isInitialized = false;\n this.rpForest = [];\n // Projected embedding\n this.embedding = [];\n this.optimizationState = new OptimizationState();\n const setParam = (key) => {\n //@ts-ignore\n if (params[key] !== undefined)\n this[key] = params[key];\n };\n setParam('distanceFn');\n setParam('learningRate');\n setParam('localConnectivity');\n setParam('minDist');\n setParam('nComponents');\n setParam('nEpochs');\n setParam('nNeighbors');\n setParam('negativeSampleRate');\n setParam('random');\n setParam('repulsionStrength');\n setParam('setOpMixRatio');\n setParam('spread');\n setParam('transformQueueSize');\n this.targetNNeighbors = params.nNeighbors || this.nNeighbors || this.targetNNeighbors;\n }\n /**\n * Fit the data to a projected embedding space synchronously.\n */\n fit(X) {\n this.initializeFit(X);\n this.optimizeLayout();\n return this.embedding;\n }\n /**\n * Fit the data to a projected embedding space asynchronously, with a callback\n * function invoked on every epoch of optimization.\n */\n async fitAsync(X, callback = () => true) {\n this.initializeFit(X);\n await this.optimizeLayoutAsync(callback);\n return this.embedding;\n }\n /**\n * Initializes parameters needed for supervised projection.\n */\n setSupervisedProjection(Y, params = {}) {\n this.Y = Y;\n this.targetMetric = params.targetMetric || this.targetMetric;\n this.targetWeight = params.targetWeight || this.targetWeight;\n this.targetNNeighbors = params.targetNNeighbors || this.targetNNeighbors;\n }\n /**\n * Initializes umap with precomputed KNN indices and distances.\n */\n setPrecomputedKNN(knnIndices, knnDistances) {\n this.knnIndices = knnIndices;\n this.knnDistances = knnDistances;\n }\n /**\n * Initializes fit by computing KNN and a fuzzy simplicial set, as well as\n * initializing the projected embeddings. Sets the optimization state ahead\n * of optimization steps. Returns the number of epochs to be used for the\n * SGD optimization.\n */\n initializeFit(X) {\n if (X.length <= this.nNeighbors)\n throw new Error(`Not enough data points (${X.length}) to create nNeighbors: ${this.nNeighbors}. Add more data points or adjust the configuration.`);\n // We don't need to reinitialize if we've already initialized for this data.\n if (this.X === X && this.isInitialized)\n return this.getNEpochs();\n this.X = X;\n if (!this.knnIndices && !this.knnDistances) {\n const knnResults = this.nearestNeighbors(X);\n this.knnIndices = knnResults.knnIndices;\n this.knnDistances = knnResults.knnDistances;\n }\n this.graph = this.fuzzySimplicialSet(X, this.nNeighbors, this.setOpMixRatio);\n // Set up the search graph for subsequent transformation.\n this.makeSearchFns();\n this.searchGraph = this.makeSearchGraph(X);\n // Check if supervised projection, then adjust the graph.\n this.processGraphForSupervisedProjection();\n const { head, tail, epochsPerSample, } = this.initializeSimplicialSetEmbedding();\n // Set the optimization routine state\n this.optimizationState.head = head;\n this.optimizationState.tail = tail;\n this.optimizationState.epochsPerSample = epochsPerSample;\n // Now, initialize the optimization steps\n this.initializeOptimization();\n this.prepareForOptimizationLoop();\n this.isInitialized = true;\n return this.getNEpochs();\n }\n makeSearchFns() {\n const { initFromTree, initFromRandom } = nnDescent.makeInitializations(this.distanceFn);\n this.initFromTree = initFromTree;\n this.initFromRandom = initFromRandom;\n this.search = nnDescent.makeInitializedNNSearch(this.distanceFn);\n }\n makeSearchGraph(X) {\n const knnIndices = this.knnIndices;\n const knnDistances = this.knnDistances;\n const dims = [X.length, X.length];\n const searchGraph = new matrix.SparseMatrix([], [], [], dims);\n for (let i = 0; i < knnIndices.length; i++) {\n const knn = knnIndices[i];\n const distances = knnDistances[i];\n for (let j = 0; j < knn.length; j++) {\n const neighbor = knn[j];\n const distance = distances[j];\n if (distance > 0)\n searchGraph.set(i, neighbor, distance);\n }\n }\n const transpose = matrix.transpose(searchGraph);\n return matrix.maximum(searchGraph, transpose);\n }\n /**\n * Transforms data to the existing embedding space.\n */\n transform(toTransform) {\n // Use the previous rawData\n const rawData = this.X;\n if (rawData === undefined || rawData.length === 0)\n throw new Error('No data has been fit.');\n let nNeighbors = Math.floor(this.nNeighbors * this.transformQueueSize);\n nNeighbors = Math.min(rawData.length, nNeighbors);\n const init = nnDescent.initializeSearch(this.rpForest, rawData, toTransform, nNeighbors, this.initFromRandom, this.initFromTree, this.random);\n const result = this.search(rawData, this.searchGraph, init, toTransform);\n let { indices, weights: distances } = heap.deheapSort(result);\n indices = indices.map((x) => x.slice(0, this.nNeighbors));\n distances = distances.map((x) => x.slice(0, this.nNeighbors));\n const adjustedLocalConnectivity = Math.max(0, this.localConnectivity - 1);\n const { sigmas, rhos } = this.smoothKNNDistance(distances, this.nNeighbors, adjustedLocalConnectivity);\n const { rows, cols, vals } = this.computeMembershipStrengths(indices, distances, sigmas, rhos);\n const size = [toTransform.length, rawData.length];\n let graph = new matrix.SparseMatrix(rows, cols, vals, size);\n // This was a very specially constructed graph with constant degree.\n // That lets us do fancy unpacking by reshaping the csr matrix indices\n // and data. Doing so relies on the constant degree assumption!\n const normed = matrix.normalize(graph, \"l1\" /* matrix.NormType.l1 */);\n const csrMatrix = matrix.getCSR(normed);\n const nPoints = toTransform.length;\n const eIndices = utils.reshape2d(csrMatrix.indices, nPoints, this.nNeighbors);\n const eWeights = utils.reshape2d(csrMatrix.values, nPoints, this.nNeighbors);\n const embedding = initTransform(eIndices, eWeights, this.embedding);\n const nEpochs = this.nEpochs ?\n this.nEpochs / 3 :\n graph.nRows <= 10000 ?\n 100 :\n 30;\n const graphMax = graph\n .getValues()\n .reduce((max, val) => (val > max ? val : max), 0);\n graph = graph.map((value) => (value < graphMax / nEpochs ? 0 : value));\n graph = matrix.eliminateZeros(graph);\n const epochsPerSample = this.makeEpochsPerSample(graph.getValues(), nEpochs);\n const head = graph.getRows();\n const tail = graph.getCols();\n // Initialize optimization slightly differently than the fit method.\n this.assignOptimizationStateParameters({\n headEmbedding: embedding,\n tailEmbedding: this.embedding,\n head,\n tail,\n currentEpoch: 0,\n nEpochs,\n nVertices: graph.getDims()[1],\n epochsPerSample,\n });\n this.prepareForOptimizationLoop();\n return this.optimizeLayout();\n }\n /**\n * Checks if we're using supervised projection, then process the graph\n * accordingly.\n */\n processGraphForSupervisedProjection() {\n const { Y, X } = this;\n if (Y) {\n if (Y.length !== X.length)\n throw new Error('Length of X and y must be equal');\n if (this.targetMetric === \"categorical\" /* TargetMetric.categorical */) {\n const lt = this.targetWeight < 1.0;\n const farDist = lt ? 2.5 * (1.0 / (1.0 - this.targetWeight)) : 1.0e12;\n this.graph = this.categoricalSimplicialSetIntersection(this.graph, Y, farDist);\n }\n // TODO (andycoenen@): add non-categorical supervised embeddings.\n }\n }\n /**\n * Manually step through the optimization process one epoch at a time.\n */\n step() {\n const { currentEpoch } = this.optimizationState;\n if (currentEpoch < this.getNEpochs())\n this.optimizeLayoutStep(currentEpoch);\n return this.optimizationState.currentEpoch;\n }\n /**\n * Returns the computed projected embedding.\n */\n getEmbedding() {\n return this.embedding;\n }\n /**\n * Compute the ``nNeighbors`` nearest points for each data point in ``X``\n * This may be exact, but more likely is approximated via nearest neighbor\n * descent.\n */\n nearestNeighbors(X) {\n const { distanceFn, nNeighbors } = this;\n const log2 = (n) => Math.log(n) / Math.log(2);\n const metricNNDescent = nnDescent.makeNNDescent(distanceFn, this.random);\n // Handle python3 rounding down from 0.5 discrpancy\n const round = (n) => {\n return n === 0.5 ? 0 : Math.round(n);\n };\n const nTrees = 5 + Math.floor(round(X.length ** 0.5 / 20.0));\n const nIters = Math.max(5, Math.floor(Math.round(log2(X.length))));\n this.rpForest = tree.makeForest(X, nNeighbors, nTrees, this.random);\n const leafArray = tree.makeLeafArray(this.rpForest);\n const { indices, weights } = metricNNDescent(X, leafArray, nNeighbors, nIters);\n return { knnIndices: indices, knnDistances: weights };\n }\n /**\n * Given a set of data X, a neighborhood size, and a measure of distance\n * compute the fuzzy simplicial set (here represented as a fuzzy graph in\n * the form of a sparse matrix) associated to the data. This is done by\n * locally approximating geodesic distance at each point, creating a fuzzy\n * simplicial set for each such point, and then combining all the local\n * fuzzy simplicial sets into a global one via a fuzzy union.\n */\n fuzzySimplicialSet(X, nNeighbors, setOpMixRatio = 1.0) {\n const { knnIndices = [], knnDistances = [], localConnectivity } = this;\n const { sigmas, rhos } = this.smoothKNNDistance(knnDistances, nNeighbors, localConnectivity);\n const { rows, cols, vals } = this.computeMembershipStrengths(knnIndices, knnDistances, sigmas, rhos);\n const size = [X.length, X.length];\n const sparseMatrix = new matrix.SparseMatrix(rows, cols, vals, size);\n const transpose = matrix.transpose(sparseMatrix);\n const prodMatrix = matrix.pairwiseMultiply(sparseMatrix, transpose);\n const a = matrix.subtract(matrix.add(sparseMatrix, transpose), prodMatrix);\n const b = matrix.multiplyScalar(a, setOpMixRatio);\n const c = matrix.multiplyScalar(prodMatrix, 1.0 - setOpMixRatio);\n const result = matrix.add(b, c);\n return result;\n }\n /**\n * Combine a fuzzy simplicial set with another fuzzy simplicial set\n * generated from categorical data using categorical distances. The target\n * data is assumed to be categorical label data (a vector of labels),\n * and this will update the fuzzy simplicial set to respect that label data.\n */\n categoricalSimplicialSetIntersection(simplicialSet, target, farDist, unknownDist = 1.0) {\n let intersection = fastIntersection(simplicialSet, target, unknownDist, farDist);\n intersection = matrix.eliminateZeros(intersection);\n return resetLocalConnectivity(intersection);\n }\n /**\n * Compute a continuous version of the distance to the kth nearest\n * neighbor. That is, this is similar to knn-distance but allows continuous\n * k values rather than requiring an integral k. In esscence we are simply\n * computing the distance such that the cardinality of fuzzy set we generate\n * is k.\n */\n smoothKNNDistance(distances, k, localConnectivity = 1.0, nIter = 64, bandwidth = 1.0) {\n const target = (Math.log(k) / Math.log(2)) * bandwidth;\n const rho = utils.zeros(distances.length);\n const result = utils.zeros(distances.length);\n for (let i = 0; i < distances.length; i++) {\n let lo = 0.0;\n let hi = Infinity;\n let mid = 1.0;\n // TODO: This is very inefficient, but will do for now. FIXME\n const ithDistances = distances[i];\n const nonZeroDists = ithDistances.filter((d) => d > 0.0);\n if (nonZeroDists.length >= localConnectivity) {\n const index = Math.floor(localConnectivity);\n const interpolation = localConnectivity - index;\n if (index > 0) {\n rho[i] = nonZeroDists[index - 1];\n if (interpolation > SMOOTH_K_TOLERANCE) {\n rho[i] +=\n interpolation * (nonZeroDists[index] - nonZeroDists[index - 1]);\n }\n }\n else {\n rho[i] = interpolation * nonZeroDists[0];\n }\n }\n else if (nonZeroDists.length > 0) {\n rho[i] = utils.max(nonZeroDists);\n }\n for (let n = 0; n < nIter; n++) {\n let psum = 0.0;\n for (let j = 1; j < distances[i].length; j++) {\n const d = distances[i][j] - rho[i];\n if (d > 0)\n psum += Math.exp(-(d / mid));\n else\n psum += 1.0;\n }\n if (Math.abs(psum - target) < SMOOTH_K_TOLERANCE)\n break;\n if (psum > target) {\n hi = mid;\n mid = (lo + hi) / 2.0;\n }\n else {\n lo = mid;\n if (hi === Infinity)\n mid *= 2;\n else\n mid = (lo + hi) / 2.0;\n }\n }\n result[i] = mid;\n // TODO: This is very inefficient, but will do for now. FIXME\n if (rho[i] > 0.0) {\n const meanIthDistances = utils.mean(ithDistances);\n if (result[i] < MIN_K_DIST_SCALE * meanIthDistances)\n result[i] = MIN_K_DIST_SCALE * meanIthDistances;\n }\n else {\n const meanDistances = utils.mean(distances.map(utils.mean));\n if (result[i] < MIN_K_DIST_SCALE * meanDistances)\n result[i] = MIN_K_DIST_SCALE * meanDistances;\n }\n }\n return { sigmas: result, rhos: rho };\n }\n /**\n * Construct the membership strength data for the 1-skeleton of each local\n * fuzzy simplicial set -- this is formed as a sparse matrix where each row is\n * a local fuzzy simplicial set, with a membership strength for the\n * 1-simplex to each other data point.\n */\n computeMembershipStrengths(knnIndices, knnDistances, sigmas, rhos) {\n const nSamples = knnIndices.length;\n const nNeighbors = knnIndices[0].length;\n const rows = utils.zeros(nSamples * nNeighbors);\n const cols = utils.zeros(nSamples * nNeighbors);\n const vals = utils.zeros(nSamples * nNeighbors);\n for (let i = 0; i < nSamples; i++) {\n for (let j = 0; j < nNeighbors; j++) {\n let val = 0;\n if (knnIndices[i][j] === -1)\n continue; // We didn't get the full knn for i\n if (knnIndices[i][j] === i)\n val = 0.0;\n else if (knnDistances[i][j] - rhos[i] <= 0.0)\n val = 1.0;\n else\n val = Math.exp(-((knnDistances[i][j] - rhos[i]) / sigmas[i]));\n rows[i * nNeighbors + j] = i;\n cols[i * nNeighbors + j] = knnIndices[i][j];\n vals[i * nNeighbors + j] = val;\n }\n }\n return { rows, cols, vals };\n }\n /**\n * Initialize a fuzzy simplicial set embedding, using a specified\n * initialisation method and then minimizing the fuzzy set cross entropy\n * between the 1-skeletons of the high and low dimensional fuzzy simplicial\n * sets.\n */\n initializeSimplicialSetEmbedding() {\n const nEpochs = this.getNEpochs();\n const { nComponents } = this;\n const graphValues = this.graph.getValues();\n let graphMax = 0;\n for (let i = 0; i < graphValues.length; i++) {\n const value = graphValues[i];\n if (graphMax < graphValues[i])\n graphMax = value;\n }\n const graph = this.graph.map((value) => {\n if (value < graphMax / nEpochs)\n return 0;\n else\n return value;\n });\n // We're not computing the spectral initialization in this implementation\n // until we determine a better eigenvalue/eigenvector computation\n // approach\n this.embedding = utils.zeros(graph.nRows).map(() => {\n return utils.zeros(nComponents).map(() => {\n return utils.tauRand(this.random) * 20 + -10; // Random from -10 to 10\n });\n });\n // Get graph data in ordered way...\n const weights = [];\n const head = [];\n const tail = [];\n const rowColValues = graph.getAll();\n for (let i = 0; i < rowColValues.length; i++) {\n const entry = rowColValues[i];\n if (entry.value) {\n weights.push(entry.value);\n tail.push(entry.row);\n head.push(entry.col);\n }\n }\n const epochsPerSample = this.makeEpochsPerSample(weights, nEpochs);\n return { head, tail, epochsPerSample };\n }\n /**\n * Given a set of weights and number of epochs generate the number of\n * epochs per sample for each weight.\n */\n makeEpochsPerSample(weights, nEpochs) {\n const result = utils.filled(weights.length, -1.0);\n const max = utils.max(weights);\n const nSamples = weights.map((w) => (w / max) * nEpochs);\n nSamples.forEach((n, i) => {\n if (n > 0)\n result[i] = nEpochs / nSamples[i];\n });\n return result;\n }\n /**\n * Assigns optimization state parameters from a partial optimization state.\n */\n assignOptimizationStateParameters(state) {\n Object.assign(this.optimizationState, state);\n }\n /**\n * Sets a few optimization state parameters that are necessary before entering\n * the optimization step loop.\n */\n prepareForOptimizationLoop() {\n // Hyperparameters\n const { repulsionStrength, learningRate, negativeSampleRate } = this;\n const { epochsPerSample, headEmbedding, tailEmbedding, } = this.optimizationState;\n const dim = headEmbedding[0].length;\n const moveOther = headEmbedding.length === tailEmbedding.length;\n const epochsPerNegativeSample = epochsPerSample.map((e) => e / negativeSampleRate);\n const epochOfNextNegativeSample = [...epochsPerNegativeSample];\n const epochOfNextSample = [...epochsPerSample];\n this.assignOptimizationStateParameters({\n epochOfNextSample,\n epochOfNextNegativeSample,\n epochsPerNegativeSample,\n moveOther,\n initialAlpha: learningRate,\n alpha: learningRate,\n gamma: repulsionStrength,\n dim,\n });\n }\n /**\n * Initializes optimization state for stepwise optimization.\n */\n initializeOptimization() {\n // Algorithm state\n const headEmbedding = this.embedding;\n const tailEmbedding = this.embedding;\n // Initialized in initializeSimplicialSetEmbedding()\n const { head, tail, epochsPerSample } = this.optimizationState;\n const nEpochs = this.getNEpochs();\n const nVertices = this.graph.nCols;\n const { a, b } = findABParams(this.spread, this.minDist);\n this.assignOptimizationStateParameters({\n headEmbedding,\n tailEmbedding,\n head,\n tail,\n epochsPerSample,\n a,\n b,\n nEpochs,\n nVertices,\n });\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayoutStep(n) {\n const { optimizationState } = this;\n const { head, tail, headEmbedding, tailEmbedding, epochsPerSample, epochOfNextSample, epochOfNextNegativeSample, epochsPerNegativeSample, moveOther, initialAlpha, alpha, gamma, a, b, dim, nEpochs, nVertices, } = optimizationState;\n const clipValue = 4.0;\n for (let i = 0; i < epochsPerSample.length; i++) {\n if (epochOfNextSample[i] > n)\n continue;\n const j = head[i];\n const k = tail[i];\n const current = headEmbedding[j];\n const other = tailEmbedding[k];\n const distSquared = rDist(current, other);\n let gradCoeff = 0;\n if (distSquared > 0) {\n gradCoeff = -2.0 * a * b * Math.pow(distSquared, b - 1.0);\n gradCoeff /= a * Math.pow(distSquared, b) + 1.0;\n }\n for (let d = 0; d < dim; d++) {\n const gradD = clip(gradCoeff * (current[d] - other[d]), clipValue);\n current[d] += gradD * alpha;\n if (moveOther)\n other[d] += -gradD * alpha;\n }\n epochOfNextSample[i] += epochsPerSample[i];\n const nNegSamples = Math.floor((n - epochOfNextNegativeSample[i]) / epochsPerNegativeSample[i]);\n for (let p = 0; p < nNegSamples; p++) {\n const k = utils.tauRandInt(nVertices, this.random);\n const other = tailEmbedding[k];\n const distSquared = rDist(current, other);\n let gradCoeff = 0.0;\n if (distSquared > 0.0) {\n gradCoeff = 2.0 * gamma * b;\n gradCoeff /=\n (0.001 + distSquared) * (a * Math.pow(distSquared, b) + 1);\n }\n else if (j === k) {\n continue;\n }\n for (let d = 0; d < dim; d++) {\n let gradD = 4.0;\n if (gradCoeff > 0.0)\n gradD = clip(gradCoeff * (current[d] - other[d]), clipValue);\n current[d] += gradD * alpha;\n }\n }\n epochOfNextNegativeSample[i] += nNegSamples * epochsPerNegativeSample[i];\n }\n optimizationState.alpha = initialAlpha * (1.0 - n / nEpochs);\n optimizationState.currentEpoch += 1;\n return headEmbedding;\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayoutAsync(epochCallback = () => true) {\n return new Promise((resolve, reject) => {\n const step = async () => {\n try {\n const { nEpochs, currentEpoch } = this.optimizationState;\n this.embedding = this.optimizeLayoutStep(currentEpoch);\n const epochCompleted = this.optimizationState.currentEpoch;\n const shouldStop = epochCallback(epochCompleted) === false;\n const isFinished = epochCompleted === nEpochs;\n if (!shouldStop && !isFinished)\n setTimeout(() => step(), 0);\n else\n return resolve(isFinished);\n }\n catch (err) {\n reject(err);\n }\n };\n setTimeout(() => step(), 0);\n });\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayout(epochCallback = () => true) {\n let isFinished = false;\n let embedding = [];\n while (!isFinished) {\n const { nEpochs, currentEpoch } = this.optimizationState;\n embedding = this.optimizeLayoutStep(currentEpoch);\n const epochCompleted = this.optimizationState.currentEpoch;\n const shouldStop = epochCallback(epochCompleted) === false;\n isFinished = epochCompleted === nEpochs || shouldStop;\n }\n return embedding;\n }\n /**\n * Gets the number of epochs for optimizing the projection.\n * NOTE: This heuristic differs from the python version\n */\n getNEpochs() {\n const graph = this.graph;\n if (this.nEpochs > 0)\n return this.nEpochs;\n if (!graph)\n return 200;\n const length = graph.nRows;\n if (length <= 2500)\n return 500;\n else if (length <= 5000)\n return 400;\n else if (length <= 7500)\n return 300;\n else\n return 200;\n }\n}\nexport function euclidean(x, y) {\n let result = 0;\n for (let i = 0; i < x.length; i++)\n result += (x[i] - y[i]) ** 2;\n return Math.sqrt(result);\n}\nexport function numeric(x, y) {\n const result = Math.abs(x - y);\n return result;\n}\nexport function cosine(x, y) {\n let result = 0.0;\n let normX = 0.0;\n let normY = 0.0;\n for (let i = 0; i < x.length; i++) {\n result += x[i] * y[i];\n normX += x[i] ** 2;\n normY += y[i] ** 2;\n }\n if (normX === 0 && normY === 0)\n return 0;\n else if (normX === 0 || normY === 0)\n return 1.0;\n else\n return 1.0 - result / Math.sqrt(normX * normY);\n}\n/**\n * An interface representing the optimization state tracked between steps of\n * the SGD optimization\n */\nclass OptimizationState {\n constructor() {\n this.currentEpoch = 0;\n // Data tracked during optimization steps.\n this.headEmbedding = [];\n this.tailEmbedding = [];\n this.head = [];\n this.tail = [];\n this.epochsPerSample = [];\n this.epochOfNextSample = [];\n this.epochOfNextNegativeSample = [];\n this.epochsPerNegativeSample = [];\n this.moveOther = true;\n this.initialAlpha = 1.0;\n this.alpha = 1.0;\n this.gamma = 1.0;\n this.a = 1.5769434603113077;\n this.b = 0.8950608779109733;\n this.dim = 2;\n this.nEpochs = 500;\n this.nVertices = 0;\n }\n}\n/**\n * Standard clamping of a value into a fixed range\n */\nfunction clip(x, clipValue) {\n if (x > clipValue)\n return clipValue;\n else if (x < -clipValue)\n return -clipValue;\n else\n return x;\n}\n/**\n * Reduced Euclidean distance.\n */\nfunction rDist(x, y) {\n let result = 0.0;\n for (let i = 0; i < x.length; i++)\n result += Math.pow(x[i] - y[i], 2);\n return result;\n}\n/**\n * Fit a, b params for the differentiable curve used in lower\n * dimensional fuzzy simplicial complex construction. We want the\n * smooth curve (from a pre-defined family with simple gradient) that\n * best matches an offset exponential decay.\n */\nexport function findABParams(spread, minDist) {\n const curve = ([a, b]) => (x) => {\n return 1.0 / (1.0 + a * x ** (2 * b));\n };\n const xv = utils\n .linear(0, spread * 3, 300)\n .map((val) => (val < minDist ? 1.0 : val));\n const yv = utils.zeros(xv.length).map((val, index) => {\n const gte = xv[index] >= minDist;\n return gte ? Math.exp(-(xv[index] - minDist) / spread) : val;\n });\n const initialValues = [0.5, 0.5];\n const data = { x: xv, y: yv };\n // Default options for the algorithm (from github example)\n const options = {\n damping: 1.5,\n initialValues,\n gradientDifference: 10e-2,\n maxIterations: 100,\n errorTolerance: 10e-3,\n };\n // eslint-disable-next-line new-cap\n const { parameterValues } = LM(data, curve, options);\n const [a, b] = parameterValues;\n return { a, b };\n}\n/**\n * Under the assumption of categorical distance for the intersecting\n * simplicial set perform a fast intersection.\n */\nexport function fastIntersection(graph, target, unknownDist = 1.0, farDist = 5.0) {\n return graph.map((value, row, col) => {\n if (target[row] === -1 || target[col] === -1)\n return value * Math.exp(-unknownDist);\n else if (target[row] !== target[col])\n return value * Math.exp(-farDist);\n else\n return value;\n });\n}\n/**\n * Reset the local connectivity requirement -- each data sample should\n * have complete confidence in at least one 1-simplex in the simplicial set.\n * We can enforce this by locally rescaling confidences, and then remerging the\n * different local simplicial sets together.\n */\nexport function resetLocalConnectivity(simplicialSet) {\n simplicialSet = matrix.normalize(simplicialSet, \"max\" /* matrix.NormType.max */);\n const transpose = matrix.transpose(simplicialSet);\n const prodMatrix = matrix.pairwiseMultiply(transpose, simplicialSet);\n simplicialSet = matrix.add(simplicialSet, matrix.subtract(transpose, prodMatrix));\n return matrix.eliminateZeros(simplicialSet);\n}\n/**\n * Given indices and weights and an original embeddings\n * initialize the positions of new points relative to the\n * indices and weights (of their neighbors in the source data).\n */\nexport function initTransform(indices, weights, embedding) {\n const result = utils\n .zeros(indices.length)\n .map((_z) => utils.zeros(embedding[0].length));\n for (let i = 0; i < indices.length; i++) {\n for (let j = 0; j < indices[0].length; j++) {\n for (let d = 0; d < embedding[0].length; d++) {\n const a = indices[i][j];\n result[i][d] += weights[i][j] * embedding[a][d];\n }\n }\n }\n return result;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW1hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInVtYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNEJBQTRCO0FBQzVCOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVIOzs7OztHQUtHO0FBRUg7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQkc7QUFFSCxPQUFPLEtBQUssSUFBSSxNQUFNLFFBQVEsQ0FBQztBQUMvQixPQUFPLEtBQUssTUFBTSxNQUFNLFVBQVUsQ0FBQztBQUNuQyxPQUFPLEtBQUssU0FBUyxNQUFNLGNBQWMsQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLFFBQVEsQ0FBQztBQUMvQixPQUFPLEtBQUssS0FBSyxNQUFNLFNBQVMsQ0FBQztBQUNqQyxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQWF4QyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQztBQUNoQyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQztBQW1IOUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxNQUFNLE9BQU8sSUFBSTtJQTJDZixJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDekIsQ0FBQztJQUNELFlBQVksU0FBeUIsRUFBRTtRQTdDaEMsaUJBQVksR0FBRyxHQUFHLENBQUM7UUFDbkIsc0JBQWlCLEdBQUcsR0FBRyxDQUFDO1FBQ3hCLFlBQU8sR0FBRyxHQUFHLENBQUM7UUFDZCxnQkFBVyxHQUFHLENBQUMsQ0FBQztRQUNmLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWixlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLHVCQUFrQixHQUFHLENBQUMsQ0FBQztRQUN2QixXQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNyQixzQkFBaUIsR0FBRyxHQUFHLENBQUM7UUFDeEIsa0JBQWEsR0FBRyxHQUFHLENBQUM7UUFDcEIsV0FBTSxHQUFHLEdBQUcsQ0FBQztRQUNa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QyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUMzQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUM3QyxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hCLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG4vKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBoZWFwIGZyb20gJy4vaGVhcCc7XG5pbXBvcnQgKiBhcyBtYXRyaXggZnJvbSAnLi9tYXRyaXgnO1xuaW1wb3J0ICogYXMgbm5EZXNjZW50IGZyb20gJy4vbm5fZGVzY2VudCc7XG5pbXBvcnQgKiBhcyB0cmVlIGZyb20gJy4vdHJlZSc7XG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcbmltcG9ydCBMTSBmcm9tICdtbC1sZXZlbmJlcmctbWFycXVhcmR0JztcblxuZXhwb3J0IHR5cGUgRGlzdGFuY2VGbiA9ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gbnVtYmVyO1xuZXhwb3J0IHR5cGUgUmFuZG9tRm4gPSAoKSA9PiBudW1iZXI7XG5leHBvcnQgdHlwZSBFcG9jaENhbGxiYWNrID0gKGVwb2NoOiBudW1iZXIpID0+IGJvb2xlYW4gfCB2b2lkO1xuZXhwb3J0IHR5cGUgVmVjdG9yID0gbnVtYmVyW107XG5leHBvcnQgdHlwZSBWZWN0b3JzID0gVmVjdG9yW107XG5leHBvcnQgY29uc3QgZW51bSBUYXJnZXRNZXRyaWMge1xuICBjYXRlZ29yaWNhbCA9ICdjYXRlZ29yaWNhbCcsXG4gIGwxID0gJ2wxJyxcbiAgbDIgPSAnbDInLFxufVxuXG5jb25zdCBTTU9PVEhfS19UT0xFUkFOQ0UgPSAxZS01O1xuY29uc3QgTUlOX0tfRElTVF9TQ0FMRSA9IDFlLTM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVU1BUFBhcmFtZXRlcnMge1xuICAvKipcbiAgICogVGhlIGRpc3RhbmNlIGZ1bmN0aW9uIHdpdGggd2hpY2ggdG8gYXNzZXNzIG5lYXJlc3QgbmVpZ2hib3JzLCBkZWZhdWx0c1xuICAgKiB0byBldWNsaWRlYW4gZGlzdGFuY2UuXG4gICAqL1xuICBkaXN0YW5jZUZuPzogRGlzdGFuY2VGbjtcbiAgLyoqXG4gICAqIFRoZSBpbml0aWFsIGxlYXJuaW5nIHJhdGUgZm9yIHRoZSBlbWJlZGRpbmcgb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgbGVhcm5pbmdSYXRlPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGxvY2FsIGNvbm5lY3Rpdml0eSByZXF1aXJlZCAtLSBpLmUuIHRoZSBudW1iZXIgb2YgbmVhcmVzdFxuICAgKiBuZWlnaGJvcnMgdGhhdCBzaG91bGQgYmUgYXNzdW1lZCB0byBiZSBjb25uZWN0ZWQgYXQgYSBsb2NhbCBsZXZlbC5cbiAgICogVGhlIGhpZ2hlciB0aGlzIHZhbHVlIHRoZSBtb3JlIGNvbm5lY3RlZCB0aGUgbWFuaWZvbGQgYmVjb21lc1xuICAgKiBsb2NhbGx5LiBJbiBwcmFjdGljZSB0aGlzIHNob3VsZCBiZSBub3QgbW9yZSB0aGFuIHRoZSBsb2NhbCBpbnRyaW5zaWNcbiAgICogZGltZW5zaW9uIG9mIHRoZSBtYW5pZm9sZC5cbiAgICovXG4gIGxvY2FsQ29ubmVjdGl2aXR5PzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGVmZmVjdGl2ZSBtaW5pbXVtIGRpc3RhbmNlIGJldHdlZW4gZW1iZWRkZWQgcG9pbnRzLiBTbWFsbGVyIHZhbHVlc1xuICAgKiB3aWxsIHJlc3VsdCBpbiBhIG1vcmUgY2x1c3RlcmVkL2NsdW1wZWQgZW1iZWRkaW5nIHdoZXJlIG5lYXJieSBwb2ludHNcbiAgICogb24gdGhlIG1hbmlmb2xkIGFyZSBkcmF3biBjbG9zZXIgdG9nZXRoZXIsIHdoaWxlIGxhcmdlciB2YWx1ZXMgd2lsbFxuICAgKiByZXN1bHQgb24gYSBtb3JlIGV2ZW4gZGlzcGVyc2FsIG9mIHBvaW50cy4gVGhlIHZhbHVlIHNob3VsZCBiZSBzZXRcbiAgICogcmVsYXRpdmUgdG8gdGhlIGBgc3ByZWFkYGAgdmFsdWUsIHdoaWNoIGRldGVybWluZXMgdGhlIHNjYWxlIGF0IHdoaWNoXG4gICAqIGVtYmVkZGVkIHBvaW50cyB3aWxsIGJlIHNwcmVhZCBvdXQuXG4gICAqL1xuICBtaW5EaXN0PzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGRpbWVuc2lvbiBvZiB0aGUgc3BhY2UgdG8gZW1iZWQgaW50by4gVGhpcyBkZWZhdWx0cyB0byAyIHRvXG4gICAqIHByb3ZpZGUgZWFzeSB2aXN1YWxpemF0aW9uLCBidXQgY2FuIHJlYXNvbmFibHkgYmUgc2V0IHRvIGFueVxuICAgKiBpbnRlZ2VyIHZhbHVlIGluIHRoZSByYW5nZSAyIHRvIDEwMC5cbiAgICovXG4gIG5Db21wb25lbnRzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiB0cmFpbmluZyBlcG9jaHMgdG8gYmUgdXNlZCBpbiBvcHRpbWl6aW5nIHRoZVxuICAgKiBsb3cgZGltZW5zaW9uYWwgZW1iZWRkaW5nLiBMYXJnZXIgdmFsdWVzIHJlc3VsdCBpbiBtb3JlIGFjY3VyYXRlXG4gICAqIGVtYmVkZGluZ3MuIElmIE5vbmUgaXMgc3BlY2lmaWVkIGEgdmFsdWUgd2lsbCBiZSBzZWxlY3RlZCBiYXNlZCBvblxuICAgKiB0aGUgc2l6ZSBvZiB0aGUgaW5wdXQgZGF0YXNldCAoMjAwIGZvciBsYXJnZSBkYXRhc2V0cywgNTAwIGZvciBzbWFsbCkuXG4gICAqL1xuICBuRXBvY2hzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIHNpemUgb2YgbG9jYWwgbmVpZ2hib3Job29kIChpbiB0ZXJtcyBvZiBudW1iZXIgb2YgbmVpZ2hib3JpbmdcbiAgICogc2FtcGxlIHBvaW50cykgdXNlZCBmb3IgbWFuaWZvbGQgYXBwcm94aW1hdGlvbi4gTGFyZ2VyIHZhbHVlc1xuICAgKiByZXN1bHQgaW4gbW9yZSBnbG9iYWwgdmlld3Mgb2YgdGhlIG1hbmlmb2xkLCB3aGlsZSBzbWFsbGVyXG4gICAqIHZhbHVlcyByZXN1bHQgaW4gbW9yZSBsb2NhbCBkYXRhIGJlaW5nIHByZXNlcnZlZC4gSW4gZ2VuZXJhbFxuICAgKiB2YWx1ZXMgc2hvdWxkIGJlIGluIHRoZSByYW5nZSAyIHRvIDEwMC5cbiAgICovXG4gIG5OZWlnaGJvcnM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIG5lZ2F0aXZlIHNhbXBsZXMgdG8gc2VsZWN0IHBlciBwb3NpdGl2ZSBzYW1wbGVcbiAgICogaW4gdGhlIG9wdGltaXphdGlvbiBwcm9jZXNzLiBJbmNyZWFzaW5nIHRoaXMgdmFsdWUgd2lsbCByZXN1bHRcbiAgICogaW4gZ3JlYXRlciByZXB1bHNpdmUgZm9yY2UgYmVpbmcgYXBwbGllZCwgZ3JlYXRlciBvcHRpbWl6YXRpb25cbiAgICogY29zdCwgYnV0IHNsaWdodGx5IG1vcmUgYWNjdXJhY3kuXG4gICAqL1xuICBuZWdhdGl2ZVNhbXBsZVJhdGU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBXZWlnaHRpbmcgYXBwbGllZCB0byBuZWdhdGl2ZSBzYW1wbGVzIGluIGxvdyBkaW1lbnNpb25hbCBlbWJlZGRpbmdcbiAgICogb3B0aW1pemF0aW9uLiBWYWx1ZXMgaGlnaGVyIHRoYW4gb25lIHdpbGwgcmVzdWx0IGluIGdyZWF0ZXIgd2VpZ2h0XG4gICAqIGJlaW5nIGdpdmVuIHRvIG5lZ2F0aXZlIHNhbXBsZXMuXG4gICAqL1xuICByZXB1bHNpb25TdHJlbmd0aD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdXNlZCBieSB0aGUgc3RvY2hhc3RpYyBwYXJ0cyBvZiB0aGVcbiAgICogYWxnb3JpdGhtLlxuICAgKi9cbiAgcmFuZG9tPzogUmFuZG9tRm47XG4gIC8qKlxuICAgKiBJbnRlcnBvbGF0ZSBiZXR3ZWVuIChmdXp6eSkgdW5pb24gYW5kIGludGVyc2VjdGlvbiBhcyB0aGUgc2V0IG9wZXJhdGlvblxuICAgKiB1c2VkIHRvIGNvbWJpbmUgbG9jYWwgZnV6enkgc2ltcGxpY2lhbCBzZXRzIHRvIG9idGFpbiBhIGdsb2JhbCBmdXp6eVxuICAgKiBzaW1wbGljaWFsIHNldHMuIEJvdGggZnV6enkgc2V0IG9wZXJhdGlvbnMgdXNlIHRoZSBwcm9kdWN0IHQtbm9ybS5cbiAgICogVGhlIHZhbHVlIG9mIHRoaXMgcGFyYW1ldGVyIHNob3VsZCBiZSBiZXR3ZWVuIDAuMCBhbmQgMS4wOyBhIHZhbHVlIG9mXG4gICAqIDEuMCB3aWxsIHVzZSBhIHB1cmUgZnV6enkgdW5pb24sIHdoaWxlIDAuMCB3aWxsIHVzZSBhIHB1cmUgZnV6enlcbiAgICogaW50ZXJzZWN0aW9uLlxuICAgKi9cbiAgc2V0T3BNaXhSYXRpbz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBlZmZlY3RpdmUgc2NhbGUgb2YgZW1iZWRkZWQgcG9pbnRzLiBJbiBjb21iaW5hdGlvbiB3aXRoIGBgbWluX2Rpc3RgYFxuICAgKiB0aGlzIGRldGVybWluZXMgaG93IGNsdXN0ZXJlZC9jbHVtcGVkIHRoZSBlbWJlZGRlZCBwb2ludHMgYXJlLlxuICAgKi9cbiAgc3ByZWFkPzogbnVtYmVyO1xuICAvKipcbiAgICogRm9yIHRyYW5zZm9ybSBvcGVyYXRpb25zIChlbWJlZGRpbmcgbmV3IHBvaW50cyB1c2luZyBhIHRyYWluZWQgbW9kZWwpXG4gICAqIHRoaXMgd2lsbCBjb250cm9sIGhvdyBhZ2dyZXNzaXZlbHkgdG8gc2VhcmNoIGZvciBuZWFyZXN0IG5laWdoYm9ycy5cbiAgICogTGFyZ2VyIHZhbHVlcyB3aWxsIHJlc3VsdCBpbiBzbG93ZXIgcGVyZm9ybWFuY2UgYnV0IG1vcmUgYWNjdXJhdGVcbiAgICogbmVhcmVzdCBuZWlnaGJvciBldmFsdWF0aW9uLlxuICAgKi9cbiAgdHJhbnNmb3JtUXVldWVTaXplPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVNQVBTdXBlcnZpc2VkUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBtZXRyaWMgdXNlZCB0byBtZWFzdXJlIGRpc3RhbmNlIGZvciBhIHRhcmdldCBhcnJheSBpcyB1c2luZyBzdXBlcnZpc2VkXG4gICAqIGRpbWVuc2lvbiByZWR1Y3Rpb24uIEJ5IGRlZmF1bHQgdGhpcyBpcyAnY2F0ZWdvcmljYWwnIHdoaWNoIHdpbGwgbWVhc3VyZVxuICAgKiBkaXN0YW5jZSBpbiB0ZXJtcyBvZiB3aGV0aGVyIGNhdGVnb3JpZXMgbWF0Y2ggb3IgYXJlIGRpZmZlcmVudC4gRnVydGhlcm1vcmUsXG4gICAqIGlmIHNlbWktc3VwZXJ2aXNlZCBpcyByZXF1aXJlZCB0YXJnZXQgdmFsdWVzIG9mIC0xIHdpbGwgYmUgdHJlYXRlZCBhc1xuICAgKiB1bmxhYmVsbGVkIHVuZGVyIHRoZSAnY2F0ZWdvcmljYWwnIG1ldHJpYy4gSWYgdGhlIHRhcmdldCBhcnJheSB0YWtlc1xuICAgKiBjb250aW51b3VzIHZhbHVlcyAoZS5nLiBmb3IgYSByZWdyZXNzaW9uIHByb2JsZW0pIHRoZW4gbWV0cmljIG9mICdsMSdcbiAgICogb3IgJ2wyJyBpcyBwcm9iYWJseSBtb3JlIGFwcHJvcHJpYXRlLlxuICAgKi9cbiAgdGFyZ2V0TWV0cmljPzogVGFyZ2V0TWV0cmljO1xuICAvKipcbiAgICogV2VpZ2h0aW5nIGZhY3RvciBiZXR3ZWVuIGRhdGEgdG9wb2xvZ3kgYW5kIHRhcmdldCB0b3BvbG9neS4gQSB2YWx1ZSBvZlxuICAgKiAwLjAgd2VpZ2h0cyBlbnRpcmVseSBvbiBkYXRhLCBhIHZhbHVlIG9mIDEuMCB3ZWlnaHRzIGVudGlyZWx5IG9uIHRhcmdldC5cbiAgICogVGhlIGRlZmF1bHQgb2YgMC41IGJhbGFuY2VzIHRoZSB3ZWlnaHRpbmcgZXF1YWxseSBiZXR3ZWVuIGRhdGEgYW5kIHRhcmdldC5cbiAgICovXG4gIHRhcmdldFdlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgbmVhcmVzdCBuZWlnaGJvcnMgdG8gdXNlIHRvIGNvbnN0cnVjdCB0aGUgdGFyZ2V0IHNpbXBsY2lhbFxuICAgKiBzZXQuIERlZmF1bHRzIHRvIHRoZSBgbmVhcmVzdE5laWdoYm9yc2AgcGFyYW1ldGVyLlxuICAgKi9cbiAgdGFyZ2V0Tk5laWdoYm9ycz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBVTUFQIHByb2plY3Rpb24gc3lzdGVtLCBiYXNlZCBvbiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZyb20gTWNJbm5lcywgTCxcbiAqIEhlYWx5LCBKLCBVTUFQOiBVbmlmb3JtIE1hbmlmb2xkIEFwcHJveGltYXRpb24gYW5kIFByb2plY3Rpb24gZm9yIERpbWVuc2lvblxuICogUmVkdWN0aW9uIChodHRwczovL2dpdGh1Yi5jb20vbG1jaW5uZXMvdW1hcCkuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBkaWZmZXJzIGluIGEgZmV3IHJlZ2FyZHM6XG4gKiBhKSBUaGUgaW5pdGlhbGl6YXRpb24gb2YgdGhlIGVtYmVkZGluZyBmb3Igb3B0aW1pemF0aW9uIGlzIG5vdCBjb21wdXRlZCB1c2luZ1xuICogICAgYSBzcGVjdHJhbCBtZXRob2QsIHJhdGhlciBpdCBpcyBpbml0aWFsaXplZCByYW5kb21seS4gVGhpcyBhdm9pZHMgc29tZVxuICogICAgY29tcHV0YXRpb25hbGx5IGludGVuc2l2ZSBtYXRyaXggZWlnZW4gY29tcHV0YXRpb25zIHRoYXQgYXJlbid0IGVhc2lseVxuICogICAgcG9ydGVkIHRvIEphdmFTY3JpcHQuXG4gKiBiKSBBIGxvdCBvZiBcImV4dHJhXCIgZnVuY3Rpb25hbGl0eSBoYXMgYmVlbiBvbWl0dGVkIGZyb20gdGhpcyBpbXBsZW1lbnRhdGlvbixcbiAqICAgIG1vc3Qgbm90YWJseSBhIGdyZWF0IGRlYWwgb2YgYWx0ZXJuYXRlIGRpc3RhbmNlIGZ1bmN0aW9ucy5cbiAqXG4gKiBUaGlzIGltcGxlbWVudGF0aW9uIHByb3ZpZGVzIHRocmVlIG1ldGhvZHMgb2YgcmVkdWNpbmcgZGltZW5zaW9uYWxpdHk6XG4gKiAxKSBmaXQ6IGZpdCB0aGUgZGF0YSBzeW5jaHJvbm91c2x5XG4gKiAyKSBmaXRBc3luYzogZml0IHRoZSBkYXRhIGFzeW5jaHJvbm91c2x5LCB3aXRoIGEgY2FsbGJhY2sgZnVuY3Rpb24gcHJvdmlkZWRcbiAqICAgICAgdGhhdCBpcyBpbnZva2VkIG9uIGVhY2ggb3B0aW1pemF0aW9uIHN0ZXAuXG4gKiAzKSBpbml0aWFsaXplRml0IC8gc3RlcDogbWFudWFsbHkgaW5pdGlhbGl6ZSB0aGUgYWxnb3JpdGhtIHRoZW4gZXhwbGljdGx5XG4gKiAgICAgIHN0ZXAgdGhyb3VnaCBlYWNoIGVwb2NoIG9mIHRoZSBTR0Qgb3B0aW1pemF0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBVTUFQIHtcbiAgcHVibGljIGxlYXJuaW5nUmF0ZSA9IDEuMDtcbiAgcHVibGljIGxvY2FsQ29ubmVjdGl2aXR5ID0gMS4wO1xuICBwdWJsaWMgbWluRGlzdCA9IDAuMTtcbiAgcHVibGljIG5Db21wb25lbnRzID0gMjtcbiAgcHJpdmF0ZSBuRXBvY2hzID0gMDtcbiAgcHJpdmF0ZSBuTmVpZ2hib3JzID0gMTU7XG4gIHB1YmxpYyBuZWdhdGl2ZVNhbXBsZVJhdGUgPSA1O1xuICBwdWJsaWMgcmFuZG9tID0gTWF0aC5yYW5kb207XG4gIHB1YmxpYyByZXB1bHNpb25TdHJlbmd0aCA9IDEuMDtcbiAgcHVibGljIHNldE9wTWl4UmF0aW8gPSAxLjA7XG4gIHB1YmxpYyBzcHJlYWQgPSAxLjA7XG4gIHByaXZhdGUgdHJhbnNmb3JtUXVldWVTaXplID0gNC4wO1xuXG4gIC8vIFN1cGVydmlzZWQgcHJvamVjdGlvbiBwYXJhbXNcbiAgcHJpdmF0ZSB0YXJnZXRNZXRyaWMgPSBUYXJnZXRNZXRyaWMuY2F0ZWdvcmljYWw7XG4gIHByaXZhdGUgdGFyZ2V0V2VpZ2h0ID0gMC41O1xuICBwcml2YXRlIHRhcmdldE5OZWlnaGJvcnMgPSAxNTtcblxuICBwcml2YXRlIGRpc3RhbmNlRm46IERpc3RhbmNlRm4gPSBudW1lcmljO1xuXG4gIC8vIEtOTiBzdGF0ZSAoY2FuIGJlIHByZWNvbXB1dGVkIGFuZCBzdXBwbGllZCB2aWEgaW5pdGlhbGl6ZUZpdClcbiAgcHJpdmF0ZSBrbm5JbmRpY2VzPzogbnVtYmVyW11bXTtcbiAgcHJpdmF0ZSBrbm5EaXN0YW5jZXM/OiBudW1iZXJbXVtdO1xuXG4gIC8vIEludGVybmFsIGdyYXBoIGNvbm5lY3Rpdml0eSByZXByZXNlbnRhdGlvblxuICBwcml2YXRlIGdyYXBoITogbWF0cml4LlNwYXJzZU1hdHJpeDtcbiAgcHJpdmF0ZSBYITogVmVjdG9yO1xuICBwcml2YXRlIGlzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBycEZvcmVzdDogdHJlZS5GbGF0VHJlZVtdID0gW107XG4gIHByaXZhdGUgaW5pdEZyb21SYW5kb20hOiBubkRlc2NlbnQuSW5pdEZyb21SYW5kb21GbjtcbiAgcHJpdmF0ZSBpbml0RnJvbVRyZWUhOiBubkRlc2NlbnQuSW5pdEZyb21UcmVlRm47XG4gIHByaXZhdGUgc2VhcmNoITogbm5EZXNjZW50LlNlYXJjaEZuO1xuICBwcml2YXRlIHNlYXJjaEdyYXBoITogbWF0cml4LlNwYXJzZU1hdHJpeDtcblxuICAvLyBTdXBlcnZpc2VkIHByb2plY3Rpb24gbGFiZWxzIC8gdGFyZ2V0c1xuICBwcml2YXRlIFk/OiBudW1iZXJbXTtcblxuICAvLyBQcm9qZWN0ZWQgZW1iZWRkaW5nXG4gIHByaXZhdGUgZW1iZWRkaW5nOiBudW1iZXJbXVtdID0gW107XG4gIHByaXZhdGUgb3B0aW1pemF0aW9uU3RhdGUgPSBuZXcgT3B0aW1pemF0aW9uU3RhdGUoKTtcblxuXG4gIGdldCBuZWlnaGJvcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMubk5laWdoYm9ycztcbiAgfVxuICBjb25zdHJ1Y3RvcihwYXJhbXM6IFVNQVBQYXJhbWV0ZXJzID0ge30pIHtcbiAgICBjb25zdCBzZXRQYXJhbSA9IChrZXk6IGtleW9mIFVNQVBQYXJhbWV0ZXJzKSA9PiB7XG4gICAgICAvL0B0cy1pZ25vcmVcbiAgICAgIGlmIChwYXJhbXNba2V5XSAhPT0gdW5kZWZpbmVkKSB0aGlzW2tleV0gPSBwYXJhbXNba2V5XTtcbiAgICB9O1xuXG4gICAgc2V0UGFyYW0oJ2Rpc3RhbmNlRm4nKTtcbiAgICBzZXRQYXJhbSgnbGVhcm5pbmdSYXRlJyk7XG4gICAgc2V0UGFyYW0oJ2xvY2FsQ29ubmVjdGl2aXR5Jyk7XG4gICAgc2V0UGFyYW0oJ21pbkRpc3QnKTtcbiAgICBzZXRQYXJhbSgnbkNvbXBvbmVudHMnKTtcbiAgICBzZXRQYXJhbSgnbkVwb2NocycpO1xuICAgIHNldFBhcmFtKCduTmVpZ2hib3JzJyk7XG4gICAgc2V0UGFyYW0oJ25lZ2F0aXZlU2FtcGxlUmF0ZScpO1xuICAgIHNldFBhcmFtKCdyYW5kb20nKTtcbiAgICBzZXRQYXJhbSgncmVwdWxzaW9uU3RyZW5ndGgnKTtcbiAgICBzZXRQYXJhbSgnc2V0T3BNaXhSYXRpbycpO1xuICAgIHNldFBhcmFtKCdzcHJlYWQnKTtcbiAgICBzZXRQYXJhbSgndHJhbnNmb3JtUXVldWVTaXplJyk7XG4gICAgdGhpcy50YXJnZXROTmVpZ2hib3JzID0gcGFyYW1zLm5OZWlnaGJvcnMgfHwgdGhpcy5uTmVpZ2hib3JzIHx8IHRoaXMudGFyZ2V0Tk5laWdoYm9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIHN5bmNocm9ub3VzbHkuXG4gICAqL1xuICBmaXQoWDogVmVjdG9yKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuICAgIHRoaXMub3B0aW1pemVMYXlvdXQoKTtcblxuICAgIHJldHVybiB0aGlzLmVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIGFzeW5jaHJvbm91c2x5LCB3aXRoIGEgY2FsbGJhY2tcbiAgICogZnVuY3Rpb24gaW52b2tlZCBvbiBldmVyeSBlcG9jaCBvZiBvcHRpbWl6YXRpb24uXG4gICAqL1xuICBhc3luYyBmaXRBc3luYyhcbiAgICBYOiBWZWN0b3IsXG4gICAgY2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuXG4gICAgYXdhaXQgdGhpcy5vcHRpbWl6ZUxheW91dEFzeW5jKGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy5lbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgcGFyYW1ldGVycyBuZWVkZWQgZm9yIHN1cGVydmlzZWQgcHJvamVjdGlvbi5cbiAgICovXG4gIHNldFN1cGVydmlzZWRQcm9qZWN0aW9uKFk6IG51bWJlcltdLCBwYXJhbXM6IFVNQVBTdXBlcnZpc2VkUGFyYW1zID0ge30pIHtcbiAgICB0aGlzLlkgPSBZO1xuICAgIHRoaXMudGFyZ2V0TWV0cmljID0gcGFyYW1zLnRhcmdldE1ldHJpYyB8fCB0aGlzLnRhcmdldE1ldHJpYztcbiAgICB0aGlzLnRhcmdldFdlaWdodCA9IHBhcmFtcy50YXJnZXRXZWlnaHQgfHwgdGhpcy50YXJnZXRXZWlnaHQ7XG4gICAgdGhpcy50YXJnZXROTmVpZ2hib3JzID0gcGFyYW1zLnRhcmdldE5OZWlnaGJvcnMgfHwgdGhpcy50YXJnZXROTmVpZ2hib3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHVtYXAgd2l0aCBwcmVjb21wdXRlZCBLTk4gaW5kaWNlcyBhbmQgZGlzdGFuY2VzLlxuICAgKi9cbiAgc2V0UHJlY29tcHV0ZWRLTk4oa25uSW5kaWNlczogbnVtYmVyW11bXSwga25uRGlzdGFuY2VzOiBudW1iZXJbXVtdKSB7XG4gICAgdGhpcy5rbm5JbmRpY2VzID0ga25uSW5kaWNlcztcbiAgICB0aGlzLmtubkRpc3RhbmNlcyA9IGtubkRpc3RhbmNlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBmaXQgYnkgY29tcHV0aW5nIEtOTiBhbmQgYSBmdXp6eSBzaW1wbGljaWFsIHNldCwgYXMgd2VsbCBhc1xuICAgKiBpbml0aWFsaXppbmcgdGhlIHByb2plY3RlZCBlbWJlZGRpbmdzLiBTZXRzIHRoZSBvcHRpbWl6YXRpb24gc3RhdGUgYWhlYWRcbiAgICogb2Ygb3B0aW1pemF0aW9uIHN0ZXBzLiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZXBvY2hzIHRvIGJlIHVzZWQgZm9yIHRoZVxuICAgKiBTR0Qgb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgaW5pdGlhbGl6ZUZpdChYOiBWZWN0b3IpOiBudW1iZXIge1xuICAgIGlmIChYLmxlbmd0aCA8PSB0aGlzLm5OZWlnaGJvcnMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBlbm91Z2ggZGF0YSBwb2ludHMgKCR7WC5sZW5ndGh9KSB0byBjcmVhdGUgbk5laWdoYm9yczogJHt0aGlzLm5OZWlnaGJvcnN9LiAgQWRkIG1vcmUgZGF0YSBwb2ludHMgb3IgYWRqdXN0IHRoZSBjb25maWd1cmF0aW9uLmApO1xuXG5cbiAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJlaW5pdGlhbGl6ZSBpZiB3ZSd2ZSBhbHJlYWR5IGluaXRpYWxpemVkIGZvciB0aGlzIGRhdGEuXG4gICAgaWYgKHRoaXMuWCA9PT0gWCAmJiB0aGlzLmlzSW5pdGlhbGl6ZWQpXG4gICAgICByZXR1cm4gdGhpcy5nZXRORXBvY2hzKCk7XG5cblxuICAgIHRoaXMuWCA9IFg7XG5cbiAgICBpZiAoIXRoaXMua25uSW5kaWNlcyAmJiAhdGhpcy5rbm5EaXN0YW5jZXMpIHtcbiAgICAgIGNvbnN0IGtublJlc3VsdHMgPSB0aGlzLm5lYXJlc3ROZWlnaGJvcnMoWCk7XG4gICAgICB0aGlzLmtubkluZGljZXMgPSBrbm5SZXN1bHRzLmtubkluZGljZXM7XG4gICAgICB0aGlzLmtubkRpc3RhbmNlcyA9IGtublJlc3VsdHMua25uRGlzdGFuY2VzO1xuICAgIH1cblxuICAgIHRoaXMuZ3JhcGggPSB0aGlzLmZ1enp5U2ltcGxpY2lhbFNldChcbiAgICAgIFgsXG4gICAgICB0aGlzLm5OZWlnaGJvcnMsXG4gICAgICB0aGlzLnNldE9wTWl4UmF0aW9cbiAgICApO1xuXG4gICAgLy8gU2V0IHVwIHRoZSBzZWFyY2ggZ3JhcGggZm9yIHN1YnNlcXVlbnQgdHJhbnNmb3JtYXRpb24uXG4gICAgdGhpcy5tYWtlU2VhcmNoRm5zKCk7XG4gICAgdGhpcy5zZWFyY2hHcmFwaCA9IHRoaXMubWFrZVNlYXJjaEdyYXBoKFgpO1xuXG4gICAgLy8gQ2hlY2sgaWYgc3VwZXJ2aXNlZCBwcm9qZWN0aW9uLCB0aGVuIGFkanVzdCB0aGUgZ3JhcGguXG4gICAgdGhpcy5wcm9jZXNzR3JhcGhGb3JTdXBlcnZpc2VkUHJvamVjdGlvbigpO1xuXG4gICAgY29uc3Qge1xuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgfSA9IHRoaXMuaW5pdGlhbGl6ZVNpbXBsaWNpYWxTZXRFbWJlZGRpbmcoKTtcblxuICAgIC8vIFNldCB0aGUgb3B0aW1pemF0aW9uIHJvdXRpbmUgc3RhdGVcbiAgICB0aGlzLm9wdGltaXphdGlvblN0YXRlLmhlYWQgPSBoZWFkO1xuICAgIHRoaXMub3B0aW1pemF0aW9uU3RhdGUudGFpbCA9IHRhaWw7XG4gICAgdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5lcG9jaHNQZXJTYW1wbGUgPSBlcG9jaHNQZXJTYW1wbGU7XG5cbiAgICAvLyBOb3csIGluaXRpYWxpemUgdGhlIG9wdGltaXphdGlvbiBzdGVwc1xuICAgIHRoaXMuaW5pdGlhbGl6ZU9wdGltaXphdGlvbigpO1xuICAgIHRoaXMucHJlcGFyZUZvck9wdGltaXphdGlvbkxvb3AoKTtcbiAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0TkVwb2NocygpO1xuICB9XG5cbiAgcHJpdmF0ZSBtYWtlU2VhcmNoRm5zKCkge1xuICAgIGNvbnN0IHtpbml0RnJvbVRyZWUsIGluaXRGcm9tUmFuZG9tfSA9IG5uRGVzY2VudC5tYWtlSW5pdGlhbGl6YXRpb25zKFxuICAgICAgdGhpcy5kaXN0YW5jZUZuXG4gICAgKTtcbiAgICB0aGlzLmluaXRGcm9tVHJlZSA9IGluaXRGcm9tVHJlZTtcbiAgICB0aGlzLmluaXRGcm9tUmFuZG9tID0gaW5pdEZyb21SYW5kb207XG4gICAgdGhpcy5zZWFyY2ggPSBubkRlc2NlbnQubWFrZUluaXRpYWxpemVkTk5TZWFyY2godGhpcy5kaXN0YW5jZUZuKTtcbiAgfVxuXG4gIHByaXZhdGUgbWFrZVNlYXJjaEdyYXBoKFg6IFZlY3Rvcikge1xuICAgIGNvbnN0IGtubkluZGljZXMgPSB0aGlzLmtubkluZGljZXMhO1xuICAgIGNvbnN0IGtubkRpc3RhbmNlcyA9IHRoaXMua25uRGlzdGFuY2VzITtcbiAgICBjb25zdCBkaW1zID0gW1gubGVuZ3RoLCBYLmxlbmd0aF07XG4gICAgY29uc3Qgc2VhcmNoR3JhcGggPSBuZXcgbWF0cml4LlNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBkaW1zKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtubkluZGljZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGtubiA9IGtubkluZGljZXNbaV07XG4gICAgICBjb25zdCBkaXN0YW5jZXMgPSBrbm5EaXN0YW5jZXNbaV07XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGtubi5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBuZWlnaGJvciA9IGtubltqXTtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBkaXN0YW5jZXNbal07XG4gICAgICAgIGlmIChkaXN0YW5jZSA+IDApXG4gICAgICAgICAgc2VhcmNoR3JhcGguc2V0KGksIG5laWdoYm9yLCBkaXN0YW5jZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdHJhbnNwb3NlID0gbWF0cml4LnRyYW5zcG9zZShzZWFyY2hHcmFwaCk7XG4gICAgcmV0dXJuIG1hdHJpeC5tYXhpbXVtKHNlYXJjaEdyYXBoLCB0cmFuc3Bvc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zZm9ybXMgZGF0YSB0byB0aGUgZXhpc3RpbmcgZW1iZWRkaW5nIHNwYWNlLlxuICAgKi9cbiAgdHJhbnNmb3JtKHRvVHJhbnNmb3JtOiBWZWN0b3IpIHtcbiAgICAvLyBVc2UgdGhlIHByZXZpb3VzIHJhd0RhdGFcbiAgICBjb25zdCByYXdEYXRhID0gdGhpcy5YO1xuICAgIGlmIChyYXdEYXRhID09PSB1bmRlZmluZWQgfHwgcmF3RGF0YS5sZW5ndGggPT09IDApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGRhdGEgaGFzIGJlZW4gZml0LicpO1xuXG5cbiAgICBsZXQgbk5laWdoYm9ycyA9IE1hdGguZmxvb3IodGhpcy5uTmVpZ2hib3JzICogdGhpcy50cmFuc2Zvcm1RdWV1ZVNpemUpO1xuICAgIG5OZWlnaGJvcnMgPSBNYXRoLm1pbihyYXdEYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG4gICAgY29uc3QgaW5pdCA9IG5uRGVzY2VudC5pbml0aWFsaXplU2VhcmNoKFxuICAgICAgdGhpcy5ycEZvcmVzdCxcbiAgICAgIHJhd0RhdGEsXG4gICAgICB0b1RyYW5zZm9ybSxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICB0aGlzLmluaXRGcm9tUmFuZG9tLFxuICAgICAgdGhpcy5pbml0RnJvbVRyZWUsXG4gICAgICB0aGlzLnJhbmRvbVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnNlYXJjaChyYXdEYXRhLCB0aGlzLnNlYXJjaEdyYXBoLCBpbml0LCB0b1RyYW5zZm9ybSk7XG5cbiAgICBsZXQge2luZGljZXMsIHdlaWdodHM6IGRpc3RhbmNlc30gPSBoZWFwLmRlaGVhcFNvcnQocmVzdWx0KTtcblxuICAgIGluZGljZXMgPSBpbmRpY2VzLm1hcCgoeCkgPT4geC5zbGljZSgwLCB0aGlzLm5OZWlnaGJvcnMpKTtcbiAgICBkaXN0YW5jZXMgPSBkaXN0YW5jZXMubWFwKCh4KSA9PiB4LnNsaWNlKDAsIHRoaXMubk5laWdoYm9ycykpO1xuXG4gICAgY29uc3QgYWRqdXN0ZWRMb2NhbENvbm5lY3Rpdml0eSA9IE1hdGgubWF4KDAsIHRoaXMubG9jYWxDb25uZWN0aXZpdHkgLSAxKTtcbiAgICBjb25zdCB7c2lnbWFzLCByaG9zfSA9IHRoaXMuc21vb3RoS05ORGlzdGFuY2UoXG4gICAgICBkaXN0YW5jZXMsXG4gICAgICB0aGlzLm5OZWlnaGJvcnMsXG4gICAgICBhZGp1c3RlZExvY2FsQ29ubmVjdGl2aXR5XG4gICAgKTtcblxuICAgIGNvbnN0IHtyb3dzLCBjb2xzLCB2YWxzfSA9IHRoaXMuY29tcHV0ZU1lbWJlcnNoaXBTdHJlbmd0aHMoXG4gICAgICBpbmRpY2VzLFxuICAgICAgZGlzdGFuY2VzLFxuICAgICAgc2lnbWFzLFxuICAgICAgcmhvc1xuICAgICk7XG5cbiAgICBjb25zdCBzaXplID0gW3RvVHJhbnNmb3JtLmxlbmd0aCwgcmF3RGF0YS5sZW5ndGhdO1xuICAgIGxldCBncmFwaCA9IG5ldyBtYXRyaXguU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIHNpemUpO1xuXG4gICAgLy8gVGhpcyB3YXMgYSB2ZXJ5IHNwZWNpYWxseSBjb25zdHJ1Y3RlZCBncmFwaCB3aXRoIGNvbnN0YW50IGRlZ3JlZS5cbiAgICAvLyBUaGF0IGxldHMgdXMgZG8gZmFuY3kgdW5wYWNraW5nIGJ5IHJlc2hhcGluZyB0aGUgY3NyIG1hdHJpeCBpbmRpY2VzXG4gICAgLy8gYW5kIGRhdGEuIERvaW5nIHNvIHJlbGllcyBvbiB0aGUgY29uc3RhbnQgZGVncmVlIGFzc3VtcHRpb24hXG5cbiAgICBjb25zdCBub3JtZWQgPSBtYXRyaXgubm9ybWFsaXplKGdyYXBoLCBtYXRyaXguTm9ybVR5cGUubDEpO1xuXG4gICAgY29uc3QgY3NyTWF0cml4ID0gbWF0cml4LmdldENTUihub3JtZWQpO1xuICAgIGNvbnN0IG5Qb2ludHMgPSB0b1RyYW5zZm9ybS5sZW5ndGg7XG5cbiAgICBjb25zdCBlSW5kaWNlcyA9IHV0aWxzLnJlc2hhcGUyZChcbiAgICAgIGNzck1hdHJpeC5pbmRpY2VzLFxuICAgICAgblBvaW50cyxcbiAgICAgIHRoaXMubk5laWdoYm9yc1xuICAgICk7XG5cbiAgICBjb25zdCBlV2VpZ2h0cyA9IHV0aWxzLnJlc2hhcGUyZChcbiAgICAgIGNzck1hdHJpeC52YWx1ZXMsXG4gICAgICBuUG9pbnRzLFxuICAgICAgdGhpcy5uTmVpZ2hib3JzXG4gICAgKTtcblxuICAgIGNvbnN0IGVtYmVkZGluZyA9IGluaXRUcmFuc2Zvcm0oZUluZGljZXMsIGVXZWlnaHRzLCB0aGlzLmVtYmVkZGluZyk7XG5cbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5uRXBvY2hzID9cbiAgICAgIHRoaXMubkVwb2NocyAvIDMgOlxuICAgICAgZ3JhcGgublJvd3MgPD0gMTAwMDAgP1xuICAgICAgICAxMDAgOlxuICAgICAgICAzMDtcblxuICAgIGNvbnN0IGdyYXBoTWF4ID0gZ3JhcGhcbiAgICAgIC5nZXRWYWx1ZXMoKVxuICAgICAgLnJlZHVjZSgobWF4LCB2YWwpID0+ICh2YWwgPiBtYXggPyB2YWwgOiBtYXgpLCAwKTtcbiAgICBncmFwaCA9IGdyYXBoLm1hcCgodmFsdWUpID0+ICh2YWx1ZSA8IGdyYXBoTWF4IC8gbkVwb2NocyA/IDAgOiB2YWx1ZSkpO1xuICAgIGdyYXBoID0gbWF0cml4LmVsaW1pbmF0ZVplcm9zKGdyYXBoKTtcblxuICAgIGNvbnN0IGVwb2Noc1BlclNhbXBsZSA9IHRoaXMubWFrZUVwb2Noc1BlclNhbXBsZShcbiAgICAgIGdyYXBoLmdldFZhbHVlcygpLFxuICAgICAgbkVwb2Noc1xuICAgICk7XG4gICAgY29uc3QgaGVhZCA9IGdyYXBoLmdldFJvd3MoKTtcbiAgICBjb25zdCB0YWlsID0gZ3JhcGguZ2V0Q29scygpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBvcHRpbWl6YXRpb24gc2xpZ2h0bHkgZGlmZmVyZW50bHkgdGhhbiB0aGUgZml0IG1ldGhvZC5cbiAgICB0aGlzLmFzc2lnbk9wdGltaXphdGlvblN0YXRlUGFyYW1ldGVycyh7XG4gICAgICBoZWFkRW1iZWRkaW5nOiBlbWJlZGRpbmcsXG4gICAgICB0YWlsRW1iZWRkaW5nOiB0aGlzLmVtYmVkZGluZyxcbiAgICAgIGhlYWQsXG4gICAgICB0YWlsLFxuICAgICAgY3VycmVudEVwb2NoOiAwLFxuICAgICAgbkVwb2NocyxcbiAgICAgIG5WZXJ0aWNlczogZ3JhcGguZ2V0RGltcygpWzFdLFxuICAgICAgZXBvY2hzUGVyU2FtcGxlLFxuICAgIH0pO1xuICAgIHRoaXMucHJlcGFyZUZvck9wdGltaXphdGlvbkxvb3AoKTtcblxuICAgIHJldHVybiB0aGlzLm9wdGltaXplTGF5b3V0KCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHdlJ3JlIHVzaW5nIHN1cGVydmlzZWQgcHJvamVjdGlvbiwgdGhlbiBwcm9jZXNzIHRoZSBncmFwaFxuICAgKiBhY2NvcmRpbmdseS5cbiAgICovXG4gIHByaXZhdGUgcHJvY2Vzc0dyYXBoRm9yU3VwZXJ2aXNlZFByb2plY3Rpb24oKSB7XG4gICAgY29uc3Qge1ksIFh9ID0gdGhpcztcbiAgICBpZiAoWSkge1xuICAgICAgaWYgKFkubGVuZ3RoICE9PSBYLmxlbmd0aClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggb2YgWCBhbmQgeSBtdXN0IGJlIGVxdWFsJyk7XG5cblxuICAgICAgaWYgKHRoaXMudGFyZ2V0TWV0cmljID09PSBUYXJnZXRNZXRyaWMuY2F0ZWdvcmljYWwpIHtcbiAgICAgICAgY29uc3QgbHQgPSB0aGlzLnRhcmdldFdlaWdodCA8IDEuMDtcbiAgICAgICAgY29uc3QgZmFyRGlzdCA9IGx0ID8gMi41ICogKDEuMCAvICgxLjAgLSB0aGlzLnRhcmdldFdlaWdodCkpIDogMS4wZTEyO1xuICAgICAgICB0aGlzLmdyYXBoID0gdGhpcy5jYXRlZ29yaWNhbFNpbXBsaWNpYWxTZXRJbnRlcnNlY3Rpb24oXG4gICAgICAgICAgdGhpcy5ncmFwaCxcbiAgICAgICAgICBZLFxuICAgICAgICAgIGZhckRpc3RcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIFRPRE8gKGFuZHljb2VuZW5AKTogYWRkIG5vbi1jYXRlZ29yaWNhbCBzdXBlcnZpc2VkIGVtYmVkZGluZ3MuXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1hbnVhbGx5IHN0ZXAgdGhyb3VnaCB0aGUgb3B0aW1pemF0aW9uIHByb2Nlc3Mgb25lIGVwb2NoIGF0IGEgdGltZS5cbiAgICovXG4gIHN0ZXAoKSB7XG4gICAgY29uc3Qge2N1cnJlbnRFcG9jaH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuXG4gICAgaWYgKGN1cnJlbnRFcG9jaCA8IHRoaXMuZ2V0TkVwb2NocygpKVxuICAgICAgdGhpcy5vcHRpbWl6ZUxheW91dFN0ZXAoY3VycmVudEVwb2NoKTtcblxuICAgIHJldHVybiB0aGlzLm9wdGltaXphdGlvblN0YXRlLmN1cnJlbnRFcG9jaDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb21wdXRlZCBwcm9qZWN0ZWQgZW1iZWRkaW5nLlxuICAgKi9cbiAgZ2V0RW1iZWRkaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIHRoZSBgYG5OZWlnaGJvcnNgYCBuZWFyZXN0IHBvaW50cyBmb3IgZWFjaCBkYXRhIHBvaW50IGluIGBgWGBgXG4gICAqIFRoaXMgbWF5IGJlIGV4YWN0LCBidXQgbW9yZSBsaWtlbHkgaXMgYXBwcm94aW1hdGVkIHZpYSBuZWFyZXN0IG5laWdoYm9yXG4gICAqIGRlc2NlbnQuXG4gICAqL1xuICBwcml2YXRlIG5lYXJlc3ROZWlnaGJvcnMoWDogVmVjdG9yKSB7XG4gICAgY29uc3Qge2Rpc3RhbmNlRm4sIG5OZWlnaGJvcnN9ID0gdGhpcztcbiAgICBjb25zdCBsb2cyID0gKG46IG51bWJlcikgPT4gTWF0aC5sb2cobikgLyBNYXRoLmxvZygyKTtcbiAgICBjb25zdCBtZXRyaWNOTkRlc2NlbnQgPSBubkRlc2NlbnQubWFrZU5ORGVzY2VudChkaXN0YW5jZUZuLCB0aGlzLnJhbmRvbSk7XG5cbiAgICAvLyBIYW5kbGUgcHl0aG9uMyByb3VuZGluZyBkb3duIGZyb20gMC41IGRpc2NycGFuY3lcbiAgICBjb25zdCByb3VuZCA9IChuOiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBuID09PSAwLjUgPyAwIDogTWF0aC5yb3VuZChuKTtcbiAgICB9O1xuXG4gICAgY29uc3QgblRyZWVzID0gNSArIE1hdGguZmxvb3Iocm91bmQoWC5sZW5ndGggKiogMC41IC8gMjAuMCkpO1xuICAgIGNvbnN0IG5JdGVycyA9IE1hdGgubWF4KDUsIE1hdGguZmxvb3IoTWF0aC5yb3VuZChsb2cyKFgubGVuZ3RoKSkpKTtcblxuICAgIHRoaXMucnBGb3Jlc3QgPSB0cmVlLm1ha2VGb3Jlc3QoWCwgbk5laWdoYm9ycywgblRyZWVzLCB0aGlzLnJhbmRvbSk7XG5cbiAgICBjb25zdCBsZWFmQXJyYXkgPSB0cmVlLm1ha2VMZWFmQXJyYXkodGhpcy5ycEZvcmVzdCk7XG4gICAgY29uc3Qge2luZGljZXMsIHdlaWdodHN9ID0gbWV0cmljTk5EZXNjZW50KFxuICAgICAgWCxcbiAgICAgIGxlYWZBcnJheSxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICBuSXRlcnNcbiAgICApO1xuICAgIHJldHVybiB7a25uSW5kaWNlczogaW5kaWNlcywga25uRGlzdGFuY2VzOiB3ZWlnaHRzfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHNldCBvZiBkYXRhIFgsIGEgbmVpZ2hib3Job29kIHNpemUsIGFuZCBhIG1lYXN1cmUgb2YgZGlzdGFuY2VcbiAgICogY29tcHV0ZSB0aGUgZnV6enkgc2ltcGxpY2lhbCBzZXQgKGhlcmUgcmVwcmVzZW50ZWQgYXMgYSBmdXp6eSBncmFwaCBpblxuICAgKiB0aGUgZm9ybSBvZiBhIHNwYXJzZSBtYXRyaXgpIGFzc29jaWF0ZWQgdG8gdGhlIGRhdGEuIFRoaXMgaXMgZG9uZSBieVxuICAgKiBsb2NhbGx5IGFwcHJveGltYXRpbmcgZ2VvZGVzaWMgZGlzdGFuY2UgYXQgZWFjaCBwb2ludCwgY3JlYXRpbmcgYSBmdXp6eVxuICAgKiBzaW1wbGljaWFsIHNldCBmb3IgZWFjaCBzdWNoIHBvaW50LCBhbmQgdGhlbiBjb21iaW5pbmcgYWxsIHRoZSBsb2NhbFxuICAgKiBmdXp6eSBzaW1wbGljaWFsIHNldHMgaW50byBhIGdsb2JhbCBvbmUgdmlhIGEgZnV6enkgdW5pb24uXG4gICAqL1xuICBwcml2YXRlIGZ1enp5U2ltcGxpY2lhbFNldChcbiAgICBYOiBWZWN0b3IsXG4gICAgbk5laWdoYm9yczogbnVtYmVyLFxuICAgIHNldE9wTWl4UmF0aW8gPSAxLjBcbiAgKSB7XG4gICAgY29uc3Qge2tubkluZGljZXMgPSBbXSwga25uRGlzdGFuY2VzID0gW10sIGxvY2FsQ29ubmVjdGl2aXR5fSA9IHRoaXM7XG5cbiAgICBjb25zdCB7c2lnbWFzLCByaG9zfSA9IHRoaXMuc21vb3RoS05ORGlzdGFuY2UoXG4gICAgICBrbm5EaXN0YW5jZXMsXG4gICAgICBuTmVpZ2hib3JzLFxuICAgICAgbG9jYWxDb25uZWN0aXZpdHlcbiAgICApO1xuXG4gICAgY29uc3Qge3Jvd3MsIGNvbHMsIHZhbHN9ID0gdGhpcy5jb21wdXRlTWVtYmVyc2hpcFN0cmVuZ3RocyhcbiAgICAgIGtubkluZGljZXMsXG4gICAgICBrbm5EaXN0YW5jZXMsXG4gICAgICBzaWdtYXMsXG4gICAgICByaG9zXG4gICAgKTtcblxuICAgIGNvbnN0IHNpemUgPSBbWC5sZW5ndGgsIFgubGVuZ3RoXTtcbiAgICBjb25zdCBzcGFyc2VNYXRyaXggPSBuZXcgbWF0cml4LlNwYXJzZU1hdHJpeChyb3dzLCBjb2xzLCB2YWxzLCBzaXplKTtcblxuICAgIGNvbnN0IHRyYW5zcG9zZSA9IG1hdHJpeC50cmFuc3Bvc2Uoc3BhcnNlTWF0cml4KTtcbiAgICBjb25zdCBwcm9kTWF0cml4ID0gbWF0cml4LnBhaXJ3aXNlTXVsdGlwbHkoc3BhcnNlTWF0cml4LCB0cmFuc3Bvc2UpO1xuXG4gICAgY29uc3QgYSA9IG1hdHJpeC5zdWJ0cmFjdChtYXRyaXguYWRkKHNwYXJzZU1hdHJpeCwgdHJhbnNwb3NlKSwgcHJvZE1hdHJpeCk7XG4gICAgY29uc3QgYiA9IG1hdHJpeC5tdWx0aXBseVNjYWxhcihhLCBzZXRPcE1peFJhdGlvKTtcbiAgICBjb25zdCBjID0gbWF0cml4Lm11bHRpcGx5U2NhbGFyKHByb2RNYXRyaXgsIDEuMCAtIHNldE9wTWl4UmF0aW8pO1xuICAgIGNvbnN0IHJlc3VsdCA9IG1hdHJpeC5hZGQoYiwgYyk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbWJpbmUgYSBmdXp6eSBzaW1wbGljaWFsIHNldCB3aXRoIGFub3RoZXIgZnV6enkgc2ltcGxpY2lhbCBzZXRcbiAgICogZ2VuZXJhdGVkIGZyb20gY2F0ZWdvcmljYWwgZGF0YSB1c2luZyBjYXRlZ29yaWNhbCBkaXN0YW5jZXMuIFRoZSB0YXJnZXRcbiAgICogZGF0YSBpcyBhc3N1bWVkIHRvIGJlIGNhdGVnb3JpY2FsIGxhYmVsIGRhdGEgKGEgdmVjdG9yIG9mIGxhYmVscyksXG4gICAqIGFuZCB0aGlzIHdpbGwgdXBkYXRlIHRoZSBmdXp6eSBzaW1wbGljaWFsIHNldCB0byByZXNwZWN0IHRoYXQgbGFiZWwgZGF0YS5cbiAgICovXG4gIHByaXZhdGUgY2F0ZWdvcmljYWxTaW1wbGljaWFsU2V0SW50ZXJzZWN0aW9uKFxuICAgIHNpbXBsaWNpYWxTZXQ6IG1hdHJpeC5TcGFyc2VNYXRyaXgsXG4gICAgdGFyZ2V0OiBudW1iZXJbXSxcbiAgICBmYXJEaXN0OiBudW1iZXIsXG4gICAgdW5rbm93bkRpc3QgPSAxLjBcbiAgKSB7XG4gICAgbGV0IGludGVyc2VjdGlvbiA9IGZhc3RJbnRlcnNlY3Rpb24oXG4gICAgICBzaW1wbGljaWFsU2V0LFxuICAgICAgdGFyZ2V0LFxuICAgICAgdW5rbm93bkRpc3QsXG4gICAgICBmYXJEaXN0XG4gICAgKTtcbiAgICBpbnRlcnNlY3Rpb24gPSBtYXRyaXguZWxpbWluYXRlWmVyb3MoaW50ZXJzZWN0aW9uKTtcbiAgICByZXR1cm4gcmVzZXRMb2NhbENvbm5lY3Rpdml0eShpbnRlcnNlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgYSBjb250aW51b3VzIHZlcnNpb24gb2YgdGhlIGRpc3RhbmNlIHRvIHRoZSBrdGggbmVhcmVzdFxuICAgKiBuZWlnaGJvci4gVGhhdCBpcywgdGhpcyBpcyBzaW1pbGFyIHRvIGtubi1kaXN0YW5jZSBidXQgYWxsb3dzIGNvbnRpbnVvdXNcbiAgICogayB2YWx1ZXMgcmF0aGVyIHRoYW4gcmVxdWlyaW5nIGFuIGludGVncmFsIGsuIEluIGVzc2NlbmNlIHdlIGFyZSBzaW1wbHlcbiAgICogY29tcHV0aW5nIHRoZSBkaXN0YW5jZSBzdWNoIHRoYXQgdGhlIGNhcmRpbmFsaXR5IG9mIGZ1enp5IHNldCB3ZSBnZW5lcmF0ZVxuICAgKiBpcyBrLlxuICAgKi9cbiAgcHJpdmF0ZSBzbW9vdGhLTk5EaXN0YW5jZShcbiAgICBkaXN0YW5jZXM6IFZlY3RvcnMsXG4gICAgazogbnVtYmVyLFxuICAgIGxvY2FsQ29ubmVjdGl2aXR5ID0gMS4wLFxuICAgIG5JdGVyID0gNjQsXG4gICAgYmFuZHdpZHRoID0gMS4wXG4gICkge1xuICAgIGNvbnN0IHRhcmdldCA9IChNYXRoLmxvZyhrKSAvIE1hdGgubG9nKDIpKSAqIGJhbmR3aWR0aDtcbiAgICBjb25zdCByaG8gPSB1dGlscy56ZXJvcyhkaXN0YW5jZXMubGVuZ3RoKTtcbiAgICBjb25zdCByZXN1bHQgPSB1dGlscy56ZXJvcyhkaXN0YW5jZXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlzdGFuY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgbG8gPSAwLjA7XG4gICAgICBsZXQgaGkgPSBJbmZpbml0eTtcbiAgICAgIGxldCBtaWQgPSAxLjA7XG5cbiAgICAgIC8vIFRPRE86IFRoaXMgaXMgdmVyeSBpbmVmZmljaWVudCwgYnV0IHdpbGwgZG8gZm9yIG5vdy4gRklYTUVcbiAgICAgIGNvbnN0IGl0aERpc3RhbmNlcyA9IGRpc3RhbmNlc1tpXTtcbiAgICAgIGNvbnN0IG5vblplcm9EaXN0cyA9IGl0aERpc3RhbmNlcy5maWx0ZXIoKGQpID0+IGQgPiAwLjApO1xuXG4gICAgICBpZiAobm9uWmVyb0Rpc3RzLmxlbmd0aCA+PSBsb2NhbENvbm5lY3Rpdml0eSkge1xuICAgICAgICBjb25zdCBpbmRleCA9IE1hdGguZmxvb3IobG9jYWxDb25uZWN0aXZpdHkpO1xuICAgICAgICBjb25zdCBpbnRlcnBvbGF0aW9uID0gbG9jYWxDb25uZWN0aXZpdHkgLSBpbmRleDtcbiAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgIHJob1tpXSA9IG5vblplcm9EaXN0c1tpbmRleCAtIDFdO1xuICAgICAgICAgIGlmIChpbnRlcnBvbGF0aW9uID4gU01PT1RIX0tfVE9MRVJBTkNFKSB7XG4gICAgICAgICAgICByaG9baV0gKz1cbiAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvbiAqIChub25aZXJvRGlzdHNbaW5kZXhdIC0gbm9uWmVyb0Rpc3RzW2luZGV4IC0gMV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByaG9baV0gPSBpbnRlcnBvbGF0aW9uICogbm9uWmVyb0Rpc3RzWzBdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vblplcm9EaXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJob1tpXSA9IHV0aWxzLm1heChub25aZXJvRGlzdHMpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBuID0gMDsgbiA8IG5JdGVyOyBuKyspIHtcbiAgICAgICAgbGV0IHBzdW0gPSAwLjA7XG4gICAgICAgIGZvciAobGV0IGogPSAxOyBqIDwgZGlzdGFuY2VzW2ldLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlc1tpXVtqXSAtIHJob1tpXTtcbiAgICAgICAgICBpZiAoZCA+IDApXG4gICAgICAgICAgICBwc3VtICs9IE1hdGguZXhwKC0oZCAvIG1pZCkpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHBzdW0gKz0gMS4wO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKE1hdGguYWJzKHBzdW0gLSB0YXJnZXQpIDwgU01PT1RIX0tfVE9MRVJBTkNFKVxuICAgICAgICAgIGJyZWFrO1xuXG5cbiAgICAgICAgaWYgKHBzdW0gPiB0YXJnZXQpIHtcbiAgICAgICAgICBoaSA9IG1pZDtcbiAgICAgICAgICBtaWQgPSAobG8gKyBoaSkgLyAyLjA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG8gPSBtaWQ7XG4gICAgICAgICAgaWYgKGhpID09PSBJbmZpbml0eSlcbiAgICAgICAgICAgIG1pZCAqPSAyO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG1pZCA9IChsbyArIGhpKSAvIDIuMDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXN1bHRbaV0gPSBtaWQ7XG5cbiAgICAgIC8vIFRPRE86IFRoaXMgaXMgdmVyeSBpbmVmZmljaWVudCwgYnV0IHdpbGwgZG8gZm9yIG5vdy4gRklYTUVcbiAgICAgIGlmIChyaG9baV0gPiAwLjApIHtcbiAgICAgICAgY29uc3QgbWVhbkl0aERpc3RhbmNlcyA9IHV0aWxzLm1lYW4oaXRoRGlzdGFuY2VzKTtcbiAgICAgICAgaWYgKHJlc3VsdFtpXSA8IE1JTl9LX0RJU1RfU0NBTEUgKiBtZWFuSXRoRGlzdGFuY2VzKVxuICAgICAgICAgIHJlc3VsdFtpXSA9IE1JTl9LX0RJU1RfU0NBTEUgKiBtZWFuSXRoRGlzdGFuY2VzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWVhbkRpc3RhbmNlcyA9IHV0aWxzLm1lYW4oZGlzdGFuY2VzLm1hcCh1dGlscy5tZWFuKSk7XG4gICAgICAgIGlmIChyZXN1bHRbaV0gPCBNSU5fS19ESVNUX1NDQUxFICogbWVhbkRpc3RhbmNlcylcbiAgICAgICAgICByZXN1bHRbaV0gPSBNSU5fS19ESVNUX1NDQUxFICogbWVhbkRpc3RhbmNlcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge3NpZ21hczogcmVzdWx0LCByaG9zOiByaG99O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCB0aGUgbWVtYmVyc2hpcCBzdHJlbmd0aCBkYXRhIGZvciB0aGUgMS1za2VsZXRvbiBvZiBlYWNoIGxvY2FsXG4gICAqIGZ1enp5IHNpbXBsaWNpYWwgc2V0IC0tIHRoaXMgaXMgZm9ybWVkIGFzIGEgc3BhcnNlIG1hdHJpeCB3aGVyZSBlYWNoIHJvdyBpc1xuICAgKiBhIGxvY2FsIGZ1enp5IHNpbXBsaWNpYWwgc2V0LCB3aXRoIGEgbWVtYmVyc2hpcCBzdHJlbmd0aCBmb3IgdGhlXG4gICAqIDEtc2ltcGxleCB0byBlYWNoIG90aGVyIGRhdGEgcG9pbnQuXG4gICAqL1xuICBwcml2YXRlIGNvbXB1dGVNZW1iZXJzaGlwU3RyZW5ndGhzKFxuICAgIGtubkluZGljZXM6IFZlY3RvcnMsXG4gICAga25uRGlzdGFuY2VzOiBWZWN0b3JzLFxuICAgIHNpZ21hczogbnVtYmVyW10sXG4gICAgcmhvczogbnVtYmVyW11cbiAgKTogeyByb3dzOiBudW1iZXJbXTsgY29sczogbnVtYmVyW107IHZhbHM6IG51bWJlcltdIH0ge1xuICAgIGNvbnN0IG5TYW1wbGVzID0ga25uSW5kaWNlcy5sZW5ndGg7XG4gICAgY29uc3Qgbk5laWdoYm9ycyA9IGtubkluZGljZXNbMF0ubGVuZ3RoO1xuXG4gICAgY29uc3Qgcm93cyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgY29scyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgdmFscyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICAgIGxldCB2YWwgPSAwO1xuICAgICAgICBpZiAoa25uSW5kaWNlc1tpXVtqXSA9PT0gLTEpXG4gICAgICAgICAgY29udGludWU7IC8vIFdlIGRpZG4ndCBnZXQgdGhlIGZ1bGwga25uIGZvciBpXG5cbiAgICAgICAgaWYgKGtubkluZGljZXNbaV1bal0gPT09IGkpXG4gICAgICAgICAgdmFsID0gMC4wO1xuICAgICAgICBlbHNlIGlmIChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldIDw9IDAuMClcbiAgICAgICAgICB2YWwgPSAxLjA7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB2YWwgPSBNYXRoLmV4cCgtKChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldKSAvIHNpZ21hc1tpXSkpO1xuXG5cbiAgICAgICAgcm93c1tpICogbk5laWdoYm9ycyArIGpdID0gaTtcbiAgICAgICAgY29sc1tpICogbk5laWdoYm9ycyArIGpdID0ga25uSW5kaWNlc1tpXVtqXTtcbiAgICAgICAgdmFsc1tpICogbk5laWdoYm9ycyArIGpdID0gdmFsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7cm93cywgY29scywgdmFsc307XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhIGZ1enp5IHNpbXBsaWNpYWwgc2V0IGVtYmVkZGluZywgdXNpbmcgYSBzcGVjaWZpZWRcbiAgICogaW5pdGlhbGlzYXRpb24gbWV0aG9kIGFuZCB0aGVuIG1pbmltaXppbmcgdGhlIGZ1enp5IHNldCBjcm9zcyBlbnRyb3B5XG4gICAqIGJldHdlZW4gdGhlIDEtc2tlbGV0b25zIG9mIHRoZSBoaWdoIGFuZCBsb3cgZGltZW5zaW9uYWwgZnV6enkgc2ltcGxpY2lhbFxuICAgKiBzZXRzLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplU2ltcGxpY2lhbFNldEVtYmVkZGluZygpIHtcbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5nZXRORXBvY2hzKCk7XG5cbiAgICBjb25zdCB7bkNvbXBvbmVudHN9ID0gdGhpcztcbiAgICBjb25zdCBncmFwaFZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCk7XG4gICAgbGV0IGdyYXBoTWF4ID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGdyYXBoVmFsdWVzW2ldO1xuICAgICAgaWYgKGdyYXBoTWF4IDwgZ3JhcGhWYWx1ZXNbaV0pXG4gICAgICAgIGdyYXBoTWF4ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgZ3JhcGggPSB0aGlzLmdyYXBoLm1hcCgodmFsdWUpID0+IHtcbiAgICAgIGlmICh2YWx1ZSA8IGdyYXBoTWF4IC8gbkVwb2NocylcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9KTtcblxuICAgIC8vIFdlJ3JlIG5vdCBjb21wdXRpbmcgdGhlIHNwZWN0cmFsIGluaXRpYWxpemF0aW9uIGluIHRoaXMgaW1wbGVtZW50YXRpb25cbiAgICAvLyB1bnRpbCB3ZSBkZXRlcm1pbmUgYSBiZXR0ZXIgZWlnZW52YWx1ZS9laWdlbnZlY3RvciBjb21wdXRhdGlvblxuICAgIC8vIGFwcHJvYWNoXG4gICAgdGhpcy5lbWJlZGRpbmcgPSB1dGlscy56ZXJvcyhncmFwaC5uUm93cykubWFwKCgpID0+IHtcbiAgICAgIHJldHVybiB1dGlscy56ZXJvcyhuQ29tcG9uZW50cykubWFwKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHV0aWxzLnRhdVJhbmQodGhpcy5yYW5kb20pICogMjAgKyAtMTA7IC8vIFJhbmRvbSBmcm9tIC0xMCB0byAxMFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBHZXQgZ3JhcGggZGF0YSBpbiBvcmRlcmVkIHdheS4uLlxuICAgIGNvbnN0IHdlaWdodHM6IG51bWJlcltdID0gW107XG4gICAgY29uc3QgaGVhZDogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCB0YWlsOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IHJvd0NvbFZhbHVlcyA9IGdyYXBoLmdldEFsbCgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93Q29sVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IHJvd0NvbFZhbHVlc1tpXTtcbiAgICAgIGlmIChlbnRyeS52YWx1ZSkge1xuICAgICAgICB3ZWlnaHRzLnB1c2goZW50cnkudmFsdWUpO1xuICAgICAgICB0YWlsLnB1c2goZW50cnkucm93KTtcbiAgICAgICAgaGVhZC5wdXNoKGVudHJ5LmNvbCk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGVwb2Noc1BlclNhbXBsZSA9IHRoaXMubWFrZUVwb2Noc1BlclNhbXBsZSh3ZWlnaHRzLCBuRXBvY2hzKTtcblxuICAgIHJldHVybiB7aGVhZCwgdGFpbCwgZXBvY2hzUGVyU2FtcGxlfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHNldCBvZiB3ZWlnaHRzIGFuZCBudW1iZXIgb2YgZXBvY2hzIGdlbmVyYXRlIHRoZSBudW1iZXIgb2ZcbiAgICogZXBvY2hzIHBlciBzYW1wbGUgZm9yIGVhY2ggd2VpZ2h0LlxuICAgKi9cbiAgcHJpdmF0ZSBtYWtlRXBvY2hzUGVyU2FtcGxlKHdlaWdodHM6IG51bWJlcltdLCBuRXBvY2hzOiBudW1iZXIpIHtcbiAgICBjb25zdCByZXN1bHQgPSB1dGlscy5maWxsZWQod2VpZ2h0cy5sZW5ndGgsIC0xLjApO1xuICAgIGNvbnN0IG1heCA9IHV0aWxzLm1heCh3ZWlnaHRzKTtcbiAgICBjb25zdCBuU2FtcGxlcyA9IHdlaWdodHMubWFwKCh3KSA9PiAodyAvIG1heCkgKiBuRXBvY2hzKTtcbiAgICBuU2FtcGxlcy5mb3JFYWNoKChuLCBpKSA9PiB7XG4gICAgICBpZiAobiA+IDApIHJlc3VsdFtpXSA9IG5FcG9jaHMgLyBuU2FtcGxlc1tpXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2lnbnMgb3B0aW1pemF0aW9uIHN0YXRlIHBhcmFtZXRlcnMgZnJvbSBhIHBhcnRpYWwgb3B0aW1pemF0aW9uIHN0YXRlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3NpZ25PcHRpbWl6YXRpb25TdGF0ZVBhcmFtZXRlcnMoc3RhdGU6IFBhcnRpYWw8T3B0aW1pemF0aW9uU3RhdGU+KSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLm9wdGltaXphdGlvblN0YXRlLCBzdGF0ZSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIGZldyBvcHRpbWl6YXRpb24gc3RhdGUgcGFyYW1ldGVycyB0aGF0IGFyZSBuZWNlc3NhcnkgYmVmb3JlIGVudGVyaW5nXG4gICAqIHRoZSBvcHRpbWl6YXRpb24gc3RlcCBsb29wLlxuICAgKi9cbiAgcHJpdmF0ZSBwcmVwYXJlRm9yT3B0aW1pemF0aW9uTG9vcCgpIHtcbiAgICAvLyBIeXBlcnBhcmFtZXRlcnNcbiAgICBjb25zdCB7cmVwdWxzaW9uU3RyZW5ndGgsIGxlYXJuaW5nUmF0ZSwgbmVnYXRpdmVTYW1wbGVSYXRlfSA9IHRoaXM7XG5cbiAgICBjb25zdCB7XG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBoZWFkRW1iZWRkaW5nLFxuICAgICAgdGFpbEVtYmVkZGluZyxcbiAgICB9ID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZTtcblxuICAgIGNvbnN0IGRpbSA9IGhlYWRFbWJlZGRpbmdbMF0ubGVuZ3RoO1xuICAgIGNvbnN0IG1vdmVPdGhlciA9IGhlYWRFbWJlZGRpbmcubGVuZ3RoID09PSB0YWlsRW1iZWRkaW5nLmxlbmd0aDtcblxuICAgIGNvbnN0IGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlID0gZXBvY2hzUGVyU2FtcGxlLm1hcChcbiAgICAgIChlKSA9PiBlIC8gbmVnYXRpdmVTYW1wbGVSYXRlXG4gICAgKTtcbiAgICBjb25zdCBlcG9jaE9mTmV4dE5lZ2F0aXZlU2FtcGxlID0gWy4uLmVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlXTtcbiAgICBjb25zdCBlcG9jaE9mTmV4dFNhbXBsZSA9IFsuLi5lcG9jaHNQZXJTYW1wbGVdO1xuXG4gICAgdGhpcy5hc3NpZ25PcHRpbWl6YXRpb25TdGF0ZVBhcmFtZXRlcnMoe1xuICAgICAgZXBvY2hPZk5leHRTYW1wbGUsXG4gICAgICBlcG9jaE9mTmV4dE5lZ2F0aXZlU2FtcGxlLFxuICAgICAgZXBvY2hzUGVyTmVnYXRpdmVTYW1wbGUsXG4gICAgICBtb3ZlT3RoZXIsXG4gICAgICBpbml0aWFsQWxwaGE6IGxlYXJuaW5nUmF0ZSxcbiAgICAgIGFscGhhOiBsZWFybmluZ1JhdGUsXG4gICAgICBnYW1tYTogcmVwdWxzaW9uU3RyZW5ndGgsXG4gICAgICBkaW0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgb3B0aW1pemF0aW9uIHN0YXRlIGZvciBzdGVwd2lzZSBvcHRpbWl6YXRpb24uXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVPcHRpbWl6YXRpb24oKSB7XG4gICAgLy8gQWxnb3JpdGhtIHN0YXRlXG4gICAgY29uc3QgaGVhZEVtYmVkZGluZyA9IHRoaXMuZW1iZWRkaW5nO1xuICAgIGNvbnN0IHRhaWxFbWJlZGRpbmcgPSB0aGlzLmVtYmVkZGluZztcblxuICAgIC8vIEluaXRpYWxpemVkIGluIGluaXRpYWxpemVTaW1wbGljaWFsU2V0RW1iZWRkaW5nKClcbiAgICBjb25zdCB7aGVhZCwgdGFpbCwgZXBvY2hzUGVyU2FtcGxlfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG5cbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5nZXRORXBvY2hzKCk7XG4gICAgY29uc3QgblZlcnRpY2VzID0gdGhpcy5ncmFwaC5uQ29scztcblxuICAgIGNvbnN0IHthLCBifSA9IGZpbmRBQlBhcmFtcyh0aGlzLnNwcmVhZCwgdGhpcy5taW5EaXN0KTtcblxuICAgIHRoaXMuYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHtcbiAgICAgIGhlYWRFbWJlZGRpbmcsXG4gICAgICB0YWlsRW1iZWRkaW5nLFxuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBhLFxuICAgICAgYixcbiAgICAgIG5FcG9jaHMsXG4gICAgICBuVmVydGljZXMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dFN0ZXAobjogbnVtYmVyKSB7XG4gICAgY29uc3Qge29wdGltaXphdGlvblN0YXRlfSA9IHRoaXM7XG4gICAgY29uc3Qge1xuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBoZWFkRW1iZWRkaW5nLFxuICAgICAgdGFpbEVtYmVkZGluZyxcbiAgICAgIGVwb2Noc1BlclNhbXBsZSxcbiAgICAgIGVwb2NoT2ZOZXh0U2FtcGxlLFxuICAgICAgZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZSxcbiAgICAgIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlLFxuICAgICAgbW92ZU90aGVyLFxuICAgICAgaW5pdGlhbEFscGhhLFxuICAgICAgYWxwaGEsXG4gICAgICBnYW1tYSxcbiAgICAgIGEsXG4gICAgICBiLFxuICAgICAgZGltLFxuICAgICAgbkVwb2NocyxcbiAgICAgIG5WZXJ0aWNlcyxcbiAgICB9ID0gb3B0aW1pemF0aW9uU3RhdGU7XG5cbiAgICBjb25zdCBjbGlwVmFsdWUgPSA0LjA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVwb2Noc1BlclNhbXBsZS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGVwb2NoT2ZOZXh0U2FtcGxlW2ldID4gbilcbiAgICAgICAgY29udGludWU7XG5cblxuICAgICAgY29uc3QgaiA9IGhlYWRbaV07XG4gICAgICBjb25zdCBrID0gdGFpbFtpXTtcblxuICAgICAgY29uc3QgY3VycmVudCA9IGhlYWRFbWJlZGRpbmdbal07XG4gICAgICBjb25zdCBvdGhlciA9IHRhaWxFbWJlZGRpbmdba107XG5cbiAgICAgIGNvbnN0IGRpc3RTcXVhcmVkID0gckRpc3QoY3VycmVudCwgb3RoZXIpO1xuXG4gICAgICBsZXQgZ3JhZENvZWZmID0gMDtcbiAgICAgIGlmIChkaXN0U3F1YXJlZCA+IDApIHtcbiAgICAgICAgZ3JhZENvZWZmID0gLTIuMCAqIGEgKiBiICogTWF0aC5wb3coZGlzdFNxdWFyZWQsIGIgLSAxLjApO1xuICAgICAgICBncmFkQ29lZmYgLz0gYSAqIE1hdGgucG93KGRpc3RTcXVhcmVkLCBiKSArIDEuMDtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCBkaW07IGQrKykge1xuICAgICAgICBjb25zdCBncmFkRCA9IGNsaXAoZ3JhZENvZWZmICogKGN1cnJlbnRbZF0gLSBvdGhlcltkXSksIGNsaXBWYWx1ZSk7XG4gICAgICAgIGN1cnJlbnRbZF0gKz0gZ3JhZEQgKiBhbHBoYTtcbiAgICAgICAgaWYgKG1vdmVPdGhlcilcbiAgICAgICAgICBvdGhlcltkXSArPSAtZ3JhZEQgKiBhbHBoYTtcbiAgICAgIH1cblxuICAgICAgZXBvY2hPZk5leHRTYW1wbGVbaV0gKz0gZXBvY2hzUGVyU2FtcGxlW2ldO1xuXG4gICAgICBjb25zdCBuTmVnU2FtcGxlcyA9IE1hdGguZmxvb3IoXG4gICAgICAgIChuIC0gZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZVtpXSkgLyBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZVtpXVxuICAgICAgKTtcblxuICAgICAgZm9yIChsZXQgcCA9IDA7IHAgPCBuTmVnU2FtcGxlczsgcCsrKSB7XG4gICAgICAgIGNvbnN0IGsgPSB1dGlscy50YXVSYW5kSW50KG5WZXJ0aWNlcywgdGhpcy5yYW5kb20pO1xuICAgICAgICBjb25zdCBvdGhlciA9IHRhaWxFbWJlZGRpbmdba107XG5cbiAgICAgICAgY29uc3QgZGlzdFNxdWFyZWQgPSByRGlzdChjdXJyZW50LCBvdGhlcik7XG5cbiAgICAgICAgbGV0IGdyYWRDb2VmZiA9IDAuMDtcbiAgICAgICAgaWYgKGRpc3RTcXVhcmVkID4gMC4wKSB7XG4gICAgICAgICAgZ3JhZENvZWZmID0gMi4wICogZ2FtbWEgKiBiO1xuICAgICAgICAgIGdyYWRDb2VmZiAvPVxuICAgICAgICAgICAgKDAuMDAxICsgZGlzdFNxdWFyZWQpICogKGEgKiBNYXRoLnBvdyhkaXN0U3F1YXJlZCwgYikgKyAxKTtcbiAgICAgICAgfSBlbHNlIGlmIChqID09PSBrKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBkID0gMDsgZCA8IGRpbTsgZCsrKSB7XG4gICAgICAgICAgbGV0IGdyYWREID0gNC4wO1xuICAgICAgICAgIGlmIChncmFkQ29lZmYgPiAwLjApXG4gICAgICAgICAgICBncmFkRCA9IGNsaXAoZ3JhZENvZWZmICogKGN1cnJlbnRbZF0gLSBvdGhlcltkXSksIGNsaXBWYWx1ZSk7XG5cbiAgICAgICAgICBjdXJyZW50W2RdICs9IGdyYWREICogYWxwaGE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGVbaV0gKz0gbk5lZ1NhbXBsZXMgKiBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZVtpXTtcbiAgICB9XG4gICAgb3B0aW1pemF0aW9uU3RhdGUuYWxwaGEgPSBpbml0aWFsQWxwaGEgKiAoMS4wIC0gbiAvIG5FcG9jaHMpO1xuXG4gICAgb3B0aW1pemF0aW9uU3RhdGUuY3VycmVudEVwb2NoICs9IDE7XG4gICAgcmV0dXJuIGhlYWRFbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dEFzeW5jKFxuICAgIGVwb2NoQ2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHN0ZXAgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qge25FcG9jaHMsIGN1cnJlbnRFcG9jaH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuICAgICAgICAgIHRoaXMuZW1iZWRkaW5nID0gdGhpcy5vcHRpbWl6ZUxheW91dFN0ZXAoY3VycmVudEVwb2NoKTtcbiAgICAgICAgICBjb25zdCBlcG9jaENvbXBsZXRlZCA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGUuY3VycmVudEVwb2NoO1xuICAgICAgICAgIGNvbnN0IHNob3VsZFN0b3AgPSBlcG9jaENhbGxiYWNrKGVwb2NoQ29tcGxldGVkKSA9PT0gZmFsc2U7XG4gICAgICAgICAgY29uc3QgaXNGaW5pc2hlZCA9IGVwb2NoQ29tcGxldGVkID09PSBuRXBvY2hzO1xuICAgICAgICAgIGlmICghc2hvdWxkU3RvcCAmJiAhaXNGaW5pc2hlZClcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gc3RlcCgpLCAwKTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShpc0ZpbmlzaGVkKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHN0ZXAoKSwgMCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dChcbiAgICBlcG9jaENhbGxiYWNrOiAoZXBvY2hOdW1iZXI6IG51bWJlcikgPT4gdm9pZCB8IGJvb2xlYW4gPSAoKSA9PiB0cnVlXG4gICk6IFZlY3RvcnMge1xuICAgIGxldCBpc0ZpbmlzaGVkID0gZmFsc2U7XG4gICAgbGV0IGVtYmVkZGluZzogVmVjdG9ycyA9IFtdO1xuICAgIHdoaWxlICghaXNGaW5pc2hlZCkge1xuICAgICAgY29uc3Qge25FcG9jaHMsIGN1cnJlbnRFcG9jaH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuICAgICAgZW1iZWRkaW5nID0gdGhpcy5vcHRpbWl6ZUxheW91dFN0ZXAoY3VycmVudEVwb2NoKTtcbiAgICAgIGNvbnN0IGVwb2NoQ29tcGxldGVkID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5jdXJyZW50RXBvY2g7XG4gICAgICBjb25zdCBzaG91bGRTdG9wID0gZXBvY2hDYWxsYmFjayhlcG9jaENvbXBsZXRlZCkgPT09IGZhbHNlO1xuICAgICAgaXNGaW5pc2hlZCA9IGVwb2NoQ29tcGxldGVkID09PSBuRXBvY2hzIHx8IHNob3VsZFN0b3A7XG4gICAgfVxuICAgIHJldHVybiBlbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGVwb2NocyBmb3Igb3B0aW1pemluZyB0aGUgcHJvamVjdGlvbi5cbiAgICogTk9URTogVGhpcyBoZXVyaXN0aWMgZGlmZmVycyBmcm9tIHRoZSBweXRob24gdmVyc2lvblxuICAgKi9cbiAgcHVibGljIGdldE5FcG9jaHMoKSB7XG4gICAgY29uc3QgZ3JhcGggPSB0aGlzLmdyYXBoO1xuXG4gICAgaWYgKHRoaXMubkVwb2NocyA+IDApXG4gICAgICByZXR1cm4gdGhpcy5uRXBvY2hzO1xuXG5cbiAgICBpZiAoIWdyYXBoKVxuICAgICAgcmV0dXJuIDIwMDtcblxuXG4gICAgY29uc3QgbGVuZ3RoID0gZ3JhcGgublJvd3M7XG4gICAgaWYgKGxlbmd0aCA8PSAyNTAwKVxuICAgICAgcmV0dXJuIDUwMDtcbiAgICBlbHNlIGlmIChsZW5ndGggPD0gNTAwMClcbiAgICAgIHJldHVybiA0MDA7XG4gICAgZWxzZSBpZiAobGVuZ3RoIDw9IDc1MDApXG4gICAgICByZXR1cm4gMzAwO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiAyMDA7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV1Y2xpZGVhbih4OiBWZWN0b3IsIHk6IFZlY3Rvcikge1xuICBsZXQgcmVzdWx0ID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKVxuICAgIHJlc3VsdCArPSAoeFtpXSAtIHlbaV0pICoqIDI7XG5cbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbnVtZXJpYyh4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICBjb25zdCByZXN1bHQgPSBNYXRoLmFicyh4IC0geSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmUoeDogVmVjdG9yLCB5OiBWZWN0b3IpIHtcbiAgbGV0IHJlc3VsdCA9IDAuMDtcbiAgbGV0IG5vcm1YID0gMC4wO1xuICBsZXQgbm9ybVkgPSAwLjA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IHhbaV0gKiB5W2ldO1xuICAgIG5vcm1YICs9IHhbaV0gKiogMjtcbiAgICBub3JtWSArPSB5W2ldICoqIDI7XG4gIH1cblxuICBpZiAobm9ybVggPT09IDAgJiYgbm9ybVkgPT09IDApXG4gICAgcmV0dXJuIDA7XG4gIGVsc2UgaWYgKG5vcm1YID09PSAwIHx8IG5vcm1ZID09PSAwKVxuICAgIHJldHVybiAxLjA7XG4gIGVsc2VcbiAgICByZXR1cm4gMS4wIC0gcmVzdWx0IC8gTWF0aC5zcXJ0KG5vcm1YICogbm9ybVkpO1xufVxuXG4vKipcbiAqIEFuIGludGVyZmFjZSByZXByZXNlbnRpbmcgdGhlIG9wdGltaXphdGlvbiBzdGF0ZSB0cmFja2VkIGJldHdlZW4gc3RlcHMgb2ZcbiAqIHRoZSBTR0Qgb3B0aW1pemF0aW9uXG4gKi9cbmNsYXNzIE9wdGltaXphdGlvblN0YXRlIHtcbiAgY3VycmVudEVwb2NoID0gMDtcblxuICAvLyBEYXRhIHRyYWNrZWQgZHVyaW5nIG9wdGltaXphdGlvbiBzdGVwcy5cbiAgaGVhZEVtYmVkZGluZzogbnVtYmVyW11bXSA9IFtdO1xuICB0YWlsRW1iZWRkaW5nOiBudW1iZXJbXVtdID0gW107XG4gIGhlYWQ6IG51bWJlcltdID0gW107XG4gIHRhaWw6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1BlclNhbXBsZTogbnVtYmVyW10gPSBbXTtcbiAgZXBvY2hPZk5leHRTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlOiBudW1iZXJbXSA9IFtdO1xuICBtb3ZlT3RoZXIgPSB0cnVlO1xuICBpbml0aWFsQWxwaGEgPSAxLjA7XG4gIGFscGhhID0gMS4wO1xuICBnYW1tYSA9IDEuMDtcbiAgYSA9IDEuNTc2OTQzNDYwMzExMzA3NztcbiAgYiA9IDAuODk1MDYwODc3OTEwOTczMztcbiAgZGltID0gMjtcbiAgbkVwb2NocyA9IDUwMDtcbiAgblZlcnRpY2VzID0gMDtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBjbGFtcGluZyBvZiBhIHZhbHVlIGludG8gYSBmaXhlZCByYW5nZVxuICovXG5mdW5jdGlvbiBjbGlwKHg6IG51bWJlciwgY2xpcFZhbHVlOiBudW1iZXIpIHtcbiAgaWYgKHggPiBjbGlwVmFsdWUpIHJldHVybiBjbGlwVmFsdWU7XG4gIGVsc2UgaWYgKHggPCAtY2xpcFZhbHVlKSByZXR1cm4gLWNsaXBWYWx1ZTtcbiAgZWxzZSByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBSZWR1Y2VkIEV1Y2xpZGVhbiBkaXN0YW5jZS5cbiAqL1xuZnVuY3Rpb24gckRpc3QoeDogbnVtYmVyW10sIHk6IG51bWJlcltdKSB7XG4gIGxldCByZXN1bHQgPSAwLjA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKylcbiAgICByZXN1bHQgKz0gTWF0aC5wb3coeFtpXSAtIHlbaV0sIDIpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRml0IGEsIGIgcGFyYW1zIGZvciB0aGUgZGlmZmVyZW50aWFibGUgY3VydmUgdXNlZCBpbiBsb3dlclxuICogZGltZW5zaW9uYWwgZnV6enkgc2ltcGxpY2lhbCBjb21wbGV4IGNvbnN0cnVjdGlvbi4gV2Ugd2FudCB0aGVcbiAqIHNtb290aCBjdXJ2ZSAoZnJvbSBhIHByZS1kZWZpbmVkIGZhbWlseSB3aXRoIHNpbXBsZSBncmFkaWVudCkgdGhhdFxuICogYmVzdCBtYXRjaGVzIGFuIG9mZnNldCBleHBvbmVudGlhbCBkZWNheS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBQlBhcmFtcyhzcHJlYWQ6IG51bWJlciwgbWluRGlzdDogbnVtYmVyKSB7XG4gIGNvbnN0IGN1cnZlID0gKFthLCBiXTogbnVtYmVyW10pID0+ICh4OiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gMS4wIC8gKDEuMCArIGEgKiB4ICoqICgyICogYikpO1xuICB9O1xuXG4gIGNvbnN0IHh2ID0gdXRpbHNcbiAgICAubGluZWFyKDAsIHNwcmVhZCAqIDMsIDMwMClcbiAgICAubWFwKCh2YWwpID0+ICh2YWwgPCBtaW5EaXN0ID8gMS4wIDogdmFsKSk7XG5cbiAgY29uc3QgeXYgPSB1dGlscy56ZXJvcyh4di5sZW5ndGgpLm1hcCgodmFsLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IGd0ZSA9IHh2W2luZGV4XSA+PSBtaW5EaXN0O1xuICAgIHJldHVybiBndGUgPyBNYXRoLmV4cCgtKHh2W2luZGV4XSAtIG1pbkRpc3QpIC8gc3ByZWFkKSA6IHZhbDtcbiAgfSk7XG5cbiAgY29uc3QgaW5pdGlhbFZhbHVlcyA9IFswLjUsIDAuNV07XG4gIGNvbnN0IGRhdGEgPSB7eDogeHYsIHk6IHl2fTtcblxuICAvLyBEZWZhdWx0IG9wdGlvbnMgZm9yIHRoZSBhbGdvcml0aG0gKGZyb20gZ2l0aHViIGV4YW1wbGUpXG4gIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgZGFtcGluZzogMS41LFxuICAgIGluaXRpYWxWYWx1ZXMsXG4gICAgZ3JhZGllbnREaWZmZXJlbmNlOiAxMGUtMixcbiAgICBtYXhJdGVyYXRpb25zOiAxMDAsXG4gICAgZXJyb3JUb2xlcmFuY2U6IDEwZS0zLFxuICB9O1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuZXctY2FwXG4gIGNvbnN0IHtwYXJhbWV0ZXJWYWx1ZXN9ID0gTE0oZGF0YSwgY3VydmUsIG9wdGlvbnMpO1xuICBjb25zdCBbYSwgYl0gPSBwYXJhbWV0ZXJWYWx1ZXMgYXMgbnVtYmVyW107XG4gIHJldHVybiB7YSwgYn07XG59XG5cbi8qKlxuICogVW5kZXIgdGhlIGFzc3VtcHRpb24gb2YgY2F0ZWdvcmljYWwgZGlzdGFuY2UgZm9yIHRoZSBpbnRlcnNlY3RpbmdcbiAqIHNpbXBsaWNpYWwgc2V0IHBlcmZvcm0gYSBmYXN0IGludGVyc2VjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhc3RJbnRlcnNlY3Rpb24oXG4gIGdyYXBoOiBtYXRyaXguU3BhcnNlTWF0cml4LFxuICB0YXJnZXQ6IG51bWJlcltdLFxuICB1bmtub3duRGlzdCA9IDEuMCxcbiAgZmFyRGlzdCA9IDUuMFxuKSB7XG4gIHJldHVybiBncmFwaC5tYXAoKHZhbHVlLCByb3csIGNvbCkgPT4ge1xuICAgIGlmICh0YXJnZXRbcm93XSA9PT0gLTEgfHwgdGFyZ2V0W2NvbF0gPT09IC0xKVxuICAgICAgcmV0dXJuIHZhbHVlICogTWF0aC5leHAoLXVua25vd25EaXN0KTtcbiAgICBlbHNlIGlmICh0YXJnZXRbcm93XSAhPT0gdGFyZ2V0W2NvbF0pXG4gICAgICByZXR1cm4gdmFsdWUgKiBNYXRoLmV4cCgtZmFyRGlzdCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXNldCB0aGUgbG9jYWwgY29ubmVjdGl2aXR5IHJlcXVpcmVtZW50IC0tIGVhY2ggZGF0YSBzYW1wbGUgc2hvdWxkXG4gKiBoYXZlIGNvbXBsZXRlIGNvbmZpZGVuY2UgaW4gYXQgbGVhc3Qgb25lIDEtc2ltcGxleCBpbiB0aGUgc2ltcGxpY2lhbCBzZXQuXG4gKiBXZSBjYW4gZW5mb3JjZSB0aGlzIGJ5IGxvY2FsbHkgcmVzY2FsaW5nIGNvbmZpZGVuY2VzLCBhbmQgdGhlbiByZW1lcmdpbmcgdGhlXG4gKiBkaWZmZXJlbnQgbG9jYWwgc2ltcGxpY2lhbCBzZXRzIHRvZ2V0aGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRMb2NhbENvbm5lY3Rpdml0eShzaW1wbGljaWFsU2V0OiBtYXRyaXguU3BhcnNlTWF0cml4KSB7XG4gIHNpbXBsaWNpYWxTZXQgPSBtYXRyaXgubm9ybWFsaXplKHNpbXBsaWNpYWxTZXQsIG1hdHJpeC5Ob3JtVHlwZS5tYXgpO1xuICBjb25zdCB0cmFuc3Bvc2UgPSBtYXRyaXgudHJhbnNwb3NlKHNpbXBsaWNpYWxTZXQpO1xuICBjb25zdCBwcm9kTWF0cml4ID0gbWF0cml4LnBhaXJ3aXNlTXVsdGlwbHkodHJhbnNwb3NlLCBzaW1wbGljaWFsU2V0KTtcbiAgc2ltcGxpY2lhbFNldCA9IG1hdHJpeC5hZGQoXG4gICAgc2ltcGxpY2lhbFNldCxcbiAgICBtYXRyaXguc3VidHJhY3QodHJhbnNwb3NlLCBwcm9kTWF0cml4KVxuICApO1xuICByZXR1cm4gbWF0cml4LmVsaW1pbmF0ZVplcm9zKHNpbXBsaWNpYWxTZXQpO1xufVxuXG4vKipcbiAqIEdpdmVuIGluZGljZXMgYW5kIHdlaWdodHMgYW5kIGFuIG9yaWdpbmFsIGVtYmVkZGluZ3NcbiAqIGluaXRpYWxpemUgdGhlIHBvc2l0aW9ucyBvZiBuZXcgcG9pbnRzIHJlbGF0aXZlIHRvIHRoZVxuICogaW5kaWNlcyBhbmQgd2VpZ2h0cyAob2YgdGhlaXIgbmVpZ2hib3JzIGluIHRoZSBzb3VyY2UgZGF0YSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0VHJhbnNmb3JtKFxuICBpbmRpY2VzOiBudW1iZXJbXVtdLFxuICB3ZWlnaHRzOiBudW1iZXJbXVtdLFxuICBlbWJlZGRpbmc6IFZlY3RvcnNcbikge1xuICBjb25zdCByZXN1bHQgPSB1dGlsc1xuICAgIC56ZXJvcyhpbmRpY2VzLmxlbmd0aClcbiAgICAubWFwKChfeikgPT4gdXRpbHMuemVyb3MoZW1iZWRkaW5nWzBdLmxlbmd0aCkpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlc1swXS5sZW5ndGg7IGorKykge1xuICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCBlbWJlZGRpbmdbMF0ubGVuZ3RoOyBkKyspIHtcbiAgICAgICAgY29uc3QgYSA9IGluZGljZXNbaV1bal07XG4gICAgICAgIHJlc3VsdFtpXVtkXSArPSB3ZWlnaHRzW2ldW2pdICogZW1iZWRkaW5nW2FdW2RdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuIl19","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as heap from './heap';\nimport * as matrix from './matrix';\nimport * as tree from './tree';\nimport * as utils from './utils';\n/**\n * Create a version of nearest neighbor descent.\n */\nexport function makeNNDescent(distanceFn, random) {\n return function nNDescent(data, leafArray, nNeighbors, nIters = 10, maxCandidates = 50, delta = 0.001, rho = 0.5, rpTreeInit = true) {\n const nVertices = data.length;\n const currentGraph = heap.makeHeap(data.length, nNeighbors);\n for (let i = 0; i < data.length; i++) {\n const indices = heap.rejectionSample(nNeighbors, data.length, random);\n for (let j = 0; j < indices.length; j++) {\n const d = distanceFn(data[i], data[indices[j]]);\n heap.heapPush(currentGraph, i, d, indices[j], 1);\n heap.heapPush(currentGraph, indices[j], d, i, 1);\n }\n }\n if (rpTreeInit) {\n for (let n = 0; n < leafArray.length; n++) {\n for (let i = 0; i < leafArray[n].length; i++) {\n if (leafArray[n][i] < 0)\n break;\n for (let j = i + 1; j < leafArray[n].length; j++) {\n if (leafArray[n][j] < 0)\n break;\n const d = distanceFn(data[leafArray[n][i]], data[leafArray[n][j]]);\n heap.heapPush(currentGraph, leafArray[n][i], d, leafArray[n][j], 1);\n heap.heapPush(currentGraph, leafArray[n][j], d, leafArray[n][i], 1);\n }\n }\n }\n }\n for (let n = 0; n < nIters; n++) {\n const candidateNeighbors = heap.buildCandidates(currentGraph, nVertices, nNeighbors, maxCandidates, random);\n let c = 0;\n for (let i = 0; i < nVertices; i++) {\n for (let j = 0; j < maxCandidates; j++) {\n const p = Math.floor(candidateNeighbors[0][i][j]);\n if (p < 0 || utils.tauRand(random) < rho)\n continue;\n for (let k = 0; k < maxCandidates; k++) {\n const q = Math.floor(candidateNeighbors[0][i][k]);\n const cj = candidateNeighbors[2][i][j];\n const ck = candidateNeighbors[2][i][k];\n if (q < 0 || (!cj && !ck))\n continue;\n const d = distanceFn(data[p], data[q]);\n c += heap.heapPush(currentGraph, p, d, q, 1);\n c += heap.heapPush(currentGraph, q, d, p, 1);\n }\n }\n }\n if (c <= delta * nNeighbors * data.length)\n break;\n }\n const sorted = heap.deheapSort(currentGraph);\n return sorted;\n };\n}\nexport function makeInitializations(distanceFn) {\n function initFromRandom(nNeighbors, data, queryPoints, _heap, random) {\n for (let i = 0; i < queryPoints.length; i++) {\n const indices = utils.rejectionSample(nNeighbors, data.length, random);\n for (let j = 0; j < indices.length; j++) {\n if (indices[j] < 0)\n continue;\n const d = distanceFn(data[indices[j]], queryPoints[i]);\n heap.heapPush(_heap, i, d, indices[j], 1);\n }\n }\n }\n function initFromTree(_tree, data, queryPoints, _heap, random) {\n for (let i = 0; i < queryPoints.length; i++) {\n const indices = tree.searchFlatTree(queryPoints[i], _tree, random);\n for (let j = 0; j < indices.length; j++) {\n if (indices[j] < 0)\n return;\n const d = distanceFn(data[indices[j]], queryPoints[i]);\n heap.heapPush(_heap, i, d, indices[j], 1);\n }\n }\n return;\n }\n return { initFromRandom, initFromTree };\n}\nexport function makeInitializedNNSearch(distanceFn) {\n return function nnSearchFn(data, graph, initialization, queryPoints) {\n const { indices, indptr } = matrix.getCSR(graph);\n for (let i = 0; i < queryPoints.length; i++) {\n const tried = new Set(initialization[0][i]);\n while (true) {\n // Find smallest flagged vertex\n const vertex = heap.smallestFlagged(initialization, i);\n if (vertex === -1)\n break;\n const candidates = indices.slice(indptr[vertex], indptr[vertex + 1]);\n for (const candidate of candidates) {\n if (candidate === vertex ||\n candidate === -1 ||\n tried.has(candidate))\n continue;\n const d = distanceFn(data[candidate], queryPoints[i]);\n heap.uncheckedHeapPush(initialization, i, d, candidate, 1);\n tried.add(candidate);\n }\n }\n }\n return initialization;\n };\n}\nexport function initializeSearch(forest, data, queryPoints, nNeighbors, initFromRandom, initFromTree, random) {\n const results = heap.makeHeap(queryPoints.length, nNeighbors);\n initFromRandom(nNeighbors, data, queryPoints, results, random);\n if (forest) {\n for (const tree of forest)\n initFromTree(tree, data, queryPoints, results, random);\n }\n return results;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm5fZGVzY2VudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm5uX2Rlc2NlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBR2pDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxVQUFzQixFQUFFLE1BQWdCO0lBQ3BFLE9BQU8sU0FBUyxTQUFTLENBQ3ZCLElBQVksRUFDWixTQUFrQixFQUNsQixVQUFrQixFQUNsQixNQUFNLEdBQUcsRUFBRSxFQUNYLGFBQWEsR0FBRyxFQUFFLEVBQ2xCLEtBQUssR0FBRyxLQUFLLEVBQ2IsR0FBRyxHQUFHLEdBQUcsRUFDVCxVQUFVLEdBQUcsSUFBSTtRQUVqQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzlCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUU1RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdEUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxF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QUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBoZWFwIGZyb20gJy4vaGVhcCc7XG5pbXBvcnQgKiBhcyBtYXRyaXggZnJvbSAnLi9tYXRyaXgnO1xuaW1wb3J0ICogYXMgdHJlZSBmcm9tICcuL3RyZWUnO1xuaW1wb3J0ICogYXMgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge1JhbmRvbUZuLCBWZWN0b3JzLCBEaXN0YW5jZUZuLCBWZWN0b3J9IGZyb20gJy4vdW1hcCc7XG5cbi8qKlxuICogQ3JlYXRlIGEgdmVyc2lvbiBvZiBuZWFyZXN0IG5laWdoYm9yIGRlc2NlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTk5EZXNjZW50KGRpc3RhbmNlRm46IERpc3RhbmNlRm4sIHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIG5ORGVzY2VudChcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgbGVhZkFycmF5OiBWZWN0b3JzLFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBuSXRlcnMgPSAxMCxcbiAgICBtYXhDYW5kaWRhdGVzID0gNTAsXG4gICAgZGVsdGEgPSAwLjAwMSxcbiAgICByaG8gPSAwLjUsXG4gICAgcnBUcmVlSW5pdCA9IHRydWVcbiAgKSB7XG4gICAgY29uc3QgblZlcnRpY2VzID0gZGF0YS5sZW5ndGg7XG4gICAgY29uc3QgY3VycmVudEdyYXBoID0gaGVhcC5tYWtlSGVhcChkYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSBoZWFwLnJlamVjdGlvblNhbXBsZShuTmVpZ2hib3JzLCBkYXRhLmxlbmd0aCwgcmFuZG9tKTtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2ldLCBkYXRhW2luZGljZXNbal1dKTtcblxuICAgICAgICBoZWFwLmhlYXBQdXNoKGN1cnJlbnRHcmFwaCwgaSwgZCwgaW5kaWNlc1tqXSwgMSk7XG4gICAgICAgIGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBpbmRpY2VzW2pdLCBkLCBpLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJwVHJlZUluaXQpIHtcbiAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgbGVhZkFycmF5Lmxlbmd0aDsgbisrKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVhZkFycmF5W25dLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGxlYWZBcnJheVtuXVtpXSA8IDApXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IGxlYWZBcnJheVtuXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgaWYgKGxlYWZBcnJheVtuXVtqXSA8IDApXG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2xlYWZBcnJheVtuXVtpXV0sIGRhdGFbbGVhZkFycmF5W25dW2pdXSk7XG4gICAgICAgICAgICBoZWFwLmhlYXBQdXNoKGN1cnJlbnRHcmFwaCwgbGVhZkFycmF5W25dW2ldLCBkLCBsZWFmQXJyYXlbbl1bal0sIDEpO1xuICAgICAgICAgICAgaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIGxlYWZBcnJheVtuXVtqXSwgZCwgbGVhZkFycmF5W25dW2ldLCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGxldCBuID0gMDsgbiA8IG5JdGVyczsgbisrKSB7XG4gICAgICBjb25zdCBjYW5kaWRhdGVOZWlnaGJvcnMgPSBoZWFwLmJ1aWxkQ2FuZGlkYXRlcyhcbiAgICAgICAgY3VycmVudEdyYXBoLFxuICAgICAgICBuVmVydGljZXMsXG4gICAgICAgIG5OZWlnaGJvcnMsXG4gICAgICAgIG1heENhbmRpZGF0ZXMsXG4gICAgICAgIHJhbmRvbVxuICAgICAgKTtcblxuICAgICAgbGV0IGMgPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuVmVydGljZXM7IGkrKykge1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG1heENhbmRpZGF0ZXM7IGorKykge1xuICAgICAgICAgIGNvbnN0IHAgPSBNYXRoLmZsb29yKGNhbmRpZGF0ZU5laWdoYm9yc1swXVtpXVtqXSk7XG4gICAgICAgICAgaWYgKHAgPCAwIHx8IHV0aWxzLnRhdVJhbmQocmFuZG9tKSA8IHJobylcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuXG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBtYXhDYW5kaWRhdGVzOyBrKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHEgPSBNYXRoLmZsb29yKGNhbmRpZGF0ZU5laWdoYm9yc1swXVtpXVtrXSk7XG4gICAgICAgICAgICBjb25zdCBjaiA9IGNhbmRpZGF0ZU5laWdoYm9yc1syXVtpXVtqXTtcbiAgICAgICAgICAgIGNvbnN0IGNrID0gY2FuZGlkYXRlTmVpZ2hib3JzWzJdW2ldW2tdO1xuICAgICAgICAgICAgaWYgKHEgPCAwIHx8ICghY2ogJiYgIWNrKSlcbiAgICAgICAgICAgICAgY29udGludWU7XG5cblxuICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtwXSwgZGF0YVtxXSk7XG4gICAgICAgICAgICBjICs9IGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBwLCBkLCBxLCAxKTtcbiAgICAgICAgICAgIGMgKz0gaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIHEsIGQsIHAsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGMgPD0gZGVsdGEgKiBuTmVpZ2hib3JzICogZGF0YS5sZW5ndGgpXG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBzb3J0ZWQgPSBoZWFwLmRlaGVhcFNvcnQoY3VycmVudEdyYXBoKTtcbiAgICByZXR1cm4gc29ydGVkO1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBJbml0RnJvbVJhbmRvbUZuID0gKFxuICBuTmVpZ2hib3JzOiBudW1iZXIsXG4gIGRhdGE6IFZlY3RvcixcbiAgcXVlcnlQb2ludHM6IFZlY3RvcixcbiAgX2hlYXA6IGhlYXAuSGVhcCxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSA9PiB2b2lkO1xuXG5leHBvcnQgdHlwZSBJbml0RnJvbVRyZWVGbiA9IChcbiAgX3RyZWU6IHRyZWUuRmxhdFRyZWUsXG4gIGRhdGE6IFZlY3RvcixcbiAgcXVlcnlQb2ludHM6IFZlY3RvcixcbiAgX2hlYXA6IGhlYXAuSGVhcCxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSA9PiB2b2lkO1xuXG5leHBvcnQgZnVuY3Rpb24gbWFrZUluaXRpYWxpemF0aW9ucyhkaXN0YW5jZUZuOiBEaXN0YW5jZUZuKSB7XG4gIGZ1bmN0aW9uIGluaXRGcm9tUmFuZG9tKFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgcXVlcnlQb2ludHM6IFZlY3RvcixcbiAgICBfaGVhcDogaGVhcC5IZWFwLFxuICAgIHJhbmRvbTogUmFuZG9tRm5cbiAgKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyeVBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgaW5kaWNlcyA9IHV0aWxzLnJlamVjdGlvblNhbXBsZShuTmVpZ2hib3JzLCBkYXRhLmxlbmd0aCwgcmFuZG9tKTtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoaW5kaWNlc1tqXSA8IDApXG4gICAgICAgICAgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtpbmRpY2VzW2pdXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICBoZWFwLmhlYXBQdXNoKF9oZWFwLCBpLCBkLCBpbmRpY2VzW2pdLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0RnJvbVRyZWUoXG4gICAgX3RyZWU6IHRyZWUuRmxhdFRyZWUsXG4gICAgZGF0YTogVmVjdG9yLFxuICAgIHF1ZXJ5UG9pbnRzOiBWZWN0b3IsXG4gICAgX2hlYXA6IGhlYXAuSGVhcCxcbiAgICByYW5kb206IFJhbmRvbUZuXG4gICkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcXVlcnlQb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSB0cmVlLnNlYXJjaEZsYXRUcmVlKHF1ZXJ5UG9pbnRzW2ldLCBfdHJlZSwgcmFuZG9tKTtcblxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRpY2VzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChpbmRpY2VzW2pdIDwgMClcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtpbmRpY2VzW2pdXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICBoZWFwLmhlYXBQdXNoKF9oZWFwLCBpLCBkLCBpbmRpY2VzW2pdLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIHtpbml0RnJvbVJhbmRvbSwgaW5pdEZyb21UcmVlfTtcbn1cblxuZXhwb3J0IHR5cGUgU2VhcmNoRm4gPSAoXG4gIGRhdGE6IFZlY3RvcixcbiAgZ3JhcGg6IG1hdHJpeC5TcGFyc2VNYXRyaXgsXG4gIGluaXRpYWxpemF0aW9uOiBoZWFwLkhlYXAsXG4gIHF1ZXJ5UG9pbnRzOiBWZWN0b3JcbikgPT4gaGVhcC5IZWFwO1xuXG5leHBvcnQgZnVuY3Rpb24gbWFrZUluaXRpYWxpemVkTk5TZWFyY2goZGlzdGFuY2VGbjogRGlzdGFuY2VGbikge1xuICByZXR1cm4gZnVuY3Rpb24gbm5TZWFyY2hGbihcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgZ3JhcGg6IG1hdHJpeC5TcGFyc2VNYXRyaXgsXG4gICAgaW5pdGlhbGl6YXRpb246IGhlYXAuSGVhcCxcbiAgICBxdWVyeVBvaW50czogVmVjdG9yXG4gICkge1xuICAgIGNvbnN0IHtpbmRpY2VzLCBpbmRwdHJ9ID0gbWF0cml4LmdldENTUihncmFwaCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5UG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB0cmllZCA9IG5ldyBTZXQoaW5pdGlhbGl6YXRpb25bMF1baV0pO1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgLy8gRmluZCBzbWFsbGVzdCBmbGFnZ2VkIHZlcnRleFxuICAgICAgICBjb25zdCB2ZXJ0ZXggPSBoZWFwLnNtYWxsZXN0RmxhZ2dlZChpbml0aWFsaXphdGlvbiwgaSk7XG5cbiAgICAgICAgaWYgKHZlcnRleCA9PT0gLTEpXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IGluZGljZXMuc2xpY2UoaW5kcHRyW3ZlcnRleF0sIGluZHB0clt2ZXJ0ZXggKyAxXSk7XG4gICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBjYW5kaWRhdGUgPT09IHZlcnRleCB8fFxuICAgICAgICAgICAgY2FuZGlkYXRlID09PSAtMSB8fFxuICAgICAgICAgICAgdHJpZWQuaGFzKGNhbmRpZGF0ZSlcbiAgICAgICAgICApXG4gICAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZUZuKGRhdGFbY2FuZGlkYXRlXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICAgIGhlYXAudW5jaGVja2VkSGVhcFB1c2goaW5pdGlhbGl6YXRpb24sIGksIGQsIGNhbmRpZGF0ZSwgMSk7XG4gICAgICAgICAgdHJpZWQuYWRkKGNhbmRpZGF0ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluaXRpYWxpemF0aW9uO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5pdGlhbGl6ZVNlYXJjaChcbiAgZm9yZXN0OiB0cmVlLkZsYXRUcmVlW10sXG4gIGRhdGE6IFZlY3RvcixcbiAgcXVlcnlQb2ludHM6IFZlY3RvcixcbiAgbk5laWdoYm9yczogbnVtYmVyLFxuICBpbml0RnJvbVJhbmRvbTogSW5pdEZyb21SYW5kb21GbixcbiAgaW5pdEZyb21UcmVlOiBJbml0RnJvbVRyZWVGbixcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBoZWFwLm1ha2VIZWFwKHF1ZXJ5UG9pbnRzLmxlbmd0aCwgbk5laWdoYm9ycyk7XG4gIGluaXRGcm9tUmFuZG9tKG5OZWlnaGJvcnMsIGRhdGEsIHF1ZXJ5UG9pbnRzLCByZXN1bHRzLCByYW5kb20pO1xuICBpZiAoZm9yZXN0KSB7XG4gICAgZm9yIChjb25zdCB0cmVlIG9mIGZvcmVzdClcbiAgICAgIGluaXRGcm9tVHJlZSh0cmVlLCBkYXRhLCBxdWVyeVBvaW50cywgcmVzdWx0cywgcmFuZG9tKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0cztcbn1cbiJdfQ==","import isArray from 'is-any-array';\n\nimport errorCalculation from './errorCalculation';\nimport step from './step';\n\n/**\n * Curve fitting algorithm\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @param {object} [options] - Options object\n * @param {number} [options.damping] - Levenberg-Marquardt parameter\n * @param {number} [options.gradientDifference = 10e-2] - Adjustment for decrease the damping parameter\n * @param {Array<number>} [options.minValues] - Minimum allowed values for parameters\n * @param {Array<number>} [options.maxValues] - Maximum allowed values for parameters\n * @param {Array<number>} [options.initialValues] - Array of initial parameter values\n * @param {number} [options.maxIterations = 100] - Maximum of allowed iterations\n * @param {number} [options.errorTolerance = 10e-3] - Minimum uncertainty allowed for each point\n * @return {{parameterValues: Array<number>, parameterError: number, iterations: number}}\n */\nexport default function levenbergMarquardt(\n data,\n parameterizedFunction,\n options = {},\n) {\n let {\n maxIterations = 100,\n gradientDifference = 10e-2,\n damping = 0,\n errorTolerance = 10e-3,\n minValues,\n maxValues,\n initialValues,\n } = options;\n\n if (damping <= 0) {\n throw new Error('The damping option must be a positive number');\n } else if (!data.x || !data.y) {\n throw new Error('The data parameter must have x and y elements');\n } else if (\n !isArray(data.x) ||\n data.x.length < 2 ||\n !isArray(data.y) ||\n data.y.length < 2\n ) {\n throw new Error(\n 'The data parameter elements must be an array with more than 2 points',\n );\n } else if (data.x.length !== data.y.length) {\n throw new Error('The data parameter elements must have the same size');\n }\n\n let parameters =\n initialValues || new Array(parameterizedFunction.length).fill(1);\n let parLen = parameters.length;\n maxValues = maxValues || new Array(parLen).fill(Number.MAX_SAFE_INTEGER);\n minValues = minValues || new Array(parLen).fill(Number.MIN_SAFE_INTEGER);\n\n if (maxValues.length !== minValues.length) {\n throw new Error('minValues and maxValues must be the same size');\n }\n\n if (!isArray(parameters)) {\n throw new Error('initialValues must be an array');\n }\n\n let error = errorCalculation(data, parameters, parameterizedFunction);\n\n let converged = error <= errorTolerance;\n\n let iteration;\n for (iteration = 0; iteration < maxIterations && !converged; iteration++) {\n parameters = step(\n data,\n parameters,\n damping,\n gradientDifference,\n parameterizedFunction,\n );\n\n for (let k = 0; k < parLen; k++) {\n parameters[k] = Math.min(\n Math.max(minValues[k], parameters[k]),\n maxValues[k],\n );\n }\n\n error = errorCalculation(data, parameters, parameterizedFunction);\n if (isNaN(error)) break;\n converged = error <= errorTolerance;\n }\n\n return {\n parameterValues: parameters,\n parameterError: error,\n iterations: iteration,\n };\n}\n","import { dmLinearIndex } from '../distance-matrix';\nexport class TSNE {\n assert(condition, message) {\n if (!condition)\n throw message || 'Assertion failed';\n }\n // syntax sugar\n getopt(opt, field, defaultval) {\n if (opt.hasOwnProperty(field))\n return opt[field];\n else\n return defaultval;\n }\n gaussRandom() {\n if (this.returnV) {\n this.returnV = false;\n return this.vValue;\n }\n const u = 2 * this.random() - 1;\n const v = 2 * this.random() - 1;\n const r = u * u + v * v;\n if (r === 0 || r > 1)\n return this.gaussRandom();\n const c = Math.sqrt(-2 * Math.log(r) / r);\n this.vValue = v * c; // cache this for next function call for efficiency\n this.returnV = true;\n return u * c;\n }\n // return random normal number\n randn(mu, std) {\n return mu + this.gaussRandom() * std;\n }\n // utilitity that creates contiguous vector of zeros of size n\n zeros(n) {\n if (typeof (n) === 'undefined' || isNaN(n))\n return new Float32Array();\n if (typeof ArrayBuffer === 'undefined') {\n // lacking browser support\n const arr = new Float32Array(n);\n for (let i = 0; i < n; i++)\n arr[i] = 0;\n return arr;\n }\n else {\n return new Float32Array(n); // typed arrays are faster\n }\n }\n // utility that returns 2d array filled with random numbers\n // or with value s, if provided\n randn2d(n, d, s) {\n const uses = typeof s !== 'undefined';\n const x = (new Array(n)).fill(null).map(() => new Float32Array(d));\n if (uses) {\n for (let i = 0; i < n; i++)\n x[i] = new Float32Array(d).fill(s);\n }\n else {\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < d; j++)\n x[i][j] = this.randn(0.0, 1e-4);\n }\n }\n return x;\n }\n // compute L2 distance between two vectors\n l2(x1, x2) {\n const D = x1.length;\n let d = 0;\n for (let i = 0; i < D; i++) {\n const x1i = x1[i];\n const x2i = x2[i];\n d += (x1i - x2i) * (x1i - x2i);\n }\n return d;\n }\n // compute pairwise distance in all vectors in X\n xtod(X) {\n const N = X.length;\n const dist = this.zeros(N * N); // allocate contiguous array\n for (let i = 0; i < N; i++) {\n for (let j = i + 1; j < N; j++) {\n const d = this.l2(X[i], X[j]);\n dist[i * N + j] = d;\n dist[j * N + i] = d;\n }\n }\n return dist;\n }\n getIterSize(rowSize) {\n if (rowSize <= 2000)\n return 100;\n else if (rowSize <= 3000)\n return 90;\n else if (rowSize <= 5000)\n return 80;\n else\n return 70;\n }\n // compute (p_{i|j} + p_{j|i})/(2n)\n d2p(D, perplexity, tol, rowSize) {\n // const nf = Math.sqrt(D.length); // this better be an integer\n // const n = Math.floor(nf);\n // this.assert(n === nf, 'D should have square number of elements.');\n const indexer = dmLinearIndex(rowSize);\n const distances = new Float32Array(rowSize * rowSize);\n for (let i = 0; i < rowSize; i++) {\n for (let j = i + 1; j < rowSize; j++)\n distances[i * rowSize + j] = distances[j * rowSize + i] = D[indexer(i, j)];\n }\n const n = rowSize;\n const hTarget = Math.log(perplexity); // target entropy of distribution\n const P = this.zeros(n * n); // temporary probability matrix\n const prow = this.zeros(n); // a temporary storage compartment\n for (let i = 0; i < n; i++) {\n let betamin = -Infinity;\n let betamax = Infinity;\n let beta = 1; // initial value of precision\n let done = false;\n const maxtries = Math.floor(this.getIterSize(rowSize) / 5);\n // perform binary search to find a suitable precision beta\n // so that the entropy of the distribution is appropriate\n let num = 0;\n while (!done) {\n //debugger;\n // compute entropy and kernel row with beta precision\n let psum = 0.0;\n for (let j = 0; j < n; j++) {\n const pj = i === j ? 0 : Math.exp(-distances[i * n + j] * beta);\n prow[j] = pj;\n psum += pj;\n }\n // normalize p and compute entropy\n let nHere = 0.0;\n for (let j = 0; j < n; j++) {\n let pj;\n if (psum === 0)\n pj = 0;\n else\n pj = prow[j] / psum;\n prow[j] = pj;\n if (pj > 1e-7)\n nHere -= pj * Math.log(pj);\n }\n // adjust beta based on result\n if (nHere > hTarget) {\n // entropy was too high (distribution too diffuse)\n // so we need to increase the precision for more peaky distribution\n betamin = beta; // move up the bounds\n if (betamax === Infinity)\n beta = beta * 2;\n else\n beta = (beta + betamax) / 2;\n }\n else {\n // converse case. make distrubtion less peaky\n betamax = beta;\n if (betamin === -Infinity)\n beta = beta / 2;\n else\n beta = (beta + betamin) / 2;\n }\n // stopping conditions: too many tries or got a good precision\n num++;\n if (Math.abs(nHere - hTarget) < tol)\n done = true;\n if (num >= maxtries)\n done = true;\n }\n // console.log('data point ' + i + ' gets precision ' + beta + ' after ' + num + ' binary search steps.');\n // copy over the final prow to P at row i\n for (let j = 0; j < n; j++)\n P[i * n + j] = prow[j];\n } // end loop over examples i\n // symmetrize P and normalize it to sum to 1 over all ij\n const pOut = this.zeros(n * n);\n const N2 = n * 2;\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++)\n pOut[i * n + j] = Math.max((P[i * n + j] + P[j * n + i]) / N2, 1e-100);\n }\n return pOut;\n }\n // helper function\n sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }\n constructor(opt) {\n this.iter = 0;\n this.random = Math.random;\n // return 0 mean unit standard deviation random number\n this.returnV = false;\n this.vValue = 0.0;\n opt = opt || {};\n this.perplexity = this.getopt(opt, 'perplexity', 30); // effective number of nearest neighbors\n this.dim = this.getopt(opt, 'dim', 2); // by default 2-D tSNE\n this.epsilon = this.getopt(opt, 'epsilon', 10); // learning rate\n this.random = this.getopt(opt, 'random', Math.random); // random number generator\n }\n // this function takes a set of high-dimensional points\n // and creates matrix P from them using gaussian kernel\n initDataRaw(X) {\n const N = X.length;\n const D = X[0].length;\n this.assert(N > 0, ' X is empty? You must have some data!');\n this.assert(D > 0, ' X[0] is empty? Where is the data?');\n const dists = this.xtod(X); // convert X to distances using gaussian kernel\n this.P = this.d2p(dists, this.perplexity, 1e-4, D); // attach to object\n this.N = N; // back up the size of the dataset\n this.initSolution(); // refresh this\n }\n // this function takes a given distance matrix and creates\n // matrix P from them.\n // D is assumed to be provided as a list of lists, and should be symmetric\n initDataDist(D, rowSize) {\n const N = D.length;\n this.assert(N > 0, ' X is empty? You must have some data!');\n // convert D to a (fast) typed array version\n // dists.forEach((d) => console.log(d));\n console.time('distances to matrix');\n this.P = this.d2p(D, this.perplexity, 1e-4, rowSize);\n console.timeEnd('distances to matrix');\n this.N = rowSize;\n this.initSolution(); // refresh this\n }\n // (re)initializes the solution to random\n initSolution() {\n // generate random solution to t-SNE\n this.Y = this.randn2d(this.N, this.dim); // the solution\n this.gains = this.randn2d(this.N, this.dim, 1.0); // step gains to accelerate progress in unchanging directions\n this.ystep = this.randn2d(this.N, this.dim, 0.0); // momentum accumulator\n this.iter = 0;\n }\n // return pointer to current solution\n getSolution() {\n return this.Y;\n }\n // perform a single step of optimization to improve the embedding\n step() {\n this.iter += 1;\n const N = this.N;\n const cg = this.costGrad(this.Y); // evaluate gradient\n const cost = cg.cost;\n const grad = cg.grad;\n // perform gradient step\n const ymean = this.zeros(this.dim);\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++) {\n const gid = grad[i][d];\n const sid = this.ystep[i][d];\n const gainid = this.gains[i][d];\n // compute gain update\n let newgain = this.sign(gid) === this.sign(sid) ? gainid * 0.8 : gainid + 0.2;\n if (newgain < 0.01)\n newgain = 0.01; // clamp\n this.gains[i][d] = newgain; // store for next turn\n // compute momentum step direction\n const momval = this.iter < 250 ? 0.5 : 0.8;\n const newsid = momval * sid - this.epsilon * newgain * grad[i][d];\n this.ystep[i][d] = newsid; // remember the step we took\n // step!\n this.Y[i][d] += newsid;\n ymean[d] += this.Y[i][d]; // accumulate mean so that we can center later\n }\n }\n // reproject Y to be zero mean\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++)\n this.Y[i][d] -= ymean[d] / N;\n }\n //if(this.iter%100===0) console.log('iter ' + this.iter + ', cost: ' + cost);\n return cost; // return current cost\n }\n // for debugging: gradient check\n debugGrad() {\n const N = this.N;\n const cg = this.costGrad(this.Y); // evaluate gradient\n //const cost = cg.cost;\n const grad = cg.grad;\n const e = 1e-5;\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++) {\n const yold = this.Y[i][d];\n this.Y[i][d] = yold + e;\n const cg0 = this.costGrad(this.Y);\n this.Y[i][d] = yold - e;\n const cg1 = this.costGrad(this.Y);\n const analytic = grad[i][d];\n const numerical = (cg0.cost - cg1.cost) / (2 * e);\n console.log(i + ',' + d + ': gradcheck analytic: ' + analytic + ' vs. numerical: ' + numerical);\n this.Y[i][d] = yold;\n }\n }\n }\n // return cost and gradient, given an arrangement\n costGrad(Y) {\n const N = this.N;\n const dim = this.dim; // dim of output space\n const P = this.P;\n const pmul = this.iter < 100 ? 4 : 1; // trick that helps with local optima\n // compute current Q distribution, unnormalized first\n this.quArr ?? (this.quArr = this.zeros(N * N));\n let qsum = 0.0;\n for (let i = 0; i < N; i++) {\n for (let j = i + 1; j < N; j++) {\n const dsum = new Array(dim).reduce((prev, _, d) => prev + Math.pow(Y[i][d] - Y[j][d], 2), 0);\n const qu = 1.0 / (1.0 + dsum); // Student t-distribution\n this.quArr[i * N + j] = qu;\n this.quArr[j * N + i] = qu;\n qsum += 2 * qu;\n }\n }\n // normalize Q distribution to sum to 1\n //const NN = N * N;\n //const Q = this.zeros(NN);\n let cost = 0.0;\n const grad = new Array(N).fill(null).map(() => (new Float32Array(dim)).fill(0.0));\n for (let i = 0; i < N; i++) {\n // const gsum = new Float32Array(dim).fill(0.0); // init grad for point i\n for (let j = i + 1; j < N; j++) {\n const Q = Math.max(this.quArr[i * N + j] / qsum, 1e-100);\n cost += (-P[i * N + j] * Math.log(Q)) * 2; // accumulate cost (the non-constant portion at least...)\n const premult = 4 * (pmul * P[i * N + j] - Q) * this.quArr[i * N + j];\n //console.log(premult, Q, i, j);\n for (let d = 0; d < dim; d++) {\n grad[i][d] += premult * (Y[i][d] - Y[j][d]);\n grad[j][d] += premult * (Y[j][d] - Y[i][d]);\n }\n }\n //grad[i] = gsum;\n }\n return { cost, grad };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidC1zbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0LXNuZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFHakQsTUFBTSxPQUFPLElBQUk7SUFXUCxNQUFNLENBQUMsU0FBYyxFQUFFLE9BQVk7UUFDekMsSUFBSSxDQUFDLFNBQVM7WUFBRSxNQUFNLE9BQU8sSUFBSSxrQkFBa0IsQ0FBQztJQUN0RCxDQUFDO0lBRUQsZUFBZTtJQUNQLE1BQU0sQ0FBQyxHQUF1QixFQUFFLEtBQWEsRUFBRSxVQUFlO1FBQ3BFLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUM7WUFDM0IsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7O1lBRWxCLE9BQU8sVUFBVSxDQUFDO0lBQ3RCLENBQUM7SUFLQyxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDckIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3JCLENBQUM7UUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNoQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNoQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDaEQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENB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Li9kaXN0YW5jZS1tYXRyaXgnO1xuXG5cbmV4cG9ydCBjbGFzcyBUU05FIHtcbiAgcHJpdmF0ZSBwZXJwbGV4aXR5OiBudW1iZXI7XG4gIHByaXZhdGUgZGltOiBudW1iZXI7XG4gIHByaXZhdGUgZXBzaWxvbjogbnVtYmVyO1xuICBwcml2YXRlIGl0ZXIgPSAwO1xuICBwcml2YXRlIE4hOiBudW1iZXI7XG4gIHByaXZhdGUgUCE6IEZsb2F0MzJBcnJheTtcbiAgcHJpdmF0ZSBZITogYW55W107XG4gIHByaXZhdGUgZ2FpbnMhOiBhbnlbXTtcbiAgcHJpdmF0ZSB5c3RlcCE6IGFueVtdO1xuICBwcml2YXRlIHJhbmRvbTogKCkgPT4gbnVtYmVyID0gTWF0aC5yYW5kb207XG4gIHByaXZhdGUgYXNzZXJ0KGNvbmRpdGlvbjogYW55LCBtZXNzYWdlOiBhbnkpIHtcbiAgICBpZiAoIWNvbmRpdGlvbikgdGhyb3cgbWVzc2FnZSB8fCAnQXNzZXJ0aW9uIGZhaWxlZCc7XG4gIH1cblxuICAvLyBzeW50YXggc3VnYXJcbiAgcHJpdmF0ZSBnZXRvcHQob3B0OiB7W186IHN0cmluZ106IGFueX0sIGZpZWxkOiBzdHJpbmcsIGRlZmF1bHR2YWw6IGFueSkge1xuICAgIGlmIChvcHQuaGFzT3duUHJvcGVydHkoZmllbGQpKVxuICAgICAgcmV0dXJuIG9wdFtmaWVsZF07XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIGRlZmF1bHR2YWw7XG4gIH1cblxuICAgIC8vIHJldHVybiAwIG1lYW4gdW5pdCBzdGFuZGFyZCBkZXZpYXRpb24gcmFuZG9tIG51bWJlclxuICAgIHByaXZhdGUgcmV0dXJuViA9IGZhbHNlO1xuICAgIHByaXZhdGUgdlZhbHVlID0gMC4wO1xuICAgIGdhdXNzUmFuZG9tKCk6IG51bWJlciB7XG4gICAgICBpZiAodGhpcy5yZXR1cm5WKSB7XG4gICAgICAgIHRoaXMucmV0dXJuViA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gdGhpcy52VmFsdWU7XG4gICAgICB9XG4gICAgICBjb25zdCB1ID0gMiAqIHRoaXMucmFuZG9tKCkgLSAxO1xuICAgICAgY29uc3QgdiA9IDIgKiB0aGlzLnJhbmRvbSgpIC0gMTtcbiAgICAgIGNvbnN0IHIgPSB1ICogdSArIHYgKiB2O1xuICAgICAgaWYgKHIgPT09IDAgfHwgciA+IDEpIHJldHVybiB0aGlzLmdhdXNzUmFuZG9tKCk7XG4gICAgICBjb25zdCBjID0gTWF0aC5zcXJ0KC0yICogTWF0aC5sb2cocikgLyByKTtcbiAgICAgIHRoaXMudlZhbHVlID0gdiAqIGM7IC8vIGNhY2hlIHRoaXMgZm9yIG5leHQgZnVuY3Rpb24gY2FsbCBmb3IgZWZmaWNpZW5jeVxuICAgICAgdGhpcy5yZXR1cm5WID0gdHJ1ZTtcbiAgICAgIHJldHVybiB1ICogYztcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gcmFuZG9tIG5vcm1hbCBudW1iZXJcbiAgICBwcml2YXRlIHJhbmRuKG11OiBudW1iZXIsIHN0ZDogbnVtYmVyKSB7XG4gICAgICByZXR1cm4gbXUgKyB0aGlzLmdhdXNzUmFuZG9tKCkgKiBzdGQ7XG4gICAgfVxuXG4gICAgLy8gdXRpbGl0aXR5IHRoYXQgY3JlYXRlcyBjb250aWd1b3VzIHZlY3RvciBvZiB6ZXJvcyBvZiBzaXplIG5cbiAgICBwcml2YXRlIHplcm9zKG46IG51bWJlcikge1xuICAgICAgaWYgKHR5cGVvZiAobikgPT09ICd1bmRlZmluZWQnIHx8IGlzTmFOKG4pKSByZXR1cm4gbmV3IEZsb2F0MzJBcnJheSgpO1xuICAgICAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gbGFja2luZyBicm93c2VyIHN1cHBvcnRcbiAgICAgICAgY29uc3QgYXJyID0gbmV3IEZsb2F0MzJBcnJheShuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIGFycltpXSA9IDA7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShuKTsgLy8gdHlwZWQgYXJyYXlzIGFyZSBmYXN0ZXJcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB1dGlsaXR5IHRoYXQgcmV0dXJucyAyZCBhcnJheSBmaWxsZWQgd2l0aCByYW5kb20gbnVtYmVyc1xuICAgIC8vIG9yIHdpdGggdmFsdWUgcywgaWYgcHJvdmlkZWRcbiAgICBwcml2YXRlIHJhbmRuMmQobjogbnVtYmVyLCBkOiBudW1iZXIsIHM/OiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IHVzZXMgPSB0eXBlb2YgcyAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgICBjb25zdCB4ID0gKG5ldyBBcnJheShuKSkuZmlsbChudWxsKS5tYXAoKCkgPT4gbmV3IEZsb2F0MzJBcnJheShkKSk7XG4gICAgICBpZiAodXNlcykge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKylcbiAgICAgICAgICB4W2ldID0gbmV3IEZsb2F0MzJBcnJheShkKS5maWxsKHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGQ7IGorKylcbiAgICAgICAgICAgIHhbaV1bal0gPSB0aGlzLnJhbmRuKDAuMCwgMWUtNCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB4O1xuICAgIH1cblxuICAgIC8vIGNvbXB1dGUgTDIgZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjdG9yc1xuICAgIHByaXZhdGUgbDIoeDE6IG51bWJlcltdLCB4MjogbnVtYmVyW10pIHtcbiAgICAgIGNvbnN0IEQgPSB4MS5sZW5ndGg7XG4gICAgICBsZXQgZCA9IDA7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEQ7IGkrKykge1xuICAgICAgICBjb25zdCB4MWkgPSB4MVtpXTtcbiAgICAgICAgY29uc3QgeDJpID0geDJbaV07XG4gICAgICAgIGQgKz0gKHgxaSAtIHgyaSkgKiAoeDFpIC0geDJpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkO1xuICAgIH1cblxuICAgIC8vIGNvbXB1dGUgcGFpcndpc2UgZGlzdGFuY2UgaW4gYWxsIHZlY3RvcnMgaW4gWFxuICAgIHByaXZhdGUgeHRvZChYOiBBcnJheTwgQXJyYXk8bnVtYmVyPiA+KSB7XG4gICAgICBjb25zdCBOID0gWC5sZW5ndGg7XG4gICAgICBjb25zdCBkaXN0ID0gdGhpcy56ZXJvcyhOICogTik7IC8vIGFsbG9jYXRlIGNvbnRpZ3VvdXMgYXJyYXlcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IE47IGorKykge1xuICAgICAgICAgIGNvbnN0IGQgPSB0aGlzLmwyKFhbaV0sIFhbal0pO1xuICAgICAgICAgIGRpc3RbaSAqIE4gKyBqXSA9IGQ7XG4gICAgICAgICAgZGlzdFtqICogTiArIGldID0gZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGRpc3Q7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEl0ZXJTaXplKHJvd1NpemU6IG51bWJlcikge1xuICAgICAgaWYgKHJvd1NpemUgPD0gMjAwMClcbiAgICAgICAgcmV0dXJuIDEwMDtcbiAgICAgIGVsc2UgaWYgKHJvd1NpemUgPD0gMzAwMClcbiAgICAgICAgcmV0dXJuIDkwO1xuICAgICAgZWxzZSBpZiAocm93U2l6ZSA8PSA1MDAwKVxuICAgICAgICByZXR1cm4gODA7XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiA3MDtcbiAgICB9XG5cbiAgICAvLyBjb21wdXRlIChwX3tpfGp9ICsgcF97anxpfSkvKDJuKVxuICAgIHByaXZhdGUgZDJwKEQ6IEZsb2F0MzJBcnJheSwgcGVycGxleGl0eTogbnVtYmVyLCB0b2w6IG51bWJlciwgcm93U2l6ZTogbnVtYmVyKSB7XG4gICAgICAvLyBjb25zdCBuZiA9IE1hdGguc3FydChELmxlbmd0aCk7IC8vIHRoaXMgYmV0dGVyIGJlIGFuIGludGVnZXJcbiAgICAgIC8vIGNvbnN0IG4gPSBNYXRoLmZsb29yKG5mKTtcbiAgICAgIC8vIHRoaXMuYXNzZXJ0KG4gPT09IG5mLCAnRCBzaG91bGQgaGF2ZSBzcXVhcmUgbnVtYmVyIG9mIGVsZW1lbnRzLicpO1xuICAgICAgY29uc3QgaW5kZXhlciA9IGRtTGluZWFySW5kZXgocm93U2l6ZSk7XG4gICAgICBjb25zdCBkaXN0YW5jZXMgPSBuZXcgRmxvYXQzMkFycmF5KHJvd1NpemUgKiByb3dTaXplKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93U2l6ZTsgaSsrKSB7XG4gICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJvd1NpemU7IGorKylcbiAgICAgICAgICBkaXN0YW5jZXNbaSAqIHJvd1NpemUgKyBqXSA9IGRpc3RhbmNlc1tqICogcm93U2l6ZSArIGldID0gRFtpbmRleGVyKGksIGopXTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG4gPSByb3dTaXplO1xuICAgICAgY29uc3QgaFRhcmdldCA9IE1hdGgubG9nKHBlcnBsZXhpdHkpOyAvLyB0YXJnZXQgZW50cm9weSBvZiBkaXN0cmlidXRpb25cbiAgICAgIGNvbnN0IFAgPSB0aGlzLnplcm9zKG4gKiBuKTsgLy8gdGVtcG9yYXJ5IHByb2JhYmlsaXR5IG1hdHJpeFxuICAgICAgY29uc3QgcHJvdyA9IHRoaXMuemVyb3Mobik7IC8vIGEgdGVtcG9yYXJ5IHN0b3JhZ2UgY29tcGFydG1lbnRcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIGxldCBiZXRhbWluID0gLUluZmluaXR5O1xuICAgICAgICBsZXQgYmV0YW1heCA9IEluZmluaXR5O1xuICAgICAgICBsZXQgYmV0YSA9IDE7IC8vIGluaXRpYWwgdmFsdWUgb2YgcHJlY2lzaW9uXG4gICAgICAgIGxldCBkb25lID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG1heHRyaWVzID0gTWF0aC5mbG9vcih0aGlzLmdldEl0ZXJTaXplKHJvd1NpemUpIC8gNSk7XG5cbiAgICAgICAgLy8gcGVyZm9ybSBiaW5hcnkgc2VhcmNoIHRvIGZpbmQgYSBzdWl0YWJsZSBwcmVjaXNpb24gYmV0YVxuICAgICAgICAvLyBzbyB0aGF0IHRoZSBlbnRyb3B5IG9mIHRoZSBkaXN0cmlidXRpb24gaXMgYXBwcm9wcmlhdGVcbiAgICAgICAgbGV0IG51bSA9IDA7XG4gICAgICAgIHdoaWxlICghZG9uZSkge1xuICAgICAgICAgIC8vZGVidWdnZXI7XG5cbiAgICAgICAgICAvLyBjb21wdXRlIGVudHJvcHkgYW5kIGtlcm5lbCByb3cgd2l0aCBiZXRhIHByZWNpc2lvblxuICAgICAgICAgIGxldCBwc3VtID0gMC4wO1xuICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSB7XG4gICAgICAgICAgICBjb25zdCBwaiA9IGkgPT09IGogPyAwIDogTWF0aC5leHAoLSBkaXN0YW5jZXNbaSAqIG4gKyBqXSAqIGJldGEpO1xuICAgICAgICAgICAgcHJvd1tqXSA9IHBqO1xuICAgICAgICAgICAgcHN1bSArPSBwajtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gbm9ybWFsaXplIHAgYW5kIGNvbXB1dGUgZW50cm9weVxuICAgICAgICAgIGxldCBuSGVyZSA9IDAuMDtcbiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykge1xuICAgICAgICAgICAgbGV0IHBqO1xuICAgICAgICAgICAgaWYgKHBzdW0gPT09IDApXG4gICAgICAgICAgICAgIHBqID0gMDtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgcGogPSBwcm93W2pdIC8gcHN1bTtcblxuICAgICAgICAgICAgcHJvd1tqXSA9IHBqO1xuICAgICAgICAgICAgaWYgKHBqID4gMWUtNykgbkhlcmUgLT0gcGogKiBNYXRoLmxvZyhwaik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gYWRqdXN0IGJldGEgYmFzZWQgb24gcmVzdWx0XG4gICAgICAgICAgaWYgKG5IZXJlID4gaFRhcmdldCkge1xuICAgICAgICAgICAgLy8gZW50cm9weSB3YXMgdG9vIGhpZ2ggKGRpc3RyaWJ1dGlvbiB0b28gZGlmZnVzZSlcbiAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgdG8gaW5jcmVhc2UgdGhlIHByZWNpc2lvbiBmb3IgbW9yZSBwZWFreSBkaXN0cmlidXRpb25cbiAgICAgICAgICAgIGJldGFtaW4gPSBiZXRhOyAvLyBtb3ZlIHVwIHRoZSBib3VuZHNcbiAgICAgICAgICAgIGlmIChiZXRhbWF4ID09PSBJbmZpbml0eSkgYmV0YSA9IGJldGEgKiAyOyBlbHNlIGJldGEgPSAoYmV0YSArIGJldGFtYXgpIC8gMjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gY29udmVyc2UgY2FzZS4gbWFrZSBkaXN0cnVidGlvbiBsZXNzIHBlYWt5XG4gICAgICAgICAgICBiZXRhbWF4ID0gYmV0YTtcbiAgICAgICAgICAgIGlmIChiZXRhbWluID09PSAtSW5maW5pdHkpIGJldGEgPSBiZXRhIC8gMjsgZWxzZSBiZXRhID0gKGJldGEgKyBiZXRhbWluKSAvIDI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gc3RvcHBpbmcgY29uZGl0aW9uczogdG9vIG1hbnkgdHJpZXMgb3IgZ290IGEgZ29vZCBwcmVjaXNpb25cbiAgICAgICAgICBudW0rKztcbiAgICAgICAgICBpZiAoTWF0aC5hYnMobkhlcmUgLSBoVGFyZ2V0KSA8IHRvbCkgZG9uZSA9IHRydWU7XG4gICAgICAgICAgaWYgKG51bSA+PSBtYXh0cmllcykgZG9uZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjb25zb2xlLmxvZygnZGF0YSBwb2ludCAnICsgaSArICcgZ2V0cyBwcmVjaXNpb24gJyArIGJldGEgKyAnIGFmdGVyICcgKyBudW0gKyAnIGJpbmFyeSBzZWFyY2ggc3RlcHMuJyk7XG4gICAgICAgIC8vIGNvcHkgb3ZlciB0aGUgZmluYWwgcHJvdyB0byBQIGF0IHJvdyBpXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSBQW2kgKiBuICsgal0gPSBwcm93W2pdO1xuICAgICAgfSAvLyBlbmQgbG9vcCBvdmVyIGV4YW1wbGVzIGlcblxuICAgICAgLy8gc3ltbWV0cml6ZSBQIGFuZCBub3JtYWxpemUgaXQgdG8gc3VtIHRvIDEgb3ZlciBhbGwgaWpcbiAgICAgIGNvbnN0IHBPdXQgPSB0aGlzLnplcm9zKG4gKiBuKTtcbiAgICAgIGNvbnN0IE4yID0gbiAqIDI7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKylcbiAgICAgICAgICBwT3V0W2kgKiBuICsgal0gPSBNYXRoLm1heCgoUFtpICogbiArIGpdICsgUFtqICogbiArIGldKSAvIE4yLCAxZS0xMDApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcE91dDtcbiAgICB9XG5cbiAgICAvLyBoZWxwZXIgZnVuY3Rpb25cbiAgICBwcml2YXRlIHNpZ24oeDogbnVtYmVyKSB7IHJldHVybiB4ID4gMCA/IDEgOiB4IDwgMCA/IC0xIDogMDsgfVxuXG4gICAgY29uc3RydWN0b3Iob3B0OiB7W186IHN0cmluZ106IGFueX0pIHtcbiAgICAgIG9wdCA9IG9wdCB8fCB7fTtcbiAgICAgIHRoaXMucGVycGxleGl0eSA9IHRoaXMuZ2V0b3B0KG9wdCwgJ3BlcnBsZXhpdHknLCAzMCk7IC8vIGVmZmVjdGl2ZSBudW1iZXIgb2YgbmVhcmVzdCBuZWlnaGJvcnNcbiAgICAgIHRoaXMuZGltID0gdGhpcy5nZXRvcHQob3B0LCAnZGltJywgMik7IC8vIGJ5IGRlZmF1bHQgMi1EIHRTTkVcbiAgICAgIHRoaXMuZXBzaWxvbiA9IHRoaXMuZ2V0b3B0KG9wdCwgJ2Vwc2lsb24nLCAxMCk7IC8vIGxlYXJuaW5nIHJhdGVcbiAgICAgIHRoaXMucmFuZG9tID0gdGhpcy5nZXRvcHQob3B0LCAncmFuZG9tJywgTWF0aC5yYW5kb20pOyAvLyByYW5kb20gbnVtYmVyIGdlbmVyYXRvclxuICAgIH1cblxuICAgIC8vIHRoaXMgZnVuY3Rpb24gdGFrZXMgYSBzZXQgb2YgaGlnaC1kaW1lbnNpb25hbCBwb2ludHNcbiAgICAvLyBhbmQgY3JlYXRlcyBtYXRyaXggUCBmcm9tIHRoZW0gdXNpbmcgZ2F1c3NpYW4ga2VybmVsXG4gICAgcHVibGljIGluaXREYXRhUmF3KFg6IEFycmF5PEFycmF5PGFueT4+KSB7XG4gICAgICBjb25zdCBOID0gWC5sZW5ndGg7XG4gICAgICBjb25zdCBEID0gWFswXS5sZW5ndGg7XG4gICAgICB0aGlzLmFzc2VydChOID4gMCwgJyBYIGlzIGVtcHR5PyBZb3UgbXVzdCBoYXZlIHNvbWUgZGF0YSEnKTtcbiAgICAgIHRoaXMuYXNzZXJ0KEQgPiAwLCAnIFhbMF0gaXMgZW1wdHk/IFdoZXJlIGlzIHRoZSBkYXRhPycpO1xuICAgICAgY29uc3QgZGlzdHMgPSB0aGlzLnh0b2QoWCk7IC8vIGNvbnZlcnQgWCB0byBkaXN0YW5jZXMgdXNpbmcgZ2F1c3NpYW4ga2VybmVsXG4gICAgICB0aGlzLlAgPSB0aGlzLmQycChkaXN0cywgdGhpcy5wZXJwbGV4aXR5LCAxZS00LCBEKTsgLy8gYXR0YWNoIHRvIG9iamVjdFxuICAgICAgdGhpcy5OID0gTjsgLy8gYmFjayB1cCB0aGUgc2l6ZSBvZiB0aGUgZGF0YXNldFxuICAgICAgdGhpcy5pbml0U29sdXRpb24oKTsgLy8gcmVmcmVzaCB0aGlzXG4gICAgfVxuXG4gICAgLy8gdGhpcyBmdW5jdGlvbiB0YWtlcyBhIGdpdmVuIGRpc3RhbmNlIG1hdHJpeCBhbmQgY3JlYXRlc1xuICAgIC8vIG1hdHJpeCBQIGZyb20gdGhlbS5cbiAgICAvLyBEIGlzIGFzc3VtZWQgdG8gYmUgcHJvdmlkZWQgYXMgYSBsaXN0IG9mIGxpc3RzLCBhbmQgc2hvdWxkIGJlIHN5bW1ldHJpY1xuICAgIHB1YmxpYyBpbml0RGF0YURpc3QoRDogRmxvYXQzMkFycmF5LCByb3dTaXplOiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IE4gPSBELmxlbmd0aDtcbiAgICAgIHRoaXMuYXNzZXJ0KE4gPiAwLCAnIFggaXMgZW1wdHk/IFlvdSBtdXN0IGhhdmUgc29tZSBkYXRhIScpO1xuICAgICAgLy8gY29udmVydCBEIHRvIGEgKGZhc3QpIHR5cGVkIGFycmF5IHZlcnNpb25cbiAgICAgIC8vIGRpc3RzLmZvckVhY2goKGQpID0+IGNvbnNvbGUubG9nKGQpKTtcbiAgICAgIGNvbnNvbGUudGltZSgnZGlzdGFuY2VzIHRvIG1hdHJpeCcpO1xuICAgICAgdGhpcy5QID0gdGhpcy5kMnAoRCwgdGhpcy5wZXJwbGV4aXR5LCAxZS00LCByb3dTaXplKTtcbiAgICAgIGNvbnNvbGUudGltZUVuZCgnZGlzdGFuY2VzIHRvIG1hdHJpeCcpO1xuICAgICAgdGhpcy5OID0gcm93U2l6ZTtcbiAgICAgIHRoaXMuaW5pdFNvbHV0aW9uKCk7IC8vIHJlZnJlc2ggdGhpc1xuICAgIH1cblxuICAgIC8vIChyZSlpbml0aWFsaXplcyB0aGUgc29sdXRpb24gdG8gcmFuZG9tXG4gICAgcHVibGljIGluaXRTb2x1dGlvbigpIHtcbiAgICAgIC8vIGdlbmVyYXRlIHJhbmRvbSBzb2x1dGlvbiB0byB0LVNORVxuICAgICAgdGhpcy5ZID0gdGhpcy5yYW5kbjJkKHRoaXMuTiwgdGhpcy5kaW0pOyAvLyB0aGUgc29sdXRpb25cbiAgICAgIHRoaXMuZ2FpbnMgPSB0aGlzLnJhbmRuMmQodGhpcy5OLCB0aGlzLmRpbSwgMS4wKTsgLy8gc3RlcCBnYWlucyB0byBhY2NlbGVyYXRlIHByb2dyZXNzIGluIHVuY2hhbmdpbmcgZGlyZWN0aW9uc1xuICAgICAgdGhpcy55c3RlcCA9IHRoaXMucmFuZG4yZCh0aGlzLk4sIHRoaXMuZGltLCAwLjApOyAvLyBtb21lbnR1bSBhY2N1bXVsYXRvclxuICAgICAgdGhpcy5pdGVyID0gMDtcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gcG9pbnRlciB0byBjdXJyZW50IHNvbHV0aW9uXG4gICAgcHVibGljIGdldFNvbHV0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuWTtcbiAgICB9XG5cbiAgICAvLyBwZXJmb3JtIGEgc2luZ2xlIHN0ZXAgb2Ygb3B0aW1pemF0aW9uIHRvIGltcHJvdmUgdGhlIGVtYmVkZGluZ1xuICAgIHB1YmxpYyBzdGVwKCkge1xuICAgICAgdGhpcy5pdGVyICs9IDE7XG4gICAgICBjb25zdCBOID0gdGhpcy5OO1xuICAgICAgY29uc3QgY2cgPSB0aGlzLmNvc3RHcmFkKHRoaXMuWSk7IC8vIGV2YWx1YXRlIGdyYWRpZW50XG4gICAgICBjb25zdCBjb3N0ID0gY2cuY29zdDtcbiAgICAgIGNvbnN0IGdyYWQgPSBjZy5ncmFkO1xuXG4gICAgICAvLyBwZXJmb3JtIGdyYWRpZW50IHN0ZXBcbiAgICAgIGNvbnN0IHltZWFuID0gdGhpcy56ZXJvcyh0aGlzLmRpbSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgICBmb3IgKGxldCBkID0gMDsgZCA8IHRoaXMuZGltOyBkKyspIHtcbiAgICAgICAgICBjb25zdCBnaWQgPSBncmFkW2ldW2RdO1xuICAgICAgICAgIGNvbnN0IHNpZCA9IHRoaXMueXN0ZXBbaV1bZF07XG4gICAgICAgICAgY29uc3QgZ2FpbmlkID0gdGhpcy5nYWluc1tpXVtkXTtcblxuICAgICAgICAgIC8vIGNvbXB1dGUgZ2FpbiB1cGRhdGVcbiAgICAgICAgICBsZXQgbmV3Z2FpbiA9IHRoaXMuc2lnbihnaWQpID09PSB0aGlzLnNpZ24oc2lkKSA/IGdhaW5pZCAqIDAuOCA6IGdhaW5pZCArIDAuMjtcbiAgICAgICAgICBpZiAobmV3Z2FpbiA8IDAuMDEpIG5ld2dhaW4gPSAwLjAxOyAvLyBjbGFtcFxuICAgICAgICAgIHRoaXMuZ2FpbnNbaV1bZF0gPSBuZXdnYWluOyAvLyBzdG9yZSBmb3IgbmV4dCB0dXJuXG5cbiAgICAgICAgICAvLyBjb21wdXRlIG1vbWVudHVtIHN0ZXAgZGlyZWN0aW9uXG4gICAgICAgICAgY29uc3QgbW9tdmFsID0gdGhpcy5pdGVyIDwgMjUwID8gMC41IDogMC44O1xuICAgICAgICAgIGNvbnN0IG5ld3NpZCA9IG1vbXZhbCAqIHNpZCAtIHRoaXMuZXBzaWxvbiAqIG5ld2dhaW4gKiBncmFkW2ldW2RdO1xuICAgICAgICAgIHRoaXMueXN0ZXBbaV1bZF0gPSBuZXdzaWQ7IC8vIHJlbWVtYmVyIHRoZSBzdGVwIHdlIHRvb2tcblxuICAgICAgICAgIC8vIHN0ZXAhXG4gICAgICAgICAgdGhpcy5ZW2ldW2RdICs9IG5ld3NpZDtcblxuICAgICAgICAgIHltZWFuW2RdICs9IHRoaXMuWVtpXVtkXTsgLy8gYWNjdW11bGF0ZSBtZWFuIHNvIHRoYXQgd2UgY2FuIGNlbnRlciBsYXRlclxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHJlcHJvamVjdCBZIHRvIGJlIHplcm8gbWVhblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCB0aGlzLmRpbTsgZCsrKVxuICAgICAgICAgIHRoaXMuWVtpXVtkXSAtPSB5bWVhbltkXSAvIE47XG4gICAgICB9XG5cbiAgICAgIC8vaWYodGhpcy5pdGVyJTEwMD09PTApIGNvbnNvbGUubG9nKCdpdGVyICcgKyB0aGlzLml0ZXIgKyAnLCBjb3N0OiAnICsgY29zdCk7XG4gICAgICByZXR1cm4gY29zdDsgLy8gcmV0dXJuIGN1cnJlbnQgY29zdFxuICAgIH1cblxuICAgIC8vIGZvciBkZWJ1Z2dpbmc6IGdyYWRpZW50IGNoZWNrXG4gICAgcHVibGljIGRlYnVnR3JhZCgpIHtcbiAgICAgIGNvbnN0IE4gPSB0aGlzLk47XG5cbiAgICAgIGNvbnN0IGNnID0gdGhpcy5jb3N0R3JhZCh0aGlzLlkpOyAvLyBldmFsdWF0ZSBncmFkaWVudFxuICAgICAgLy9jb25zdCBjb3N0ID0gY2cuY29zdDtcbiAgICAgIGNvbnN0IGdyYWQgPSBjZy5ncmFkO1xuXG4gICAgICBjb25zdCBlID0gMWUtNTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgdGhpcy5kaW07IGQrKykge1xuICAgICAgICAgIGNvbnN0IHlvbGQgPSB0aGlzLllbaV1bZF07XG5cbiAgICAgICAgICB0aGlzLllbaV1bZF0gPSB5b2xkICsgZTtcbiAgICAgICAgICBjb25zdCBjZzAgPSB0aGlzLmNvc3RHcmFkKHRoaXMuWSk7XG5cbiAgICAgICAgICB0aGlzLllbaV1bZF0gPSB5b2xkIC0gZTtcbiAgICAgICAgICBjb25zdCBjZzEgPSB0aGlzLmNvc3RHcmFkKHRoaXMuWSk7XG5cbiAgICAgICAgICBjb25zdCBhbmFseXRpYyA9IGdyYWRbaV1bZF07XG4gICAgICAgICAgY29uc3QgbnVtZXJpY2FsID0gKGNnMC5jb3N0IC0gY2cxLmNvc3QpIC8gKDIgKiBlKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhpICsgJywnICsgZCArICc6IGdyYWRjaGVjayBhbmFseXRpYzogJyArIGFuYWx5dGljICsgJyB2cy4gbnVtZXJpY2FsOiAnICsgbnVtZXJpY2FsKTtcblxuICAgICAgICAgIHRoaXMuWVtpXVtkXSA9IHlvbGQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHF1QXJyPzogRmxvYXQzMkFycmF5O1xuICAgIC8vIHJldHVybiBjb3N0IGFuZCBncmFkaWVudCwgZ2l2ZW4gYW4gYXJyYW5nZW1lbnRcbiAgICBwdWJsaWMgY29zdEdyYWQoWTogbnVtYmVyW11bXSkge1xuICAgICAgY29uc3QgTiA9IHRoaXMuTjtcbiAgICAgIGNvbnN0IGRpbSA9IHRoaXMuZGltOyAvLyBkaW0gb2Ygb3V0cHV0IHNwYWNlXG4gICAgICBjb25zdCBQID0gdGhpcy5QO1xuXG4gICAgICBjb25zdCBwbXVsID0gdGhpcy5pdGVyIDwgMTAwID8gNCA6IDE7IC8vIHRyaWNrIHRoYXQgaGVscHMgd2l0aCBsb2NhbCBvcHRpbWFcblxuICAgICAgLy8gY29tcHV0ZSBjdXJyZW50IFEgZGlzdHJpYnV0aW9uLCB1bm5vcm1hbGl6ZWQgZmlyc3RcbiAgICAgIHRoaXMucXVBcnIgPz89IHRoaXMuemVyb3MoTiAqIE4pO1xuICAgICAgbGV0IHFzdW0gPSAwLjA7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBOOyBqKyspIHtcbiAgICAgICAgICBjb25zdCBkc3VtID0gbmV3IEFycmF5KGRpbSkucmVkdWNlKChwcmV2LCBfLCBkKSA9PiBwcmV2ICsgTWF0aC5wb3coWVtpXVtkXSAtIFlbal1bZF0sIDIpLCAwKTtcbiAgICAgICAgICBjb25zdCBxdSA9IDEuMCAvICgxLjAgKyBkc3VtKTsgLy8gU3R1ZGVudCB0LWRpc3RyaWJ1dGlvblxuICAgICAgICAgIHRoaXMucXVBcnJbaSAqIE4gKyBqXSA9IHF1O1xuICAgICAgICAgIHRoaXMucXVBcnJbaiAqIE4gKyBpXSA9IHF1O1xuICAgICAgICAgIHFzdW0gKz0gMiAqIHF1O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBub3JtYWxpemUgUSBkaXN0cmlidXRpb24gdG8gc3VtIHRvIDFcbiAgICAgIC8vY29uc3QgTk4gPSBOICogTjtcbiAgICAgIC8vY29uc3QgUSA9IHRoaXMuemVyb3MoTk4pO1xuICAgICAgbGV0IGNvc3QgPSAwLjA7XG4gICAgICBjb25zdCBncmFkID0gbmV3IEFycmF5KE4pLmZpbGwobnVsbCkubWFwKCgpID0+IChuZXcgRmxvYXQzMkFycmF5KGRpbSkpLmZpbGwoMC4wKSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgICAvLyBjb25zdCBnc3VtID0gbmV3IEZsb2F0MzJBcnJheShkaW0pLmZpbGwoMC4wKTsgLy8gaW5pdCBncmFkIGZvciBwb2ludCBpXG4gICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IE47IGorKykge1xuICAgICAgICAgIGNvbnN0IFEgPSBNYXRoLm1heCh0aGlzLnF1QXJyW2kgKiBOICsgal0gLyBxc3VtLCAxZS0xMDApO1xuICAgICAgICAgIGNvc3QgKz0gKC0gUFtpICogTiArIGpdICogTWF0aC5sb2coUSkpICogMjsgLy8gYWNjdW11bGF0ZSBjb3N0ICh0aGUgbm9uLWNvbnN0YW50IHBvcnRpb24gYXQgbGVhc3QuLi4pXG4gICAgICAgICAgY29uc3QgcHJlbXVsdCA9IDQgKiAocG11bCAqIFBbaSAqIE4gKyBqXSAtIFEpICogdGhpcy5xdUFycltpICogTiArIGpdO1xuICAgICAgICAgIC8vY29uc29sZS5sb2cocHJlbXVsdCwgUSwgaSwgaik7XG4gICAgICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCBkaW07IGQrKykge1xuICAgICAgICAgICAgZ3JhZFtpXVtkXSArPSBwcmVtdWx0ICogKFlbaV1bZF0gLSBZW2pdW2RdKTtcbiAgICAgICAgICAgIGdyYWRbal1bZF0gKz0gcHJlbXVsdCAqIChZW2pdW2RdIC0gWVtpXVtkXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vZ3JhZFtpXSA9IGdzdW07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7Y29zdCwgZ3JhZH07XG4gICAgfVxufVxuIl19","/** Proxy for DistanceMatrix class. Allows to index matrix as matrix[i][j]\n * Note: much slower than direct indexing, but still much faster than recalculating distances.\n * will be used for T-SNE mainly.\n * @param {Float32Array}condensedArray - array of distances between all pairs of objects\n * @param {number}size - number of comparebles in matrix\n * @return {Float32Array} - proxy for condensedArray\n*/\nexport function distanceMatrixProxy(condensedArray, size) {\n const linearFunc = dmLinearIndex(size);\n function linearIndex(i, j) {\n const iNum = Number(i);\n const jNum = Number(j);\n return linearFunc(iNum, jNum);\n }\n function idx2Handler(idx1) {\n return ({\n get(target, idx2, _receiver) {\n if (idx1 === idx2)\n return 0;\n const linearIdx = Number(idx1) > Number(idx2) ? linearIndex(idx2, idx1) : linearIndex(idx1, idx2);\n return target[linearIdx];\n },\n });\n }\n const idx1Handler = {\n get(target, idx1, _receiver) {\n if (idx1 === 'length')\n return size;\n return new Proxy(target, idx2Handler(idx1));\n },\n };\n return new Proxy(condensedArray, idx1Handler);\n}\nexport function dmLinearIndex(size) {\n return (i, j) => size * i + j - Math.floor(((i + 2) * (i + 1)) / 2);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7O0VBTUU7QUFDRixNQUFNLFVBQVUsbUJBQW1CLENBQUMsY0FBNEIsRUFBRSxJQUFZO0lBQzVFLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxTQUFTLFdBQVcsQ0FBQyxDQUFrQixFQUFFLENBQWtCO1FBQ3pELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsT0FBTyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxTQUFTLFdBQVcsQ0FBQyxJQUFxQjtRQUN4QyxPQUFPLENBQ0w7WUFDRSxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTO2dCQUN6QixJQUFJLElBQUksS0FBSyxJQUFJO29CQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUM1QixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNsRyxPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMzQixDQUFDO1NBQ0YsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sV0FBVyxHQUErQjtRQUM5QyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTO1lBQ3pCLElBQUksSUFBSSxLQUFLLFFBQVE7Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFDbkMsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDOUMsQ0FBQztLQUNGLENBQUM7SUFFRixPQUFPLElBQUksS0FBSyxDQUFDLGNBQWMsRUFBRSxXQUFXLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFZO0lBQ3hDLE9BQU8sQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN0RixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXG5cbi8qKiBQcm94eSBmb3IgRGlzdGFuY2VNYXRyaXggY2xhc3MuIEFsbG93cyB0byBpbmRleCBtYXRyaXggYXMgbWF0cml4W2ldW2pdXG4gKiBOb3RlOiBtdWNoIHNsb3dlciB0aGFuIGRpcmVjdCBpbmRleGluZywgYnV0IHN0aWxsIG11Y2ggZmFzdGVyIHRoYW4gcmVjYWxjdWxhdGluZyBkaXN0YW5jZXMuXG4gKiB3aWxsIGJlIHVzZWQgZm9yIFQtU05FIG1haW5seS5cbiAqIEBwYXJhbSB7RmxvYXQzMkFycmF5fWNvbmRlbnNlZEFycmF5IC0gYXJyYXkgb2YgZGlzdGFuY2VzIGJldHdlZW4gYWxsIHBhaXJzIG9mIG9iamVjdHNcbiAqIEBwYXJhbSB7bnVtYmVyfXNpemUgLSBudW1iZXIgb2YgY29tcGFyZWJsZXMgaW4gbWF0cml4XG4gKiBAcmV0dXJuIHtGbG9hdDMyQXJyYXl9IC0gcHJveHkgZm9yIGNvbmRlbnNlZEFycmF5XG4qL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlTWF0cml4UHJveHkoY29uZGVuc2VkQXJyYXk6IEZsb2F0MzJBcnJheSwgc2l6ZTogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgY29uc3QgbGluZWFyRnVuYyA9IGRtTGluZWFySW5kZXgoc2l6ZSk7XG4gIGZ1bmN0aW9uIGxpbmVhckluZGV4KGk6IHN5bWJvbCB8IHN0cmluZywgajogc3ltYm9sIHwgc3RyaW5nKSB7XG4gICAgY29uc3QgaU51bSA9IE51bWJlcihpKTtcbiAgICBjb25zdCBqTnVtID0gTnVtYmVyKGopO1xuICAgIHJldHVybiBsaW5lYXJGdW5jKGlOdW0sIGpOdW0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaWR4MkhhbmRsZXIoaWR4MTogc3ltYm9sIHwgc3RyaW5nKTpQcm94eUhhbmRsZXI8RmxvYXQzMkFycmF5PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHtcbiAgICAgICAgZ2V0KHRhcmdldCwgaWR4MiwgX3JlY2VpdmVyKSB7XG4gICAgICAgICAgaWYgKGlkeDEgPT09IGlkeDIpIHJldHVybiAwO1xuICAgICAgICAgIGNvbnN0IGxpbmVhcklkeCA9IE51bWJlcihpZHgxKSA+IE51bWJlcihpZHgyKSA/IGxpbmVhckluZGV4KGlkeDIsIGlkeDEpIDogbGluZWFySW5kZXgoaWR4MSwgaWR4Mik7XG4gICAgICAgICAgcmV0dXJuIHRhcmdldFtsaW5lYXJJZHhdO1xuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG4gIH1cbiAgY29uc3QgaWR4MUhhbmRsZXI6IFByb3h5SGFuZGxlcjxGbG9hdDMyQXJyYXk+ID0ge1xuICAgIGdldCh0YXJnZXQsIGlkeDEsIF9yZWNlaXZlcikge1xuICAgICAgaWYgKGlkeDEgPT09ICdsZW5ndGgnKSByZXR1cm4gc2l6ZTtcbiAgICAgIHJldHVybiBuZXcgUHJveHkodGFyZ2V0LCBpZHgySGFuZGxlcihpZHgxKSk7XG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gbmV3IFByb3h5KGNvbmRlbnNlZEFycmF5LCBpZHgxSGFuZGxlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkbUxpbmVhckluZGV4KHNpemU6IG51bWJlcik6IChpOiBudW1iZXIsIGo6IG51bWJlcikgPT4gbnVtYmVyIHtcbiAgcmV0dXJuIChpOiBudW1iZXIsIGo6IG51bWJlcikgPT4gc2l6ZSAqIGkgKyBqIC0gTWF0aC5mbG9vcigoKGkgKyAyKSAqIChpICsgMSkpIC8gMik7XG59XG4iXX0=","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};\nlet gpuAdapter = null;\nlet gpuDevice = null;\nexport function getGPUDevice() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!navigator.gpu) {\n console.error('WebGPU is not supported in this browser');\n return null;\n }\n if (!gpuAdapter) {\n //reason: only here we get the gpuAdapter\n // eslint-disable-next-line no-restricted-syntax\n gpuAdapter = yield navigator.gpu.requestAdapter({ powerPreference: 'high-performance' });\n if (gpuAdapter == null)\n return null;\n }\n let isLost = false;\n if (gpuDevice) {\n gpuDevice.lost.then(() => {\n isLost = true;\n });\n yield new Promise((r) => setTimeout(r, 10)); // wait to see if the device is lost\n }\n if (!gpuDevice || isLost) {\n const requiredBufferSize = 1000000000; // ~1000MB\n const adapterLimits = gpuAdapter.limits;\n const buffferSizeLimit = adapterLimits.maxBufferSize;\n const storageBufferSizeLimit = adapterLimits.maxStorageBufferBindingSize;\n try {\n gpuDevice = yield gpuAdapter.requestDevice({ requiredLimits: {\n maxBufferSize: Math.min(buffferSizeLimit, requiredBufferSize),\n maxStorageBufferBindingSize: Math.min(storageBufferSizeLimit, requiredBufferSize)\n } });\n return gpuDevice;\n }\n catch (e) {\n console.error('Failed to create device with required limits', e);\n gpuDevice = yield gpuAdapter.requestDevice();\n return gpuDevice;\n }\n }\n return gpuDevice;\n });\n}\nexport function getGPUAdapterDescription() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!navigator.gpu) {\n console.error('WebGPU is not supported in this browser');\n return null;\n }\n if (!gpuAdapter) {\n // reason: only here we get the gpuAdapter\n // eslint-disable-next-line no-restricted-syntax\n gpuAdapter = yield navigator.gpu.requestAdapter();\n if (gpuAdapter == null)\n return null;\n }\n let info = null;\n if ('info' in gpuAdapter)\n info = gpuAdapter.info;\n // this option is sort of deprecated but still available in every initial release\n else if ('requestAdapterInfo' in gpuAdapter && typeof gpuAdapter.requestAdapterInfo === 'function')\n info = (yield gpuAdapter.requestAdapterInfo());\n if (!info)\n return null;\n const outString = replaceEmptyString(info.description, replaceEmptyString(info.vendor, 'No GPU description available'));\n return outString;\n });\n}\nfunction replaceEmptyString(str, replacement) {\n return !str || str == '' ? replacement : str;\n}\n//# sourceMappingURL=getGPUDevice.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 / 30),\n [WEBGPUDISTANCE.SOKAL]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.COSINE]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.ASYMMETRIC]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\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","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/* eslint-disable max-len */\nimport { getGPUDevice } from '../getGPUDevice';\nimport { WEBGSLAGGREGATION, WEBGSLAGGREGATIONFUNCTIONS } from '../multi-col-distances/webGPU-aggregation';\nimport { WEBGPUDISTANCE, webGPUFunctions } from '../multi-col-distances/webGPU-multicol-distances';\nimport { webGPUProcessInfo } from '../preprocessing/webGPU-process-info';\n/** generate KNN based on list of lists of entries.\n * these entries are each encoded as Uint32Array or FLOAT32Array (depending on their type).\n * for example, sequences would be encoded as Uint32Array based on char code of the letter at each position.\n * [65, 66, 67, 68, 69] would be a sequence of 5 letters.\n * for chemical fingerprints, it would be a binary array of 0s and 1s,\n * represented as Uint32Array(_data property of DG bitarray).\n *\n * Be ware that size of entryList, distanceMetrics, weights and options must be the same.\n * if there are no options for entries i, pass an empty object.\n * for now options are needed for:\n * needleman-wunsch and monomer chemical distances: see {@link BioDistanceFnOptions} as for how it should be passed\n * numeric distances (Difference): {range: number} where range is the range of the values in the column (max - min).\n * in both cases, if options are not provided, they will be calculated automatically.\n */\nexport function multiColWebGPUKNN(entryList, // list of lists of entries, for multiple columns\nknnSize = 15, // size of the k-nearest neighbors\ndistanceMetrics, // distance metrics for each column\naggregationFunction, // aggregation function for the distances\nweights, // weights for each column\noptions // supplementary options for each column\n) {\n return __awaiter(this, void 0, void 0, function* () {\n // first, check that all the supplementary options are provided and are the same length:\n if (options.length !== entryList.length ||\n options.length !== distanceMetrics.length || options.length !== weights.length)\n throw new Error('Options, weigths and distance functions must be provided for each column');\n // check that all the entry lists are the same length\n if (entryList.some((list) => list.length !== entryList[0].length))\n throw new Error('All entry lists must be the same length');\n const availableDistanceMetrics = Object.values(WEBGPUDISTANCE);\n if (distanceMetrics.some((metric) => !availableDistanceMetrics.includes(metric)))\n throw new Error('Invalid distance metrics provided: ' + distanceMetrics.join(', '));\n const availableAggregationFunctions = Object.values(WEBGSLAGGREGATION);\n if (!availableAggregationFunctions.includes(aggregationFunction))\n throw new Error('Invalid aggregation function provided: ' + aggregationFunction);\n const numOfColumns = entryList.length; // number of columns\n if (numOfColumns === 0)\n throw new Error('No columns provided. Please provide at least one column of data.');\n const device = yield getGPUDevice();\n if (!device)\n return null;\n // device may be lost\n let deviceLost = false;\n device.lost.then(() => {\n deviceLost = true;\n });\n const listSize = entryList[0].length; // size of each list (or column)\n const processInfo = entryList.map((entry, i) => {\n return webGPUProcessInfo(entry, distanceMetrics[i], i, options[i]);\n });\n if (numOfColumns === 1)\n aggregationFunction = WEBGSLAGGREGATION.MANHATTAN; // save a bit of time\n // combine all struct types into one to put into the suppInfo struct.\n let suppInfoWgsl = processInfo.map((info) => info.suppInfoStructWgsl)\n .filter((wgsl) => !!wgsl && wgsl != '').join(',\\n');\n // structures in wgsl must have at least one member, so if we have no structures, we need to add a dummy one\n let needsDummy = false;\n if (!suppInfoWgsl || suppInfoWgsl.trim() == '') {\n needsDummy = true;\n suppInfoWgsl = '\\ndummy: f32\\n';\n }\n // combine all complexities into one\n const combinedComplexity = processInfo.reduce((a, b) => a + b.complexity, 0);\n // combine all data wgsl struct code into one\n const dataWgsl = processInfo.map((info) => info.dataStructWgsl).filter((wgsl) => !!wgsl && wgsl != '').join(',\\n');\n // combine all array sizes into one array (easier for setting)\n const arraySizes = new Uint32Array(numOfColumns * listSize);\n processInfo.forEach((info, i) => {\n arraySizes.set(info.arraySizes, i * listSize);\n }); // array.flat is not as optimized as this\n // if we try to map large knn directly from GPU, sometimes, device disconnects. so we need to do it in chunks, a good number\n // we found is 10000. So we will perform computations in chunks of 10000.\n const computationsPerPass = 10000;\n // also, as the computation per thread takes some time, we also need to divide the work into smaller chunks. meaning\n // that we will divide nummper of pair computations per pass. start and end of the pair comparisons will be stored in startAtEndAt buffer (vec4<u32>) as z and w coordinates.\n const pairComparisonsPerPass = Math.ceil(10000 / combinedComplexity);\n const workGroupDivision = 10; // how many threads inside of one workgroup dimension (in this case 10 * 10 threads per workgroup)\n const threadsPerWorkgroup = workGroupDivision * workGroupDivision;\n const workgroupsDim = Math.ceil(Math.sqrt(Math.ceil(computationsPerPass / threadsPerWorkgroup))); // how many workgroups per 2d dimension\n const globalThreadDimSize = workgroupsDim * workGroupDivision; // how many threads per 2d dimension\n // console.log(getCombinedDistanceScript(distanceMetrics, processInfo.map((info) => info.maxEntryLen), knnSize, aggregationFunction));\n // return;\n const resultIndexes = new Array(listSize)\n .fill(null)\n .map(() => new Uint32Array(knnSize));\n const resultDistances = new Array(listSize)\n .fill(null)\n .map(() => new Float32Array(knnSize));\n const module = device.createShaderModule({\n label: 'KNN compute shader',\n code: `\n // this struct will contain all the info about the computation, startAtEndAt will contain the start and end of the knnDistances and knnIndexes.\n // array of sizes for each entries, and the main data as arrays of arrays called data0, data1 and so on. good thing is that because the first entry is vec4<u32>,\n // there will be no paddings, so no need to worry about padding data. also, arrays and matrices get stucked together, so no padding there as well.\n // what we need to worry about is the padding of overall struct. the size of overall struct will be factor of 16 bytes, so keep that in mind.\n struct ComputeInfo {\n // the x coordinate will contain the start index of the knnDistances and knnIndexes, while y will contain the end index \n // the z coordinate will contain the start of the pair comparisons, while w will contain the end of the pair comparisons\n // just keep in mind that this vec4 will be in first 16 bytes of corresponding buffer.\n startAtEndAt: vec4<u32>,\n // the ACTUALLY sizes of each entry\n entrySizes: array<array<u32, ${listSize}>, ${numOfColumns}>,\n // the weights for each entry\n weights: array<f32, ${numOfColumns}>,\n // the data for each entry\n ${dataWgsl} // an example of the dataWgsl would be:\n //data0: array<array<u32,20>,100>,\n //data1: array<array<u32,20>,100>\n };\n\n struct SuppInfo {\n // struct containing all the supplementary info, like scoring matrix, alphabet indexes, range, etc.\n ${suppInfoWgsl}\n };\n \n @group(0) @binding(0) var<storage, read_write> knnIndexes: array<array<u32, ${knnSize}>, ${computationsPerPass}>;\n @group(0) @binding(1) var<storage, read_write> knnDistances: array<array<f32, ${knnSize}>, ${computationsPerPass}>; // each time just compute for a subset of the list\n @group(0) @binding(2) var<storage, read_write> computeInfo: ComputeInfo;\n @group(0) @binding(3) var<storage, read_write> suppInfo: SuppInfo;\n \n @compute @workgroup_size(${workGroupDivision}, ${workGroupDivision}) fn calcKNN(\n @builtin(global_invocation_id) id: vec3<u32>\n ) {\n ${needsDummy ? `let otherDummy = suppInfo.dummy * 2;` : ''} // just to make sure that the suppInfo is not optimized out\n let col = id.x; //* ${workGroupDivision} + localId.x;\n let row = id.y; //* ${workGroupDivision} + localId.y;\n let graphIndex = row * ${globalThreadDimSize} + col;\n let index = graphIndex + computeInfo.startAtEndAt.x; // add the starting index of the knnDistances and knnIndexes\n \n if (index >= min(${listSize}u, computeInfo.startAtEndAt.y)) {return;}\n \n let pairComparisonStartAt = computeInfo.startAtEndAt.z;\n let pairComparisonEndAt = min(computeInfo.startAtEndAt.w, ${listSize}u);\n \n \n // only clear the knnDistances and knnIndexes if we are at the start of the pair comparison\n if (pairComparisonStartAt == 0u) {\n for (var i = 0u; i < ${knnSize}; i = i + 1u) {\n knnDistances[graphIndex][i] = 99999.0;\n knnIndexes[graphIndex][i] = 0u;\n }\n }\n \n for (var i: u32 = pairComparisonStartAt; i < pairComparisonEndAt; i = i + 1u) {\n if (i == index) {continue;}\n let dist = combinedDistance(index, i);\n insertKnn(graphIndex, dist, i);\n }\n \n }\n // this will generate the distance script for each distance metric and then combine them into one\n ${getCombinedDistanceScript(distanceMetrics, processInfo.map((info) => info.maxEntryLen), knnSize, aggregationFunction)}\n \n fn insertKnn(knnIndex: u32, dist: f32, index: u32) {\n // small optimization, if the distance is larger than the last element in the knnDistances, we can skip\n if (dist >= knnDistances[knnIndex][${knnSize} - 1u]) {return;}\n for (var i = 0u; i < ${knnSize}; i = i + 1u) {\n if (dist < knnDistances[knnIndex][i]) {\n for (var j = ${knnSize} - 1u; j > i; j = j - 1u) {\n knnDistances[knnIndex][j] = knnDistances[knnIndex][j - 1u];\n knnIndexes[knnIndex][j] = knnIndexes[knnIndex][j - 1u];\n }\n knnDistances[knnIndex][i] = dist;\n knnIndexes[knnIndex][i] = index;\n return;\n }\n }\n }\n `,\n });\n const pipeline = device.createComputePipeline({\n label: 'hamming compute pipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'calcKNN',\n },\n });\n // calculate the size of computeInfo struct buffer in terms of 32bit values\n // startAtEndAt=4, entrySizes, weights, data0 + data1 + ...\n const computeInfo32Size = 4 + numOfColumns * listSize + numOfColumns + processInfo.reduce((a, b) => a + b.sourceArraySize, 0);\n // calculate the size of suppInfo struct buffer in terms of 32bit values\n const suppInfo32Size = processInfo.reduce((a, b) => a + b.suppInfoSize, 0);\n // create a buffer on the GPU to hold computeInfo\n // beware that struct must be padded to 16 bytes, so we need to calculate the size of the struct in 32bit values\n const computeInfoBufferSize = computeInfo32Size * Uint32Array.BYTES_PER_ELEMENT;\n let paddedComputeInfoBufferSize = computeInfoBufferSize;\n const remainder = computeInfoBufferSize & 15; // check if the size is a multiple of 16\n if (remainder !== 0)\n paddedComputeInfoBufferSize += 16 - remainder; // pad the size accordingly\n const computeInfoBuffer = device.createBuffer({\n label: 'compute info buffer',\n size: paddedComputeInfoBufferSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedComputeInfoArrayBuffer = computeInfoBuffer.getMappedRange(); // get full buffer\n // create vars to hold startAtEndAt\n let startAt = 0;\n let endAt = computationsPerPass;\n let pairComparisonStartAt = 0;\n let pairComparisonEndAt = pairComparisonsPerPass;\n const startAtEndAtSize = 4;\n // copy the data into the buffer at correct places\n let computeInfoOffSet = 0;\n const startAtEndAtView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, startAtEndAtSize); //new Uint32Array(computeInfoBuffer.getMappedRange(computeInfoOffSet, 4 * Uint32Array.BYTES_PER_ELEMENT));\n startAtEndAtView.set([startAt, endAt, pairComparisonStartAt, pairComparisonEndAt]);\n // write entry sizes\n computeInfoOffSet += startAtEndAtSize * Uint32Array.BYTES_PER_ELEMENT;\n const entrySizesView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, arraySizes.length); //new Uint32Array(computeInfoBuffer.getMappedRange(computeInfoOffSet, arraySizes.byteLength));\n entrySizesView.set(arraySizes);\n // write weights\n computeInfoOffSet += arraySizes.byteLength; // arraySizes.length * Uint32Array.BYTES_PER_ELEMENT;\n const weightsView = new Float32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, numOfColumns); //new Float32Array(computeInfoBuffer.getMappedRange(computeInfoOffSet, numOfColumns * Float32Array.BYTES_PER_ELEMENT));\n weightsView.set(weights);\n // write data\n computeInfoOffSet += numOfColumns * Float32Array.BYTES_PER_ELEMENT;\n for (const info of processInfo) {\n //device.queue.writeBuffer(computeInfoBuffer, computeInfoOffSet, info.flatSourceArray, 0, chunkByteSize);\n const ArrayConstructor = info.EncodedArrayConstructor;\n const chunkSize = info.sourceArraySize;\n const dataView = new ArrayConstructor(mappedComputeInfoArrayBuffer, computeInfoOffSet, chunkSize); //new ArrayConstructor(computeInfoBuffer.getMappedRange(computeInfoOffSet, chunkByteSize));\n dataView.set(info.flatSourceArray);\n computeInfoOffSet += chunkSize * ArrayConstructor.BYTES_PER_ELEMENT;\n }\n // we are done at this point.\n computeInfoBuffer.unmap();\n // create a buffer on the GPU to hold suppInfo\n // same here, we need to pad the size of the struct to 16 bytes\n const suppInfoBufferSize = suppInfo32Size * Uint32Array.BYTES_PER_ELEMENT;\n let paddedSuppInfoBufferSize = suppInfoBufferSize;\n const suppInfoRemainder = suppInfoBufferSize & 15; // check if the size is a multiple of 16\n if (suppInfoRemainder !== 0)\n paddedSuppInfoBufferSize += 16 - suppInfoRemainder; // pad the size accordingly\n paddedSuppInfoBufferSize = Math.max(paddedSuppInfoBufferSize, 16);\n const suppInfoBuffer = device.createBuffer({\n label: 'supp info buffer',\n size: paddedSuppInfoBufferSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedSuppInfoArrayBuffer = suppInfoBuffer.getMappedRange(); // get full buffer\n let suppInfoOffSet = 0;\n for (const info of processInfo) {\n if (info.suppInfoBuffer && info.suppInfoBuffer.byteLength > 0 && info.suppInfoSize > 0) {\n const ArrayConstructor = info.suppInfoType === \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */ ? Uint32Array : Float32Array;\n const suppInfoView = new ArrayConstructor(mappedSuppInfoArrayBuffer, suppInfoOffSet, info.suppInfoBuffer.length); //new ArrayConstructor(suppInfoBuffer.getMappedRange(suppInfoOffSet, info.suppInfoBuffer.byteLength));\n suppInfoView.set(info.suppInfoBuffer);\n suppInfoOffSet += info.suppInfoBuffer.byteLength; // info.suppInfoBuffer.length * ArrayConstructor.BYTES_PER_ELEMENT;\n }\n }\n if (suppInfoOffSet === 0) {\n const dummyView = new Uint32Array(mappedSuppInfoArrayBuffer, 0, 4); //new Uint32Array(suppInfoBuffer.getMappedRange(0, 16));\n dummyView.set([1, 1, 1, 1]);\n }\n suppInfoBuffer.unmap();\n const outKnnArraySize = knnSize * Uint32Array.BYTES_PER_ELEMENT * computationsPerPass; // size of the slice of the knnIndexes and knnDistances\n // create a buffer on the GPU to hold knnIndexes and knnDistances\n const bufferDistances = device.createBuffer({\n label: 'buffer distances',\n size: outKnnArraySize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n const bufferIndexes = device.createBuffer({\n label: 'buffer indexes',\n size: outKnnArraySize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n // no need to copy anything to the knn buffers.\n const bytesPerOutArrayRow = knnSize * Uint32Array.BYTES_PER_ELEMENT; // how many bytes one row of the knnDistances and knnIndexes will take\n // Setup a bindGroup to tell the shader which\n // buffer to use for the computation\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for knn buffer',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: bufferIndexes } },\n { binding: 1, resource: { buffer: bufferDistances } },\n { binding: 2, resource: { buffer: computeInfoBuffer } },\n { binding: 3, resource: { buffer: suppInfoBuffer } },\n // { binding: 4, resource: { buffer: arraySizesBuffer } },\n ],\n });\n //create a buffer on the GPU to get a copy of the results\n const resultBufferDistances = device.createBuffer({\n label: 'result buffer distances',\n size: bufferDistances.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n const resultBufferIndexes = device.createBuffer({\n label: 'result buffer indexes',\n size: bufferIndexes.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n for (let iter = 0; iter < Math.ceil(listSize / computationsPerPass); iter++) {\n startAt = iter * computationsPerPass;\n endAt = Math.min((iter + 1) * computationsPerPass, listSize);\n const pairComparisonPasses = Math.ceil(listSize / pairComparisonsPerPass);\n for (let pairIter = 0; pairIter < pairComparisonPasses; pairIter++) {\n pairComparisonStartAt = pairIter * pairComparisonsPerPass;\n pairComparisonEndAt = Math.min((pairIter + 1) * pairComparisonsPerPass, listSize);\n // write only four values to the buffer, startAt, endAt, pairComparisonStartAt, pairComparisonEndAt, corresponding to vec4<u32> at the start of info struct\n device.queue.writeBuffer(computeInfoBuffer, 0, new Uint32Array([\n startAt,\n endAt,\n pairComparisonStartAt,\n pairComparisonEndAt,\n ]));\n // Encode commands to do the computation\n const encoder = device.createCommandEncoder({\n label: 'distance encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'distance compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(workgroupsDim, \n //workgroupsDim,\n Math.ceil(computationsPerPass / workgroupsDim / threadsPerWorkgroup));\n pass.end();\n // if we are at the last pair comparison pass, we need to read the results\n if (pairIter === pairComparisonPasses - 1) {\n // Encode a command to copy the results to a mappable buffer.\n encoder.copyBufferToBuffer(bufferDistances, 0, resultBufferDistances, 0, resultBufferDistances.size);\n encoder.copyBufferToBuffer(bufferIndexes, 0, resultBufferIndexes, 0, resultBufferIndexes.size);\n // Finish encoding and submit the commands\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n // Read the results\n //console.time('pass end');\n yield device.queue.onSubmittedWorkDone();\n // console.timeEnd('pass end');\n // console.time(\"read\");\n //const offsetBytes = startAt * bytesPerOutArrayRow;\n //const sizeBytes = (endAt - startAt) * bytesPerOutArrayRow;\n yield resultBufferDistances.mapAsync(GPUMapMode.READ);\n yield resultBufferIndexes.mapAsync(GPUMapMode.READ);\n // console.timeEnd(\"read\");\n const indexes = resultBufferIndexes.getMappedRange();\n const distances = resultBufferDistances.getMappedRange();\n // console.time(\"decode\");\n for (let i = 0; i < endAt - startAt; i++) {\n const index = new Uint32Array(indexes, i * bytesPerOutArrayRow, knnSize);\n const distance = new Float32Array(distances, i * bytesPerOutArrayRow, knnSize);\n resultIndexes[startAt + i].set(index);\n resultDistances[startAt + i].set(distance);\n }\n resultBufferIndexes.unmap();\n resultBufferDistances.unmap();\n }\n else {\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n // Read the results\n // console.time('pass between');\n yield device.queue.onSubmittedWorkDone();\n // console.timeEnd('pass between');\n }\n // device may get lost during opperation, so in this case, we need to return null\n if (deviceLost)\n return null;\n }\n }\n bufferDistances.destroy();\n bufferIndexes.destroy();\n computeInfoBuffer.destroy();\n suppInfoBuffer.destroy();\n resultBufferDistances.destroy();\n resultBufferIndexes.destroy();\n if (deviceLost)\n return null;\n return { knnIndexes: resultIndexes, knnDistances: resultDistances };\n });\n}\nfunction getCombinedDistanceScript(distanceMetrics, maxEntryLens, knnSize, aggregation) {\n const distanceWgsls = distanceMetrics.map((metric, i) => {\n return `\n fn distanceScript${i}(aIndex: u32, bIndex: u32) -> f32 {\n let a = computeInfo.data${i}[aIndex];\n let b = computeInfo.data${i}[bIndex];\n let maxDistance: f32 = knnDistances[aIndex - computeInfo.startAtEndAt.x][${knnSize} - 1u];\n ${webGPUFunctions[metric](maxEntryLens[i], i)}\n }\n `;\n });\n const allDistanceScripts = distanceWgsls.join('\\n');\n const combineDistancesScript = `\n fn combinedDistance(aIndex: u32, bIndex: u32) -> f32 {\n var distances: array<f32, ${distanceMetrics.length}>;\n ${distanceMetrics.map((_, i) => `distances[${i}] = distanceScript${i}(aIndex, bIndex);`).join('\\n')}\n ${WEBGSLAGGREGATIONFUNCTIONS[aggregation](distanceMetrics.length)}\n }\n \n `;\n return allDistanceScripts + '\\n' + combineDistancesScript;\n}\n//# sourceMappingURL=multiCol-KNN.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 max-len */\nimport { distanceFunctionComplexity, TypeSupportedDistances, WEBGPUDISTANCE } from '../multi-col-distances/webGPU-multicol-distances';\nexport function webGPUProcessInfo(entryList, distanceMetric = WEBGPUDISTANCE.HAMMING, entryIndex, // index of the entries in the list of lists that we want to process\noptions = { gapOpenPenalty: 1.0, gapExtensionPenalty: 0.6 }) {\n var _a, _b;\n let entryType = null;\n const encodedList = (() => {\n if (entryList.some((e) => typeof e === 'string')) {\n entryType = \"STRING\" /* WGPUENTRYTYPE.STRING */;\n return entryList.map((entry) => new Uint32Array(entry.split('').map((c) => c.charCodeAt(0))));\n }\n if (entryList.some((e) => typeof e === 'number')) {\n entryType = \"NUMBER\" /* WGPUENTRYTYPE.NUMBER */;\n return entryList.map((entry) => new Float32Array([entry]));\n }\n if (typeof entryList[0] == 'object' && entryList.some((e) => '_data' in e && '_length' in e)) {\n entryType = \"BITARRAY\" /* WGPUENTRYTYPE.BITARRAY */;\n return entryList.map((entry) => entry._data);\n }\n if (entryList.some((e) => e instanceof Float32Array)) {\n entryType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n return entryList;\n }\n if (entryList.some((e) => e instanceof Uint32Array)) {\n entryType = \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */;\n return entryList;\n }\n if (entryList.some((e) => e instanceof Int32Array)) {\n entryType = \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */;\n return entryList;\n }\n //return entryList as Uint32Array[];\n })();\n if (!encodedList || !entryType)\n throw new Error('Invalid entry type, could not determine entry type from input list');\n const encodedListType = encodedList[0] instanceof Int32Array ? \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */ :\n encodedList[0] instanceof Float32Array ? \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */ : \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */;\n // sizes of each entries might differ, so we need to keep track of that for some distance metrics, like hamming for example\n const arraySizes = new Uint32Array(encodedList.map((arr) => arr.length));\n if (!TypeSupportedDistances[entryType] || !TypeSupportedDistances[entryType].has(distanceMetric))\n throw new Error(`Distance metric '${distanceMetric}' not supported for entry type '${entryType}'`);\n const maxEntryLen = arraySizes.reduce((a, b) => Math.max(a, b), 0);\n // get the complexity of used algorithm\n const complexity = distanceFunctionComplexity[distanceMetric](maxEntryLen);\n const EncodedArrayConstructor = encodedListType === \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */ ? Int32Array :\n (encodedListType === \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */ ? Float32Array : Uint32Array);\n const flatSourceArray = new EncodedArrayConstructor(encodedList.length * maxEntryLen);\n // when setting, we need to set each array at a specific offset, which is controlled by maxArrayLen because each array might have different sizes.\n // this way we will get correct matrix representation in the compute shader\n encodedList.forEach((seq, i) => {\n flatSourceArray.set(seq, i * maxEntryLen);\n });\n // NB! all this before the line was generic, now we need to calculate some specific things for some specific distance metrics\n // initialize supp info line that will be included in the final shader;\n let suppInfoStructWgsl = ''; // the code that will be included in the struct of suppInfo\n let suppInfoSize = 0;\n let suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n let suppInfoBuffer = null;\n if (distanceMetric === WEBGPUDISTANCE.NEEDLEMAN_WUNSCH || distanceMetric === WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE) {\n let maxMonomerIndex = options.scoringMatrix && options.alphabetIndexes ?\n Object.keys(options.alphabetIndexes).reduce((prev, n) => Math.max(prev, n.charCodeAt(0)), 0) : -1;\n // generate default similarity matrix if it is not provided\n if (!options.alphabetIndexes || !options.scoringMatrix) {\n for (let i = 0; i < flatSourceArray.length; i++) {\n if (flatSourceArray[i] > maxMonomerIndex)\n maxMonomerIndex = flatSourceArray[i];\n }\n options.scoringMatrix =\n new Array(maxMonomerIndex + 1).fill(null).map(() => new Array(maxMonomerIndex + 1).fill(0));\n options.alphabetIndexes = {};\n for (let i = 0; i < options.scoringMatrix.length; i++) {\n options.scoringMatrix[i][i] = 1;\n options.alphabetIndexes[String.fromCharCode(i)] = i;\n }\n }\n const similarityMatrixSize = (maxMonomerIndex + 1) * (maxMonomerIndex + 1);\n const transferedSimilarityMatrix = new Array(maxMonomerIndex + 1).fill(null).map(() => new Float32Array(maxMonomerIndex + 1));\n // set diagonal to 1\n for (let i = 0; i < maxMonomerIndex + 1; i++)\n transferedSimilarityMatrix[i][i] = 1;\n const alphabetIndexes = options.alphabetIndexes;\n for (const key of Object.keys(alphabetIndexes)) {\n for (const key2 of Object.keys(alphabetIndexes)) {\n if (key === key2)\n continue;\n transferedSimilarityMatrix[key.charCodeAt(0)][key2.charCodeAt(0)] =\n options.scoringMatrix[alphabetIndexes[key]][alphabetIndexes[key2]];\n }\n }\n // in memory layout, we will have 2 float32 s for gapOpen and gapExtension penalties, and then f32 array<array<f32>> for similarity matrix.\n // because of primitives, there will be no padding, so we can calculate the size directly\n suppInfoSize = 2 + similarityMatrixSize;\n suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n suppInfoBuffer = new Float32Array(suppInfoSize);\n suppInfoBuffer[0] = (_a = options.gapOpenPenalty) !== null && _a !== void 0 ? _a : 1.0;\n suppInfoBuffer[1] = (_b = options.gapExtensionPenalty) !== null && _b !== void 0 ? _b : 0.6;\n let offset = 2;\n for (let i = 0; i < transferedSimilarityMatrix.length; i++) {\n suppInfoBuffer.set(transferedSimilarityMatrix[i], offset);\n offset += transferedSimilarityMatrix[i].length;\n }\n suppInfoStructWgsl = `\n gapOpenPenalty${entryIndex}: f32,\n gapExtensionPenalty${entryIndex}: f32,\n similarityMatrix${entryIndex}: array<array<f32, ${maxMonomerIndex + 1}>, ${maxMonomerIndex + 1}>`;\n }\n else if (distanceMetric === WEBGPUDISTANCE.Difference) {\n // for difference, we need range of values for normalization of the difference\n if (!options.range || typeof options.range !== 'number' || options.range <= 0) {\n const min = flatSourceArray.reduce((a, b) => Math.min(a, b), flatSourceArray[0]);\n const max = flatSourceArray.reduce((a, b) => Math.max(a, b), flatSourceArray[0]);\n options.range = max - min;\n }\n if (options.range <= 0)\n options.range = 1.0; // this means that all values are the same, and all distances will produce 0.\n suppInfoSize = 1;\n suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n suppInfoBuffer = new Float32Array([options.range]);\n suppInfoStructWgsl = `\n range${entryIndex}: f32`;\n }\n const dataTypeWGSL = flatSourceArray instanceof Int32Array ? 'i32' : (flatSourceArray instanceof Float32Array ? 'f32' : 'u32');\n const dataStructWgsl = `data${entryIndex}: array<array<${dataTypeWGSL}, ${maxEntryLen}>, ${encodedList.length}>`;\n // for now, other distances do not require any additional information, so we can skip that\n return {\n flatSourceArray,\n sourceArraySize: flatSourceArray.length,\n maxEntryLen,\n arraySizes,\n complexity,\n suppInfoBuffer,\n suppInfoSize,\n suppInfoType: suppInfoType,\n suppInfoStructWgsl,\n entryType,\n dataTypeWGSL,\n dataStructWgsl,\n EncodedArrayConstructor\n };\n}\n//# sourceMappingURL=webGPU-process-info.js.map","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 { getGPUDevice } from '../getGPUDevice';\nimport { knnMatrixOpInfoWGSL } from './wgsl/knn-sparse-info.wgsl';\n/**\n * this will get all the info needed for subsequent operation in umap\n * like sizes of each array of transposed knn and sizes of union of knn and its transpose rows.\n * after this point, all knn structures will be in single array form, with corresponding offsets.\n * @param knnIndexes\n * @returns\n */\nexport function getKnnSparseOpInfo(knnIndexes) {\n return __awaiter(this, void 0, void 0, function* () {\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const numOfEntries = knnIndexes.length;\n const requiredWorkgroups = Math.ceil(numOfEntries / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const knnSize = knnIndexes[0].length;\n const processWgsl = knnMatrixOpInfoWGSL(threadsPerWorkgroupDim, threadsPerWorkgroupDim * numOfWorkgroupsPerDim, numOfEntries, knnSize);\n const indexesBuffer32Size = numOfEntries * knnIndexes[0].length;\n const device = yield getGPUDevice();\n if (device == null)\n return;\n const module = device.createShaderModule({\n label: 'transposedSizesCalulation',\n code: processWgsl\n });\n const pipeline = device.createComputePipeline({\n label: 'transposedSizesPipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'countTransposedCols',\n },\n });\n const indexBuffer = device.createBuffer({\n label: 'indexes buffer',\n size: indexesBuffer32Size * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedIndexesBuffer = indexBuffer.getMappedRange();\n const mappedIndexesArray = new Int32Array(mappedIndexesBuffer);\n for (let i = 0; i < knnIndexes.length; i++)\n mappedIndexesArray.set(knnIndexes[i], i * knnIndexes[i].length);\n indexBuffer.unmap();\n const sizesBuffer = device.createBuffer({\n label: 'transpose sizes buffer',\n size: knnIndexes.length * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n });\n const unionSizesBuffer = device.createBuffer({\n label: 'union sizes buffer',\n size: knnIndexes.length * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedUnionSizesBuffer = unionSizesBuffer.getMappedRange();\n const mappedUnionSizesArray = new Uint32Array(mappedUnionSizesBuffer);\n mappedUnionSizesArray.fill(knnSize);\n unionSizesBuffer.unmap();\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for count ops',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: indexBuffer } },\n { binding: 1, resource: { buffer: sizesBuffer } },\n { binding: 2, resource: { buffer: unionSizesBuffer } }\n // { binding: 4, resource: { buffer: arraySizesBuffer } },\n ],\n });\n const encoder = device.createCommandEncoder({\n label: 'matrix ops encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'matrix ops compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n const resultTransposeSizesBuffer = device.createBuffer({\n label: 'result transpose sizes',\n size: sizesBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n const resultUnionSizesBuffer = device.createBuffer({\n label: 'result union sizes',\n size: unionSizesBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n encoder.copyBufferToBuffer(sizesBuffer, 0, resultTransposeSizesBuffer, 0, resultTransposeSizesBuffer.size);\n encoder.copyBufferToBuffer(unionSizesBuffer, 0, resultUnionSizesBuffer, 0, resultUnionSizesBuffer.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n yield resultTransposeSizesBuffer.mapAsync(GPUMapMode.READ);\n yield resultUnionSizesBuffer.mapAsync(GPUMapMode.READ);\n const resultTransposeSizesArrayBuffer = resultTransposeSizesBuffer.getMappedRange();\n const resultUnionSizesArrayBuffer = resultUnionSizesBuffer.getMappedRange();\n const resultTransposeSizesArray = new Uint32Array(knnIndexes.length);\n resultTransposeSizesArray.set(new Uint32Array(resultTransposeSizesArrayBuffer, 0, knnIndexes.length));\n resultTransposeSizesBuffer.unmap();\n const resultUnionSizesArray = new Uint32Array(knnIndexes.length);\n resultUnionSizesArray.set(new Uint32Array(resultUnionSizesArrayBuffer, 0, knnIndexes.length));\n resultUnionSizesBuffer.unmap();\n const unionMatrixSize = resultUnionSizesArray.reduce((old, val) => old + val, 0);\n resultUnionSizesBuffer.destroy();\n resultTransposeSizesBuffer.destroy();\n sizesBuffer.destroy();\n indexBuffer.destroy();\n unionSizesBuffer.destroy();\n // sizes of each transposed knn row, sizes of each union of knn and its transpose row, total size of union matrix\n return { resultTransposeSizesArray, resultUnionSizesArray, unionMatrixSize };\n //counteTransposedCols\n });\n}\n//# sourceMappingURL=knn-sparse-info.js.map","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 { getGPUDevice } from '../getGPUDevice';\n/* eslint-disable max-len */\n/**\n * wgsl code for pairwise operation on two sparse matrices.\n * @param indexes1 - indexes of first sparse matrix\n * @param distances1 - values1 of first sparse matrix\n * @param offsets1 - 32 bit offsets of first sparse matrix\n * @param indexes2 - indexes of second sparse matrix\n * @param distances2 - values of second sparse matrix\n * @param offsets2 - 32 bit offsets of second sparse matrix\n * @param numOfEntries - number of entries in original data\n * @param unionMatrixOffsets - offsets of union matrix, used to store result\n * @param op - operation to perform\n * @returns\n */\nexport function pairwiseOpSparse(indexes1, distances1, offsets1, indexes2, distances2, offsets2, numOfEntries, unionMatrixOffsets, // array of size numOfEntries + 1\nop) {\n return __awaiter(this, void 0, void 0, function* () {\n // this function is only meant for regular knn matrix, not for sparse matrix for of knn.\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const requiredWorkgroups = Math.ceil(numOfEntries / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const threadsPerYDimension = threadsPerWorkgroupDim * numOfWorkgroupsPerDim;\n const sparseSize1 = offsets1[offsets1.length - 1];\n const sparseSize2 = offsets2[offsets2.length - 1];\n // this array will have offsets of each row in union matrix with length of numOfEntries + 1\n const unionMatrixSize = unionMatrixOffsets[unionMatrixOffsets.length - 1]; // last index will be last offset i.e. full size\n const processWgsl = `\n struct SparseKNNStorage1 {\n indexes:array<i32, ${sparseSize1}>,\n knnDistances: array<f32, ${sparseSize1}>,\n offsets: array<u32, ${numOfEntries + 1}>\n }\n\n struct SparseKNNStorage2 {\n indexes:array<i32, ${sparseSize2}>,\n knnDistances: array<f32, ${sparseSize2}>,\n offsets: array<u32, ${numOfEntries + 1}>\n }\n\n struct ResKnn {\n knnIndexes: array<i32, ${unionMatrixSize}>,\n knnDistances: array<f32, ${unionMatrixSize}>\n }\n\n @group(0) @binding(0) var<storage, read_write> source1: SparseKNNStorage1;\n @group(0) @binding(1) var<storage, read_write> source2: SparseKNNStorage2;\n @group(0) @binding(2) var<storage, read_write> result: ResKnn;\n @group(0) @binding(3) var<storage, read_write> unionMatrixOffsets: array<u32, ${numOfEntries + 1}>;\n @compute @workgroup_size(${threadsPerWorkgroupDim}, ${threadsPerWorkgroupDim}) fn pairwiseOp(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n\n let col: u32 = id.x;\n let row: u32 = id.y;\n let workingIndex: u32 = row * ${threadsPerYDimension} + col;\n\n if (workingIndex >= ${numOfEntries}) {\n return;\n }\n var curUnionOffset: u32 = unionMatrixOffsets[workingIndex]; // offset at which to start writing in union matrix\n\n let start1 = source1.offsets[workingIndex];\n let end1 = source1.offsets[workingIndex + 1];\n let start2 = source2.offsets[workingIndex];\n let end2 = source2.offsets[workingIndex + 1];\n // TODO: sort a copy of these arrays, will make operation faster\n for (var i: u32 = start1; i < end1; i++) {\n let val1: f32 = source1.knnDistances[i];\n var val2: f32 = 0.0;\n let curIndex: i32 = source1.indexes[i];\n for (var j: u32 = start2; j < end2; j++) {\n if (source2.indexes[j] == curIndex) {\n val2 = source2.knnDistances[j];\n break;\n }\n }\n \n result.knnIndexes[curUnionOffset] = curIndex;\n result.knnDistances[curUnionOffset] = val1 ${op} val2;\n curUnionOffset += 1;\n }\n\n if (curUnionOffset >= unionMatrixOffsets[workingIndex + 1]) {\n // small optimization applicable only to our case, but saves a good amount of time\n return;\n }\n\n // do the same for source2 but skip the indexes where they are already present in source1\n for (var i: u32 = start2; i < end2; i++) {\n let val1: f32 = source2.knnDistances[i];\n let curIndex: i32 = source2.indexes[i];\n var found = false;\n for (var j: u32 = start1; j < end1; j++) {\n if (source1.indexes[j] == curIndex) {\n found = true;\n break;\n }\n }\n if (!found) {\n result.knnIndexes[curUnionOffset] = curIndex;\n result.knnDistances[curUnionOffset] = val1 ${op} 0.0;\n curUnionOffset += 1;\n }\n }\n }\n`;\n const storage32Size1 = sparseSize1 * 2 + numOfEntries + 1;\n const storage32Size2 = sparseSize2 * 2 + numOfEntries + 1;\n const resStorage32Size = unionMatrixSize * 2;\n // standard stuff to pad the storage size to multiple of 16 bytes\n let paddedStorage1ByteSize = storage32Size1 * 4;\n const remainder1 = paddedStorage1ByteSize & 15;\n if (remainder1 !== 0)\n paddedStorage1ByteSize += 16 - remainder1;\n let paddedStorage2ByteSize = storage32Size2 * 4;\n const remainder2 = paddedStorage2ByteSize & 15;\n if (remainder2 !== 0)\n paddedStorage2ByteSize += 16 - remainder2;\n let paddedResStorageByteSize = resStorage32Size * 4;\n const remainder3 = paddedResStorageByteSize & 15;\n if (remainder3 !== 0)\n paddedResStorageByteSize += 16 - remainder3;\n const device = yield getGPUDevice();\n if (device == null)\n return;\n const module = device.createShaderModule({\n label: 'pairwiseOpShader',\n code: processWgsl\n });\n const pipeline = device.createComputePipeline({\n label: 'pairwiseOpPipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'pairwiseOp',\n },\n });\n // input params\n const source1Buffer = device.createBuffer({\n label: 'source 1 buffer',\n size: paddedStorage1ByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedSource1Buffer = source1Buffer.getMappedRange();\n const source1IndexesArray = new Int32Array(mappedSource1Buffer, 0, sparseSize1);\n source1IndexesArray.set(indexes1);\n const source1DistancesArray = new Float32Array(mappedSource1Buffer, sparseSize1 * 4, sparseSize1);\n source1DistancesArray.set(distances1);\n const source1OffsetsArray = new Uint32Array(mappedSource1Buffer, sparseSize1 * 8, numOfEntries + 1);\n source1OffsetsArray.set(offsets1);\n source1Buffer.unmap();\n const source2Buffer = device.createBuffer({\n label: 'source 2 buffer',\n size: paddedStorage2ByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedSource2Buffer = source2Buffer.getMappedRange();\n const source2IndexesArray = new Int32Array(mappedSource2Buffer, 0, sparseSize2);\n source2IndexesArray.set(indexes2);\n const source2DistancesArray = new Float32Array(mappedSource2Buffer, sparseSize2 * 4, sparseSize2);\n source2DistancesArray.set(distances2);\n const source2OffsetsArray = new Uint32Array(mappedSource2Buffer, sparseSize2 * 8, numOfEntries + 1);\n source2OffsetsArray.set(offsets2);\n source2Buffer.unmap();\n const resBuffer = device.createBuffer({\n label: 'res buffer',\n size: paddedResStorageByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n });\n const unionMatrixOffsetsBuffer = device.createBuffer({\n label: 'union matrix offsets buffer',\n size: (numOfEntries + 1) * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedUnionMatrixOffsetsBuffer = unionMatrixOffsetsBuffer.getMappedRange();\n const unionMatrixOffsetsArray = new Uint32Array(mappedUnionMatrixOffsetsBuffer);\n unionMatrixOffsetsArray.set(unionMatrixOffsets);\n unionMatrixOffsetsBuffer.unmap();\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for pairwise ops',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: source1Buffer } },\n { binding: 1, resource: { buffer: source2Buffer } },\n { binding: 2, resource: { buffer: resBuffer } },\n { binding: 3, resource: { buffer: unionMatrixOffsetsBuffer } }\n ],\n });\n const encoder = device.createCommandEncoder({\n label: 'matrix ops encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'matrix ops compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n const resultBuffer = device.createBuffer({\n label: 'result buffer',\n size: paddedResStorageByteSize,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n encoder.copyBufferToBuffer(resBuffer, 0, resultBuffer, 0, resultBuffer.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n yield resultBuffer.mapAsync(GPUMapMode.READ);\n const resultArrayBuffer = resultBuffer.getMappedRange();\n const resultKnnIndexes = new Int32Array(unionMatrixSize);\n const resultKnnDistances = new Float32Array(unionMatrixSize);\n // its actually a sparse matrix.\n resultKnnIndexes.set(new Int32Array(resultArrayBuffer, 0, unionMatrixSize));\n resultKnnDistances.set(new Float32Array(resultArrayBuffer, unionMatrixSize * 4, unionMatrixSize));\n resultBuffer.unmap();\n resultBuffer.destroy();\n source1Buffer.destroy();\n source2Buffer.destroy();\n resBuffer.destroy();\n unionMatrixOffsetsBuffer.destroy();\n return { resultKnnIndexes, resultKnnDistances };\n });\n}\n//# sourceMappingURL=pairwise-sparse-ops.js.map","/**\n * the sum of the weighted squares of the errors (or weighted residuals) between the data.y\n * and the curve-fit function.\n * @ignore\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {ArrayLike<number>} parameters - Array of current parameter values\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @param {ArrayLike<number>} weightSquare - Square of weights\n * @return {number}\n */\nexport default function errorCalculation(data, parameters, parameterizedFunction, weightSquare) {\n let error = 0;\n const func = parameterizedFunction(parameters);\n for (let i = 0; i < data.x.length; i++) {\n error += Math.pow(data.y[i] - func(data.x[i]), 2) / weightSquare[i];\n }\n return error;\n}\n//# sourceMappingURL=errorCalculation.js.map","import { inverse, Matrix } from 'ml-matrix';\nimport gradientFunction from './gradientFunction';\n/**\n * Matrix function over the samples\n * @ignore\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {ArrayLike<number>} evaluatedData - Array of previous evaluated function values\n * @return {Matrix}\n */\nfunction matrixFunction(data, evaluatedData) {\n const m = data.x.length;\n let ans = new Matrix(m, 1);\n for (let point = 0; point < m; point++) {\n ans.set(point, 0, data.y[point] - evaluatedData[point]);\n }\n return ans;\n}\n/**\n * Iteration for Levenberg-Marquardt\n * @ignore\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number} damping - Levenberg-Marquardt parameter\n * @param {number|array} gradientDifference - The step size to approximate the jacobian matrix\n * @param {boolean} centralDifference - If true the jacobian matrix is approximated by central differences otherwise by forward differences\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n */\nexport default function step(data, params, damping, gradientDifference, parameterizedFunction, centralDifference, weights) {\n let value = damping;\n let identity = Matrix.eye(params.length, params.length, value);\n const func = parameterizedFunction(params);\n let evaluatedData = new Float64Array(data.x.length);\n for (let i = 0; i < data.x.length; i++) {\n evaluatedData[i] = func(data.x[i]);\n }\n let gradientFunc = gradientFunction(data, evaluatedData, params, gradientDifference, parameterizedFunction, centralDifference);\n let residualError = matrixFunction(data, evaluatedData);\n let inverseMatrix = inverse(identity.add(gradientFunc.mmul(gradientFunc.transpose().scale('row', { scale: weights }))));\n let jacobianWeightResidualError = gradientFunc.mmul(residualError.scale('row', { scale: weights }));\n let perturbations = inverseMatrix.mmul(jacobianWeightResidualError);\n return {\n perturbations,\n jacobianWeightResidualError,\n };\n}\n//# sourceMappingURL=step.js.map","import { Matrix } from 'ml-matrix';\n/**\n * Difference of the matrix function over the parameters\n * @ignore\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {ArrayLike<number>} evaluatedData - Array of previous evaluated function values\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number|array} gradientDifference - The step size to approximate the jacobian matrix\n * @param {boolean} centralDifference - If true the jacobian matrix is approximated by central differences otherwise by forward differences\n * @param {function} paramFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {Matrix}\n */\nexport default function gradientFunction(data, evaluatedData, params, gradientDifference, paramFunction, centralDifference) {\n const nbParams = params.length;\n const nbPoints = data.x.length;\n let ans = Matrix.zeros(nbParams, nbPoints);\n let rowIndex = 0;\n for (let param = 0; param < nbParams; param++) {\n if (gradientDifference[param] === 0)\n continue;\n let delta = gradientDifference[param];\n let auxParams = params.slice();\n auxParams[param] += delta;\n let funcParam = paramFunction(auxParams);\n if (!centralDifference) {\n for (let point = 0; point < nbPoints; point++) {\n ans.set(rowIndex, point, (evaluatedData[point] - funcParam(data.x[point])) / delta);\n }\n }\n else {\n auxParams = params.slice();\n auxParams[param] -= delta;\n delta *= 2;\n let funcParam2 = paramFunction(auxParams);\n for (let point = 0; point < nbPoints; point++) {\n ans.set(rowIndex, point, (funcParam2(data.x[point]) - funcParam(data.x[point])) / delta);\n }\n }\n rowIndex++;\n }\n return ans;\n}\n//# sourceMappingURL=gradientFunction.js.map","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 { levenbergMarquardt } from 'ml-levenberg-marquardt';\nexport function linear(x1, x2, n) {\n const step = (x2 - x1) / (n - 1);\n return Array.from({ length: n }, (_, i) => x1 + step * i);\n}\n/**\n * Fit a, b params for the differentiable curve used in lower\n * dimensional fuzzy simplicial complex construction. We want the\n * smooth curve (from a pre-defined family with simple gradient) that\n * best matches an offset exponential decay.\n */\nexport function findABParams(spread, minDist) {\n const curve = ([a, b]) => (x) => {\n return 1.0 / (1.0 + a * Math.pow(x, (2 * b)));\n };\n const xv = linear(0, spread * 3, 300)\n .map((val) => (val < minDist ? 1.0 : val));\n const yv = new Array(xv.length).fill(0).map((val, index) => {\n const gte = xv[index] >= minDist;\n return gte ? Math.exp(-(xv[index] - minDist) / spread) : val;\n });\n const initialValues = [0.5, 0.5];\n const data = { x: xv, y: yv };\n // Default options for the algorithm (from github example)\n const options = {\n damping: 1.5,\n initialValues,\n gradientDifference: 10e-2,\n maxIterations: 100,\n errorTolerance: 10e-3,\n };\n // eslint-disable-next-line new-cap\n const { parameterValues } = levenbergMarquardt(data, curve, options);\n const [a, b] = parameterValues;\n return { a, b };\n}\n/**\n * heuristic for number of epochs of umap, differs from cpu version, because of the way gpu passes data\n * @param entryLen number of entries\n * @returns\n */\nexport function getNEpochs(entryLen) {\n //\n const length = entryLen;\n if (length <= 2500)\n return 1000;\n else if (length <= 5000)\n return 800;\n else if (length <= 7500)\n return 650;\n else\n return 400;\n}\n/** helper function that transforms array of sizes to offset form */\nexport function toOffsetForm(ar) {\n const res = new Uint32Array(ar.length + 1);\n let offset = 0;\n for (let i = 0; i < ar.length; i++) {\n res[i] = offset;\n offset += ar[i];\n }\n res[ar.length] = offset;\n return res;\n}\n/** multiplies flat representation of sparse knn info by scalar.\n * also no point of doing this on gpu, can be done on cpu pretty quickly.\n * if there will be need for it, it can be done on gpu as well very very easily.\n * @param values values array\n * @param scalar\n */\nexport function multiplyScalar(values, scalar) {\n for (let i = 0; i < values.length; i++)\n values[i] = values[i] * scalar;\n}\n/**\n * generate transpose of knn from the transposition info taken from sparse knn info\n * using this information avoids billions of array.push calls, is much cleaner, allows typed array use and is faster.\n * no point of doing this on gpu, can be done on cpu as we already have all the info needed.\n * @param knnIndexes\n * @param knnDistances\n * @param knnSparseInfo\n * @param knnSize\n * @returns\n */\nexport function transposeKNN(knnIndexes, knnDistances, knnSparseInfo, knnSize = 15) {\n return __awaiter(this, void 0, void 0, function* () {\n const numOfEntries = knnIndexes.length;\n const fullKnnEntrySize = knnSize * numOfEntries;\n const transposeSizes = knnSparseInfo.resultTransposeSizesArray;\n const transposeOffsets = toOffsetForm(transposeSizes);\n const offsetsCopy = new Uint32Array(transposeOffsets.length);\n offsetsCopy.set(transposeOffsets); // will be used for dynamic indexing\n const transposeKNNIndexes = new Int32Array(fullKnnEntrySize).fill(0);\n const transposeKNNDistances = new Float32Array(fullKnnEntrySize).fill(0);\n for (let i = 0; i < numOfEntries; i++) {\n for (let j = 0; j < knnSize; j++) {\n const otherIndex = knnIndexes[i][j];\n const otherIndexOffset = offsetsCopy[otherIndex];\n transposeKNNIndexes[otherIndexOffset] = i;\n transposeKNNDistances[otherIndexOffset] = knnDistances[i][j];\n offsetsCopy[otherIndex] += 1;\n }\n }\n return { transposeKNNIndexes, transposeKNNDistances, transposeOffsets };\n });\n}\n//# sourceMappingURL=utils.js.map","import checkOptions from './checkOptions';\nimport errorCalculation from './errorCalculation';\nimport step from './step';\n/**\n * Curve fitting algorithm\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {function} parameterizedFunction - Takes an array of parameters and returns a function with the independent variable as its sole argument\n * @param {object} options - Options object\n * @param {ArrayLike<number>} options.initialValues - Array of initial parameter values\n * @param {number|ArrayLike<number>} [options.weights = 1] - weighting vector, if the length does not match with the number of data points, the vector is reconstructed with first value.\n * @param {number} [options.damping = 1e-2] - Levenberg-Marquardt parameter, small values of the damping parameter λ result in a Gauss-Newton update and large\nvalues of λ result in a gradient descent update\n * @param {number} [options.dampingStepDown = 9] - factor to reduce the damping (Levenberg-Marquardt parameter) when there is not an improvement when updating parameters.\n * @param {number} [options.dampingStepUp = 11] - factor to increase the damping (Levenberg-Marquardt parameter) when there is an improvement when updating parameters.\n * @param {number} [options.improvementThreshold = 1e-3] - the threshold to define an improvement through an update of parameters\n * @param {number|ArrayLike<number>} [options.gradientDifference = 10e-2] - The step size to approximate the jacobian matrix\n * @param {boolean} [options.centralDifference = false] - If true the jacobian matrix is approximated by central differences otherwise by forward differences\n * @param {ArrayLike<number>} [options.minValues] - Minimum allowed values for parameters\n * @param {ArrayLike<number>} [options.maxValues] - Maximum allowed values for parameters\n * @param {number} [options.maxIterations = 100] - Maximum of allowed iterations\n * @param {number} [options.errorTolerance = 10e-3] - Minimum uncertainty allowed for each point.\n * @param {number} [options.timeout] - maximum time running before throw in seconds.\n * @return {{parameterValues: Array<number>, parameterError: number, iterations: number}}\n */\nexport function levenbergMarquardt(data, parameterizedFunction, options) {\n let { checkTimeout, minValues, maxValues, parameters, weightSquare, damping, dampingStepUp, dampingStepDown, maxIterations, errorTolerance, centralDifference, gradientDifference, improvementThreshold, } = checkOptions(data, parameterizedFunction, options);\n let error = errorCalculation(data, parameters, parameterizedFunction, weightSquare);\n let optimalError = error;\n let optimalParameters = parameters.slice();\n let converged = error <= errorTolerance;\n let iteration = 0;\n for (; iteration < maxIterations && !converged; iteration++) {\n let previousError = error;\n let { perturbations, jacobianWeightResidualError } = step(data, parameters, damping, gradientDifference, parameterizedFunction, centralDifference, weightSquare);\n for (let k = 0; k < parameters.length; k++) {\n parameters[k] = Math.min(Math.max(minValues[k], parameters[k] - perturbations.get(k, 0)), maxValues[k]);\n }\n error = errorCalculation(data, parameters, parameterizedFunction, weightSquare);\n if (isNaN(error))\n break;\n if (error < optimalError - errorTolerance) {\n optimalError = error;\n optimalParameters = parameters.slice();\n }\n let improvementMetric = (previousError - error) /\n perturbations\n .transpose()\n .mmul(perturbations.mul(damping).add(jacobianWeightResidualError))\n .get(0, 0);\n if (improvementMetric > improvementThreshold) {\n damping = Math.max(damping / dampingStepDown, 1e-7);\n }\n else {\n damping = Math.min(damping * dampingStepUp, 1e7);\n }\n if (checkTimeout()) {\n throw new Error(`The execution time is over to ${options.timeout} seconds`);\n }\n converged = error <= errorTolerance;\n }\n return {\n parameterValues: optimalParameters,\n parameterError: optimalError,\n iterations: iteration,\n };\n}\n//# sourceMappingURL=index.js.map","import { isAnyArray } from 'is-any-array';\nexport default function checkOptions(data, parameterizedFunction, options) {\n let { timeout, minValues, maxValues, initialValues, weights = 1, damping = 1e-2, dampingStepUp = 11, dampingStepDown = 9, maxIterations = 100, errorTolerance = 1e-7, centralDifference = false, gradientDifference = 10e-2, improvementThreshold = 1e-3, } = options;\n if (damping <= 0) {\n throw new Error('The damping option must be a positive number');\n }\n else if (!data.x || !data.y) {\n throw new Error('The data parameter must have x and y elements');\n }\n else if (!isAnyArray(data.x) ||\n data.x.length < 2 ||\n !isAnyArray(data.y) ||\n data.y.length < 2) {\n throw new Error('The data parameter elements must be an array with more than 2 points');\n }\n else if (data.x.length !== data.y.length) {\n throw new Error('The data parameter elements must have the same size');\n }\n if (!(initialValues && initialValues.length > 0)) {\n throw new Error('The initialValues option is mandatory and must be an array');\n }\n let parameters = initialValues;\n let nbPoints = data.y.length;\n let parLen = parameters.length;\n maxValues = maxValues || new Array(parLen).fill(Number.MAX_SAFE_INTEGER);\n minValues = minValues || new Array(parLen).fill(Number.MIN_SAFE_INTEGER);\n if (maxValues.length !== minValues.length) {\n throw new Error('minValues and maxValues must be the same size');\n }\n if (typeof gradientDifference === 'number') {\n gradientDifference = new Array(parameters.length).fill(gradientDifference);\n }\n else if (isAnyArray(gradientDifference)) {\n if (gradientDifference.length !== parLen) {\n gradientDifference = new Array(parLen).fill(gradientDifference[0]);\n }\n }\n else {\n throw new Error('gradientDifference should be a number or array with length equal to the number of parameters');\n }\n let filler;\n if (typeof weights === 'number') {\n let value = 1 / weights ** 2;\n filler = () => value;\n }\n else if (isAnyArray(weights)) {\n if (weights.length < data.x.length) {\n let value = 1 / weights[0] ** 2;\n filler = () => value;\n }\n else {\n filler = (i) => 1 / weights[i] ** 2;\n }\n }\n else {\n throw new Error('weights should be a number or array with length equal to the number of data points');\n }\n let checkTimeout;\n if (timeout !== undefined) {\n if (typeof timeout !== 'number') {\n throw new Error('timeout should be a number');\n }\n let endTime = Date.now() + timeout * 1000;\n checkTimeout = () => Date.now() > endTime;\n }\n else {\n checkTimeout = () => false;\n }\n let weightSquare = new Array(data.x.length);\n for (let i = 0; i < nbPoints; i++) {\n weightSquare[i] = filler(i);\n }\n return {\n checkTimeout,\n minValues,\n maxValues,\n parameters,\n weightSquare,\n damping,\n dampingStepUp,\n dampingStepDown,\n maxIterations,\n errorTolerance,\n centralDifference,\n gradientDifference,\n improvementThreshold,\n };\n}\n//# sourceMappingURL=checkOptions.js.map","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 { getKnnSparseOpInfo } from './knn-sparse-info';\nimport { pairwiseOpSparse } from './pairwise-sparse-ops';\nimport { multiplyScalar, toOffsetForm, transposeKNN } from './utils';\nexport function performMatrixOps(knnIndexes, knnDistances, setOpMixRatio = 1.0) {\n return __awaiter(this, void 0, void 0, function* () {\n const flatKnnIndexes = new Int32Array(knnIndexes.length * knnIndexes[0].length);\n const flatKnnDistances = new Float32Array(knnDistances.length * knnDistances[0].length);\n for (let i = 0; i < knnIndexes.length; i++) {\n flatKnnIndexes.set(knnIndexes[i], i * knnIndexes[i].length);\n flatKnnDistances.set(knnDistances[i], i * knnDistances[i].length);\n }\n const unionInfo = yield getKnnSparseOpInfo(knnIndexes);\n const numOfEntries = knnIndexes.length;\n const transposed = yield transposeKNN(knnIndexes, knnDistances, unionInfo, knnDistances[0].length);\n const sourceOffsets = toOffsetForm(new Uint32Array(numOfEntries).fill(knnIndexes[0].length));\n const unionMatrixOffsets = toOffsetForm(unionInfo.resultUnionSizesArray);\n const transposeMultRes = yield pairwiseOpSparse(flatKnnIndexes, flatKnnDistances, sourceOffsets, transposed.transposeKNNIndexes, transposed.transposeKNNDistances, transposed.transposeOffsets, numOfEntries, unionMatrixOffsets, '*');\n const addRes = yield pairwiseOpSparse(flatKnnIndexes, flatKnnDistances, sourceOffsets, transposed.transposeKNNIndexes, transposed.transposeKNNDistances, transposed.transposeOffsets, numOfEntries, unionMatrixOffsets, '+');\n // these offsets will be same as union matrix offsets\n const subtRes = yield pairwiseOpSparse(addRes.resultKnnIndexes, addRes.resultKnnDistances, unionMatrixOffsets, transposeMultRes.resultKnnIndexes, transposeMultRes.resultKnnDistances, unionMatrixOffsets, numOfEntries, unionMatrixOffsets, '-');\n if (setOpMixRatio !== 1.0) {\n multiplyScalar(subtRes.resultKnnDistances, setOpMixRatio);\n multiplyScalar(transposeMultRes.resultKnnDistances, 1.0 - setOpMixRatio);\n const res = yield pairwiseOpSparse(subtRes.resultKnnIndexes, subtRes.resultKnnDistances, unionMatrixOffsets, transposeMultRes.resultKnnIndexes, transposeMultRes.resultKnnDistances, unionMatrixOffsets, numOfEntries, unionMatrixOffsets, '+');\n return { res, unionMatrixOffsets };\n }\n return { res: subtRes, unionMatrixOffsets, unionSizes: unionInfo.resultUnionSizesArray };\n });\n}\n//# sourceMappingURL=fuzzy-simplical-set.js.map","/* eslint-disable max-len */\nexport function knnMatrixOpInfoWGSL(threadsPerWorkgroupDim, threadsPerYDimension, entryLen, knnSize = 15) {\n return `\n\n @group(0) @binding(0) var<storage, read_write> knnIndexes: array<array<i32, ${knnSize}>, ${entryLen}>;\n @group(0) @binding(1) var<storage, read_write> resTransposedSizes: array<atomic<u32>, ${entryLen}>;\n // this array will store the union of knn and its transpose sizes per index. should be initialized to knnSize each.\n @group(0) @binding(2) var<storage, read_write> resUnionMatrixSizes: array<atomic<u32>, ${entryLen}>;\n\n @compute @workgroup_size(${threadsPerWorkgroupDim}, ${threadsPerWorkgroupDim}) fn countTransposedCols(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let col: u32 = id.x;\n let row: u32 = id.y;\n let workingIndex: u32 = row * ${threadsPerYDimension} + col;\n\n if (workingIndex >= ${entryLen}) {\n return;\n }\n \n for (var i = 0u; i < ${knnSize}u; i++) {\n let otherIndex: i32 = knnIndexes[workingIndex][i];\n if (otherIndex != -1 && otherIndex < ${entryLen}) {\n atomicAdd(&resTransposedSizes[otherIndex], 1u);\n atomicAdd(&resUnionMatrixSizes[otherIndex], 1u);\n let otherIndexes = &knnIndexes[otherIndex];\n for(var j = 0u; j < ${knnSize}; j++) {\n if ((*otherIndexes)[j] == i32(workingIndex)) {\n atomicSub(&resUnionMatrixSizes[workingIndex], 1u);\n // if same is found in other array, decrement by one;\n break;\n }\n }\n }\n\n }\n }\n `;\n}\n//# sourceMappingURL=knn-sparse-info.wgsl.js.map","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 { getGPUDevice } from '../getGPUDevice';\nimport { smoothKNNDistanceWGSL } from './wgsl/smooth-knn-distance.wgsl';\nexport function smoothKNNDistance(knnDistances, nNeighbors = 15, localConnectivity = 1.0, nIter = 64, bandwidth = 1.0) {\n return __awaiter(this, void 0, void 0, function* () {\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const numOfEntries = knnDistances.length;\n const requiredWorkgroups = Math.ceil(numOfEntries / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const processWgsl = smoothKNNDistanceWGSL(threadsPerWorkgroupDim, threadsPerWorkgroupDim * numOfWorkgroupsPerDim, knnDistances, nNeighbors, localConnectivity, nIter, bandwidth);\n const distanceBuffer32Size = numOfEntries * knnDistances[0].length;\n // const flatDistanceArray = new Float32Array(distanceBuffer32Size);\n // for (let i = 0; i < knnDistances.length; i ++) {\n // flatDistanceArray.set(knnDistances[i], i * knnDistances[i].length);\n // }\n const device = yield getGPUDevice();\n if (device == null)\n return;\n const resultSigmas = new Float32Array(numOfEntries);\n const resultRhos = new Float32Array(numOfEntries);\n const module = device.createShaderModule({\n label: 'sigmaRhoCalulation',\n code: processWgsl\n });\n const pipeline = device.createComputePipeline({\n label: 'sigmaRhoPipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'smoothKNNDistance',\n },\n });\n const distancesBuffer = device.createBuffer({\n label: 'distance buffer',\n size: distanceBuffer32Size * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedDistanceBuffer = distancesBuffer.getMappedRange();\n const mappedDistanceArray = new Float32Array(mappedDistanceBuffer);\n for (let i = 0; i < knnDistances.length; i++)\n mappedDistanceArray.set(knnDistances[i], i * knnDistances[i].length);\n distancesBuffer.unmap();\n const bufferSigmas = device.createBuffer({\n label: 'buffer sigmas',\n size: numOfEntries * 4,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n const bufferRhos = device.createBuffer({\n label: 'buffer Rhos',\n size: numOfEntries * 4,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for sigmarho buffers',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: bufferSigmas } },\n { binding: 1, resource: { buffer: bufferRhos } },\n { binding: 2, resource: { buffer: distancesBuffer } },\n // { binding: 4, resource: { buffer: arraySizesBuffer } },\n ],\n });\n const encoder = device.createCommandEncoder({\n label: 'sigmarho encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'sigmarho compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n const resultBufferRhos = device.createBuffer({\n label: 'result buffer rhos',\n size: bufferRhos.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n const resultBufferSigmas = device.createBuffer({\n label: 'result buffer sigmas',\n size: bufferSigmas.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n encoder.copyBufferToBuffer(bufferRhos, 0, resultBufferRhos, 0, resultBufferRhos.size);\n encoder.copyBufferToBuffer(bufferSigmas, 0, resultBufferSigmas, 0, resultBufferSigmas.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n yield resultBufferRhos.mapAsync(GPUMapMode.READ);\n yield resultBufferSigmas.mapAsync(GPUMapMode.READ);\n resultRhos.set(new Float32Array(resultBufferRhos.getMappedRange()));\n resultSigmas.set(new Float32Array(resultBufferSigmas.getMappedRange()));\n resultBufferRhos.unmap();\n resultBufferSigmas.unmap();\n distancesBuffer.destroy();\n bufferSigmas.destroy();\n bufferRhos.destroy();\n resultBufferRhos.destroy();\n resultBufferSigmas.destroy();\n return { resultRhos, resultSigmas };\n });\n}\n//# sourceMappingURL=smooth-knn-distance.js.map","export function smoothKNNDistanceWGSL(threadsPerWorkgroupDim = 10, threadsPerYDimension, knnDistances, nNeighbors = 15, localConnectivity = 1.0, nIter = 64, bandwidth = 1.0) {\n const numOfEntries = knnDistances.length;\n let meanDistancesSum = 0.0;\n for (let i = 0; i < numOfEntries; i++) {\n let currentMean = 0.0;\n for (let j = 0; j < nNeighbors; j++)\n currentMean += knnDistances[i][j];\n meanDistancesSum += currentMean / nNeighbors;\n }\n const meanDistances = meanDistancesSum / numOfEntries;\n const target = Math.log(nNeighbors) / Math.log(2) * bandwidth;\n return ` \n var<private> SMOOTH_K_TOLERANCE: f32 = 1e-5;\n var<private> MIN_K_DIST_SCALE: f32 = 1e-3;\n var<private> nNeighbors: u32 = ${nNeighbors};\n var<private> localConnectivity: f32 = ${localConnectivity}; \n var<private> nIter: u32 = ${nIter};\n var<private> bandwidth: u32 = ${bandwidth};\n var<private> meanDistances: f32 = ${meanDistances};\n var<private> targetValue: f32 = ${target};\n @group(0) @binding(0) var<storage, read_write> sigmas: array<f32, ${numOfEntries}>;\n @group(0) @binding(1) var<storage, read_write> rhos: array<f32, ${numOfEntries}>;\n @group(0) @binding(2) var<storage, read> distances: array<array<f32, ${nNeighbors}>, ${numOfEntries}>;\n @compute @workgroup_size(${threadsPerWorkgroupDim}, ${threadsPerWorkgroupDim}) fn smoothKNNDistance(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let col: u32 = id.x;\n let row: u32 = id.y;\n let workingIndex: u32 = row * ${threadsPerYDimension} + col;\n\n if (workingIndex >= ${numOfEntries}) {\n return;\n }\n\n var lo: f32 = 0.0;\n var hi: f32 = 1.0e+30; // treated as Infinity\n var mid: f32 = 1.0;\n\n var nonZeroDists: array<f32, ${nNeighbors}>;\n var nonZeroDistsSize: u32 = 0;\n for (var j = 0u; j < nNeighbors; j = j + 1u) {\n if (distances[workingIndex][j] > 0.0) {\n nonZeroDists[nonZeroDistsSize] = distances[workingIndex][j];\n nonZeroDistsSize = nonZeroDistsSize + 1u;\n }\n }\n\n if (f32(nonZeroDistsSize) >= localConnectivity) {\n let index: u32 = u32(floor(localConnectivity));\n let interpolation: f32 = localConnectivity - f32(index);\n if (index > 0) {\n rhos[workingIndex] = nonZeroDists[index - 1];\n if (interpolation > SMOOTH_K_TOLERANCE) {\n rhos[workingIndex] += interpolation * (nonZeroDists[index] - nonZeroDists[index - 1]);\n }\n }\n else {\n rhos[workingIndex] = interpolation * nonZeroDists[0];\n }\n }\n else if (nonZeroDistsSize > 0u) {\n var maxDist: f32 = 0.0;\n for (var j = 0u; j < nonZeroDistsSize; j = j + 1u) {\n maxDist = max(nonZeroDists[j], maxDist);\n }\n rhos[workingIndex] = maxDist;\n }\n\n for (var n = 0u; n < nIter; n = n + 1u) {\n var psum: f32 = 0.0;\n for (var j = 1u; j < ${nNeighbors}; j = j + 1u) {\n let d: f32 = distances[workingIndex][j] - rhos[workingIndex];\n if (d > 0.0) {\n psum += exp(0.0 - (d / mid));\n }\n else {\n psum += 1.0;\n }\n }\n\n if (abs(psum - targetValue) < SMOOTH_K_TOLERANCE) {\n break;\n }\n\n if (psum > targetValue) {\n hi = mid;\n mid = (lo + hi) / 2.0;\n }\n else {\n lo = mid;\n if (hi == 1.0e+30) {\n mid *= 2.0;\n }\n else {\n mid = (lo + hi) / 2.0;\n }\n }\n }\n\n sigmas[workingIndex] = mid;\n\n if (rhos[workingIndex] > 0.0) {\n var sum: f32 = 0.0;\n for (var j = 0u; j < ${nNeighbors}; j = j + 1u) {\n sum += distances[workingIndex][j];\n }\n let meanIthDistances: f32 = sum / ${nNeighbors}.0;\n if (sigmas[workingIndex] < MIN_K_DIST_SCALE * meanIthDistances) {\n sigmas[workingIndex] = MIN_K_DIST_SCALE * meanIthDistances;\n }\n }\n else {\n if (sigmas[workingIndex] < MIN_K_DIST_SCALE * meanDistances) {\n sigmas[workingIndex] = MIN_K_DIST_SCALE * meanDistances;\n }\n }\n }\n `;\n}\n//# sourceMappingURL=smooth-knn-distance.wgsl.js.map","/* eslint-disable max-len */\nvar __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 { performMatrixOps } from './fuzzy-simplical-set';\nimport { computeMembershipStrengths } from './membership-strengths';\nimport { optimizationLoop } from './optimization-loop';\nimport { initializeSimplicialSetEmbedding } from './simplical-set-embedding';\nimport { smoothKNNDistance } from './smooth-knn-distance';\n// TODO: FIT ASYNC METHOD WITH CALLBACKS on each step\n// TODO: random function passing in params\nexport class UmapParams {\n constructor() {\n this.nComponents = 2;\n this.gamma = 1;\n this.alpha = 1;\n this.entryLen = 0;\n this.nNeighbours = 15;\n this.spread = 1;\n this.minDist = 0.1;\n this.negativeSampleRate = 5;\n this.localConnectivity = 1.0;\n this.setOpMixRatio = 1.0;\n }\n}\nexport class WebGPUUMAP {\n constructor(entryLen, params) {\n this.params = new UmapParams();\n this.knnIndexes = null;\n this.knnDistances = null;\n this.rhos = null;\n this.sigmas = null;\n this.membershipStrengths = null;\n this.params.entryLen = entryLen;\n Object.assign(this.params, params);\n }\n setPrecomputedKNN(knnIndexes, knnDistances) {\n this.knnIndexes = knnIndexes;\n this.knnDistances = knnDistances;\n }\n // for now, not sure if we should include this, maybe webGPU UMAP should be stand alone.\n // eslint-disable-next-line max-len\n // async calcKNN(entryList: SupportedEntryTypes[][], distanceMetrics: WEBGPUDISTANCE[], aggregationFunction: WEBGSLAGGREGATION, weights: number[], options: {\n // [key: string]: any;\n // }[]) {\n // try {\n // const knnRes = await multiColWebGPUKNN(entryList, this.params.nNeighbours, distanceMetrics, aggregationFunction, weights, options);\n // if (knnRes) {\n // this.knnIndexes = knnRes.knnIndexes;\n // this.knnDistances = knnRes.knnDistances;\n // }\n // } catch (e) {\n // console.error(e);\n // }\n // if (!this.knnIndexes || !this.knnDistances)\n // throw new Error('failed to compute knn indexes and distances');\n // }\n // async calcKNNSingle(entryList: SupportedEntryTypes[], distanceMetrics: WEBGPUDISTANCE, options?: {\n // [key: string]: any;\n // }) {\n // if (!options)\n // options = {};\n // await this.calcKNN([entryList], [distanceMetrics], WEBGSLAGGREGATION.MANHATTAN, [1], [options]);\n // }\n initializeFit() {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.calcSmoothKNNDistances();\n yield this.calcMembershipStrengths();\n });\n }\n fit() {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.initializeFit();\n const umapParams = yield this.initializeSimplicialSetEmbedding();\n if (!umapParams)\n throw new Error('failed to compute umap simplistical set embeddings');\n const { head, tail, epochsPerSample, epochsPerNegativeSample, a, b, gamma, initialAlpha, nComponents, nEpochs, entryLen } = umapParams;\n const resEmbeddings = yield optimizationLoop(head, tail, entryLen, epochsPerSample, epochsPerNegativeSample, initialAlpha, gamma, a, b, nComponents, nEpochs, entryLen);\n return resEmbeddings;\n });\n }\n calcSmoothKNNDistances() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!this.knnIndexes || !this.knnDistances)\n throw new Error('knn indexes and distances must be set before calling fit');\n const res = yield smoothKNNDistance(this.knnDistances, this.params.nNeighbours, this.params.localConnectivity, 64);\n if (!res)\n throw new Error('failed to compute smooth knn distances');\n this.rhos = res.resultRhos;\n this.sigmas = res.resultSigmas;\n });\n }\n calcMembershipStrengths() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!this.knnIndexes || !this.knnDistances || !this.rhos || !this.sigmas)\n throw new Error('knn indexes, distances, rhos, and sigmas must be set before calling fit');\n const res = yield computeMembershipStrengths(this.knnDistances, this.sigmas, this.rhos);\n if (!res)\n throw new Error('failed to compute membership strengths');\n this.membershipStrengths = res;\n });\n }\n fuzzySimplicialSet() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!this.knnIndexes || !this.knnDistances || !this.rhos || !this.sigmas || !this.membershipStrengths)\n throw new Error('knn indexes, distances, rhos, sigmas, and membership strengths must be set before calling fit');\n const res = yield performMatrixOps(this.knnIndexes, this.membershipStrengths, this.params.setOpMixRatio);\n if (!res)\n throw new Error('failed to compute pairwise multiply with transpose');\n return res;\n });\n }\n initializeSimplicialSetEmbedding() {\n return __awaiter(this, void 0, void 0, function* () {\n const fuzzySimplicialSetRes = yield this.fuzzySimplicialSet();\n if (!fuzzySimplicialSetRes || !fuzzySimplicialSetRes.res || !fuzzySimplicialSetRes.unionMatrixOffsets || !fuzzySimplicialSetRes.unionSizes)\n throw new Error('failed to compute fuzzy simplicial set');\n const eRes = yield initializeSimplicialSetEmbedding(fuzzySimplicialSetRes, this.params.entryLen, this.params.spread, this.params.minDist, this.params.negativeSampleRate);\n if (!eRes)\n throw new Error('failed to compute umap simplistical set embeddings');\n return eRes;\n });\n }\n}\n//# sourceMappingURL=WEBGPU-UMAP.js.map","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 { getGPUDevice } from '../getGPUDevice';\nimport { optimizeLayoutWGSL } from './wgsl/optimization-loop.wgsl';\nexport function optimizationLoop(head, tail, embeddingSize, epochsPerSample, epochsPerNegativeSample, initialAlpha, gamma, a, b, dim, nEpochs, nVertices) {\n return __awaiter(this, void 0, void 0, function* () {\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const requiredWorkgroups = Math.ceil(head.length / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const threadsPerYDimension = threadsPerWorkgroupDim * numOfWorkgroupsPerDim;\n const device = yield getGPUDevice();\n if (!device)\n return;\n const divisionFactor = 10000000;\n const headSize = head.length;\n const processWGSL = optimizeLayoutWGSL(headSize, embeddingSize, true, initialAlpha, gamma, a, b, dim, nEpochs, nVertices, threadsPerWorkgroupDim, threadsPerYDimension, divisionFactor);\n // head/tail\n const matrixStorage32Size = headSize * 2;\n let paddedMatrixStorageSize = matrixStorage32Size * 4;\n const remainder1 = paddedMatrixStorageSize & 15;\n if (remainder1 !== 0)\n paddedMatrixStorageSize += 16 - remainder1;\n const epochStorage32Size = headSize * 4;\n let paddedepochStorageSize = epochStorage32Size * 4;\n const remainder2 = paddedepochStorageSize & 15;\n if (remainder2 !== 0)\n paddedepochStorageSize += 16 - remainder2;\n const embedStorage32Size = embeddingSize * 2 * 2;\n let paddedembedStorageSize = embedStorage32Size * 4;\n const remainder3 = paddedembedStorageSize & 15;\n if (remainder3 !== 0)\n paddedembedStorageSize += 16 - remainder3;\n const comuteInfo32Size = 2 + headSize;\n let paddedComputeInfoSize = comuteInfo32Size * 4;\n const remainder4 = paddedComputeInfoSize & 15;\n if (remainder4 !== 0)\n paddedComputeInfoSize += 16 - remainder4;\n const module = device.createShaderModule({\n label: 'optimizeShader',\n code: processWGSL\n });\n const pipeline = device.createComputePipeline({\n label: 'optimizePipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'optimizeStep',\n },\n });\n const matrixStorageBuffer = device.createBuffer({\n label: 'matrix storage buffer',\n size: paddedMatrixStorageSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const matrixStorageArrayBuffer = matrixStorageBuffer.getMappedRange();\n const headView = new Uint32Array(matrixStorageArrayBuffer, 0, headSize);\n headView.set(head);\n const tailView = new Uint32Array(matrixStorageArrayBuffer, headSize * 4, headSize);\n tailView.set(tail);\n matrixStorageBuffer.unmap();\n const epochStorageBuffer = device.createBuffer({\n label: 'epoch storage buffer',\n size: paddedepochStorageSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const epochStorageArrayBuffer = epochStorageBuffer.getMappedRange();\n // all are float32 so we get the whole view\n const epochStorageArrayView = new Float32Array(epochStorageArrayBuffer);\n // first epochsPerSample\n epochStorageArrayView.set(epochsPerSample, 0);\n //epochOfNextSample, set to same\n epochStorageArrayView.set(epochsPerSample, headSize);\n //epochsPerNegativeSample\n epochStorageArrayView.set(epochsPerNegativeSample, headSize * 2);\n //epochOfNextNegativeSample\n epochStorageArrayView.set(epochsPerNegativeSample, headSize * 3);\n epochStorageBuffer.unmap();\n const headEmbeddings = new Int32Array(embeddingSize * dim).map(() => Math.floor((Math.random() * 2 - 1) * divisionFactor));\n const tailEmbeddings = new Int32Array(embeddingSize * dim);\n tailEmbeddings.set(headEmbeddings);\n const embeddingStorageBuffer = device.createBuffer({\n label: 'embedding storage buffer',\n size: paddedembedStorageSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedEmbeddingStorageBuffer = embeddingStorageBuffer.getMappedRange();\n const mappedEmbeddingStorageArray = new Int32Array(mappedEmbeddingStorageBuffer);\n mappedEmbeddingStorageArray.set(headEmbeddings, 0);\n mappedEmbeddingStorageArray.set(headEmbeddings, headEmbeddings.length);\n embeddingStorageBuffer.unmap();\n const computeInfoBuffer = device.createBuffer({\n label: 'compute info buffer',\n size: paddedComputeInfoSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const randomNumbers = new Uint32Array(headSize).map(() => Math.floor(Math.random() * divisionFactor));\n const computeInfoArrayBuffer = computeInfoBuffer.getMappedRange();\n const computeInfoMappedArray = new Float32Array(computeInfoArrayBuffer, 0, 2);\n computeInfoMappedArray.set([0.0, initialAlpha]);\n const randomNumbersView = new Uint32Array(computeInfoArrayBuffer, 8, headSize);\n randomNumbersView.set(randomNumbers);\n computeInfoBuffer.unmap();\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for optimize',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: matrixStorageBuffer } },\n { binding: 1, resource: { buffer: epochStorageBuffer } },\n { binding: 2, resource: { buffer: embeddingStorageBuffer } },\n { binding: 3, resource: { buffer: computeInfoBuffer } }\n ],\n });\n let alpha = initialAlpha;\n const outEmbedViewBuffer = device.createBuffer({\n label: 'result buffer',\n size: embeddingStorageBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n for (let iter = 0; iter < nEpochs; iter++) {\n // write n and alpha\n device.queue.writeBuffer(computeInfoBuffer, 0, new Float32Array([iter, alpha]), 0);\n const encoder = device.createCommandEncoder({\n label: 'matrix ops encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'matrix ops compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n // here, we copy the head/tail views to their correct places in embeddings.\n if (iter === nEpochs - 1)\n encoder.copyBufferToBuffer(embeddingStorageBuffer, 0, outEmbedViewBuffer, 0, outEmbedViewBuffer.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n alpha = initialAlpha * (1.0 - iter / nEpochs);\n }\n yield outEmbedViewBuffer.mapAsync(GPUMapMode.READ);\n const resArrayBuffer = outEmbedViewBuffer.getMappedRange();\n const headEmbeddingsView = new Int32Array(resArrayBuffer, 0, headEmbeddings.length);\n headEmbeddings.set(headEmbeddingsView);\n outEmbedViewBuffer.unmap();\n const result = new Array(dim).fill(null).map((_) => new Float32Array(embeddingSize));\n for (let i = 0; i < embeddingSize; i++) {\n for (let j = 0; j < dim; j++)\n result[j][i] = headEmbeddings[i * dim + j] / divisionFactor;\n }\n matrixStorageBuffer.destroy();\n epochStorageBuffer.destroy();\n embeddingStorageBuffer.destroy();\n computeInfoBuffer.destroy();\n outEmbedViewBuffer.destroy();\n return result;\n });\n}\n//# sourceMappingURL=optimization-loop.js.map","/* eslint-disable max-len */\nexport function optimizeLayoutWGSL(headSize, embedSize, moveOther, initialAlpha, gamma, a, b, dim, nEpochs, nVertices, workgroupDim, threadsPerRow, divisionFactor = 100000) {\n return `\n// first define some functions\n\nfn rDist(ar1: array<f32, ${dim}>, ar2: array<f32, ${dim}>) -> f32 {\n var res = 0.0;\n for (var i1 = 0u; i1 < ${dim}; i1++) {\n let diff = ar1[i1] - ar2[i1];\n res += pow(diff, 2);\n }\n return res;\n}\n\nfn clip(x: f32, clipValue: f32) -> f32 {\n if (x > clipValue) {\n return clipValue;\n }\n else if (x < 0.0 - clipValue) {\n return 0.0 - clipValue;\n }\n return x;\n}\n\nvar<private> randomSeedInt: u32 = 0;\nvar<private> nVertices: u32 = ${nVertices};\nvar<private> initialAlpha: f32 = ${initialAlpha};\nvar<private> gamma: f32 = ${gamma};\nvar<private> a: f32 = ${a};\nvar<private> b: f32 = ${b};\nvar<private> dim: u32 = ${dim};\nvar<private> nEpochs: f32 = ${nEpochs};\nvar<private> moveOther: u32 = ${moveOther === true ? 1 : 0};\n\nfn random() -> u32 {\n randomSeedInt = (randomSeedInt ^ 61) ^ (randomSeedInt >> 16);\n randomSeedInt *= 9;\n randomSeedInt = randomSeedInt ^ (randomSeedInt >> 4);\n randomSeedInt *= 0x27d4eb2d;\n randomSeedInt = randomSeedInt ^ (randomSeedInt >> 15);\n return randomSeedInt;\n}\n\nfn randInt(maxVal: u32) -> u32 {\n let nextRandomNum = random();\n return u32(floor((f32(nextRandomNum) * (f32(maxVal) / 4294967296.0))));\n}\n\nstruct MatrixStorage {\n head: array<u32, ${headSize}>,\n tail: array<u32, ${headSize}>,\n}\n\nstruct EpochStorage {\n epochsPerSample: array<f32, ${headSize}>,\n epochOfNextSample: array<f32, ${headSize}>,\n epochsPerNegativeSample: array<f32, ${headSize}>,\n epochOfNextNegativeSample: array<f32, ${headSize}>\n}\n\nstruct EmbeddingStorage {\n // embeddings will be in range of -10 to 10, as atomics only can store i32 or u32, we will store them as floor(f32 * 100_000)\n headEmbeddings: array<array<atomic<i32>, ${dim}>, ${embedSize}>,\n tailEmbeddings: array<array<atomic<i32>, ${dim}>, ${embedSize}>\n}\n\nstruct ComputeInfo {\n n: f32,\n alpha: f32,\n randomNumbers: array<u32, ${headSize}>,\n //tailOffsets: array<u32, ${embedSize + 1}>\n}\n @group(0) @binding(0) var<storage, read_write> matrixStorage: MatrixStorage;\n @group(0) @binding(1) var<storage, read_write> epochStorage: EpochStorage;\n @group(0) @binding(2) var<storage, read_write> embedStorage: EmbeddingStorage;\n @group(0) @binding(3) var<storage, read_write> computeInfo: ComputeInfo;\n @compute @workgroup_size(${workgroupDim}, ${workgroupDim}) fn optimizeStep(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let divisionFactor: f32 = ${divisionFactor};\n let col: u32 = id.x;\n let row: u32 = id.y;\n let threadIndex: u32 = row * ${threadsPerRow} + col;\n let clipValue: f32 = 4.0;\n\n if (threadIndex >= ${headSize}) {\n return;\n }\n\n let workingIndex = threadIndex;\n //let startAtOffset = computeInfo.tailOffsets[threadIndex];\n //let endAtOffset = computeInfo.tailOffsets[threadIndex + 1];\n //for (var workingIndex = startAtOffset; workingIndex < endAtOffset; workingIndex++) {\n randomSeedInt = computeInfo.randomNumbers[workingIndex] * u32(computeInfo.n);\n\n let epochOfNextSample = epochStorage.epochOfNextSample[workingIndex];\n if (epochOfNextSample > computeInfo.n) {\n return;\n }\n\n let j = matrixStorage.head[workingIndex];\n let k = matrixStorage.tail[workingIndex];\n\n // as said before, we will store embeddings as floor(f32 * 100_000)\n var current: array<f32, ${dim}>;\n var other: array<f32, ${dim}>;\n for (var i = 0u; i < ${dim}u; i++) {\n current[i] = f32(atomicLoad(&embedStorage.headEmbeddings[j][i])) / divisionFactor;\n other[i] = f32(atomicLoad(&embedStorage.tailEmbeddings[k][i])) / divisionFactor;\n }\n\n let distSquared = rDist(current, other);\n \n var gradCoeff: f32 = 0.0;\n if (distSquared > 0.0) {\n gradCoeff = (0.0 - 2.0) * ${a} * ${b} * pow(distSquared, b - 1.0);\n gradCoeff /= (a * pow(distSquared, b) + 1.0);\n }\n\n var gradBuff: array<i32, ${dim}>;\n for (var d = 0u; d < ${dim}u; d++) {\n let gradD = clip((gradCoeff * (current[d] - other[d])), clipValue);\n let toAdd = gradD * computeInfo.alpha;\n gradBuff[d] = i32(floor(toAdd * divisionFactor));\n current[d] += toAdd;\n other[d] -= toAdd;\n }\n\n for (var d = 0u; d < ${dim}u; d++) {\n atomicAdd(&embedStorage.headEmbeddings[j][d], gradBuff[d]);\n atomicSub(&embedStorage.tailEmbeddings[k][d], gradBuff[d]);\n }\n\n epochStorage.epochOfNextSample[workingIndex] += epochStorage.epochsPerSample[workingIndex];\n var nNegSamples: i32 = i32(floor((computeInfo.n - epochStorage.epochOfNextNegativeSample[workingIndex]) / epochStorage.epochsPerNegativeSample[workingIndex]));\n\n for (var p = 0i; p < nNegSamples; p++) {\n let k1 = randInt(nVertices);\n var other1: array<f32, ${dim}>;\n for (var i = 0u; i < ${dim}u; i++) {\n other1[i] = f32(atomicLoad(&embedStorage.tailEmbeddings[k1][i])) / divisionFactor;\n }\n\n let distSquared1 = rDist(current, other1);\n\n var gradCoeff1: f32 = 0.0;\n if (distSquared1 > 0.0) {\n gradCoeff1 = 2.0 * gamma * b;\n gradCoeff1 /= (0.001 + distSquared1) * (a * pow(distSquared1, b) + 1);\n }\n else if (j == k1) {\n continue;\n }\n\n var gradDBuff: array<i32, ${dim}>;\n for (var d = 0u; d < ${dim}u; d++) {\n var gradD: f32 = 4.0;\n if (gradCoeff1 > 0.0) {\n gradD = clip(gradCoeff1 * (current[d] - other1[d]), clipValue);\n }\n\n gradDBuff[d] = i32(floor(gradD * computeInfo.alpha * divisionFactor));\n \n }\n for (var d = 0u; d < ${dim}u; d++) {\n atomicAdd(&embedStorage.headEmbeddings[j][d], gradDBuff[d]);\n }\n }\n epochStorage.epochOfNextNegativeSample[workingIndex] += f32(nNegSamples) * epochStorage.epochsPerNegativeSample[workingIndex];\n //}\n }\n`;\n}\n//# sourceMappingURL=optimization-loop.wgsl.js.map","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 { getGPUDevice } from '../getGPUDevice';\nimport { computeMembershipStrengthsWGSL } from './wgsl/membership-strengths.wgsl';\nexport function computeMembershipStrengths(knnDistances, sigmas, rhos) {\n return __awaiter(this, void 0, void 0, function* () {\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const numOfEntries = knnDistances.length;\n const requiredWorkgroups = Math.ceil(numOfEntries / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const processWgsl = computeMembershipStrengthsWGSL(threadsPerWorkgroupDim, threadsPerWorkgroupDim * numOfWorkgroupsPerDim, knnDistances, sigmas, rhos);\n const distanceBuffer32Size = numOfEntries * knnDistances[0].length;\n const device = yield getGPUDevice();\n if (device == null)\n return;\n const module = device.createShaderModule({\n label: 'rowsColsValsCalulation',\n code: processWgsl\n });\n const pipeline = device.createComputePipeline({\n label: 'rowsColsValsPipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'computeMembershipStrengths',\n },\n });\n const rhos32Size = rhos.length;\n const sigmas32Size = sigmas.length;\n const combinedMembershipStrengthsInfo32Size = rhos32Size + sigmas32Size + distanceBuffer32Size;\n let paddedCombinedMembershipStructByteSize = combinedMembershipStrengthsInfo32Size * 4;\n const remainder = paddedCombinedMembershipStructByteSize & 15;\n if (remainder != 0)\n paddedCombinedMembershipStructByteSize += 16 - remainder;\n // input params\n const membershipStrengthsInfoBuffer = device.createBuffer({\n label: 'info buffer',\n size: paddedCombinedMembershipStructByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedInfoBuffer = membershipStrengthsInfoBuffer.getMappedRange();\n const mappedInfoArray = new Float32Array(mappedInfoBuffer);\n // first set knn distances\n for (let i = 0; i < knnDistances.length; i++)\n mappedInfoArray.set(knnDistances[i], i * knnDistances[i].length);\n let offset = knnDistances[0].length * knnDistances.length;\n // now set sigmas\n mappedInfoArray.set(sigmas, offset);\n offset += sigmas.length;\n // now set rhos\n mappedInfoArray.set(rhos, offset);\n membershipStrengthsInfoBuffer.unmap();\n const knnDistancesBuffer = device.createBuffer({\n label: 'knn distance buffer',\n size: knnDistances[0].length * knnDistances.length * Float32Array.BYTES_PER_ELEMENT,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n });\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for membership strhegths buffers',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: membershipStrengthsInfoBuffer } },\n { binding: 1, resource: { buffer: knnDistancesBuffer } },\n // { binding: 4, resource: { buffer: arraySizesBuffer } },\n ],\n });\n const encoder = device.createCommandEncoder({\n label: 'membership strengths encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'membership strengths compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n const resultBufferDistances = device.createBuffer({\n label: 'result buffer distances',\n size: knnDistancesBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n encoder.copyBufferToBuffer(knnDistancesBuffer, 0, resultBufferDistances, 0, resultBufferDistances.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n yield resultBufferDistances.mapAsync(GPUMapMode.READ);\n const resultKnnDistancesArrayBuffer = resultBufferDistances.getMappedRange();\n const bytesPerKnnRow = knnDistances[0].length * Float32Array.BYTES_PER_ELEMENT;\n const resKnnDistances = new Array(knnDistances.length).fill(null).map((_, i) => {\n const dataView = new Float32Array(resultKnnDistancesArrayBuffer, bytesPerKnnRow * i, knnDistances[0].length);\n const out = new Float32Array(knnDistances[0].length);\n out.set(dataView);\n return out;\n });\n resultBufferDistances.unmap();\n resultBufferDistances.destroy();\n knnDistancesBuffer.destroy();\n membershipStrengthsInfoBuffer.destroy();\n return resKnnDistances;\n });\n}\n//# sourceMappingURL=membership-strengths.js.map","/* eslint-disable max-len */\nexport function computeMembershipStrengthsWGSL(threadsPerWorkgroupDim = 10, threadsPerYDimension, knnDistances, sigmas, rhos) {\n const numOfEntries = knnDistances.length;\n const sigmasLength = sigmas.length;\n const rhosLength = rhos.length;\n // TODO: do it with structs\n return `\n struct MembershipStrengthsInfo {\n knnDistances: array<array<f32, ${knnDistances[0].length}>, ${numOfEntries}>,\n sigmas: array<f32, ${sigmasLength}>,\n rhos: array<f32, ${rhosLength}>\n };\n var<private> nNeighbors: u32 = ${knnDistances[0].length};\n @group(0) @binding(0) var<storage, read> membershipStrengthsInfo: MembershipStrengthsInfo;\n @group(0) @binding(1) var<storage, read_write> resultKnnDistances: array<array<f32, ${knnDistances[0].length}>, ${numOfEntries}>;\n @compute @workgroup_size(${threadsPerWorkgroupDim}, ${threadsPerWorkgroupDim}) fn computeMembershipStrengths(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let col: u32 = id.x;\n let row: u32 = id.y;\n let workingIndex: u32 = row * ${threadsPerYDimension} + col;\n\n if (workingIndex >= ${numOfEntries}) {\n return;\n }\n\n let workingResKnnDistances = &resultKnnDistances[workingIndex];\n let knnDistances = &membershipStrengthsInfo.knnDistances[workingIndex];\n for (var j = 0u; j < nNeighbors; j = j + 1u) {\n var val: f32 = 0.0;\n\n if ((*knnDistances)[j] - membershipStrengthsInfo.rhos[workingIndex] <= 0.0) {\n val = 1.0;\n } else {\n val = exp(0.0 - ((knnDistances[j] - membershipStrengthsInfo.rhos[workingIndex]) / membershipStrengthsInfo.sigmas[workingIndex])); \n }\n\n (*workingResKnnDistances)[j] = val;\n }\n }\n `;\n}\n//# sourceMappingURL=membership-strengths.wgsl.js.map","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 { findABParams, getNEpochs, toOffsetForm } from './utils';\nexport function initializeSimplicialSetEmbedding(graph, entryLen, spread, minDist, negativeSampleRate = 5) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!graph.unionSizes)\n return;\n const nEpochs = getNEpochs(entryLen);\n const nComponents = 2; // todo: support mult dims\n // get max value:\n const maxVal = graph.res.resultKnnDistances.reduce((prev, cur) => Math.max(prev, cur));\n //let offsetAccum = 0;\n // for (let i = 0; i < graph.unionSizes.length; i++) {\n // for (let j = 0; j < graph.unionSizes)\n // }\n const minGraphVal = maxVal / nEpochs;\n // this will hold the sizes of arrays with all zeros removed.\n const unionSizesCopy = new Uint32Array(graph.unionSizes.length);\n unionSizesCopy.set(graph.unionSizes);\n let offsetAccum = 0;\n for (let i = 0; i < graph.unionSizes.length; i++) {\n for (let j = 0; j < graph.unionSizes[i]; j++) {\n const index = offsetAccum + j;\n if (graph.res.resultKnnDistances[index] < minGraphVal) {\n graph.res.resultKnnDistances[index] = 0;\n unionSizesCopy[i]--;\n }\n }\n offsetAccum += graph.unionSizes[i];\n }\n const nonZeroGraphOffsets = toOffsetForm(unionSizesCopy);\n const nonZeroGraphSize = nonZeroGraphOffsets[nonZeroGraphOffsets.length - 1];\n const weights = new Float32Array(nonZeroGraphSize);\n const head = new Uint32Array(nonZeroGraphSize);\n const tail = new Uint32Array(nonZeroGraphSize);\n offsetAccum = 0;\n for (let i = 0; i < graph.unionSizes.length; i++) {\n for (let j = 0; j < graph.unionSizes[i]; j++) {\n const index = graph.unionMatrixOffsets[i] + j;\n if (graph.res.resultKnnDistances[index] != 0) {\n weights[offsetAccum] = graph.res.resultKnnDistances[index];\n head[offsetAccum] = graph.res.resultKnnIndexes[index];\n tail[offsetAccum] = i;\n offsetAccum += 1;\n }\n }\n }\n const epochsPerSample = new Float32Array(weights.length).fill(-1);\n const nSamples = weights.map((w) => (w / maxVal) * nEpochs);\n nSamples.forEach((n, i) => {\n if (n > 0)\n epochsPerSample[i] = nEpochs / nSamples[i];\n });\n const { a, b } = findABParams(spread, minDist);\n const epochsPerNegativeSample = epochsPerSample.map((e) => e / negativeSampleRate);\n const gamma = 1.0;\n const initialAlpha = 1.0;\n return { epochsPerSample, epochsPerNegativeSample, a, b,\n head, tail, entryLen, nEpochs, nComponents, initialAlpha, gamma };\n });\n}\n//# sourceMappingURL=simplical-set-embedding.js.map","import { Vector } from '@datagrok-libraries/utils/src/type-declarations';\nimport { AvailableMetrics, Measure, isBitArrayMetric } from '../typed-metrics';\nimport { DistanceMatrixService } from '../distance-matrix';\nimport { UMAP } from '../umap';\nimport { assert, transposeMatrix } from '@datagrok-libraries/utils/src/vector-operations';\nimport { SparseMatrixService } from '../distance-matrix/sparse-matrix-service';\nimport BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport seedRandom from 'seedrandom';\n//import {TSNE} from '@keckelt/tsne';\nimport { TSNE } from '../t-sne/t-sne';\nimport { multiColWebGPUKNN } from '@datagrok-libraries/math';\nimport { WebGPUUMAP } from '@datagrok-libraries/math/src/webGPU/umap';\nclass MultiColumnReducer {\n constructor(options) {\n this.data = options.data;\n this.weights = options.weights;\n this.aggregationMethod = options.aggregationMethod;\n }\n}\nclass TSNEReducer extends MultiColumnReducer {\n /**\n * Creates an instance of TSNEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof TSNEReducer\n */\n constructor(options) {\n super(options);\n const randomSeed = options.randomSeed ?? Date();\n const randomFn = seedRandom(randomSeed);\n options.dim = 2; // TODO: make it configurable\n options.random = randomFn;\n this.reducer = new TSNE(options);\n this.iterations = options?.iterations ?? this.reducer.getIterSize(this.data[0].length);\n this.distanceFnames = options.distanceFnames;\n this.distanceFns = options.distanceFns;\n this.distanceFnArgs = options.distanceFnArgs;\n this.progressFunc = options.progressFunc;\n }\n /**\n * Embeds the data given into the two-dimensional space using t-SNE method.\\\n * @param {boolean} [parallelDistanceWorkers] Whether to use parallel distance workers.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n if (this.data[0].length > 10000)\n throw new Error('Maximum number of samples for T-SNE is 10000');\n const matrixService = new DistanceMatrixService(true, false);\n try {\n // const aggregate = getAggregationFunction(this.aggregationMethod, this.weights);\n // const distances: Array<Float32Array> = [];\n // for (let i = 0; i < this.data.length; ++i) {\n // const dist = await matrixService.calc(this.data[i], this.distanceFnames[i], false, this.distanceFnArgs[i]);\n // distances.push(dist);\n // }\n // const distance = new Float32Array(distances[0].length).fill(0);\n // for (let i = 0; i < distances[0].length; ++i)\n // distance[i] = aggregate(distances.map((d) => d[i]));\n const distance = await matrixService.calcMulti(this.data, this.distanceFnames, false, this.distanceFnArgs, this.weights, this.aggregationMethod);\n matrixService.terminate();\n // const matrixProxy = distanceMatrixProxy(distance, this.data[0].length);\n this.reducer.initDataDist(distance, this.data[0].length);\n for (let i = 0; i < this.iterations; ++i) {\n this.reducer.step(); // every time you call this, solution gets better\n if (this.progressFunc)\n this.progressFunc(i, this.iterations, []);\n }\n return this.reducer.getSolution();\n }\n catch (e) {\n matrixService.terminate();\n throw e;\n }\n }\n}\nclass UMAPReducer extends MultiColumnReducer {\n /**\n * Creates an instance of UMAPReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof UMAPReducer\n */\n constructor(options) {\n const randomSeed = options.randomSeed ?? Date();\n const randomFn = seedRandom(randomSeed);\n super(options);\n this.useWebGPU = false;\n assert('distanceFnames' in options);\n assert('distanceFns' in options);\n this.distanceFnArgs = options.distanceFnArgs;\n this.distanceFns = options.distanceFns;\n this.progressFunc = options.progressFunc;\n this.useWebGPU = options.useWebGPU ?? false;\n this.distanceFnames = options.distanceFnames;\n options.nComponents = 2; // TODO: make it configurable\n //Umap uses vector indexing, so we need to create an array of vectors as indeces.\n this.vectors = new Array(this.data[0].length).fill(0).map((_, i) => i);\n if (this.data[0].length <= (options.nNeighbors ?? 15))\n options.nNeighbors = this.data[0].length - 1;\n options.random = randomFn;\n this.reducer = new UMAP(options);\n // this.reducer.distanceFn = this._encodedDistance.bind(this);\n }\n /**\n * Embeds the data given into the two-dimensional space using UMAP method.\n * @param {boolean} [_parallelDistanceWorkers] Whether to use parallel distance matrix workers.\n * @return {any} Cartesian coordinate of this embedding.\n */\n async transform(_parallelDistanceWorkers) {\n console.time('knn graph');\n let knnGraph = undefined;\n if (this.useWebGPU) {\n try {\n knnGraph = await multiColWebGPUKNN(this.data, this.reducer.neighbors, this.distanceFnames, this.aggregationMethod, this.weights, this.distanceFnArgs);\n }\n catch (e) {\n console.error(e);\n }\n }\n if (!knnGraph) {\n if (this.useWebGPU)\n console.error('WEBGPU KNN failed, falling back to multithreaded CPU implementation');\n knnGraph = await new SparseMatrixService()\n .multiColumnKNN(this.data, this.distanceFnames, this.reducer.neighbors, this.distanceFnArgs, this.weights, this.aggregationMethod);\n }\n console.timeEnd('knn graph');\n if (this.useWebGPU) {\n this.webGPUReducer = new WebGPUUMAP(this.vectors.length, {\n nComponents: this.reducer.nComponents,\n gamma: this.reducer.repulsionStrength,\n alpha: this.reducer.learningRate,\n nNeighbours: this.reducer.neighbors,\n spread: this.reducer.spread,\n minDist: this.reducer.minDist,\n negativeSampleRate: this.reducer.negativeSampleRate,\n localConnectivity: this.reducer.localConnectivity,\n setOpMixRatio: this.reducer.setOpMixRatio,\n });\n this.webGPUReducer.setPrecomputedKNN(knnGraph.knnIndexes, knnGraph.knnDistances);\n }\n else {\n this.reducer.setPrecomputedKNN(knnGraph.knnIndexes, knnGraph.knnDistances);\n }\n // needed so that garbage collector can free memory from distance matrix\n await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, 300);\n });\n let embedding = null;\n console.time('fit');\n try {\n if (this.useWebGPU && this.webGPUReducer) {\n embedding = await this.webGPUReducer.fit();\n if (!embedding)\n throw new Error('Failed to compute embedding');\n embedding = // transpose TODO: do a better job here\n new Array(embedding[0].length).fill(null).map((_, i) => new Float32Array(embedding.map((v) => v[i])));\n }\n }\n catch (e) {\n console.error(e);\n }\n if (!embedding) {\n if (this.useWebGPU)\n console.error('WEBGPU UMAP failed, falling back to CPU implementation');\n embedding = await this.reducer.fitAsync(this.vectors, (epoc) => {\n if (this.progressFunc)\n this.progressFunc(epoc, this.reducer.getNEpochs(), this.reducer.getEmbedding());\n });\n }\n console.timeEnd('fit');\n return arrayCast2Coordinates(embedding);\n function arrayCast2Coordinates(data) {\n return new Array(data.length).fill(0).map((_, i) => (Vector.from(data[i])));\n }\n }\n}\nconst AvailableReducers = {\n 'UMAP': UMAPReducer,\n 't-SNE': TSNEReducer,\n};\nexport class MultiColDimReducer {\n /**\n * Creates an instance of DimensionalityReducer.\n * @param {any[]} data Vectors to embed.\n * @param {KnownMethods} method Embedding method to be applied\n * @param {KnownMetrics} metric Distance metric to be computed between each of the vectors.\n * @param {Options} [options] Options to pass to the implementing embedders.\n * @memberof DimensionalityReducer\n */\n constructor(data, method, metrics, weights, distanceAggregation, options) {\n const measures = [];\n for (let idx = 0; idx < metrics.length; ++idx) {\n const measure = new Measure(metrics[idx]).getMeasure(options.distanceFnArgs[idx]);\n measures.push(measure);\n let bitArrayLength = 2048;\n for (let i = 0; i < data[idx].length; ++i) {\n if (data[idx][i] && data[idx][i]._length) {\n bitArrayLength = data[idx][i]._length;\n break;\n }\n }\n if (isBitArrayMetric(metrics[idx])) {\n for (let i = 0; i < data[idx].length; ++i) {\n if (data[idx][i] && data[idx][i]._data)\n data[idx][i] = new BitArray(data[idx][i]._data, data[idx][i]._length);\n else\n data[idx][i] = new BitArray(bitArrayLength);\n }\n }\n }\n if (method == 'UMAP') {\n this.reducer = new UMAPReducer({\n data: data,\n distanceFnames: metrics,\n distanceFns: measures,\n distanceFnArgs: options.distanceFnArgs,\n weights: weights,\n aggregationMethod: distanceAggregation,\n ...options\n });\n }\n else if (method == 't-SNE') {\n this.reducer = new TSNEReducer({\n data: data,\n distanceFnames: metrics,\n distanceFns: measures,\n distanceFnArgs: options.distanceFnArgs,\n weights: weights,\n aggregationMethod: distanceAggregation,\n ...options\n });\n }\n }\n /**\n * Embeds the data given into the two-dimensional space using the chosen method.\n *\n * @param {boolean} transpose Whether to transform coordinates to have columns-first orientation.\n * @param {boolean} parallelDistanceWorkers Whether to use parallel distance computation.\n * @throws {Error} If the embedding method was not found.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n * @memberof DimensionalityReducer\n */\n async transform(transpose = false) {\n if (this.reducer === undefined)\n throw new Error('Reducer was not defined.');\n let embedding = await this.reducer.transform();\n if (transpose)\n embedding = transposeMatrix(embedding);\n return embedding;\n }\n /**\n * Returns metrics available by type.\n *\n * @param {AvailableDataTypes} typeName type name\n * @return {string[]} Metric names which expects the given data type\n * @memberof DimensionalityReducer\n */\n static availableMetricsByType(typeName) {\n return Object.keys(AvailableMetrics[typeName]);\n }\n /**\n * Returns dimensionality reduction methods available.\n *\n * @readonly\n * @memberof DimensionalityReducer\n */\n static get availableMethods() {\n return Object.keys(AvailableReducers);\n }\n /**\n * Returns metrics available.\n *\n * @readonly\n * @memberof DimensionalityReducer\n */\n static get availableMetrics() {\n let ans = [];\n Object.values(AvailableMetrics).forEach((obj) => {\n const array = Object.values(obj);\n ans = [...ans, ...array];\n });\n return ans;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktY29sdW1uLWRpbS1yZWR1Y2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibXVsdGktY29sdW1uLWRpbS1yZWR1Y2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBK0MsTUFBTSxFQUFVLE1BQy9ELGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBcUIsZ0JBQWdCLEVBQWdCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQy9HLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBRXpELE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFDN0IsT0FBTyxFQUFDLE1BQU0sRUFBRSxlQUFlLEVBQUMsTUFBTSxpREFBaUQsQ0FBQztBQUN4RixPQUFPLEVBQVksbUJBQW1CLEVBQUMsTUFBTSwwQ0FBMEMsQ0FBQztBQUV4RixPQUFPLFFBQVEsTUFBTSx5Q0FBeUMsQ0FBQztBQUMvRCxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFDcEMscUNBQXFDO0FBQ3JDLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwQyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sMENBQTBDLENBQUM7QUFpQ3BFLE1BQWUsa0JBQWtCO0lBSTdCLFlBQVksT0FBZ0I7UUFDMUIsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztRQUMvQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDO0lBQ3JELENBQUM7Q0FLSjtBQUVELE1BQU0sV0FBWSxTQUFRLGtCQUFrQjtJQU94Qzs7OztPQUlHO0lBQ0gsWUFBWSxPQUFnQjtRQUMxQixLQUFLLENB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Q0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUM5QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pDLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29vcmRpbmF0ZXMsIERpc3RhbmNlTWV0cmljLCBNYXRyaXgsIE9wdGlvbnMsIFZlY3RvciwgVmVjdG9yc31cbiAgZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdHlwZS1kZWNsYXJhdGlvbnMnO1xuaW1wb3J0IHtBdmFpbGFibGVEYXRhVHlwZXMsIEF2YWlsYWJsZU1ldHJpY3MsIEtub3duTWV0cmljcywgTWVhc3VyZSwgaXNCaXRBcnJheU1ldHJpY30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQge0Rpc3RhbmNlTWF0cml4U2VydmljZX0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4JztcbmltcG9ydCB7RGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZH0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3R5cGVzJztcbmltcG9ydCB7VU1BUH0gZnJvbSAnLi4vdW1hcCc7XG5pbXBvcnQge2Fzc2VydCwgdHJhbnNwb3NlTWF0cml4fSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy92ZWN0b3Itb3BlcmF0aW9ucyc7XG5pbXBvcnQge0tublJlc3VsdCwgU3BhcnNlTWF0cml4U2VydmljZX0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3NwYXJzZS1tYXRyaXgtc2VydmljZSc7XG5pbXBvcnQge0RpbVJlZHVjdGlvbk1ldGhvZHN9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQgc2VlZFJhbmRvbSBmcm9tICdzZWVkcmFuZG9tJztcbi8vaW1wb3J0IHtUU05FfSBmcm9tICdAa2Vja2VsdC90c25lJztcbmltcG9ydCB7VFNORX0gZnJvbSAnLi4vdC1zbmUvdC1zbmUnO1xuaW1wb3J0IHttdWx0aUNvbFdlYkdQVUtOTn0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy9tYXRoJztcbmltcG9ydCB7V2ViR1BVVU1BUH0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy9tYXRoL3NyYy93ZWJHUFUvdW1hcCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVVNQVBPcHRpb25zIHtcbiAgICBsZWFybmluZ1JhdGU/OiBudW1iZXI7XG4gICAgbkNvbXBvbmVudHM/OiBudW1iZXI7XG4gICAgbkVwb2Nocz86IG51bWJlcjtcbiAgICBuTmVpZ2hib3JzPzogbnVtYmVyO1xuICAgIHNwcmVhZD86IG51bWJlcjtcbiAgICBtaW5EaXN0PzogbnVtYmVyO1xuICAgIHByb2dyZXNzRnVuYz86IChlcG9jOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmdzOiBudW1iZXJbXVtdKSA9PiB2b2lkO1xuICAgIHJhbmRvbVNlZWQ/OiBzdHJpbmc7XG4gICAgdXNlV2ViR1BVPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVFNORU9wdGlvbnMge1xuICAgIGVwc2lsb24/OiBudW1iZXI7XG4gICAgcGVycGxleGl0eT86IG51bWJlcjtcbiAgICBkaW0/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSURpbVJlZHVjdGlvblBhcmFtPFQgZXh0ZW5kcyBudW1iZXIgfCBzdHJpbmcgfCBib29sZWFuID0gbnVtYmVyPiB7XG4gICAgdWlOYW1lOiBzdHJpbmc7XG4gICAgdmFsdWU6IChUIGV4dGVuZHMgbnVtYmVyID8gbnVtYmVyIDogVCBleHRlbmRzIHN0cmluZyA/IHN0cmluZyA6IGJvb2xlYW4pIHwgbnVsbDtcbiAgICB0b29sdGlwOiBzdHJpbmc7XG4gICAgdHlwZT86IFQgZXh0ZW5kcyBudW1iZXIgPyAnbnVtYmVyJyA6IFQgZXh0ZW5kcyBzdHJpbmcgPyAnc3RyaW5nJyA6ICdib29sZWFuJztcbiAgICBwbGFjZWhvbGRlcj86IHN0cmluZztcbiAgICBtaW4/OiBudW1iZXI7XG4gICAgbWF4PzogbnVtYmVyO1xuICAgIHN0ZXA/OiBudW1iZXI7XG4gICAgZGlzYWJsZT86IGJvb2xlYW47XG4gICAgZGlzYWJsZVRvb2x0aXA/OiBzdHJpbmc7XG59XG5cbmFic3RyYWN0IGNsYXNzIE11bHRpQ29sdW1uUmVkdWNlciB7XG4gICAgcHJvdGVjdGVkIGRhdGE6IFZlY3RvcnNbXTtcbiAgICBwcm90ZWN0ZWQgd2VpZ2h0czogbnVtYmVyW107XG4gICAgcHJvdGVjdGVkIGFnZ3JlZ2F0aW9uTWV0aG9kOiBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kO1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICAgIHRoaXMuZGF0YSA9IG9wdGlvbnMuZGF0YTtcbiAgICAgIHRoaXMud2VpZ2h0cyA9IG9wdGlvbnMud2VpZ2h0cztcbiAgICAgIHRoaXMuYWdncmVnYXRpb25NZXRob2QgPSBvcHRpb25zLmFnZ3JlZ2F0aW9uTWV0aG9kO1xuICAgIH1cblxuICAgIC8qKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlLlxuICAgICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLiAqL1xuICAgIGFic3RyYWN0IHRyYW5zZm9ybSgpOiBQcm9taXNlPE1hdHJpeD47XG59XG5cbmNsYXNzIFRTTkVSZWR1Y2VyIGV4dGVuZHMgTXVsdGlDb2x1bW5SZWR1Y2VyIHtcbiAgICBwcm90ZWN0ZWQgcmVkdWNlcjogVFNORTtcbiAgICBwcm90ZWN0ZWQgaXRlcmF0aW9uczogbnVtYmVyO1xuICAgIHByb3RlY3RlZCBkaXN0YW5jZUZuYW1lczogS25vd25NZXRyaWNzW107XG4gICAgcHJvdGVjdGVkIGRpc3RhbmNlRm5zOiAoKGE6IGFueSwgYjogYW55KSA9PiBudW1iZXIpW107XG4gICAgcHJvdGVjdGVkIGRpc3RhbmNlRm5BcmdzOiB7W186IHN0cmluZ106IGFueX1bXTtcbiAgICBwcm90ZWN0ZWQgcHJvZ3Jlc3NGdW5jPzogKGVwb2M6IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZ3M/OiBudW1iZXJbXVtdKSA9PiB2b2lkO1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgVFNORVJlZHVjZXIuXG4gICAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgY29uc3RydWN0b3IuXG4gICAgICogQG1lbWJlcm9mIFRTTkVSZWR1Y2VyXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucykge1xuICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICBjb25zdCByYW5kb21TZWVkOiBzdHJpbmcgPSBvcHRpb25zLnJhbmRvbVNlZWQgPz8gRGF0ZSgpO1xuICAgICAgY29uc3QgcmFuZG9tRm4gPSBzZWVkUmFuZG9tKHJhbmRvbVNlZWQpO1xuICAgICAgb3B0aW9ucy5kaW0gPSAyOyAvLyBUT0RPOiBtYWtlIGl0IGNvbmZpZ3VyYWJsZVxuICAgICAgb3B0aW9ucy5yYW5kb20gPSByYW5kb21GbjtcbiAgICAgIHRoaXMucmVkdWNlciA9IG5ldyBUU05FKG9wdGlvbnMpO1xuICAgICAgdGhpcy5pdGVyYXRpb25zID0gb3B0aW9ucz8uaXRlcmF0aW9ucyA/PyB0aGlzLnJlZHVjZXIuZ2V0SXRlclNpemUodGhpcy5kYXRhWzBdLmxlbmd0aCk7XG4gICAgICB0aGlzLmRpc3RhbmNlRm5hbWVzID0gb3B0aW9ucy5kaXN0YW5jZUZuYW1lcztcbiAgICAgIHRoaXMuZGlzdGFuY2VGbnMgPSBvcHRpb25zLmRpc3RhbmNlRm5zO1xuICAgICAgdGhpcy5kaXN0YW5jZUZuQXJncyA9IG9wdGlvbnMuZGlzdGFuY2VGbkFyZ3M7XG4gICAgICB0aGlzLnByb2dyZXNzRnVuYyA9IG9wdGlvbnMucHJvZ3Jlc3NGdW5jO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgdC1TTkUgbWV0aG9kLlxcXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnNdIFdoZXRoZXIgdG8gdXNlIHBhcmFsbGVsIGRpc3RhbmNlIHdvcmtlcnMuXG4gICAgICogQHJldHVybiB7YW55fSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBvZiB0aGlzIGVtYmVkZGluZyBhbmQgZGlzdGFuY2UgbWF0cml4IHdoZXJlIGFwcGxpY2FibGUuXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIHRyYW5zZm9ybSgpOiBQcm9taXNlPE1hdHJpeD4ge1xuICAgICAgaWYgKHRoaXMuZGF0YVswXS5sZW5ndGggPiAxMDAwMClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYXhpbXVtIG51bWJlciBvZiBzYW1wbGVzIGZvciBULVNORSBpcyAxMDAwMCcpO1xuICAgICAgY29uc3QgbWF0cml4U2VydmljZSA9IG5ldyBEaXN0YW5jZU1hdHJpeFNlcnZpY2UodHJ1ZSwgZmFsc2UpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gY29uc3QgYWdncmVnYXRlID0gZ2V0QWdncmVnYXRpb25GdW5jdGlvbih0aGlzLmFnZ3JlZ2F0aW9uTWV0aG9kLCB0aGlzLndlaWdodHMpO1xuICAgICAgICAvLyBjb25zdCBkaXN0YW5jZXM6IEFycmF5PEZsb2F0MzJBcnJheT4gPSBbXTtcbiAgICAgICAgLy8gZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmRhdGEubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgLy8gICBjb25zdCBkaXN0ID0gYXdhaXQgbWF0cml4U2VydmljZS5jYWxjKHRoaXMuZGF0YVtpXSwgdGhpcy5kaXN0YW5jZUZuYW1lc1tpXSwgZmFsc2UsIHRoaXMuZGlzdGFuY2VGbkFyZ3NbaV0pO1xuICAgICAgICAvLyAgIGRpc3RhbmNlcy5wdXNoKGRpc3QpO1xuICAgICAgICAvLyB9XG4gICAgICAgIC8vIGNvbnN0IGRpc3RhbmNlID0gbmV3IEZsb2F0MzJBcnJheShkaXN0YW5jZXNbMF0ubGVuZ3RoKS5maWxsKDApO1xuICAgICAgICAvLyBmb3IgKGxldCBpID0gMDsgaSA8IGRpc3RhbmNlc1swXS5sZW5ndGg7ICsraSlcbiAgICAgICAgLy8gICBkaXN0YW5jZVtpXSA9IGFnZ3JlZ2F0ZShkaXN0YW5jZXMubWFwKChkKSA9PiBkW2ldKSk7XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gYXdhaXQgbWF0cml4U2VydmljZS5jYWxjTXVsdGkodGhpcy5kYXRhLCB0aGlzLmRpc3RhbmNlRm5hbWVzLCBmYWxzZSwgdGhpcy5kaXN0YW5jZUZuQXJncyxcbiAgICAgICAgICB0aGlzLndlaWdodHMsIHRoaXMuYWdncmVnYXRpb25NZXRob2QpO1xuICAgICAgICBtYXRyaXhTZXJ2aWNlLnRlcm1pbmF0ZSgpO1xuICAgICAgICAvLyBjb25zdCBtYXRyaXhQcm94eSA9IGRpc3RhbmNlTWF0cml4UHJveHkoZGlzdGFuY2UsIHRoaXMuZGF0YVswXS5sZW5ndGgpO1xuICAgICAgICB0aGlzLnJlZHVjZXIuaW5pdERhdGFEaXN0KGRpc3RhbmNlLCB0aGlzLmRhdGFbMF0ubGVuZ3RoKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuaXRlcmF0aW9uczsgKytpKSB7XG4gICAgICAgICAgdGhpcy5yZWR1Y2VyLnN0ZXAoKTsgLy8gZXZlcnkgdGltZSB5b3UgY2FsbCB0aGlzLCBzb2x1dGlvbiBnZXRzIGJldHRlclxuICAgICAgICAgIGlmICh0aGlzLnByb2dyZXNzRnVuYylcbiAgICAgICAgICAgIHRoaXMucHJvZ3Jlc3NGdW5jKGksIHRoaXMuaXRlcmF0aW9ucywgW10pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnJlZHVjZXIuZ2V0U29sdXRpb24oKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbWF0cml4U2VydmljZS50ZXJtaW5hdGUoKTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFVNQVBSZWR1Y2VyIGV4dGVuZHMgTXVsdGlDb2x1bW5SZWR1Y2VyIHtcbiAgICBwcm90ZWN0ZWQgcmVkdWNlcjogVU1BUDtcbiAgICBwcm90ZWN0ZWQgZGlzdGFuY2VGbmFtZXM6IEtub3duTWV0cmljc1tdO1xuICAgIHByb3RlY3RlZCBkaXN0YW5jZUZuczogRnVuY3Rpb25bXTtcbiAgICBwcm90ZWN0ZWQgdmVjdG9yczogbnVtYmVyW107XG4gICAgcHJvdGVjdGVkIHByb2dyZXNzRnVuYz86IChlcG9jOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmc6IG51bWJlcltdW10pID0+IHZvaWQ7XG4gICAgcHJvdGVjdGVkIGRpc3RhbmNlRm5BcmdzOiB7W186IHN0cmluZ106IGFueX1bXTtcbiAgICBwcm90ZWN0ZWQgdXNlV2ViR1BVOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIHdlYkdQVVJlZHVjZXI6IFdlYkdQVVVNQVAgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBVTUFQUmVkdWNlci5cbiAgICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKiBAbWVtYmVyb2YgVU1BUFJlZHVjZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zKSB7XG4gICAgICBjb25zdCByYW5kb21TZWVkOiBzdHJpbmcgPSBvcHRpb25zLnJhbmRvbVNlZWQgPz8gRGF0ZSgpO1xuICAgICAgY29uc3QgcmFuZG9tRm4gPSBzZWVkUmFuZG9tKHJhbmRvbVNlZWQpO1xuICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICBhc3NlcnQoJ2Rpc3RhbmNlRm5hbWVzJyBpbiBvcHRpb25zKTtcbiAgICAgIGFzc2VydCgnZGlzdGFuY2VGbnMnIGluIG9wdGlvbnMpO1xuICAgICAgdGhpcy5kaXN0YW5jZUZuQXJncyA9IG9wdGlvbnMuZGlzdGFuY2VGbkFyZ3M7XG4gICAgICB0aGlzLmRpc3RhbmNlRm5zID0gb3B0aW9ucy5kaXN0YW5jZUZucyE7XG4gICAgICB0aGlzLnByb2dyZXNzRnVuYyA9IG9wdGlvbnMucHJvZ3Jlc3NGdW5jO1xuICAgICAgdGhpcy51c2VXZWJHUFUgPSBvcHRpb25zLnVzZVdlYkdQVSA/PyBmYWxzZTtcbiAgICAgIHRoaXMuZGlzdGFuY2VGbmFtZXMgPSBvcHRpb25zLmRpc3RhbmNlRm5hbWVzITtcbiAgICAgIG9wdGlvbnMubkNvbXBvbmVudHMgPSAyOyAvLyBUT0RPOiBtYWtlIGl0IGNvbmZpZ3VyYWJsZVxuICAgICAgLy9VbWFwIHVzZXMgdmVjdG9yIGluZGV4aW5nLCBzbyB3ZSBuZWVkIHRvIGNyZWF0ZSBhbiBhcnJheSBvZiB2ZWN0b3JzIGFzIGluZGVjZXMuXG4gICAgICB0aGlzLnZlY3RvcnMgPSBuZXcgQXJyYXkodGhpcy5kYXRhWzBdLmxlbmd0aCkuZmlsbCgwKS5tYXAoKF8sIGkpID0+IGkpO1xuXG4gICAgICBpZiAodGhpcy5kYXRhWzBdLmxlbmd0aCA8PSAob3B0aW9ucy5uTmVpZ2hib3JzID8/IDE1KSlcbiAgICAgICAgb3B0aW9ucy5uTmVpZ2hib3JzID0gdGhpcy5kYXRhWzBdLmxlbmd0aCAtIDE7XG4gICAgICBvcHRpb25zLnJhbmRvbSA9IHJhbmRvbUZuO1xuICAgICAgdGhpcy5yZWR1Y2VyID0gbmV3IFVNQVAob3B0aW9ucyk7XG4gICAgICAvLyB0aGlzLnJlZHVjZXIuZGlzdGFuY2VGbiA9IHRoaXMuX2VuY29kZWREaXN0YW5jZS5iaW5kKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgVU1BUCBtZXRob2QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbX3BhcmFsbGVsRGlzdGFuY2VXb3JrZXJzXSBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSBtYXRyaXggd29ya2Vycy5cbiAgICAgKiBAcmV0dXJuIHthbnl9IENhcnRlc2lhbiBjb29yZGluYXRlIG9mIHRoaXMgZW1iZWRkaW5nLlxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0oX3BhcmFsbGVsRGlzdGFuY2VXb3JrZXJzPzogYm9vbGVhbik6IFByb21pc2U8TWF0cml4PiB7XG4gICAgICBjb25zb2xlLnRpbWUoJ2tubiBncmFwaCcpO1xuICAgICAgbGV0IGtubkdyYXBoOiBLbm5SZXN1bHQgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICBpZiAodGhpcy51c2VXZWJHUFUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBrbm5HcmFwaCA9IGF3YWl0IG11bHRpQ29sV2ViR1BVS05OKFxuICAgICAgICAgICAgdGhpcy5kYXRhLCB0aGlzLnJlZHVjZXIubmVpZ2hib3JzLCB0aGlzLmRpc3RhbmNlRm5hbWVzIGFzIGFueSwgdGhpcy5hZ2dyZWdhdGlvbk1ldGhvZCBhcyBhbnksXG4gICAgICAgICAgICB0aGlzLndlaWdodHMsIHRoaXMuZGlzdGFuY2VGbkFyZ3NcbiAgICAgICAgICApIGFzIHVua25vd24gYXMgS25uUmVzdWx0O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFrbm5HcmFwaCkge1xuICAgICAgICBpZiAodGhpcy51c2VXZWJHUFUpXG4gICAgICAgICAgY29uc29sZS5lcnJvcignV0VCR1BVIEtOTiBmYWlsZWQsIGZhbGxpbmcgYmFjayB0byBtdWx0aXRocmVhZGVkIENQVSBpbXBsZW1lbnRhdGlvbicpO1xuICAgICAgICBrbm5HcmFwaCA9IGF3YWl0IG5ldyBTcGFyc2VNYXRyaXhTZXJ2aWNlKClcbiAgICAgICAgICAubXVsdGlDb2x1bW5LTk4odGhpcy5kYXRhLCB0aGlzLmRpc3RhbmNlRm5hbWVzLCB0aGlzLnJlZHVjZXIubmVpZ2hib3JzLFxuICAgICAgICAgICAgdGhpcy5kaXN0YW5jZUZuQXJncywgdGhpcy53ZWlnaHRzLCB0aGlzLmFnZ3JlZ2F0aW9uTWV0aG9kKTtcbiAgICAgIH1cbiAgICAgIGNvbnNvbGUudGltZUVuZCgna25uIGdyYXBoJyk7XG4gICAgICBpZiAodGhpcy51c2VXZWJHUFUpIHtcbiAgICAgICAgdGhpcy53ZWJHUFVSZWR1Y2VyID0gbmV3IFdlYkdQVVVNQVAodGhpcy52ZWN0b3JzLmxlbmd0aCwge1xuICAgICAgICAgIG5Db21wb25lbnRzOiB0aGlzLnJlZHVjZXIubkNvbXBvbmVudHMsXG4gICAgICAgICAgZ2FtbWE6IHRoaXMucmVkdWNlci5yZXB1bHNpb25TdHJlbmd0aCxcbiAgICAgICAgICBhbHBoYTogdGhpcy5yZWR1Y2VyLmxlYXJuaW5nUmF0ZSxcbiAgICAgICAgICBuTmVpZ2hib3VyczogdGhpcy5yZWR1Y2VyLm5laWdoYm9ycyxcbiAgICAgICAgICBzcHJlYWQ6IHRoaXMucmVkdWNlci5zcHJlYWQsXG4gICAgICAgICAgbWluRGlzdDogdGhpcy5yZWR1Y2VyLm1pbkRpc3QsXG4gICAgICAgICAgbmVnYXRpdmVTYW1wbGVSYXRlOiB0aGlzLnJlZHVjZXIubmVnYXRpdmVTYW1wbGVSYXRlLFxuICAgICAgICAgIGxvY2FsQ29ubmVjdGl2aXR5OiB0aGlzLnJlZHVjZXIubG9jYWxDb25uZWN0aXZpdHksXG4gICAgICAgICAgc2V0T3BNaXhSYXRpbzogdGhpcy5yZWR1Y2VyLnNldE9wTWl4UmF0aW8sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLndlYkdQVVJlZHVjZXIuc2V0UHJlY29tcHV0ZWRLTk4oa25uR3JhcGgua25uSW5kZXhlcywga25uR3JhcGgua25uRGlzdGFuY2VzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVkdWNlci5zZXRQcmVjb21wdXRlZEtOTihrbm5HcmFwaC5rbm5JbmRleGVzLCBrbm5HcmFwaC5rbm5EaXN0YW5jZXMpO1xuICAgICAgfVxuXG4gICAgICAvLyBuZWVkZWQgc28gdGhhdCBnYXJiYWdlIGNvbGxlY3RvciBjYW4gZnJlZSBtZW1vcnkgZnJvbSBkaXN0YW5jZSBtYXRyaXhcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSwgMzAwKTtcbiAgICAgIH0pO1xuXG4gICAgICBsZXQgZW1iZWRkaW5nOiBudW1iZXJbXVtdIHwgRmxvYXQzMkFycmF5W10gfCB1bmRlZmluZWQgfG51bGwgPSBudWxsO1xuICAgICAgY29uc29sZS50aW1lKCdmaXQnKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICh0aGlzLnVzZVdlYkdQVSAmJiB0aGlzLndlYkdQVVJlZHVjZXIpIHtcbiAgICAgICAgICBlbWJlZGRpbmcgPSBhd2FpdCB0aGlzLndlYkdQVVJlZHVjZXIuZml0KCk7XG4gICAgICAgICAgaWYgKCFlbWJlZGRpbmcpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBjb21wdXRlIGVtYmVkZGluZycpO1xuICAgICAgICAgIGVtYmVkZGluZyA9IC8vIHRyYW5zcG9zZSBUT0RPOiBkbyBhIGJldHRlciBqb2IgaGVyZVxuICAgICAgICAgICAgbmV3IEFycmF5KGVtYmVkZGluZ1swXS5sZW5ndGgpLmZpbGwobnVsbCkubWFwKChfLCBpKSA9PiBuZXcgRmxvYXQzMkFycmF5KGVtYmVkZGluZyEubWFwKCh2KSA9PiB2W2ldKSkpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICB9XG4gICAgICBpZiAoIWVtYmVkZGluZykge1xuICAgICAgICBpZiAodGhpcy51c2VXZWJHUFUpXG4gICAgICAgICAgY29uc29sZS5lcnJvcignV0VCR1BVIFVNQVAgZmFpbGVkLCBmYWxsaW5nIGJhY2sgdG8gQ1BVIGltcGxlbWVudGF0aW9uJyk7XG4gICAgICAgIGVtYmVkZGluZyA9IGF3YWl0IHRoaXMucmVkdWNlci5maXRBc3luYyh0aGlzLnZlY3RvcnMsIChlcG9jKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMucHJvZ3Jlc3NGdW5jKVxuICAgICAgICAgICAgdGhpcy5wcm9ncmVzc0Z1bmMoZXBvYywgdGhpcy5yZWR1Y2VyLmdldE5FcG9jaHMoKSwgdGhpcy5yZWR1Y2VyLmdldEVtYmVkZGluZygpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zb2xlLnRpbWVFbmQoJ2ZpdCcpO1xuICAgICAgcmV0dXJuIGFycmF5Q2FzdDJDb29yZGluYXRlcyhlbWJlZGRpbmcpO1xuICAgICAgZnVuY3Rpb24gYXJyYXlDYXN0MkNvb3JkaW5hdGVzKGRhdGE6IG51bWJlcltdW10gfCBGbG9hdDMyQXJyYXlbXSk6IENvb3JkaW5hdGVzIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBcnJheShkYXRhLmxlbmd0aCkuZmlsbCgwKS5tYXAoKF8sIGkpID0+IChWZWN0b3IuZnJvbShkYXRhW2ldKSkpO1xuICAgICAgfVxuICAgIH1cbn1cblxuY29uc3QgQXZhaWxhYmxlUmVkdWNlcnMgPSB7XG4gICdVTUFQJzogVU1BUFJlZHVjZXIsXG4gICd0LVNORSc6IFRTTkVSZWR1Y2VyLFxufTtcblxuZXhwb3J0IHR5cGUgS25vd25NZXRob2RzID0ga2V5b2YgdHlwZW9mIEF2YWlsYWJsZVJlZHVjZXJzO1xuXG5leHBvcnQgY2xhc3MgTXVsdGlDb2xEaW1SZWR1Y2VyIHtcbiAgICBwcml2YXRlIHJlZHVjZXI6IE11bHRpQ29sdW1uUmVkdWNlciB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXIuXG4gICAqIEBwYXJhbSB7YW55W119IGRhdGEgVmVjdG9ycyB0byBlbWJlZC5cbiAgICogQHBhcmFtIHtLbm93bk1ldGhvZHN9IG1ldGhvZCBFbWJlZGRpbmcgbWV0aG9kIHRvIGJlIGFwcGxpZWRcbiAgICogQHBhcmFtIHtLbm93bk1ldHJpY3N9IG1ldHJpYyBEaXN0YW5jZSBtZXRyaWMgdG8gYmUgY29tcHV0ZWQgYmV0d2VlbiBlYWNoIG9mIHRoZSB2ZWN0b3JzLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IFtvcHRpb25zXSBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGltcGxlbWVudGluZyBlbWJlZGRlcnMuXG4gICAqIEBtZW1iZXJvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAgICovXG4gICAgY29uc3RydWN0b3IoZGF0YTogQXJyYXk8YW55W10+LCBtZXRob2Q6IERpbVJlZHVjdGlvbk1ldGhvZHMsIG1ldHJpY3M6IEtub3duTWV0cmljc1tdLFxuICAgICAgd2VpZ2h0czogbnVtYmVyW10sIGRpc3RhbmNlQWdncmVnYXRpb246IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsIG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IG1lYXN1cmVzOiBEaXN0YW5jZU1ldHJpY1tdID0gW107XG4gICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCBtZXRyaWNzLmxlbmd0aDsgKytpZHgpIHtcbiAgICAgICAgY29uc3QgbWVhc3VyZSA9IG5ldyBNZWFzdXJlKG1ldHJpY3NbaWR4XSkuZ2V0TWVhc3VyZShvcHRpb25zLmRpc3RhbmNlRm5BcmdzW2lkeF0pO1xuICAgICAgICBtZWFzdXJlcy5wdXNoKG1lYXN1cmUpO1xuICAgICAgICBsZXQgYml0QXJyYXlMZW5ndGggPSAyMDQ4O1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFbaWR4XS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmIChkYXRhW2lkeF1baV0gJiYgZGF0YVtpZHhdW2ldLl9sZW5ndGgpIHtcbiAgICAgICAgICAgIGJpdEFycmF5TGVuZ3RoID0gZGF0YVtpZHhdW2ldLl9sZW5ndGg7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQml0QXJyYXlNZXRyaWMobWV0cmljc1tpZHhdKSkge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YVtpZHhdLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAoZGF0YVtpZHhdW2ldICYmIGRhdGFbaWR4XVtpXS5fZGF0YSlcbiAgICAgICAgICAgICAgZGF0YVtpZHhdW2ldID0gbmV3IEJpdEFycmF5KGRhdGFbaWR4XVtpXS5fZGF0YSwgZGF0YVtpZHhdW2ldLl9sZW5ndGgpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBkYXRhW2lkeF1baV0gPSBuZXcgQml0QXJyYXkoYml0QXJyYXlMZW5ndGgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobWV0aG9kID09ICdVTUFQJykge1xuICAgICAgICB0aGlzLnJlZHVjZXIgPSBuZXcgVU1BUFJlZHVjZXIoe1xuICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgZGlzdGFuY2VGbmFtZXM6IG1ldHJpY3MsXG4gICAgICAgICAgZGlzdGFuY2VGbnM6IG1lYXN1cmVzLFxuICAgICAgICAgIGRpc3RhbmNlRm5BcmdzOiBvcHRpb25zLmRpc3RhbmNlRm5BcmdzLFxuICAgICAgICAgIHdlaWdodHM6IHdlaWdodHMsXG4gICAgICAgICAgYWdncmVnYXRpb25NZXRob2Q6IGRpc3RhbmNlQWdncmVnYXRpb24sXG4gICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09ICd0LVNORScpIHtcbiAgICAgICAgdGhpcy5yZWR1Y2VyID0gbmV3IFRTTkVSZWR1Y2VyKHtcbiAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgIGRpc3RhbmNlRm5hbWVzOiBtZXRyaWNzLFxuICAgICAgICAgIGRpc3RhbmNlRm5zOiBtZWFzdXJlcyxcbiAgICAgICAgICBkaXN0YW5jZUZuQXJnczogb3B0aW9ucy5kaXN0YW5jZUZuQXJncyxcbiAgICAgICAgICB3ZWlnaHRzOiB3ZWlnaHRzLFxuICAgICAgICAgIGFnZ3JlZ2F0aW9uTWV0aG9kOiBkaXN0YW5jZUFnZ3JlZ2F0aW9uLFxuICAgICAgICAgIC4uLm9wdGlvbnNcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgdGhlIGNob3NlbiBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdHJhbnNwb3NlIFdoZXRoZXIgdG8gdHJhbnNmb3JtIGNvb3JkaW5hdGVzIHRvIGhhdmUgY29sdW1ucy1maXJzdCBvcmllbnRhdGlvbi5cbiAgICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSBjb21wdXRhdGlvbi5cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBlbWJlZGRpbmcgbWV0aG9kIHdhcyBub3QgZm91bmQuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLlxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICAgIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0odHJhbnNwb3NlOiBib29sZWFuID0gZmFsc2UpOiBQcm9taXNlPE1hdHJpeD4ge1xuICAgICAgaWYgKHRoaXMucmVkdWNlciA9PT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZHVjZXIgd2FzIG5vdCBkZWZpbmVkLicpO1xuXG4gICAgICBsZXQgZW1iZWRkaW5nID0gYXdhaXQgdGhpcy5yZWR1Y2VyLnRyYW5zZm9ybSgpO1xuXG4gICAgICBpZiAodHJhbnNwb3NlKVxuICAgICAgICBlbWJlZGRpbmcgPSB0cmFuc3Bvc2VNYXRyaXgoZW1iZWRkaW5nKTtcblxuICAgICAgcmV0dXJuIGVtYmVkZGluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICogUmV0dXJucyBtZXRyaWNzIGF2YWlsYWJsZSBieSB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0ge0F2YWlsYWJsZURhdGFUeXBlc30gdHlwZU5hbWUgdHlwZSBuYW1lXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBNZXRyaWMgbmFtZXMgd2hpY2ggZXhwZWN0cyB0aGUgZ2l2ZW4gZGF0YSB0eXBlXG4gICAqIEBtZW1iZXJvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAgICovXG4gICAgc3RhdGljIGF2YWlsYWJsZU1ldHJpY3NCeVR5cGUodHlwZU5hbWU6IEF2YWlsYWJsZURhdGFUeXBlcykge1xuICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3NbdHlwZU5hbWVdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICogUmV0dXJucyBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gbWV0aG9kcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEByZWFkb25seVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICAgIHN0YXRpYyBnZXQgYXZhaWxhYmxlTWV0aG9kcygpIHtcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhBdmFpbGFibGVSZWR1Y2Vycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAqIFJldHVybnMgbWV0cmljcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEByZWFkb25seVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICAgIHN0YXRpYyBnZXQgYXZhaWxhYmxlTWV0cmljcygpIHtcbiAgICAgIGxldCBhbnM6IHN0cmluZ1tdID0gW107XG4gICAgICBPYmplY3QudmFsdWVzKEF2YWlsYWJsZU1ldHJpY3MpLmZvckVhY2goKG9iaikgPT4ge1xuICAgICAgICBjb25zdCBhcnJheSA9IE9iamVjdC52YWx1ZXMob2JqKTtcbiAgICAgICAgYW5zID0gWy4uLmFucywgLi4uYXJyYXldO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYW5zO1xuICAgIH1cbn1cbiJdfQ==","import { MultiColDimReducer } from './multi-column-dim-reducer';\n/**\n * Worker thread receiving data function.\n *\n * @param {any[]} columnData Samples to process.\n * @param {KnownMethods} method Embedding method.\n * @param {KnownMetrics} measure Distance metric.\n * @param {any} options Options to pass to algorithm.\n * @param {boolean} parallelDistanceWorkers Whether to use parallel distance workers.\n * @return {any} Embedding (and distance matrix where applicable).\n */\nasync function onMessage(columnsData, method, metrics, weights, aggregationMethod, options) {\n const reducer = new MultiColDimReducer(columnsData, method, metrics, weights, aggregationMethod, { ...options, progressFunc });\n return await reducer.transform(true);\n}\nasync function progressFunc(epochNum, epochsLength, embedding) {\n if (epochNum % 5 === 0)\n self.postMessage({ epochNum, epochsLength, embedding });\n}\nself.onmessage = async ({ data: { columnsData, method, distanceMetrics, options, weights, aggregationMethod } }) => {\n let data;\n try {\n const embedding = await onMessage(columnsData, method, distanceMetrics, weights, aggregationMethod, options);\n data = { embedding };\n }\n catch (e) {\n data = { error: e };\n }\n self.postMessage({\n error: data.error,\n embedding: data.embedding,\n });\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsaXQtY29sdW1uLWRpbS1yZWR1Y2VyLXdvcmtlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm11bGl0LWNvbHVtbi1kaW0tcmVkdWNlci13b3JrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFFOUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsS0FBSyxVQUFVLFNBQVMsQ0FBQyxXQUF5QixFQUFFLE1BQTJCLEVBQUUsT0FBdUIsRUFDdEcsT0FBaUIsRUFBRSxpQkFBNEMsRUFDL0QsT0FBWTtJQUNaLE1BQU0sT0FBTyxHQUFHLElBQUksa0JBQWtCLENBQ3BDLFdBQVcsRUFDWCxNQUFNLEVBQ04sT0FBTyxFQUNQLE9BQU8sRUFDUCxpQkFBaUIsRUFDakIsRUFBQyxHQUFHLE9BQU8sRUFBRSxZQUFZLEVBQUMsQ0FDM0IsQ0FBQztJQUNGLE9BQU8sTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3ZDLENBQUM7QUFFRCxLQUFLLFVBQVUsWUFBWSxDQUFDLFFBQWdCLEVBQUUsWUFBb0IsRUFBRSxTQUFxQjtJQUN2RixJQUFJLFFBQVEsR0FBRyxDQUFDLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUMsQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssRUFBRSxFQUFDLElBQUksRUFBRSxFQUFDLFdBQVcsRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUMsRUFBQyxFQUFFLEVBQUU7SUFDN0csSUFBSSxJQUFvQyxDQUFDO0lBQ3pDLElBQUksQ0FBQztRQUNILE1BQU0sU0FBUyxHQUFHLE1BQU0sU0FBUyxDQUFDLFdBQVcsRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM3RyxJQUFJLEdBQUcsRUFBQyxTQUFTLEVBQUMsQ0FBQztJQUNyQixDQUFDO0lBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztRQUNoQixJQUFJLEdBQUcsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUM7SUFDcEIsQ0FBQztJQUNELElBQUksQ0FBQyxXQUFXLENBQUM7UUFDZixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7UUFDakIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO0tBQzFCLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TWF0cml4fSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge0tub3duTWV0cmljc30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcy90eXBlZC1tZXRyaWNzJztcbmltcG9ydCB7RGltUmVkdWN0aW9uTWV0aG9kc30gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge0Rpc3RhbmNlQWdncmVnYXRpb25NZXRob2R9IGZyb20gJy4uL2Rpc3RhbmNlLW1hdHJpeC90eXBlcyc7XG5pbXBvcnQge011bHRpQ29sRGltUmVkdWNlcn0gZnJvbSAnLi9tdWx0aS1jb2x1bW4tZGltLXJlZHVjZXInO1xuXG4vKipcbiAqIFdvcmtlciB0aHJlYWQgcmVjZWl2aW5nIGRhdGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHthbnlbXX0gY29sdW1uRGF0YSBTYW1wbGVzIHRvIHByb2Nlc3MuXG4gKiBAcGFyYW0ge0tub3duTWV0aG9kc30gbWV0aG9kIEVtYmVkZGluZyBtZXRob2QuXG4gKiBAcGFyYW0ge0tub3duTWV0cmljc30gbWVhc3VyZSBEaXN0YW5jZSBtZXRyaWMuXG4gKiBAcGFyYW0ge2FueX0gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gYWxnb3JpdGhtLlxuICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSB3b3JrZXJzLlxuICogQHJldHVybiB7YW55fSBFbWJlZGRpbmcgKGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZSkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG9uTWVzc2FnZShjb2x1bW5zRGF0YTogQXJyYXk8YW55W10+LCBtZXRob2Q6IERpbVJlZHVjdGlvbk1ldGhvZHMsIG1ldHJpY3M6IEtub3duTWV0cmljc1tdLFxuICB3ZWlnaHRzOiBudW1iZXJbXSwgYWdncmVnYXRpb25NZXRob2Q6IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsXG4gIG9wdGlvbnM6IGFueSk6IFByb21pc2U8TWF0cml4PiB7XG4gIGNvbnN0IHJlZHVjZXIgPSBuZXcgTXVsdGlDb2xEaW1SZWR1Y2VyKFxuICAgIGNvbHVtbnNEYXRhLFxuICAgIG1ldGhvZCxcbiAgICBtZXRyaWNzLFxuICAgIHdlaWdodHMsXG4gICAgYWdncmVnYXRpb25NZXRob2QsXG4gICAgey4uLm9wdGlvbnMsIHByb2dyZXNzRnVuY31cbiAgKTtcbiAgcmV0dXJuIGF3YWl0IHJlZHVjZXIudHJhbnNmb3JtKHRydWUpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwcm9ncmVzc0Z1bmMoZXBvY2hOdW06IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZzogbnVtYmVyW11bXSkge1xuICBpZiAoZXBvY2hOdW0gJSA1ID09PSAwKVxuICAgIHNlbGYucG9zdE1lc3NhZ2Uoe2Vwb2NoTnVtLCBlcG9jaHNMZW5ndGgsIGVtYmVkZGluZ30pO1xufVxuXG5zZWxmLm9ubWVzc2FnZSA9IGFzeW5jICh7ZGF0YToge2NvbHVtbnNEYXRhLCBtZXRob2QsIGRpc3RhbmNlTWV0cmljcywgb3B0aW9ucywgd2VpZ2h0cywgYWdncmVnYXRpb25NZXRob2R9fSkgPT4ge1xuICBsZXQgZGF0YToge2Vycm9yPzogYW55LCBlbWJlZGRpbmc/OiBhbnl9O1xuICB0cnkge1xuICAgIGNvbnN0IGVtYmVkZGluZyA9IGF3YWl0IG9uTWVzc2FnZShjb2x1bW5zRGF0YSwgbWV0aG9kLCBkaXN0YW5jZU1ldHJpY3MsIHdlaWdodHMsIGFnZ3JlZ2F0aW9uTWV0aG9kLCBvcHRpb25zKTtcbiAgICBkYXRhID0ge2VtYmVkZGluZ307XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGRhdGEgPSB7ZXJyb3I6IGV9O1xuICB9XG4gIHNlbGYucG9zdE1lc3NhZ2Uoe1xuICAgIGVycm9yOiBkYXRhLmVycm9yLFxuICAgIGVtYmVkZGluZzogZGF0YS5lbWJlZGRpbmcsXG4gIH0pO1xufTtcbiJdfQ==","// A library of seedable RNGs implemented in Javascript.\n//\n// Usage:\n//\n// var seedrandom = require('seedrandom');\n// var random = seedrandom(1); // or any seed.\n// var x = random(); // 0 <= x < 1. Every bit is random.\n// var x = random.quick(); // 0 <= x < 1. 32 bits of randomness.\n\n// alea, a 53-bit multiply-with-carry generator by Johannes Baagøe.\n// Period: ~2^116\n// Reported to pass all BigCrush tests.\nvar alea = require('./lib/alea');\n\n// xor128, a pure xor-shift generator by George Marsaglia.\n// Period: 2^128-1.\n// Reported to fail: MatrixRank and LinearComp.\nvar xor128 = require('./lib/xor128');\n\n// xorwow, George Marsaglia's 160-bit xor-shift combined plus weyl.\n// Period: 2^192-2^32\n// Reported to fail: CollisionOver, SimpPoker, and LinearComp.\nvar xorwow = require('./lib/xorwow');\n\n// xorshift7, by François Panneton and Pierre L'ecuyer, takes\n// a different approach: it adds robustness by allowing more shifts\n// than Marsaglia's original three. It is a 7-shift generator\n// with 256 bits, that passes BigCrush with no systmatic failures.\n// Period 2^256-1.\n// No systematic BigCrush failures reported.\nvar xorshift7 = require('./lib/xorshift7');\n\n// xor4096, by Richard Brent, is a 4096-bit xor-shift with a\n// very long period that also adds a Weyl generator. It also passes\n// BigCrush with no systematic failures. Its long period may\n// be useful if you have many generators and need to avoid\n// collisions.\n// Period: 2^4128-2^32.\n// No systematic BigCrush failures reported.\nvar xor4096 = require('./lib/xor4096');\n\n// Tyche-i, by Samuel Neves and Filipe Araujo, is a bit-shifting random\n// number generator derived from ChaCha, a modern stream cipher.\n// https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf\n// Period: ~2^127\n// No systematic BigCrush failures reported.\nvar tychei = require('./lib/tychei');\n\n// The original ARC4-based prng included in this library.\n// Period: ~2^1600\nvar sr = require('./seedrandom');\n\nsr.alea = alea;\nsr.xor128 = xor128;\nsr.xorwow = xorwow;\nsr.xorshift7 = xorshift7;\nsr.xor4096 = xor4096;\nsr.tychei = tychei;\n\nmodule.exports = sr;\n","// A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010\n// http://baagoe.com/en/RandomMusings/javascript/\n// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror\n// Original work is under MIT license -\n\n// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n\n\n(function(global, module, define) {\n\nfunction Alea(seed) {\n var me = this, mash = Mash();\n\n me.next = function() {\n var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32\n me.s0 = me.s1;\n me.s1 = me.s2;\n return me.s2 = t - (me.c = t | 0);\n };\n\n // Apply the seeding algorithm from Baagoe.\n me.c = 1;\n me.s0 = mash(' ');\n me.s1 = mash(' ');\n me.s2 = mash(' ');\n me.s0 -= mash(seed);\n if (me.s0 < 0) { me.s0 += 1; }\n me.s1 -= mash(seed);\n if (me.s1 < 0) { me.s1 += 1; }\n me.s2 -= mash(seed);\n if (me.s2 < 0) { me.s2 += 1; }\n mash = null;\n}\n\nfunction copy(f, t) {\n t.c = f.c;\n t.s0 = f.s0;\n t.s1 = f.s1;\n t.s2 = f.s2;\n return t;\n}\n\nfunction impl(seed, opts) {\n var xg = new Alea(seed),\n state = opts && opts.state,\n prng = xg.next;\n prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }\n prng.double = function() {\n return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53\n };\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nfunction Mash() {\n var n = 0xefc8249d;\n\n var mash = function(data) {\n data = String(data);\n for (var i = 0; i < data.length; i++) {\n n += data.charCodeAt(i);\n var h = 0.02519603282416938 * n;\n n = h >>> 0;\n h -= n;\n h *= n;\n n = h >>> 0;\n h -= n;\n n += h * 0x100000000; // 2^32\n }\n return (n >>> 0) * 2.3283064365386963e-10; // 2^-32\n };\n\n return mash;\n}\n\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.alea = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","// A Javascript implementaion of the \"Tyche-i\" prng algorithm by\n// Samuel Neves and Filipe Araujo.\n// See https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this, strseed = '';\n\n // Set up generator function.\n me.next = function() {\n var b = me.b, c = me.c, d = me.d, a = me.a;\n b = (b << 25) ^ (b >>> 7) ^ c;\n c = (c - d) | 0;\n d = (d << 24) ^ (d >>> 8) ^ a;\n a = (a - b) | 0;\n me.b = b = (b << 20) ^ (b >>> 12) ^ c;\n me.c = c = (c - d) | 0;\n me.d = (d << 16) ^ (c >>> 16) ^ a;\n return me.a = (a - b) | 0;\n };\n\n /* The following is non-inverted tyche, which has better internal\n * bit diffusion, but which is about 25% slower than tyche-i in JS.\n me.next = function() {\n var a = me.a, b = me.b, c = me.c, d = me.d;\n a = (me.a + me.b | 0) >>> 0;\n d = me.d ^ a; d = d << 16 ^ d >>> 16;\n c = me.c + d | 0;\n b = me.b ^ c; b = b << 12 ^ d >>> 20;\n me.a = a = a + b | 0;\n d = d ^ a; me.d = d = d << 8 ^ d >>> 24;\n me.c = c = c + d | 0;\n b = b ^ c;\n return me.b = (b << 7 ^ b >>> 25);\n }\n */\n\n me.a = 0;\n me.b = 0;\n me.c = 2654435769 | 0;\n me.d = 1367130551;\n\n if (seed === Math.floor(seed)) {\n // Integer seed.\n me.a = (seed / 0x100000000) | 0;\n me.b = seed | 0;\n } else {\n // String seed.\n strseed += seed;\n }\n\n // Mix in string seed, then discard an initial batch of 64 values.\n for (var k = 0; k < strseed.length + 20; k++) {\n me.b ^= strseed.charCodeAt(k) | 0;\n me.next();\n }\n}\n\nfunction copy(f, t) {\n t.a = f.a;\n t.b = f.b;\n t.c = f.c;\n t.d = f.d;\n return t;\n};\n\nfunction impl(seed, opts) {\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.tychei = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","// A Javascript implementaion of the \"xor128\" prng algorithm by\n// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this, strseed = '';\n\n me.x = 0;\n me.y = 0;\n me.z = 0;\n me.w = 0;\n\n // Set up generator function.\n me.next = function() {\n var t = me.x ^ (me.x << 11);\n me.x = me.y;\n me.y = me.z;\n me.z = me.w;\n return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8);\n };\n\n if (seed === (seed | 0)) {\n // Integer seed.\n me.x = seed;\n } else {\n // String seed.\n strseed += seed;\n }\n\n // Mix in string seed, then discard an initial batch of 64 values.\n for (var k = 0; k < strseed.length + 64; k++) {\n me.x ^= strseed.charCodeAt(k) | 0;\n me.next();\n }\n}\n\nfunction copy(f, t) {\n t.x = f.x;\n t.y = f.y;\n t.z = f.z;\n t.w = f.w;\n return t;\n}\n\nfunction impl(seed, opts) {\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.xor128 = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","// A Javascript implementaion of Richard Brent's Xorgens xor4096 algorithm.\n//\n// This fast non-cryptographic random number generator is designed for\n// use in Monte-Carlo algorithms. It combines a long-period xorshift\n// generator with a Weyl generator, and it passes all common batteries\n// of stasticial tests for randomness while consuming only a few nanoseconds\n// for each prng generated. For background on the generator, see Brent's\n// paper: \"Some long-period random number generators using shifts and xors.\"\n// http://arxiv.org/pdf/1004.3115v1.pdf\n//\n// Usage:\n//\n// var xor4096 = require('xor4096');\n// random = xor4096(1); // Seed with int32 or string.\n// assert.equal(random(), 0.1520436450538547); // (0, 1) range, 53 bits.\n// assert.equal(random.int32(), 1806534897); // signed int32, 32 bits.\n//\n// For nonzero numeric keys, this impelementation provides a sequence\n// identical to that by Brent's xorgens 3 implementaion in C. This\n// implementation also provides for initalizing the generator with\n// string seeds, or for saving and restoring the state of the generator.\n//\n// On Chrome, this prng benchmarks about 2.1 times slower than\n// Javascript's built-in Math.random().\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this;\n\n // Set up generator function.\n me.next = function() {\n var w = me.w,\n X = me.X, i = me.i, t, v;\n // Update Weyl generator.\n me.w = w = (w + 0x61c88647) | 0;\n // Update xor generator.\n v = X[(i + 34) & 127];\n t = X[i = ((i + 1) & 127)];\n v ^= v << 13;\n t ^= t << 17;\n v ^= v >>> 15;\n t ^= t >>> 12;\n // Update Xor generator array state.\n v = X[i] = v ^ t;\n me.i = i;\n // Result is the combination.\n return (v + (w ^ (w >>> 16))) | 0;\n };\n\n function init(me, seed) {\n var t, v, i, j, w, X = [], limit = 128;\n if (seed === (seed | 0)) {\n // Numeric seeds initialize v, which is used to generates X.\n v = seed;\n seed = null;\n } else {\n // String seeds are mixed into v and X one character at a time.\n seed = seed + '\\0';\n v = 0;\n limit = Math.max(limit, seed.length);\n }\n // Initialize circular array and weyl value.\n for (i = 0, j = -32; j < limit; ++j) {\n // Put the unicode characters into the array, and shuffle them.\n if (seed) v ^= seed.charCodeAt((j + 32) % seed.length);\n // After 32 shuffles, take v as the starting w value.\n if (j === 0) w = v;\n v ^= v << 10;\n v ^= v >>> 15;\n v ^= v << 4;\n v ^= v >>> 13;\n if (j >= 0) {\n w = (w + 0x61c88647) | 0; // Weyl.\n t = (X[j & 127] ^= (v + w)); // Combine xor and weyl to init array.\n i = (0 == t) ? i + 1 : 0; // Count zeroes.\n }\n }\n // We have detected all zeroes; make the key nonzero.\n if (i >= 128) {\n X[(seed && seed.length || 0) & 127] = -1;\n }\n // Run the generator 512 times to further mix the state before using it.\n // Factoring this as a function slows the main generator, so it is just\n // unrolled here. The weyl generator is not advanced while warming up.\n i = 127;\n for (j = 4 * 128; j > 0; --j) {\n v = X[(i + 34) & 127];\n t = X[i = ((i + 1) & 127)];\n v ^= v << 13;\n t ^= t << 17;\n v ^= v >>> 15;\n t ^= t >>> 12;\n X[i] = v ^ t;\n }\n // Storing state as object members is faster than using closure variables.\n me.w = w;\n me.X = X;\n me.i = i;\n }\n\n init(me, seed);\n}\n\nfunction copy(f, t) {\n t.i = f.i;\n t.w = f.w;\n t.X = f.X.slice();\n return t;\n};\n\nfunction impl(seed, opts) {\n if (seed == null) seed = +(new Date);\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (state.X) copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.xor4096 = impl;\n}\n\n})(\n this, // window object or global\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n","// A Javascript implementaion of the \"xorshift7\" algorithm by\n// François Panneton and Pierre L'ecuyer:\n// \"On the Xorgshift Random Number Generators\"\n// http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this;\n\n // Set up generator function.\n me.next = function() {\n // Update xor generator.\n var X = me.x, i = me.i, t, v, w;\n t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24);\n t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10);\n t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3);\n t = X[(i + 4) & 7]; v ^= t ^ (t << 7);\n t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9);\n X[i] = v;\n me.i = (i + 1) & 7;\n return v;\n };\n\n function init(me, seed) {\n var j, w, X = [];\n\n if (seed === (seed | 0)) {\n // Seed state array using a 32-bit integer.\n w = X[0] = seed;\n } else {\n // Seed state using a string.\n seed = '' + seed;\n for (j = 0; j < seed.length; ++j) {\n X[j & 7] = (X[j & 7] << 15) ^\n (seed.charCodeAt(j) + X[(j + 1) & 7] << 13);\n }\n }\n // Enforce an array length of 8, not all zeroes.\n while (X.length < 8) X.push(0);\n for (j = 0; j < 8 && X[j] === 0; ++j);\n if (j == 8) w = X[7] = -1; else w = X[j];\n\n me.x = X;\n me.i = 0;\n\n // Discard an initial 256 values.\n for (j = 256; j > 0; --j) {\n me.next();\n }\n }\n\n init(me, seed);\n}\n\nfunction copy(f, t) {\n t.x = f.x.slice();\n t.i = f.i;\n return t;\n}\n\nfunction impl(seed, opts) {\n if (seed == null) seed = +(new Date);\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (state.x) copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.xorshift7 = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n","// A Javascript implementaion of the \"xorwow\" prng algorithm by\n// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this, strseed = '';\n\n // Set up generator function.\n me.next = function() {\n var t = (me.x ^ (me.x >>> 2));\n me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v;\n return (me.d = (me.d + 362437 | 0)) +\n (me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0;\n };\n\n me.x = 0;\n me.y = 0;\n me.z = 0;\n me.w = 0;\n me.v = 0;\n\n if (seed === (seed | 0)) {\n // Integer seed.\n me.x = seed;\n } else {\n // String seed.\n strseed += seed;\n }\n\n // Mix in string seed, then discard an initial batch of 64 values.\n for (var k = 0; k < strseed.length + 64; k++) {\n me.x ^= strseed.charCodeAt(k) | 0;\n if (k == strseed.length) {\n me.d = me.x << 10 ^ me.x >>> 4;\n }\n me.next();\n }\n}\n\nfunction copy(f, t) {\n t.x = f.x;\n t.y = f.y;\n t.z = f.z;\n t.w = f.w;\n t.v = f.v;\n t.d = f.d;\n return t;\n}\n\nfunction impl(seed, opts) {\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.xorwow = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","/*\nCopyright 2019 David Bau.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n(function (global, pool, math) {\n//\n// The following constants are related to IEEE 754 limits.\n//\n\nvar width = 256, // each RC4 output is 0 <= x < 256\n chunks = 6, // at least six RC4 outputs for each double\n digits = 52, // there are 52 significant digits in a double\n rngname = 'random', // rngname: name for Math.random and Math.seedrandom\n startdenom = math.pow(width, chunks),\n significance = math.pow(2, digits),\n overflow = significance * 2,\n mask = width - 1,\n nodecrypto; // node.js crypto module, initialized at the bottom.\n\n//\n// seedrandom()\n// This is the seedrandom function described above.\n//\nfunction seedrandom(seed, options, callback) {\n var key = [];\n options = (options == true) ? { entropy: true } : (options || {});\n\n // Flatten the seed string or build one from local entropy if needed.\n var shortseed = mixkey(flatten(\n options.entropy ? [seed, tostring(pool)] :\n (seed == null) ? autoseed() : seed, 3), key);\n\n // Use the seed to initialize an ARC4 generator.\n var arc4 = new ARC4(key);\n\n // This function returns a random double in [0, 1) that contains\n // randomness in every bit of the mantissa of the IEEE 754 value.\n var prng = function() {\n var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48\n d = startdenom, // and denominator d = 2 ^ 48.\n x = 0; // and no 'extra last byte'.\n while (n < significance) { // Fill up all significant digits by\n n = (n + x) * width; // shifting numerator and\n d *= width; // denominator and generating a\n x = arc4.g(1); // new least-significant-byte.\n }\n while (n >= overflow) { // To avoid rounding up, before adding\n n /= 2; // last byte, shift everything\n d /= 2; // right using integer math until\n x >>>= 1; // we have exactly the desired bits.\n }\n return (n + x) / d; // Form the number within [0, 1).\n };\n\n prng.int32 = function() { return arc4.g(4) | 0; }\n prng.quick = function() { return arc4.g(4) / 0x100000000; }\n prng.double = prng;\n\n // Mix the randomness into accumulated entropy.\n mixkey(tostring(arc4.S), pool);\n\n // Calling convention: what to return as a function of prng, seed, is_math.\n return (options.pass || callback ||\n function(prng, seed, is_math_call, state) {\n if (state) {\n // Load the arc4 state from the given state if it has an S array.\n if (state.S) { copy(state, arc4); }\n // Only provide the .state method if requested via options.state.\n prng.state = function() { return copy(arc4, {}); }\n }\n\n // If called as a method of Math (Math.seedrandom()), mutate\n // Math.random because that is how seedrandom.js has worked since v1.0.\n if (is_math_call) { math[rngname] = prng; return seed; }\n\n // Otherwise, it is a newer calling convention, so return the\n // prng directly.\n else return prng;\n })(\n prng,\n shortseed,\n 'global' in options ? options.global : (this == math),\n options.state);\n}\n\n//\n// ARC4\n//\n// An ARC4 implementation. The constructor takes a key in the form of\n// an array of at most (width) integers that should be 0 <= x < (width).\n//\n// The g(count) method returns a pseudorandom integer that concatenates\n// the next (count) outputs from ARC4. Its return value is a number x\n// that is in the range 0 <= x < (width ^ count).\n//\nfunction ARC4(key) {\n var t, keylen = key.length,\n me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];\n\n // The empty key [] is treated as [0].\n if (!keylen) { key = [keylen++]; }\n\n // Set up S using the standard key scheduling algorithm.\n while (i < width) {\n s[i] = i++;\n }\n for (i = 0; i < width; i++) {\n s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];\n s[j] = t;\n }\n\n // The \"g\" method returns the next (count) outputs as one number.\n (me.g = function(count) {\n // Using instance members instead of closure state nearly doubles speed.\n var t, r = 0,\n i = me.i, j = me.j, s = me.S;\n while (count--) {\n t = s[i = mask & (i + 1)];\n r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];\n }\n me.i = i; me.j = j;\n return r;\n // For robust unpredictability, the function call below automatically\n // discards an initial batch of values. This is called RC4-drop[256].\n // See http://google.com/search?q=rsa+fluhrer+response&btnI\n })(width);\n}\n\n//\n// copy()\n// Copies internal state of ARC4 to or from a plain object.\n//\nfunction copy(f, t) {\n t.i = f.i;\n t.j = f.j;\n t.S = f.S.slice();\n return t;\n};\n\n//\n// flatten()\n// Converts an object tree to nested arrays of strings.\n//\nfunction flatten(obj, depth) {\n var result = [], typ = (typeof obj), prop;\n if (depth && typ == 'object') {\n for (prop in obj) {\n try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}\n }\n }\n return (result.length ? result : typ == 'string' ? obj : obj + '\\0');\n}\n\n//\n// mixkey()\n// Mixes a string seed into a key that is an array of integers, and\n// returns a shortened string seed that is equivalent to the result key.\n//\nfunction mixkey(seed, key) {\n var stringseed = seed + '', smear, j = 0;\n while (j < stringseed.length) {\n key[mask & j] =\n mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));\n }\n return tostring(key);\n}\n\n//\n// autoseed()\n// Returns an object for autoseeding, using window.crypto and Node crypto\n// module if available.\n//\nfunction autoseed() {\n try {\n var out;\n if (nodecrypto && (out = nodecrypto.randomBytes)) {\n // The use of 'out' to remember randomBytes makes tight minified code.\n out = out(width);\n } else {\n out = new Uint8Array(width);\n (global.crypto || global.msCrypto).getRandomValues(out);\n }\n return tostring(out);\n } catch (e) {\n var browser = global.navigator,\n plugins = browser && browser.plugins;\n return [+new Date, global, plugins, global.screen, tostring(pool)];\n }\n}\n\n//\n// tostring()\n// Converts an array of charcodes to a string\n//\nfunction tostring(a) {\n return String.fromCharCode.apply(0, a);\n}\n\n//\n// When seedrandom.js is loaded, we immediately mix a few bits\n// from the built-in RNG into the entropy pool. Because we do\n// not want to interfere with deterministic PRNG state later,\n// seedrandom will not call math.random on its own again after\n// initialization.\n//\nmixkey(math.random(), pool);\n\n//\n// Nodejs and AMD support: export the implementation as a module using\n// either convention.\n//\nif ((typeof module) == 'object' && module.exports) {\n module.exports = seedrandom;\n // When in node.js, try using crypto package for autoseeding.\n try {\n nodecrypto = require('crypto');\n } catch (ex) {}\n} else if ((typeof define) == 'function' && define.amd) {\n define(function() { return seedrandom; });\n} else {\n // When included as a plain script, set up Math.seedrandom global.\n math['seed' + rngname] = seedrandom;\n}\n\n\n// End anonymous scope, and pass initial values.\n})(\n // global: `self` in browsers (including strict mode and web workers),\n // otherwise `this` in Node and other environments\n (typeof self !== 'undefined') ? self : this,\n [], // pool: entropy pool starts empty\n Math // math: package containing random, pow, and seedrandom\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","isNil","insertSmaller","distancesAr","indexes","index","newPosition","findIndex","v","splice","assert","condition","message","Error","vectorDistanceMetricsMethods","Euclidean","p","q","pow","sqrt","stringDistanceMetricsMethods","Levenshtein","JaroWinkler","Manhattan","s1","s2","dist","Onehot","bitArrayDistanceMetricsMethods","Tanimoto","Dice","Asymmetric","BraunBlanquet","Cosine","Kulczynski","McConnaughey","RogotGoldberg","Russel","Sokal","Hamming","intArrayDistanceMetricsMethods","TanimotoIntArray","numberDistanceMetricsMethods","Difference","numberArrayDistanceMetrics","CommonItems","AvailableMetrics","Vector","BitArray","MacroMolecule","HAMMING","LEVENSHTEIN","NEEDLEMANN_WUNSCH","MONOMER_CHEMICAL_DISTANCE","Number","IntArray","NumberArray","MetricToDataType","keys","reduce","key","val","Measure","constructor","method","dataType","metricNeedsArgs","toString","name","isNumberArrayMetric","getMeasure","dict","hasOwnProperty","getMetricByDataType","availableMeasures","DistanceMatrixService","useConcurrentWorkers","terminateOnComplete","threadCount","navigator","hardwareConcurrency","_workerCount","_workers","Array","fill","map","Worker","URL","_terminateOnComplete","calc","values","fnName","normalize","calcMulti","MANHATTAN","fnNames","weights","aggregationMethod","async","promises","totalLength","chunkSize","distanceMatrix","endRow","endCol","lmin","lmax","MIN_VALUE","start","floor","end","startRow","startCol","postMessage","chunckSize","resolveWorker","rejectWorker","onmessage","data","error","distanceMatrixData","terminate","all","forEach","value","worker","tauRandInt","n","random","tauRand","empty","output","push","range","_","filled","zeros","mean","input","sum","rejectionSample","nSamples","poolSize","rejectSample","j","broken","k","reshape2d","a","rows","col","makeHeap","nPoints","makeArrays","fillValue","Infinity","heapPush","row","weight","flag","indices","uncheckedHeapPush","isNew","iSwap","ic1","ic2","heapShape2","buildCandidates","currentGraph","nVertices","nNeighbors","maxCandidates","candidateNeighbors","isn","d","deheapSort","indHeap","distHeap","indHeapIndex","distHeapIndex","temp1","temp2","siftDown","heap1","heap2","ceiling","elt","leftChild","rightChild","swap","smallestFlagged","ind","minDist","resultIndex","SparseMatrix","cols","dims","entries","Map","nRows","nCols","checkDims","makeKey","has","get","defaultValue","getAll","ordered","rowColValues","sort","getDims","getRows","from","_key","getCols","getValues","fn","vals","toArray","matrix","oldRows","oldCols","oldVals","matlen","pairwiseMultiply","elementWise","y","add","subtract","multiplyScalar","scalar","eliminateZeros","m","zeroIndices","Set","removeByZeroIndex","nextValues","filter","nextRows","nextCols","normType","normFn","normFns","colsByRow","nextMatrix","norm","xs","op","visited","operate","nextValue","valuesA","rowsA","colsA","valuesB","rowsB","colsB","getCSR","indptr","currentRow","FlatTree","hyperplanes","offsets","children","makeForest","nTrees","leafSize","trees","makeEuclideanTree","makeTree","forest","tree","nNodes","numNodes","nLeaves","numLeaves","hyperplane","recursiveFlatten","flattenTree","splitResults","leftIndex","rightIndex","left","right","hyperplaneOffset","hyperplaneVector","nLeft","nRight","side","margin","indicesLeft","indicesRight","offset","euclideanRandomProjectionSplit","isLeaf","nodeNum","leafNum","oldNodeNum","res","selectSide","point","searchFlatTree","prototype","isAnyArray","object","call","endsWith","errorCalculation","parameters","parameterizedFunction","abs","step","params","damping","gradientDifference","identity","eye","evaluatedData","gradientFunc","paramFunction","ans","param","auxParams","slice","funcParam","gradientFunction","matrixFunc","matrixFunction","inverseMatrix","mmul","transpose","sub","mul","to1DArray","SMOOTH_K_TOLERANCE","MIN_K_DIST_SCALE","UMAP","neighbors","learningRate","localConnectivity","nComponents","nEpochs","negativeSampleRate","repulsionStrength","setOpMixRatio","spread","transformQueueSize","targetMetric","targetWeight","targetNNeighbors","distanceFn","numeric","isInitialized","rpForest","embedding","optimizationState","OptimizationState","setParam","fit","X","initializeFit","optimizeLayout","fitAsync","optimizeLayoutAsync","setSupervisedProjection","Y","setPrecomputedKNN","knnIndices","knnDistances","getNEpochs","knnResults","nearestNeighbors","graph","fuzzySimplicialSet","makeSearchFns","searchGraph","makeSearchGraph","processGraphForSupervisedProjection","head","tail","epochsPerSample","initializeSimplicialSetEmbedding","initializeOptimization","prepareForOptimizationLoop","initFromTree","initFromRandom","queryPoints","_heap","_tree","search","initialization","tried","vertex","candidates","candidate","knn","distances","neighbor","distance","transform","toTransform","rawData","results","adjustedLocalConnectivity","sigmas","rhos","smoothKNNDistance","computeMembershipStrengths","csrMatrix","_z","initTransform","graphMax","makeEpochsPerSample","assignOptimizationStateParameters","headEmbedding","tailEmbedding","currentEpoch","farDist","categoricalSimplicialSetIntersection","optimizeLayoutStep","getEmbedding","metricNNDescent","leafArray","nIters","delta","rho","rpTreeInit","cj","ck","round","log2","sparseMatrix","prodMatrix","simplicialSet","target","unknownDist","intersection","exp","fastIntersection","resetLocalConnectivity","nIter","bandwidth","lo","hi","mid","ithDistances","nonZeroDists","interpolation","psum","meanIthDistances","meanDistances","graphValues","entry","w","state","dim","moveOther","epochsPerNegativeSample","epochOfNextNegativeSample","epochOfNextSample","initialAlpha","alpha","gamma","xv","yv","parameterValues","options","maxIterations","errorTolerance","minValues","maxValues","initialValues","parLen","MAX_SAFE_INTEGER","MIN_SAFE_INTEGER","iteration","converged","isNaN","parameterError","iterations","findABParams","current","other","distSquared","rDist","gradCoeff","gradD","clip","nNegSamples","epochCallback","epochCompleted","shouldStop","isFinished","clipValue","TSNE","getopt","opt","field","defaultval","gaussRandom","returnV","vValue","r","randn","mu","std","ArrayBuffer","randn2d","s","uses","l2","x1","x2","D","x1i","x2i","xtod","N","getIterSize","rowSize","d2p","perplexity","tol","indexer","hTarget","P","prow","betamin","betamax","beta","done","maxtries","pj","nHere","pOut","N2","sign","iter","epsilon","initDataRaw","dists","initSolution","initDataDist","time","timeEnd","gains","ystep","getSolution","cg","costGrad","cost","grad","ymean","gid","sid","gainid","newgain","newsid","debugGrad","yold","cg0","cg1","analytic","numerical","pmul","quArr","qsum","qu","prev","Q","premult","thisArg","_arguments","generator","fulfilled","next","rejected","gpuAdapter","gpuDevice","gpu","requestAdapter","powerPreference","isLost","lost","requiredBufferSize","adapterLimits","limits","buffferSizeLimit","maxBufferSize","storageBufferSizeLimit","maxStorageBufferBindingSize","requestDevice","requiredLimits","WEBGSLAGGREGATION","EUCLIDEAN","arraySize","WEBGPUDISTANCE","_maxArraySize","entryIndex","maxArraySize","_entryIndex","TANIMOTO","LEVENSTEIN","NEEDLEMAN_WUNSCH","SOKAL","COSINE","ASYMMETRIC","OneHot","distanceFunctionComplexity","maxEntrySize","ceil","_maxEntrySize","TypeSupportedDistances","MatrixMatrixOpType","MatrixOpType","MatrixScalarOpType","multiColWebGPUKNN","entryList","knnSize","distanceMetrics","aggregationFunction","some","list","availableDistanceMetrics","metric","includes","join","numOfColumns","device","deviceLost","listSize","processInfo","distanceMetric","gapOpenPenalty","gapExtensionPenalty","_a","_b","entryType","encodedList","split","_data","encodedListType","arraySizes","maxEntryLen","complexity","EncodedArrayConstructor","flatSourceArray","seq","suppInfoStructWgsl","suppInfoSize","suppInfoType","suppInfoBuffer","maxMonomerIndex","scoringMatrix","alphabetIndexes","similarityMatrixSize","transferedSimilarityMatrix","key2","dataTypeWGSL","dataStructWgsl","sourceArraySize","suppInfoWgsl","wgsl","needsDummy","trim","combinedComplexity","dataWgsl","computationsPerPass","pairComparisonsPerPass","workgroupsDim","globalThreadDimSize","resultIndexes","resultDistances","createShaderModule","label","code","getCombinedDistanceScript","pipeline","createComputePipeline","layout","compute","entryPoint","computeInfo32Size","suppInfo32Size","computeInfoBufferSize","BYTES_PER_ELEMENT","paddedComputeInfoBufferSize","remainder","computeInfoBuffer","createBuffer","usage","GPUBufferUsage","STORAGE","COPY_SRC","COPY_DST","mappedAtCreation","mappedComputeInfoArrayBuffer","getMappedRange","startAt","endAt","pairComparisonStartAt","pairComparisonEndAt","computeInfoOffSet","ArrayConstructor","unmap","suppInfoBufferSize","paddedSuppInfoBufferSize","suppInfoRemainder","mappedSuppInfoArrayBuffer","suppInfoOffSet","outKnnArraySize","bufferDistances","bufferIndexes","bytesPerOutArrayRow","bindGroup","createBindGroup","getBindGroupLayout","binding","resource","resultBufferDistances","MAP_READ","resultBufferIndexes","pairComparisonPasses","pairIter","queue","writeBuffer","encoder","createCommandEncoder","pass","beginComputePass","setPipeline","setBindGroup","dispatchWorkgroups","workGroupDivision","copyBufferToBuffer","commandBuffer","finish","submit","onSubmittedWorkDone","mapAsync","GPUMapMode","READ","destroy","knnIndexes","maxEntryLens","aggregation","pairwiseOpSparse","indexes1","distances1","offsets1","indexes2","distances2","offsets2","numOfEntries","unionMatrixOffsets","requiredWorkgroups","threadsPerWorkgroupDim","numOfWorkgroupsPerDim","threadsPerYDimension","sparseSize1","sparseSize2","unionMatrixSize","processWgsl","paddedStorage1ByteSize","remainder1","paddedStorage2ByteSize","remainder2","paddedResStorageByteSize","remainder3","source1Buffer","mappedSource1Buffer","source2Buffer","mappedSource2Buffer","resBuffer","unionMatrixOffsetsBuffer","mappedUnionMatrixOffsetsBuffer","resultBuffer","resultArrayBuffer","resultKnnIndexes","resultKnnDistances","weightSquare","centralDifference","nbParams","nbPoints","rowIndex","funcParam2","residualError","scale","jacobianWeightResidualError","perturbations","checkTimeout","dampingStepUp","dampingStepDown","improvementThreshold","timeout","filler","endTime","Date","now","checkOptions","optimalError","optimalParameters","previousError","toOffsetForm","ar","performMatrixOps","flatKnnIndexes","flatKnnDistances","unionInfo","entryLen","knnMatrixOpInfoWGSL","indexesBuffer32Size","indexBuffer","mappedIndexesBuffer","mappedIndexesArray","sizesBuffer","unionSizesBuffer","mappedUnionSizesBuffer","resultTransposeSizesBuffer","resultUnionSizesBuffer","resultTransposeSizesArrayBuffer","resultUnionSizesArrayBuffer","resultTransposeSizesArray","resultUnionSizesArray","old","getKnnSparseOpInfo","transposed","knnSparseInfo","fullKnnEntrySize","transposeOffsets","offsetsCopy","transposeKNNIndexes","transposeKNNDistances","otherIndex","otherIndexOffset","transposeKNN","sourceOffsets","transposeMultRes","addRes","subtRes","unionSizes","meanDistancesSum","currentMean","smoothKNNDistanceWGSL","distanceBuffer32Size","resultSigmas","resultRhos","distancesBuffer","mappedDistanceBuffer","mappedDistanceArray","bufferSigmas","bufferRhos","resultBufferRhos","resultBufferSigmas","UmapParams","nNeighbours","WebGPUUMAP","membershipStrengths","calcSmoothKNNDistances","calcMembershipStrengths","umapParams","resEmbeddings","embeddingSize","divisionFactor","headSize","processWGSL","embedSize","workgroupDim","threadsPerRow","optimizeLayoutWGSL","paddedMatrixStorageSize","paddedepochStorageSize","paddedembedStorageSize","paddedComputeInfoSize","remainder4","matrixStorageBuffer","matrixStorageArrayBuffer","epochStorageBuffer","epochStorageArrayBuffer","epochStorageArrayView","headEmbeddings","embeddingStorageBuffer","mappedEmbeddingStorageBuffer","mappedEmbeddingStorageArray","randomNumbers","computeInfoArrayBuffer","outEmbedViewBuffer","resArrayBuffer","headEmbeddingsView","optimizationLoop","sigmasLength","rhosLength","computeMembershipStrengthsWGSL","paddedCombinedMembershipStructByteSize","membershipStrengthsInfoBuffer","mappedInfoBuffer","mappedInfoArray","knnDistancesBuffer","resultKnnDistancesArrayBuffer","bytesPerKnnRow","resKnnDistances","dataView","out","fuzzySimplicialSetRes","eRes","maxVal","cur","minGraphVal","unionSizesCopy","offsetAccum","nonZeroGraphOffsets","nonZeroGraphSize","MultiColumnReducer","TSNEReducer","super","randomSeed","randomFn","reducer","distanceFnames","distanceFns","distanceFnArgs","progressFunc","matrixService","UMAPReducer","useWebGPU","vectors","_parallelDistanceWorkers","knnGraph","multiColumnKNN","webGPUReducer","epoc","AvailableReducers","MultiColDimReducer","metrics","distanceAggregation","measures","measure","bitArrayLength","_length","transposeMatrix","availableMetricsByType","typeName","availableMethods","availableMetrics","obj","epochNum","epochsLength","columnsData","onMessage","alea","xor128","xorwow","xorshift7","xor4096","tychei","sr","global","Alea","seed","me","mash","h","t","s0","copy","f","impl","xg","prng","int32","double","quick","XorGen","strseed","z","limit","pool","math","nodecrypto","width","startdenom","significance","overflow","mask","seedrandom","shortseed","mixkey","flatten","entropy","tostring","randomBytes","crypto","msCrypto","getRandomValues","browser","plugins","screen","autoseed","arc4","ARC4","g","S","is_math_call","keylen","count","depth","prop","typ","smear","stringseed","ex"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"738.js","mappings":"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","sources":["webpack://eda/./node_modules/@datagrok-libraries/math/src/dbscan/wasm/wasmDbscan.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/utils.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/type-declarations.js","webpack://eda/./node_modules/@datagrok-libraries/utils/src/vector-operations.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/typed-metrics/typed-metrics.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/distance-matrix-service.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/utils.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/heap.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/matrix.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/tree.js","webpack://eda/./node_modules/@datagrok-libraries/ml/node_modules/is-any-array/src/index.js","webpack://eda/./node_modules/@datagrok-libraries/ml/node_modules/ml-levenberg-marquardt/src/errorCalculation.js","webpack://eda/./node_modules/@datagrok-libraries/ml/node_modules/ml-levenberg-marquardt/src/step.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/umap.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/umap/nn_descent.js","webpack://eda/./node_modules/@datagrok-libraries/ml/node_modules/ml-levenberg-marquardt/src/index.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/t-sne/t-sne.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/distance-matrix/proxy.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/getGPUDevice.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/multi-col-knn/multiCol-KNN.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/types.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/preprocessing/webGPU-process-info.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/knn-sparse-info.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/pairwise-sparse-ops.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/errorCalculation.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/step.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/gradientFunction.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/utils.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/index.js","webpack://eda/./node_modules/ml-levenberg-marquardt/lib-esm/checkOptions.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/fuzzy-simplical-set.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/wgsl/knn-sparse-info.wgsl.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/smooth-knn-distance.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/wgsl/smooth-knn-distance.wgsl.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/WEBGPU-UMAP.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/optimization-loop.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/wgsl/optimization-loop.wgsl.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/membership-strengths.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/wgsl/membership-strengths.wgsl.js","webpack://eda/./node_modules/@datagrok-libraries/math/src/webGPU/umap/simplical-set-embedding.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/multi-column-dim-reducer.js","webpack://eda/./node_modules/@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/mulit-column-dim-reducer-worker.js","webpack://eda/./node_modules/seedrandom/index.js","webpack://eda/./node_modules/seedrandom/lib/alea.js","webpack://eda/./node_modules/seedrandom/lib/tychei.js","webpack://eda/./node_modules/seedrandom/lib/xor128.js","webpack://eda/./node_modules/seedrandom/lib/xor4096.js","webpack://eda/./node_modules/seedrandom/lib/xorshift7.js","webpack://eda/./node_modules/seedrandom/lib/xorwow.js","webpack://eda/./node_modules/seedrandom/seedrandom.js"],"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","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","/**\n * Denotes a vector of floating poit values.\n *\n * @export\n * @class Vector\n * @extends {Float32Array}\n */\nexport class Vector extends Float32Array {\n}\n/**\n * Denotes a two-dimensional matrix.\n *\n * @export\n * @class Matrix\n * @extends {Array<Vector>}\n */\nexport class Matrix extends Array {\n}\n/**\n * Denotes cartesian coordinates.\n *\n * @export\n * @class Coordinates\n * @extends {Matrix}\n */\nexport class Coordinates extends Matrix {\n}\n/**\n * Denotes an array of arbitrary-typed vectors.\n *\n * @export\n * @class Vectors\n * @extends {Array<any>}\n */\nexport class Vectors extends Array {\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1kZWNsYXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlLWRlY2xhcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLFlBQVk7Q0FBRztBQUUzQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLEtBQWE7Q0FBRztBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sV0FBWSxTQUFRLE1BQU07Q0FBRztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sT0FBUSxTQUFRLEtBQVU7Q0FBRyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cbi8qKlxuICogRGVub3RlcyBhIHZlY3RvciBvZiBmbG9hdGluZyBwb2l0IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgVmVjdG9yXG4gKiBAZXh0ZW5kcyB7RmxvYXQzMkFycmF5fVxuICovXG5leHBvcnQgY2xhc3MgVmVjdG9yIGV4dGVuZHMgRmxvYXQzMkFycmF5IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIHR3by1kaW1lbnNpb25hbCBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE1hdHJpeFxuICogQGV4dGVuZHMge0FycmF5PFZlY3Rvcj59XG4gKi9cbmV4cG9ydCBjbGFzcyBNYXRyaXggZXh0ZW5kcyBBcnJheTxWZWN0b3I+IHt9XG5cbi8qKlxuICogRGVub3RlcyBjYXJ0ZXNpYW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIENvb3JkaW5hdGVzXG4gKiBAZXh0ZW5kcyB7TWF0cml4fVxuICovXG5leHBvcnQgY2xhc3MgQ29vcmRpbmF0ZXMgZXh0ZW5kcyBNYXRyaXgge31cblxuLyoqXG4gKiBEZW5vdGVzIGFuIGFycmF5IG9mIGFyYml0cmFyeS10eXBlZCB2ZWN0b3JzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBWZWN0b3JzXG4gKiBAZXh0ZW5kcyB7QXJyYXk8YW55Pn1cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY3RvcnMgZXh0ZW5kcyBBcnJheTxhbnk+IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIGRpY3Rpb25hcnkgY29udGFpbmluZyBmdW5jdGlvbiBvcHRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEB0eXBlIE9wdGlvbnNcbiAqL1xuZXhwb3J0IHR5cGUgT3B0aW9ucyA9IHtbbmFtZTogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBEZW5vdGVzIGN1c3RvbSBkaXN0YW5jZSBtZXRyaWMgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHR5cGUgRGlzdGFuY2VNZXRyaWNcbiAqIEBwYXJhbSB7YW55fSB2MSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHthbnl9IHYyIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICovXG5leHBvcnQgdHlwZSBEaXN0YW5jZU1ldHJpYyA9ICh2MTogYW55LCB2MjogYW55KSA9PiAobnVtYmVyKTtcblxuLyoqXG4gKiBEZW5vdGVzIGEgc2ltcGxlIHN0cmluZyB0byBzdHJpbmcgZGljdGlvbmFyeS5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAdHlwZSBTdHJpbmdEaWN0aW9uYXJ5XG4gKi9cbmV4cG9ydCB0eXBlIFN0cmluZ0RpY3Rpb25hcnkgPSB7W2tleTogc3RyaW5nXTogc3RyaW5nfTtcblxuXG5leHBvcnQgdHlwZSBDb2x1bW5JbnB1dE9wdGlvbnMgPSB7XG4gICAgZmlsdGVyPzogKGNvbDogREcuQ29sdW1uKSA9PiBib29sZWFuO1xufTtcbiJdfQ==","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=","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 { DistanceAggregationMethods } from './types';\nexport class DistanceMatrixService {\n constructor(useConcurrentWorkers = true, terminateOnComplete = true) {\n const threadCount = navigator.hardwareConcurrency;\n this._workerCount = useConcurrentWorkers ? Math.max(threadCount - 2, 1) : 1;\n this._workers = new Array(this._workerCount).fill(null)\n .map(() => new Worker(new URL('./distance-matrix-worker', import.meta.url)));\n this._terminateOnComplete = terminateOnComplete;\n }\n ;\n async calc(values, fnName, normalize = true, opts) {\n return await this.calcMulti([values], [fnName], normalize, [opts ?? {}], [1], DistanceAggregationMethods.MANHATTAN);\n }\n async calcMulti(values, fnNames, normalize = true, opts = [{}], weights = [1], aggregationMethod = DistanceAggregationMethods.MANHATTAN) {\n if (values.length < 1)\n throw new Error('values must contain at least one array');\n if (fnNames.length !== values.length || opts.length !== values.length || weights.length !== values.length)\n throw new Error('values, fnNames, weights and opts must have the same length');\n return new Promise(async (resolve, reject) => {\n try {\n const len = values[0].length;\n const promises = new Array(this._workerCount);\n const totalLength = len * (len - 1) / 2; // size of reduced distance matrix\n this._workerCount = Math.min(this._workerCount, totalLength);\n const chunkSize = totalLength / this._workerCount;\n const distanceMatrix = new Float32Array(totalLength);\n let endRow = 0;\n let endCol = 1;\n // minmax for normalization\n let lmin = 0;\n let lmax = Number.MIN_VALUE;\n for (let i = 0; i < this._workerCount; i++) {\n const start = Math.floor(i * chunkSize);\n const end = (i === this._workerCount - 1) ? totalLength : Math.floor((i + 1) * chunkSize);\n const startRow = endRow;\n const startCol = endCol;\n if (i !== this._workerCount - 1) {\n // These formulas map the linear index to the upper triangular matrix indices\n endRow = len - 2 - Math.floor(Math.sqrt(-8 * end + 4 * len * (len - 1) - 7) / 2 - 0.5);\n endCol = end - len * endRow + Math.floor((endRow + 1) * (endRow + 2) / 2);\n }\n this._workers[i].postMessage({ values, fnNames, startRow, startCol, chunckSize: end - start, opts, weights, aggregationMethod });\n promises[i] = new Promise((resolveWorker, rejectWorker) => {\n this._workers[i].onmessage = ({ data: { error, distanceMatrixData, min, max } }) => {\n this._terminateOnComplete && setTimeout(() => this._workers[i].terminate());\n if (error) {\n rejectWorker(error);\n }\n else {\n distanceMatrix.set(distanceMatrixData, start);\n if (min < lmin)\n lmin = min;\n if (max > lmax)\n lmax = max;\n resolveWorker();\n }\n };\n });\n }\n await Promise.all(promises);\n if (normalize)\n distanceMatrix.forEach((value, index) => { distanceMatrix[index] = (value - lmin) / (lmax - lmin); });\n resolve(distanceMatrix);\n }\n catch (e) {\n reject(e);\n }\n });\n }\n terminate() {\n this._workers.forEach((worker) => worker.terminate());\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWF0cml4LXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkaXN0YW5jZS1tYXRyaXgtc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQTRCLDBCQUEwQixFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRTlFLE1BQU0sT0FBTyxxQkFBcUI7SUFJOUIsWUFBbUIsb0JBQW9CLEdBQUcsSUFBSSxFQUFFLG1CQUFtQixHQUFHLElBQUk7UUFDeEUsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLG1CQUFtQixDQUFDO1FBQ2xELElBQUksQ0FBQyxZQUFZLEdBQUcsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDcEQsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLDBCQUEwQixFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9FLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxtQkFBbUIsQ0FBQztJQUNsRCxDQUFDO0lBQUEsQ0FBQztJQUVLLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBc0IsRUFBRSxNQUFvQixFQUM1RCxTQUFTLEdBQUcsSUFBSSxFQUFFLElBQXlCO1FBQzNDLE9BQU8sTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFTLEVBQ3ZELENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsMEJBQTBCLENBQUMs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QUFJLFNBQVM7b0JBQ1gsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4RyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDMUIsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ1osQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFNBQVM7UUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtLbm93bk1ldHJpY3N9IGZyb20gJy4uL3R5cGVkLW1ldHJpY3MnO1xuaW1wb3J0IHtEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kLCBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kc30gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBEaXN0YW5jZU1hdHJpeFNlcnZpY2Uge1xuICAgIHByaXZhdGUgX3dvcmtlcnM6IFdvcmtlcltdO1xuICAgIHByaXZhdGUgX3dvcmtlckNvdW50OiBudW1iZXI7XG4gICAgcHJpdmF0ZSBfdGVybWluYXRlT25Db21wbGV0ZTogYm9vbGVhbjtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IodXNlQ29uY3VycmVudFdvcmtlcnMgPSB0cnVlLCB0ZXJtaW5hdGVPbkNvbXBsZXRlID0gdHJ1ZSkge1xuICAgICAgY29uc3QgdGhyZWFkQ291bnQgPSBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeTtcbiAgICAgIHRoaXMuX3dvcmtlckNvdW50ID0gdXNlQ29uY3VycmVudFdvcmtlcnMgPyBNYXRoLm1heCh0aHJlYWRDb3VudCAtIDIsIDEpIDogMTtcbiAgICAgIHRoaXMuX3dvcmtlcnMgPSBuZXcgQXJyYXkodGhpcy5fd29ya2VyQ291bnQpLmZpbGwobnVsbClcbiAgICAgICAgLm1hcCgoKSA9PiBuZXcgV29ya2VyKG5ldyBVUkwoJy4vZGlzdGFuY2UtbWF0cml4LXdvcmtlcicsIGltcG9ydC5tZXRhLnVybCkpKTtcbiAgICAgIHRoaXMuX3Rlcm1pbmF0ZU9uQ29tcGxldGUgPSB0ZXJtaW5hdGVPbkNvbXBsZXRlO1xuICAgIH07XG5cbiAgICBwdWJsaWMgYXN5bmMgY2FsYyh2YWx1ZXM6IEFycmF5TGlrZTxhbnk+LCBmbk5hbWU6IEtub3duTWV0cmljcyxcbiAgICAgIG5vcm1hbGl6ZSA9IHRydWUsIG9wdHM/OiB7W186IHN0cmluZ106IGFueX0pOiBQcm9taXNlPEZsb2F0MzJBcnJheT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2FsY011bHRpKFt2YWx1ZXNdLCBbZm5OYW1lXSwgbm9ybWFsaXplLFxuICAgICAgICBbb3B0cyA/PyB7fV0sIFsxXSwgRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZHMuTUFOSEFUVEFOKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgY2FsY011bHRpKFxuICAgICAgdmFsdWVzOiBBcnJheUxpa2U8YW55PltdLCBmbk5hbWVzOiBLbm93bk1ldHJpY3NbXSxcbiAgICAgIG5vcm1hbGl6ZSA9IHRydWUsIG9wdHM6IHtbXzogc3RyaW5nXTogYW55fVtdID0gW3t9XSxcbiAgICAgIHdlaWdodHM6IG51bWJlcltdID0gWzFdLCBhZ2dyZWdhdGlvbk1ldGhvZDogRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCA9IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2RzLk1BTkhBVFRBTlxuICAgICk6IFByb21pc2U8RmxvYXQzMkFycmF5PiB7XG4gICAgICBpZiAodmFsdWVzLmxlbmd0aCA8IDEpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndmFsdWVzIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgYXJyYXknKTtcbiAgICAgIGlmIChmbk5hbWVzLmxlbmd0aCAhPT0gdmFsdWVzLmxlbmd0aCB8fCBvcHRzLmxlbmd0aCAhPT0gdmFsdWVzLmxlbmd0aCB8fCB3ZWlnaHRzLmxlbmd0aCAhPT0gdmFsdWVzLmxlbmd0aClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd2YWx1ZXMsIGZuTmFtZXMsIHdlaWdodHMgYW5kIG9wdHMgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aCcpO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBsZW4gPSB2YWx1ZXNbMF0ubGVuZ3RoO1xuICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8dm9pZD4+KHRoaXMuX3dvcmtlckNvdW50KTtcbiAgICAgICAgICBjb25zdCB0b3RhbExlbmd0aCA9IGxlbiAqIChsZW4gLSAxKSAvIDI7IC8vIHNpemUgb2YgcmVkdWNlZCBkaXN0YW5jZSBtYXRyaXhcbiAgICAgICAgICB0aGlzLl93b3JrZXJDb3VudCA9IE1hdGgubWluKHRoaXMuX3dvcmtlckNvdW50LCB0b3RhbExlbmd0aCk7XG4gICAgICAgICAgY29uc3QgY2h1bmtTaXplID0gdG90YWxMZW5ndGggLyB0aGlzLl93b3JrZXJDb3VudDtcbiAgICAgICAgICBjb25zdCBkaXN0YW5jZU1hdHJpeCA9IG5ldyBGbG9hdDMyQXJyYXkodG90YWxMZW5ndGgpO1xuICAgICAgICAgIGxldCBlbmRSb3cgPSAwO1xuICAgICAgICAgIGxldCBlbmRDb2wgPSAxO1xuICAgICAgICAgIC8vIG1pbm1heCBmb3Igbm9ybWFsaXphdGlvblxuICAgICAgICAgIGxldCBsbWluID0gMDtcbiAgICAgICAgICBsZXQgbG1heCA9IE51bWJlci5NSU5fVkFMVUU7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl93b3JrZXJDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IE1hdGguZmxvb3IoaSAqIGNodW5rU2l6ZSk7XG4gICAgICAgICAgICBjb25zdCBlbmQgPSAoaSA9PT0gdGhpcy5fd29ya2VyQ291bnQgLSAxKSA/IHRvdGFsTGVuZ3RoIDogTWF0aC5mbG9vcigoaSArIDEpICogY2h1bmtTaXplKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0Um93ID0gZW5kUm93O1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRDb2wgPSBlbmRDb2w7XG4gICAgICAgICAgICBpZiAoaSAhPT0gdGhpcy5fd29ya2VyQ291bnQgLSAxKSB7XG4gICAgICAgICAgICAgIC8vIFRoZXNlIGZvcm11bGFzIG1hcCB0aGUgbGluZWFyIGluZGV4IHRvIHRoZSB1cHBlciB0cmlhbmd1bGFyIG1hdHJpeCBpbmRpY2VzXG4gICAgICAgICAgICAgIGVuZFJvdyA9IGxlbiAtIDIgLSBNYXRoLmZsb29yKE1hdGguc3FydCgtOCAqIGVuZCArIDQgKiBsZW4gKiAobGVuIC0gMSkgLSA3KSAvIDIgLSAwLjUpO1xuICAgICAgICAgICAgICBlbmRDb2wgPSBlbmQgLSBsZW4gKiBlbmRSb3cgKyBNYXRoLmZsb29yKChlbmRSb3cgKyAxKSAqIChlbmRSb3cgKyAyKSAvIDIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fd29ya2Vyc1tpXS5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgICAge3ZhbHVlcywgZm5OYW1lcywgc3RhcnRSb3csIHN0YXJ0Q29sLCBjaHVuY2tTaXplOiBlbmQgLSBzdGFydCwgb3B0cywgd2VpZ2h0cywgYWdncmVnYXRpb25NZXRob2R9XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcHJvbWlzZXNbaV0gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZVdvcmtlciwgcmVqZWN0V29ya2VyKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuX3dvcmtlcnNbaV0ub25tZXNzYWdlID0gKHtkYXRhOiB7ZXJyb3IsIGRpc3RhbmNlTWF0cml4RGF0YSwgbWluLCBtYXh9fSk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Rlcm1pbmF0ZU9uQ29tcGxldGUgJiYgc2V0VGltZW91dCgoKSA9PiB0aGlzLl93b3JrZXJzW2ldLnRlcm1pbmF0ZSgpKTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIHJlamVjdFdvcmtlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGRpc3RhbmNlTWF0cml4LnNldChkaXN0YW5jZU1hdHJpeERhdGEsIHN0YXJ0KTtcbiAgICAgICAgICAgICAgICAgIGlmIChtaW4gPCBsbWluKVxuICAgICAgICAgICAgICAgICAgICBsbWluID0gbWluO1xuICAgICAgICAgICAgICAgICAgaWYgKG1heCA+IGxtYXgpXG4gICAgICAgICAgICAgICAgICAgIGxtYXggPSBtYXg7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlV29ya2VyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgICBpZiAobm9ybWFsaXplKVxuICAgICAgICAgICAgZGlzdGFuY2VNYXRyaXguZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7IGRpc3RhbmNlTWF0cml4W2luZGV4XSA9ICh2YWx1ZSAtIGxtaW4pIC8gKGxtYXggLSBsbWluKTsgfSk7XG4gICAgICAgICAgcmVzb2x2ZShkaXN0YW5jZU1hdHJpeCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyB0ZXJtaW5hdGUoKTogdm9pZCB7XG4gICAgICB0aGlzLl93b3JrZXJzLmZvckVhY2goKHdvcmtlcikgPT4gd29ya2VyLnRlcm1pbmF0ZSgpKTtcbiAgICB9XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * Simple random integer function\n */\nexport function tauRandInt(n, random) {\n return Math.floor(random() * n);\n}\n/**\n * Simple random float function\n */\nexport function tauRand(random) {\n return random();\n}\n/**\n * Compute the (standard l2) norm of a vector.\n */\nexport function norm(vec) {\n let result = 0;\n for (const item of vec)\n result += item ** 2;\n return Math.sqrt(result);\n}\n/**\n * Creates an empty array (filled with undefined)\n */\nexport function empty(n) {\n const output = [];\n for (let i = 0; i < n; i++)\n output.push(undefined);\n return output;\n}\n/**\n * Creates an array filled with index values\n */\nexport function range(n) {\n return empty(n).map((_, i) => i);\n}\n/**\n * Creates an array filled with a specific value\n */\nexport function filled(n, v) {\n return empty(n).map(() => v);\n}\n/**\n * Creates an array filled with zeros\n */\nexport function zeros(n) {\n return filled(n, 0);\n}\n/**\n * Creates an array filled with ones\n */\nexport function ones(n) {\n return filled(n, 1);\n}\n/**\n * Creates an array from a to b, of length len, inclusive\n */\nexport function linear(a, b, len) {\n return empty(len).map((_, i) => {\n return a + i * ((b - a) / (len - 1));\n });\n}\n/**\n * Returns the sum of an array\n */\nexport function sum(input) {\n return input.reduce((sum, val) => sum + val);\n}\n/**\n * Returns the mean of an array\n */\nexport function mean(input) {\n return sum(input) / input.length;\n}\n/**\n * Returns the maximum value of an array\n */\nexport function max(input) {\n let max = 0;\n for (let i = 0; i < input.length; i++)\n max = input[i] > max ? input[i] : max;\n return max;\n}\n/**\n * Returns the maximum value of a 2d array\n */\nexport function max2d(input) {\n let max = 0;\n for (let i = 0; i < input.length; i++) {\n for (let j = 0; j < input[i].length; j++)\n max = input[i][j] > max ? input[i][j] : max;\n }\n return max;\n}\n/**\n * Generate nSamples many integers from 0 to poolSize such that no\n * integer is selected twice. The duplication constraint is achieved via\n * rejection sampling.\n */\nexport function rejectionSample(nSamples, poolSize, random) {\n const result = zeros(nSamples);\n for (let i = 0; i < nSamples; i++) {\n let rejectSample = true;\n while (rejectSample) {\n const j = tauRandInt(poolSize, random);\n let broken = false;\n for (let k = 0; k < i; k++) {\n if (j === result[k]) {\n broken = true;\n break;\n }\n }\n if (!broken)\n rejectSample = false;\n result[i] = j;\n }\n }\n return result;\n}\n/**\n * Reshapes a 1d array into a 2D of given dimensions.\n */\nexport function reshape2d(x, a, b) {\n const rows = [];\n // let count = 0;\n let index = 0;\n if (x.length !== a * b)\n throw new Error('Array dimensions must match input length.');\n for (let i = 0; i < a; i++) {\n const col = [];\n for (let j = 0; j < b; j++) {\n col.push(x[index]);\n index += 1;\n }\n rows.push(col);\n // count += 1;\n }\n return rows;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFJSDs7R0FFRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsQ0FBUyxFQUFFLE1BQWdCO0lBQ3BELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLE1BQWdCO0lBQ3RDLE9BQU8sTUFBTSxFQUFFLENBQUM7QUFDbEIsQ0FBQztBQUNEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FBQyxHQUFhO0lBQ2hDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNmLEtBQUssTUFBTSxJQUFJLElBQUksR0FBRztRQUNwQixNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQztJQUV0QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLEtBQUssQ0FBQyxDQUFTO0lBQzdCLE1BQU0sTUFBTSxHQUFnQixFQUFFLENBQUM7SUFDL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUU7UUFDeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV6QixPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsS0FBSyxDQUFDLENBQVM7SUFDN0IsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxV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QztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDZixjQUFjO0lBQ2hCLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQge1JhbmRvbUZufSBmcm9tICcuL3VtYXAnO1xuXG4vKipcbiAqIFNpbXBsZSByYW5kb20gaW50ZWdlciBmdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdGF1UmFuZEludChuOiBudW1iZXIsIHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IocmFuZG9tKCkgKiBuKTtcbn1cblxuLyoqXG4gKiBTaW1wbGUgcmFuZG9tIGZsb2F0IGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0YXVSYW5kKHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIHJhbmRvbSgpO1xufVxuLyoqXG4gKiBDb21wdXRlIHRoZSAoc3RhbmRhcmQgbDIpIG5vcm0gb2YgYSB2ZWN0b3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtKHZlYzogbnVtYmVyW10pIHtcbiAgbGV0IHJlc3VsdCA9IDA7XG4gIGZvciAoY29uc3QgaXRlbSBvZiB2ZWMpXG4gICAgcmVzdWx0ICs9IGl0ZW0gKiogMjtcblxuICByZXR1cm4gTWF0aC5zcXJ0KHJlc3VsdCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBlbXB0eSBhcnJheSAoZmlsbGVkIHdpdGggdW5kZWZpbmVkKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZW1wdHkobjogbnVtYmVyKTogdW5kZWZpbmVkW10ge1xuICBjb25zdCBvdXRwdXQ6IHVuZGVmaW5lZFtdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKVxuICAgIG91dHB1dC5wdXNoKHVuZGVmaW5lZCk7XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGluZGV4IHZhbHVlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2UobjogbnVtYmVyKTogbnVtYmVyW10ge1xuICByZXR1cm4gZW1wdHkobikubWFwKChfLCBpKSA9PiBpKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGEgc3BlY2lmaWMgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGxlZChuOiBudW1iZXIsIHY6IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGVtcHR5KG4pLm1hcCgoKSA9PiB2KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIHplcm9zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvcyhuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBmaWxsZWQobiwgMCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBmaWxsZWQgd2l0aCBvbmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVzKG46IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGZpbGxlZChuLCAxKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZyb20gYSB0byBiLCBvZiBsZW5ndGggbGVuLCBpbmNsdXNpdmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhcihhOiBudW1iZXIsIGI6IG51bWJlciwgbGVuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBlbXB0eShsZW4pLm1hcCgoXywgaSkgPT4ge1xuICAgIHJldHVybiBhICsgaSAqICgoYiAtIGEpIC8gKGxlbiAtIDEpKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3VtIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdW0oaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgcmV0dXJuIGlucHV0LnJlZHVjZSgoc3VtLCB2YWwpID0+IHN1bSArIHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWVhbiBvZiBhbiBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVhbihpbnB1dDogbnVtYmVyW10pOiBudW1iZXIge1xuICByZXR1cm4gc3VtKGlucHV0KSAvIGlucHV0Lmxlbmd0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgoaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgbGV0IG1heCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspXG4gICAgbWF4ID0gaW5wdXRbaV0gPiBtYXggPyBpbnB1dFtpXSA6IG1heDtcblxuICByZXR1cm4gbWF4O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUgb2YgYSAyZCBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF4MmQoaW5wdXQ6IG51bWJlcltdW10pOiBudW1iZXIge1xuICBsZXQgbWF4ID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRbaV0ubGVuZ3RoOyBqKyspXG4gICAgICBtYXggPSBpbnB1dFtpXVtqXSA+IG1heCA/IGlucHV0W2ldW2pdIDogbWF4O1xuICB9XG4gIHJldHVybiBtYXg7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgblNhbXBsZXMgbWFueSBpbnRlZ2VycyBmcm9tIDAgdG8gcG9vbFNpemUgc3VjaCB0aGF0IG5vXG4gKiBpbnRlZ2VyIGlzIHNlbGVjdGVkIHR3aWNlLiBUaGUgZHVwbGljYXRpb24gY29uc3RyYWludCBpcyBhY2hpZXZlZCB2aWFcbiAqIHJlamVjdGlvbiBzYW1wbGluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlamVjdGlvblNhbXBsZShcbiAgblNhbXBsZXM6IG51bWJlcixcbiAgcG9vbFNpemU6IG51bWJlcixcbiAgcmFuZG9tOiBSYW5kb21GblxuKTogbnVtYmVyW10ge1xuICBjb25zdCByZXN1bHQgPSB6ZXJvcyhuU2FtcGxlcyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgblNhbXBsZXM7IGkrKykge1xuICAgIGxldCByZWplY3RTYW1wbGUgPSB0cnVlO1xuICAgIHdoaWxlIChyZWplY3RTYW1wbGUpIHtcbiAgICAgIGNvbnN0IGogPSB0YXVSYW5kSW50KHBvb2xTaXplLCByYW5kb20pO1xuICAgICAgbGV0IGJyb2tlbiA9IGZhbHNlO1xuICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBpOyBrKyspIHtcbiAgICAgICAgaWYgKGogPT09IHJlc3VsdFtrXSkge1xuICAgICAgICAgIGJyb2tlbiA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghYnJva2VuKVxuICAgICAgICByZWplY3RTYW1wbGUgPSBmYWxzZTtcblxuICAgICAgcmVzdWx0W2ldID0gajtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBSZXNoYXBlcyBhIDFkIGFycmF5IGludG8gYSAyRCBvZiBnaXZlbiBkaW1lbnNpb25zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzaGFwZTJkPFQ+KHg6IFRbXSwgYTogbnVtYmVyLCBiOiBudW1iZXIpOiBUW11bXSB7XG4gIGNvbnN0IHJvd3M6IFRbXVtdID0gW107XG4gIC8vIGxldCBjb3VudCA9IDA7XG4gIGxldCBpbmRleCA9IDA7XG5cbiAgaWYgKHgubGVuZ3RoICE9PSBhICogYilcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FycmF5IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCBpbnB1dCBsZW5ndGguJyk7XG5cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGE7IGkrKykge1xuICAgIGNvbnN0IGNvbDogVFtdID0gW107XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBiOyBqKyspIHtcbiAgICAgIGNvbC5wdXNoKHhbaW5kZXhdKTtcbiAgICAgIGluZGV4ICs9IDE7XG4gICAgfVxuICAgIHJvd3MucHVzaChjb2wpO1xuICAgIC8vIGNvdW50ICs9IDE7XG4gIH1cbiAgcmV0dXJuIHJvd3M7XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\nimport * as utils from './utils';\n/**\n * Constructor for the heap objects. The heaps are used\n * for approximate nearest neighbor search, maintaining a list of potential\n * neighbors sorted by their distance. We also flag if potential neighbors\n * are newly added to the list or not. Internally this is stored as\n * a single array; the first axis determines whether we are looking at the\n * array of candidate indices, the array of distances, or the flag array for\n * whether elements are new or not. Each of these arrays are of shape\n * (``nPoints``, ``size``)\n */\nexport function makeHeap(nPoints, size) {\n const makeArrays = (fillValue) => {\n return utils.empty(nPoints).map(() => {\n return utils.filled(size, fillValue);\n });\n };\n const heap = [];\n heap.push(makeArrays(-1));\n heap.push(makeArrays(Infinity));\n heap.push(makeArrays(0));\n return heap;\n}\n/**\n * Generate n_samples many integers from 0 to pool_size such that no\n * integer is selected twice. The duplication constraint is achieved via\n * rejection sampling.\n */\nexport function rejectionSample(nSamples, poolSize, random) {\n const result = utils.zeros(nSamples);\n for (let i = 0; i < nSamples; i++) {\n let rejectSample = true;\n let j = 0;\n while (rejectSample) {\n j = utils.tauRandInt(poolSize, random);\n let broken = false;\n for (let k = 0; k < i; k++) {\n if (j === result[k]) {\n broken = true;\n break;\n }\n }\n if (!broken)\n rejectSample = false;\n }\n result[i] = j;\n }\n return result;\n}\n/**\n * Push a new element onto the heap. The heap stores potential neighbors\n * for each data point. The ``row`` parameter determines which data point we\n * are addressing, the ``weight`` determines the distance (for heap sorting),\n * the ``index`` is the element to add, and the flag determines whether this\n * is to be considered a new addition.\n */\nexport function heapPush(heap, row, weight, index, flag) {\n row = Math.floor(row);\n const indices = heap[0][row];\n const weights = heap[1][row];\n //const isNew = heap[2][row];\n if (weight >= weights[0])\n return 0;\n // Break if we already have this element.\n for (let i = 0; i < indices.length; i++) {\n if (index === indices[i])\n return 0;\n }\n return uncheckedHeapPush(heap, row, weight, index, flag);\n}\n/**\n * Push a new element onto the heap. The heap stores potential neighbors\n * for each data point. The ``row`` parameter determines which data point we\n * are addressing, the ``weight`` determines the distance (for heap sorting),\n * the ``index`` is the element to add, and the flag determines whether this\n * is to be considered a new addition.\n */\nexport function uncheckedHeapPush(heap, row, weight, index, flag) {\n const indices = heap[0][row];\n const weights = heap[1][row];\n const isNew = heap[2][row];\n if (weight >= weights[0])\n return 0;\n // Insert val at position zero\n weights[0] = weight;\n indices[0] = index;\n isNew[0] = flag;\n // Descend the heap, swapping values until the max heap criterion is met\n let i = 0;\n let iSwap = 0;\n while (true) {\n const ic1 = 2 * i + 1;\n const ic2 = ic1 + 1;\n const heapShape2 = heap[0][0].length;\n if (ic1 >= heapShape2) {\n break;\n }\n else if (ic2 >= heapShape2) {\n if (weights[ic1] > weight)\n iSwap = ic1;\n else\n break;\n }\n else if (weights[ic1] >= weights[ic2]) {\n if (weight < weights[ic1])\n iSwap = ic1;\n else\n break;\n }\n else {\n if (weight < weights[ic2])\n iSwap = ic2;\n else\n break;\n }\n weights[i] = weights[iSwap];\n indices[i] = indices[iSwap];\n isNew[i] = isNew[iSwap];\n i = iSwap;\n }\n weights[i] = weight;\n indices[i] = index;\n isNew[i] = flag;\n return 1;\n}\n/**\n * Build a heap of candidate neighbors for nearest neighbor descent. For\n * each vertex the candidate neighbors are any current neighbors, and any\n * vertices that have the vertex as one of their nearest neighbors.\n */\nexport function buildCandidates(currentGraph, nVertices, nNeighbors, maxCandidates, random) {\n const candidateNeighbors = makeHeap(nVertices, maxCandidates);\n for (let i = 0; i < nVertices; i++) {\n for (let j = 0; j < nNeighbors; j++) {\n if (currentGraph[0][i][j] < 0)\n continue;\n const idx = currentGraph[0][i][j];\n const isn = currentGraph[2][i][j];\n const d = utils.tauRand(random);\n heapPush(candidateNeighbors, i, d, idx, isn);\n heapPush(candidateNeighbors, idx, d, i, isn);\n currentGraph[2][i][j] = 0;\n }\n }\n return candidateNeighbors;\n}\n/**\n * Given an array of heaps (of indices and weights), unpack the heap\n * out to give and array of sorted lists of indices and weights by increasing\n * weight. This is effectively just the second half of heap sort (the first\n * half not being required since we already have the data in a heap).\n */\nexport function deheapSort(heap) {\n const indices = heap[0];\n const weights = heap[1];\n for (let i = 0; i < indices.length; i++) {\n const indHeap = indices[i];\n const distHeap = weights[i];\n for (let j = 0; j < indHeap.length - 1; j++) {\n const indHeapIndex = indHeap.length - j - 1;\n const distHeapIndex = distHeap.length - j - 1;\n const temp1 = indHeap[0];\n indHeap[0] = indHeap[indHeapIndex];\n indHeap[indHeapIndex] = temp1;\n const temp2 = distHeap[0];\n distHeap[0] = distHeap[distHeapIndex];\n distHeap[distHeapIndex] = temp2;\n siftDown(distHeap, indHeap, distHeapIndex, 0);\n }\n }\n return { indices, weights };\n}\n/**\n * Restore the heap property for a heap with an out of place element\n * at position ``elt``. This works with a heap pair where heap1 carries\n * the weights and heap2 holds the corresponding elements.\n */\nfunction siftDown(heap1, heap2, ceiling, elt) {\n while (elt * 2 + 1 < ceiling) {\n const leftChild = elt * 2 + 1;\n const rightChild = leftChild + 1;\n let swap = elt;\n if (heap1[swap] < heap1[leftChild])\n swap = leftChild;\n if (rightChild < ceiling && heap1[swap] < heap1[rightChild])\n swap = rightChild;\n if (swap === elt) {\n break;\n }\n else {\n const temp1 = heap1[elt];\n heap1[elt] = heap1[swap];\n heap1[swap] = temp1;\n const temp2 = heap2[elt];\n heap2[elt] = heap2[swap];\n heap2[swap] = temp2;\n elt = swap;\n }\n }\n}\n/**\n * Search the heap for the smallest element that is still flagged.\n */\nexport function smallestFlagged(heap, row) {\n const ind = heap[0][row];\n const dist = heap[1][row];\n const flag = heap[2][row];\n let minDist = Infinity;\n let resultIndex = -1;\n for (let i = 0; i > ind.length; i++) {\n if (flag[i] === 1 && dist[i] < minDist) {\n minDist = dist[i];\n resultIndex = i;\n }\n }\n if (resultIndex >= 0) {\n flag[resultIndex] = 0;\n return Math.floor(ind[resultIndex]);\n }\n else {\n return -1;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhlYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBMkNILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsT0FBZSxFQUFFLElBQVk7SUFDcEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxTQUFpQixFQUFFLEVBQUU7UUFDdkMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDbkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztJQUVGLE1BQU0sSUFBSSxHQUFTLEVBQUUsQ0FBQztJQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUM3QixRQUFnQixFQUNoQixRQUFnQixFQUNoQixNQUFnQjtJQUVoQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNsQyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDeEIsSUFBSSxDQUFDLEdBQUcs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SUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUxQixJQUFJLE9BQU8sR0FBRyxRQUFRLENBQUM7SUFDdkIsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNwQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO1lBQ3ZDLE9BQU8sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEIsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksV0FBVyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7U0FBTSxDQUFDO1FBQ04sT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNaLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgSmF2YVNjcmlwdCByZWltcGxlbWVudGF0aW9uIG9mIFVNQVAgKG9yaWdpbmFsIGxpY2Vuc2UgYmVsb3cpLCBmcm9tXG4gKiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9sbWNpbm5lcy91bWFwLlxuICpcbiAqIEBhdXRob3IgYW5keWNvZW5lbkBnb29nbGUuY29tIChBbmR5IENvZW5lbilcbiAqL1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBCU0QgMy1DbGF1c2UgTGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNywgTGVsYW5kIE1jSW5uZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4gKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcbiAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXG4gKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcbiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuaW1wb3J0IHtSYW5kb21Gbn0gZnJvbSAnLi91bWFwJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgdHlwZSBIZWFwID0gbnVtYmVyW11bXVtdO1xuXG4vKipcbiAqICBDb25zdHJ1Y3RvciBmb3IgdGhlIGhlYXAgb2JqZWN0cy4gVGhlIGhlYXBzIGFyZSB1c2VkXG4gKiBmb3IgYXBwcm94aW1hdGUgbmVhcmVzdCBuZWlnaGJvciBzZWFyY2gsIG1haW50YWluaW5nIGEgbGlzdCBvZiBwb3RlbnRpYWxcbiAqIG5laWdoYm9ycyBzb3J0ZWQgYnkgdGhlaXIgZGlzdGFuY2UuIFdlIGFsc28gZmxhZyBpZiBwb3RlbnRpYWwgbmVpZ2hib3JzXG4gKiBhcmUgbmV3bHkgYWRkZWQgdG8gdGhlIGxpc3Qgb3Igbm90LiBJbnRlcm5hbGx5IHRoaXMgaXMgc3RvcmVkIGFzXG4gKiBhIHNpbmdsZSBhcnJheTsgdGhlIGZpcnN0IGF4aXMgZGV0ZXJtaW5lcyB3aGV0aGVyIHdlIGFyZSBsb29raW5nIGF0IHRoZVxuICogYXJyYXkgb2YgY2FuZGlkYXRlIGluZGljZXMsIHRoZSBhcnJheSBvZiBkaXN0YW5jZXMsIG9yIHRoZSBmbGFnIGFycmF5IGZvclxuICogd2hldGhlciBlbGVtZW50cyBhcmUgbmV3IG9yIG5vdC4gRWFjaCBvZiB0aGVzZSBhcnJheXMgYXJlIG9mIHNoYXBlXG4gKiAoYGBuUG9pbnRzYGAsIGBgc2l6ZWBgKVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFrZUhlYXAoblBvaW50czogbnVtYmVyLCBzaXplOiBudW1iZXIpOiBIZWFwIHtcbiAgY29uc3QgbWFrZUFycmF5cyA9IChmaWxsVmFsdWU6IG51bWJlcikgPT4ge1xuICAgIHJldHVybiB1dGlscy5lbXB0eShuUG9pbnRzKS5tYXAoKCkgPT4ge1xuICAgICAgcmV0dXJuIHV0aWxzLmZpbGxlZChzaXplLCBmaWxsVmFsdWUpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGhlYXA6IEhlYXAgPSBbXTtcbiAgaGVhcC5wdXNoKG1ha2VBcnJheXMoLTEpKTtcbiAgaGVhcC5wdXNoKG1ha2VBcnJheXMoSW5maW5pdHkpKTtcbiAgaGVhcC5wdXNoKG1ha2VBcnJheXMoMCkpO1xuICByZXR1cm4gaGVhcDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBuX3NhbXBsZXMgbWFueSBpbnRlZ2VycyBmcm9tIDAgdG8gcG9vbF9zaXplIHN1Y2ggdGhhdCBub1xuICogaW50ZWdlciBpcyBzZWxlY3RlZCB0d2ljZS4gVGhlIGR1cGxpY2F0aW9uIGNvbnN0cmFpbnQgaXMgYWNoaWV2ZWQgdmlhXG4gKiByZWplY3Rpb24gc2FtcGxpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWplY3Rpb25TYW1wbGUoXG4gIG5TYW1wbGVzOiBudW1iZXIsXG4gIHBvb2xTaXplOiBudW1iZXIsXG4gIHJhbmRvbTogUmFuZG9tRm5cbikge1xuICBjb25zdCByZXN1bHQgPSB1dGlscy56ZXJvcyhuU2FtcGxlcyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgblNhbXBsZXM7IGkrKykge1xuICAgIGxldCByZWplY3RTYW1wbGUgPSB0cnVlO1xuICAgIGxldCBqID0gMDtcbiAgICB3aGlsZSAocmVqZWN0U2FtcGxlKSB7XG4gICAgICBqID0gdXRpbHMudGF1UmFuZEludChwb29sU2l6ZSwgcmFuZG9tKTtcbiAgICAgIGxldCBicm9rZW4gPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaTsgaysrKSB7XG4gICAgICAgIGlmIChqID09PSByZXN1bHRba10pIHtcbiAgICAgICAgICBicm9rZW4gPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWJyb2tlbikgcmVqZWN0U2FtcGxlID0gZmFsc2U7XG4gICAgfVxuICAgIHJlc3VsdFtpXSA9IGo7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBQdXNoIGEgbmV3IGVsZW1lbnQgb250byB0aGUgaGVhcC4gVGhlIGhlYXAgc3RvcmVzIHBvdGVudGlhbCBuZWlnaGJvcnNcbiAqIGZvciBlYWNoIGRhdGEgcG9pbnQuIFRoZSBgYHJvd2BgIHBhcmFtZXRlciBkZXRlcm1pbmVzIHdoaWNoIGRhdGEgcG9pbnQgd2VcbiAqIGFyZSBhZGRyZXNzaW5nLCB0aGUgYGB3ZWlnaHRgYCBkZXRlcm1pbmVzIHRoZSBkaXN0YW5jZSAoZm9yIGhlYXAgc29ydGluZyksXG4gKiB0aGUgYGBpbmRleGBgIGlzIHRoZSBlbGVtZW50IHRvIGFkZCwgYW5kIHRoZSBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGlzXG4gKiBpcyB0byBiZSBjb25zaWRlcmVkIGEgbmV3IGFkZGl0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGVhcFB1c2goXG4gIGhlYXA6IEhlYXAsXG4gIHJvdzogbnVtYmVyLFxuICB3ZWlnaHQ6IG51bWJlcixcbiAgaW5kZXg6IG51bWJlcixcbiAgZmxhZzogbnVtYmVyXG4pOiBudW1iZXIge1xuICByb3cgPSBNYXRoLmZsb29yKHJvdyk7XG4gIGNvbnN0IGluZGljZXMgPSBoZWFwWzBdW3Jvd107XG4gIGNvbnN0IHdlaWdodHMgPSBoZWFwWzFdW3Jvd107XG4gIC8vY29uc3QgaXNOZXcgPSBoZWFwWzJdW3Jvd107XG5cbiAgaWYgKHdlaWdodCA+PSB3ZWlnaHRzWzBdKVxuICAgIHJldHVybiAwO1xuXG5cbiAgLy8gQnJlYWsgaWYgd2UgYWxyZWFkeSBoYXZlIHRoaXMgZWxlbWVudC5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGluZGV4ID09PSBpbmRpY2VzW2ldKVxuICAgICAgcmV0dXJuIDA7XG4gIH1cblxuICByZXR1cm4gdW5jaGVja2VkSGVhcFB1c2goaGVhcCwgcm93LCB3ZWlnaHQsIGluZGV4LCBmbGFnKTtcbn1cblxuLyoqXG4gKiBQdXNoIGEgbmV3IGVsZW1lbnQgb250byB0aGUgaGVhcC4gVGhlIGhlYXAgc3RvcmVzIHBvdGVudGlhbCBuZWlnaGJvcnNcbiAqIGZvciBlYWNoIGRhdGEgcG9pbnQuIFRoZSBgYHJvd2BgIHBhcmFtZXRlciBkZXRlcm1pbmVzIHdoaWNoIGRhdGEgcG9pbnQgd2VcbiAqIGFyZSBhZGRyZXNzaW5nLCB0aGUgYGB3ZWlnaHRgYCBkZXRlcm1pbmVzIHRoZSBkaXN0YW5jZSAoZm9yIGhlYXAgc29ydGluZyksXG4gKiB0aGUgYGBpbmRleGBgIGlzIHRoZSBlbGVtZW50IHRvIGFkZCwgYW5kIHRoZSBmbGFnIGRldGVybWluZXMgd2hldGhlciB0aGlzXG4gKiBpcyB0byBiZSBjb25zaWRlcmVkIGEgbmV3IGFkZGl0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5jaGVja2VkSGVhcFB1c2goXG4gIGhlYXA6IEhlYXAsXG4gIHJvdzogbnVtYmVyLFxuICB3ZWlnaHQ6IG51bWJlcixcbiAgaW5kZXg6IG51bWJlcixcbiAgZmxhZzogbnVtYmVyXG4pOiBudW1iZXIge1xuICBjb25zdCBpbmRpY2VzID0gaGVhcFswXVtyb3ddO1xuICBjb25zdCB3ZWlnaHRzID0gaGVhcFsxXVtyb3ddO1xuICBjb25zdCBpc05ldyA9IGhlYXBbMl1bcm93XTtcblxuICBpZiAod2VpZ2h0ID49IHdlaWdodHNbMF0pXG4gICAgcmV0dXJuIDA7XG5cblxuICAvLyBJbnNlcnQgdmFsIGF0IHBvc2l0aW9uIHplcm9cbiAgd2VpZ2h0c1swXSA9IHdlaWdodDtcbiAgaW5kaWNlc1swXSA9IGluZGV4O1xuICBpc05ld1swXSA9IGZsYWc7XG5cbiAgLy8gRGVzY2VuZCB0aGUgaGVhcCwgc3dhcHBpbmcgdmFsdWVzIHVudGlsIHRoZSBtYXggaGVhcCBjcml0ZXJpb24gaXMgbWV0XG4gIGxldCBpID0gMDtcbiAgbGV0IGlTd2FwID0gMDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCBpYzEgPSAyICogaSArIDE7XG4gICAgY29uc3QgaWMyID0gaWMxICsgMTtcblxuICAgIGNvbnN0IGhlYXBTaGFwZTIgPSBoZWFwWzBdWzBdLmxlbmd0aDtcbiAgICBpZiAoaWMxID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoaWMyID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGlmICh3ZWlnaHRzW2ljMV0gPiB3ZWlnaHQpXG4gICAgICAgIGlTd2FwID0gaWMxO1xuICAgICAgZWxzZVxuICAgICAgICBicmVhaztcbiAgICB9IGVsc2UgaWYgKHdlaWdodHNbaWMxXSA+PSB3ZWlnaHRzW2ljMl0pIHtcbiAgICAgIGlmICh3ZWlnaHQgPCB3ZWlnaHRzW2ljMV0pXG4gICAgICAgIGlTd2FwID0gaWMxO1xuICAgICAgZWxzZVxuICAgICAgICBicmVhaztcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHdlaWdodCA8IHdlaWdodHNbaWMyXSlcbiAgICAgICAgaVN3YXAgPSBpYzI7XG4gICAgICBlbHNlXG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHdlaWdodHNbaV0gPSB3ZWlnaHRzW2lTd2FwXTtcbiAgICBpbmRpY2VzW2ldID0gaW5kaWNlc1tpU3dhcF07XG4gICAgaXNOZXdbaV0gPSBpc05ld1tpU3dhcF07XG5cbiAgICBpID0gaVN3YXA7XG4gIH1cblxuICB3ZWlnaHRzW2ldID0gd2VpZ2h0O1xuICBpbmRpY2VzW2ldID0gaW5kZXg7XG4gIGlzTmV3W2ldID0gZmxhZztcbiAgcmV0dXJuIDE7XG59XG5cbi8qKlxuICogQnVpbGQgYSBoZWFwIG9mIGNhbmRpZGF0ZSBuZWlnaGJvcnMgZm9yIG5lYXJlc3QgbmVpZ2hib3IgZGVzY2VudC4gRm9yXG4gKiBlYWNoIHZlcnRleCB0aGUgY2FuZGlkYXRlIG5laWdoYm9ycyBhcmUgYW55IGN1cnJlbnQgbmVpZ2hib3JzLCBhbmQgYW55XG4gKiB2ZXJ0aWNlcyB0aGF0IGhhdmUgdGhlIHZlcnRleCBhcyBvbmUgb2YgdGhlaXIgbmVhcmVzdCBuZWlnaGJvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENhbmRpZGF0ZXMoXG4gIGN1cnJlbnRHcmFwaDogSGVhcCxcbiAgblZlcnRpY2VzOiBudW1iZXIsXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgbWF4Q2FuZGlkYXRlczogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgY29uc3QgY2FuZGlkYXRlTmVpZ2hib3JzID0gbWFrZUhlYXAoblZlcnRpY2VzLCBtYXhDYW5kaWRhdGVzKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuVmVydGljZXM7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICBpZiAoY3VycmVudEdyYXBoWzBdW2ldW2pdIDwgMClcbiAgICAgICAgY29udGludWU7XG5cbiAgICAgIGNvbnN0IGlkeCA9IGN1cnJlbnRHcmFwaFswXVtpXVtqXTtcbiAgICAgIGNvbnN0IGlzbiA9IGN1cnJlbnRHcmFwaFsyXVtpXVtqXTtcbiAgICAgIGNvbnN0IGQgPSB1dGlscy50YXVSYW5kKHJhbmRvbSk7XG4gICAgICBoZWFwUHVzaChjYW5kaWRhdGVOZWlnaGJvcnMsIGksIGQsIGlkeCwgaXNuKTtcbiAgICAgIGhlYXBQdXNoKGNhbmRpZGF0ZU5laWdoYm9ycywgaWR4LCBkLCBpLCBpc24pO1xuICAgICAgY3VycmVudEdyYXBoWzJdW2ldW2pdID0gMDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNhbmRpZGF0ZU5laWdoYm9ycztcbn1cblxuLyoqXG4gKiBHaXZlbiBhbiBhcnJheSBvZiBoZWFwcyAob2YgaW5kaWNlcyBhbmQgd2VpZ2h0cyksIHVucGFjayB0aGUgaGVhcFxuICogb3V0IHRvIGdpdmUgYW5kIGFycmF5IG9mIHNvcnRlZCBsaXN0cyBvZiBpbmRpY2VzIGFuZCB3ZWlnaHRzIGJ5IGluY3JlYXNpbmdcbiAqIHdlaWdodC4gVGhpcyBpcyBlZmZlY3RpdmVseSBqdXN0IHRoZSBzZWNvbmQgaGFsZiBvZiBoZWFwIHNvcnQgKHRoZSBmaXJzdFxuICogaGFsZiBub3QgYmVpbmcgcmVxdWlyZWQgc2luY2Ugd2UgYWxyZWFkeSBoYXZlIHRoZSBkYXRhIGluIGEgaGVhcCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWhlYXBTb3J0KGhlYXA6IEhlYXApIHtcbiAgY29uc3QgaW5kaWNlcyA9IGhlYXBbMF07XG4gIGNvbnN0IHdlaWdodHMgPSBoZWFwWzFdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGluZEhlYXAgPSBpbmRpY2VzW2ldO1xuICAgIGNvbnN0IGRpc3RIZWFwID0gd2VpZ2h0c1tpXTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kSGVhcC5sZW5ndGggLSAxOyBqKyspIHtcbiAgICAgIGNvbnN0IGluZEhlYXBJbmRleCA9IGluZEhlYXAubGVuZ3RoIC0gaiAtIDE7XG4gICAgICBjb25zdCBkaXN0SGVhcEluZGV4ID0gZGlzdEhlYXAubGVuZ3RoIC0gaiAtIDE7XG5cbiAgICAgIGNvbnN0IHRlbXAxID0gaW5kSGVhcFswXTtcbiAgICAgIGluZEhlYXBbMF0gPSBpbmRIZWFwW2luZEhlYXBJbmRleF07XG4gICAgICBpbmRIZWFwW2luZEhlYXBJbmRleF0gPSB0ZW1wMTtcblxuICAgICAgY29uc3QgdGVtcDIgPSBkaXN0SGVhcFswXTtcbiAgICAgIGRpc3RIZWFwWzBdID0gZGlzdEhlYXBbZGlzdEhlYXBJbmRleF07XG4gICAgICBkaXN0SGVhcFtkaXN0SGVhcEluZGV4XSA9IHRlbXAyO1xuXG4gICAgICBzaWZ0RG93bihkaXN0SGVhcCwgaW5kSGVhcCwgZGlzdEhlYXBJbmRleCwgMCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7aW5kaWNlcywgd2VpZ2h0c307XG59XG5cbi8qKlxuICogUmVzdG9yZSB0aGUgaGVhcCBwcm9wZXJ0eSBmb3IgYSBoZWFwIHdpdGggYW4gb3V0IG9mIHBsYWNlIGVsZW1lbnRcbiAqIGF0IHBvc2l0aW9uIGBgZWx0YGAuIFRoaXMgd29ya3Mgd2l0aCBhIGhlYXAgcGFpciB3aGVyZSBoZWFwMSBjYXJyaWVzXG4gKiB0aGUgd2VpZ2h0cyBhbmQgaGVhcDIgaG9sZHMgdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMuXG4gKi9cbmZ1bmN0aW9uIHNpZnREb3duKFxuICBoZWFwMTogbnVtYmVyW10sXG4gIGhlYXAyOiBudW1iZXJbXSxcbiAgY2VpbGluZzogbnVtYmVyLFxuICBlbHQ6IG51bWJlclxuKSB7XG4gIHdoaWxlIChlbHQgKiAyICsgMSA8IGNlaWxpbmcpIHtcbiAgICBjb25zdCBsZWZ0Q2hpbGQgPSBlbHQgKiAyICsgMTtcbiAgICBjb25zdCByaWdodENoaWxkID0gbGVmdENoaWxkICsgMTtcbiAgICBsZXQgc3dhcCA9IGVsdDtcblxuICAgIGlmIChoZWFwMVtzd2FwXSA8IGhlYXAxW2xlZnRDaGlsZF0pXG4gICAgICBzd2FwID0gbGVmdENoaWxkO1xuXG4gICAgaWYgKHJpZ2h0Q2hpbGQgPCBjZWlsaW5nICYmIGhlYXAxW3N3YXBdIDwgaGVhcDFbcmlnaHRDaGlsZF0pXG4gICAgICBzd2FwID0gcmlnaHRDaGlsZDtcblxuXG4gICAgaWYgKHN3YXAgPT09IGVsdCkge1xuICAgICAgYnJlYWs7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRlbXAxID0gaGVhcDFbZWx0XTtcbiAgICAgIGhlYXAxW2VsdF0gPSBoZWFwMVtzd2FwXTtcbiAgICAgIGhlYXAxW3N3YXBdID0gdGVtcDE7XG5cbiAgICAgIGNvbnN0IHRlbXAyID0gaGVhcDJbZWx0XTtcbiAgICAgIGhlYXAyW2VsdF0gPSBoZWFwMltzd2FwXTtcbiAgICAgIGhlYXAyW3N3YXBdID0gdGVtcDI7XG4gICAgICBlbHQgPSBzd2FwO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNlYXJjaCB0aGUgaGVhcCBmb3IgdGhlIHNtYWxsZXN0IGVsZW1lbnQgdGhhdCBpcyBzdGlsbCBmbGFnZ2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc21hbGxlc3RGbGFnZ2VkKGhlYXA6IEhlYXAsIHJvdzogbnVtYmVyKSB7XG4gIGNvbnN0IGluZCA9IGhlYXBbMF1bcm93XTtcbiAgY29uc3QgZGlzdCA9IGhlYXBbMV1bcm93XTtcbiAgY29uc3QgZmxhZyA9IGhlYXBbMl1bcm93XTtcblxuICBsZXQgbWluRGlzdCA9IEluZmluaXR5O1xuICBsZXQgcmVzdWx0SW5kZXggPSAtMTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA+IGluZC5sZW5ndGg7IGkrKykge1xuICAgIGlmIChmbGFnW2ldID09PSAxICYmIGRpc3RbaV0gPCBtaW5EaXN0KSB7XG4gICAgICBtaW5EaXN0ID0gZGlzdFtpXTtcbiAgICAgIHJlc3VsdEluZGV4ID0gaTtcbiAgICB9XG4gIH1cblxuICBpZiAocmVzdWx0SW5kZXggPj0gMCkge1xuICAgIGZsYWdbcmVzdWx0SW5kZXhdID0gMDtcbiAgICByZXR1cm4gTWF0aC5mbG9vcihpbmRbcmVzdWx0SW5kZXhdKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbn1cbiJdfQ==","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\nimport * as utils from './utils';\n/**\n * Internal 2-dimensional sparse matrix class\n */\nexport class SparseMatrix {\n constructor(rows, cols, values, dims) {\n this.entries = new Map();\n this.nRows = 0;\n this.nCols = 0;\n if (rows.length !== cols.length || rows.length !== values.length) {\n throw new Error('rows, cols and values arrays must all have the same length');\n }\n // TODO: Assert that dims are legit.\n this.nRows = dims[0];\n this.nCols = dims[1];\n for (let i = 0; i < values.length; i++) {\n const row = rows[i];\n const col = cols[i];\n this.checkDims(row, col);\n const key = this.makeKey(row, col);\n this.entries.set(key, { value: values[i], row, col });\n }\n }\n makeKey(row, col) {\n return `${row}:${col}`;\n }\n checkDims(row, col) {\n const withinBounds = row < this.nRows && col < this.nCols;\n if (!withinBounds)\n throw new Error('row and/or col specified outside of matrix dimensions');\n }\n set(row, col, value) {\n this.checkDims(row, col);\n const key = this.makeKey(row, col);\n if (!this.entries.has(key))\n this.entries.set(key, { value, row, col });\n else\n this.entries.get(key).value = value;\n }\n get(row, col, defaultValue = 0) {\n //this.checkDims(row, col);\n const key = this.makeKey(row, col);\n if (this.entries.has(key))\n return this.entries.get(key).value;\n else\n return defaultValue;\n }\n getAll(ordered = true) {\n const rowColValues = new Array(this.entries.size).fill(null);\n let i = 0;\n this.entries.forEach((value) => {\n rowColValues[i++] = value;\n });\n if (ordered) {\n // Ordering the result isn't required for processing but it does make it easier to write tests\n rowColValues.sort((a, b) => {\n if (a.row === b.row)\n return a.col - b.col;\n else\n return a.row - b.row;\n });\n }\n return rowColValues;\n }\n getDims() {\n return [this.nRows, this.nCols];\n }\n getRows() {\n return Array.from(this.entries, ([_key, value]) => value.row);\n // return this.rows as unknown as number[];\n }\n getCols() {\n return Array.from(this.entries, ([_key, value]) => value.col);\n // return this.cols as unknown as number[];\n }\n getValues() {\n return Array.from(this.entries, ([_key, value]) => value.value);\n //return this.values as unknown as number[];\n }\n forEach(fn) {\n this.entries.forEach((value) => fn(value.value, value.row, value.col));\n }\n map(fn) {\n const vals = new Float32Array(this.entries.size);\n let i = 0;\n this.entries.forEach((value) => {\n vals[i++] = fn(value.value, value.row, value.col);\n });\n const dims = [this.nRows, this.nCols];\n return new SparseMatrix(this.getRows(), this.getCols(), vals, dims);\n }\n toArray() {\n const rows = utils.empty(this.nRows);\n const output = rows.map(() => {\n return utils.zeros(this.nCols);\n });\n this.entries.forEach((value) => {\n output[value.row][value.col] = value.value;\n });\n return output;\n }\n}\n/**\n * Transpose a sparse matrix\n */\nexport function transpose(matrix) {\n const oldRows = matrix.getRows();\n const oldCols = matrix.getCols();\n const oldVals = matrix.getValues();\n const matlen = oldCols.length;\n const cols = new Int32Array(matlen);\n const rows = new Int32Array(matlen);\n const vals = new Float32Array(matlen);\n cols.set(oldRows);\n rows.set(oldCols);\n vals.set(oldVals);\n const dims = [matrix.nCols, matrix.nRows];\n return new SparseMatrix(rows, cols, vals, dims);\n}\n/**\n * Construct a sparse identity matrix\n */\nexport function identity(size) {\n const [rows] = size;\n const matrix = new SparseMatrix([], [], [], size);\n for (let i = 0; i < rows; i++)\n matrix.set(i, i, 1);\n return matrix;\n}\n/**\n * Element-wise multiplication of two matrices\n */\nexport function pairwiseMultiply(a, b) {\n return elementWise(a, b, (x, y) => x * y);\n}\n/**\n * Element-wise addition of two matrices\n */\nexport function add(a, b) {\n return elementWise(a, b, (x, y) => x + y);\n}\n/**\n * Element-wise subtraction of two matrices\n */\nexport function subtract(a, b) {\n return elementWise(a, b, (x, y) => x - y);\n}\n/**\n * Element-wise maximum of two matrices\n */\nexport function maximum(a, b) {\n return elementWise(a, b, (x, y) => (x > y ? x : y));\n}\n/**\n * Scalar multiplication of two matrices\n */\nexport function multiplyScalar(a, scalar) {\n return a.map((value) => {\n return value * scalar;\n });\n}\n/**\n * Returns a new matrix with zero entries removed.\n */\nexport function eliminateZeros(m) {\n const zeroIndices = new Set();\n const values = m.getValues();\n const rows = m.getRows();\n const cols = m.getCols();\n for (let i = 0; i < values.length; i++) {\n if (values[i] === 0)\n zeroIndices.add(i);\n }\n const removeByZeroIndex = (_, index) => !zeroIndices.has(index);\n const nextValues = values.filter(removeByZeroIndex);\n const nextRows = rows.filter(removeByZeroIndex);\n const nextCols = cols.filter(removeByZeroIndex);\n return new SparseMatrix(nextRows, nextCols, nextValues, m.getDims());\n}\n/**\n * Normalization of a sparse matrix.\n */\nexport function normalize(m, normType = \"l2\" /* NormType.l2 */) {\n const normFn = normFns[normType];\n const colsByRow = new Map();\n m.forEach((_, row, col) => {\n const cols = colsByRow.get(row) || [];\n cols.push(col);\n colsByRow.set(row, cols);\n });\n const nextMatrix = new SparseMatrix([], [], [], m.getDims());\n for (const row of colsByRow.keys()) {\n const cols = colsByRow.get(row).sort();\n const vals = cols.map((col) => m.get(row, col));\n const norm = normFn(vals);\n for (let i = 0; i < norm.length; i++)\n nextMatrix.set(row, cols[i], norm[i]);\n }\n return nextMatrix;\n}\nconst normFns = {\n [\"max\" /* NormType.max */]: (xs) => {\n let max = -Infinity;\n for (let i = 0; i < xs.length; i++)\n max = xs[i] > max ? xs[i] : max;\n return xs.map((x) => x / max);\n },\n [\"l1\" /* NormType.l1 */]: (xs) => {\n let sum = 0;\n for (let i = 0; i < xs.length; i++)\n sum += xs[i];\n return xs.map((x) => x / sum);\n },\n [\"l2\" /* NormType.l2 */]: (xs) => {\n let sum = 0;\n for (let i = 0; i < xs.length; i++)\n sum += xs[i] ** 2;\n return xs.map((x) => Math.sqrt(x ** 2 / sum));\n },\n};\n/**\n * Helper function for element-wise operations.\n */\nfunction elementWise(a, b, op) {\n const visited = new Set();\n const rows = [];\n const cols = [];\n const vals = [];\n const operate = (row, col) => {\n rows.push(row);\n cols.push(col);\n const nextValue = op(a.get(row, col), b.get(row, col));\n vals.push(nextValue);\n };\n const valuesA = a.getValues();\n const rowsA = a.getRows();\n const colsA = a.getCols();\n for (let i = 0; i < valuesA.length; i++) {\n const row = rowsA[i];\n const col = colsA[i];\n const key = `${row}:${col}`;\n visited.add(key);\n operate(row, col);\n }\n const valuesB = b.getValues();\n const rowsB = b.getRows();\n const colsB = b.getCols();\n for (let i = 0; i < valuesB.length; i++) {\n const row = rowsB[i];\n const col = colsB[i];\n const key = `${row}:${col}`;\n if (visited.has(key))\n continue;\n operate(row, col);\n }\n const dims = [a.nRows, a.nCols];\n return new SparseMatrix(rows, cols, vals, dims);\n}\n/**\n * Helper function for getting data, indices, and inptr arrays from a sparse\n * matrix to follow csr matrix conventions. Super inefficient (and kind of\n * defeats the purpose of this convention) but a lot of the ported python tree\n * search logic depends on this data format.\n */\nexport function getCSR(x) {\n const entries = [];\n x.forEach((value, row, col) => {\n entries.push({ value, row, col });\n });\n entries.sort((a, b) => {\n if (a.row === b.row)\n return a.col - b.col;\n else\n return a.row - b.row;\n });\n const indices = [];\n const values = [];\n const indptr = [];\n let currentRow = -1;\n for (let i = 0; i < entries.length; i++) {\n const { row, col, value } = entries[i];\n if (row !== currentRow) {\n currentRow = row;\n indptr.push(i);\n }\n indices.push(col);\n values.push(value);\n }\n return { indices, values, indptr };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0cml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibWF0cml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFNdkIsWUFDRSxJQUEyQixFQUMzQixJQUEyQixFQUMzQixNQUErQixFQUMvQixJQUFjO1FBVFIsWUFBTyxHQUFHLElBQUksR0FBRyxFQUFpQixDQUFDO1FBRWxDLFVBQUssR0FBVyxDQUFDLENBQUM7UUFDbEIsVUFBSyxHQUFXLENBQUMsQ0FBQztRQVF6QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqRSxNQUFNLElBQUksS0FBSyxDQUNiLDREQUE0RCxDQUM3RCxDQUFDO1FBQ0osQ0FBQztRQUVELG9DQUFvQztRQUNwQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbkMsSUFBSSxD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TUFBTSxHQUFhLEVBQUUsQ0FBQztJQUM1QixNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFFNUIsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDcEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN4QyxNQUFNLEVBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsSUFBSSxHQUFHLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDdkIsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pCLENBQUM7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckIsQ0FBQztJQUVELE9BQU8sRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBQyxDQUFDO0FBQ25DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcblxudHlwZSBFbnRyeSA9IHsgdmFsdWU6IG51bWJlcjsgcm93OiBudW1iZXI7IGNvbDogbnVtYmVyIH07XG5cbi8qKlxuICogSW50ZXJuYWwgMi1kaW1lbnNpb25hbCBzcGFyc2UgbWF0cml4IGNsYXNzXG4gKi9cbmV4cG9ydCBjbGFzcyBTcGFyc2VNYXRyaXgge1xuICBwcml2YXRlIGVudHJpZXMgPSBuZXcgTWFwPHN0cmluZywgRW50cnk+KCk7XG5cbiAgcmVhZG9ubHkgblJvd3M6IG51bWJlciA9IDA7XG4gIHJlYWRvbmx5IG5Db2xzOiBudW1iZXIgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJvd3M6IG51bWJlcltdIHwgSW50MzJBcnJheSxcbiAgICBjb2xzOiBudW1iZXJbXSB8IEludDMyQXJyYXksXG4gICAgdmFsdWVzOiBudW1iZXJbXSB8IEZsb2F0MzJBcnJheSxcbiAgICBkaW1zOiBudW1iZXJbXVxuICApIHtcbiAgICBpZiAocm93cy5sZW5ndGggIT09IGNvbHMubGVuZ3RoIHx8IHJvd3MubGVuZ3RoICE9PSB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdyb3dzLCBjb2xzIGFuZCB2YWx1ZXMgYXJyYXlzIG11c3QgYWxsIGhhdmUgdGhlIHNhbWUgbGVuZ3RoJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBBc3NlcnQgdGhhdCBkaW1zIGFyZSBsZWdpdC5cbiAgICB0aGlzLm5Sb3dzID0gZGltc1swXTtcbiAgICB0aGlzLm5Db2xzID0gZGltc1sxXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgcm93ID0gcm93c1tpXTtcbiAgICAgIGNvbnN0IGNvbCA9IGNvbHNbaV07XG4gICAgICB0aGlzLmNoZWNrRGltcyhyb3csIGNvbCk7XG4gICAgICBjb25zdCBrZXkgPSB0aGlzLm1ha2VLZXkocm93LCBjb2wpO1xuICAgICAgdGhpcy5lbnRyaWVzLnNldChrZXksIHt2YWx1ZTogdmFsdWVzW2ldLCByb3csIGNvbH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWFrZUtleShyb3c6IG51bWJlciwgY29sOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtyb3d9OiR7Y29sfWA7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrRGltcyhyb3c6IG51bWJlciwgY29sOiBudW1iZXIpIHtcbiAgICBjb25zdCB3aXRoaW5Cb3VuZHMgPSByb3cgPCB0aGlzLm5Sb3dzICYmIGNvbCA8IHRoaXMubkNvbHM7XG4gICAgaWYgKCF3aXRoaW5Cb3VuZHMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3JvdyBhbmQvb3IgY29sIHNwZWNpZmllZCBvdXRzaWRlIG9mIG1hdHJpeCBkaW1lbnNpb25zJyk7XG4gIH1cblxuICBzZXQocm93OiBudW1iZXIsIGNvbDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5jaGVja0RpbXMocm93LCBjb2wpO1xuICAgIGNvbnN0IGtleSA9IHRoaXMubWFrZUtleShyb3csIGNvbCk7XG4gICAgaWYgKCF0aGlzLmVudHJpZXMuaGFzKGtleSkpXG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwge3ZhbHVlLCByb3csIGNvbH0pO1xuICAgIGVsc2VcbiAgICAgIHRoaXMuZW50cmllcy5nZXQoa2V5KSEudmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldChyb3c6IG51bWJlciwgY29sOiBudW1iZXIsIGRlZmF1bHRWYWx1ZSA9IDApIHtcbiAgICAvL3RoaXMuY2hlY2tEaW1zKHJvdywgY29sKTtcbiAgICBjb25zdCBrZXkgPSB0aGlzLm1ha2VLZXkocm93LCBjb2wpO1xuICAgIGlmICh0aGlzLmVudHJpZXMuaGFzKGtleSkpXG4gICAgICByZXR1cm4gdGhpcy5lbnRyaWVzLmdldChrZXkpIS52YWx1ZTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICB9XG5cbiAgZ2V0QWxsKG9yZGVyZWQgPSB0cnVlKTogeyB2YWx1ZTogbnVtYmVyOyByb3c6IG51bWJlcjsgY29sOiBudW1iZXIgfVtdIHtcbiAgICBjb25zdCByb3dDb2xWYWx1ZXM6IEVudHJ5W10gPSBuZXcgQXJyYXkodGhpcy5lbnRyaWVzLnNpemUpLmZpbGwobnVsbCk7XG4gICAgbGV0IGkgPSAwO1xuICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgcm93Q29sVmFsdWVzW2krK10gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICBpZiAob3JkZXJlZCkge1xuICAgICAgLy8gT3JkZXJpbmcgdGhlIHJlc3VsdCBpc24ndCByZXF1aXJlZCBmb3IgcHJvY2Vzc2luZyBidXQgaXQgZG9lcyBtYWtlIGl0IGVhc2llciB0byB3cml0ZSB0ZXN0c1xuICAgICAgcm93Q29sVmFsdWVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgaWYgKGEucm93ID09PSBiLnJvdylcbiAgICAgICAgICByZXR1cm4gYS5jb2wgLSBiLmNvbDtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHJldHVybiBhLnJvdyAtIGIucm93O1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByb3dDb2xWYWx1ZXM7XG4gIH1cblxuICBnZXREaW1zKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gW3RoaXMublJvd3MsIHRoaXMubkNvbHNdO1xuICB9XG5cbiAgZ2V0Um93cygpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5lbnRyaWVzLCAoW19rZXksIHZhbHVlXSkgPT4gdmFsdWUucm93KTtcbiAgICAvLyByZXR1cm4gdGhpcy5yb3dzIGFzIHVua25vd24gYXMgbnVtYmVyW107XG4gIH1cblxuICBnZXRDb2xzKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMsIChbX2tleSwgdmFsdWVdKSA9PiB2YWx1ZS5jb2wpO1xuICAgIC8vIHJldHVybiB0aGlzLmNvbHMgYXMgdW5rbm93biBhcyBudW1iZXJbXTtcbiAgfVxuXG4gIGdldFZhbHVlcygpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5lbnRyaWVzLCAoW19rZXksIHZhbHVlXSkgPT4gdmFsdWUudmFsdWUpO1xuICAvL3JldHVybiB0aGlzLnZhbHVlcyBhcyB1bmtub3duIGFzIG51bWJlcltdO1xuICB9XG5cbiAgZm9yRWFjaChmbjogKHZhbHVlOiBudW1iZXIsIHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKCh2YWx1ZSkgPT4gZm4odmFsdWUudmFsdWUsIHZhbHVlLnJvdywgdmFsdWUuY29sKSk7XG4gIH1cblxuICBtYXAoZm46ICh2YWx1ZTogbnVtYmVyLCByb3c6IG51bWJlciwgY29sOiBudW1iZXIpID0+IG51bWJlcik6IFNwYXJzZU1hdHJpeCB7XG4gICAgY29uc3QgdmFscyA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5lbnRyaWVzLnNpemUpO1xuICAgIGxldCBpID0gMDtcbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgIHZhbHNbaSsrXSA9IGZuKHZhbHVlLnZhbHVlLCB2YWx1ZS5yb3csIHZhbHVlLmNvbCk7XG4gICAgfSk7XG4gICAgY29uc3QgZGltcyA9IFt0aGlzLm5Sb3dzLCB0aGlzLm5Db2xzXTtcbiAgICByZXR1cm4gbmV3IFNwYXJzZU1hdHJpeCh0aGlzLmdldFJvd3MoKSwgdGhpcy5nZXRDb2xzKCksIHZhbHMgYXMgdW5rbm93biBhcyBudW1iZXJbXSwgZGltcyk7XG4gIH1cblxuICB0b0FycmF5KCkge1xuICAgIGNvbnN0IHJvd3M6IHVuZGVmaW5lZFtdID0gdXRpbHMuZW1wdHkodGhpcy5uUm93cyk7XG4gICAgY29uc3Qgb3V0cHV0ID0gcm93cy5tYXAoKCkgPT4ge1xuICAgICAgcmV0dXJuIHV0aWxzLnplcm9zKHRoaXMubkNvbHMpO1xuICAgIH0pO1xuICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgb3V0cHV0W3ZhbHVlLnJvd11bdmFsdWUuY29sXSA9IHZhbHVlLnZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn1cblxuLyoqXG4gKiBUcmFuc3Bvc2UgYSBzcGFyc2UgbWF0cml4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2UobWF0cml4OiBTcGFyc2VNYXRyaXgpOiBTcGFyc2VNYXRyaXgge1xuICBjb25zdCBvbGRSb3dzID0gbWF0cml4LmdldFJvd3MoKTtcbiAgY29uc3Qgb2xkQ29scyA9IG1hdHJpeC5nZXRDb2xzKCk7XG4gIGNvbnN0IG9sZFZhbHMgPSBtYXRyaXguZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IG1hdGxlbiA9IG9sZENvbHMubGVuZ3RoO1xuICBjb25zdCBjb2xzID0gbmV3IEludDMyQXJyYXkobWF0bGVuKTtcbiAgY29uc3Qgcm93cyA9IG5ldyBJbnQzMkFycmF5KG1hdGxlbik7XG4gIGNvbnN0IHZhbHMgPSBuZXcgRmxvYXQzMkFycmF5KG1hdGxlbik7XG5cbiAgY29scy5zZXQob2xkUm93cyk7XG4gIHJvd3Muc2V0KG9sZENvbHMpO1xuICB2YWxzLnNldChvbGRWYWxzKTtcbiAgY29uc3QgZGltcyA9IFttYXRyaXgubkNvbHMsIG1hdHJpeC5uUm93c107XG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIGRpbXMpO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHNwYXJzZSBpZGVudGl0eSBtYXRyaXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KHNpemU6IG51bWJlcltdKTogU3BhcnNlTWF0cml4IHtcbiAgY29uc3QgW3Jvd3NdID0gc2l6ZTtcbiAgY29uc3QgbWF0cml4ID0gbmV3IFNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBzaXplKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspXG4gICAgbWF0cml4LnNldChpLCBpLCAxKTtcblxuICByZXR1cm4gbWF0cml4O1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBtdWx0aXBsaWNhdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhaXJ3aXNlTXVsdGlwbHkoXG4gIGE6IFNwYXJzZU1hdHJpeCxcbiAgYjogU3BhcnNlTWF0cml4XG4pOiBTcGFyc2VNYXRyaXgge1xuICByZXR1cm4gZWxlbWVudFdpc2UoYSwgYiwgKHgsIHkpID0+IHggKiB5KTtcbn1cblxuLyoqXG4gKiBFbGVtZW50LXdpc2UgYWRkaXRpb24gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGQoYTogU3BhcnNlTWF0cml4LCBiOiBTcGFyc2VNYXRyaXgpOiBTcGFyc2VNYXRyaXgge1xuICByZXR1cm4gZWxlbWVudFdpc2UoYSwgYiwgKHgsIHkpID0+IHggKyB5KTtcbn1cblxuLyoqXG4gKiBFbGVtZW50LXdpc2Ugc3VidHJhY3Rpb24gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdWJ0cmFjdChhOiBTcGFyc2VNYXRyaXgsIGI6IFNwYXJzZU1hdHJpeCk6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4geCAtIHkpO1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBtYXhpbXVtIG9mIHR3byBtYXRyaWNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWF4aW11bShhOiBTcGFyc2VNYXRyaXgsIGI6IFNwYXJzZU1hdHJpeCk6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4gKHggPiB5ID8geCA6IHkpKTtcbn1cblxuLyoqXG4gKiBTY2FsYXIgbXVsdGlwbGljYXRpb24gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtdWx0aXBseVNjYWxhcihhOiBTcGFyc2VNYXRyaXgsIHNjYWxhcjogbnVtYmVyKTogU3BhcnNlTWF0cml4IHtcbiAgcmV0dXJuIGEubWFwKCh2YWx1ZTogbnVtYmVyKSA9PiB7XG4gICAgcmV0dXJuIHZhbHVlICogc2NhbGFyO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IG1hdHJpeCB3aXRoIHplcm8gZW50cmllcyByZW1vdmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZWxpbWluYXRlWmVyb3MobTogU3BhcnNlTWF0cml4KSB7XG4gIGNvbnN0IHplcm9JbmRpY2VzID0gbmV3IFNldCgpO1xuICBjb25zdCB2YWx1ZXMgPSBtLmdldFZhbHVlcygpO1xuICBjb25zdCByb3dzID0gbS5nZXRSb3dzKCk7XG4gIGNvbnN0IGNvbHMgPSBtLmdldENvbHMoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodmFsdWVzW2ldID09PSAwKVxuICAgICAgemVyb0luZGljZXMuYWRkKGkpO1xuICB9XG4gIGNvbnN0IHJlbW92ZUJ5WmVyb0luZGV4ID0gKF86IGFueSwgaW5kZXg6IG51bWJlcikgPT4gIXplcm9JbmRpY2VzLmhhcyhpbmRleCk7XG4gIGNvbnN0IG5leHRWYWx1ZXMgPSB2YWx1ZXMuZmlsdGVyKHJlbW92ZUJ5WmVyb0luZGV4KTtcbiAgY29uc3QgbmV4dFJvd3MgPSByb3dzLmZpbHRlcihyZW1vdmVCeVplcm9JbmRleCk7XG4gIGNvbnN0IG5leHRDb2xzID0gY29scy5maWx0ZXIocmVtb3ZlQnlaZXJvSW5kZXgpO1xuXG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KG5leHRSb3dzLCBuZXh0Q29scywgbmV4dFZhbHVlcywgbS5nZXREaW1zKCkpO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6YXRpb24gb2YgYSBzcGFyc2UgbWF0cml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKG06IFNwYXJzZU1hdHJpeCwgbm9ybVR5cGUgPSBOb3JtVHlwZS5sMikge1xuICBjb25zdCBub3JtRm4gPSBub3JtRm5zW25vcm1UeXBlXTtcblxuICBjb25zdCBjb2xzQnlSb3cgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyW10+KCk7XG4gIG0uZm9yRWFjaCgoXywgcm93LCBjb2wpID0+IHtcbiAgICBjb25zdCBjb2xzID0gY29sc0J5Um93LmdldChyb3cpIHx8IFtdO1xuICAgIGNvbHMucHVzaChjb2wpO1xuICAgIGNvbHNCeVJvdy5zZXQocm93LCBjb2xzKTtcbiAgfSk7XG5cbiAgY29uc3QgbmV4dE1hdHJpeCA9IG5ldyBTcGFyc2VNYXRyaXgoW10sIFtdLCBbXSwgbS5nZXREaW1zKCkpO1xuXG4gIGZvciAoY29uc3Qgcm93IG9mIGNvbHNCeVJvdy5rZXlzKCkpIHtcbiAgICBjb25zdCBjb2xzID0gY29sc0J5Um93LmdldChyb3cpIS5zb3J0KCk7XG5cbiAgICBjb25zdCB2YWxzID0gY29scy5tYXAoKGNvbCkgPT4gbS5nZXQocm93LCBjb2wpKTtcbiAgICBjb25zdCBub3JtID0gbm9ybUZuKHZhbHMpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9ybS5sZW5ndGg7IGkrKylcbiAgICAgIG5leHRNYXRyaXguc2V0KHJvdywgY29sc1tpXSwgbm9ybVtpXSk7XG4gIH1cblxuICByZXR1cm4gbmV4dE1hdHJpeDtcbn1cblxuLyoqXG4gKiBWZWN0b3Igbm9ybWFsaXphdGlvbiBmdW5jdGlvbnNcbiAqL1xudHlwZSBOb3JtRm5zID0geyBba2V5IGluIE5vcm1UeXBlXTogKHY6IG51bWJlcltdKSA9PiBudW1iZXJbXSB9O1xuY29uc3Qgbm9ybUZuczogTm9ybUZucyA9IHtcbiAgW05vcm1UeXBlLm1heF06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgbWF4ID0gLUluZmluaXR5O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspXG4gICAgICBtYXggPSB4c1tpXSA+IG1heCA/IHhzW2ldIDogbWF4O1xuXG4gICAgcmV0dXJuIHhzLm1hcCgoeCkgPT4geCAvIG1heCk7XG4gIH0sXG4gIFtOb3JtVHlwZS5sMV06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKVxuICAgICAgc3VtICs9IHhzW2ldO1xuXG4gICAgcmV0dXJuIHhzLm1hcCgoeCkgPT4geCAvIHN1bSk7XG4gIH0sXG4gIFtOb3JtVHlwZS5sMl06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKVxuICAgICAgc3VtICs9IHhzW2ldICoqIDI7XG5cbiAgICByZXR1cm4geHMubWFwKCh4KSA9PiBNYXRoLnNxcnQoeCAqKiAyIC8gc3VtKSk7XG4gIH0sXG59O1xuXG5leHBvcnQgY29uc3QgZW51bSBOb3JtVHlwZSB7XG4gIG1heCA9ICdtYXgnLFxuICBsMSA9ICdsMScsXG4gIGwyID0gJ2wyJyxcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGVsZW1lbnQtd2lzZSBvcGVyYXRpb25zLlxuICovXG5mdW5jdGlvbiBlbGVtZW50V2lzZShcbiAgYTogU3BhcnNlTWF0cml4LFxuICBiOiBTcGFyc2VNYXRyaXgsXG4gIG9wOiAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IG51bWJlclxuKTogU3BhcnNlTWF0cml4IHtcbiAgY29uc3QgdmlzaXRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCByb3dzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBjb2xzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCB2YWxzOiBudW1iZXJbXSA9IFtdO1xuXG4gIGNvbnN0IG9wZXJhdGUgPSAocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKSA9PiB7XG4gICAgcm93cy5wdXNoKHJvdyk7XG4gICAgY29scy5wdXNoKGNvbCk7XG4gICAgY29uc3QgbmV4dFZhbHVlID0gb3AoYS5nZXQocm93LCBjb2wpLCBiLmdldChyb3csIGNvbCkpO1xuICAgIHZhbHMucHVzaChuZXh0VmFsdWUpO1xuICB9O1xuICBjb25zdCB2YWx1ZXNBID0gYS5nZXRWYWx1ZXMoKTtcbiAgY29uc3Qgcm93c0EgPSBhLmdldFJvd3MoKTtcbiAgY29uc3QgY29sc0EgPSBhLmdldENvbHMoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXNBLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgcm93ID0gcm93c0FbaV07XG4gICAgY29uc3QgY29sID0gY29sc0FbaV07XG4gICAgY29uc3Qga2V5ID0gYCR7cm93fToke2NvbH1gO1xuICAgIHZpc2l0ZWQuYWRkKGtleSk7XG4gICAgb3BlcmF0ZShyb3csIGNvbCk7XG4gIH1cblxuICBjb25zdCB2YWx1ZXNCID0gYi5nZXRWYWx1ZXMoKTtcbiAgY29uc3Qgcm93c0IgPSBiLmdldFJvd3MoKTtcbiAgY29uc3QgY29sc0IgPSBiLmdldENvbHMoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXNCLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgcm93ID0gcm93c0JbaV07XG4gICAgY29uc3QgY29sID0gY29sc0JbaV07XG4gICAgY29uc3Qga2V5ID0gYCR7cm93fToke2NvbH1gO1xuICAgIGlmICh2aXNpdGVkLmhhcyhrZXkpKSBjb250aW51ZTtcbiAgICBvcGVyYXRlKHJvdywgY29sKTtcbiAgfVxuXG4gIGNvbnN0IGRpbXMgPSBbYS5uUm93cywgYS5uQ29sc107XG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIGRpbXMpO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiBmb3IgZ2V0dGluZyBkYXRhLCBpbmRpY2VzLCBhbmQgaW5wdHIgYXJyYXlzIGZyb20gYSBzcGFyc2VcbiAqIG1hdHJpeCB0byBmb2xsb3cgY3NyIG1hdHJpeCBjb252ZW50aW9ucy4gU3VwZXIgaW5lZmZpY2llbnQgKGFuZCBraW5kIG9mXG4gKiBkZWZlYXRzIHRoZSBwdXJwb3NlIG9mIHRoaXMgY29udmVudGlvbikgYnV0IGEgbG90IG9mIHRoZSBwb3J0ZWQgcHl0aG9uIHRyZWVcbiAqIHNlYXJjaCBsb2dpYyBkZXBlbmRzIG9uIHRoaXMgZGF0YSBmb3JtYXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDU1IoeDogU3BhcnNlTWF0cml4KSB7XG4gIGNvbnN0IGVudHJpZXM6IEVudHJ5W10gPSBbXTtcblxuICB4LmZvckVhY2goKHZhbHVlLCByb3csIGNvbCkgPT4ge1xuICAgIGVudHJpZXMucHVzaCh7dmFsdWUsIHJvdywgY29sfSk7XG4gIH0pO1xuXG4gIGVudHJpZXMuc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhLnJvdyA9PT0gYi5yb3cpXG4gICAgICByZXR1cm4gYS5jb2wgLSBiLmNvbDtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gYS5yb3cgLSBiLnJvdztcbiAgfSk7XG5cbiAgY29uc3QgaW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgdmFsdWVzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBpbmRwdHI6IG51bWJlcltdID0gW107XG5cbiAgbGV0IGN1cnJlbnRSb3cgPSAtMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbnRyaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qge3JvdywgY29sLCB2YWx1ZX0gPSBlbnRyaWVzW2ldO1xuICAgIGlmIChyb3cgIT09IGN1cnJlbnRSb3cpIHtcbiAgICAgIGN1cnJlbnRSb3cgPSByb3c7XG4gICAgICBpbmRwdHIucHVzaChpKTtcbiAgICB9XG4gICAgaW5kaWNlcy5wdXNoKGNvbCk7XG4gICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHtpbmRpY2VzLCB2YWx1ZXMsIGluZHB0cn07XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as utils from './utils';\nexport class FlatTree {\n constructor(hyperplanes, offsets, children, indices) {\n this.hyperplanes = hyperplanes;\n this.offsets = offsets;\n this.children = children;\n this.indices = indices;\n }\n}\n/**\n * Build a random projection forest with ``nTrees``.\n */\nexport function makeForest(data, nNeighbors, nTrees, random) {\n const leafSize = Math.max(10, nNeighbors);\n const trees = utils\n .range(nTrees)\n .map((_, i) => makeTree(data, leafSize, i, random));\n const forest = trees.map((tree) => flattenTree(tree, leafSize));\n return forest;\n}\n/**\n * Construct a random projection tree based on ``data`` with leaves\n * of size at most ``leafSize``\n */\nfunction makeTree(data, leafSize = 30, n, random) {\n const indices = utils.range(data.length);\n const tree = makeEuclideanTree(data, indices, leafSize, n, random);\n return tree;\n}\nfunction makeEuclideanTree(data, indices, leafSize = 30, q, random) {\n if (indices.length > leafSize) {\n const splitResults = euclideanRandomProjectionSplit(data, indices, random);\n const { indicesLeft, indicesRight, hyperplane, offset } = splitResults;\n const leftChild = makeEuclideanTree(data, indicesLeft, leafSize, q + 1, random);\n const rightChild = makeEuclideanTree(data, indicesRight, leafSize, q + 1, random);\n const node = { leftChild, rightChild, isLeaf: false, hyperplane, offset };\n return node;\n }\n else {\n const node = { indices, isLeaf: true };\n return node;\n }\n}\n/**\n * Given a set of ``indices`` for data points from ``data``, create\n * a random hyperplane to split the data, returning two arrays indices\n * that fall on either side of the hyperplane. This is the basis for a\n * random projection tree, which simply uses this splitting recursively.\n * This particular split uses euclidean distance to determine the hyperplane\n * and which side each data sample falls on.\n */\nfunction euclideanRandomProjectionSplit(data, indices, random) {\n //const dim = 1;\n // Select two random points, set the hyperplane between them\n const leftIndex = utils.tauRandInt(indices.length, random);\n let rightIndex = utils.tauRandInt(indices.length, random);\n rightIndex += leftIndex === rightIndex ? 1 : 0;\n rightIndex = rightIndex % indices.length;\n const left = indices[leftIndex];\n const right = indices[rightIndex];\n // Compute the normal vector to the hyperplane (the vector between the two\n // points) and the offset from the origin\n let hyperplaneOffset = 0;\n let hyperplaneVector = 0;\n hyperplaneVector = data[left] - data[right];\n hyperplaneOffset -=\n (hyperplaneVector * (data[left] + data[right])) / 2.0;\n // For each point compute the margin (project into normal vector)\n // If we are on lower side of the hyperplane put in one pile, otherwise\n // put it in the other pile (if we hit hyperplane on the nose, flip a coin)\n let nLeft = 0;\n let nRight = 0;\n const side = utils.zeros(indices.length);\n for (let i = 0; i < indices.length; i++) {\n let margin = hyperplaneOffset;\n margin += hyperplaneVector * data[indices[i]];\n if (margin === 0) {\n side[i] = utils.tauRandInt(2, random);\n if (side[i] === 0)\n nLeft += 1;\n else\n nRight += 1;\n }\n else if (margin > 0) {\n side[i] = 0;\n nLeft += 1;\n }\n else {\n side[i] = 1;\n nRight += 1;\n }\n }\n // Now that we have the counts, allocate arrays\n const indicesLeft = utils.zeros(nLeft);\n const indicesRight = utils.zeros(nRight);\n // Populate the arrays with indices according to which side they fell on\n nLeft = 0;\n nRight = 0;\n for (let i = 0; i < side.length; i++) {\n if (side[i] === 0) {\n indicesLeft[nLeft] = indices[i];\n nLeft += 1;\n }\n else {\n indicesRight[nRight] = indices[i];\n nRight += 1;\n }\n }\n return {\n indicesLeft,\n indicesRight,\n hyperplane: hyperplaneVector,\n offset: hyperplaneOffset,\n };\n}\nfunction flattenTree(tree, leafSize) {\n const nNodes = numNodes(tree);\n const nLeaves = numLeaves(tree);\n // TODO: Verify that sparse code is not relevant...\n const hyperplanes = utils\n .range(nNodes)\n .map(() => tree.hyperplane ? 1 : 0);\n const offsets = utils.zeros(nNodes);\n const children = utils.range(nNodes).map(() => [-1, -1]);\n const indices = utils\n .range(nLeaves)\n .map(() => utils.range(leafSize).map(() => -1));\n recursiveFlatten(tree, hyperplanes, offsets, children, indices, 0, 0);\n return new FlatTree(hyperplanes, offsets, children, indices);\n}\nfunction recursiveFlatten(tree, hyperplanes, offsets, children, indices, nodeNum, leafNum) {\n if (tree.isLeaf) {\n children[nodeNum][0] = -leafNum;\n // TODO: Triple check this operation corresponds to\n // indices[leafNum : tree.indices.shape[0]] = tree.indices\n indices[leafNum].splice(0, tree.indices.length, ...tree.indices);\n leafNum += 1;\n return { nodeNum, leafNum };\n }\n else {\n hyperplanes[nodeNum] = tree.hyperplane;\n offsets[nodeNum] = tree.offset;\n children[nodeNum][0] = nodeNum + 1;\n const oldNodeNum = nodeNum;\n let res = recursiveFlatten(tree.leftChild, hyperplanes, offsets, children, indices, nodeNum + 1, leafNum);\n nodeNum = res.nodeNum;\n leafNum = res.leafNum;\n children[oldNodeNum][1] = nodeNum + 1;\n res = recursiveFlatten(tree.rightChild, hyperplanes, offsets, children, indices, nodeNum + 1, leafNum);\n return { nodeNum: res.nodeNum, leafNum: res.leafNum };\n }\n}\nfunction numNodes(tree) {\n if (tree.isLeaf)\n return 1;\n else\n return 1 + numNodes(tree.leftChild) + numNodes(tree.rightChild);\n}\nfunction numLeaves(tree) {\n if (tree.isLeaf)\n return 1;\n else\n return numLeaves(tree.leftChild) + numLeaves(tree.rightChild);\n}\n/**\n * Generate an array of sets of candidate nearest neighbors by\n * constructing a random projection forest and taking the leaves of all the\n * trees. Any given tree has leaves that are a set of potential nearest\n * neighbors. Given enough trees the set of all such leaves gives a good\n * likelihood of getting a good set of nearest neighbors in composite. Since\n * such a random projection forest is inexpensive to compute, this can be a\n * useful means of seeding other nearest neighbor algorithms.\n */\nexport function makeLeafArray(rpForest) {\n if (rpForest.length > 0) {\n const output = [];\n for (const tree of rpForest)\n output.push(...tree.indices);\n return output;\n }\n else {\n return [[-1]];\n }\n}\n/**\n * Selects the side of the tree to search during flat tree search.\n */\nfunction selectSide(hyperplane, offset, point, random) {\n let margin = offset;\n margin += hyperplane * point;\n if (margin === 0) {\n const side = utils.tauRandInt(2, random);\n return side;\n }\n else if (margin > 0) {\n return 0;\n }\n else {\n return 1;\n }\n}\n/**\n * Searches a flattened rp-tree for a point.\n */\nexport function searchFlatTree(point, tree, random) {\n let node = 0;\n while (tree.children[node][0] > 0) {\n const side = selectSide(tree.hyperplanes[node], tree.offsets[node], point, random);\n if (side === 0)\n node = tree.children[node][0];\n else\n node = tree.children[node][1];\n }\n const index = -1 * tree.children[node][0];\n return tree.indices[index];\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBZWpDLE1BQU0sT0FBTyxRQUFRO0lBQ25CLFlBQ1MsV0FBcUIsRUFDckIsT0FBaUIsRUFDakIsUUFBb0IsRUFDcEIsT0FBbUI7UUFIbkIsZ0JBQVcsR0FBWCxXQUFXLENBQVU7UUFDckIsWUFBTyxHQUFQLE9BQU8sQ0FBVTtRQUNqQixhQUFRLEdBQVIsUUFBUSxDQUFZO1FBQ3BCLFlBQU8sR0FBUCxPQUFPLENBQVk7SUFDekIsQ0FBQztDQUNMO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUN4QixJQUFZLEVBQ1osVUFBa0IsRUFDbEIsTUFBYyxFQUNkLE1BQWdCO0lBRWhCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRTFDLE1BQU0sS0FBSyxHQUFHLEtBQUs7U0FDaEIsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUNiLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUVoRSxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxRQUFRLENBQ2YsSUFBWSxFQUNaLFFBQVEsR0FBRyxFQUFF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SSxJQUFJLEtBQUssQ0FBQztZQUNaLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOztZQUU5QixJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbi8qKlxuICogVGhpcyBpcyBhIEphdmFTY3JpcHQgcmVpbXBsZW1lbnRhdGlvbiBvZiBVTUFQIChvcmlnaW5hbCBsaWNlbnNlIGJlbG93KSwgZnJvbVxuICogdGhlIHB5dGhvbiBpbXBsZW1lbnRhdGlvbiBmb3VuZCBhdCBodHRwczovL2dpdGh1Yi5jb20vbG1jaW5uZXMvdW1hcC5cbiAqXG4gKiBAYXV0aG9yIGFuZHljb2VuZW5AZ29vZ2xlLmNvbSAoQW5keSBDb2VuZW4pXG4gKi9cblxuLyoqXG4gKiBAbGljZW5zZVxuICogQlNEIDMtQ2xhdXNlIExpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTcsIExlbGFuZCBNY0lubmVzXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4gKlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiAqICAgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKlxuICogKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAqICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKlxuICogKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBjb3B5cmlnaHQgaG9sZGVyIG5vciB0aGUgbmFtZXMgb2YgaXRzXG4gKiAgIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tXG4gKiAgIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRVxuICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUxcbiAqIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SXG4gKiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUlxuICogQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSxcbiAqIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFXG4gKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHtSYW5kb21GbiwgVmVjdG9yfSBmcm9tICcuL3VtYXAnO1xuXG4vKipcbiAqIFRyZWUgZnVuY3Rpb25hbGl0eSBmb3IgYXBwcm94aW1hdGluZyBuZWFyZXN0IG5laWdoYm9yc1xuICovXG5pbnRlcmZhY2UgUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlIHtcbiAgaXNMZWFmOiBib29sZWFuO1xuICBpbmRpY2VzPzogbnVtYmVyW107XG4gIGxlZnRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgcmlnaHRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgaHlwZXJwbGFuZT86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgRmxhdFRyZWUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgaHlwZXJwbGFuZXM6IG51bWJlcltdLFxuICAgIHB1YmxpYyBvZmZzZXRzOiBudW1iZXJbXSxcbiAgICBwdWJsaWMgY2hpbGRyZW46IG51bWJlcltdW10sXG4gICAgcHVibGljIGluZGljZXM6IG51bWJlcltdW11cbiAgKSB7fVxufVxuXG4vKipcbiAqIEJ1aWxkIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IHdpdGggYGBuVHJlZXNgYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VGb3Jlc3QoXG4gIGRhdGE6IFZlY3RvcixcbiAgbk5laWdoYm9yczogbnVtYmVyLFxuICBuVHJlZXM6IG51bWJlcixcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IGxlYWZTaXplID0gTWF0aC5tYXgoMTAsIG5OZWlnaGJvcnMpO1xuXG4gIGNvbnN0IHRyZWVzID0gdXRpbHNcbiAgICAucmFuZ2UoblRyZWVzKVxuICAgIC5tYXAoKF8sIGkpID0+IG1ha2VUcmVlKGRhdGEsIGxlYWZTaXplLCBpLCByYW5kb20pKTtcbiAgY29uc3QgZm9yZXN0ID0gdHJlZXMubWFwKCh0cmVlKSA9PiBmbGF0dGVuVHJlZSh0cmVlLCBsZWFmU2l6ZSkpO1xuXG4gIHJldHVybiBmb3Jlc3Q7XG59XG5cbi8qKlxuICogQ29uc3RydWN0IGEgcmFuZG9tIHByb2plY3Rpb24gdHJlZSBiYXNlZCBvbiBgYGRhdGFgYCB3aXRoIGxlYXZlc1xuICogb2Ygc2l6ZSBhdCBtb3N0IGBgbGVhZlNpemVgYFxuICovXG5mdW5jdGlvbiBtYWtlVHJlZShcbiAgZGF0YTogVmVjdG9yLFxuICBsZWFmU2l6ZSA9IDMwLFxuICBuOiBudW1iZXIsXG4gIHJhbmRvbTogUmFuZG9tRm5cbik6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSB7XG4gIGNvbnN0IGluZGljZXMgPSB1dGlscy5yYW5nZShkYXRhLmxlbmd0aCk7XG4gIGNvbnN0IHRyZWUgPSBtYWtlRXVjbGlkZWFuVHJlZShkYXRhLCBpbmRpY2VzLCBsZWFmU2l6ZSwgbiwgcmFuZG9tKTtcbiAgcmV0dXJuIHRyZWU7XG59XG5cbmZ1bmN0aW9uIG1ha2VFdWNsaWRlYW5UcmVlKFxuICBkYXRhOiBWZWN0b3IsXG4gIGluZGljZXM6IG51bWJlcltdLFxuICBsZWFmU2l6ZSA9IDMwLFxuICBxOiBudW1iZXIsXG4gIHJhbmRvbTogUmFuZG9tRm5cbik6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSB7XG4gIGlmIChpbmRpY2VzLmxlbmd0aCA+IGxlYWZTaXplKSB7XG4gICAgY29uc3Qgc3BsaXRSZXN1bHRzID0gZXVjbGlkZWFuUmFuZG9tUHJvamVjdGlvblNwbGl0KGRhdGEsIGluZGljZXMsIHJhbmRvbSk7XG4gICAgY29uc3Qge2luZGljZXNMZWZ0LCBpbmRpY2VzUmlnaHQsIGh5cGVycGxhbmUsIG9mZnNldH0gPSBzcGxpdFJlc3VsdHM7XG5cbiAgICBjb25zdCBsZWZ0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzTGVmdCxcbiAgICAgIGxlYWZTaXplLFxuICAgICAgcSArIDEsXG4gICAgICByYW5kb21cbiAgICApO1xuICAgIGNvbnN0IHJpZ2h0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzUmlnaHQsXG4gICAgICBsZWFmU2l6ZSxcbiAgICAgIHEgKyAxLFxuICAgICAgcmFuZG9tXG4gICAgKTtcblxuICAgIGNvbnN0IG5vZGUgPSB7bGVmdENoaWxkLCByaWdodENoaWxkLCBpc0xlYWY6IGZhbHNlLCBoeXBlcnBsYW5lLCBvZmZzZXR9O1xuICAgIHJldHVybiBub2RlO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IG5vZGUgPSB7aW5kaWNlcywgaXNMZWFmOiB0cnVlfTtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxufVxuXG4vKipcbiAqIEdpdmVuIGEgc2V0IG9mIGBgaW5kaWNlc2BgIGZvciBkYXRhIHBvaW50cyBmcm9tIGBgZGF0YWBgLCBjcmVhdGVcbiAqIGEgcmFuZG9tIGh5cGVycGxhbmUgdG8gc3BsaXQgdGhlIGRhdGEsIHJldHVybmluZyB0d28gYXJyYXlzIGluZGljZXNcbiAqIHRoYXQgZmFsbCBvbiBlaXRoZXIgc2lkZSBvZiB0aGUgaHlwZXJwbGFuZS4gVGhpcyBpcyB0aGUgYmFzaXMgZm9yIGFcbiAqIHJhbmRvbSBwcm9qZWN0aW9uIHRyZWUsIHdoaWNoIHNpbXBseSB1c2VzIHRoaXMgc3BsaXR0aW5nIHJlY3Vyc2l2ZWx5LlxuICogVGhpcyBwYXJ0aWN1bGFyIHNwbGl0IHVzZXMgZXVjbGlkZWFuIGRpc3RhbmNlIHRvIGRldGVybWluZSB0aGUgaHlwZXJwbGFuZVxuICogYW5kIHdoaWNoIHNpZGUgZWFjaCBkYXRhIHNhbXBsZSBmYWxscyBvbi5cbiAqL1xuZnVuY3Rpb24gZXVjbGlkZWFuUmFuZG9tUHJvamVjdGlvblNwbGl0KFxuICBkYXRhOiBWZWN0b3IsXG4gIGluZGljZXM6IG51bWJlcltdLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgLy9jb25zdCBkaW0gPSAxO1xuXG4gIC8vIFNlbGVjdCB0d28gcmFuZG9tIHBvaW50cywgc2V0IHRoZSBoeXBlcnBsYW5lIGJldHdlZW4gdGhlbVxuICBjb25zdCBsZWZ0SW5kZXggPSB1dGlscy50YXVSYW5kSW50KGluZGljZXMubGVuZ3RoLCByYW5kb20pO1xuICBsZXQgcmlnaHRJbmRleCA9IHV0aWxzLnRhdVJhbmRJbnQoaW5kaWNlcy5sZW5ndGgsIHJhbmRvbSk7XG4gIHJpZ2h0SW5kZXggKz0gbGVmdEluZGV4ID09PSByaWdodEluZGV4ID8gMSA6IDA7XG4gIHJpZ2h0SW5kZXggPSByaWdodEluZGV4ICUgaW5kaWNlcy5sZW5ndGg7XG4gIGNvbnN0IGxlZnQgPSBpbmRpY2VzW2xlZnRJbmRleF07XG4gIGNvbnN0IHJpZ2h0ID0gaW5kaWNlc1tyaWdodEluZGV4XTtcblxuICAvLyBDb21wdXRlIHRoZSBub3JtYWwgdmVjdG9yIHRvIHRoZSBoeXBlcnBsYW5lICh0aGUgdmVjdG9yIGJldHdlZW4gdGhlIHR3b1xuICAvLyBwb2ludHMpIGFuZCB0aGUgb2Zmc2V0IGZyb20gdGhlIG9yaWdpblxuICBsZXQgaHlwZXJwbGFuZU9mZnNldCA9IDA7XG4gIGxldCBoeXBlcnBsYW5lVmVjdG9yID0gMDtcblxuXG4gIGh5cGVycGxhbmVWZWN0b3IgPSBkYXRhW2xlZnRdIC0gZGF0YVtyaWdodF07XG4gIGh5cGVycGxhbmVPZmZzZXQgLT1cbiAgICAoaHlwZXJwbGFuZVZlY3RvciAqIChkYXRhW2xlZnRdICsgZGF0YVtyaWdodF0pKSAvIDIuMDtcblxuXG4gIC8vIEZvciBlYWNoIHBvaW50IGNvbXB1dGUgdGhlIG1hcmdpbiAocHJvamVjdCBpbnRvIG5vcm1hbCB2ZWN0b3IpXG4gIC8vIElmIHdlIGFyZSBvbiBsb3dlciBzaWRlIG9mIHRoZSBoeXBlcnBsYW5lIHB1dCBpbiBvbmUgcGlsZSwgb3RoZXJ3aXNlXG4gIC8vIHB1dCBpdCBpbiB0aGUgb3RoZXIgcGlsZSAoaWYgd2UgaGl0IGh5cGVycGxhbmUgb24gdGhlIG5vc2UsIGZsaXAgYSBjb2luKVxuICBsZXQgbkxlZnQgPSAwO1xuICBsZXQgblJpZ2h0ID0gMDtcbiAgY29uc3Qgc2lkZSA9IHV0aWxzLnplcm9zKGluZGljZXMubGVuZ3RoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IG1hcmdpbiA9IGh5cGVycGxhbmVPZmZzZXQ7XG5cbiAgICBtYXJnaW4gKz0gaHlwZXJwbGFuZVZlY3RvciAqIGRhdGFbaW5kaWNlc1tpXV07XG5cbiAgICBpZiAobWFyZ2luID09PSAwKSB7XG4gICAgICBzaWRlW2ldID0gdXRpbHMudGF1UmFuZEludCgyLCByYW5kb20pO1xuICAgICAgaWYgKHNpZGVbaV0gPT09IDApXG4gICAgICAgIG5MZWZ0ICs9IDE7XG4gICAgICBlbHNlXG4gICAgICAgIG5SaWdodCArPSAxO1xuICAgIH0gZWxzZSBpZiAobWFyZ2luID4gMCkge1xuICAgICAgc2lkZVtpXSA9IDA7XG4gICAgICBuTGVmdCArPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaWRlW2ldID0gMTtcbiAgICAgIG5SaWdodCArPSAxO1xuICAgIH1cbiAgfVxuXG4gIC8vIE5vdyB0aGF0IHdlIGhhdmUgdGhlIGNvdW50cywgYWxsb2NhdGUgYXJyYXlzXG4gIGNvbnN0IGluZGljZXNMZWZ0ID0gdXRpbHMuemVyb3MobkxlZnQpO1xuICBjb25zdCBpbmRpY2VzUmlnaHQgPSB1dGlscy56ZXJvcyhuUmlnaHQpO1xuXG4gIC8vIFBvcHVsYXRlIHRoZSBhcnJheXMgd2l0aCBpbmRpY2VzIGFjY29yZGluZyB0byB3aGljaCBzaWRlIHRoZXkgZmVsbCBvblxuICBuTGVmdCA9IDA7XG4gIG5SaWdodCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2lkZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChzaWRlW2ldID09PSAwKSB7XG4gICAgICBpbmRpY2VzTGVmdFtuTGVmdF0gPSBpbmRpY2VzW2ldO1xuICAgICAgbkxlZnQgKz0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5kaWNlc1JpZ2h0W25SaWdodF0gPSBpbmRpY2VzW2ldO1xuICAgICAgblJpZ2h0ICs9IDE7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBpbmRpY2VzTGVmdCxcbiAgICBpbmRpY2VzUmlnaHQsXG4gICAgaHlwZXJwbGFuZTogaHlwZXJwbGFuZVZlY3RvcixcbiAgICBvZmZzZXQ6IGh5cGVycGxhbmVPZmZzZXQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGZsYXR0ZW5UcmVlKHRyZWU6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSwgbGVhZlNpemU6IG51bWJlcikge1xuICBjb25zdCBuTm9kZXMgPSBudW1Ob2Rlcyh0cmVlKTtcbiAgY29uc3QgbkxlYXZlcyA9IG51bUxlYXZlcyh0cmVlKTtcblxuICAvLyBUT0RPOiBWZXJpZnkgdGhhdCBzcGFyc2UgY29kZSBpcyBub3QgcmVsZXZhbnQuLi5cbiAgY29uc3QgaHlwZXJwbGFuZXMgPSB1dGlsc1xuICAgIC5yYW5nZShuTm9kZXMpXG4gICAgLm1hcCgoKSA9PiB0cmVlLmh5cGVycGxhbmUgPyAxIDogMCk7XG5cbiAgY29uc3Qgb2Zmc2V0cyA9IHV0aWxzLnplcm9zKG5Ob2Rlcyk7XG4gIGNvbnN0IGNoaWxkcmVuID0gdXRpbHMucmFuZ2Uobk5vZGVzKS5tYXAoKCkgPT4gWy0xLCAtMV0pO1xuICBjb25zdCBpbmRpY2VzID0gdXRpbHNcbiAgICAucmFuZ2UobkxlYXZlcylcbiAgICAubWFwKCgpID0+IHV0aWxzLnJhbmdlKGxlYWZTaXplKS5tYXAoKCkgPT4gLTEpKTtcbiAgcmVjdXJzaXZlRmxhdHRlbih0cmVlLCBoeXBlcnBsYW5lcywgb2Zmc2V0cywgY2hpbGRyZW4sIGluZGljZXMsIDAsIDApO1xuICByZXR1cm4gbmV3IEZsYXRUcmVlKGh5cGVycGxhbmVzLCBvZmZzZXRzLCBjaGlsZHJlbiwgaW5kaWNlcyk7XG59XG5cbmZ1bmN0aW9uIHJlY3Vyc2l2ZUZsYXR0ZW4oXG4gIHRyZWU6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSxcbiAgaHlwZXJwbGFuZXM6IG51bWJlcltdLFxuICBvZmZzZXRzOiBudW1iZXJbXSxcbiAgY2hpbGRyZW46IG51bWJlcltdW10sXG4gIGluZGljZXM6IG51bWJlcltdW10sXG4gIG5vZGVOdW06IG51bWJlcixcbiAgbGVhZk51bTogbnVtYmVyXG4pOiB7IG5vZGVOdW06IG51bWJlcjsgbGVhZk51bTogbnVtYmVyIH0ge1xuICBpZiAodHJlZS5pc0xlYWYpIHtcbiAgICBjaGlsZHJlbltub2RlTnVtXVswXSA9IC1sZWFmTnVtO1xuXG4gICAgLy8gVE9ETzogVHJpcGxlIGNoZWNrIHRoaXMgb3BlcmF0aW9uIGNvcnJlc3BvbmRzIHRvXG4gICAgLy8gaW5kaWNlc1tsZWFmTnVtIDogdHJlZS5pbmRpY2VzLnNoYXBlWzBdXSA9IHRyZWUuaW5kaWNlc1xuICAgIGluZGljZXNbbGVhZk51bV0uc3BsaWNlKDAsIHRyZWUuaW5kaWNlcyEubGVuZ3RoLCAuLi50cmVlLmluZGljZXMhKTtcbiAgICBsZWFmTnVtICs9IDE7XG4gICAgcmV0dXJuIHtub2RlTnVtLCBsZWFmTnVtfTtcbiAgfSBlbHNlIHtcbiAgICBoeXBlcnBsYW5lc1tub2RlTnVtXSA9IHRyZWUuaHlwZXJwbGFuZSE7XG4gICAgb2Zmc2V0c1tub2RlTnVtXSA9IHRyZWUub2Zmc2V0ITtcbiAgICBjaGlsZHJlbltub2RlTnVtXVswXSA9IG5vZGVOdW0gKyAxO1xuICAgIGNvbnN0IG9sZE5vZGVOdW0gPSBub2RlTnVtO1xuXG4gICAgbGV0IHJlcyA9IHJlY3Vyc2l2ZUZsYXR0ZW4oXG4gICAgICB0cmVlLmxlZnRDaGlsZCEsXG4gICAgICBoeXBlcnBsYW5lcyxcbiAgICAgIG9mZnNldHMsXG4gICAgICBjaGlsZHJlbixcbiAgICAgIGluZGljZXMsXG4gICAgICBub2RlTnVtICsgMSxcbiAgICAgIGxlYWZOdW1cbiAgICApO1xuICAgIG5vZGVOdW0gPSByZXMubm9kZU51bTtcbiAgICBsZWFmTnVtID0gcmVzLmxlYWZOdW07XG5cbiAgICBjaGlsZHJlbltvbGROb2RlTnVtXVsxXSA9IG5vZGVOdW0gKyAxO1xuXG4gICAgcmVzID0gcmVjdXJzaXZlRmxhdHRlbihcbiAgICAgIHRyZWUucmlnaHRDaGlsZCEsXG4gICAgICBoeXBlcnBsYW5lcyxcbiAgICAgIG9mZnNldHMsXG4gICAgICBjaGlsZHJlbixcbiAgICAgIGluZGljZXMsXG4gICAgICBub2RlTnVtICsgMSxcbiAgICAgIGxlYWZOdW1cbiAgICApO1xuICAgIHJldHVybiB7bm9kZU51bTogcmVzLm5vZGVOdW0sIGxlYWZOdW06IHJlcy5sZWFmTnVtfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1Ob2Rlcyh0cmVlOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUpOiBudW1iZXIge1xuICBpZiAodHJlZS5pc0xlYWYpXG4gICAgcmV0dXJuIDE7XG4gIGVsc2VcbiAgICByZXR1cm4gMSArIG51bU5vZGVzKHRyZWUubGVmdENoaWxkISkgKyBudW1Ob2Rlcyh0cmVlLnJpZ2h0Q2hpbGQhKTtcbn1cblxuZnVuY3Rpb24gbnVtTGVhdmVzKHRyZWU6IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZSk6IG51bWJlciB7XG4gIGlmICh0cmVlLmlzTGVhZilcbiAgICByZXR1cm4gMTtcbiAgZWxzZVxuICAgIHJldHVybiBudW1MZWF2ZXModHJlZS5sZWZ0Q2hpbGQhKSArIG51bUxlYXZlcyh0cmVlLnJpZ2h0Q2hpbGQhKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhbiBhcnJheSBvZiBzZXRzIG9mIGNhbmRpZGF0ZSBuZWFyZXN0IG5laWdoYm9ycyBieVxuICogY29uc3RydWN0aW5nIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IGFuZCB0YWtpbmcgdGhlIGxlYXZlcyBvZiBhbGwgdGhlXG4gKiB0cmVlcy4gQW55IGdpdmVuIHRyZWUgaGFzIGxlYXZlcyB0aGF0IGFyZSBhIHNldCBvZiBwb3RlbnRpYWwgbmVhcmVzdFxuICogbmVpZ2hib3JzLiBHaXZlbiBlbm91Z2ggdHJlZXMgdGhlIHNldCBvZiBhbGwgc3VjaCBsZWF2ZXMgZ2l2ZXMgYSBnb29kXG4gKiBsaWtlbGlob29kIG9mIGdldHRpbmcgYSBnb29kIHNldCBvZiBuZWFyZXN0IG5laWdoYm9ycyBpbiBjb21wb3NpdGUuIFNpbmNlXG4gKiBzdWNoIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IGlzIGluZXhwZW5zaXZlIHRvIGNvbXB1dGUsIHRoaXMgY2FuIGJlIGFcbiAqIHVzZWZ1bCBtZWFucyBvZiBzZWVkaW5nIG90aGVyIG5lYXJlc3QgbmVpZ2hib3IgYWxnb3JpdGhtcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VMZWFmQXJyYXkocnBGb3Jlc3Q6IEZsYXRUcmVlW10pOiBudW1iZXJbXVtdIHtcbiAgaWYgKHJwRm9yZXN0Lmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBvdXRwdXQ6IG51bWJlcltdW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRyZWUgb2YgcnBGb3Jlc3QpXG4gICAgICBvdXRwdXQucHVzaCguLi50cmVlLmluZGljZXMhKTtcblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtbLTFdXTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbGVjdHMgdGhlIHNpZGUgb2YgdGhlIHRyZWUgdG8gc2VhcmNoIGR1cmluZyBmbGF0IHRyZWUgc2VhcmNoLlxuICovXG5mdW5jdGlvbiBzZWxlY3RTaWRlKFxuICBoeXBlcnBsYW5lOiBudW1iZXIsXG4gIG9mZnNldDogbnVtYmVyLFxuICBwb2ludDogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgbGV0IG1hcmdpbiA9IG9mZnNldDtcblxuICBtYXJnaW4gKz0gaHlwZXJwbGFuZSAqIHBvaW50O1xuXG5cbiAgaWYgKG1hcmdpbiA9PT0gMCkge1xuICAgIGNvbnN0IHNpZGUgPSB1dGlscy50YXVSYW5kSW50KDIsIHJhbmRvbSk7XG4gICAgcmV0dXJuIHNpZGU7XG4gIH0gZWxzZSBpZiAobWFyZ2luID4gMCkge1xuICAgIHJldHVybiAwO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAxO1xuICB9XG59XG5cbi8qKlxuICogU2VhcmNoZXMgYSBmbGF0dGVuZWQgcnAtdHJlZSBmb3IgYSBwb2ludC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlYXJjaEZsYXRUcmVlKFxuICBwb2ludDogbnVtYmVyLFxuICB0cmVlOiBGbGF0VHJlZSxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGxldCBub2RlID0gMDtcbiAgd2hpbGUgKHRyZWUuY2hpbGRyZW5bbm9kZV1bMF0gPiAwKSB7XG4gICAgY29uc3Qgc2lkZSA9IHNlbGVjdFNpZGUoXG4gICAgICB0cmVlLmh5cGVycGxhbmVzW25vZGVdLFxuICAgICAgdHJlZS5vZmZzZXRzW25vZGVdLFxuICAgICAgcG9pbnQsXG4gICAgICByYW5kb21cbiAgICApO1xuICAgIGlmIChzaWRlID09PSAwKVxuICAgICAgbm9kZSA9IHRyZWUuY2hpbGRyZW5bbm9kZV1bMF07XG4gICAgZWxzZVxuICAgICAgbm9kZSA9IHRyZWUuY2hpbGRyZW5bbm9kZV1bMV07XG4gIH1cblxuICBjb25zdCBpbmRleCA9IC0xICogdHJlZS5jaGlsZHJlbltub2RlXVswXTtcbiAgcmV0dXJuIHRyZWUuaW5kaWNlc1tpbmRleF07XG59XG4iXX0=","const toString = Object.prototype.toString;\n\nexport default function isAnyArray(object) {\n return toString.call(object).endsWith('Array]');\n}\n","/**\n * Calculate current error\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} parameters - Array of current parameter values\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {number}\n */\nexport default function errorCalculation(\n data,\n parameters,\n parameterizedFunction,\n) {\n let error = 0;\n const func = parameterizedFunction(parameters);\n\n for (let i = 0; i < data.x.length; i++) {\n error += Math.abs(data.y[i] - func(data.x[i]));\n }\n\n return error;\n}\n","import { inverse, Matrix } from 'ml-matrix';\n\n/**\n * Difference of the matrix function over the parameters\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} evaluatedData - Array of previous evaluated function values\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number} gradientDifference - Adjustment for decrease the damping parameter\n * @param {function} paramFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {Matrix}\n */\nfunction gradientFunction(\n data,\n evaluatedData,\n params,\n gradientDifference,\n paramFunction,\n) {\n const n = params.length;\n const m = data.x.length;\n\n let ans = new Array(n);\n\n for (let param = 0; param < n; param++) {\n ans[param] = new Array(m);\n let auxParams = params.slice();\n auxParams[param] += gradientDifference;\n let funcParam = paramFunction(auxParams);\n\n for (let point = 0; point < m; point++) {\n ans[param][point] = evaluatedData[point] - funcParam(data.x[point]);\n }\n }\n return new Matrix(ans);\n}\n\n/**\n * Matrix function over the samples\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} evaluatedData - Array of previous evaluated function values\n * @return {Matrix}\n */\nfunction matrixFunction(data, evaluatedData) {\n const m = data.x.length;\n\n let ans = new Array(m);\n\n for (let point = 0; point < m; point++) {\n ans[point] = [data.y[point] - evaluatedData[point]];\n }\n\n return new Matrix(ans);\n}\n\n/**\n * Iteration for Levenberg-Marquardt\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number} damping - Levenberg-Marquardt parameter\n * @param {number} gradientDifference - Adjustment for decrease the damping parameter\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {Array<number>}\n */\nexport default function step(\n data,\n params,\n damping,\n gradientDifference,\n parameterizedFunction,\n) {\n let value = damping * gradientDifference * gradientDifference;\n let identity = Matrix.eye(params.length, params.length, value);\n\n const func = parameterizedFunction(params);\n\n let evaluatedData = new Float64Array(data.x.length);\n for (let i = 0; i < data.x.length; i++) {\n evaluatedData[i] = func(data.x[i]);\n }\n\n let gradientFunc = gradientFunction(\n data,\n evaluatedData,\n params,\n gradientDifference,\n parameterizedFunction,\n );\n let matrixFunc = matrixFunction(data, evaluatedData);\n let inverseMatrix = inverse(\n identity.add(gradientFunc.mmul(gradientFunc.transpose())),\n );\n\n params = new Matrix([params]);\n params = params.sub(\n inverseMatrix\n .mmul(gradientFunc)\n .mmul(matrixFunc)\n .mul(gradientDifference)\n .transpose(),\n );\n\n return params.to1DArray();\n}\n","/* eslint-disable max-len */\n/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as heap from './heap';\nimport * as matrix from './matrix';\nimport * as nnDescent from './nn_descent';\nimport * as tree from './tree';\nimport * as utils from './utils';\nimport LM from 'ml-levenberg-marquardt';\nconst SMOOTH_K_TOLERANCE = 1e-5;\nconst MIN_K_DIST_SCALE = 1e-3;\n/**\n * UMAP projection system, based on the python implementation from McInnes, L,\n * Healy, J, UMAP: Uniform Manifold Approximation and Projection for Dimension\n * Reduction (https://github.com/lmcinnes/umap).\n *\n * This implementation differs in a few regards:\n * a) The initialization of the embedding for optimization is not computed using\n * a spectral method, rather it is initialized randomly. This avoids some\n * computationally intensive matrix eigen computations that aren't easily\n * ported to JavaScript.\n * b) A lot of \"extra\" functionality has been omitted from this implementation,\n * most notably a great deal of alternate distance functions.\n *\n * This implementation provides three methods of reducing dimensionality:\n * 1) fit: fit the data synchronously\n * 2) fitAsync: fit the data asynchronously, with a callback function provided\n * that is invoked on each optimization step.\n * 3) initializeFit / step: manually initialize the algorithm then explictly\n * step through each epoch of the SGD optimization\n */\nexport class UMAP {\n get neighbors() {\n return this.nNeighbors;\n }\n constructor(params = {}) {\n this.learningRate = 1.0;\n this.localConnectivity = 1.0;\n this.minDist = 0.1;\n this.nComponents = 2;\n this.nEpochs = 0;\n this.nNeighbors = 15;\n this.negativeSampleRate = 5;\n this.random = Math.random;\n this.repulsionStrength = 1.0;\n this.setOpMixRatio = 1.0;\n this.spread = 1.0;\n this.transformQueueSize = 4.0;\n // Supervised projection params\n this.targetMetric = \"categorical\" /* TargetMetric.categorical */;\n this.targetWeight = 0.5;\n this.targetNNeighbors = 15;\n this.distanceFn = numeric;\n this.isInitialized = false;\n this.rpForest = [];\n // Projected embedding\n this.embedding = [];\n this.optimizationState = new OptimizationState();\n const setParam = (key) => {\n //@ts-ignore\n if (params[key] !== undefined)\n this[key] = params[key];\n };\n setParam('distanceFn');\n setParam('learningRate');\n setParam('localConnectivity');\n setParam('minDist');\n setParam('nComponents');\n setParam('nEpochs');\n setParam('nNeighbors');\n setParam('negativeSampleRate');\n setParam('random');\n setParam('repulsionStrength');\n setParam('setOpMixRatio');\n setParam('spread');\n setParam('transformQueueSize');\n this.targetNNeighbors = params.nNeighbors || this.nNeighbors || this.targetNNeighbors;\n }\n /**\n * Fit the data to a projected embedding space synchronously.\n */\n fit(X) {\n this.initializeFit(X);\n this.optimizeLayout();\n return this.embedding;\n }\n /**\n * Fit the data to a projected embedding space asynchronously, with a callback\n * function invoked on every epoch of optimization.\n */\n async fitAsync(X, callback = () => true) {\n this.initializeFit(X);\n await this.optimizeLayoutAsync(callback);\n return this.embedding;\n }\n /**\n * Initializes parameters needed for supervised projection.\n */\n setSupervisedProjection(Y, params = {}) {\n this.Y = Y;\n this.targetMetric = params.targetMetric || this.targetMetric;\n this.targetWeight = params.targetWeight || this.targetWeight;\n this.targetNNeighbors = params.targetNNeighbors || this.targetNNeighbors;\n }\n /**\n * Initializes umap with precomputed KNN indices and distances.\n */\n setPrecomputedKNN(knnIndices, knnDistances) {\n this.knnIndices = knnIndices;\n this.knnDistances = knnDistances;\n }\n /**\n * Initializes fit by computing KNN and a fuzzy simplicial set, as well as\n * initializing the projected embeddings. Sets the optimization state ahead\n * of optimization steps. Returns the number of epochs to be used for the\n * SGD optimization.\n */\n initializeFit(X) {\n if (X.length <= this.nNeighbors)\n throw new Error(`Not enough data points (${X.length}) to create nNeighbors: ${this.nNeighbors}. Add more data points or adjust the configuration.`);\n // We don't need to reinitialize if we've already initialized for this data.\n if (this.X === X && this.isInitialized)\n return this.getNEpochs();\n this.X = X;\n if (!this.knnIndices && !this.knnDistances) {\n const knnResults = this.nearestNeighbors(X);\n this.knnIndices = knnResults.knnIndices;\n this.knnDistances = knnResults.knnDistances;\n }\n this.graph = this.fuzzySimplicialSet(X, this.nNeighbors, this.setOpMixRatio);\n // Set up the search graph for subsequent transformation.\n this.makeSearchFns();\n this.searchGraph = this.makeSearchGraph(X);\n // Check if supervised projection, then adjust the graph.\n this.processGraphForSupervisedProjection();\n const { head, tail, epochsPerSample, } = this.initializeSimplicialSetEmbedding();\n // Set the optimization routine state\n this.optimizationState.head = head;\n this.optimizationState.tail = tail;\n this.optimizationState.epochsPerSample = epochsPerSample;\n // Now, initialize the optimization steps\n this.initializeOptimization();\n this.prepareForOptimizationLoop();\n this.isInitialized = true;\n return this.getNEpochs();\n }\n makeSearchFns() {\n const { initFromTree, initFromRandom } = nnDescent.makeInitializations(this.distanceFn);\n this.initFromTree = initFromTree;\n this.initFromRandom = initFromRandom;\n this.search = nnDescent.makeInitializedNNSearch(this.distanceFn);\n }\n makeSearchGraph(X) {\n const knnIndices = this.knnIndices;\n const knnDistances = this.knnDistances;\n const dims = [X.length, X.length];\n const searchGraph = new matrix.SparseMatrix([], [], [], dims);\n for (let i = 0; i < knnIndices.length; i++) {\n const knn = knnIndices[i];\n const distances = knnDistances[i];\n for (let j = 0; j < knn.length; j++) {\n const neighbor = knn[j];\n const distance = distances[j];\n if (distance > 0)\n searchGraph.set(i, neighbor, distance);\n }\n }\n const transpose = matrix.transpose(searchGraph);\n return matrix.maximum(searchGraph, transpose);\n }\n /**\n * Transforms data to the existing embedding space.\n */\n transform(toTransform) {\n // Use the previous rawData\n const rawData = this.X;\n if (rawData === undefined || rawData.length === 0)\n throw new Error('No data has been fit.');\n let nNeighbors = Math.floor(this.nNeighbors * this.transformQueueSize);\n nNeighbors = Math.min(rawData.length, nNeighbors);\n const init = nnDescent.initializeSearch(this.rpForest, rawData, toTransform, nNeighbors, this.initFromRandom, this.initFromTree, this.random);\n const result = this.search(rawData, this.searchGraph, init, toTransform);\n let { indices, weights: distances } = heap.deheapSort(result);\n indices = indices.map((x) => x.slice(0, this.nNeighbors));\n distances = distances.map((x) => x.slice(0, this.nNeighbors));\n const adjustedLocalConnectivity = Math.max(0, this.localConnectivity - 1);\n const { sigmas, rhos } = this.smoothKNNDistance(distances, this.nNeighbors, adjustedLocalConnectivity);\n const { rows, cols, vals } = this.computeMembershipStrengths(indices, distances, sigmas, rhos);\n const size = [toTransform.length, rawData.length];\n let graph = new matrix.SparseMatrix(rows, cols, vals, size);\n // This was a very specially constructed graph with constant degree.\n // That lets us do fancy unpacking by reshaping the csr matrix indices\n // and data. Doing so relies on the constant degree assumption!\n const normed = matrix.normalize(graph, \"l1\" /* matrix.NormType.l1 */);\n const csrMatrix = matrix.getCSR(normed);\n const nPoints = toTransform.length;\n const eIndices = utils.reshape2d(csrMatrix.indices, nPoints, this.nNeighbors);\n const eWeights = utils.reshape2d(csrMatrix.values, nPoints, this.nNeighbors);\n const embedding = initTransform(eIndices, eWeights, this.embedding);\n const nEpochs = this.nEpochs ?\n this.nEpochs / 3 :\n graph.nRows <= 10000 ?\n 100 :\n 30;\n const graphMax = graph\n .getValues()\n .reduce((max, val) => (val > max ? val : max), 0);\n graph = graph.map((value) => (value < graphMax / nEpochs ? 0 : value));\n graph = matrix.eliminateZeros(graph);\n const epochsPerSample = this.makeEpochsPerSample(graph.getValues(), nEpochs);\n const head = graph.getRows();\n const tail = graph.getCols();\n // Initialize optimization slightly differently than the fit method.\n this.assignOptimizationStateParameters({\n headEmbedding: embedding,\n tailEmbedding: this.embedding,\n head,\n tail,\n currentEpoch: 0,\n nEpochs,\n nVertices: graph.getDims()[1],\n epochsPerSample,\n });\n this.prepareForOptimizationLoop();\n return this.optimizeLayout();\n }\n /**\n * Checks if we're using supervised projection, then process the graph\n * accordingly.\n */\n processGraphForSupervisedProjection() {\n const { Y, X } = this;\n if (Y) {\n if (Y.length !== X.length)\n throw new Error('Length of X and y must be equal');\n if (this.targetMetric === \"categorical\" /* TargetMetric.categorical */) {\n const lt = this.targetWeight < 1.0;\n const farDist = lt ? 2.5 * (1.0 / (1.0 - this.targetWeight)) : 1.0e12;\n this.graph = this.categoricalSimplicialSetIntersection(this.graph, Y, farDist);\n }\n // TODO (andycoenen@): add non-categorical supervised embeddings.\n }\n }\n /**\n * Manually step through the optimization process one epoch at a time.\n */\n step() {\n const { currentEpoch } = this.optimizationState;\n if (currentEpoch < this.getNEpochs())\n this.optimizeLayoutStep(currentEpoch);\n return this.optimizationState.currentEpoch;\n }\n /**\n * Returns the computed projected embedding.\n */\n getEmbedding() {\n return this.embedding;\n }\n /**\n * Compute the ``nNeighbors`` nearest points for each data point in ``X``\n * This may be exact, but more likely is approximated via nearest neighbor\n * descent.\n */\n nearestNeighbors(X) {\n const { distanceFn, nNeighbors } = this;\n const log2 = (n) => Math.log(n) / Math.log(2);\n const metricNNDescent = nnDescent.makeNNDescent(distanceFn, this.random);\n // Handle python3 rounding down from 0.5 discrpancy\n const round = (n) => {\n return n === 0.5 ? 0 : Math.round(n);\n };\n const nTrees = 5 + Math.floor(round(X.length ** 0.5 / 20.0));\n const nIters = Math.max(5, Math.floor(Math.round(log2(X.length))));\n this.rpForest = tree.makeForest(X, nNeighbors, nTrees, this.random);\n const leafArray = tree.makeLeafArray(this.rpForest);\n const { indices, weights } = metricNNDescent(X, leafArray, nNeighbors, nIters);\n return { knnIndices: indices, knnDistances: weights };\n }\n /**\n * Given a set of data X, a neighborhood size, and a measure of distance\n * compute the fuzzy simplicial set (here represented as a fuzzy graph in\n * the form of a sparse matrix) associated to the data. This is done by\n * locally approximating geodesic distance at each point, creating a fuzzy\n * simplicial set for each such point, and then combining all the local\n * fuzzy simplicial sets into a global one via a fuzzy union.\n */\n fuzzySimplicialSet(X, nNeighbors, setOpMixRatio = 1.0) {\n const { knnIndices = [], knnDistances = [], localConnectivity } = this;\n const { sigmas, rhos } = this.smoothKNNDistance(knnDistances, nNeighbors, localConnectivity);\n const { rows, cols, vals } = this.computeMembershipStrengths(knnIndices, knnDistances, sigmas, rhos);\n const size = [X.length, X.length];\n const sparseMatrix = new matrix.SparseMatrix(rows, cols, vals, size);\n const transpose = matrix.transpose(sparseMatrix);\n const prodMatrix = matrix.pairwiseMultiply(sparseMatrix, transpose);\n const a = matrix.subtract(matrix.add(sparseMatrix, transpose), prodMatrix);\n const b = matrix.multiplyScalar(a, setOpMixRatio);\n const c = matrix.multiplyScalar(prodMatrix, 1.0 - setOpMixRatio);\n const result = matrix.add(b, c);\n return result;\n }\n /**\n * Combine a fuzzy simplicial set with another fuzzy simplicial set\n * generated from categorical data using categorical distances. The target\n * data is assumed to be categorical label data (a vector of labels),\n * and this will update the fuzzy simplicial set to respect that label data.\n */\n categoricalSimplicialSetIntersection(simplicialSet, target, farDist, unknownDist = 1.0) {\n let intersection = fastIntersection(simplicialSet, target, unknownDist, farDist);\n intersection = matrix.eliminateZeros(intersection);\n return resetLocalConnectivity(intersection);\n }\n /**\n * Compute a continuous version of the distance to the kth nearest\n * neighbor. That is, this is similar to knn-distance but allows continuous\n * k values rather than requiring an integral k. In esscence we are simply\n * computing the distance such that the cardinality of fuzzy set we generate\n * is k.\n */\n smoothKNNDistance(distances, k, localConnectivity = 1.0, nIter = 64, bandwidth = 1.0) {\n const target = (Math.log(k) / Math.log(2)) * bandwidth;\n const rho = utils.zeros(distances.length);\n const result = utils.zeros(distances.length);\n for (let i = 0; i < distances.length; i++) {\n let lo = 0.0;\n let hi = Infinity;\n let mid = 1.0;\n // TODO: This is very inefficient, but will do for now. FIXME\n const ithDistances = distances[i];\n const nonZeroDists = ithDistances.filter((d) => d > 0.0);\n if (nonZeroDists.length >= localConnectivity) {\n const index = Math.floor(localConnectivity);\n const interpolation = localConnectivity - index;\n if (index > 0) {\n rho[i] = nonZeroDists[index - 1];\n if (interpolation > SMOOTH_K_TOLERANCE) {\n rho[i] +=\n interpolation * (nonZeroDists[index] - nonZeroDists[index - 1]);\n }\n }\n else {\n rho[i] = interpolation * nonZeroDists[0];\n }\n }\n else if (nonZeroDists.length > 0) {\n rho[i] = utils.max(nonZeroDists);\n }\n for (let n = 0; n < nIter; n++) {\n let psum = 0.0;\n for (let j = 1; j < distances[i].length; j++) {\n const d = distances[i][j] - rho[i];\n if (d > 0)\n psum += Math.exp(-(d / mid));\n else\n psum += 1.0;\n }\n if (Math.abs(psum - target) < SMOOTH_K_TOLERANCE)\n break;\n if (psum > target) {\n hi = mid;\n mid = (lo + hi) / 2.0;\n }\n else {\n lo = mid;\n if (hi === Infinity)\n mid *= 2;\n else\n mid = (lo + hi) / 2.0;\n }\n }\n result[i] = mid;\n // TODO: This is very inefficient, but will do for now. FIXME\n if (rho[i] > 0.0) {\n const meanIthDistances = utils.mean(ithDistances);\n if (result[i] < MIN_K_DIST_SCALE * meanIthDistances)\n result[i] = MIN_K_DIST_SCALE * meanIthDistances;\n }\n else {\n const meanDistances = utils.mean(distances.map(utils.mean));\n if (result[i] < MIN_K_DIST_SCALE * meanDistances)\n result[i] = MIN_K_DIST_SCALE * meanDistances;\n }\n }\n return { sigmas: result, rhos: rho };\n }\n /**\n * Construct the membership strength data for the 1-skeleton of each local\n * fuzzy simplicial set -- this is formed as a sparse matrix where each row is\n * a local fuzzy simplicial set, with a membership strength for the\n * 1-simplex to each other data point.\n */\n computeMembershipStrengths(knnIndices, knnDistances, sigmas, rhos) {\n const nSamples = knnIndices.length;\n const nNeighbors = knnIndices[0].length;\n const rows = utils.zeros(nSamples * nNeighbors);\n const cols = utils.zeros(nSamples * nNeighbors);\n const vals = utils.zeros(nSamples * nNeighbors);\n for (let i = 0; i < nSamples; i++) {\n for (let j = 0; j < nNeighbors; j++) {\n let val = 0;\n if (knnIndices[i][j] === -1)\n continue; // We didn't get the full knn for i\n if (knnIndices[i][j] === i)\n val = 0.0;\n else if (knnDistances[i][j] - rhos[i] <= 0.0)\n val = 1.0;\n else\n val = Math.exp(-((knnDistances[i][j] - rhos[i]) / sigmas[i]));\n rows[i * nNeighbors + j] = i;\n cols[i * nNeighbors + j] = knnIndices[i][j];\n vals[i * nNeighbors + j] = val;\n }\n }\n return { rows, cols, vals };\n }\n /**\n * Initialize a fuzzy simplicial set embedding, using a specified\n * initialisation method and then minimizing the fuzzy set cross entropy\n * between the 1-skeletons of the high and low dimensional fuzzy simplicial\n * sets.\n */\n initializeSimplicialSetEmbedding() {\n const nEpochs = this.getNEpochs();\n const { nComponents } = this;\n const graphValues = this.graph.getValues();\n let graphMax = 0;\n for (let i = 0; i < graphValues.length; i++) {\n const value = graphValues[i];\n if (graphMax < graphValues[i])\n graphMax = value;\n }\n const graph = this.graph.map((value) => {\n if (value < graphMax / nEpochs)\n return 0;\n else\n return value;\n });\n // We're not computing the spectral initialization in this implementation\n // until we determine a better eigenvalue/eigenvector computation\n // approach\n this.embedding = utils.zeros(graph.nRows).map(() => {\n return utils.zeros(nComponents).map(() => {\n return utils.tauRand(this.random) * 20 + -10; // Random from -10 to 10\n });\n });\n // Get graph data in ordered way...\n const weights = [];\n const head = [];\n const tail = [];\n const rowColValues = graph.getAll();\n for (let i = 0; i < rowColValues.length; i++) {\n const entry = rowColValues[i];\n if (entry.value) {\n weights.push(entry.value);\n tail.push(entry.row);\n head.push(entry.col);\n }\n }\n const epochsPerSample = this.makeEpochsPerSample(weights, nEpochs);\n return { head, tail, epochsPerSample };\n }\n /**\n * Given a set of weights and number of epochs generate the number of\n * epochs per sample for each weight.\n */\n makeEpochsPerSample(weights, nEpochs) {\n const result = utils.filled(weights.length, -1.0);\n const max = utils.max(weights);\n const nSamples = weights.map((w) => (w / max) * nEpochs);\n nSamples.forEach((n, i) => {\n if (n > 0)\n result[i] = nEpochs / nSamples[i];\n });\n return result;\n }\n /**\n * Assigns optimization state parameters from a partial optimization state.\n */\n assignOptimizationStateParameters(state) {\n Object.assign(this.optimizationState, state);\n }\n /**\n * Sets a few optimization state parameters that are necessary before entering\n * the optimization step loop.\n */\n prepareForOptimizationLoop() {\n // Hyperparameters\n const { repulsionStrength, learningRate, negativeSampleRate } = this;\n const { epochsPerSample, headEmbedding, tailEmbedding, } = this.optimizationState;\n const dim = headEmbedding[0].length;\n const moveOther = headEmbedding.length === tailEmbedding.length;\n const epochsPerNegativeSample = epochsPerSample.map((e) => e / negativeSampleRate);\n const epochOfNextNegativeSample = [...epochsPerNegativeSample];\n const epochOfNextSample = [...epochsPerSample];\n this.assignOptimizationStateParameters({\n epochOfNextSample,\n epochOfNextNegativeSample,\n epochsPerNegativeSample,\n moveOther,\n initialAlpha: learningRate,\n alpha: learningRate,\n gamma: repulsionStrength,\n dim,\n });\n }\n /**\n * Initializes optimization state for stepwise optimization.\n */\n initializeOptimization() {\n // Algorithm state\n const headEmbedding = this.embedding;\n const tailEmbedding = this.embedding;\n // Initialized in initializeSimplicialSetEmbedding()\n const { head, tail, epochsPerSample } = this.optimizationState;\n const nEpochs = this.getNEpochs();\n const nVertices = this.graph.nCols;\n const { a, b } = findABParams(this.spread, this.minDist);\n this.assignOptimizationStateParameters({\n headEmbedding,\n tailEmbedding,\n head,\n tail,\n epochsPerSample,\n a,\n b,\n nEpochs,\n nVertices,\n });\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayoutStep(n) {\n const { optimizationState } = this;\n const { head, tail, headEmbedding, tailEmbedding, epochsPerSample, epochOfNextSample, epochOfNextNegativeSample, epochsPerNegativeSample, moveOther, initialAlpha, alpha, gamma, a, b, dim, nEpochs, nVertices, } = optimizationState;\n const clipValue = 4.0;\n for (let i = 0; i < epochsPerSample.length; i++) {\n if (epochOfNextSample[i] > n)\n continue;\n const j = head[i];\n const k = tail[i];\n const current = headEmbedding[j];\n const other = tailEmbedding[k];\n const distSquared = rDist(current, other);\n let gradCoeff = 0;\n if (distSquared > 0) {\n gradCoeff = -2.0 * a * b * Math.pow(distSquared, b - 1.0);\n gradCoeff /= a * Math.pow(distSquared, b) + 1.0;\n }\n for (let d = 0; d < dim; d++) {\n const gradD = clip(gradCoeff * (current[d] - other[d]), clipValue);\n current[d] += gradD * alpha;\n if (moveOther)\n other[d] += -gradD * alpha;\n }\n epochOfNextSample[i] += epochsPerSample[i];\n const nNegSamples = Math.floor((n - epochOfNextNegativeSample[i]) / epochsPerNegativeSample[i]);\n for (let p = 0; p < nNegSamples; p++) {\n const k = utils.tauRandInt(nVertices, this.random);\n const other = tailEmbedding[k];\n const distSquared = rDist(current, other);\n let gradCoeff = 0.0;\n if (distSquared > 0.0) {\n gradCoeff = 2.0 * gamma * b;\n gradCoeff /=\n (0.001 + distSquared) * (a * Math.pow(distSquared, b) + 1);\n }\n else if (j === k) {\n continue;\n }\n for (let d = 0; d < dim; d++) {\n let gradD = 4.0;\n if (gradCoeff > 0.0)\n gradD = clip(gradCoeff * (current[d] - other[d]), clipValue);\n current[d] += gradD * alpha;\n }\n }\n epochOfNextNegativeSample[i] += nNegSamples * epochsPerNegativeSample[i];\n }\n optimizationState.alpha = initialAlpha * (1.0 - n / nEpochs);\n optimizationState.currentEpoch += 1;\n return headEmbedding;\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayoutAsync(epochCallback = () => true) {\n return new Promise((resolve, reject) => {\n const step = async () => {\n try {\n const { nEpochs, currentEpoch } = this.optimizationState;\n this.embedding = this.optimizeLayoutStep(currentEpoch);\n const epochCompleted = this.optimizationState.currentEpoch;\n const shouldStop = epochCallback(epochCompleted) === false;\n const isFinished = epochCompleted === nEpochs;\n if (!shouldStop && !isFinished)\n setTimeout(() => step(), 0);\n else\n return resolve(isFinished);\n }\n catch (err) {\n reject(err);\n }\n };\n setTimeout(() => step(), 0);\n });\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayout(epochCallback = () => true) {\n let isFinished = false;\n let embedding = [];\n while (!isFinished) {\n const { nEpochs, currentEpoch } = this.optimizationState;\n embedding = this.optimizeLayoutStep(currentEpoch);\n const epochCompleted = this.optimizationState.currentEpoch;\n const shouldStop = epochCallback(epochCompleted) === false;\n isFinished = epochCompleted === nEpochs || shouldStop;\n }\n return embedding;\n }\n /**\n * Gets the number of epochs for optimizing the projection.\n * NOTE: This heuristic differs from the python version\n */\n getNEpochs() {\n const graph = this.graph;\n if (this.nEpochs > 0)\n return this.nEpochs;\n if (!graph)\n return 200;\n const length = graph.nRows;\n if (length <= 2500)\n return 500;\n else if (length <= 5000)\n return 400;\n else if (length <= 7500)\n return 300;\n else\n return 200;\n }\n}\nexport function euclidean(x, y) {\n let result = 0;\n for (let i = 0; i < x.length; i++)\n result += (x[i] - y[i]) ** 2;\n return Math.sqrt(result);\n}\nexport function numeric(x, y) {\n const result = Math.abs(x - y);\n return result;\n}\nexport function cosine(x, y) {\n let result = 0.0;\n let normX = 0.0;\n let normY = 0.0;\n for (let i = 0; i < x.length; i++) {\n result += x[i] * y[i];\n normX += x[i] ** 2;\n normY += y[i] ** 2;\n }\n if (normX === 0 && normY === 0)\n return 0;\n else if (normX === 0 || normY === 0)\n return 1.0;\n else\n return 1.0 - result / Math.sqrt(normX * normY);\n}\n/**\n * An interface representing the optimization state tracked between steps of\n * the SGD optimization\n */\nclass OptimizationState {\n constructor() {\n this.currentEpoch = 0;\n // Data tracked during optimization steps.\n this.headEmbedding = [];\n this.tailEmbedding = [];\n this.head = [];\n this.tail = [];\n this.epochsPerSample = [];\n this.epochOfNextSample = [];\n this.epochOfNextNegativeSample = [];\n this.epochsPerNegativeSample = [];\n this.moveOther = true;\n this.initialAlpha = 1.0;\n this.alpha = 1.0;\n this.gamma = 1.0;\n this.a = 1.5769434603113077;\n this.b = 0.8950608779109733;\n this.dim = 2;\n this.nEpochs = 500;\n this.nVertices = 0;\n }\n}\n/**\n * Standard clamping of a value into a fixed range\n */\nfunction clip(x, clipValue) {\n if (x > clipValue)\n return clipValue;\n else if (x < -clipValue)\n return -clipValue;\n else\n return x;\n}\n/**\n * Reduced Euclidean distance.\n */\nfunction rDist(x, y) {\n let result = 0.0;\n for (let i = 0; i < x.length; i++)\n result += Math.pow(x[i] - y[i], 2);\n return result;\n}\n/**\n * Fit a, b params for the differentiable curve used in lower\n * dimensional fuzzy simplicial complex construction. We want the\n * smooth curve (from a pre-defined family with simple gradient) that\n * best matches an offset exponential decay.\n */\nexport function findABParams(spread, minDist) {\n const curve = ([a, b]) => (x) => {\n return 1.0 / (1.0 + a * x ** (2 * b));\n };\n const xv = utils\n .linear(0, spread * 3, 300)\n .map((val) => (val < minDist ? 1.0 : val));\n const yv = utils.zeros(xv.length).map((val, index) => {\n const gte = xv[index] >= minDist;\n return gte ? Math.exp(-(xv[index] - minDist) / spread) : val;\n });\n const initialValues = [0.5, 0.5];\n const data = { x: xv, y: yv };\n // Default options for the algorithm (from github example)\n const options = {\n damping: 1.5,\n initialValues,\n gradientDifference: 10e-2,\n maxIterations: 100,\n errorTolerance: 10e-3,\n };\n // eslint-disable-next-line new-cap\n const { parameterValues } = LM(data, curve, options);\n const [a, b] = parameterValues;\n return { a, b };\n}\n/**\n * Under the assumption of categorical distance for the intersecting\n * simplicial set perform a fast intersection.\n */\nexport function fastIntersection(graph, target, unknownDist = 1.0, farDist = 5.0) {\n return graph.map((value, row, col) => {\n if (target[row] === -1 || target[col] === -1)\n return value * Math.exp(-unknownDist);\n else if (target[row] !== target[col])\n return value * Math.exp(-farDist);\n else\n return value;\n });\n}\n/**\n * Reset the local connectivity requirement -- each data sample should\n * have complete confidence in at least one 1-simplex in the simplicial set.\n * We can enforce this by locally rescaling confidences, and then remerging the\n * different local simplicial sets together.\n */\nexport function resetLocalConnectivity(simplicialSet) {\n simplicialSet = matrix.normalize(simplicialSet, \"max\" /* matrix.NormType.max */);\n const transpose = matrix.transpose(simplicialSet);\n const prodMatrix = matrix.pairwiseMultiply(transpose, simplicialSet);\n simplicialSet = matrix.add(simplicialSet, matrix.subtract(transpose, prodMatrix));\n return matrix.eliminateZeros(simplicialSet);\n}\n/**\n * Given indices and weights and an original embeddings\n * initialize the positions of new points relative to the\n * indices and weights (of their neighbors in the source data).\n */\nexport function initTransform(indices, weights, embedding) {\n const result = utils\n .zeros(indices.length)\n .map((_z) => utils.zeros(embedding[0].length));\n for (let i = 0; i < indices.length; i++) {\n for (let j = 0; j < indices[0].length; j++) {\n for (let d = 0; d < embedding[0].length; d++) {\n const a = indices[i][j];\n result[i][d] += weights[i][j] * embedding[a][d];\n }\n }\n }\n return result;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW1hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInVtYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNEJBQTRCO0FBQzVCOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVIOzs7OztHQUtHO0FBRUg7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQkc7QUFFSCxPQUFPLEtBQUssSUFBSSxNQUFNLFFBQVEsQ0FBQztBQUMvQixPQUFPLEtBQUssTUFBTSxNQUFNLFVBQVUsQ0FBQztBQUNuQyxPQUFPLEtBQUssU0FBUyxNQUFNLGNBQWMsQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLFFBQVEsQ0FBQztBQUMvQixPQUFPLEtBQUssS0FBSyxNQUFNLFNBQVMsQ0FBQztBQUNqQyxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQWF4QyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQztBQUNoQyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQztBQW1IOUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxNQUFNLE9BQU8sSUFBSTtJQTJDZixJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDekIsQ0FBQztJQUNELFlBQVksU0FBeUIsRUFBRTtRQTdDaEMsaUJBQVksR0FBRyxHQUFHLENBQUM7UUFDbkIsc0JBQWlCLEdBQUcsR0FBRyxDQUFDO1FBQ3hCLFlBQU8sR0FBRyxHQUFHLENBQUM7UUFDZCxnQkFBVyxHQUFHLENBQUMsQ0FBQztRQUNmLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWixlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLHVCQUFrQixHQUFHLENBQUMsQ0FBQztRQUN2QixXQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNyQixzQkFBaUIsR0FBRyxHQUFHLENBQUM7UUFDeEIsa0JBQWEsR0FBRyxHQUFHLENBQUM7UUFDcEIsV0FBTSxHQUFHLEdBQUcsQ0FBQztRQUNa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QyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUMzQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUM3QyxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hCLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG4vKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBoZWFwIGZyb20gJy4vaGVhcCc7XG5pbXBvcnQgKiBhcyBtYXRyaXggZnJvbSAnLi9tYXRyaXgnO1xuaW1wb3J0ICogYXMgbm5EZXNjZW50IGZyb20gJy4vbm5fZGVzY2VudCc7XG5pbXBvcnQgKiBhcyB0cmVlIGZyb20gJy4vdHJlZSc7XG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcbmltcG9ydCBMTSBmcm9tICdtbC1sZXZlbmJlcmctbWFycXVhcmR0JztcblxuZXhwb3J0IHR5cGUgRGlzdGFuY2VGbiA9ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gbnVtYmVyO1xuZXhwb3J0IHR5cGUgUmFuZG9tRm4gPSAoKSA9PiBudW1iZXI7XG5leHBvcnQgdHlwZSBFcG9jaENhbGxiYWNrID0gKGVwb2NoOiBudW1iZXIpID0+IGJvb2xlYW4gfCB2b2lkO1xuZXhwb3J0IHR5cGUgVmVjdG9yID0gbnVtYmVyW107XG5leHBvcnQgdHlwZSBWZWN0b3JzID0gVmVjdG9yW107XG5leHBvcnQgY29uc3QgZW51bSBUYXJnZXRNZXRyaWMge1xuICBjYXRlZ29yaWNhbCA9ICdjYXRlZ29yaWNhbCcsXG4gIGwxID0gJ2wxJyxcbiAgbDIgPSAnbDInLFxufVxuXG5jb25zdCBTTU9PVEhfS19UT0xFUkFOQ0UgPSAxZS01O1xuY29uc3QgTUlOX0tfRElTVF9TQ0FMRSA9IDFlLTM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVU1BUFBhcmFtZXRlcnMge1xuICAvKipcbiAgICogVGhlIGRpc3RhbmNlIGZ1bmN0aW9uIHdpdGggd2hpY2ggdG8gYXNzZXNzIG5lYXJlc3QgbmVpZ2hib3JzLCBkZWZhdWx0c1xuICAgKiB0byBldWNsaWRlYW4gZGlzdGFuY2UuXG4gICAqL1xuICBkaXN0YW5jZUZuPzogRGlzdGFuY2VGbjtcbiAgLyoqXG4gICAqIFRoZSBpbml0aWFsIGxlYXJuaW5nIHJhdGUgZm9yIHRoZSBlbWJlZGRpbmcgb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgbGVhcm5pbmdSYXRlPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGxvY2FsIGNvbm5lY3Rpdml0eSByZXF1aXJlZCAtLSBpLmUuIHRoZSBudW1iZXIgb2YgbmVhcmVzdFxuICAgKiBuZWlnaGJvcnMgdGhhdCBzaG91bGQgYmUgYXNzdW1lZCB0byBiZSBjb25uZWN0ZWQgYXQgYSBsb2NhbCBsZXZlbC5cbiAgICogVGhlIGhpZ2hlciB0aGlzIHZhbHVlIHRoZSBtb3JlIGNvbm5lY3RlZCB0aGUgbWFuaWZvbGQgYmVjb21lc1xuICAgKiBsb2NhbGx5LiBJbiBwcmFjdGljZSB0aGlzIHNob3VsZCBiZSBub3QgbW9yZSB0aGFuIHRoZSBsb2NhbCBpbnRyaW5zaWNcbiAgICogZGltZW5zaW9uIG9mIHRoZSBtYW5pZm9sZC5cbiAgICovXG4gIGxvY2FsQ29ubmVjdGl2aXR5PzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGVmZmVjdGl2ZSBtaW5pbXVtIGRpc3RhbmNlIGJldHdlZW4gZW1iZWRkZWQgcG9pbnRzLiBTbWFsbGVyIHZhbHVlc1xuICAgKiB3aWxsIHJlc3VsdCBpbiBhIG1vcmUgY2x1c3RlcmVkL2NsdW1wZWQgZW1iZWRkaW5nIHdoZXJlIG5lYXJieSBwb2ludHNcbiAgICogb24gdGhlIG1hbmlmb2xkIGFyZSBkcmF3biBjbG9zZXIgdG9nZXRoZXIsIHdoaWxlIGxhcmdlciB2YWx1ZXMgd2lsbFxuICAgKiByZXN1bHQgb24gYSBtb3JlIGV2ZW4gZGlzcGVyc2FsIG9mIHBvaW50cy4gVGhlIHZhbHVlIHNob3VsZCBiZSBzZXRcbiAgICogcmVsYXRpdmUgdG8gdGhlIGBgc3ByZWFkYGAgdmFsdWUsIHdoaWNoIGRldGVybWluZXMgdGhlIHNjYWxlIGF0IHdoaWNoXG4gICAqIGVtYmVkZGVkIHBvaW50cyB3aWxsIGJlIHNwcmVhZCBvdXQuXG4gICAqL1xuICBtaW5EaXN0PzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGRpbWVuc2lvbiBvZiB0aGUgc3BhY2UgdG8gZW1iZWQgaW50by4gVGhpcyBkZWZhdWx0cyB0byAyIHRvXG4gICAqIHByb3ZpZGUgZWFzeSB2aXN1YWxpemF0aW9uLCBidXQgY2FuIHJlYXNvbmFibHkgYmUgc2V0IHRvIGFueVxuICAgKiBpbnRlZ2VyIHZhbHVlIGluIHRoZSByYW5nZSAyIHRvIDEwMC5cbiAgICovXG4gIG5Db21wb25lbnRzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiB0cmFpbmluZyBlcG9jaHMgdG8gYmUgdXNlZCBpbiBvcHRpbWl6aW5nIHRoZVxuICAgKiBsb3cgZGltZW5zaW9uYWwgZW1iZWRkaW5nLiBMYXJnZXIgdmFsdWVzIHJlc3VsdCBpbiBtb3JlIGFjY3VyYXRlXG4gICAqIGVtYmVkZGluZ3MuIElmIE5vbmUgaXMgc3BlY2lmaWVkIGEgdmFsdWUgd2lsbCBiZSBzZWxlY3RlZCBiYXNlZCBvblxuICAgKiB0aGUgc2l6ZSBvZiB0aGUgaW5wdXQgZGF0YXNldCAoMjAwIGZvciBsYXJnZSBkYXRhc2V0cywgNTAwIGZvciBzbWFsbCkuXG4gICAqL1xuICBuRXBvY2hzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIHNpemUgb2YgbG9jYWwgbmVpZ2hib3Job29kIChpbiB0ZXJtcyBvZiBudW1iZXIgb2YgbmVpZ2hib3JpbmdcbiAgICogc2FtcGxlIHBvaW50cykgdXNlZCBmb3IgbWFuaWZvbGQgYXBwcm94aW1hdGlvbi4gTGFyZ2VyIHZhbHVlc1xuICAgKiByZXN1bHQgaW4gbW9yZSBnbG9iYWwgdmlld3Mgb2YgdGhlIG1hbmlmb2xkLCB3aGlsZSBzbWFsbGVyXG4gICAqIHZhbHVlcyByZXN1bHQgaW4gbW9yZSBsb2NhbCBkYXRhIGJlaW5nIHByZXNlcnZlZC4gSW4gZ2VuZXJhbFxuICAgKiB2YWx1ZXMgc2hvdWxkIGJlIGluIHRoZSByYW5nZSAyIHRvIDEwMC5cbiAgICovXG4gIG5OZWlnaGJvcnM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIG5lZ2F0aXZlIHNhbXBsZXMgdG8gc2VsZWN0IHBlciBwb3NpdGl2ZSBzYW1wbGVcbiAgICogaW4gdGhlIG9wdGltaXphdGlvbiBwcm9jZXNzLiBJbmNyZWFzaW5nIHRoaXMgdmFsdWUgd2lsbCByZXN1bHRcbiAgICogaW4gZ3JlYXRlciByZXB1bHNpdmUgZm9yY2UgYmVpbmcgYXBwbGllZCwgZ3JlYXRlciBvcHRpbWl6YXRpb25cbiAgICogY29zdCwgYnV0IHNsaWdodGx5IG1vcmUgYWNjdXJhY3kuXG4gICAqL1xuICBuZWdhdGl2ZVNhbXBsZVJhdGU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBXZWlnaHRpbmcgYXBwbGllZCB0byBuZWdhdGl2ZSBzYW1wbGVzIGluIGxvdyBkaW1lbnNpb25hbCBlbWJlZGRpbmdcbiAgICogb3B0aW1pemF0aW9uLiBWYWx1ZXMgaGlnaGVyIHRoYW4gb25lIHdpbGwgcmVzdWx0IGluIGdyZWF0ZXIgd2VpZ2h0XG4gICAqIGJlaW5nIGdpdmVuIHRvIG5lZ2F0aXZlIHNhbXBsZXMuXG4gICAqL1xuICByZXB1bHNpb25TdHJlbmd0aD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdXNlZCBieSB0aGUgc3RvY2hhc3RpYyBwYXJ0cyBvZiB0aGVcbiAgICogYWxnb3JpdGhtLlxuICAgKi9cbiAgcmFuZG9tPzogUmFuZG9tRm47XG4gIC8qKlxuICAgKiBJbnRlcnBvbGF0ZSBiZXR3ZWVuIChmdXp6eSkgdW5pb24gYW5kIGludGVyc2VjdGlvbiBhcyB0aGUgc2V0IG9wZXJhdGlvblxuICAgKiB1c2VkIHRvIGNvbWJpbmUgbG9jYWwgZnV6enkgc2ltcGxpY2lhbCBzZXRzIHRvIG9idGFpbiBhIGdsb2JhbCBmdXp6eVxuICAgKiBzaW1wbGljaWFsIHNldHMuIEJvdGggZnV6enkgc2V0IG9wZXJhdGlvbnMgdXNlIHRoZSBwcm9kdWN0IHQtbm9ybS5cbiAgICogVGhlIHZhbHVlIG9mIHRoaXMgcGFyYW1ldGVyIHNob3VsZCBiZSBiZXR3ZWVuIDAuMCBhbmQgMS4wOyBhIHZhbHVlIG9mXG4gICAqIDEuMCB3aWxsIHVzZSBhIHB1cmUgZnV6enkgdW5pb24sIHdoaWxlIDAuMCB3aWxsIHVzZSBhIHB1cmUgZnV6enlcbiAgICogaW50ZXJzZWN0aW9uLlxuICAgKi9cbiAgc2V0T3BNaXhSYXRpbz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBlZmZlY3RpdmUgc2NhbGUgb2YgZW1iZWRkZWQgcG9pbnRzLiBJbiBjb21iaW5hdGlvbiB3aXRoIGBgbWluX2Rpc3RgYFxuICAgKiB0aGlzIGRldGVybWluZXMgaG93IGNsdXN0ZXJlZC9jbHVtcGVkIHRoZSBlbWJlZGRlZCBwb2ludHMgYXJlLlxuICAgKi9cbiAgc3ByZWFkPzogbnVtYmVyO1xuICAvKipcbiAgICogRm9yIHRyYW5zZm9ybSBvcGVyYXRpb25zIChlbWJlZGRpbmcgbmV3IHBvaW50cyB1c2luZyBhIHRyYWluZWQgbW9kZWwpXG4gICAqIHRoaXMgd2lsbCBjb250cm9sIGhvdyBhZ2dyZXNzaXZlbHkgdG8gc2VhcmNoIGZvciBuZWFyZXN0IG5laWdoYm9ycy5cbiAgICogTGFyZ2VyIHZhbHVlcyB3aWxsIHJlc3VsdCBpbiBzbG93ZXIgcGVyZm9ybWFuY2UgYnV0IG1vcmUgYWNjdXJhdGVcbiAgICogbmVhcmVzdCBuZWlnaGJvciBldmFsdWF0aW9uLlxuICAgKi9cbiAgdHJhbnNmb3JtUXVldWVTaXplPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVNQVBTdXBlcnZpc2VkUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBtZXRyaWMgdXNlZCB0byBtZWFzdXJlIGRpc3RhbmNlIGZvciBhIHRhcmdldCBhcnJheSBpcyB1c2luZyBzdXBlcnZpc2VkXG4gICAqIGRpbWVuc2lvbiByZWR1Y3Rpb24uIEJ5IGRlZmF1bHQgdGhpcyBpcyAnY2F0ZWdvcmljYWwnIHdoaWNoIHdpbGwgbWVhc3VyZVxuICAgKiBkaXN0YW5jZSBpbiB0ZXJtcyBvZiB3aGV0aGVyIGNhdGVnb3JpZXMgbWF0Y2ggb3IgYXJlIGRpZmZlcmVudC4gRnVydGhlcm1vcmUsXG4gICAqIGlmIHNlbWktc3VwZXJ2aXNlZCBpcyByZXF1aXJlZCB0YXJnZXQgdmFsdWVzIG9mIC0xIHdpbGwgYmUgdHJlYXRlZCBhc1xuICAgKiB1bmxhYmVsbGVkIHVuZGVyIHRoZSAnY2F0ZWdvcmljYWwnIG1ldHJpYy4gSWYgdGhlIHRhcmdldCBhcnJheSB0YWtlc1xuICAgKiBjb250aW51b3VzIHZhbHVlcyAoZS5nLiBmb3IgYSByZWdyZXNzaW9uIHByb2JsZW0pIHRoZW4gbWV0cmljIG9mICdsMSdcbiAgICogb3IgJ2wyJyBpcyBwcm9iYWJseSBtb3JlIGFwcHJvcHJpYXRlLlxuICAgKi9cbiAgdGFyZ2V0TWV0cmljPzogVGFyZ2V0TWV0cmljO1xuICAvKipcbiAgICogV2VpZ2h0aW5nIGZhY3RvciBiZXR3ZWVuIGRhdGEgdG9wb2xvZ3kgYW5kIHRhcmdldCB0b3BvbG9neS4gQSB2YWx1ZSBvZlxuICAgKiAwLjAgd2VpZ2h0cyBlbnRpcmVseSBvbiBkYXRhLCBhIHZhbHVlIG9mIDEuMCB3ZWlnaHRzIGVudGlyZWx5IG9uIHRhcmdldC5cbiAgICogVGhlIGRlZmF1bHQgb2YgMC41IGJhbGFuY2VzIHRoZSB3ZWlnaHRpbmcgZXF1YWxseSBiZXR3ZWVuIGRhdGEgYW5kIHRhcmdldC5cbiAgICovXG4gIHRhcmdldFdlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgbmVhcmVzdCBuZWlnaGJvcnMgdG8gdXNlIHRvIGNvbnN0cnVjdCB0aGUgdGFyZ2V0IHNpbXBsY2lhbFxuICAgKiBzZXQuIERlZmF1bHRzIHRvIHRoZSBgbmVhcmVzdE5laWdoYm9yc2AgcGFyYW1ldGVyLlxuICAgKi9cbiAgdGFyZ2V0Tk5laWdoYm9ycz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBVTUFQIHByb2plY3Rpb24gc3lzdGVtLCBiYXNlZCBvbiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZyb20gTWNJbm5lcywgTCxcbiAqIEhlYWx5LCBKLCBVTUFQOiBVbmlmb3JtIE1hbmlmb2xkIEFwcHJveGltYXRpb24gYW5kIFByb2plY3Rpb24gZm9yIERpbWVuc2lvblxuICogUmVkdWN0aW9uIChodHRwczovL2dpdGh1Yi5jb20vbG1jaW5uZXMvdW1hcCkuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBkaWZmZXJzIGluIGEgZmV3IHJlZ2FyZHM6XG4gKiBhKSBUaGUgaW5pdGlhbGl6YXRpb24gb2YgdGhlIGVtYmVkZGluZyBmb3Igb3B0aW1pemF0aW9uIGlzIG5vdCBjb21wdXRlZCB1c2luZ1xuICogICAgYSBzcGVjdHJhbCBtZXRob2QsIHJhdGhlciBpdCBpcyBpbml0aWFsaXplZCByYW5kb21seS4gVGhpcyBhdm9pZHMgc29tZVxuICogICAgY29tcHV0YXRpb25hbGx5IGludGVuc2l2ZSBtYXRyaXggZWlnZW4gY29tcHV0YXRpb25zIHRoYXQgYXJlbid0IGVhc2lseVxuICogICAgcG9ydGVkIHRvIEphdmFTY3JpcHQuXG4gKiBiKSBBIGxvdCBvZiBcImV4dHJhXCIgZnVuY3Rpb25hbGl0eSBoYXMgYmVlbiBvbWl0dGVkIGZyb20gdGhpcyBpbXBsZW1lbnRhdGlvbixcbiAqICAgIG1vc3Qgbm90YWJseSBhIGdyZWF0IGRlYWwgb2YgYWx0ZXJuYXRlIGRpc3RhbmNlIGZ1bmN0aW9ucy5cbiAqXG4gKiBUaGlzIGltcGxlbWVudGF0aW9uIHByb3ZpZGVzIHRocmVlIG1ldGhvZHMgb2YgcmVkdWNpbmcgZGltZW5zaW9uYWxpdHk6XG4gKiAxKSBmaXQ6IGZpdCB0aGUgZGF0YSBzeW5jaHJvbm91c2x5XG4gKiAyKSBmaXRBc3luYzogZml0IHRoZSBkYXRhIGFzeW5jaHJvbm91c2x5LCB3aXRoIGEgY2FsbGJhY2sgZnVuY3Rpb24gcHJvdmlkZWRcbiAqICAgICAgdGhhdCBpcyBpbnZva2VkIG9uIGVhY2ggb3B0aW1pemF0aW9uIHN0ZXAuXG4gKiAzKSBpbml0aWFsaXplRml0IC8gc3RlcDogbWFudWFsbHkgaW5pdGlhbGl6ZSB0aGUgYWxnb3JpdGhtIHRoZW4gZXhwbGljdGx5XG4gKiAgICAgIHN0ZXAgdGhyb3VnaCBlYWNoIGVwb2NoIG9mIHRoZSBTR0Qgb3B0aW1pemF0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBVTUFQIHtcbiAgcHVibGljIGxlYXJuaW5nUmF0ZSA9IDEuMDtcbiAgcHVibGljIGxvY2FsQ29ubmVjdGl2aXR5ID0gMS4wO1xuICBwdWJsaWMgbWluRGlzdCA9IDAuMTtcbiAgcHVibGljIG5Db21wb25lbnRzID0gMjtcbiAgcHJpdmF0ZSBuRXBvY2hzID0gMDtcbiAgcHJpdmF0ZSBuTmVpZ2hib3JzID0gMTU7XG4gIHB1YmxpYyBuZWdhdGl2ZVNhbXBsZVJhdGUgPSA1O1xuICBwdWJsaWMgcmFuZG9tID0gTWF0aC5yYW5kb207XG4gIHB1YmxpYyByZXB1bHNpb25TdHJlbmd0aCA9IDEuMDtcbiAgcHVibGljIHNldE9wTWl4UmF0aW8gPSAxLjA7XG4gIHB1YmxpYyBzcHJlYWQgPSAxLjA7XG4gIHByaXZhdGUgdHJhbnNmb3JtUXVldWVTaXplID0gNC4wO1xuXG4gIC8vIFN1cGVydmlzZWQgcHJvamVjdGlvbiBwYXJhbXNcbiAgcHJpdmF0ZSB0YXJnZXRNZXRyaWMgPSBUYXJnZXRNZXRyaWMuY2F0ZWdvcmljYWw7XG4gIHByaXZhdGUgdGFyZ2V0V2VpZ2h0ID0gMC41O1xuICBwcml2YXRlIHRhcmdldE5OZWlnaGJvcnMgPSAxNTtcblxuICBwcml2YXRlIGRpc3RhbmNlRm46IERpc3RhbmNlRm4gPSBudW1lcmljO1xuXG4gIC8vIEtOTiBzdGF0ZSAoY2FuIGJlIHByZWNvbXB1dGVkIGFuZCBzdXBwbGllZCB2aWEgaW5pdGlhbGl6ZUZpdClcbiAgcHJpdmF0ZSBrbm5JbmRpY2VzPzogbnVtYmVyW11bXTtcbiAgcHJpdmF0ZSBrbm5EaXN0YW5jZXM/OiBudW1iZXJbXVtdO1xuXG4gIC8vIEludGVybmFsIGdyYXBoIGNvbm5lY3Rpdml0eSByZXByZXNlbnRhdGlvblxuICBwcml2YXRlIGdyYXBoITogbWF0cml4LlNwYXJzZU1hdHJpeDtcbiAgcHJpdmF0ZSBYITogVmVjdG9yO1xuICBwcml2YXRlIGlzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBycEZvcmVzdDogdHJlZS5GbGF0VHJlZVtdID0gW107XG4gIHByaXZhdGUgaW5pdEZyb21SYW5kb20hOiBubkRlc2NlbnQuSW5pdEZyb21SYW5kb21GbjtcbiAgcHJpdmF0ZSBpbml0RnJvbVRyZWUhOiBubkRlc2NlbnQuSW5pdEZyb21UcmVlRm47XG4gIHByaXZhdGUgc2VhcmNoITogbm5EZXNjZW50LlNlYXJjaEZuO1xuICBwcml2YXRlIHNlYXJjaEdyYXBoITogbWF0cml4LlNwYXJzZU1hdHJpeDtcblxuICAvLyBTdXBlcnZpc2VkIHByb2plY3Rpb24gbGFiZWxzIC8gdGFyZ2V0c1xuICBwcml2YXRlIFk/OiBudW1iZXJbXTtcblxuICAvLyBQcm9qZWN0ZWQgZW1iZWRkaW5nXG4gIHByaXZhdGUgZW1iZWRkaW5nOiBudW1iZXJbXVtdID0gW107XG4gIHByaXZhdGUgb3B0aW1pemF0aW9uU3RhdGUgPSBuZXcgT3B0aW1pemF0aW9uU3RhdGUoKTtcblxuXG4gIGdldCBuZWlnaGJvcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMubk5laWdoYm9ycztcbiAgfVxuICBjb25zdHJ1Y3RvcihwYXJhbXM6IFVNQVBQYXJhbWV0ZXJzID0ge30pIHtcbiAgICBjb25zdCBzZXRQYXJhbSA9IChrZXk6IGtleW9mIFVNQVBQYXJhbWV0ZXJzKSA9PiB7XG4gICAgICAvL0B0cy1pZ25vcmVcbiAgICAgIGlmIChwYXJhbXNba2V5XSAhPT0gdW5kZWZpbmVkKSB0aGlzW2tleV0gPSBwYXJhbXNba2V5XTtcbiAgICB9O1xuXG4gICAgc2V0UGFyYW0oJ2Rpc3RhbmNlRm4nKTtcbiAgICBzZXRQYXJhbSgnbGVhcm5pbmdSYXRlJyk7XG4gICAgc2V0UGFyYW0oJ2xvY2FsQ29ubmVjdGl2aXR5Jyk7XG4gICAgc2V0UGFyYW0oJ21pbkRpc3QnKTtcbiAgICBzZXRQYXJhbSgnbkNvbXBvbmVudHMnKTtcbiAgICBzZXRQYXJhbSgnbkVwb2NocycpO1xuICAgIHNldFBhcmFtKCduTmVpZ2hib3JzJyk7XG4gICAgc2V0UGFyYW0oJ25lZ2F0aXZlU2FtcGxlUmF0ZScpO1xuICAgIHNldFBhcmFtKCdyYW5kb20nKTtcbiAgICBzZXRQYXJhbSgncmVwdWxzaW9uU3RyZW5ndGgnKTtcbiAgICBzZXRQYXJhbSgnc2V0T3BNaXhSYXRpbycpO1xuICAgIHNldFBhcmFtKCdzcHJlYWQnKTtcbiAgICBzZXRQYXJhbSgndHJhbnNmb3JtUXVldWVTaXplJyk7XG4gICAgdGhpcy50YXJnZXROTmVpZ2hib3JzID0gcGFyYW1zLm5OZWlnaGJvcnMgfHwgdGhpcy5uTmVpZ2hib3JzIHx8IHRoaXMudGFyZ2V0Tk5laWdoYm9ycztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIHN5bmNocm9ub3VzbHkuXG4gICAqL1xuICBmaXQoWDogVmVjdG9yKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuICAgIHRoaXMub3B0aW1pemVMYXlvdXQoKTtcblxuICAgIHJldHVybiB0aGlzLmVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIGFzeW5jaHJvbm91c2x5LCB3aXRoIGEgY2FsbGJhY2tcbiAgICogZnVuY3Rpb24gaW52b2tlZCBvbiBldmVyeSBlcG9jaCBvZiBvcHRpbWl6YXRpb24uXG4gICAqL1xuICBhc3luYyBmaXRBc3luYyhcbiAgICBYOiBWZWN0b3IsXG4gICAgY2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuXG4gICAgYXdhaXQgdGhpcy5vcHRpbWl6ZUxheW91dEFzeW5jKGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy5lbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgcGFyYW1ldGVycyBuZWVkZWQgZm9yIHN1cGVydmlzZWQgcHJvamVjdGlvbi5cbiAgICovXG4gIHNldFN1cGVydmlzZWRQcm9qZWN0aW9uKFk6IG51bWJlcltdLCBwYXJhbXM6IFVNQVBTdXBlcnZpc2VkUGFyYW1zID0ge30pIHtcbiAgICB0aGlzLlkgPSBZO1xuICAgIHRoaXMudGFyZ2V0TWV0cmljID0gcGFyYW1zLnRhcmdldE1ldHJpYyB8fCB0aGlzLnRhcmdldE1ldHJpYztcbiAgICB0aGlzLnRhcmdldFdlaWdodCA9IHBhcmFtcy50YXJnZXRXZWlnaHQgfHwgdGhpcy50YXJnZXRXZWlnaHQ7XG4gICAgdGhpcy50YXJnZXROTmVpZ2hib3JzID0gcGFyYW1zLnRhcmdldE5OZWlnaGJvcnMgfHwgdGhpcy50YXJnZXROTmVpZ2hib3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHVtYXAgd2l0aCBwcmVjb21wdXRlZCBLTk4gaW5kaWNlcyBhbmQgZGlzdGFuY2VzLlxuICAgKi9cbiAgc2V0UHJlY29tcHV0ZWRLTk4oa25uSW5kaWNlczogbnVtYmVyW11bXSwga25uRGlzdGFuY2VzOiBudW1iZXJbXVtdKSB7XG4gICAgdGhpcy5rbm5JbmRpY2VzID0ga25uSW5kaWNlcztcbiAgICB0aGlzLmtubkRpc3RhbmNlcyA9IGtubkRpc3RhbmNlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBmaXQgYnkgY29tcHV0aW5nIEtOTiBhbmQgYSBmdXp6eSBzaW1wbGljaWFsIHNldCwgYXMgd2VsbCBhc1xuICAgKiBpbml0aWFsaXppbmcgdGhlIHByb2plY3RlZCBlbWJlZGRpbmdzLiBTZXRzIHRoZSBvcHRpbWl6YXRpb24gc3RhdGUgYWhlYWRcbiAgICogb2Ygb3B0aW1pemF0aW9uIHN0ZXBzLiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZXBvY2hzIHRvIGJlIHVzZWQgZm9yIHRoZVxuICAgKiBTR0Qgb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgaW5pdGlhbGl6ZUZpdChYOiBWZWN0b3IpOiBudW1iZXIge1xuICAgIGlmIChYLmxlbmd0aCA8PSB0aGlzLm5OZWlnaGJvcnMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBlbm91Z2ggZGF0YSBwb2ludHMgKCR7WC5sZW5ndGh9KSB0byBjcmVhdGUgbk5laWdoYm9yczogJHt0aGlzLm5OZWlnaGJvcnN9LiAgQWRkIG1vcmUgZGF0YSBwb2ludHMgb3IgYWRqdXN0IHRoZSBjb25maWd1cmF0aW9uLmApO1xuXG5cbiAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJlaW5pdGlhbGl6ZSBpZiB3ZSd2ZSBhbHJlYWR5IGluaXRpYWxpemVkIGZvciB0aGlzIGRhdGEuXG4gICAgaWYgKHRoaXMuWCA9PT0gWCAmJiB0aGlzLmlzSW5pdGlhbGl6ZWQpXG4gICAgICByZXR1cm4gdGhpcy5nZXRORXBvY2hzKCk7XG5cblxuICAgIHRoaXMuWCA9IFg7XG5cbiAgICBpZiAoIXRoaXMua25uSW5kaWNlcyAmJiAhdGhpcy5rbm5EaXN0YW5jZXMpIHtcbiAgICAgIGNvbnN0IGtublJlc3VsdHMgPSB0aGlzLm5lYXJlc3ROZWlnaGJvcnMoWCk7XG4gICAgICB0aGlzLmtubkluZGljZXMgPSBrbm5SZXN1bHRzLmtubkluZGljZXM7XG4gICAgICB0aGlzLmtubkRpc3RhbmNlcyA9IGtublJlc3VsdHMua25uRGlzdGFuY2VzO1xuICAgIH1cblxuICAgIHRoaXMuZ3JhcGggPSB0aGlzLmZ1enp5U2ltcGxpY2lhbFNldChcbiAgICAgIFgsXG4gICAgICB0aGlzLm5OZWlnaGJvcnMsXG4gICAgICB0aGlzLnNldE9wTWl4UmF0aW9cbiAgICApO1xuXG4gICAgLy8gU2V0IHVwIHRoZSBzZWFyY2ggZ3JhcGggZm9yIHN1YnNlcXVlbnQgdHJhbnNmb3JtYXRpb24uXG4gICAgdGhpcy5tYWtlU2VhcmNoRm5zKCk7XG4gICAgdGhpcy5zZWFyY2hHcmFwaCA9IHRoaXMubWFrZVNlYXJjaEdyYXBoKFgpO1xuXG4gICAgLy8gQ2hlY2sgaWYgc3VwZXJ2aXNlZCBwcm9qZWN0aW9uLCB0aGVuIGFkanVzdCB0aGUgZ3JhcGguXG4gICAgdGhpcy5wcm9jZXNzR3JhcGhGb3JTdXBlcnZpc2VkUHJvamVjdGlvbigpO1xuXG4gICAgY29uc3Qge1xuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgfSA9IHRoaXMuaW5pdGlhbGl6ZVNpbXBsaWNpYWxTZXRFbWJlZGRpbmcoKTtcblxuICAgIC8vIFNldCB0aGUgb3B0aW1pemF0aW9uIHJvdXRpbmUgc3RhdGVcbiAgICB0aGlzLm9wdGltaXphdGlvblN0YXRlLmhlYWQgPSBoZWFkO1xuICAgIHRoaXMub3B0aW1pemF0aW9uU3RhdGUudGFpbCA9IHRhaWw7XG4gICAgdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5lcG9jaHNQZXJTYW1wbGUgPSBlcG9jaHNQZXJTYW1wbGU7XG5cbiAgICAvLyBOb3csIGluaXRpYWxpemUgdGhlIG9wdGltaXphdGlvbiBzdGVwc1xuICAgIHRoaXMuaW5pdGlhbGl6ZU9wdGltaXphdGlvbigpO1xuICAgIHRoaXMucHJlcGFyZUZvck9wdGltaXphdGlvbkxvb3AoKTtcbiAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0TkVwb2NocygpO1xuICB9XG5cbiAgcHJpdmF0ZSBtYWtlU2VhcmNoRm5zKCkge1xuICAgIGNvbnN0IHtpbml0RnJvbVRyZWUsIGluaXRGcm9tUmFuZG9tfSA9IG5uRGVzY2VudC5tYWtlSW5pdGlhbGl6YXRpb25zKFxuICAgICAgdGhpcy5kaXN0YW5jZUZuXG4gICAgKTtcbiAgICB0aGlzLmluaXRGcm9tVHJlZSA9IGluaXRGcm9tVHJlZTtcbiAgICB0aGlzLmluaXRGcm9tUmFuZG9tID0gaW5pdEZyb21SYW5kb207XG4gICAgdGhpcy5zZWFyY2ggPSBubkRlc2NlbnQubWFrZUluaXRpYWxpemVkTk5TZWFyY2godGhpcy5kaXN0YW5jZUZuKTtcbiAgfVxuXG4gIHByaXZhdGUgbWFrZVNlYXJjaEdyYXBoKFg6IFZlY3Rvcikge1xuICAgIGNvbnN0IGtubkluZGljZXMgPSB0aGlzLmtubkluZGljZXMhO1xuICAgIGNvbnN0IGtubkRpc3RhbmNlcyA9IHRoaXMua25uRGlzdGFuY2VzITtcbiAgICBjb25zdCBkaW1zID0gW1gubGVuZ3RoLCBYLmxlbmd0aF07XG4gICAgY29uc3Qgc2VhcmNoR3JhcGggPSBuZXcgbWF0cml4LlNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBkaW1zKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtubkluZGljZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGtubiA9IGtubkluZGljZXNbaV07XG4gICAgICBjb25zdCBkaXN0YW5jZXMgPSBrbm5EaXN0YW5jZXNbaV07XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGtubi5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBuZWlnaGJvciA9IGtubltqXTtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBkaXN0YW5jZXNbal07XG4gICAgICAgIGlmIChkaXN0YW5jZSA+IDApXG4gICAgICAgICAgc2VhcmNoR3JhcGguc2V0KGksIG5laWdoYm9yLCBkaXN0YW5jZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdHJhbnNwb3NlID0gbWF0cml4LnRyYW5zcG9zZShzZWFyY2hHcmFwaCk7XG4gICAgcmV0dXJuIG1hdHJpeC5tYXhpbXVtKHNlYXJjaEdyYXBoLCB0cmFuc3Bvc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zZm9ybXMgZGF0YSB0byB0aGUgZXhpc3RpbmcgZW1iZWRkaW5nIHNwYWNlLlxuICAgKi9cbiAgdHJhbnNmb3JtKHRvVHJhbnNmb3JtOiBWZWN0b3IpIHtcbiAgICAvLyBVc2UgdGhlIHByZXZpb3VzIHJhd0RhdGFcbiAgICBjb25zdCByYXdEYXRhID0gdGhpcy5YO1xuICAgIGlmIChyYXdEYXRhID09PSB1bmRlZmluZWQgfHwgcmF3RGF0YS5sZW5ndGggPT09IDApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGRhdGEgaGFzIGJlZW4gZml0LicpO1xuXG5cbiAgICBsZXQgbk5laWdoYm9ycyA9IE1hdGguZmxvb3IodGhpcy5uTmVpZ2hib3JzICogdGhpcy50cmFuc2Zvcm1RdWV1ZVNpemUpO1xuICAgIG5OZWlnaGJvcnMgPSBNYXRoLm1pbihyYXdEYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG4gICAgY29uc3QgaW5pdCA9IG5uRGVzY2VudC5pbml0aWFsaXplU2VhcmNoKFxuICAgICAgdGhpcy5ycEZvcmVzdCxcbiAgICAgIHJhd0RhdGEsXG4gICAgICB0b1RyYW5zZm9ybSxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICB0aGlzLmluaXRGcm9tUmFuZG9tLFxuICAgICAgdGhpcy5pbml0RnJvbVRyZWUsXG4gICAgICB0aGlzLnJhbmRvbVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnNlYXJjaChyYXdEYXRhLCB0aGlzLnNlYXJjaEdyYXBoLCBpbml0LCB0b1RyYW5zZm9ybSk7XG5cbiAgICBsZXQge2luZGljZXMsIHdlaWdodHM6IGRpc3RhbmNlc30gPSBoZWFwLmRlaGVhcFNvcnQocmVzdWx0KTtcblxuICAgIGluZGljZXMgPSBpbmRpY2VzLm1hcCgoeCkgPT4geC5zbGljZSgwLCB0aGlzLm5OZWlnaGJvcnMpKTtcbiAgICBkaXN0YW5jZXMgPSBkaXN0YW5jZXMubWFwKCh4KSA9PiB4LnNsaWNlKDAsIHRoaXMubk5laWdoYm9ycykpO1xuXG4gICAgY29uc3QgYWRqdXN0ZWRMb2NhbENvbm5lY3Rpdml0eSA9IE1hdGgubWF4KDAsIHRoaXMubG9jYWxDb25uZWN0aXZpdHkgLSAxKTtcbiAgICBjb25zdCB7c2lnbWFzLCByaG9zfSA9IHRoaXMuc21vb3RoS05ORGlzdGFuY2UoXG4gICAgICBkaXN0YW5jZXMsXG4gICAgICB0aGlzLm5OZWlnaGJvcnMsXG4gICAgICBhZGp1c3RlZExvY2FsQ29ubmVjdGl2aXR5XG4gICAgKTtcblxuICAgIGNvbnN0IHtyb3dzLCBjb2xzLCB2YWxzfSA9IHRoaXMuY29tcHV0ZU1lbWJlcnNoaXBTdHJlbmd0aHMoXG4gICAgICBpbmRpY2VzLFxuICAgICAgZGlzdGFuY2VzLFxuICAgICAgc2lnbWFzLFxuICAgICAgcmhvc1xuICAgICk7XG5cbiAgICBjb25zdCBzaXplID0gW3RvVHJhbnNmb3JtLmxlbmd0aCwgcmF3RGF0YS5sZW5ndGhdO1xuICAgIGxldCBncmFwaCA9IG5ldyBtYXRyaXguU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIHNpemUpO1xuXG4gICAgLy8gVGhpcyB3YXMgYSB2ZXJ5IHNwZWNpYWxseSBjb25zdHJ1Y3RlZCBncmFwaCB3aXRoIGNvbnN0YW50IGRlZ3JlZS5cbiAgICAvLyBUaGF0IGxldHMgdXMgZG8gZmFuY3kgdW5wYWNraW5nIGJ5IHJlc2hhcGluZyB0aGUgY3NyIG1hdHJpeCBpbmRpY2VzXG4gICAgLy8gYW5kIGRhdGEuIERvaW5nIHNvIHJlbGllcyBvbiB0aGUgY29uc3RhbnQgZGVncmVlIGFzc3VtcHRpb24hXG5cbiAgICBjb25zdCBub3JtZWQgPSBtYXRyaXgubm9ybWFsaXplKGdyYXBoLCBtYXRyaXguTm9ybVR5cGUubDEpO1xuXG4gICAgY29uc3QgY3NyTWF0cml4ID0gbWF0cml4LmdldENTUihub3JtZWQpO1xuICAgIGNvbnN0IG5Qb2ludHMgPSB0b1RyYW5zZm9ybS5sZW5ndGg7XG5cbiAgICBjb25zdCBlSW5kaWNlcyA9IHV0aWxzLnJlc2hhcGUyZChcbiAgICAgIGNzck1hdHJpeC5pbmRpY2VzLFxuICAgICAgblBvaW50cyxcbiAgICAgIHRoaXMubk5laWdoYm9yc1xuICAgICk7XG5cbiAgICBjb25zdCBlV2VpZ2h0cyA9IHV0aWxzLnJlc2hhcGUyZChcbiAgICAgIGNzck1hdHJpeC52YWx1ZXMsXG4gICAgICBuUG9pbnRzLFxuICAgICAgdGhpcy5uTmVpZ2hib3JzXG4gICAgKTtcblxuICAgIGNvbnN0IGVtYmVkZGluZyA9IGluaXRUcmFuc2Zvcm0oZUluZGljZXMsIGVXZWlnaHRzLCB0aGlzLmVtYmVkZGluZyk7XG5cbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5uRXBvY2hzID9cbiAgICAgIHRoaXMubkVwb2NocyAvIDMgOlxuICAgICAgZ3JhcGgublJvd3MgPD0gMTAwMDAgP1xuICAgICAgICAxMDAgOlxuICAgICAgICAzMDtcblxuICAgIGNvbnN0IGdyYXBoTWF4ID0gZ3JhcGhcbiAgICAgIC5nZXRWYWx1ZXMoKVxuICAgICAgLnJlZHVjZSgobWF4LCB2YWwpID0+ICh2YWwgPiBtYXggPyB2YWwgOiBtYXgpLCAwKTtcbiAgICBncmFwaCA9IGdyYXBoLm1hcCgodmFsdWUpID0+ICh2YWx1ZSA8IGdyYXBoTWF4IC8gbkVwb2NocyA/IDAgOiB2YWx1ZSkpO1xuICAgIGdyYXBoID0gbWF0cml4LmVsaW1pbmF0ZVplcm9zKGdyYXBoKTtcblxuICAgIGNvbnN0IGVwb2Noc1BlclNhbXBsZSA9IHRoaXMubWFrZUVwb2Noc1BlclNhbXBsZShcbiAgICAgIGdyYXBoLmdldFZhbHVlcygpLFxuICAgICAgbkVwb2Noc1xuICAgICk7XG4gICAgY29uc3QgaGVhZCA9IGdyYXBoLmdldFJvd3MoKTtcbiAgICBjb25zdCB0YWlsID0gZ3JhcGguZ2V0Q29scygpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBvcHRpbWl6YXRpb24gc2xpZ2h0bHkgZGlmZmVyZW50bHkgdGhhbiB0aGUgZml0IG1ldGhvZC5cbiAgICB0aGlzLmFzc2lnbk9wdGltaXphdGlvblN0YXRlUGFyYW1ldGVycyh7XG4gICAgICBoZWFkRW1iZWRkaW5nOiBlbWJlZGRpbmcsXG4gICAgICB0YWlsRW1iZWRkaW5nOiB0aGlzLmVtYmVkZGluZyxcbiAgICAgIGhlYWQsXG4gICAgICB0YWlsLFxuICAgICAgY3VycmVudEVwb2NoOiAwLFxuICAgICAgbkVwb2NocyxcbiAgICAgIG5WZXJ0aWNlczogZ3JhcGguZ2V0RGltcygpWzFdLFxuICAgICAgZXBvY2hzUGVyU2FtcGxlLFxuICAgIH0pO1xuICAgIHRoaXMucHJlcGFyZUZvck9wdGltaXphdGlvbkxvb3AoKTtcblxuICAgIHJldHVybiB0aGlzLm9wdGltaXplTGF5b3V0KCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHdlJ3JlIHVzaW5nIHN1cGVydmlzZWQgcHJvamVjdGlvbiwgdGhlbiBwcm9jZXNzIHRoZSBncmFwaFxuICAgKiBhY2NvcmRpbmdseS5cbiAgICovXG4gIHByaXZhdGUgcHJvY2Vzc0dyYXBoRm9yU3VwZXJ2aXNlZFByb2plY3Rpb24oKSB7XG4gICAgY29uc3Qge1ksIFh9ID0gdGhpcztcbiAgICBpZiAoWSkge1xuICAgICAgaWYgKFkubGVuZ3RoICE9PSBYLmxlbmd0aClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggb2YgWCBhbmQgeSBtdXN0IGJlIGVxdWFsJyk7XG5cblxuICAgICAgaWYgKHRoaXMudGFyZ2V0TWV0cmljID09PSBUYXJnZXRNZXRyaWMuY2F0ZWdvcmljYWwpIHtcbiAgICAgICAgY29uc3QgbHQgPSB0aGlzLnRhcmdldFdlaWdodCA8IDEuMDtcbiAgICAgICAgY29uc3QgZmFyRGlzdCA9IGx0ID8gMi41ICogKDEuMCAvICgxLjAgLSB0aGlzLnRhcmdldFdlaWdodCkpIDogMS4wZTEyO1xuICAgICAgICB0aGlzLmdyYXBoID0gdGhpcy5jYXRlZ29yaWNhbFNpbXBsaWNpYWxTZXRJbnRlcnNlY3Rpb24oXG4gICAgICAgICAgdGhpcy5ncmFwaCxcbiAgICAgICAgICBZLFxuICAgICAgICAgIGZhckRpc3RcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIFRPRE8gKGFuZHljb2VuZW5AKTogYWRkIG5vbi1jYXRlZ29yaWNhbCBzdXBlcnZpc2VkIGVtYmVkZGluZ3MuXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1hbnVhbGx5IHN0ZXAgdGhyb3VnaCB0aGUgb3B0aW1pemF0aW9uIHByb2Nlc3Mgb25lIGVwb2NoIGF0IGEgdGltZS5cbiAgICovXG4gIHN0ZXAoKSB7XG4gICAgY29uc3Qge2N1cnJlbnRFcG9jaH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuXG4gICAgaWYgKGN1cnJlbnRFcG9jaCA8IHRoaXMuZ2V0TkVwb2NocygpKVxuICAgICAgdGhpcy5vcHRpbWl6ZUxheW91dFN0ZXAoY3VycmVudEVwb2NoKTtcblxuICAgIHJldHVybiB0aGlzLm9wdGltaXphdGlvblN0YXRlLmN1cnJlbnRFcG9jaDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb21wdXRlZCBwcm9qZWN0ZWQgZW1iZWRkaW5nLlxuICAgKi9cbiAgZ2V0RW1iZWRkaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIHRoZSBgYG5OZWlnaGJvcnNgYCBuZWFyZXN0IHBvaW50cyBmb3IgZWFjaCBkYXRhIHBvaW50IGluIGBgWGBgXG4gICAqIFRoaXMgbWF5IGJlIGV4YWN0LCBidXQgbW9yZSBsaWtlbHkgaXMgYXBwcm94aW1hdGVkIHZpYSBuZWFyZXN0IG5laWdoYm9yXG4gICAqIGRlc2NlbnQuXG4gICAqL1xuICBwcml2YXRlIG5lYXJlc3ROZWlnaGJvcnMoWDogVmVjdG9yKSB7XG4gICAgY29uc3Qge2Rpc3RhbmNlRm4sIG5OZWlnaGJvcnN9ID0gdGhpcztcbiAgICBjb25zdCBsb2cyID0gKG46IG51bWJlcikgPT4gTWF0aC5sb2cobikgLyBNYXRoLmxvZygyKTtcbiAgICBjb25zdCBtZXRyaWNOTkRlc2NlbnQgPSBubkRlc2NlbnQubWFrZU5ORGVzY2VudChkaXN0YW5jZUZuLCB0aGlzLnJhbmRvbSk7XG5cbiAgICAvLyBIYW5kbGUgcHl0aG9uMyByb3VuZGluZyBkb3duIGZyb20gMC41IGRpc2NycGFuY3lcbiAgICBjb25zdCByb3VuZCA9IChuOiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBuID09PSAwLjUgPyAwIDogTWF0aC5yb3VuZChuKTtcbiAgICB9O1xuXG4gICAgY29uc3QgblRyZWVzID0gNSArIE1hdGguZmxvb3Iocm91bmQoWC5sZW5ndGggKiogMC41IC8gMjAuMCkpO1xuICAgIGNvbnN0IG5JdGVycyA9IE1hdGgubWF4KDUsIE1hdGguZmxvb3IoTWF0aC5yb3VuZChsb2cyKFgubGVuZ3RoKSkpKTtcblxuICAgIHRoaXMucnBGb3Jlc3QgPSB0cmVlLm1ha2VGb3Jlc3QoWCwgbk5laWdoYm9ycywgblRyZWVzLCB0aGlzLnJhbmRvbSk7XG5cbiAgICBjb25zdCBsZWFmQXJyYXkgPSB0cmVlLm1ha2VMZWFmQXJyYXkodGhpcy5ycEZvcmVzdCk7XG4gICAgY29uc3Qge2luZGljZXMsIHdlaWdodHN9ID0gbWV0cmljTk5EZXNjZW50KFxuICAgICAgWCxcbiAgICAgIGxlYWZBcnJheSxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICBuSXRlcnNcbiAgICApO1xuICAgIHJldHVybiB7a25uSW5kaWNlczogaW5kaWNlcywga25uRGlzdGFuY2VzOiB3ZWlnaHRzfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHNldCBvZiBkYXRhIFgsIGEgbmVpZ2hib3Job29kIHNpemUsIGFuZCBhIG1lYXN1cmUgb2YgZGlzdGFuY2VcbiAgICogY29tcHV0ZSB0aGUgZnV6enkgc2ltcGxpY2lhbCBzZXQgKGhlcmUgcmVwcmVzZW50ZWQgYXMgYSBmdXp6eSBncmFwaCBpblxuICAgKiB0aGUgZm9ybSBvZiBhIHNwYXJzZSBtYXRyaXgpIGFzc29jaWF0ZWQgdG8gdGhlIGRhdGEuIFRoaXMgaXMgZG9uZSBieVxuICAgKiBsb2NhbGx5IGFwcHJveGltYXRpbmcgZ2VvZGVzaWMgZGlzdGFuY2UgYXQgZWFjaCBwb2ludCwgY3JlYXRpbmcgYSBmdXp6eVxuICAgKiBzaW1wbGljaWFsIHNldCBmb3IgZWFjaCBzdWNoIHBvaW50LCBhbmQgdGhlbiBjb21iaW5pbmcgYWxsIHRoZSBsb2NhbFxuICAgKiBmdXp6eSBzaW1wbGljaWFsIHNldHMgaW50byBhIGdsb2JhbCBvbmUgdmlhIGEgZnV6enkgdW5pb24uXG4gICAqL1xuICBwcml2YXRlIGZ1enp5U2ltcGxpY2lhbFNldChcbiAgICBYOiBWZWN0b3IsXG4gICAgbk5laWdoYm9yczogbnVtYmVyLFxuICAgIHNldE9wTWl4UmF0aW8gPSAxLjBcbiAgKSB7XG4gICAgY29uc3Qge2tubkluZGljZXMgPSBbXSwga25uRGlzdGFuY2VzID0gW10sIGxvY2FsQ29ubmVjdGl2aXR5fSA9IHRoaXM7XG5cbiAgICBjb25zdCB7c2lnbWFzLCByaG9zfSA9IHRoaXMuc21vb3RoS05ORGlzdGFuY2UoXG4gICAgICBrbm5EaXN0YW5jZXMsXG4gICAgICBuTmVpZ2hib3JzLFxuICAgICAgbG9jYWxDb25uZWN0aXZpdHlcbiAgICApO1xuXG4gICAgY29uc3Qge3Jvd3MsIGNvbHMsIHZhbHN9ID0gdGhpcy5jb21wdXRlTWVtYmVyc2hpcFN0cmVuZ3RocyhcbiAgICAgIGtubkluZGljZXMsXG4gICAgICBrbm5EaXN0YW5jZXMsXG4gICAgICBzaWdtYXMsXG4gICAgICByaG9zXG4gICAgKTtcblxuICAgIGNvbnN0IHNpemUgPSBbWC5sZW5ndGgsIFgubGVuZ3RoXTtcbiAgICBjb25zdCBzcGFyc2VNYXRyaXggPSBuZXcgbWF0cml4LlNwYXJzZU1hdHJpeChyb3dzLCBjb2xzLCB2YWxzLCBzaXplKTtcblxuICAgIGNvbnN0IHRyYW5zcG9zZSA9IG1hdHJpeC50cmFuc3Bvc2Uoc3BhcnNlTWF0cml4KTtcbiAgICBjb25zdCBwcm9kTWF0cml4ID0gbWF0cml4LnBhaXJ3aXNlTXVsdGlwbHkoc3BhcnNlTWF0cml4LCB0cmFuc3Bvc2UpO1xuXG4gICAgY29uc3QgYSA9IG1hdHJpeC5zdWJ0cmFjdChtYXRyaXguYWRkKHNwYXJzZU1hdHJpeCwgdHJhbnNwb3NlKSwgcHJvZE1hdHJpeCk7XG4gICAgY29uc3QgYiA9IG1hdHJpeC5tdWx0aXBseVNjYWxhcihhLCBzZXRPcE1peFJhdGlvKTtcbiAgICBjb25zdCBjID0gbWF0cml4Lm11bHRpcGx5U2NhbGFyKHByb2RNYXRyaXgsIDEuMCAtIHNldE9wTWl4UmF0aW8pO1xuICAgIGNvbnN0IHJlc3VsdCA9IG1hdHJpeC5hZGQoYiwgYyk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbWJpbmUgYSBmdXp6eSBzaW1wbGljaWFsIHNldCB3aXRoIGFub3RoZXIgZnV6enkgc2ltcGxpY2lhbCBzZXRcbiAgICogZ2VuZXJhdGVkIGZyb20gY2F0ZWdvcmljYWwgZGF0YSB1c2luZyBjYXRlZ29yaWNhbCBkaXN0YW5jZXMuIFRoZSB0YXJnZXRcbiAgICogZGF0YSBpcyBhc3N1bWVkIHRvIGJlIGNhdGVnb3JpY2FsIGxhYmVsIGRhdGEgKGEgdmVjdG9yIG9mIGxhYmVscyksXG4gICAqIGFuZCB0aGlzIHdpbGwgdXBkYXRlIHRoZSBmdXp6eSBzaW1wbGljaWFsIHNldCB0byByZXNwZWN0IHRoYXQgbGFiZWwgZGF0YS5cbiAgICovXG4gIHByaXZhdGUgY2F0ZWdvcmljYWxTaW1wbGljaWFsU2V0SW50ZXJzZWN0aW9uKFxuICAgIHNpbXBsaWNpYWxTZXQ6IG1hdHJpeC5TcGFyc2VNYXRyaXgsXG4gICAgdGFyZ2V0OiBudW1iZXJbXSxcbiAgICBmYXJEaXN0OiBudW1iZXIsXG4gICAgdW5rbm93bkRpc3QgPSAxLjBcbiAgKSB7XG4gICAgbGV0IGludGVyc2VjdGlvbiA9IGZhc3RJbnRlcnNlY3Rpb24oXG4gICAgICBzaW1wbGljaWFsU2V0LFxuICAgICAgdGFyZ2V0LFxuICAgICAgdW5rbm93bkRpc3QsXG4gICAgICBmYXJEaXN0XG4gICAgKTtcbiAgICBpbnRlcnNlY3Rpb24gPSBtYXRyaXguZWxpbWluYXRlWmVyb3MoaW50ZXJzZWN0aW9uKTtcbiAgICByZXR1cm4gcmVzZXRMb2NhbENvbm5lY3Rpdml0eShpbnRlcnNlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgYSBjb250aW51b3VzIHZlcnNpb24gb2YgdGhlIGRpc3RhbmNlIHRvIHRoZSBrdGggbmVhcmVzdFxuICAgKiBuZWlnaGJvci4gVGhhdCBpcywgdGhpcyBpcyBzaW1pbGFyIHRvIGtubi1kaXN0YW5jZSBidXQgYWxsb3dzIGNvbnRpbnVvdXNcbiAgICogayB2YWx1ZXMgcmF0aGVyIHRoYW4gcmVxdWlyaW5nIGFuIGludGVncmFsIGsuIEluIGVzc2NlbmNlIHdlIGFyZSBzaW1wbHlcbiAgICogY29tcHV0aW5nIHRoZSBkaXN0YW5jZSBzdWNoIHRoYXQgdGhlIGNhcmRpbmFsaXR5IG9mIGZ1enp5IHNldCB3ZSBnZW5lcmF0ZVxuICAgKiBpcyBrLlxuICAgKi9cbiAgcHJpdmF0ZSBzbW9vdGhLTk5EaXN0YW5jZShcbiAgICBkaXN0YW5jZXM6IFZlY3RvcnMsXG4gICAgazogbnVtYmVyLFxuICAgIGxvY2FsQ29ubmVjdGl2aXR5ID0gMS4wLFxuICAgIG5JdGVyID0gNjQsXG4gICAgYmFuZHdpZHRoID0gMS4wXG4gICkge1xuICAgIGNvbnN0IHRhcmdldCA9IChNYXRoLmxvZyhrKSAvIE1hdGgubG9nKDIpKSAqIGJhbmR3aWR0aDtcbiAgICBjb25zdCByaG8gPSB1dGlscy56ZXJvcyhkaXN0YW5jZXMubGVuZ3RoKTtcbiAgICBjb25zdCByZXN1bHQgPSB1dGlscy56ZXJvcyhkaXN0YW5jZXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlzdGFuY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgbG8gPSAwLjA7XG4gICAgICBsZXQgaGkgPSBJbmZpbml0eTtcbiAgICAgIGxldCBtaWQgPSAxLjA7XG5cbiAgICAgIC8vIFRPRE86IFRoaXMgaXMgdmVyeSBpbmVmZmljaWVudCwgYnV0IHdpbGwgZG8gZm9yIG5vdy4gRklYTUVcbiAgICAgIGNvbnN0IGl0aERpc3RhbmNlcyA9IGRpc3RhbmNlc1tpXTtcbiAgICAgIGNvbnN0IG5vblplcm9EaXN0cyA9IGl0aERpc3RhbmNlcy5maWx0ZXIoKGQpID0+IGQgPiAwLjApO1xuXG4gICAgICBpZiAobm9uWmVyb0Rpc3RzLmxlbmd0aCA+PSBsb2NhbENvbm5lY3Rpdml0eSkge1xuICAgICAgICBjb25zdCBpbmRleCA9IE1hdGguZmxvb3IobG9jYWxDb25uZWN0aXZpdHkpO1xuICAgICAgICBjb25zdCBpbnRlcnBvbGF0aW9uID0gbG9jYWxDb25uZWN0aXZpdHkgLSBpbmRleDtcbiAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgIHJob1tpXSA9IG5vblplcm9EaXN0c1tpbmRleCAtIDFdO1xuICAgICAgICAgIGlmIChpbnRlcnBvbGF0aW9uID4gU01PT1RIX0tfVE9MRVJBTkNFKSB7XG4gICAgICAgICAgICByaG9baV0gKz1cbiAgICAgICAgICAgICAgaW50ZXJwb2xhdGlvbiAqIChub25aZXJvRGlzdHNbaW5kZXhdIC0gbm9uWmVyb0Rpc3RzW2luZGV4IC0gMV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByaG9baV0gPSBpbnRlcnBvbGF0aW9uICogbm9uWmVyb0Rpc3RzWzBdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vblplcm9EaXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJob1tpXSA9IHV0aWxzLm1heChub25aZXJvRGlzdHMpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBuID0gMDsgbiA8IG5JdGVyOyBuKyspIHtcbiAgICAgICAgbGV0IHBzdW0gPSAwLjA7XG4gICAgICAgIGZvciAobGV0IGogPSAxOyBqIDwgZGlzdGFuY2VzW2ldLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlc1tpXVtqXSAtIHJob1tpXTtcbiAgICAgICAgICBpZiAoZCA+IDApXG4gICAgICAgICAgICBwc3VtICs9IE1hdGguZXhwKC0oZCAvIG1pZCkpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHBzdW0gKz0gMS4wO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKE1hdGguYWJzKHBzdW0gLSB0YXJnZXQpIDwgU01PT1RIX0tfVE9MRVJBTkNFKVxuICAgICAgICAgIGJyZWFrO1xuXG5cbiAgICAgICAgaWYgKHBzdW0gPiB0YXJnZXQpIHtcbiAgICAgICAgICBoaSA9IG1pZDtcbiAgICAgICAgICBtaWQgPSAobG8gKyBoaSkgLyAyLjA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG8gPSBtaWQ7XG4gICAgICAgICAgaWYgKGhpID09PSBJbmZpbml0eSlcbiAgICAgICAgICAgIG1pZCAqPSAyO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIG1pZCA9IChsbyArIGhpKSAvIDIuMDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXN1bHRbaV0gPSBtaWQ7XG5cbiAgICAgIC8vIFRPRE86IFRoaXMgaXMgdmVyeSBpbmVmZmljaWVudCwgYnV0IHdpbGwgZG8gZm9yIG5vdy4gRklYTUVcbiAgICAgIGlmIChyaG9baV0gPiAwLjApIHtcbiAgICAgICAgY29uc3QgbWVhbkl0aERpc3RhbmNlcyA9IHV0aWxzLm1lYW4oaXRoRGlzdGFuY2VzKTtcbiAgICAgICAgaWYgKHJlc3VsdFtpXSA8IE1JTl9LX0RJU1RfU0NBTEUgKiBtZWFuSXRoRGlzdGFuY2VzKVxuICAgICAgICAgIHJlc3VsdFtpXSA9IE1JTl9LX0RJU1RfU0NBTEUgKiBtZWFuSXRoRGlzdGFuY2VzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWVhbkRpc3RhbmNlcyA9IHV0aWxzLm1lYW4oZGlzdGFuY2VzLm1hcCh1dGlscy5tZWFuKSk7XG4gICAgICAgIGlmIChyZXN1bHRbaV0gPCBNSU5fS19ESVNUX1NDQUxFICogbWVhbkRpc3RhbmNlcylcbiAgICAgICAgICByZXN1bHRbaV0gPSBNSU5fS19ESVNUX1NDQUxFICogbWVhbkRpc3RhbmNlcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge3NpZ21hczogcmVzdWx0LCByaG9zOiByaG99O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCB0aGUgbWVtYmVyc2hpcCBzdHJlbmd0aCBkYXRhIGZvciB0aGUgMS1za2VsZXRvbiBvZiBlYWNoIGxvY2FsXG4gICAqIGZ1enp5IHNpbXBsaWNpYWwgc2V0IC0tIHRoaXMgaXMgZm9ybWVkIGFzIGEgc3BhcnNlIG1hdHJpeCB3aGVyZSBlYWNoIHJvdyBpc1xuICAgKiBhIGxvY2FsIGZ1enp5IHNpbXBsaWNpYWwgc2V0LCB3aXRoIGEgbWVtYmVyc2hpcCBzdHJlbmd0aCBmb3IgdGhlXG4gICAqIDEtc2ltcGxleCB0byBlYWNoIG90aGVyIGRhdGEgcG9pbnQuXG4gICAqL1xuICBwcml2YXRlIGNvbXB1dGVNZW1iZXJzaGlwU3RyZW5ndGhzKFxuICAgIGtubkluZGljZXM6IFZlY3RvcnMsXG4gICAga25uRGlzdGFuY2VzOiBWZWN0b3JzLFxuICAgIHNpZ21hczogbnVtYmVyW10sXG4gICAgcmhvczogbnVtYmVyW11cbiAgKTogeyByb3dzOiBudW1iZXJbXTsgY29sczogbnVtYmVyW107IHZhbHM6IG51bWJlcltdIH0ge1xuICAgIGNvbnN0IG5TYW1wbGVzID0ga25uSW5kaWNlcy5sZW5ndGg7XG4gICAgY29uc3Qgbk5laWdoYm9ycyA9IGtubkluZGljZXNbMF0ubGVuZ3RoO1xuXG4gICAgY29uc3Qgcm93cyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgY29scyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgdmFscyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICAgIGxldCB2YWwgPSAwO1xuICAgICAgICBpZiAoa25uSW5kaWNlc1tpXVtqXSA9PT0gLTEpXG4gICAgICAgICAgY29udGludWU7IC8vIFdlIGRpZG4ndCBnZXQgdGhlIGZ1bGwga25uIGZvciBpXG5cbiAgICAgICAgaWYgKGtubkluZGljZXNbaV1bal0gPT09IGkpXG4gICAgICAgICAgdmFsID0gMC4wO1xuICAgICAgICBlbHNlIGlmIChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldIDw9IDAuMClcbiAgICAgICAgICB2YWwgPSAxLjA7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB2YWwgPSBNYXRoLmV4cCgtKChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldKSAvIHNpZ21hc1tpXSkpO1xuXG5cbiAgICAgICAgcm93c1tpICogbk5laWdoYm9ycyArIGpdID0gaTtcbiAgICAgICAgY29sc1tpICogbk5laWdoYm9ycyArIGpdID0ga25uSW5kaWNlc1tpXVtqXTtcbiAgICAgICAgdmFsc1tpICogbk5laWdoYm9ycyArIGpdID0gdmFsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7cm93cywgY29scywgdmFsc307XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhIGZ1enp5IHNpbXBsaWNpYWwgc2V0IGVtYmVkZGluZywgdXNpbmcgYSBzcGVjaWZpZWRcbiAgICogaW5pdGlhbGlzYXRpb24gbWV0aG9kIGFuZCB0aGVuIG1pbmltaXppbmcgdGhlIGZ1enp5IHNldCBjcm9zcyBlbnRyb3B5XG4gICAqIGJldHdlZW4gdGhlIDEtc2tlbGV0b25zIG9mIHRoZSBoaWdoIGFuZCBsb3cgZGltZW5zaW9uYWwgZnV6enkgc2ltcGxpY2lhbFxuICAgKiBzZXRzLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplU2ltcGxpY2lhbFNldEVtYmVkZGluZygpIHtcbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5nZXRORXBvY2hzKCk7XG5cbiAgICBjb25zdCB7bkNvbXBvbmVudHN9ID0gdGhpcztcbiAgICBjb25zdCBncmFwaFZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCk7XG4gICAgbGV0IGdyYXBoTWF4ID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGdyYXBoVmFsdWVzW2ldO1xuICAgICAgaWYgKGdyYXBoTWF4IDwgZ3JhcGhWYWx1ZXNbaV0pXG4gICAgICAgIGdyYXBoTWF4ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgZ3JhcGggPSB0aGlzLmdyYXBoLm1hcCgodmFsdWUpID0+IHtcbiAgICAgIGlmICh2YWx1ZSA8IGdyYXBoTWF4IC8gbkVwb2NocylcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9KTtcblxuICAgIC8vIFdlJ3JlIG5vdCBjb21wdXRpbmcgdGhlIHNwZWN0cmFsIGluaXRpYWxpemF0aW9uIGluIHRoaXMgaW1wbGVtZW50YXRpb25cbiAgICAvLyB1bnRpbCB3ZSBkZXRlcm1pbmUgYSBiZXR0ZXIgZWlnZW52YWx1ZS9laWdlbnZlY3RvciBjb21wdXRhdGlvblxuICAgIC8vIGFwcHJvYWNoXG4gICAgdGhpcy5lbWJlZGRpbmcgPSB1dGlscy56ZXJvcyhncmFwaC5uUm93cykubWFwKCgpID0+IHtcbiAgICAgIHJldHVybiB1dGlscy56ZXJvcyhuQ29tcG9uZW50cykubWFwKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHV0aWxzLnRhdVJhbmQodGhpcy5yYW5kb20pICogMjAgKyAtMTA7IC8vIFJhbmRvbSBmcm9tIC0xMCB0byAxMFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBHZXQgZ3JhcGggZGF0YSBpbiBvcmRlcmVkIHdheS4uLlxuICAgIGNvbnN0IHdlaWdodHM6IG51bWJlcltdID0gW107XG4gICAgY29uc3QgaGVhZDogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCB0YWlsOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IHJvd0NvbFZhbHVlcyA9IGdyYXBoLmdldEFsbCgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93Q29sVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IHJvd0NvbFZhbHVlc1tpXTtcbiAgICAgIGlmIChlbnRyeS52YWx1ZSkge1xuICAgICAgICB3ZWlnaHRzLnB1c2goZW50cnkudmFsdWUpO1xuICAgICAgICB0YWlsLnB1c2goZW50cnkucm93KTtcbiAgICAgICAgaGVhZC5wdXNoKGVudHJ5LmNvbCk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGVwb2Noc1BlclNhbXBsZSA9IHRoaXMubWFrZUVwb2Noc1BlclNhbXBsZSh3ZWlnaHRzLCBuRXBvY2hzKTtcblxuICAgIHJldHVybiB7aGVhZCwgdGFpbCwgZXBvY2hzUGVyU2FtcGxlfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHNldCBvZiB3ZWlnaHRzIGFuZCBudW1iZXIgb2YgZXBvY2hzIGdlbmVyYXRlIHRoZSBudW1iZXIgb2ZcbiAgICogZXBvY2hzIHBlciBzYW1wbGUgZm9yIGVhY2ggd2VpZ2h0LlxuICAgKi9cbiAgcHJpdmF0ZSBtYWtlRXBvY2hzUGVyU2FtcGxlKHdlaWdodHM6IG51bWJlcltdLCBuRXBvY2hzOiBudW1iZXIpIHtcbiAgICBjb25zdCByZXN1bHQgPSB1dGlscy5maWxsZWQod2VpZ2h0cy5sZW5ndGgsIC0xLjApO1xuICAgIGNvbnN0IG1heCA9IHV0aWxzLm1heCh3ZWlnaHRzKTtcbiAgICBjb25zdCBuU2FtcGxlcyA9IHdlaWdodHMubWFwKCh3KSA9PiAodyAvIG1heCkgKiBuRXBvY2hzKTtcbiAgICBuU2FtcGxlcy5mb3JFYWNoKChuLCBpKSA9PiB7XG4gICAgICBpZiAobiA+IDApIHJlc3VsdFtpXSA9IG5FcG9jaHMgLyBuU2FtcGxlc1tpXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2lnbnMgb3B0aW1pemF0aW9uIHN0YXRlIHBhcmFtZXRlcnMgZnJvbSBhIHBhcnRpYWwgb3B0aW1pemF0aW9uIHN0YXRlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3NpZ25PcHRpbWl6YXRpb25TdGF0ZVBhcmFtZXRlcnMoc3RhdGU6IFBhcnRpYWw8T3B0aW1pemF0aW9uU3RhdGU+KSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLm9wdGltaXphdGlvblN0YXRlLCBzdGF0ZSk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIGZldyBvcHRpbWl6YXRpb24gc3RhdGUgcGFyYW1ldGVycyB0aGF0IGFyZSBuZWNlc3NhcnkgYmVmb3JlIGVudGVyaW5nXG4gICAqIHRoZSBvcHRpbWl6YXRpb24gc3RlcCBsb29wLlxuICAgKi9cbiAgcHJpdmF0ZSBwcmVwYXJlRm9yT3B0aW1pemF0aW9uTG9vcCgpIHtcbiAgICAvLyBIeXBlcnBhcmFtZXRlcnNcbiAgICBjb25zdCB7cmVwdWxzaW9uU3RyZW5ndGgsIGxlYXJuaW5nUmF0ZSwgbmVnYXRpdmVTYW1wbGVSYXRlfSA9IHRoaXM7XG5cbiAgICBjb25zdCB7XG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBoZWFkRW1iZWRkaW5nLFxuICAgICAgdGFpbEVtYmVkZGluZyxcbiAgICB9ID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZTtcblxuICAgIGNvbnN0IGRpbSA9IGhlYWRFbWJlZGRpbmdbMF0ubGVuZ3RoO1xuICAgIGNvbnN0IG1vdmVPdGhlciA9IGhlYWRFbWJlZGRpbmcubGVuZ3RoID09PSB0YWlsRW1iZWRkaW5nLmxlbmd0aDtcblxuICAgIGNvbnN0IGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlID0gZXBvY2hzUGVyU2FtcGxlLm1hcChcbiAgICAgIChlKSA9PiBlIC8gbmVnYXRpdmVTYW1wbGVSYXRlXG4gICAgKTtcbiAgICBjb25zdCBlcG9jaE9mTmV4dE5lZ2F0aXZlU2FtcGxlID0gWy4uLmVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlXTtcbiAgICBjb25zdCBlcG9jaE9mTmV4dFNhbXBsZSA9IFsuLi5lcG9jaHNQZXJTYW1wbGVdO1xuXG4gICAgdGhpcy5hc3NpZ25PcHRpbWl6YXRpb25TdGF0ZVBhcmFtZXRlcnMoe1xuICAgICAgZXBvY2hPZk5leHRTYW1wbGUsXG4gICAgICBlcG9jaE9mTmV4dE5lZ2F0aXZlU2FtcGxlLFxuICAgICAgZXBvY2hzUGVyTmVnYXRpdmVTYW1wbGUsXG4gICAgICBtb3ZlT3RoZXIsXG4gICAgICBpbml0aWFsQWxwaGE6IGxlYXJuaW5nUmF0ZSxcbiAgICAgIGFscGhhOiBsZWFybmluZ1JhdGUsXG4gICAgICBnYW1tYTogcmVwdWxzaW9uU3RyZW5ndGgsXG4gICAgICBkaW0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgb3B0aW1pemF0aW9uIHN0YXRlIGZvciBzdGVwd2lzZSBvcHRpbWl6YXRpb24uXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVPcHRpbWl6YXRpb24oKSB7XG4gICAgLy8gQWxnb3JpdGhtIHN0YXRlXG4gICAgY29uc3QgaGVhZEVtYmVkZGluZyA9IHRoaXMuZW1iZWRkaW5nO1xuICAgIGNvbnN0IHRhaWxFbWJlZGRpbmcgPSB0aGlzLmVtYmVkZGluZztcblxuICAgIC8vIEluaXRpYWxpemVkIGluIGluaXRpYWxpemVTaW1wbGljaWFsU2V0RW1iZWRkaW5nKClcbiAgICBjb25zdCB7aGVhZCwgdGFpbCwgZXBvY2hzUGVyU2FtcGxlfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG5cbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5nZXRORXBvY2hzKCk7XG4gICAgY29uc3QgblZlcnRpY2VzID0gdGhpcy5ncmFwaC5uQ29scztcblxuICAgIGNvbnN0IHthLCBifSA9IGZpbmRBQlBhcmFtcyh0aGlzLnNwcmVhZCwgdGhpcy5taW5EaXN0KTtcblxuICAgIHRoaXMuYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHtcbiAgICAgIGhlYWRFbWJlZGRpbmcsXG4gICAgICB0YWlsRW1iZWRkaW5nLFxuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBhLFxuICAgICAgYixcbiAgICAgIG5FcG9jaHMsXG4gICAgICBuVmVydGljZXMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dFN0ZXAobjogbnVtYmVyKSB7XG4gICAgY29uc3Qge29wdGltaXphdGlvblN0YXRlfSA9IHRoaXM7XG4gICAgY29uc3Qge1xuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBoZWFkRW1iZWRkaW5nLFxuICAgICAgdGFpbEVtYmVkZGluZyxcbiAgICAgIGVwb2Noc1BlclNhbXBsZSxcbiAgICAgIGVwb2NoT2ZOZXh0U2FtcGxlLFxuICAgICAgZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZSxcbiAgICAgIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlLFxuICAgICAgbW92ZU90aGVyLFxuICAgICAgaW5pdGlhbEFscGhhLFxuICAgICAgYWxwaGEsXG4gICAgICBnYW1tYSxcbiAgICAgIGEsXG4gICAgICBiLFxuICAgICAgZGltLFxuICAgICAgbkVwb2NocyxcbiAgICAgIG5WZXJ0aWNlcyxcbiAgICB9ID0gb3B0aW1pemF0aW9uU3RhdGU7XG5cbiAgICBjb25zdCBjbGlwVmFsdWUgPSA0LjA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVwb2Noc1BlclNhbXBsZS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGVwb2NoT2ZOZXh0U2FtcGxlW2ldID4gbilcbiAgICAgICAgY29udGludWU7XG5cblxuICAgICAgY29uc3QgaiA9IGhlYWRbaV07XG4gICAgICBjb25zdCBrID0gdGFpbFtpXTtcblxuICAgICAgY29uc3QgY3VycmVudCA9IGhlYWRFbWJlZGRpbmdbal07XG4gICAgICBjb25zdCBvdGhlciA9IHRhaWxFbWJlZGRpbmdba107XG5cbiAgICAgIGNvbnN0IGRpc3RTcXVhcmVkID0gckRpc3QoY3VycmVudCwgb3RoZXIpO1xuXG4gICAgICBsZXQgZ3JhZENvZWZmID0gMDtcbiAgICAgIGlmIChkaXN0U3F1YXJlZCA+IDApIHtcbiAgICAgICAgZ3JhZENvZWZmID0gLTIuMCAqIGEgKiBiICogTWF0aC5wb3coZGlzdFNxdWFyZWQsIGIgLSAxLjApO1xuICAgICAgICBncmFkQ29lZmYgLz0gYSAqIE1hdGgucG93KGRpc3RTcXVhcmVkLCBiKSArIDEuMDtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCBkaW07IGQrKykge1xuICAgICAgICBjb25zdCBncmFkRCA9IGNsaXAoZ3JhZENvZWZmICogKGN1cnJlbnRbZF0gLSBvdGhlcltkXSksIGNsaXBWYWx1ZSk7XG4gICAgICAgIGN1cnJlbnRbZF0gKz0gZ3JhZEQgKiBhbHBoYTtcbiAgICAgICAgaWYgKG1vdmVPdGhlcilcbiAgICAgICAgICBvdGhlcltkXSArPSAtZ3JhZEQgKiBhbHBoYTtcbiAgICAgIH1cblxuICAgICAgZXBvY2hPZk5leHRTYW1wbGVbaV0gKz0gZXBvY2hzUGVyU2FtcGxlW2ldO1xuXG4gICAgICBjb25zdCBuTmVnU2FtcGxlcyA9IE1hdGguZmxvb3IoXG4gICAgICAgIChuIC0gZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZVtpXSkgLyBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZVtpXVxuICAgICAgKTtcblxuICAgICAgZm9yIChsZXQgcCA9IDA7IHAgPCBuTmVnU2FtcGxlczsgcCsrKSB7XG4gICAgICAgIGNvbnN0IGsgPSB1dGlscy50YXVSYW5kSW50KG5WZXJ0aWNlcywgdGhpcy5yYW5kb20pO1xuICAgICAgICBjb25zdCBvdGhlciA9IHRhaWxFbWJlZGRpbmdba107XG5cbiAgICAgICAgY29uc3QgZGlzdFNxdWFyZWQgPSByRGlzdChjdXJyZW50LCBvdGhlcik7XG5cbiAgICAgICAgbGV0IGdyYWRDb2VmZiA9IDAuMDtcbiAgICAgICAgaWYgKGRpc3RTcXVhcmVkID4gMC4wKSB7XG4gICAgICAgICAgZ3JhZENvZWZmID0gMi4wICogZ2FtbWEgKiBiO1xuICAgICAgICAgIGdyYWRDb2VmZiAvPVxuICAgICAgICAgICAgKDAuMDAxICsgZGlzdFNxdWFyZWQpICogKGEgKiBNYXRoLnBvdyhkaXN0U3F1YXJlZCwgYikgKyAxKTtcbiAgICAgICAgfSBlbHNlIGlmIChqID09PSBrKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBkID0gMDsgZCA8IGRpbTsgZCsrKSB7XG4gICAgICAgICAgbGV0IGdyYWREID0gNC4wO1xuICAgICAgICAgIGlmIChncmFkQ29lZmYgPiAwLjApXG4gICAgICAgICAgICBncmFkRCA9IGNsaXAoZ3JhZENvZWZmICogKGN1cnJlbnRbZF0gLSBvdGhlcltkXSksIGNsaXBWYWx1ZSk7XG5cbiAgICAgICAgICBjdXJyZW50W2RdICs9IGdyYWREICogYWxwaGE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGVbaV0gKz0gbk5lZ1NhbXBsZXMgKiBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZVtpXTtcbiAgICB9XG4gICAgb3B0aW1pemF0aW9uU3RhdGUuYWxwaGEgPSBpbml0aWFsQWxwaGEgKiAoMS4wIC0gbiAvIG5FcG9jaHMpO1xuXG4gICAgb3B0aW1pemF0aW9uU3RhdGUuY3VycmVudEVwb2NoICs9IDE7XG4gICAgcmV0dXJuIGhlYWRFbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dEFzeW5jKFxuICAgIGVwb2NoQ2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHN0ZXAgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qge25FcG9jaHMsIGN1cnJlbnRFcG9jaH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuICAgICAgICAgIHRoaXMuZW1iZWRkaW5nID0gdGhpcy5vcHRpbWl6ZUxheW91dFN0ZXAoY3VycmVudEVwb2NoKTtcbiAgICAgICAgICBjb25zdCBlcG9jaENvbXBsZXRlZCA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGUuY3VycmVudEVwb2NoO1xuICAgICAgICAgIGNvbnN0IHNob3VsZFN0b3AgPSBlcG9jaENhbGxiYWNrKGVwb2NoQ29tcGxldGVkKSA9PT0gZmFsc2U7XG4gICAgICAgICAgY29uc3QgaXNGaW5pc2hlZCA9IGVwb2NoQ29tcGxldGVkID09PSBuRXBvY2hzO1xuICAgICAgICAgIGlmICghc2hvdWxkU3RvcCAmJiAhaXNGaW5pc2hlZClcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gc3RlcCgpLCAwKTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShpc0ZpbmlzaGVkKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHN0ZXAoKSwgMCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dChcbiAgICBlcG9jaENhbGxiYWNrOiAoZXBvY2hOdW1iZXI6IG51bWJlcikgPT4gdm9pZCB8IGJvb2xlYW4gPSAoKSA9PiB0cnVlXG4gICk6IFZlY3RvcnMge1xuICAgIGxldCBpc0ZpbmlzaGVkID0gZmFsc2U7XG4gICAgbGV0IGVtYmVkZGluZzogVmVjdG9ycyA9IFtdO1xuICAgIHdoaWxlICghaXNGaW5pc2hlZCkge1xuICAgICAgY29uc3Qge25FcG9jaHMsIGN1cnJlbnRFcG9jaH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuICAgICAgZW1iZWRkaW5nID0gdGhpcy5vcHRpbWl6ZUxheW91dFN0ZXAoY3VycmVudEVwb2NoKTtcbiAgICAgIGNvbnN0IGVwb2NoQ29tcGxldGVkID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5jdXJyZW50RXBvY2g7XG4gICAgICBjb25zdCBzaG91bGRTdG9wID0gZXBvY2hDYWxsYmFjayhlcG9jaENvbXBsZXRlZCkgPT09IGZhbHNlO1xuICAgICAgaXNGaW5pc2hlZCA9IGVwb2NoQ29tcGxldGVkID09PSBuRXBvY2hzIHx8IHNob3VsZFN0b3A7XG4gICAgfVxuICAgIHJldHVybiBlbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGVwb2NocyBmb3Igb3B0aW1pemluZyB0aGUgcHJvamVjdGlvbi5cbiAgICogTk9URTogVGhpcyBoZXVyaXN0aWMgZGlmZmVycyBmcm9tIHRoZSBweXRob24gdmVyc2lvblxuICAgKi9cbiAgcHVibGljIGdldE5FcG9jaHMoKSB7XG4gICAgY29uc3QgZ3JhcGggPSB0aGlzLmdyYXBoO1xuXG4gICAgaWYgKHRoaXMubkVwb2NocyA+IDApXG4gICAgICByZXR1cm4gdGhpcy5uRXBvY2hzO1xuXG5cbiAgICBpZiAoIWdyYXBoKVxuICAgICAgcmV0dXJuIDIwMDtcblxuXG4gICAgY29uc3QgbGVuZ3RoID0gZ3JhcGgublJvd3M7XG4gICAgaWYgKGxlbmd0aCA8PSAyNTAwKVxuICAgICAgcmV0dXJuIDUwMDtcbiAgICBlbHNlIGlmIChsZW5ndGggPD0gNTAwMClcbiAgICAgIHJldHVybiA0MDA7XG4gICAgZWxzZSBpZiAobGVuZ3RoIDw9IDc1MDApXG4gICAgICByZXR1cm4gMzAwO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiAyMDA7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV1Y2xpZGVhbih4OiBWZWN0b3IsIHk6IFZlY3Rvcikge1xuICBsZXQgcmVzdWx0ID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKVxuICAgIHJlc3VsdCArPSAoeFtpXSAtIHlbaV0pICoqIDI7XG5cbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbnVtZXJpYyh4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICBjb25zdCByZXN1bHQgPSBNYXRoLmFicyh4IC0geSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmUoeDogVmVjdG9yLCB5OiBWZWN0b3IpIHtcbiAgbGV0IHJlc3VsdCA9IDAuMDtcbiAgbGV0IG5vcm1YID0gMC4wO1xuICBsZXQgbm9ybVkgPSAwLjA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IHhbaV0gKiB5W2ldO1xuICAgIG5vcm1YICs9IHhbaV0gKiogMjtcbiAgICBub3JtWSArPSB5W2ldICoqIDI7XG4gIH1cblxuICBpZiAobm9ybVggPT09IDAgJiYgbm9ybVkgPT09IDApXG4gICAgcmV0dXJuIDA7XG4gIGVsc2UgaWYgKG5vcm1YID09PSAwIHx8IG5vcm1ZID09PSAwKVxuICAgIHJldHVybiAxLjA7XG4gIGVsc2VcbiAgICByZXR1cm4gMS4wIC0gcmVzdWx0IC8gTWF0aC5zcXJ0KG5vcm1YICogbm9ybVkpO1xufVxuXG4vKipcbiAqIEFuIGludGVyZmFjZSByZXByZXNlbnRpbmcgdGhlIG9wdGltaXphdGlvbiBzdGF0ZSB0cmFja2VkIGJldHdlZW4gc3RlcHMgb2ZcbiAqIHRoZSBTR0Qgb3B0aW1pemF0aW9uXG4gKi9cbmNsYXNzIE9wdGltaXphdGlvblN0YXRlIHtcbiAgY3VycmVudEVwb2NoID0gMDtcblxuICAvLyBEYXRhIHRyYWNrZWQgZHVyaW5nIG9wdGltaXphdGlvbiBzdGVwcy5cbiAgaGVhZEVtYmVkZGluZzogbnVtYmVyW11bXSA9IFtdO1xuICB0YWlsRW1iZWRkaW5nOiBudW1iZXJbXVtdID0gW107XG4gIGhlYWQ6IG51bWJlcltdID0gW107XG4gIHRhaWw6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1BlclNhbXBsZTogbnVtYmVyW10gPSBbXTtcbiAgZXBvY2hPZk5leHRTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlOiBudW1iZXJbXSA9IFtdO1xuICBtb3ZlT3RoZXIgPSB0cnVlO1xuICBpbml0aWFsQWxwaGEgPSAxLjA7XG4gIGFscGhhID0gMS4wO1xuICBnYW1tYSA9IDEuMDtcbiAgYSA9IDEuNTc2OTQzNDYwMzExMzA3NztcbiAgYiA9IDAuODk1MDYwODc3OTEwOTczMztcbiAgZGltID0gMjtcbiAgbkVwb2NocyA9IDUwMDtcbiAgblZlcnRpY2VzID0gMDtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBjbGFtcGluZyBvZiBhIHZhbHVlIGludG8gYSBmaXhlZCByYW5nZVxuICovXG5mdW5jdGlvbiBjbGlwKHg6IG51bWJlciwgY2xpcFZhbHVlOiBudW1iZXIpIHtcbiAgaWYgKHggPiBjbGlwVmFsdWUpIHJldHVybiBjbGlwVmFsdWU7XG4gIGVsc2UgaWYgKHggPCAtY2xpcFZhbHVlKSByZXR1cm4gLWNsaXBWYWx1ZTtcbiAgZWxzZSByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBSZWR1Y2VkIEV1Y2xpZGVhbiBkaXN0YW5jZS5cbiAqL1xuZnVuY3Rpb24gckRpc3QoeDogbnVtYmVyW10sIHk6IG51bWJlcltdKSB7XG4gIGxldCByZXN1bHQgPSAwLjA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKylcbiAgICByZXN1bHQgKz0gTWF0aC5wb3coeFtpXSAtIHlbaV0sIDIpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRml0IGEsIGIgcGFyYW1zIGZvciB0aGUgZGlmZmVyZW50aWFibGUgY3VydmUgdXNlZCBpbiBsb3dlclxuICogZGltZW5zaW9uYWwgZnV6enkgc2ltcGxpY2lhbCBjb21wbGV4IGNvbnN0cnVjdGlvbi4gV2Ugd2FudCB0aGVcbiAqIHNtb290aCBjdXJ2ZSAoZnJvbSBhIHByZS1kZWZpbmVkIGZhbWlseSB3aXRoIHNpbXBsZSBncmFkaWVudCkgdGhhdFxuICogYmVzdCBtYXRjaGVzIGFuIG9mZnNldCBleHBvbmVudGlhbCBkZWNheS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBQlBhcmFtcyhzcHJlYWQ6IG51bWJlciwgbWluRGlzdDogbnVtYmVyKSB7XG4gIGNvbnN0IGN1cnZlID0gKFthLCBiXTogbnVtYmVyW10pID0+ICh4OiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gMS4wIC8gKDEuMCArIGEgKiB4ICoqICgyICogYikpO1xuICB9O1xuXG4gIGNvbnN0IHh2ID0gdXRpbHNcbiAgICAubGluZWFyKDAsIHNwcmVhZCAqIDMsIDMwMClcbiAgICAubWFwKCh2YWwpID0+ICh2YWwgPCBtaW5EaXN0ID8gMS4wIDogdmFsKSk7XG5cbiAgY29uc3QgeXYgPSB1dGlscy56ZXJvcyh4di5sZW5ndGgpLm1hcCgodmFsLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IGd0ZSA9IHh2W2luZGV4XSA+PSBtaW5EaXN0O1xuICAgIHJldHVybiBndGUgPyBNYXRoLmV4cCgtKHh2W2luZGV4XSAtIG1pbkRpc3QpIC8gc3ByZWFkKSA6IHZhbDtcbiAgfSk7XG5cbiAgY29uc3QgaW5pdGlhbFZhbHVlcyA9IFswLjUsIDAuNV07XG4gIGNvbnN0IGRhdGEgPSB7eDogeHYsIHk6IHl2fTtcblxuICAvLyBEZWZhdWx0IG9wdGlvbnMgZm9yIHRoZSBhbGdvcml0aG0gKGZyb20gZ2l0aHViIGV4YW1wbGUpXG4gIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgZGFtcGluZzogMS41LFxuICAgIGluaXRpYWxWYWx1ZXMsXG4gICAgZ3JhZGllbnREaWZmZXJlbmNlOiAxMGUtMixcbiAgICBtYXhJdGVyYXRpb25zOiAxMDAsXG4gICAgZXJyb3JUb2xlcmFuY2U6IDEwZS0zLFxuICB9O1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuZXctY2FwXG4gIGNvbnN0IHtwYXJhbWV0ZXJWYWx1ZXN9ID0gTE0oZGF0YSwgY3VydmUsIG9wdGlvbnMpO1xuICBjb25zdCBbYSwgYl0gPSBwYXJhbWV0ZXJWYWx1ZXMgYXMgbnVtYmVyW107XG4gIHJldHVybiB7YSwgYn07XG59XG5cbi8qKlxuICogVW5kZXIgdGhlIGFzc3VtcHRpb24gb2YgY2F0ZWdvcmljYWwgZGlzdGFuY2UgZm9yIHRoZSBpbnRlcnNlY3RpbmdcbiAqIHNpbXBsaWNpYWwgc2V0IHBlcmZvcm0gYSBmYXN0IGludGVyc2VjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhc3RJbnRlcnNlY3Rpb24oXG4gIGdyYXBoOiBtYXRyaXguU3BhcnNlTWF0cml4LFxuICB0YXJnZXQ6IG51bWJlcltdLFxuICB1bmtub3duRGlzdCA9IDEuMCxcbiAgZmFyRGlzdCA9IDUuMFxuKSB7XG4gIHJldHVybiBncmFwaC5tYXAoKHZhbHVlLCByb3csIGNvbCkgPT4ge1xuICAgIGlmICh0YXJnZXRbcm93XSA9PT0gLTEgfHwgdGFyZ2V0W2NvbF0gPT09IC0xKVxuICAgICAgcmV0dXJuIHZhbHVlICogTWF0aC5leHAoLXVua25vd25EaXN0KTtcbiAgICBlbHNlIGlmICh0YXJnZXRbcm93XSAhPT0gdGFyZ2V0W2NvbF0pXG4gICAgICByZXR1cm4gdmFsdWUgKiBNYXRoLmV4cCgtZmFyRGlzdCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXNldCB0aGUgbG9jYWwgY29ubmVjdGl2aXR5IHJlcXVpcmVtZW50IC0tIGVhY2ggZGF0YSBzYW1wbGUgc2hvdWxkXG4gKiBoYXZlIGNvbXBsZXRlIGNvbmZpZGVuY2UgaW4gYXQgbGVhc3Qgb25lIDEtc2ltcGxleCBpbiB0aGUgc2ltcGxpY2lhbCBzZXQuXG4gKiBXZSBjYW4gZW5mb3JjZSB0aGlzIGJ5IGxvY2FsbHkgcmVzY2FsaW5nIGNvbmZpZGVuY2VzLCBhbmQgdGhlbiByZW1lcmdpbmcgdGhlXG4gKiBkaWZmZXJlbnQgbG9jYWwgc2ltcGxpY2lhbCBzZXRzIHRvZ2V0aGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRMb2NhbENvbm5lY3Rpdml0eShzaW1wbGljaWFsU2V0OiBtYXRyaXguU3BhcnNlTWF0cml4KSB7XG4gIHNpbXBsaWNpYWxTZXQgPSBtYXRyaXgubm9ybWFsaXplKHNpbXBsaWNpYWxTZXQsIG1hdHJpeC5Ob3JtVHlwZS5tYXgpO1xuICBjb25zdCB0cmFuc3Bvc2UgPSBtYXRyaXgudHJhbnNwb3NlKHNpbXBsaWNpYWxTZXQpO1xuICBjb25zdCBwcm9kTWF0cml4ID0gbWF0cml4LnBhaXJ3aXNlTXVsdGlwbHkodHJhbnNwb3NlLCBzaW1wbGljaWFsU2V0KTtcbiAgc2ltcGxpY2lhbFNldCA9IG1hdHJpeC5hZGQoXG4gICAgc2ltcGxpY2lhbFNldCxcbiAgICBtYXRyaXguc3VidHJhY3QodHJhbnNwb3NlLCBwcm9kTWF0cml4KVxuICApO1xuICByZXR1cm4gbWF0cml4LmVsaW1pbmF0ZVplcm9zKHNpbXBsaWNpYWxTZXQpO1xufVxuXG4vKipcbiAqIEdpdmVuIGluZGljZXMgYW5kIHdlaWdodHMgYW5kIGFuIG9yaWdpbmFsIGVtYmVkZGluZ3NcbiAqIGluaXRpYWxpemUgdGhlIHBvc2l0aW9ucyBvZiBuZXcgcG9pbnRzIHJlbGF0aXZlIHRvIHRoZVxuICogaW5kaWNlcyBhbmQgd2VpZ2h0cyAob2YgdGhlaXIgbmVpZ2hib3JzIGluIHRoZSBzb3VyY2UgZGF0YSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0VHJhbnNmb3JtKFxuICBpbmRpY2VzOiBudW1iZXJbXVtdLFxuICB3ZWlnaHRzOiBudW1iZXJbXVtdLFxuICBlbWJlZGRpbmc6IFZlY3RvcnNcbikge1xuICBjb25zdCByZXN1bHQgPSB1dGlsc1xuICAgIC56ZXJvcyhpbmRpY2VzLmxlbmd0aClcbiAgICAubWFwKChfeikgPT4gdXRpbHMuemVyb3MoZW1iZWRkaW5nWzBdLmxlbmd0aCkpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlc1swXS5sZW5ndGg7IGorKykge1xuICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCBlbWJlZGRpbmdbMF0ubGVuZ3RoOyBkKyspIHtcbiAgICAgICAgY29uc3QgYSA9IGluZGljZXNbaV1bal07XG4gICAgICAgIHJlc3VsdFtpXVtkXSArPSB3ZWlnaHRzW2ldW2pdICogZW1iZWRkaW5nW2FdW2RdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuIl19","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as heap from './heap';\nimport * as matrix from './matrix';\nimport * as tree from './tree';\nimport * as utils from './utils';\n/**\n * Create a version of nearest neighbor descent.\n */\nexport function makeNNDescent(distanceFn, random) {\n return function nNDescent(data, leafArray, nNeighbors, nIters = 10, maxCandidates = 50, delta = 0.001, rho = 0.5, rpTreeInit = true) {\n const nVertices = data.length;\n const currentGraph = heap.makeHeap(data.length, nNeighbors);\n for (let i = 0; i < data.length; i++) {\n const indices = heap.rejectionSample(nNeighbors, data.length, random);\n for (let j = 0; j < indices.length; j++) {\n const d = distanceFn(data[i], data[indices[j]]);\n heap.heapPush(currentGraph, i, d, indices[j], 1);\n heap.heapPush(currentGraph, indices[j], d, i, 1);\n }\n }\n if (rpTreeInit) {\n for (let n = 0; n < leafArray.length; n++) {\n for (let i = 0; i < leafArray[n].length; i++) {\n if (leafArray[n][i] < 0)\n break;\n for (let j = i + 1; j < leafArray[n].length; j++) {\n if (leafArray[n][j] < 0)\n break;\n const d = distanceFn(data[leafArray[n][i]], data[leafArray[n][j]]);\n heap.heapPush(currentGraph, leafArray[n][i], d, leafArray[n][j], 1);\n heap.heapPush(currentGraph, leafArray[n][j], d, leafArray[n][i], 1);\n }\n }\n }\n }\n for (let n = 0; n < nIters; n++) {\n const candidateNeighbors = heap.buildCandidates(currentGraph, nVertices, nNeighbors, maxCandidates, random);\n let c = 0;\n for (let i = 0; i < nVertices; i++) {\n for (let j = 0; j < maxCandidates; j++) {\n const p = Math.floor(candidateNeighbors[0][i][j]);\n if (p < 0 || utils.tauRand(random) < rho)\n continue;\n for (let k = 0; k < maxCandidates; k++) {\n const q = Math.floor(candidateNeighbors[0][i][k]);\n const cj = candidateNeighbors[2][i][j];\n const ck = candidateNeighbors[2][i][k];\n if (q < 0 || (!cj && !ck))\n continue;\n const d = distanceFn(data[p], data[q]);\n c += heap.heapPush(currentGraph, p, d, q, 1);\n c += heap.heapPush(currentGraph, q, d, p, 1);\n }\n }\n }\n if (c <= delta * nNeighbors * data.length)\n break;\n }\n const sorted = heap.deheapSort(currentGraph);\n return sorted;\n };\n}\nexport function makeInitializations(distanceFn) {\n function initFromRandom(nNeighbors, data, queryPoints, _heap, random) {\n for (let i = 0; i < queryPoints.length; i++) {\n const indices = utils.rejectionSample(nNeighbors, data.length, random);\n for (let j = 0; j < indices.length; j++) {\n if (indices[j] < 0)\n continue;\n const d = distanceFn(data[indices[j]], queryPoints[i]);\n heap.heapPush(_heap, i, d, indices[j], 1);\n }\n }\n }\n function initFromTree(_tree, data, queryPoints, _heap, random) {\n for (let i = 0; i < queryPoints.length; i++) {\n const indices = tree.searchFlatTree(queryPoints[i], _tree, random);\n for (let j = 0; j < indices.length; j++) {\n if (indices[j] < 0)\n return;\n const d = distanceFn(data[indices[j]], queryPoints[i]);\n heap.heapPush(_heap, i, d, indices[j], 1);\n }\n }\n return;\n }\n return { initFromRandom, initFromTree };\n}\nexport function makeInitializedNNSearch(distanceFn) {\n return function nnSearchFn(data, graph, initialization, queryPoints) {\n const { indices, indptr } = matrix.getCSR(graph);\n for (let i = 0; i < queryPoints.length; i++) {\n const tried = new Set(initialization[0][i]);\n while (true) {\n // Find smallest flagged vertex\n const vertex = heap.smallestFlagged(initialization, i);\n if (vertex === -1)\n break;\n const candidates = indices.slice(indptr[vertex], indptr[vertex + 1]);\n for (const candidate of candidates) {\n if (candidate === vertex ||\n candidate === -1 ||\n tried.has(candidate))\n continue;\n const d = distanceFn(data[candidate], queryPoints[i]);\n heap.uncheckedHeapPush(initialization, i, d, candidate, 1);\n tried.add(candidate);\n }\n }\n }\n return initialization;\n };\n}\nexport function initializeSearch(forest, data, queryPoints, nNeighbors, initFromRandom, initFromTree, random) {\n const results = heap.makeHeap(queryPoints.length, nNeighbors);\n initFromRandom(nNeighbors, data, queryPoints, results, random);\n if (forest) {\n for (const tree of forest)\n initFromTree(tree, data, queryPoints, results, random);\n }\n return results;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm5fZGVzY2VudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm5uX2Rlc2NlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBR2pDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxVQUFzQixFQUFFLE1BQWdCO0lBQ3BFLE9BQU8sU0FBUyxTQUFTLENBQ3ZCLElBQVksRUFDWixTQUFrQixFQUNsQixVQUFrQixFQUNsQixNQUFNLEdBQUcsRUFBRSxFQUNYLGFBQWEsR0FBRyxFQUFFLEVBQ2xCLEtBQUssR0FBRyxLQUFLLEVBQ2IsR0FBRyxHQUFHLEdBQUcsRUFDVCxVQUFVLEdBQUcsSUFBSTtRQUVqQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzlCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUU1RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdEUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxF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QUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBoZWFwIGZyb20gJy4vaGVhcCc7XG5pbXBvcnQgKiBhcyBtYXRyaXggZnJvbSAnLi9tYXRyaXgnO1xuaW1wb3J0ICogYXMgdHJlZSBmcm9tICcuL3RyZWUnO1xuaW1wb3J0ICogYXMgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge1JhbmRvbUZuLCBWZWN0b3JzLCBEaXN0YW5jZUZuLCBWZWN0b3J9IGZyb20gJy4vdW1hcCc7XG5cbi8qKlxuICogQ3JlYXRlIGEgdmVyc2lvbiBvZiBuZWFyZXN0IG5laWdoYm9yIGRlc2NlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTk5EZXNjZW50KGRpc3RhbmNlRm46IERpc3RhbmNlRm4sIHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIG5ORGVzY2VudChcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgbGVhZkFycmF5OiBWZWN0b3JzLFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBuSXRlcnMgPSAxMCxcbiAgICBtYXhDYW5kaWRhdGVzID0gNTAsXG4gICAgZGVsdGEgPSAwLjAwMSxcbiAgICByaG8gPSAwLjUsXG4gICAgcnBUcmVlSW5pdCA9IHRydWVcbiAgKSB7XG4gICAgY29uc3QgblZlcnRpY2VzID0gZGF0YS5sZW5ndGg7XG4gICAgY29uc3QgY3VycmVudEdyYXBoID0gaGVhcC5tYWtlSGVhcChkYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSBoZWFwLnJlamVjdGlvblNhbXBsZShuTmVpZ2hib3JzLCBkYXRhLmxlbmd0aCwgcmFuZG9tKTtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2ldLCBkYXRhW2luZGljZXNbal1dKTtcblxuICAgICAgICBoZWFwLmhlYXBQdXNoKGN1cnJlbnRHcmFwaCwgaSwgZCwgaW5kaWNlc1tqXSwgMSk7XG4gICAgICAgIGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBpbmRpY2VzW2pdLCBkLCBpLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJwVHJlZUluaXQpIHtcbiAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgbGVhZkFycmF5Lmxlbmd0aDsgbisrKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVhZkFycmF5W25dLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGxlYWZBcnJheVtuXVtpXSA8IDApXG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IGxlYWZBcnJheVtuXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgaWYgKGxlYWZBcnJheVtuXVtqXSA8IDApXG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2xlYWZBcnJheVtuXVtpXV0sIGRhdGFbbGVhZkFycmF5W25dW2pdXSk7XG4gICAgICAgICAgICBoZWFwLmhlYXBQdXNoKGN1cnJlbnRHcmFwaCwgbGVhZkFycmF5W25dW2ldLCBkLCBsZWFmQXJyYXlbbl1bal0sIDEpO1xuICAgICAgICAgICAgaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIGxlYWZBcnJheVtuXVtqXSwgZCwgbGVhZkFycmF5W25dW2ldLCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGxldCBuID0gMDsgbiA8IG5JdGVyczsgbisrKSB7XG4gICAgICBjb25zdCBjYW5kaWRhdGVOZWlnaGJvcnMgPSBoZWFwLmJ1aWxkQ2FuZGlkYXRlcyhcbiAgICAgICAgY3VycmVudEdyYXBoLFxuICAgICAgICBuVmVydGljZXMsXG4gICAgICAgIG5OZWlnaGJvcnMsXG4gICAgICAgIG1heENhbmRpZGF0ZXMsXG4gICAgICAgIHJhbmRvbVxuICAgICAgKTtcblxuICAgICAgbGV0IGMgPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuVmVydGljZXM7IGkrKykge1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG1heENhbmRpZGF0ZXM7IGorKykge1xuICAgICAgICAgIGNvbnN0IHAgPSBNYXRoLmZsb29yKGNhbmRpZGF0ZU5laWdoYm9yc1swXVtpXVtqXSk7XG4gICAgICAgICAgaWYgKHAgPCAwIHx8IHV0aWxzLnRhdVJhbmQocmFuZG9tKSA8IHJobylcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuXG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBtYXhDYW5kaWRhdGVzOyBrKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHEgPSBNYXRoLmZsb29yKGNhbmRpZGF0ZU5laWdoYm9yc1swXVtpXVtrXSk7XG4gICAgICAgICAgICBjb25zdCBjaiA9IGNhbmRpZGF0ZU5laWdoYm9yc1syXVtpXVtqXTtcbiAgICAgICAgICAgIGNvbnN0IGNrID0gY2FuZGlkYXRlTmVpZ2hib3JzWzJdW2ldW2tdO1xuICAgICAgICAgICAgaWYgKHEgPCAwIHx8ICghY2ogJiYgIWNrKSlcbiAgICAgICAgICAgICAgY29udGludWU7XG5cblxuICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtwXSwgZGF0YVtxXSk7XG4gICAgICAgICAgICBjICs9IGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBwLCBkLCBxLCAxKTtcbiAgICAgICAgICAgIGMgKz0gaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIHEsIGQsIHAsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGMgPD0gZGVsdGEgKiBuTmVpZ2hib3JzICogZGF0YS5sZW5ndGgpXG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBzb3J0ZWQgPSBoZWFwLmRlaGVhcFNvcnQoY3VycmVudEdyYXBoKTtcbiAgICByZXR1cm4gc29ydGVkO1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBJbml0RnJvbVJhbmRvbUZuID0gKFxuICBuTmVpZ2hib3JzOiBudW1iZXIsXG4gIGRhdGE6IFZlY3RvcixcbiAgcXVlcnlQb2ludHM6IFZlY3RvcixcbiAgX2hlYXA6IGhlYXAuSGVhcCxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSA9PiB2b2lkO1xuXG5leHBvcnQgdHlwZSBJbml0RnJvbVRyZWVGbiA9IChcbiAgX3RyZWU6IHRyZWUuRmxhdFRyZWUsXG4gIGRhdGE6IFZlY3RvcixcbiAgcXVlcnlQb2ludHM6IFZlY3RvcixcbiAgX2hlYXA6IGhlYXAuSGVhcCxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSA9PiB2b2lkO1xuXG5leHBvcnQgZnVuY3Rpb24gbWFrZUluaXRpYWxpemF0aW9ucyhkaXN0YW5jZUZuOiBEaXN0YW5jZUZuKSB7XG4gIGZ1bmN0aW9uIGluaXRGcm9tUmFuZG9tKFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgcXVlcnlQb2ludHM6IFZlY3RvcixcbiAgICBfaGVhcDogaGVhcC5IZWFwLFxuICAgIHJhbmRvbTogUmFuZG9tRm5cbiAgKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyeVBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgaW5kaWNlcyA9IHV0aWxzLnJlamVjdGlvblNhbXBsZShuTmVpZ2hib3JzLCBkYXRhLmxlbmd0aCwgcmFuZG9tKTtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoaW5kaWNlc1tqXSA8IDApXG4gICAgICAgICAgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtpbmRpY2VzW2pdXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICBoZWFwLmhlYXBQdXNoKF9oZWFwLCBpLCBkLCBpbmRpY2VzW2pdLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0RnJvbVRyZWUoXG4gICAgX3RyZWU6IHRyZWUuRmxhdFRyZWUsXG4gICAgZGF0YTogVmVjdG9yLFxuICAgIHF1ZXJ5UG9pbnRzOiBWZWN0b3IsXG4gICAgX2hlYXA6IGhlYXAuSGVhcCxcbiAgICByYW5kb206IFJhbmRvbUZuXG4gICkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcXVlcnlQb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSB0cmVlLnNlYXJjaEZsYXRUcmVlKHF1ZXJ5UG9pbnRzW2ldLCBfdHJlZSwgcmFuZG9tKTtcblxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRpY2VzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChpbmRpY2VzW2pdIDwgMClcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtpbmRpY2VzW2pdXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICBoZWFwLmhlYXBQdXNoKF9oZWFwLCBpLCBkLCBpbmRpY2VzW2pdLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIHtpbml0RnJvbVJhbmRvbSwgaW5pdEZyb21UcmVlfTtcbn1cblxuZXhwb3J0IHR5cGUgU2VhcmNoRm4gPSAoXG4gIGRhdGE6IFZlY3RvcixcbiAgZ3JhcGg6IG1hdHJpeC5TcGFyc2VNYXRyaXgsXG4gIGluaXRpYWxpemF0aW9uOiBoZWFwLkhlYXAsXG4gIHF1ZXJ5UG9pbnRzOiBWZWN0b3JcbikgPT4gaGVhcC5IZWFwO1xuXG5leHBvcnQgZnVuY3Rpb24gbWFrZUluaXRpYWxpemVkTk5TZWFyY2goZGlzdGFuY2VGbjogRGlzdGFuY2VGbikge1xuICByZXR1cm4gZnVuY3Rpb24gbm5TZWFyY2hGbihcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgZ3JhcGg6IG1hdHJpeC5TcGFyc2VNYXRyaXgsXG4gICAgaW5pdGlhbGl6YXRpb246IGhlYXAuSGVhcCxcbiAgICBxdWVyeVBvaW50czogVmVjdG9yXG4gICkge1xuICAgIGNvbnN0IHtpbmRpY2VzLCBpbmRwdHJ9ID0gbWF0cml4LmdldENTUihncmFwaCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5UG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB0cmllZCA9IG5ldyBTZXQoaW5pdGlhbGl6YXRpb25bMF1baV0pO1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgLy8gRmluZCBzbWFsbGVzdCBmbGFnZ2VkIHZlcnRleFxuICAgICAgICBjb25zdCB2ZXJ0ZXggPSBoZWFwLnNtYWxsZXN0RmxhZ2dlZChpbml0aWFsaXphdGlvbiwgaSk7XG5cbiAgICAgICAgaWYgKHZlcnRleCA9PT0gLTEpXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IGluZGljZXMuc2xpY2UoaW5kcHRyW3ZlcnRleF0sIGluZHB0clt2ZXJ0ZXggKyAxXSk7XG4gICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBjYW5kaWRhdGUgPT09IHZlcnRleCB8fFxuICAgICAgICAgICAgY2FuZGlkYXRlID09PSAtMSB8fFxuICAgICAgICAgICAgdHJpZWQuaGFzKGNhbmRpZGF0ZSlcbiAgICAgICAgICApXG4gICAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZUZuKGRhdGFbY2FuZGlkYXRlXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICAgIGhlYXAudW5jaGVja2VkSGVhcFB1c2goaW5pdGlhbGl6YXRpb24sIGksIGQsIGNhbmRpZGF0ZSwgMSk7XG4gICAgICAgICAgdHJpZWQuYWRkKGNhbmRpZGF0ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluaXRpYWxpemF0aW9uO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5pdGlhbGl6ZVNlYXJjaChcbiAgZm9yZXN0OiB0cmVlLkZsYXRUcmVlW10sXG4gIGRhdGE6IFZlY3RvcixcbiAgcXVlcnlQb2ludHM6IFZlY3RvcixcbiAgbk5laWdoYm9yczogbnVtYmVyLFxuICBpbml0RnJvbVJhbmRvbTogSW5pdEZyb21SYW5kb21GbixcbiAgaW5pdEZyb21UcmVlOiBJbml0RnJvbVRyZWVGbixcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBoZWFwLm1ha2VIZWFwKHF1ZXJ5UG9pbnRzLmxlbmd0aCwgbk5laWdoYm9ycyk7XG4gIGluaXRGcm9tUmFuZG9tKG5OZWlnaGJvcnMsIGRhdGEsIHF1ZXJ5UG9pbnRzLCByZXN1bHRzLCByYW5kb20pO1xuICBpZiAoZm9yZXN0KSB7XG4gICAgZm9yIChjb25zdCB0cmVlIG9mIGZvcmVzdClcbiAgICAgIGluaXRGcm9tVHJlZSh0cmVlLCBkYXRhLCBxdWVyeVBvaW50cywgcmVzdWx0cywgcmFuZG9tKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0cztcbn1cbiJdfQ==","import isArray from 'is-any-array';\n\nimport errorCalculation from './errorCalculation';\nimport step from './step';\n\n/**\n * Curve fitting algorithm\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @param {object} [options] - Options object\n * @param {number} [options.damping] - Levenberg-Marquardt parameter\n * @param {number} [options.gradientDifference = 10e-2] - Adjustment for decrease the damping parameter\n * @param {Array<number>} [options.minValues] - Minimum allowed values for parameters\n * @param {Array<number>} [options.maxValues] - Maximum allowed values for parameters\n * @param {Array<number>} [options.initialValues] - Array of initial parameter values\n * @param {number} [options.maxIterations = 100] - Maximum of allowed iterations\n * @param {number} [options.errorTolerance = 10e-3] - Minimum uncertainty allowed for each point\n * @return {{parameterValues: Array<number>, parameterError: number, iterations: number}}\n */\nexport default function levenbergMarquardt(\n data,\n parameterizedFunction,\n options = {},\n) {\n let {\n maxIterations = 100,\n gradientDifference = 10e-2,\n damping = 0,\n errorTolerance = 10e-3,\n minValues,\n maxValues,\n initialValues,\n } = options;\n\n if (damping <= 0) {\n throw new Error('The damping option must be a positive number');\n } else if (!data.x || !data.y) {\n throw new Error('The data parameter must have x and y elements');\n } else if (\n !isArray(data.x) ||\n data.x.length < 2 ||\n !isArray(data.y) ||\n data.y.length < 2\n ) {\n throw new Error(\n 'The data parameter elements must be an array with more than 2 points',\n );\n } else if (data.x.length !== data.y.length) {\n throw new Error('The data parameter elements must have the same size');\n }\n\n let parameters =\n initialValues || new Array(parameterizedFunction.length).fill(1);\n let parLen = parameters.length;\n maxValues = maxValues || new Array(parLen).fill(Number.MAX_SAFE_INTEGER);\n minValues = minValues || new Array(parLen).fill(Number.MIN_SAFE_INTEGER);\n\n if (maxValues.length !== minValues.length) {\n throw new Error('minValues and maxValues must be the same size');\n }\n\n if (!isArray(parameters)) {\n throw new Error('initialValues must be an array');\n }\n\n let error = errorCalculation(data, parameters, parameterizedFunction);\n\n let converged = error <= errorTolerance;\n\n let iteration;\n for (iteration = 0; iteration < maxIterations && !converged; iteration++) {\n parameters = step(\n data,\n parameters,\n damping,\n gradientDifference,\n parameterizedFunction,\n );\n\n for (let k = 0; k < parLen; k++) {\n parameters[k] = Math.min(\n Math.max(minValues[k], parameters[k]),\n maxValues[k],\n );\n }\n\n error = errorCalculation(data, parameters, parameterizedFunction);\n if (isNaN(error)) break;\n converged = error <= errorTolerance;\n }\n\n return {\n parameterValues: parameters,\n parameterError: error,\n iterations: iteration,\n };\n}\n","import { dmLinearIndex } from '../distance-matrix';\nexport class TSNE {\n assert(condition, message) {\n if (!condition)\n throw message || 'Assertion failed';\n }\n // syntax sugar\n getopt(opt, field, defaultval) {\n if (opt.hasOwnProperty(field))\n return opt[field];\n else\n return defaultval;\n }\n gaussRandom() {\n if (this.returnV) {\n this.returnV = false;\n return this.vValue;\n }\n const u = 2 * this.random() - 1;\n const v = 2 * this.random() - 1;\n const r = u * u + v * v;\n if (r === 0 || r > 1)\n return this.gaussRandom();\n const c = Math.sqrt(-2 * Math.log(r) / r);\n this.vValue = v * c; // cache this for next function call for efficiency\n this.returnV = true;\n return u * c;\n }\n // return random normal number\n randn(mu, std) {\n return mu + this.gaussRandom() * std;\n }\n // utilitity that creates contiguous vector of zeros of size n\n zeros(n) {\n if (typeof (n) === 'undefined' || isNaN(n))\n return new Float32Array();\n if (typeof ArrayBuffer === 'undefined') {\n // lacking browser support\n const arr = new Float32Array(n);\n for (let i = 0; i < n; i++)\n arr[i] = 0;\n return arr;\n }\n else {\n return new Float32Array(n); // typed arrays are faster\n }\n }\n // utility that returns 2d array filled with random numbers\n // or with value s, if provided\n randn2d(n, d, s) {\n const uses = typeof s !== 'undefined';\n const x = (new Array(n)).fill(null).map(() => new Float32Array(d));\n if (uses) {\n for (let i = 0; i < n; i++)\n x[i] = new Float32Array(d).fill(s);\n }\n else {\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < d; j++)\n x[i][j] = this.randn(0.0, 1e-4);\n }\n }\n return x;\n }\n // compute L2 distance between two vectors\n l2(x1, x2) {\n const D = x1.length;\n let d = 0;\n for (let i = 0; i < D; i++) {\n const x1i = x1[i];\n const x2i = x2[i];\n d += (x1i - x2i) * (x1i - x2i);\n }\n return d;\n }\n // compute pairwise distance in all vectors in X\n xtod(X) {\n const N = X.length;\n const dist = this.zeros(N * N); // allocate contiguous array\n for (let i = 0; i < N; i++) {\n for (let j = i + 1; j < N; j++) {\n const d = this.l2(X[i], X[j]);\n dist[i * N + j] = d;\n dist[j * N + i] = d;\n }\n }\n return dist;\n }\n getIterSize(rowSize) {\n if (rowSize <= 2000)\n return 100;\n else if (rowSize <= 3000)\n return 90;\n else if (rowSize <= 5000)\n return 80;\n else\n return 70;\n }\n // compute (p_{i|j} + p_{j|i})/(2n)\n d2p(D, perplexity, tol, rowSize) {\n // const nf = Math.sqrt(D.length); // this better be an integer\n // const n = Math.floor(nf);\n // this.assert(n === nf, 'D should have square number of elements.');\n const indexer = dmLinearIndex(rowSize);\n const distances = new Float32Array(rowSize * rowSize);\n for (let i = 0; i < rowSize; i++) {\n for (let j = i + 1; j < rowSize; j++)\n distances[i * rowSize + j] = distances[j * rowSize + i] = D[indexer(i, j)];\n }\n const n = rowSize;\n const hTarget = Math.log(perplexity); // target entropy of distribution\n const P = this.zeros(n * n); // temporary probability matrix\n const prow = this.zeros(n); // a temporary storage compartment\n for (let i = 0; i < n; i++) {\n let betamin = -Infinity;\n let betamax = Infinity;\n let beta = 1; // initial value of precision\n let done = false;\n const maxtries = Math.floor(this.getIterSize(rowSize) / 5);\n // perform binary search to find a suitable precision beta\n // so that the entropy of the distribution is appropriate\n let num = 0;\n while (!done) {\n //debugger;\n // compute entropy and kernel row with beta precision\n let psum = 0.0;\n for (let j = 0; j < n; j++) {\n const pj = i === j ? 0 : Math.exp(-distances[i * n + j] * beta);\n prow[j] = pj;\n psum += pj;\n }\n // normalize p and compute entropy\n let nHere = 0.0;\n for (let j = 0; j < n; j++) {\n let pj;\n if (psum === 0)\n pj = 0;\n else\n pj = prow[j] / psum;\n prow[j] = pj;\n if (pj > 1e-7)\n nHere -= pj * Math.log(pj);\n }\n // adjust beta based on result\n if (nHere > hTarget) {\n // entropy was too high (distribution too diffuse)\n // so we need to increase the precision for more peaky distribution\n betamin = beta; // move up the bounds\n if (betamax === Infinity)\n beta = beta * 2;\n else\n beta = (beta + betamax) / 2;\n }\n else {\n // converse case. make distrubtion less peaky\n betamax = beta;\n if (betamin === -Infinity)\n beta = beta / 2;\n else\n beta = (beta + betamin) / 2;\n }\n // stopping conditions: too many tries or got a good precision\n num++;\n if (Math.abs(nHere - hTarget) < tol)\n done = true;\n if (num >= maxtries)\n done = true;\n }\n // console.log('data point ' + i + ' gets precision ' + beta + ' after ' + num + ' binary search steps.');\n // copy over the final prow to P at row i\n for (let j = 0; j < n; j++)\n P[i * n + j] = prow[j];\n } // end loop over examples i\n // symmetrize P and normalize it to sum to 1 over all ij\n const pOut = this.zeros(n * n);\n const N2 = n * 2;\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++)\n pOut[i * n + j] = Math.max((P[i * n + j] + P[j * n + i]) / N2, 1e-100);\n }\n return pOut;\n }\n // helper function\n sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }\n constructor(opt) {\n this.iter = 0;\n this.random = Math.random;\n // return 0 mean unit standard deviation random number\n this.returnV = false;\n this.vValue = 0.0;\n opt = opt || {};\n this.perplexity = this.getopt(opt, 'perplexity', 30); // effective number of nearest neighbors\n this.dim = this.getopt(opt, 'dim', 2); // by default 2-D tSNE\n this.epsilon = this.getopt(opt, 'epsilon', 10); // learning rate\n this.random = this.getopt(opt, 'random', Math.random); // random number generator\n }\n // this function takes a set of high-dimensional points\n // and creates matrix P from them using gaussian kernel\n initDataRaw(X) {\n const N = X.length;\n const D = X[0].length;\n this.assert(N > 0, ' X is empty? You must have some data!');\n this.assert(D > 0, ' X[0] is empty? Where is the data?');\n const dists = this.xtod(X); // convert X to distances using gaussian kernel\n this.P = this.d2p(dists, this.perplexity, 1e-4, D); // attach to object\n this.N = N; // back up the size of the dataset\n this.initSolution(); // refresh this\n }\n // this function takes a given distance matrix and creates\n // matrix P from them.\n // D is assumed to be provided as a list of lists, and should be symmetric\n initDataDist(D, rowSize) {\n const N = D.length;\n this.assert(N > 0, ' X is empty? You must have some data!');\n // convert D to a (fast) typed array version\n // dists.forEach((d) => console.log(d));\n console.time('distances to matrix');\n this.P = this.d2p(D, this.perplexity, 1e-4, rowSize);\n console.timeEnd('distances to matrix');\n this.N = rowSize;\n this.initSolution(); // refresh this\n }\n // (re)initializes the solution to random\n initSolution() {\n // generate random solution to t-SNE\n this.Y = this.randn2d(this.N, this.dim); // the solution\n this.gains = this.randn2d(this.N, this.dim, 1.0); // step gains to accelerate progress in unchanging directions\n this.ystep = this.randn2d(this.N, this.dim, 0.0); // momentum accumulator\n this.iter = 0;\n }\n // return pointer to current solution\n getSolution() {\n return this.Y;\n }\n // perform a single step of optimization to improve the embedding\n step() {\n this.iter += 1;\n const N = this.N;\n const cg = this.costGrad(this.Y); // evaluate gradient\n const cost = cg.cost;\n const grad = cg.grad;\n // perform gradient step\n const ymean = this.zeros(this.dim);\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++) {\n const gid = grad[i][d];\n const sid = this.ystep[i][d];\n const gainid = this.gains[i][d];\n // compute gain update\n let newgain = this.sign(gid) === this.sign(sid) ? gainid * 0.8 : gainid + 0.2;\n if (newgain < 0.01)\n newgain = 0.01; // clamp\n this.gains[i][d] = newgain; // store for next turn\n // compute momentum step direction\n const momval = this.iter < 250 ? 0.5 : 0.8;\n const newsid = momval * sid - this.epsilon * newgain * grad[i][d];\n this.ystep[i][d] = newsid; // remember the step we took\n // step!\n this.Y[i][d] += newsid;\n ymean[d] += this.Y[i][d]; // accumulate mean so that we can center later\n }\n }\n // reproject Y to be zero mean\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++)\n this.Y[i][d] -= ymean[d] / N;\n }\n //if(this.iter%100===0) console.log('iter ' + this.iter + ', cost: ' + cost);\n return cost; // return current cost\n }\n // for debugging: gradient check\n debugGrad() {\n const N = this.N;\n const cg = this.costGrad(this.Y); // evaluate gradient\n //const cost = cg.cost;\n const grad = cg.grad;\n const e = 1e-5;\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++) {\n const yold = this.Y[i][d];\n this.Y[i][d] = yold + e;\n const cg0 = this.costGrad(this.Y);\n this.Y[i][d] = yold - e;\n const cg1 = this.costGrad(this.Y);\n const analytic = grad[i][d];\n const numerical = (cg0.cost - cg1.cost) / (2 * e);\n console.log(i + ',' + d + ': gradcheck analytic: ' + analytic + ' vs. numerical: ' + numerical);\n this.Y[i][d] = yold;\n }\n }\n }\n // return cost and gradient, given an arrangement\n costGrad(Y) {\n const N = this.N;\n const dim = this.dim; // dim of output space\n const P = this.P;\n const pmul = this.iter < 100 ? 4 : 1; // trick that helps with local optima\n // compute current Q distribution, unnormalized first\n this.quArr ?? (this.quArr = this.zeros(N * N));\n let qsum = 0.0;\n for (let i = 0; i < N; i++) {\n for (let j = i + 1; j < N; j++) {\n const dsum = new Array(dim).reduce((prev, _, d) => prev + Math.pow(Y[i][d] - Y[j][d], 2), 0);\n const qu = 1.0 / (1.0 + dsum); // Student t-distribution\n this.quArr[i * N + j] = qu;\n this.quArr[j * N + i] = qu;\n qsum += 2 * qu;\n }\n }\n // normalize Q distribution to sum to 1\n //const NN = N * N;\n //const Q = this.zeros(NN);\n let cost = 0.0;\n const grad = new Array(N).fill(null).map(() => (new Float32Array(dim)).fill(0.0));\n for (let i = 0; i < N; i++) {\n // const gsum = new Float32Array(dim).fill(0.0); // init grad for point i\n for (let j = i + 1; j < N; j++) {\n const Q = Math.max(this.quArr[i * N + j] / qsum, 1e-100);\n cost += (-P[i * N + j] * Math.log(Q)) * 2; // accumulate cost (the non-constant portion at least...)\n const premult = 4 * (pmul * P[i * N + j] - Q) * this.quArr[i * N + j];\n //console.log(premult, Q, i, j);\n for (let d = 0; d < dim; d++) {\n grad[i][d] += premult * (Y[i][d] - Y[j][d]);\n grad[j][d] += premult * (Y[j][d] - Y[i][d]);\n }\n }\n //grad[i] = gsum;\n }\n return { cost, grad };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidC1zbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0LXNuZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFHakQsTUFBTSxPQUFPLElBQUk7SUFXUCxNQUFNLENBQUMsU0FBYyxFQUFFLE9BQVk7UUFDekMsSUFBSSxDQUFDLFNBQVM7WUFBRSxNQUFNLE9BQU8sSUFBSSxrQkFBa0IsQ0FBQztJQUN0RCxDQUFDO0lBRUQsZUFBZTtJQUNQLE1BQU0sQ0FBQyxHQUF1QixFQUFFLEtBQWEsRUFBRSxVQUFlO1FBQ3BFLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUM7WUFDM0IsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7O1lBRWxCLE9BQU8sVUFBVSxDQUFDO0lBQ3RCLENBQUM7SUFLQyxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDckIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3JCLENBQUM7UUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNoQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNoQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDaEQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENB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Li9kaXN0YW5jZS1tYXRyaXgnO1xuXG5cbmV4cG9ydCBjbGFzcyBUU05FIHtcbiAgcHJpdmF0ZSBwZXJwbGV4aXR5OiBudW1iZXI7XG4gIHByaXZhdGUgZGltOiBudW1iZXI7XG4gIHByaXZhdGUgZXBzaWxvbjogbnVtYmVyO1xuICBwcml2YXRlIGl0ZXIgPSAwO1xuICBwcml2YXRlIE4hOiBudW1iZXI7XG4gIHByaXZhdGUgUCE6IEZsb2F0MzJBcnJheTtcbiAgcHJpdmF0ZSBZITogYW55W107XG4gIHByaXZhdGUgZ2FpbnMhOiBhbnlbXTtcbiAgcHJpdmF0ZSB5c3RlcCE6IGFueVtdO1xuICBwcml2YXRlIHJhbmRvbTogKCkgPT4gbnVtYmVyID0gTWF0aC5yYW5kb207XG4gIHByaXZhdGUgYXNzZXJ0KGNvbmRpdGlvbjogYW55LCBtZXNzYWdlOiBhbnkpIHtcbiAgICBpZiAoIWNvbmRpdGlvbikgdGhyb3cgbWVzc2FnZSB8fCAnQXNzZXJ0aW9uIGZhaWxlZCc7XG4gIH1cblxuICAvLyBzeW50YXggc3VnYXJcbiAgcHJpdmF0ZSBnZXRvcHQob3B0OiB7W186IHN0cmluZ106IGFueX0sIGZpZWxkOiBzdHJpbmcsIGRlZmF1bHR2YWw6IGFueSkge1xuICAgIGlmIChvcHQuaGFzT3duUHJvcGVydHkoZmllbGQpKVxuICAgICAgcmV0dXJuIG9wdFtmaWVsZF07XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIGRlZmF1bHR2YWw7XG4gIH1cblxuICAgIC8vIHJldHVybiAwIG1lYW4gdW5pdCBzdGFuZGFyZCBkZXZpYXRpb24gcmFuZG9tIG51bWJlclxuICAgIHByaXZhdGUgcmV0dXJuViA9IGZhbHNlO1xuICAgIHByaXZhdGUgdlZhbHVlID0gMC4wO1xuICAgIGdhdXNzUmFuZG9tKCk6IG51bWJlciB7XG4gICAgICBpZiAodGhpcy5yZXR1cm5WKSB7XG4gICAgICAgIHRoaXMucmV0dXJuViA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gdGhpcy52VmFsdWU7XG4gICAgICB9XG4gICAgICBjb25zdCB1ID0gMiAqIHRoaXMucmFuZG9tKCkgLSAxO1xuICAgICAgY29uc3QgdiA9IDIgKiB0aGlzLnJhbmRvbSgpIC0gMTtcbiAgICAgIGNvbnN0IHIgPSB1ICogdSArIHYgKiB2O1xuICAgICAgaWYgKHIgPT09IDAgfHwgciA+IDEpIHJldHVybiB0aGlzLmdhdXNzUmFuZG9tKCk7XG4gICAgICBjb25zdCBjID0gTWF0aC5zcXJ0KC0yICogTWF0aC5sb2cocikgLyByKTtcbiAgICAgIHRoaXMudlZhbHVlID0gdiAqIGM7IC8vIGNhY2hlIHRoaXMgZm9yIG5leHQgZnVuY3Rpb24gY2FsbCBmb3IgZWZmaWNpZW5jeVxuICAgICAgdGhpcy5yZXR1cm5WID0gdHJ1ZTtcbiAgICAgIHJldHVybiB1ICogYztcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gcmFuZG9tIG5vcm1hbCBudW1iZXJcbiAgICBwcml2YXRlIHJhbmRuKG11OiBudW1iZXIsIHN0ZDogbnVtYmVyKSB7XG4gICAgICByZXR1cm4gbXUgKyB0aGlzLmdhdXNzUmFuZG9tKCkgKiBzdGQ7XG4gICAgfVxuXG4gICAgLy8gdXRpbGl0aXR5IHRoYXQgY3JlYXRlcyBjb250aWd1b3VzIHZlY3RvciBvZiB6ZXJvcyBvZiBzaXplIG5cbiAgICBwcml2YXRlIHplcm9zKG46IG51bWJlcikge1xuICAgICAgaWYgKHR5cGVvZiAobikgPT09ICd1bmRlZmluZWQnIHx8IGlzTmFOKG4pKSByZXR1cm4gbmV3IEZsb2F0MzJBcnJheSgpO1xuICAgICAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gbGFja2luZyBicm93c2VyIHN1cHBvcnRcbiAgICAgICAgY29uc3QgYXJyID0gbmV3IEZsb2F0MzJBcnJheShuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIGFycltpXSA9IDA7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShuKTsgLy8gdHlwZWQgYXJyYXlzIGFyZSBmYXN0ZXJcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB1dGlsaXR5IHRoYXQgcmV0dXJucyAyZCBhcnJheSBmaWxsZWQgd2l0aCByYW5kb20gbnVtYmVyc1xuICAgIC8vIG9yIHdpdGggdmFsdWUgcywgaWYgcHJvdmlkZWRcbiAgICBwcml2YXRlIHJhbmRuMmQobjogbnVtYmVyLCBkOiBudW1iZXIsIHM/OiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IHVzZXMgPSB0eXBlb2YgcyAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgICBjb25zdCB4ID0gKG5ldyBBcnJheShuKSkuZmlsbChudWxsKS5tYXAoKCkgPT4gbmV3IEZsb2F0MzJBcnJheShkKSk7XG4gICAgICBpZiAodXNlcykge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKylcbiAgICAgICAgICB4W2ldID0gbmV3IEZsb2F0MzJBcnJheShkKS5maWxsKHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGQ7IGorKylcbiAgICAgICAgICAgIHhbaV1bal0gPSB0aGlzLnJhbmRuKDAuMCwgMWUtNCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB4O1xuICAgIH1cblxuICAgIC8vIGNvbXB1dGUgTDIgZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjdG9yc1xuICAgIHByaXZhdGUgbDIoeDE6IG51bWJlcltdLCB4MjogbnVtYmVyW10pIHtcbiAgICAgIGNvbnN0IEQgPSB4MS5sZW5ndGg7XG4gICAgICBsZXQgZCA9IDA7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEQ7IGkrKykge1xuICAgICAgICBjb25zdCB4MWkgPSB4MVtpXTtcbiAgICAgICAgY29uc3QgeDJpID0geDJbaV07XG4gICAgICAgIGQgKz0gKHgxaSAtIHgyaSkgKiAoeDFpIC0geDJpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkO1xuICAgIH1cblxuICAgIC8vIGNvbXB1dGUgcGFpcndpc2UgZGlzdGFuY2UgaW4gYWxsIHZlY3RvcnMgaW4gWFxuICAgIHByaXZhdGUgeHRvZChYOiBBcnJheTwgQXJyYXk8bnVtYmVyPiA+KSB7XG4gICAgICBjb25zdCBOID0gWC5sZW5ndGg7XG4gICAgICBjb25zdCBkaXN0ID0gdGhpcy56ZXJvcyhOICogTik7IC8vIGFsbG9jYXRlIGNvbnRpZ3VvdXMgYXJyYXlcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IE47IGorKykge1xuICAgICAgICAgIGNvbnN0IGQgPSB0aGlzLmwyKFhbaV0sIFhbal0pO1xuICAgICAgICAgIGRpc3RbaSAqIE4gKyBqXSA9IGQ7XG4gICAgICAgICAgZGlzdFtqICogTiArIGldID0gZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGRpc3Q7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEl0ZXJTaXplKHJvd1NpemU6IG51bWJlcikge1xuICAgICAgaWYgKHJvd1NpemUgPD0gMjAwMClcbiAgICAgICAgcmV0dXJuIDEwMDtcbiAgICAgIGVsc2UgaWYgKHJvd1NpemUgPD0gMzAwMClcbiAgICAgICAgcmV0dXJuIDkwO1xuICAgICAgZWxzZSBpZiAocm93U2l6ZSA8PSA1MDAwKVxuICAgICAgICByZXR1cm4gODA7XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiA3MDtcbiAgICB9XG5cbiAgICAvLyBjb21wdXRlIChwX3tpfGp9ICsgcF97anxpfSkvKDJuKVxuICAgIHByaXZhdGUgZDJwKEQ6IEZsb2F0MzJBcnJheSwgcGVycGxleGl0eTogbnVtYmVyLCB0b2w6IG51bWJlciwgcm93U2l6ZTogbnVtYmVyKSB7XG4gICAgICAvLyBjb25zdCBuZiA9IE1hdGguc3FydChELmxlbmd0aCk7IC8vIHRoaXMgYmV0dGVyIGJlIGFuIGludGVnZXJcbiAgICAgIC8vIGNvbnN0IG4gPSBNYXRoLmZsb29yKG5mKTtcbiAgICAgIC8vIHRoaXMuYXNzZXJ0KG4gPT09IG5mLCAnRCBzaG91bGQgaGF2ZSBzcXVhcmUgbnVtYmVyIG9mIGVsZW1lbnRzLicpO1xuICAgICAgY29uc3QgaW5kZXhlciA9IGRtTGluZWFySW5kZXgocm93U2l6ZSk7XG4gICAgICBjb25zdCBkaXN0YW5jZXMgPSBuZXcgRmxvYXQzMkFycmF5KHJvd1NpemUgKiByb3dTaXplKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93U2l6ZTsgaSsrKSB7XG4gICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHJvd1NpemU7IGorKylcbiAgICAgICAgICBkaXN0YW5jZXNbaSAqIHJvd1NpemUgKyBqXSA9IGRpc3RhbmNlc1tqICogcm93U2l6ZSArIGldID0gRFtpbmRleGVyKGksIGopXTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG4gPSByb3dTaXplO1xuICAgICAgY29uc3QgaFRhcmdldCA9IE1hdGgubG9nKHBlcnBsZXhpdHkpOyAvLyB0YXJnZXQgZW50cm9weSBvZiBkaXN0cmlidXRpb25cbiAgICAgIGNvbnN0IFAgPSB0aGlzLnplcm9zKG4gKiBuKTsgLy8gdGVtcG9yYXJ5IHByb2JhYmlsaXR5IG1hdHJpeFxuICAgICAgY29uc3QgcHJvdyA9IHRoaXMuemVyb3Mobik7IC8vIGEgdGVtcG9yYXJ5IHN0b3JhZ2UgY29tcGFydG1lbnRcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIGxldCBiZXRhbWluID0gLUluZmluaXR5O1xuICAgICAgICBsZXQgYmV0YW1heCA9IEluZmluaXR5O1xuICAgICAgICBsZXQgYmV0YSA9IDE7IC8vIGluaXRpYWwgdmFsdWUgb2YgcHJlY2lzaW9uXG4gICAgICAgIGxldCBkb25lID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG1heHRyaWVzID0gTWF0aC5mbG9vcih0aGlzLmdldEl0ZXJTaXplKHJvd1NpemUpIC8gNSk7XG5cbiAgICAgICAgLy8gcGVyZm9ybSBiaW5hcnkgc2VhcmNoIHRvIGZpbmQgYSBzdWl0YWJsZSBwcmVjaXNpb24gYmV0YVxuICAgICAgICAvLyBzbyB0aGF0IHRoZSBlbnRyb3B5IG9mIHRoZSBkaXN0cmlidXRpb24gaXMgYXBwcm9wcmlhdGVcbiAgICAgICAgbGV0IG51bSA9IDA7XG4gICAgICAgIHdoaWxlICghZG9uZSkge1xuICAgICAgICAgIC8vZGVidWdnZXI7XG5cbiAgICAgICAgICAvLyBjb21wdXRlIGVudHJvcHkgYW5kIGtlcm5lbCByb3cgd2l0aCBiZXRhIHByZWNpc2lvblxuICAgICAgICAgIGxldCBwc3VtID0gMC4wO1xuICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSB7XG4gICAgICAgICAgICBjb25zdCBwaiA9IGkgPT09IGogPyAwIDogTWF0aC5leHAoLSBkaXN0YW5jZXNbaSAqIG4gKyBqXSAqIGJldGEpO1xuICAgICAgICAgICAgcHJvd1tqXSA9IHBqO1xuICAgICAgICAgICAgcHN1bSArPSBwajtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gbm9ybWFsaXplIHAgYW5kIGNvbXB1dGUgZW50cm9weVxuICAgICAgICAgIGxldCBuSGVyZSA9IDAuMDtcbiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKykge1xuICAgICAgICAgICAgbGV0IHBqO1xuICAgICAgICAgICAgaWYgKHBzdW0gPT09IDApXG4gICAgICAgICAgICAgIHBqID0gMDtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgcGogPSBwcm93W2pdIC8gcHN1bTtcblxuICAgICAgICAgICAgcHJvd1tqXSA9IHBqO1xuICAgICAgICAgICAgaWYgKHBqID4gMWUtNykgbkhlcmUgLT0gcGogKiBNYXRoLmxvZyhwaik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gYWRqdXN0IGJldGEgYmFzZWQgb24gcmVzdWx0XG4gICAgICAgICAgaWYgKG5IZXJlID4gaFRhcmdldCkge1xuICAgICAgICAgICAgLy8gZW50cm9weSB3YXMgdG9vIGhpZ2ggKGRpc3RyaWJ1dGlvbiB0b28gZGlmZnVzZSlcbiAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgdG8gaW5jcmVhc2UgdGhlIHByZWNpc2lvbiBmb3IgbW9yZSBwZWFreSBkaXN0cmlidXRpb25cbiAgICAgICAgICAgIGJldGFtaW4gPSBiZXRhOyAvLyBtb3ZlIHVwIHRoZSBib3VuZHNcbiAgICAgICAgICAgIGlmIChiZXRhbWF4ID09PSBJbmZpbml0eSkgYmV0YSA9IGJldGEgKiAyOyBlbHNlIGJldGEgPSAoYmV0YSArIGJldGFtYXgpIC8gMjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gY29udmVyc2UgY2FzZS4gbWFrZSBkaXN0cnVidGlvbiBsZXNzIHBlYWt5XG4gICAgICAgICAgICBiZXRhbWF4ID0gYmV0YTtcbiAgICAgICAgICAgIGlmIChiZXRhbWluID09PSAtSW5maW5pdHkpIGJldGEgPSBiZXRhIC8gMjsgZWxzZSBiZXRhID0gKGJldGEgKyBiZXRhbWluKSAvIDI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gc3RvcHBpbmcgY29uZGl0aW9uczogdG9vIG1hbnkgdHJpZXMgb3IgZ290IGEgZ29vZCBwcmVjaXNpb25cbiAgICAgICAgICBudW0rKztcbiAgICAgICAgICBpZiAoTWF0aC5hYnMobkhlcmUgLSBoVGFyZ2V0KSA8IHRvbCkgZG9uZSA9IHRydWU7XG4gICAgICAgICAgaWYgKG51bSA+PSBtYXh0cmllcykgZG9uZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjb25zb2xlLmxvZygnZGF0YSBwb2ludCAnICsgaSArICcgZ2V0cyBwcmVjaXNpb24gJyArIGJldGEgKyAnIGFmdGVyICcgKyBudW0gKyAnIGJpbmFyeSBzZWFyY2ggc3RlcHMuJyk7XG4gICAgICAgIC8vIGNvcHkgb3ZlciB0aGUgZmluYWwgcHJvdyB0byBQIGF0IHJvdyBpXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbjsgaisrKSBQW2kgKiBuICsgal0gPSBwcm93W2pdO1xuICAgICAgfSAvLyBlbmQgbG9vcCBvdmVyIGV4YW1wbGVzIGlcblxuICAgICAgLy8gc3ltbWV0cml6ZSBQIGFuZCBub3JtYWxpemUgaXQgdG8gc3VtIHRvIDEgb3ZlciBhbGwgaWpcbiAgICAgIGNvbnN0IHBPdXQgPSB0aGlzLnplcm9zKG4gKiBuKTtcbiAgICAgIGNvbnN0IE4yID0gbiAqIDI7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG47IGorKylcbiAgICAgICAgICBwT3V0W2kgKiBuICsgal0gPSBNYXRoLm1heCgoUFtpICogbiArIGpdICsgUFtqICogbiArIGldKSAvIE4yLCAxZS0xMDApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcE91dDtcbiAgICB9XG5cbiAgICAvLyBoZWxwZXIgZnVuY3Rpb25cbiAgICBwcml2YXRlIHNpZ24oeDogbnVtYmVyKSB7IHJldHVybiB4ID4gMCA/IDEgOiB4IDwgMCA/IC0xIDogMDsgfVxuXG4gICAgY29uc3RydWN0b3Iob3B0OiB7W186IHN0cmluZ106IGFueX0pIHtcbiAgICAgIG9wdCA9IG9wdCB8fCB7fTtcbiAgICAgIHRoaXMucGVycGxleGl0eSA9IHRoaXMuZ2V0b3B0KG9wdCwgJ3BlcnBsZXhpdHknLCAzMCk7IC8vIGVmZmVjdGl2ZSBudW1iZXIgb2YgbmVhcmVzdCBuZWlnaGJvcnNcbiAgICAgIHRoaXMuZGltID0gdGhpcy5nZXRvcHQob3B0LCAnZGltJywgMik7IC8vIGJ5IGRlZmF1bHQgMi1EIHRTTkVcbiAgICAgIHRoaXMuZXBzaWxvbiA9IHRoaXMuZ2V0b3B0KG9wdCwgJ2Vwc2lsb24nLCAxMCk7IC8vIGxlYXJuaW5nIHJhdGVcbiAgICAgIHRoaXMucmFuZG9tID0gdGhpcy5nZXRvcHQob3B0LCAncmFuZG9tJywgTWF0aC5yYW5kb20pOyAvLyByYW5kb20gbnVtYmVyIGdlbmVyYXRvclxuICAgIH1cblxuICAgIC8vIHRoaXMgZnVuY3Rpb24gdGFrZXMgYSBzZXQgb2YgaGlnaC1kaW1lbnNpb25hbCBwb2ludHNcbiAgICAvLyBhbmQgY3JlYXRlcyBtYXRyaXggUCBmcm9tIHRoZW0gdXNpbmcgZ2F1c3NpYW4ga2VybmVsXG4gICAgcHVibGljIGluaXREYXRhUmF3KFg6IEFycmF5PEFycmF5PGFueT4+KSB7XG4gICAgICBjb25zdCBOID0gWC5sZW5ndGg7XG4gICAgICBjb25zdCBEID0gWFswXS5sZW5ndGg7XG4gICAgICB0aGlzLmFzc2VydChOID4gMCwgJyBYIGlzIGVtcHR5PyBZb3UgbXVzdCBoYXZlIHNvbWUgZGF0YSEnKTtcbiAgICAgIHRoaXMuYXNzZXJ0KEQgPiAwLCAnIFhbMF0gaXMgZW1wdHk/IFdoZXJlIGlzIHRoZSBkYXRhPycpO1xuICAgICAgY29uc3QgZGlzdHMgPSB0aGlzLnh0b2QoWCk7IC8vIGNvbnZlcnQgWCB0byBkaXN0YW5jZXMgdXNpbmcgZ2F1c3NpYW4ga2VybmVsXG4gICAgICB0aGlzLlAgPSB0aGlzLmQycChkaXN0cywgdGhpcy5wZXJwbGV4aXR5LCAxZS00LCBEKTsgLy8gYXR0YWNoIHRvIG9iamVjdFxuICAgICAgdGhpcy5OID0gTjsgLy8gYmFjayB1cCB0aGUgc2l6ZSBvZiB0aGUgZGF0YXNldFxuICAgICAgdGhpcy5pbml0U29sdXRpb24oKTsgLy8gcmVmcmVzaCB0aGlzXG4gICAgfVxuXG4gICAgLy8gdGhpcyBmdW5jdGlvbiB0YWtlcyBhIGdpdmVuIGRpc3RhbmNlIG1hdHJpeCBhbmQgY3JlYXRlc1xuICAgIC8vIG1hdHJpeCBQIGZyb20gdGhlbS5cbiAgICAvLyBEIGlzIGFzc3VtZWQgdG8gYmUgcHJvdmlkZWQgYXMgYSBsaXN0IG9mIGxpc3RzLCBhbmQgc2hvdWxkIGJlIHN5bW1ldHJpY1xuICAgIHB1YmxpYyBpbml0RGF0YURpc3QoRDogRmxvYXQzMkFycmF5LCByb3dTaXplOiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IE4gPSBELmxlbmd0aDtcbiAgICAgIHRoaXMuYXNzZXJ0KE4gPiAwLCAnIFggaXMgZW1wdHk/IFlvdSBtdXN0IGhhdmUgc29tZSBkYXRhIScpO1xuICAgICAgLy8gY29udmVydCBEIHRvIGEgKGZhc3QpIHR5cGVkIGFycmF5IHZlcnNpb25cbiAgICAgIC8vIGRpc3RzLmZvckVhY2goKGQpID0+IGNvbnNvbGUubG9nKGQpKTtcbiAgICAgIGNvbnNvbGUudGltZSgnZGlzdGFuY2VzIHRvIG1hdHJpeCcpO1xuICAgICAgdGhpcy5QID0gdGhpcy5kMnAoRCwgdGhpcy5wZXJwbGV4aXR5LCAxZS00LCByb3dTaXplKTtcbiAgICAgIGNvbnNvbGUudGltZUVuZCgnZGlzdGFuY2VzIHRvIG1hdHJpeCcpO1xuICAgICAgdGhpcy5OID0gcm93U2l6ZTtcbiAgICAgIHRoaXMuaW5pdFNvbHV0aW9uKCk7IC8vIHJlZnJlc2ggdGhpc1xuICAgIH1cblxuICAgIC8vIChyZSlpbml0aWFsaXplcyB0aGUgc29sdXRpb24gdG8gcmFuZG9tXG4gICAgcHVibGljIGluaXRTb2x1dGlvbigpIHtcbiAgICAgIC8vIGdlbmVyYXRlIHJhbmRvbSBzb2x1dGlvbiB0byB0LVNORVxuICAgICAgdGhpcy5ZID0gdGhpcy5yYW5kbjJkKHRoaXMuTiwgdGhpcy5kaW0pOyAvLyB0aGUgc29sdXRpb25cbiAgICAgIHRoaXMuZ2FpbnMgPSB0aGlzLnJhbmRuMmQodGhpcy5OLCB0aGlzLmRpbSwgMS4wKTsgLy8gc3RlcCBnYWlucyB0byBhY2NlbGVyYXRlIHByb2dyZXNzIGluIHVuY2hhbmdpbmcgZGlyZWN0aW9uc1xuICAgICAgdGhpcy55c3RlcCA9IHRoaXMucmFuZG4yZCh0aGlzLk4sIHRoaXMuZGltLCAwLjApOyAvLyBtb21lbnR1bSBhY2N1bXVsYXRvclxuICAgICAgdGhpcy5pdGVyID0gMDtcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gcG9pbnRlciB0byBjdXJyZW50IHNvbHV0aW9uXG4gICAgcHVibGljIGdldFNvbHV0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuWTtcbiAgICB9XG5cbiAgICAvLyBwZXJmb3JtIGEgc2luZ2xlIHN0ZXAgb2Ygb3B0aW1pemF0aW9uIHRvIGltcHJvdmUgdGhlIGVtYmVkZGluZ1xuICAgIHB1YmxpYyBzdGVwKCkge1xuICAgICAgdGhpcy5pdGVyICs9IDE7XG4gICAgICBjb25zdCBOID0gdGhpcy5OO1xuICAgICAgY29uc3QgY2cgPSB0aGlzLmNvc3RHcmFkKHRoaXMuWSk7IC8vIGV2YWx1YXRlIGdyYWRpZW50XG4gICAgICBjb25zdCBjb3N0ID0gY2cuY29zdDtcbiAgICAgIGNvbnN0IGdyYWQgPSBjZy5ncmFkO1xuXG4gICAgICAvLyBwZXJmb3JtIGdyYWRpZW50IHN0ZXBcbiAgICAgIGNvbnN0IHltZWFuID0gdGhpcy56ZXJvcyh0aGlzLmRpbSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgICBmb3IgKGxldCBkID0gMDsgZCA8IHRoaXMuZGltOyBkKyspIHtcbiAgICAgICAgICBjb25zdCBnaWQgPSBncmFkW2ldW2RdO1xuICAgICAgICAgIGNvbnN0IHNpZCA9IHRoaXMueXN0ZXBbaV1bZF07XG4gICAgICAgICAgY29uc3QgZ2FpbmlkID0gdGhpcy5nYWluc1tpXVtkXTtcblxuICAgICAgICAgIC8vIGNvbXB1dGUgZ2FpbiB1cGRhdGVcbiAgICAgICAgICBsZXQgbmV3Z2FpbiA9IHRoaXMuc2lnbihnaWQpID09PSB0aGlzLnNpZ24oc2lkKSA/IGdhaW5pZCAqIDAuOCA6IGdhaW5pZCArIDAuMjtcbiAgICAgICAgICBpZiAobmV3Z2FpbiA8IDAuMDEpIG5ld2dhaW4gPSAwLjAxOyAvLyBjbGFtcFxuICAgICAgICAgIHRoaXMuZ2FpbnNbaV1bZF0gPSBuZXdnYWluOyAvLyBzdG9yZSBmb3IgbmV4dCB0dXJuXG5cbiAgICAgICAgICAvLyBjb21wdXRlIG1vbWVudHVtIHN0ZXAgZGlyZWN0aW9uXG4gICAgICAgICAgY29uc3QgbW9tdmFsID0gdGhpcy5pdGVyIDwgMjUwID8gMC41IDogMC44O1xuICAgICAgICAgIGNvbnN0IG5ld3NpZCA9IG1vbXZhbCAqIHNpZCAtIHRoaXMuZXBzaWxvbiAqIG5ld2dhaW4gKiBncmFkW2ldW2RdO1xuICAgICAgICAgIHRoaXMueXN0ZXBbaV1bZF0gPSBuZXdzaWQ7IC8vIHJlbWVtYmVyIHRoZSBzdGVwIHdlIHRvb2tcblxuICAgICAgICAgIC8vIHN0ZXAhXG4gICAgICAgICAgdGhpcy5ZW2ldW2RdICs9IG5ld3NpZDtcblxuICAgICAgICAgIHltZWFuW2RdICs9IHRoaXMuWVtpXVtkXTsgLy8gYWNjdW11bGF0ZSBtZWFuIHNvIHRoYXQgd2UgY2FuIGNlbnRlciBsYXRlclxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHJlcHJvamVjdCBZIHRvIGJlIHplcm8gbWVhblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCB0aGlzLmRpbTsgZCsrKVxuICAgICAgICAgIHRoaXMuWVtpXVtkXSAtPSB5bWVhbltkXSAvIE47XG4gICAgICB9XG5cbiAgICAgIC8vaWYodGhpcy5pdGVyJTEwMD09PTApIGNvbnNvbGUubG9nKCdpdGVyICcgKyB0aGlzLml0ZXIgKyAnLCBjb3N0OiAnICsgY29zdCk7XG4gICAgICByZXR1cm4gY29zdDsgLy8gcmV0dXJuIGN1cnJlbnQgY29zdFxuICAgIH1cblxuICAgIC8vIGZvciBkZWJ1Z2dpbmc6IGdyYWRpZW50IGNoZWNrXG4gICAgcHVibGljIGRlYnVnR3JhZCgpIHtcbiAgICAgIGNvbnN0IE4gPSB0aGlzLk47XG5cbiAgICAgIGNvbnN0IGNnID0gdGhpcy5jb3N0R3JhZCh0aGlzLlkpOyAvLyBldmFsdWF0ZSBncmFkaWVudFxuICAgICAgLy9jb25zdCBjb3N0ID0gY2cuY29zdDtcbiAgICAgIGNvbnN0IGdyYWQgPSBjZy5ncmFkO1xuXG4gICAgICBjb25zdCBlID0gMWUtNTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgdGhpcy5kaW07IGQrKykge1xuICAgICAgICAgIGNvbnN0IHlvbGQgPSB0aGlzLllbaV1bZF07XG5cbiAgICAgICAgICB0aGlzLllbaV1bZF0gPSB5b2xkICsgZTtcbiAgICAgICAgICBjb25zdCBjZzAgPSB0aGlzLmNvc3RHcmFkKHRoaXMuWSk7XG5cbiAgICAgICAgICB0aGlzLllbaV1bZF0gPSB5b2xkIC0gZTtcbiAgICAgICAgICBjb25zdCBjZzEgPSB0aGlzLmNvc3RHcmFkKHRoaXMuWSk7XG5cbiAgICAgICAgICBjb25zdCBhbmFseXRpYyA9IGdyYWRbaV1bZF07XG4gICAgICAgICAgY29uc3QgbnVtZXJpY2FsID0gKGNnMC5jb3N0IC0gY2cxLmNvc3QpIC8gKDIgKiBlKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhpICsgJywnICsgZCArICc6IGdyYWRjaGVjayBhbmFseXRpYzogJyArIGFuYWx5dGljICsgJyB2cy4gbnVtZXJpY2FsOiAnICsgbnVtZXJpY2FsKTtcblxuICAgICAgICAgIHRoaXMuWVtpXVtkXSA9IHlvbGQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHF1QXJyPzogRmxvYXQzMkFycmF5O1xuICAgIC8vIHJldHVybiBjb3N0IGFuZCBncmFkaWVudCwgZ2l2ZW4gYW4gYXJyYW5nZW1lbnRcbiAgICBwdWJsaWMgY29zdEdyYWQoWTogbnVtYmVyW11bXSkge1xuICAgICAgY29uc3QgTiA9IHRoaXMuTjtcbiAgICAgIGNvbnN0IGRpbSA9IHRoaXMuZGltOyAvLyBkaW0gb2Ygb3V0cHV0IHNwYWNlXG4gICAgICBjb25zdCBQID0gdGhpcy5QO1xuXG4gICAgICBjb25zdCBwbXVsID0gdGhpcy5pdGVyIDwgMTAwID8gNCA6IDE7IC8vIHRyaWNrIHRoYXQgaGVscHMgd2l0aCBsb2NhbCBvcHRpbWFcblxuICAgICAgLy8gY29tcHV0ZSBjdXJyZW50IFEgZGlzdHJpYnV0aW9uLCB1bm5vcm1hbGl6ZWQgZmlyc3RcbiAgICAgIHRoaXMucXVBcnIgPz89IHRoaXMuemVyb3MoTiAqIE4pO1xuICAgICAgbGV0IHFzdW0gPSAwLjA7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBOOyBqKyspIHtcbiAgICAgICAgICBjb25zdCBkc3VtID0gbmV3IEFycmF5KGRpbSkucmVkdWNlKChwcmV2LCBfLCBkKSA9PiBwcmV2ICsgTWF0aC5wb3coWVtpXVtkXSAtIFlbal1bZF0sIDIpLCAwKTtcbiAgICAgICAgICBjb25zdCBxdSA9IDEuMCAvICgxLjAgKyBkc3VtKTsgLy8gU3R1ZGVudCB0LWRpc3RyaWJ1dGlvblxuICAgICAgICAgIHRoaXMucXVBcnJbaSAqIE4gKyBqXSA9IHF1O1xuICAgICAgICAgIHRoaXMucXVBcnJbaiAqIE4gKyBpXSA9IHF1O1xuICAgICAgICAgIHFzdW0gKz0gMiAqIHF1O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBub3JtYWxpemUgUSBkaXN0cmlidXRpb24gdG8gc3VtIHRvIDFcbiAgICAgIC8vY29uc3QgTk4gPSBOICogTjtcbiAgICAgIC8vY29uc3QgUSA9IHRoaXMuemVyb3MoTk4pO1xuICAgICAgbGV0IGNvc3QgPSAwLjA7XG4gICAgICBjb25zdCBncmFkID0gbmV3IEFycmF5KE4pLmZpbGwobnVsbCkubWFwKCgpID0+IChuZXcgRmxvYXQzMkFycmF5KGRpbSkpLmZpbGwoMC4wKSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgICAvLyBjb25zdCBnc3VtID0gbmV3IEZsb2F0MzJBcnJheShkaW0pLmZpbGwoMC4wKTsgLy8gaW5pdCBncmFkIGZvciBwb2ludCBpXG4gICAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IE47IGorKykge1xuICAgICAgICAgIGNvbnN0IFEgPSBNYXRoLm1heCh0aGlzLnF1QXJyW2kgKiBOICsgal0gLyBxc3VtLCAxZS0xMDApO1xuICAgICAgICAgIGNvc3QgKz0gKC0gUFtpICogTiArIGpdICogTWF0aC5sb2coUSkpICogMjsgLy8gYWNjdW11bGF0ZSBjb3N0ICh0aGUgbm9uLWNvbnN0YW50IHBvcnRpb24gYXQgbGVhc3QuLi4pXG4gICAgICAgICAgY29uc3QgcHJlbXVsdCA9IDQgKiAocG11bCAqIFBbaSAqIE4gKyBqXSAtIFEpICogdGhpcy5xdUFycltpICogTiArIGpdO1xuICAgICAgICAgIC8vY29uc29sZS5sb2cocHJlbXVsdCwgUSwgaSwgaik7XG4gICAgICAgICAgZm9yIChsZXQgZCA9IDA7IGQgPCBkaW07IGQrKykge1xuICAgICAgICAgICAgZ3JhZFtpXVtkXSArPSBwcmVtdWx0ICogKFlbaV1bZF0gLSBZW2pdW2RdKTtcbiAgICAgICAgICAgIGdyYWRbal1bZF0gKz0gcHJlbXVsdCAqIChZW2pdW2RdIC0gWVtpXVtkXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vZ3JhZFtpXSA9IGdzdW07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7Y29zdCwgZ3JhZH07XG4gICAgfVxufVxuIl19","/** Proxy for DistanceMatrix class. Allows to index matrix as matrix[i][j]\n * Note: much slower than direct indexing, but still much faster than recalculating distances.\n * will be used for T-SNE mainly.\n * @param {Float32Array}condensedArray - array of distances between all pairs of objects\n * @param {number}size - number of comparebles in matrix\n * @return {Float32Array} - proxy for condensedArray\n*/\nexport function distanceMatrixProxy(condensedArray, size) {\n const linearFunc = dmLinearIndex(size);\n function linearIndex(i, j) {\n const iNum = Number(i);\n const jNum = Number(j);\n return linearFunc(iNum, jNum);\n }\n function idx2Handler(idx1) {\n return ({\n get(target, idx2, _receiver) {\n if (idx1 === idx2)\n return 0;\n const linearIdx = Number(idx1) > Number(idx2) ? linearIndex(idx2, idx1) : linearIndex(idx1, idx2);\n return target[linearIdx];\n },\n });\n }\n const idx1Handler = {\n get(target, idx1, _receiver) {\n if (idx1 === 'length')\n return size;\n return new Proxy(target, idx2Handler(idx1));\n },\n };\n return new Proxy(condensedArray, idx1Handler);\n}\nexport function dmLinearIndex(size) {\n return (i, j) => size * i + j - Math.floor(((i + 2) * (i + 1)) / 2);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7O0VBTUU7QUFDRixNQUFNLFVBQVUsbUJBQW1CLENBQUMsY0FBNEIsRUFBRSxJQUFZO0lBQzVFLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxTQUFTLFdBQVcsQ0FBQyxDQUFrQixFQUFFLENBQWtCO1FBQ3pELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsT0FBTyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxTQUFTLFdBQVcsQ0FBQyxJQUFxQjtRQUN4QyxPQUFPLENBQ0w7WUFDRSxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTO2dCQUN6QixJQUFJLElBQUksS0FBSyxJQUFJO29CQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUM1QixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNsRyxPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMzQixDQUFDO1NBQ0YsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sV0FBVyxHQUErQjtRQUM5QyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTO1lBQ3pCLElBQUksSUFBSSxLQUFLLFFBQVE7Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFDbkMsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDOUMsQ0FBQztLQUNGLENBQUM7SUFFRixPQUFPLElBQUksS0FBSyxDQUFDLGNBQWMsRUFBRSxXQUFXLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFZO0lBQ3hDLE9BQU8sQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN0RixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXG5cbi8qKiBQcm94eSBmb3IgRGlzdGFuY2VNYXRyaXggY2xhc3MuIEFsbG93cyB0byBpbmRleCBtYXRyaXggYXMgbWF0cml4W2ldW2pdXG4gKiBOb3RlOiBtdWNoIHNsb3dlciB0aGFuIGRpcmVjdCBpbmRleGluZywgYnV0IHN0aWxsIG11Y2ggZmFzdGVyIHRoYW4gcmVjYWxjdWxhdGluZyBkaXN0YW5jZXMuXG4gKiB3aWxsIGJlIHVzZWQgZm9yIFQtU05FIG1haW5seS5cbiAqIEBwYXJhbSB7RmxvYXQzMkFycmF5fWNvbmRlbnNlZEFycmF5IC0gYXJyYXkgb2YgZGlzdGFuY2VzIGJldHdlZW4gYWxsIHBhaXJzIG9mIG9iamVjdHNcbiAqIEBwYXJhbSB7bnVtYmVyfXNpemUgLSBudW1iZXIgb2YgY29tcGFyZWJsZXMgaW4gbWF0cml4XG4gKiBAcmV0dXJuIHtGbG9hdDMyQXJyYXl9IC0gcHJveHkgZm9yIGNvbmRlbnNlZEFycmF5XG4qL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlTWF0cml4UHJveHkoY29uZGVuc2VkQXJyYXk6IEZsb2F0MzJBcnJheSwgc2l6ZTogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgY29uc3QgbGluZWFyRnVuYyA9IGRtTGluZWFySW5kZXgoc2l6ZSk7XG4gIGZ1bmN0aW9uIGxpbmVhckluZGV4KGk6IHN5bWJvbCB8IHN0cmluZywgajogc3ltYm9sIHwgc3RyaW5nKSB7XG4gICAgY29uc3QgaU51bSA9IE51bWJlcihpKTtcbiAgICBjb25zdCBqTnVtID0gTnVtYmVyKGopO1xuICAgIHJldHVybiBsaW5lYXJGdW5jKGlOdW0sIGpOdW0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaWR4MkhhbmRsZXIoaWR4MTogc3ltYm9sIHwgc3RyaW5nKTpQcm94eUhhbmRsZXI8RmxvYXQzMkFycmF5PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHtcbiAgICAgICAgZ2V0KHRhcmdldCwgaWR4MiwgX3JlY2VpdmVyKSB7XG4gICAgICAgICAgaWYgKGlkeDEgPT09IGlkeDIpIHJldHVybiAwO1xuICAgICAgICAgIGNvbnN0IGxpbmVhcklkeCA9IE51bWJlcihpZHgxKSA+IE51bWJlcihpZHgyKSA/IGxpbmVhckluZGV4KGlkeDIsIGlkeDEpIDogbGluZWFySW5kZXgoaWR4MSwgaWR4Mik7XG4gICAgICAgICAgcmV0dXJuIHRhcmdldFtsaW5lYXJJZHhdO1xuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG4gIH1cbiAgY29uc3QgaWR4MUhhbmRsZXI6IFByb3h5SGFuZGxlcjxGbG9hdDMyQXJyYXk+ID0ge1xuICAgIGdldCh0YXJnZXQsIGlkeDEsIF9yZWNlaXZlcikge1xuICAgICAgaWYgKGlkeDEgPT09ICdsZW5ndGgnKSByZXR1cm4gc2l6ZTtcbiAgICAgIHJldHVybiBuZXcgUHJveHkodGFyZ2V0LCBpZHgySGFuZGxlcihpZHgxKSk7XG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gbmV3IFByb3h5KGNvbmRlbnNlZEFycmF5LCBpZHgxSGFuZGxlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkbUxpbmVhckluZGV4KHNpemU6IG51bWJlcik6IChpOiBudW1iZXIsIGo6IG51bWJlcikgPT4gbnVtYmVyIHtcbiAgcmV0dXJuIChpOiBudW1iZXIsIGo6IG51bWJlcikgPT4gc2l6ZSAqIGkgKyBqIC0gTWF0aC5mbG9vcigoKGkgKyAyKSAqIChpICsgMSkpIC8gMik7XG59XG4iXX0=","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};\nlet gpuAdapter = null;\nlet gpuDevice = null;\nexport function getGPUDevice() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!navigator.gpu) {\n console.error('WebGPU is not supported in this browser');\n return null;\n }\n if (!gpuAdapter) {\n //reason: only here we get the gpuAdapter\n // eslint-disable-next-line no-restricted-syntax\n gpuAdapter = yield navigator.gpu.requestAdapter({ powerPreference: 'high-performance' });\n if (gpuAdapter == null)\n return null;\n }\n let isLost = false;\n if (gpuDevice) {\n gpuDevice.lost.then(() => {\n isLost = true;\n });\n yield new Promise((r) => setTimeout(r, 10)); // wait to see if the device is lost\n }\n if (!gpuDevice || isLost) {\n const requiredBufferSize = 1000000000; // ~1000MB\n const adapterLimits = gpuAdapter.limits;\n const buffferSizeLimit = adapterLimits.maxBufferSize;\n const storageBufferSizeLimit = adapterLimits.maxStorageBufferBindingSize;\n try {\n gpuDevice = yield gpuAdapter.requestDevice({ requiredLimits: {\n maxBufferSize: Math.min(buffferSizeLimit, requiredBufferSize),\n maxStorageBufferBindingSize: Math.min(storageBufferSizeLimit, requiredBufferSize)\n } });\n return gpuDevice;\n }\n catch (e) {\n console.error('Failed to create device with required limits', e);\n gpuDevice = yield gpuAdapter.requestDevice();\n return gpuDevice;\n }\n }\n return gpuDevice;\n });\n}\nexport function getGPUAdapterDescription() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!navigator.gpu) {\n console.error('WebGPU is not supported in this browser');\n return null;\n }\n if (!gpuAdapter) {\n // reason: only here we get the gpuAdapter\n // eslint-disable-next-line no-restricted-syntax\n gpuAdapter = yield navigator.gpu.requestAdapter();\n if (gpuAdapter == null)\n return null;\n }\n let info = null;\n if ('info' in gpuAdapter)\n info = gpuAdapter.info;\n // this option is sort of deprecated but still available in every initial release\n // else if ('requestAdapterInfo' in gpuAdapter && typeof gpuAdapter.requestAdapterInfo === 'function')\n // info = (await gpuAdapter.requestAdapterInfo()) as GPUAdapterInfo;\n if (!info)\n return 'No GPU description available';\n const outString = replaceEmptyString(info.description, replaceEmptyString(info.vendor, 'No GPU description available'));\n return outString;\n });\n}\nfunction replaceEmptyString(str, replacement) {\n return !str || str == '' ? replacement : str;\n}\n//# sourceMappingURL=getGPUDevice.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 / 30),\n [WEBGPUDISTANCE.SOKAL]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.COSINE]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.ASYMMETRIC]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\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","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/* eslint-disable max-len */\nimport { getGPUDevice } from '../getGPUDevice';\nimport { WEBGSLAGGREGATION, WEBGSLAGGREGATIONFUNCTIONS } from '../multi-col-distances/webGPU-aggregation';\nimport { WEBGPUDISTANCE, webGPUFunctions } from '../multi-col-distances/webGPU-multicol-distances';\nimport { webGPUProcessInfo } from '../preprocessing/webGPU-process-info';\n/** generate KNN based on list of lists of entries.\n * these entries are each encoded as Uint32Array or FLOAT32Array (depending on their type).\n * for example, sequences would be encoded as Uint32Array based on char code of the letter at each position.\n * [65, 66, 67, 68, 69] would be a sequence of 5 letters.\n * for chemical fingerprints, it would be a binary array of 0s and 1s,\n * represented as Uint32Array(_data property of DG bitarray).\n *\n * Be ware that size of entryList, distanceMetrics, weights and options must be the same.\n * if there are no options for entries i, pass an empty object.\n * for now options are needed for:\n * needleman-wunsch and monomer chemical distances: see {@link BioDistanceFnOptions} as for how it should be passed\n * numeric distances (Difference): {range: number} where range is the range of the values in the column (max - min).\n * in both cases, if options are not provided, they will be calculated automatically.\n */\nexport function multiColWebGPUKNN(entryList, // list of lists of entries, for multiple columns\nknnSize = 15, // size of the k-nearest neighbors\ndistanceMetrics, // distance metrics for each column\naggregationFunction, // aggregation function for the distances\nweights, // weights for each column\noptions // supplementary options for each column\n) {\n return __awaiter(this, void 0, void 0, function* () {\n // first, check that all the supplementary options are provided and are the same length:\n if (options.length !== entryList.length ||\n options.length !== distanceMetrics.length || options.length !== weights.length)\n throw new Error('Options, weigths and distance functions must be provided for each column');\n // check that all the entry lists are the same length\n if (entryList.some((list) => list.length !== entryList[0].length))\n throw new Error('All entry lists must be the same length');\n const availableDistanceMetrics = Object.values(WEBGPUDISTANCE);\n if (distanceMetrics.some((metric) => !availableDistanceMetrics.includes(metric)))\n throw new Error('Invalid distance metrics provided: ' + distanceMetrics.join(', '));\n const availableAggregationFunctions = Object.values(WEBGSLAGGREGATION);\n if (!availableAggregationFunctions.includes(aggregationFunction))\n throw new Error('Invalid aggregation function provided: ' + aggregationFunction);\n const numOfColumns = entryList.length; // number of columns\n if (numOfColumns === 0)\n throw new Error('No columns provided. Please provide at least one column of data.');\n const device = yield getGPUDevice();\n if (!device)\n return null;\n // device may be lost\n let deviceLost = false;\n device.lost.then(() => {\n deviceLost = true;\n });\n const listSize = entryList[0].length; // size of each list (or column)\n const processInfo = entryList.map((entry, i) => {\n return webGPUProcessInfo(entry, distanceMetrics[i], i, options[i]);\n });\n if (numOfColumns === 1)\n aggregationFunction = WEBGSLAGGREGATION.MANHATTAN; // save a bit of time\n // combine all struct types into one to put into the suppInfo struct.\n let suppInfoWgsl = processInfo.map((info) => info.suppInfoStructWgsl)\n .filter((wgsl) => !!wgsl && wgsl != '').join(',\\n');\n // structures in wgsl must have at least one member, so if we have no structures, we need to add a dummy one\n let needsDummy = false;\n if (!suppInfoWgsl || suppInfoWgsl.trim() == '') {\n needsDummy = true;\n suppInfoWgsl = '\\ndummy: f32\\n';\n }\n // combine all complexities into one\n const combinedComplexity = processInfo.reduce((a, b) => a + b.complexity, 0);\n // combine all data wgsl struct code into one\n const dataWgsl = processInfo.map((info) => info.dataStructWgsl).filter((wgsl) => !!wgsl && wgsl != '').join(',\\n');\n // combine all array sizes into one array (easier for setting)\n const arraySizes = new Uint32Array(numOfColumns * listSize);\n processInfo.forEach((info, i) => {\n arraySizes.set(info.arraySizes, i * listSize);\n }); // array.flat is not as optimized as this\n // if we try to map large knn directly from GPU, sometimes, device disconnects. so we need to do it in chunks, a good number\n // we found is 10000. So we will perform computations in chunks of 10000.\n const computationsPerPass = 10000;\n // also, as the computation per thread takes some time, we also need to divide the work into smaller chunks. meaning\n // that we will divide nummper of pair computations per pass. start and end of the pair comparisons will be stored in startAtEndAt buffer (vec4<u32>) as z and w coordinates.\n const pairComparisonsPerPass = Math.ceil(10000 / combinedComplexity);\n const workGroupDivision = 10; // how many threads inside of one workgroup dimension (in this case 10 * 10 threads per workgroup)\n const threadsPerWorkgroup = workGroupDivision * workGroupDivision;\n const workgroupsDim = Math.ceil(Math.sqrt(Math.ceil(computationsPerPass / threadsPerWorkgroup))); // how many workgroups per 2d dimension\n const globalThreadDimSize = workgroupsDim * workGroupDivision; // how many threads per 2d dimension\n // console.log(getCombinedDistanceScript(distanceMetrics, processInfo.map((info) => info.maxEntryLen), knnSize, aggregationFunction));\n // return;\n const resultIndexes = new Array(listSize)\n .fill(null)\n .map(() => new Uint32Array(knnSize));\n const resultDistances = new Array(listSize)\n .fill(null)\n .map(() => new Float32Array(knnSize));\n const module = device.createShaderModule({\n label: 'KNN compute shader',\n code: `\n // this struct will contain all the info about the computation, startAtEndAt will contain the start and end of the knnDistances and knnIndexes.\n // array of sizes for each entries, and the main data as arrays of arrays called data0, data1 and so on. good thing is that because the first entry is vec4<u32>,\n // there will be no paddings, so no need to worry about padding data. also, arrays and matrices get stucked together, so no padding there as well.\n // what we need to worry about is the padding of overall struct. the size of overall struct will be factor of 16 bytes, so keep that in mind.\n struct ComputeInfo {\n // the x coordinate will contain the start index of the knnDistances and knnIndexes, while y will contain the end index \n // the z coordinate will contain the start of the pair comparisons, while w will contain the end of the pair comparisons\n // just keep in mind that this vec4 will be in first 16 bytes of corresponding buffer.\n startAtEndAt: vec4<u32>,\n // the ACTUALLY sizes of each entry\n entrySizes: array<array<u32, ${listSize}>, ${numOfColumns}>,\n // the weights for each entry\n weights: array<f32, ${numOfColumns}>,\n // the data for each entry\n ${dataWgsl} // an example of the dataWgsl would be:\n //data0: array<array<u32,20>,100>,\n //data1: array<array<u32,20>,100>\n };\n\n struct SuppInfo {\n // struct containing all the supplementary info, like scoring matrix, alphabet indexes, range, etc.\n ${suppInfoWgsl}\n };\n \n @group(0) @binding(0) var<storage, read_write> knnIndexes: array<array<u32, ${knnSize}>, ${computationsPerPass}>;\n @group(0) @binding(1) var<storage, read_write> knnDistances: array<array<f32, ${knnSize}>, ${computationsPerPass}>; // each time just compute for a subset of the list\n @group(0) @binding(2) var<storage, read_write> computeInfo: ComputeInfo;\n @group(0) @binding(3) var<storage, read_write> suppInfo: SuppInfo;\n \n @compute @workgroup_size(${workGroupDivision}, ${workGroupDivision}) fn calcKNN(\n @builtin(global_invocation_id) id: vec3<u32>\n ) {\n ${needsDummy ? `let otherDummy = suppInfo.dummy * 2;` : ''} // just to make sure that the suppInfo is not optimized out\n let col = id.x; //* ${workGroupDivision} + localId.x;\n let row = id.y; //* ${workGroupDivision} + localId.y;\n let graphIndex = row * ${globalThreadDimSize} + col;\n let index = graphIndex + computeInfo.startAtEndAt.x; // add the starting index of the knnDistances and knnIndexes\n \n if (index >= min(${listSize}u, computeInfo.startAtEndAt.y)) {return;}\n \n let pairComparisonStartAt = computeInfo.startAtEndAt.z;\n let pairComparisonEndAt = min(computeInfo.startAtEndAt.w, ${listSize}u);\n \n \n // only clear the knnDistances and knnIndexes if we are at the start of the pair comparison\n if (pairComparisonStartAt == 0u) {\n for (var i = 0u; i < ${knnSize}; i = i + 1u) {\n knnDistances[graphIndex][i] = 99999.0;\n knnIndexes[graphIndex][i] = 0u;\n }\n }\n \n for (var i: u32 = pairComparisonStartAt; i < pairComparisonEndAt; i = i + 1u) {\n if (i == index) {continue;}\n let dist = combinedDistance(index, i);\n insertKnn(graphIndex, dist, i);\n }\n \n }\n // this will generate the distance script for each distance metric and then combine them into one\n ${getCombinedDistanceScript(distanceMetrics, processInfo.map((info) => info.maxEntryLen), knnSize, aggregationFunction)}\n \n fn insertKnn(knnIndex: u32, dist: f32, index: u32) {\n // small optimization, if the distance is larger than the last element in the knnDistances, we can skip\n if (dist >= knnDistances[knnIndex][${knnSize} - 1u]) {return;}\n for (var i = 0u; i < ${knnSize}; i = i + 1u) {\n if (dist < knnDistances[knnIndex][i]) {\n for (var j = ${knnSize} - 1u; j > i; j = j - 1u) {\n knnDistances[knnIndex][j] = knnDistances[knnIndex][j - 1u];\n knnIndexes[knnIndex][j] = knnIndexes[knnIndex][j - 1u];\n }\n knnDistances[knnIndex][i] = dist;\n knnIndexes[knnIndex][i] = index;\n return;\n }\n }\n }\n `,\n });\n const pipeline = device.createComputePipeline({\n label: 'hamming compute pipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'calcKNN',\n },\n });\n // calculate the size of computeInfo struct buffer in terms of 32bit values\n // startAtEndAt=4, entrySizes, weights, data0 + data1 + ...\n const computeInfo32Size = 4 + numOfColumns * listSize + numOfColumns + processInfo.reduce((a, b) => a + b.sourceArraySize, 0);\n // calculate the size of suppInfo struct buffer in terms of 32bit values\n const suppInfo32Size = processInfo.reduce((a, b) => a + b.suppInfoSize, 0);\n // create a buffer on the GPU to hold computeInfo\n // beware that struct must be padded to 16 bytes, so we need to calculate the size of the struct in 32bit values\n const computeInfoBufferSize = computeInfo32Size * Uint32Array.BYTES_PER_ELEMENT;\n let paddedComputeInfoBufferSize = computeInfoBufferSize;\n const remainder = computeInfoBufferSize & 15; // check if the size is a multiple of 16\n if (remainder !== 0)\n paddedComputeInfoBufferSize += 16 - remainder; // pad the size accordingly\n const computeInfoBuffer = device.createBuffer({\n label: 'compute info buffer',\n size: paddedComputeInfoBufferSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedComputeInfoArrayBuffer = computeInfoBuffer.getMappedRange(); // get full buffer\n // create vars to hold startAtEndAt\n let startAt = 0;\n let endAt = computationsPerPass;\n let pairComparisonStartAt = 0;\n let pairComparisonEndAt = pairComparisonsPerPass;\n const startAtEndAtSize = 4;\n // copy the data into the buffer at correct places\n let computeInfoOffSet = 0;\n const startAtEndAtView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, startAtEndAtSize); //new Uint32Array(computeInfoBuffer.getMappedRange(computeInfoOffSet, 4 * Uint32Array.BYTES_PER_ELEMENT));\n startAtEndAtView.set([startAt, endAt, pairComparisonStartAt, pairComparisonEndAt]);\n // write entry sizes\n computeInfoOffSet += startAtEndAtSize * Uint32Array.BYTES_PER_ELEMENT;\n const entrySizesView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, arraySizes.length); //new Uint32Array(computeInfoBuffer.getMappedRange(computeInfoOffSet, arraySizes.byteLength));\n entrySizesView.set(arraySizes);\n // write weights\n computeInfoOffSet += arraySizes.byteLength; // arraySizes.length * Uint32Array.BYTES_PER_ELEMENT;\n const weightsView = new Float32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, numOfColumns); //new Float32Array(computeInfoBuffer.getMappedRange(computeInfoOffSet, numOfColumns * Float32Array.BYTES_PER_ELEMENT));\n weightsView.set(weights);\n // write data\n computeInfoOffSet += numOfColumns * Float32Array.BYTES_PER_ELEMENT;\n for (const info of processInfo) {\n //device.queue.writeBuffer(computeInfoBuffer, computeInfoOffSet, info.flatSourceArray, 0, chunkByteSize);\n const ArrayConstructor = info.EncodedArrayConstructor;\n const chunkSize = info.sourceArraySize;\n const dataView = new ArrayConstructor(mappedComputeInfoArrayBuffer, computeInfoOffSet, chunkSize); //new ArrayConstructor(computeInfoBuffer.getMappedRange(computeInfoOffSet, chunkByteSize));\n dataView.set(info.flatSourceArray);\n computeInfoOffSet += chunkSize * ArrayConstructor.BYTES_PER_ELEMENT;\n }\n // we are done at this point.\n computeInfoBuffer.unmap();\n // create a buffer on the GPU to hold suppInfo\n // same here, we need to pad the size of the struct to 16 bytes\n const suppInfoBufferSize = suppInfo32Size * Uint32Array.BYTES_PER_ELEMENT;\n let paddedSuppInfoBufferSize = suppInfoBufferSize;\n const suppInfoRemainder = suppInfoBufferSize & 15; // check if the size is a multiple of 16\n if (suppInfoRemainder !== 0)\n paddedSuppInfoBufferSize += 16 - suppInfoRemainder; // pad the size accordingly\n paddedSuppInfoBufferSize = Math.max(paddedSuppInfoBufferSize, 16);\n const suppInfoBuffer = device.createBuffer({\n label: 'supp info buffer',\n size: paddedSuppInfoBufferSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedSuppInfoArrayBuffer = suppInfoBuffer.getMappedRange(); // get full buffer\n let suppInfoOffSet = 0;\n for (const info of processInfo) {\n if (info.suppInfoBuffer && info.suppInfoBuffer.byteLength > 0 && info.suppInfoSize > 0) {\n const ArrayConstructor = info.suppInfoType === \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */ ? Uint32Array : Float32Array;\n const suppInfoView = new ArrayConstructor(mappedSuppInfoArrayBuffer, suppInfoOffSet, info.suppInfoBuffer.length); //new ArrayConstructor(suppInfoBuffer.getMappedRange(suppInfoOffSet, info.suppInfoBuffer.byteLength));\n suppInfoView.set(info.suppInfoBuffer);\n suppInfoOffSet += info.suppInfoBuffer.byteLength; // info.suppInfoBuffer.length * ArrayConstructor.BYTES_PER_ELEMENT;\n }\n }\n if (suppInfoOffSet === 0) {\n const dummyView = new Uint32Array(mappedSuppInfoArrayBuffer, 0, 4); //new Uint32Array(suppInfoBuffer.getMappedRange(0, 16));\n dummyView.set([1, 1, 1, 1]);\n }\n suppInfoBuffer.unmap();\n const outKnnArraySize = knnSize * Uint32Array.BYTES_PER_ELEMENT * computationsPerPass; // size of the slice of the knnIndexes and knnDistances\n // create a buffer on the GPU to hold knnIndexes and knnDistances\n const bufferDistances = device.createBuffer({\n label: 'buffer distances',\n size: outKnnArraySize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n const bufferIndexes = device.createBuffer({\n label: 'buffer indexes',\n size: outKnnArraySize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n // no need to copy anything to the knn buffers.\n const bytesPerOutArrayRow = knnSize * Uint32Array.BYTES_PER_ELEMENT; // how many bytes one row of the knnDistances and knnIndexes will take\n // Setup a bindGroup to tell the shader which\n // buffer to use for the computation\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for knn buffer',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: bufferIndexes } },\n { binding: 1, resource: { buffer: bufferDistances } },\n { binding: 2, resource: { buffer: computeInfoBuffer } },\n { binding: 3, resource: { buffer: suppInfoBuffer } },\n // { binding: 4, resource: { buffer: arraySizesBuffer } },\n ],\n });\n //create a buffer on the GPU to get a copy of the results\n const resultBufferDistances = device.createBuffer({\n label: 'result buffer distances',\n size: bufferDistances.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n const resultBufferIndexes = device.createBuffer({\n label: 'result buffer indexes',\n size: bufferIndexes.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n for (let iter = 0; iter < Math.ceil(listSize / computationsPerPass); iter++) {\n startAt = iter * computationsPerPass;\n endAt = Math.min((iter + 1) * computationsPerPass, listSize);\n const pairComparisonPasses = Math.ceil(listSize / pairComparisonsPerPass);\n for (let pairIter = 0; pairIter < pairComparisonPasses; pairIter++) {\n pairComparisonStartAt = pairIter * pairComparisonsPerPass;\n pairComparisonEndAt = Math.min((pairIter + 1) * pairComparisonsPerPass, listSize);\n // write only four values to the buffer, startAt, endAt, pairComparisonStartAt, pairComparisonEndAt, corresponding to vec4<u32> at the start of info struct\n device.queue.writeBuffer(computeInfoBuffer, 0, new Uint32Array([\n startAt,\n endAt,\n pairComparisonStartAt,\n pairComparisonEndAt,\n ]));\n // Encode commands to do the computation\n const encoder = device.createCommandEncoder({\n label: 'distance encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'distance compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(workgroupsDim, \n //workgroupsDim,\n Math.ceil(computationsPerPass / workgroupsDim / threadsPerWorkgroup));\n pass.end();\n // if we are at the last pair comparison pass, we need to read the results\n if (pairIter === pairComparisonPasses - 1) {\n // Encode a command to copy the results to a mappable buffer.\n encoder.copyBufferToBuffer(bufferDistances, 0, resultBufferDistances, 0, resultBufferDistances.size);\n encoder.copyBufferToBuffer(bufferIndexes, 0, resultBufferIndexes, 0, resultBufferIndexes.size);\n // Finish encoding and submit the commands\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n // Read the results\n //console.time('pass end');\n yield device.queue.onSubmittedWorkDone();\n // console.timeEnd('pass end');\n // console.time(\"read\");\n //const offsetBytes = startAt * bytesPerOutArrayRow;\n //const sizeBytes = (endAt - startAt) * bytesPerOutArrayRow;\n yield resultBufferDistances.mapAsync(GPUMapMode.READ);\n yield resultBufferIndexes.mapAsync(GPUMapMode.READ);\n // console.timeEnd(\"read\");\n const indexes = resultBufferIndexes.getMappedRange();\n const distances = resultBufferDistances.getMappedRange();\n // console.time(\"decode\");\n for (let i = 0; i < endAt - startAt; i++) {\n const index = new Uint32Array(indexes, i * bytesPerOutArrayRow, knnSize);\n const distance = new Float32Array(distances, i * bytesPerOutArrayRow, knnSize);\n resultIndexes[startAt + i].set(index);\n resultDistances[startAt + i].set(distance);\n }\n resultBufferIndexes.unmap();\n resultBufferDistances.unmap();\n }\n else {\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n // Read the results\n // console.time('pass between');\n yield device.queue.onSubmittedWorkDone();\n // console.timeEnd('pass between');\n }\n // device may get lost during opperation, so in this case, we need to return null\n if (deviceLost)\n return null;\n }\n }\n bufferDistances.destroy();\n bufferIndexes.destroy();\n computeInfoBuffer.destroy();\n suppInfoBuffer.destroy();\n resultBufferDistances.destroy();\n resultBufferIndexes.destroy();\n if (deviceLost)\n return null;\n return { knnIndexes: resultIndexes, knnDistances: resultDistances };\n });\n}\nfunction getCombinedDistanceScript(distanceMetrics, maxEntryLens, knnSize, aggregation) {\n const distanceWgsls = distanceMetrics.map((metric, i) => {\n return `\n fn distanceScript${i}(aIndex: u32, bIndex: u32) -> f32 {\n let a = computeInfo.data${i}[aIndex];\n let b = computeInfo.data${i}[bIndex];\n let maxDistance: f32 = knnDistances[aIndex - computeInfo.startAtEndAt.x][${knnSize} - 1u];\n ${webGPUFunctions[metric](maxEntryLens[i], i)}\n }\n `;\n });\n const allDistanceScripts = distanceWgsls.join('\\n');\n const combineDistancesScript = `\n fn combinedDistance(aIndex: u32, bIndex: u32) -> f32 {\n var distances: array<f32, ${distanceMetrics.length}>;\n ${distanceMetrics.map((_, i) => `distances[${i}] = distanceScript${i}(aIndex, bIndex);`).join('\\n')}\n ${WEBGSLAGGREGATIONFUNCTIONS[aggregation](distanceMetrics.length)}\n }\n \n `;\n return allDistanceScripts + '\\n' + combineDistancesScript;\n}\n//# sourceMappingURL=multiCol-KNN.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 max-len */\nimport { distanceFunctionComplexity, TypeSupportedDistances, WEBGPUDISTANCE } from '../multi-col-distances/webGPU-multicol-distances';\nexport function webGPUProcessInfo(entryList, distanceMetric = WEBGPUDISTANCE.HAMMING, entryIndex, // index of the entries in the list of lists that we want to process\noptions = { gapOpenPenalty: 1.0, gapExtensionPenalty: 0.6 }) {\n var _a, _b;\n let entryType = null;\n const encodedList = (() => {\n if (entryList.some((e) => typeof e === 'string')) {\n entryType = \"STRING\" /* WGPUENTRYTYPE.STRING */;\n return entryList.map((entry) => new Uint32Array(entry.split('').map((c) => c.charCodeAt(0))));\n }\n if (entryList.some((e) => typeof e === 'number')) {\n entryType = \"NUMBER\" /* WGPUENTRYTYPE.NUMBER */;\n return entryList.map((entry) => new Float32Array([entry]));\n }\n if (typeof entryList[0] == 'object' && entryList.some((e) => '_data' in e && '_length' in e)) {\n entryType = \"BITARRAY\" /* WGPUENTRYTYPE.BITARRAY */;\n return entryList.map((entry) => entry._data);\n }\n if (entryList.some((e) => e instanceof Float32Array)) {\n entryType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n return entryList;\n }\n if (entryList.some((e) => e instanceof Uint32Array)) {\n entryType = \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */;\n return entryList;\n }\n if (entryList.some((e) => e instanceof Int32Array)) {\n entryType = \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */;\n return entryList;\n }\n //return entryList as Uint32Array[];\n })();\n if (!encodedList || !entryType)\n throw new Error('Invalid entry type, could not determine entry type from input list');\n const encodedListType = encodedList[0] instanceof Int32Array ? \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */ :\n encodedList[0] instanceof Float32Array ? \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */ : \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */;\n // sizes of each entries might differ, so we need to keep track of that for some distance metrics, like hamming for example\n const arraySizes = new Uint32Array(encodedList.map((arr) => arr.length));\n if (!TypeSupportedDistances[entryType] || !TypeSupportedDistances[entryType].has(distanceMetric))\n throw new Error(`Distance metric '${distanceMetric}' not supported for entry type '${entryType}'`);\n const maxEntryLen = arraySizes.reduce((a, b) => Math.max(a, b), 0);\n // get the complexity of used algorithm\n const complexity = distanceFunctionComplexity[distanceMetric](maxEntryLen);\n const EncodedArrayConstructor = encodedListType === \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */ ? Int32Array :\n (encodedListType === \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */ ? Float32Array : Uint32Array);\n const flatSourceArray = new EncodedArrayConstructor(encodedList.length * maxEntryLen);\n // when setting, we need to set each array at a specific offset, which is controlled by maxArrayLen because each array might have different sizes.\n // this way we will get correct matrix representation in the compute shader\n encodedList.forEach((seq, i) => {\n flatSourceArray.set(seq, i * maxEntryLen);\n });\n // NB! all this before the line was generic, now we need to calculate some specific things for some specific distance metrics\n // initialize supp info line that will be included in the final shader;\n let suppInfoStructWgsl = ''; // the code that will be included in the struct of suppInfo\n let suppInfoSize = 0;\n let suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n let suppInfoBuffer = null;\n if (distanceMetric === WEBGPUDISTANCE.NEEDLEMAN_WUNSCH || distanceMetric === WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE) {\n let maxMonomerIndex = options.scoringMatrix && options.alphabetIndexes ?\n Object.keys(options.alphabetIndexes).reduce((prev, n) => Math.max(prev, n.charCodeAt(0)), 0) : -1;\n // generate default similarity matrix if it is not provided\n if (!options.alphabetIndexes || !options.scoringMatrix) {\n for (let i = 0; i < flatSourceArray.length; i++) {\n if (flatSourceArray[i] > maxMonomerIndex)\n maxMonomerIndex = flatSourceArray[i];\n }\n options.scoringMatrix =\n new Array(maxMonomerIndex + 1).fill(null).map(() => new Array(maxMonomerIndex + 1).fill(0));\n options.alphabetIndexes = {};\n for (let i = 0; i < options.scoringMatrix.length; i++) {\n options.scoringMatrix[i][i] = 1;\n options.alphabetIndexes[String.fromCharCode(i)] = i;\n }\n }\n const similarityMatrixSize = (maxMonomerIndex + 1) * (maxMonomerIndex + 1);\n const transferedSimilarityMatrix = new Array(maxMonomerIndex + 1).fill(null).map(() => new Float32Array(maxMonomerIndex + 1));\n // set diagonal to 1\n for (let i = 0; i < maxMonomerIndex + 1; i++)\n transferedSimilarityMatrix[i][i] = 1;\n const alphabetIndexes = options.alphabetIndexes;\n for (const key of Object.keys(alphabetIndexes)) {\n for (const key2 of Object.keys(alphabetIndexes)) {\n if (key === key2)\n continue;\n transferedSimilarityMatrix[key.charCodeAt(0)][key2.charCodeAt(0)] =\n options.scoringMatrix[alphabetIndexes[key]][alphabetIndexes[key2]];\n }\n }\n // in memory layout, we will have 2 float32 s for gapOpen and gapExtension penalties, and then f32 array<array<f32>> for similarity matrix.\n // because of primitives, there will be no padding, so we can calculate the size directly\n suppInfoSize = 2 + similarityMatrixSize;\n suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n suppInfoBuffer = new Float32Array(suppInfoSize);\n suppInfoBuffer[0] = (_a = options.gapOpenPenalty) !== null && _a !== void 0 ? _a : 1.0;\n suppInfoBuffer[1] = (_b = options.gapExtensionPenalty) !== null && _b !== void 0 ? _b : 0.6;\n let offset = 2;\n for (let i = 0; i < transferedSimilarityMatrix.length; i++) {\n suppInfoBuffer.set(transferedSimilarityMatrix[i], offset);\n offset += transferedSimilarityMatrix[i].length;\n }\n suppInfoStructWgsl = `\n gapOpenPenalty${entryIndex}: f32,\n gapExtensionPenalty${entryIndex}: f32,\n similarityMatrix${entryIndex}: array<array<f32, ${maxMonomerIndex + 1}>, ${maxMonomerIndex + 1}>`;\n }\n else if (distanceMetric === WEBGPUDISTANCE.Difference) {\n // for difference, we need range of values for normalization of the difference\n if (!options.range || typeof options.range !== 'number' || options.range <= 0) {\n const min = flatSourceArray.reduce((a, b) => Math.min(a, b), flatSourceArray[0]);\n const max = flatSourceArray.reduce((a, b) => Math.max(a, b), flatSourceArray[0]);\n options.range = max - min;\n }\n if (options.range <= 0)\n options.range = 1.0; // this means that all values are the same, and all distances will produce 0.\n suppInfoSize = 1;\n suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n suppInfoBuffer = new Float32Array([options.range]);\n suppInfoStructWgsl = `\n range${entryIndex}: f32`;\n }\n const dataTypeWGSL = flatSourceArray instanceof Int32Array ? 'i32' : (flatSourceArray instanceof Float32Array ? 'f32' : 'u32');\n const dataStructWgsl = `data${entryIndex}: array<array<${dataTypeWGSL}, ${maxEntryLen}>, ${encodedList.length}>`;\n // for now, other distances do not require any additional information, so we can skip that\n return {\n flatSourceArray,\n sourceArraySize: flatSourceArray.length,\n maxEntryLen,\n arraySizes,\n complexity,\n suppInfoBuffer,\n suppInfoSize,\n suppInfoType: suppInfoType,\n suppInfoStructWgsl,\n entryType,\n dataTypeWGSL,\n dataStructWgsl,\n EncodedArrayConstructor\n };\n}\n//# sourceMappingURL=webGPU-process-info.js.map","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 { getGPUDevice } from '../getGPUDevice';\nimport { knnMatrixOpInfoWGSL } from './wgsl/knn-sparse-info.wgsl';\n/**\n * this will get all the info needed for subsequent operation in umap\n * like sizes of each array of transposed knn and sizes of union of knn and its transpose rows.\n * after this point, all knn structures will be in single array form, with corresponding offsets.\n * @param knnIndexes\n * @returns\n */\nexport function getKnnSparseOpInfo(knnIndexes) {\n return __awaiter(this, void 0, void 0, function* () {\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const numOfEntries = knnIndexes.length;\n const requiredWorkgroups = Math.ceil(numOfEntries / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const knnSize = knnIndexes[0].length;\n const processWgsl = knnMatrixOpInfoWGSL(threadsPerWorkgroupDim, threadsPerWorkgroupDim * numOfWorkgroupsPerDim, numOfEntries, knnSize);\n const indexesBuffer32Size = numOfEntries * knnIndexes[0].length;\n const device = yield getGPUDevice();\n if (device == null)\n return;\n const module = device.createShaderModule({\n label: 'transposedSizesCalulation',\n code: processWgsl\n });\n const pipeline = device.createComputePipeline({\n label: 'transposedSizesPipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'countTransposedCols',\n },\n });\n const indexBuffer = device.createBuffer({\n label: 'indexes buffer',\n size: indexesBuffer32Size * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedIndexesBuffer = indexBuffer.getMappedRange();\n const mappedIndexesArray = new Int32Array(mappedIndexesBuffer);\n for (let i = 0; i < knnIndexes.length; i++)\n mappedIndexesArray.set(knnIndexes[i], i * knnIndexes[i].length);\n indexBuffer.unmap();\n const sizesBuffer = device.createBuffer({\n label: 'transpose sizes buffer',\n size: knnIndexes.length * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n });\n const unionSizesBuffer = device.createBuffer({\n label: 'union sizes buffer',\n size: knnIndexes.length * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedUnionSizesBuffer = unionSizesBuffer.getMappedRange();\n const mappedUnionSizesArray = new Uint32Array(mappedUnionSizesBuffer);\n mappedUnionSizesArray.fill(knnSize);\n unionSizesBuffer.unmap();\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for count ops',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: indexBuffer } },\n { binding: 1, resource: { buffer: sizesBuffer } },\n { binding: 2, resource: { buffer: unionSizesBuffer } }\n // { binding: 4, resource: { buffer: arraySizesBuffer } },\n ],\n });\n const encoder = device.createCommandEncoder({\n label: 'matrix ops encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'matrix ops compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n const resultTransposeSizesBuffer = device.createBuffer({\n label: 'result transpose sizes',\n size: sizesBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n const resultUnionSizesBuffer = device.createBuffer({\n label: 'result union sizes',\n size: unionSizesBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n encoder.copyBufferToBuffer(sizesBuffer, 0, resultTransposeSizesBuffer, 0, resultTransposeSizesBuffer.size);\n encoder.copyBufferToBuffer(unionSizesBuffer, 0, resultUnionSizesBuffer, 0, resultUnionSizesBuffer.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n yield resultTransposeSizesBuffer.mapAsync(GPUMapMode.READ);\n yield resultUnionSizesBuffer.mapAsync(GPUMapMode.READ);\n const resultTransposeSizesArrayBuffer = resultTransposeSizesBuffer.getMappedRange();\n const resultUnionSizesArrayBuffer = resultUnionSizesBuffer.getMappedRange();\n const resultTransposeSizesArray = new Uint32Array(knnIndexes.length);\n resultTransposeSizesArray.set(new Uint32Array(resultTransposeSizesArrayBuffer, 0, knnIndexes.length));\n resultTransposeSizesBuffer.unmap();\n const resultUnionSizesArray = new Uint32Array(knnIndexes.length);\n resultUnionSizesArray.set(new Uint32Array(resultUnionSizesArrayBuffer, 0, knnIndexes.length));\n resultUnionSizesBuffer.unmap();\n const unionMatrixSize = resultUnionSizesArray.reduce((old, val) => old + val, 0);\n resultUnionSizesBuffer.destroy();\n resultTransposeSizesBuffer.destroy();\n sizesBuffer.destroy();\n indexBuffer.destroy();\n unionSizesBuffer.destroy();\n // sizes of each transposed knn row, sizes of each union of knn and its transpose row, total size of union matrix\n return { resultTransposeSizesArray, resultUnionSizesArray, unionMatrixSize };\n //counteTransposedCols\n });\n}\n//# sourceMappingURL=knn-sparse-info.js.map","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 { getGPUDevice } from '../getGPUDevice';\n/* eslint-disable max-len */\n/**\n * wgsl code for pairwise operation on two sparse matrices.\n * @param indexes1 - indexes of first sparse matrix\n * @param distances1 - values1 of first sparse matrix\n * @param offsets1 - 32 bit offsets of first sparse matrix\n * @param indexes2 - indexes of second sparse matrix\n * @param distances2 - values of second sparse matrix\n * @param offsets2 - 32 bit offsets of second sparse matrix\n * @param numOfEntries - number of entries in original data\n * @param unionMatrixOffsets - offsets of union matrix, used to store result\n * @param op - operation to perform\n * @returns\n */\nexport function pairwiseOpSparse(indexes1, distances1, offsets1, indexes2, distances2, offsets2, numOfEntries, unionMatrixOffsets, // array of size numOfEntries + 1\nop) {\n return __awaiter(this, void 0, void 0, function* () {\n // this function is only meant for regular knn matrix, not for sparse matrix for of knn.\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const requiredWorkgroups = Math.ceil(numOfEntries / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const threadsPerYDimension = threadsPerWorkgroupDim * numOfWorkgroupsPerDim;\n const sparseSize1 = offsets1[offsets1.length - 1];\n const sparseSize2 = offsets2[offsets2.length - 1];\n // this array will have offsets of each row in union matrix with length of numOfEntries + 1\n const unionMatrixSize = unionMatrixOffsets[unionMatrixOffsets.length - 1]; // last index will be last offset i.e. full size\n const processWgsl = `\n struct SparseKNNStorage1 {\n indexes:array<i32, ${sparseSize1}>,\n knnDistances: array<f32, ${sparseSize1}>,\n offsets: array<u32, ${numOfEntries + 1}>\n }\n\n struct SparseKNNStorage2 {\n indexes:array<i32, ${sparseSize2}>,\n knnDistances: array<f32, ${sparseSize2}>,\n offsets: array<u32, ${numOfEntries + 1}>\n }\n\n struct ResKnn {\n knnIndexes: array<i32, ${unionMatrixSize}>,\n knnDistances: array<f32, ${unionMatrixSize}>\n }\n\n @group(0) @binding(0) var<storage, read_write> source1: SparseKNNStorage1;\n @group(0) @binding(1) var<storage, read_write> source2: SparseKNNStorage2;\n @group(0) @binding(2) var<storage, read_write> result: ResKnn;\n @group(0) @binding(3) var<storage, read_write> unionMatrixOffsets: array<u32, ${numOfEntries + 1}>;\n @compute @workgroup_size(${threadsPerWorkgroupDim}, ${threadsPerWorkgroupDim}) fn pairwiseOp(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n\n let col: u32 = id.x;\n let row: u32 = id.y;\n let workingIndex: u32 = row * ${threadsPerYDimension} + col;\n\n if (workingIndex >= ${numOfEntries}) {\n return;\n }\n var curUnionOffset: u32 = unionMatrixOffsets[workingIndex]; // offset at which to start writing in union matrix\n\n let start1 = source1.offsets[workingIndex];\n let end1 = source1.offsets[workingIndex + 1];\n let start2 = source2.offsets[workingIndex];\n let end2 = source2.offsets[workingIndex + 1];\n // TODO: sort a copy of these arrays, will make operation faster\n for (var i: u32 = start1; i < end1; i++) {\n let val1: f32 = source1.knnDistances[i];\n var val2: f32 = 0.0;\n let curIndex: i32 = source1.indexes[i];\n for (var j: u32 = start2; j < end2; j++) {\n if (source2.indexes[j] == curIndex) {\n val2 = source2.knnDistances[j];\n break;\n }\n }\n \n result.knnIndexes[curUnionOffset] = curIndex;\n result.knnDistances[curUnionOffset] = val1 ${op} val2;\n curUnionOffset += 1;\n }\n\n if (curUnionOffset >= unionMatrixOffsets[workingIndex + 1]) {\n // small optimization applicable only to our case, but saves a good amount of time\n return;\n }\n\n // do the same for source2 but skip the indexes where they are already present in source1\n for (var i: u32 = start2; i < end2; i++) {\n let val1: f32 = source2.knnDistances[i];\n let curIndex: i32 = source2.indexes[i];\n var found = false;\n for (var j: u32 = start1; j < end1; j++) {\n if (source1.indexes[j] == curIndex) {\n found = true;\n break;\n }\n }\n if (!found) {\n result.knnIndexes[curUnionOffset] = curIndex;\n result.knnDistances[curUnionOffset] = val1 ${op} 0.0;\n curUnionOffset += 1;\n }\n }\n }\n`;\n const storage32Size1 = sparseSize1 * 2 + numOfEntries + 1;\n const storage32Size2 = sparseSize2 * 2 + numOfEntries + 1;\n const resStorage32Size = unionMatrixSize * 2;\n // standard stuff to pad the storage size to multiple of 16 bytes\n let paddedStorage1ByteSize = storage32Size1 * 4;\n const remainder1 = paddedStorage1ByteSize & 15;\n if (remainder1 !== 0)\n paddedStorage1ByteSize += 16 - remainder1;\n let paddedStorage2ByteSize = storage32Size2 * 4;\n const remainder2 = paddedStorage2ByteSize & 15;\n if (remainder2 !== 0)\n paddedStorage2ByteSize += 16 - remainder2;\n let paddedResStorageByteSize = resStorage32Size * 4;\n const remainder3 = paddedResStorageByteSize & 15;\n if (remainder3 !== 0)\n paddedResStorageByteSize += 16 - remainder3;\n const device = yield getGPUDevice();\n if (device == null)\n return;\n const module = device.createShaderModule({\n label: 'pairwiseOpShader',\n code: processWgsl\n });\n const pipeline = device.createComputePipeline({\n label: 'pairwiseOpPipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'pairwiseOp',\n },\n });\n // input params\n const source1Buffer = device.createBuffer({\n label: 'source 1 buffer',\n size: paddedStorage1ByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedSource1Buffer = source1Buffer.getMappedRange();\n const source1IndexesArray = new Int32Array(mappedSource1Buffer, 0, sparseSize1);\n source1IndexesArray.set(indexes1);\n const source1DistancesArray = new Float32Array(mappedSource1Buffer, sparseSize1 * 4, sparseSize1);\n source1DistancesArray.set(distances1);\n const source1OffsetsArray = new Uint32Array(mappedSource1Buffer, sparseSize1 * 8, numOfEntries + 1);\n source1OffsetsArray.set(offsets1);\n source1Buffer.unmap();\n const source2Buffer = device.createBuffer({\n label: 'source 2 buffer',\n size: paddedStorage2ByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedSource2Buffer = source2Buffer.getMappedRange();\n const source2IndexesArray = new Int32Array(mappedSource2Buffer, 0, sparseSize2);\n source2IndexesArray.set(indexes2);\n const source2DistancesArray = new Float32Array(mappedSource2Buffer, sparseSize2 * 4, sparseSize2);\n source2DistancesArray.set(distances2);\n const source2OffsetsArray = new Uint32Array(mappedSource2Buffer, sparseSize2 * 8, numOfEntries + 1);\n source2OffsetsArray.set(offsets2);\n source2Buffer.unmap();\n const resBuffer = device.createBuffer({\n label: 'res buffer',\n size: paddedResStorageByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n });\n const unionMatrixOffsetsBuffer = device.createBuffer({\n label: 'union matrix offsets buffer',\n size: (numOfEntries + 1) * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedUnionMatrixOffsetsBuffer = unionMatrixOffsetsBuffer.getMappedRange();\n const unionMatrixOffsetsArray = new Uint32Array(mappedUnionMatrixOffsetsBuffer);\n unionMatrixOffsetsArray.set(unionMatrixOffsets);\n unionMatrixOffsetsBuffer.unmap();\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for pairwise ops',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: source1Buffer } },\n { binding: 1, resource: { buffer: source2Buffer } },\n { binding: 2, resource: { buffer: resBuffer } },\n { binding: 3, resource: { buffer: unionMatrixOffsetsBuffer } }\n ],\n });\n const encoder = device.createCommandEncoder({\n label: 'matrix ops encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'matrix ops compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n const resultBuffer = device.createBuffer({\n label: 'result buffer',\n size: paddedResStorageByteSize,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n encoder.copyBufferToBuffer(resBuffer, 0, resultBuffer, 0, resultBuffer.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n yield resultBuffer.mapAsync(GPUMapMode.READ);\n const resultArrayBuffer = resultBuffer.getMappedRange();\n const resultKnnIndexes = new Int32Array(unionMatrixSize);\n const resultKnnDistances = new Float32Array(unionMatrixSize);\n // its actually a sparse matrix.\n resultKnnIndexes.set(new Int32Array(resultArrayBuffer, 0, unionMatrixSize));\n resultKnnDistances.set(new Float32Array(resultArrayBuffer, unionMatrixSize * 4, unionMatrixSize));\n resultBuffer.unmap();\n resultBuffer.destroy();\n source1Buffer.destroy();\n source2Buffer.destroy();\n resBuffer.destroy();\n unionMatrixOffsetsBuffer.destroy();\n return { resultKnnIndexes, resultKnnDistances };\n });\n}\n//# sourceMappingURL=pairwise-sparse-ops.js.map","/**\n * the sum of the weighted squares of the errors (or weighted residuals) between the data.y\n * and the curve-fit function.\n * @ignore\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {ArrayLike<number>} parameters - Array of current parameter values\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @param {ArrayLike<number>} weightSquare - Square of weights\n * @return {number}\n */\nexport default function errorCalculation(data, parameters, parameterizedFunction, weightSquare) {\n let error = 0;\n const func = parameterizedFunction(parameters);\n for (let i = 0; i < data.x.length; i++) {\n error += Math.pow(data.y[i] - func(data.x[i]), 2) / weightSquare[i];\n }\n return error;\n}\n//# sourceMappingURL=errorCalculation.js.map","import { inverse, Matrix } from 'ml-matrix';\nimport gradientFunction from './gradientFunction';\n/**\n * Matrix function over the samples\n * @ignore\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {ArrayLike<number>} evaluatedData - Array of previous evaluated function values\n * @return {Matrix}\n */\nfunction matrixFunction(data, evaluatedData) {\n const m = data.x.length;\n let ans = new Matrix(m, 1);\n for (let point = 0; point < m; point++) {\n ans.set(point, 0, data.y[point] - evaluatedData[point]);\n }\n return ans;\n}\n/**\n * Iteration for Levenberg-Marquardt\n * @ignore\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number} damping - Levenberg-Marquardt parameter\n * @param {number|array} gradientDifference - The step size to approximate the jacobian matrix\n * @param {boolean} centralDifference - If true the jacobian matrix is approximated by central differences otherwise by forward differences\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n */\nexport default function step(data, params, damping, gradientDifference, parameterizedFunction, centralDifference, weights) {\n let value = damping;\n let identity = Matrix.eye(params.length, params.length, value);\n const func = parameterizedFunction(params);\n let evaluatedData = new Float64Array(data.x.length);\n for (let i = 0; i < data.x.length; i++) {\n evaluatedData[i] = func(data.x[i]);\n }\n let gradientFunc = gradientFunction(data, evaluatedData, params, gradientDifference, parameterizedFunction, centralDifference);\n let residualError = matrixFunction(data, evaluatedData);\n let inverseMatrix = inverse(identity.add(gradientFunc.mmul(gradientFunc.transpose().scale('row', { scale: weights }))));\n let jacobianWeightResidualError = gradientFunc.mmul(residualError.scale('row', { scale: weights }));\n let perturbations = inverseMatrix.mmul(jacobianWeightResidualError);\n return {\n perturbations,\n jacobianWeightResidualError,\n };\n}\n//# sourceMappingURL=step.js.map","import { Matrix } from 'ml-matrix';\n/**\n * Difference of the matrix function over the parameters\n * @ignore\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {ArrayLike<number>} evaluatedData - Array of previous evaluated function values\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number|array} gradientDifference - The step size to approximate the jacobian matrix\n * @param {boolean} centralDifference - If true the jacobian matrix is approximated by central differences otherwise by forward differences\n * @param {function} paramFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {Matrix}\n */\nexport default function gradientFunction(data, evaluatedData, params, gradientDifference, paramFunction, centralDifference) {\n const nbParams = params.length;\n const nbPoints = data.x.length;\n let ans = Matrix.zeros(nbParams, nbPoints);\n let rowIndex = 0;\n for (let param = 0; param < nbParams; param++) {\n if (gradientDifference[param] === 0)\n continue;\n let delta = gradientDifference[param];\n let auxParams = params.slice();\n auxParams[param] += delta;\n let funcParam = paramFunction(auxParams);\n if (!centralDifference) {\n for (let point = 0; point < nbPoints; point++) {\n ans.set(rowIndex, point, (evaluatedData[point] - funcParam(data.x[point])) / delta);\n }\n }\n else {\n auxParams = params.slice();\n auxParams[param] -= delta;\n delta *= 2;\n let funcParam2 = paramFunction(auxParams);\n for (let point = 0; point < nbPoints; point++) {\n ans.set(rowIndex, point, (funcParam2(data.x[point]) - funcParam(data.x[point])) / delta);\n }\n }\n rowIndex++;\n }\n return ans;\n}\n//# sourceMappingURL=gradientFunction.js.map","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 { levenbergMarquardt } from 'ml-levenberg-marquardt';\nexport function linear(x1, x2, n) {\n const step = (x2 - x1) / (n - 1);\n return Array.from({ length: n }, (_, i) => x1 + step * i);\n}\n/**\n * Fit a, b params for the differentiable curve used in lower\n * dimensional fuzzy simplicial complex construction. We want the\n * smooth curve (from a pre-defined family with simple gradient) that\n * best matches an offset exponential decay.\n */\nexport function findABParams(spread, minDist) {\n const curve = ([a, b]) => (x) => {\n return 1.0 / (1.0 + a * Math.pow(x, (2 * b)));\n };\n const xv = linear(0, spread * 3, 300)\n .map((val) => (val < minDist ? 1.0 : val));\n const yv = new Array(xv.length).fill(0).map((val, index) => {\n const gte = xv[index] >= minDist;\n return gte ? Math.exp(-(xv[index] - minDist) / spread) : val;\n });\n const initialValues = [0.5, 0.5];\n const data = { x: xv, y: yv };\n // Default options for the algorithm (from github example)\n const options = {\n damping: 1.5,\n initialValues,\n gradientDifference: 10e-2,\n maxIterations: 100,\n errorTolerance: 10e-3,\n };\n // eslint-disable-next-line new-cap\n const { parameterValues } = levenbergMarquardt(data, curve, options);\n const [a, b] = parameterValues;\n return { a, b };\n}\n/**\n * heuristic for number of epochs of umap, differs from cpu version, because of the way gpu passes data\n * @param entryLen number of entries\n * @returns\n */\nexport function getNEpochs(entryLen) {\n //\n const length = entryLen;\n if (length <= 2500)\n return 1000;\n else if (length <= 5000)\n return 800;\n else if (length <= 7500)\n return 650;\n else\n return 400;\n}\n/** helper function that transforms array of sizes to offset form */\nexport function toOffsetForm(ar) {\n const res = new Uint32Array(ar.length + 1);\n let offset = 0;\n for (let i = 0; i < ar.length; i++) {\n res[i] = offset;\n offset += ar[i];\n }\n res[ar.length] = offset;\n return res;\n}\n/** multiplies flat representation of sparse knn info by scalar.\n * also no point of doing this on gpu, can be done on cpu pretty quickly.\n * if there will be need for it, it can be done on gpu as well very very easily.\n * @param values values array\n * @param scalar\n */\nexport function multiplyScalar(values, scalar) {\n for (let i = 0; i < values.length; i++)\n values[i] = values[i] * scalar;\n}\n/**\n * generate transpose of knn from the transposition info taken from sparse knn info\n * using this information avoids billions of array.push calls, is much cleaner, allows typed array use and is faster.\n * no point of doing this on gpu, can be done on cpu as we already have all the info needed.\n * @param knnIndexes\n * @param knnDistances\n * @param knnSparseInfo\n * @param knnSize\n * @returns\n */\nexport function transposeKNN(knnIndexes, knnDistances, knnSparseInfo, knnSize = 15) {\n return __awaiter(this, void 0, void 0, function* () {\n const numOfEntries = knnIndexes.length;\n const fullKnnEntrySize = knnSize * numOfEntries;\n const transposeSizes = knnSparseInfo.resultTransposeSizesArray;\n const transposeOffsets = toOffsetForm(transposeSizes);\n const offsetsCopy = new Uint32Array(transposeOffsets.length);\n offsetsCopy.set(transposeOffsets); // will be used for dynamic indexing\n const transposeKNNIndexes = new Int32Array(fullKnnEntrySize).fill(0);\n const transposeKNNDistances = new Float32Array(fullKnnEntrySize).fill(0);\n for (let i = 0; i < numOfEntries; i++) {\n for (let j = 0; j < knnSize; j++) {\n const otherIndex = knnIndexes[i][j];\n const otherIndexOffset = offsetsCopy[otherIndex];\n transposeKNNIndexes[otherIndexOffset] = i;\n transposeKNNDistances[otherIndexOffset] = knnDistances[i][j];\n offsetsCopy[otherIndex] += 1;\n }\n }\n return { transposeKNNIndexes, transposeKNNDistances, transposeOffsets };\n });\n}\n//# sourceMappingURL=utils.js.map","import checkOptions from './checkOptions';\nimport errorCalculation from './errorCalculation';\nimport step from './step';\n/**\n * Curve fitting algorithm\n * @param {{x:ArrayLike<number>, y:ArrayLike<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {function} parameterizedFunction - Takes an array of parameters and returns a function with the independent variable as its sole argument\n * @param {object} options - Options object\n * @param {ArrayLike<number>} options.initialValues - Array of initial parameter values\n * @param {number|ArrayLike<number>} [options.weights = 1] - weighting vector, if the length does not match with the number of data points, the vector is reconstructed with first value.\n * @param {number} [options.damping = 1e-2] - Levenberg-Marquardt parameter, small values of the damping parameter λ result in a Gauss-Newton update and large\nvalues of λ result in a gradient descent update\n * @param {number} [options.dampingStepDown = 9] - factor to reduce the damping (Levenberg-Marquardt parameter) when there is not an improvement when updating parameters.\n * @param {number} [options.dampingStepUp = 11] - factor to increase the damping (Levenberg-Marquardt parameter) when there is an improvement when updating parameters.\n * @param {number} [options.improvementThreshold = 1e-3] - the threshold to define an improvement through an update of parameters\n * @param {number|ArrayLike<number>} [options.gradientDifference = 10e-2] - The step size to approximate the jacobian matrix\n * @param {boolean} [options.centralDifference = false] - If true the jacobian matrix is approximated by central differences otherwise by forward differences\n * @param {ArrayLike<number>} [options.minValues] - Minimum allowed values for parameters\n * @param {ArrayLike<number>} [options.maxValues] - Maximum allowed values for parameters\n * @param {number} [options.maxIterations = 100] - Maximum of allowed iterations\n * @param {number} [options.errorTolerance = 10e-3] - Minimum uncertainty allowed for each point.\n * @param {number} [options.timeout] - maximum time running before throw in seconds.\n * @return {{parameterValues: Array<number>, parameterError: number, iterations: number}}\n */\nexport function levenbergMarquardt(data, parameterizedFunction, options) {\n let { checkTimeout, minValues, maxValues, parameters, weightSquare, damping, dampingStepUp, dampingStepDown, maxIterations, errorTolerance, centralDifference, gradientDifference, improvementThreshold, } = checkOptions(data, parameterizedFunction, options);\n let error = errorCalculation(data, parameters, parameterizedFunction, weightSquare);\n let optimalError = error;\n let optimalParameters = parameters.slice();\n let converged = error <= errorTolerance;\n let iteration = 0;\n for (; iteration < maxIterations && !converged; iteration++) {\n let previousError = error;\n let { perturbations, jacobianWeightResidualError } = step(data, parameters, damping, gradientDifference, parameterizedFunction, centralDifference, weightSquare);\n for (let k = 0; k < parameters.length; k++) {\n parameters[k] = Math.min(Math.max(minValues[k], parameters[k] - perturbations.get(k, 0)), maxValues[k]);\n }\n error = errorCalculation(data, parameters, parameterizedFunction, weightSquare);\n if (isNaN(error))\n break;\n if (error < optimalError - errorTolerance) {\n optimalError = error;\n optimalParameters = parameters.slice();\n }\n let improvementMetric = (previousError - error) /\n perturbations\n .transpose()\n .mmul(perturbations.mul(damping).add(jacobianWeightResidualError))\n .get(0, 0);\n if (improvementMetric > improvementThreshold) {\n damping = Math.max(damping / dampingStepDown, 1e-7);\n }\n else {\n damping = Math.min(damping * dampingStepUp, 1e7);\n }\n if (checkTimeout()) {\n throw new Error(`The execution time is over to ${options.timeout} seconds`);\n }\n converged = error <= errorTolerance;\n }\n return {\n parameterValues: optimalParameters,\n parameterError: optimalError,\n iterations: iteration,\n };\n}\n//# sourceMappingURL=index.js.map","import { isAnyArray } from 'is-any-array';\nexport default function checkOptions(data, parameterizedFunction, options) {\n let { timeout, minValues, maxValues, initialValues, weights = 1, damping = 1e-2, dampingStepUp = 11, dampingStepDown = 9, maxIterations = 100, errorTolerance = 1e-7, centralDifference = false, gradientDifference = 10e-2, improvementThreshold = 1e-3, } = options;\n if (damping <= 0) {\n throw new Error('The damping option must be a positive number');\n }\n else if (!data.x || !data.y) {\n throw new Error('The data parameter must have x and y elements');\n }\n else if (!isAnyArray(data.x) ||\n data.x.length < 2 ||\n !isAnyArray(data.y) ||\n data.y.length < 2) {\n throw new Error('The data parameter elements must be an array with more than 2 points');\n }\n else if (data.x.length !== data.y.length) {\n throw new Error('The data parameter elements must have the same size');\n }\n if (!(initialValues && initialValues.length > 0)) {\n throw new Error('The initialValues option is mandatory and must be an array');\n }\n let parameters = initialValues;\n let nbPoints = data.y.length;\n let parLen = parameters.length;\n maxValues = maxValues || new Array(parLen).fill(Number.MAX_SAFE_INTEGER);\n minValues = minValues || new Array(parLen).fill(Number.MIN_SAFE_INTEGER);\n if (maxValues.length !== minValues.length) {\n throw new Error('minValues and maxValues must be the same size');\n }\n if (typeof gradientDifference === 'number') {\n gradientDifference = new Array(parameters.length).fill(gradientDifference);\n }\n else if (isAnyArray(gradientDifference)) {\n if (gradientDifference.length !== parLen) {\n gradientDifference = new Array(parLen).fill(gradientDifference[0]);\n }\n }\n else {\n throw new Error('gradientDifference should be a number or array with length equal to the number of parameters');\n }\n let filler;\n if (typeof weights === 'number') {\n let value = 1 / weights ** 2;\n filler = () => value;\n }\n else if (isAnyArray(weights)) {\n if (weights.length < data.x.length) {\n let value = 1 / weights[0] ** 2;\n filler = () => value;\n }\n else {\n filler = (i) => 1 / weights[i] ** 2;\n }\n }\n else {\n throw new Error('weights should be a number or array with length equal to the number of data points');\n }\n let checkTimeout;\n if (timeout !== undefined) {\n if (typeof timeout !== 'number') {\n throw new Error('timeout should be a number');\n }\n let endTime = Date.now() + timeout * 1000;\n checkTimeout = () => Date.now() > endTime;\n }\n else {\n checkTimeout = () => false;\n }\n let weightSquare = new Array(data.x.length);\n for (let i = 0; i < nbPoints; i++) {\n weightSquare[i] = filler(i);\n }\n return {\n checkTimeout,\n minValues,\n maxValues,\n parameters,\n weightSquare,\n damping,\n dampingStepUp,\n dampingStepDown,\n maxIterations,\n errorTolerance,\n centralDifference,\n gradientDifference,\n improvementThreshold,\n };\n}\n//# sourceMappingURL=checkOptions.js.map","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 { getKnnSparseOpInfo } from './knn-sparse-info';\nimport { pairwiseOpSparse } from './pairwise-sparse-ops';\nimport { multiplyScalar, toOffsetForm, transposeKNN } from './utils';\nexport function performMatrixOps(knnIndexes, knnDistances, setOpMixRatio = 1.0) {\n return __awaiter(this, void 0, void 0, function* () {\n const flatKnnIndexes = new Int32Array(knnIndexes.length * knnIndexes[0].length);\n const flatKnnDistances = new Float32Array(knnDistances.length * knnDistances[0].length);\n for (let i = 0; i < knnIndexes.length; i++) {\n flatKnnIndexes.set(knnIndexes[i], i * knnIndexes[i].length);\n flatKnnDistances.set(knnDistances[i], i * knnDistances[i].length);\n }\n const unionInfo = yield getKnnSparseOpInfo(knnIndexes);\n const numOfEntries = knnIndexes.length;\n const transposed = yield transposeKNN(knnIndexes, knnDistances, unionInfo, knnDistances[0].length);\n const sourceOffsets = toOffsetForm(new Uint32Array(numOfEntries).fill(knnIndexes[0].length));\n const unionMatrixOffsets = toOffsetForm(unionInfo.resultUnionSizesArray);\n const transposeMultRes = yield pairwiseOpSparse(flatKnnIndexes, flatKnnDistances, sourceOffsets, transposed.transposeKNNIndexes, transposed.transposeKNNDistances, transposed.transposeOffsets, numOfEntries, unionMatrixOffsets, '*');\n const addRes = yield pairwiseOpSparse(flatKnnIndexes, flatKnnDistances, sourceOffsets, transposed.transposeKNNIndexes, transposed.transposeKNNDistances, transposed.transposeOffsets, numOfEntries, unionMatrixOffsets, '+');\n // these offsets will be same as union matrix offsets\n const subtRes = yield pairwiseOpSparse(addRes.resultKnnIndexes, addRes.resultKnnDistances, unionMatrixOffsets, transposeMultRes.resultKnnIndexes, transposeMultRes.resultKnnDistances, unionMatrixOffsets, numOfEntries, unionMatrixOffsets, '-');\n if (setOpMixRatio !== 1.0) {\n multiplyScalar(subtRes.resultKnnDistances, setOpMixRatio);\n multiplyScalar(transposeMultRes.resultKnnDistances, 1.0 - setOpMixRatio);\n const res = yield pairwiseOpSparse(subtRes.resultKnnIndexes, subtRes.resultKnnDistances, unionMatrixOffsets, transposeMultRes.resultKnnIndexes, transposeMultRes.resultKnnDistances, unionMatrixOffsets, numOfEntries, unionMatrixOffsets, '+');\n return { res, unionMatrixOffsets };\n }\n return { res: subtRes, unionMatrixOffsets, unionSizes: unionInfo.resultUnionSizesArray };\n });\n}\n//# sourceMappingURL=fuzzy-simplical-set.js.map","/* eslint-disable max-len */\nexport function knnMatrixOpInfoWGSL(threadsPerWorkgroupDim, threadsPerYDimension, entryLen, knnSize = 15) {\n return `\n\n @group(0) @binding(0) var<storage, read_write> knnIndexes: array<array<i32, ${knnSize}>, ${entryLen}>;\n @group(0) @binding(1) var<storage, read_write> resTransposedSizes: array<atomic<u32>, ${entryLen}>;\n // this array will store the union of knn and its transpose sizes per index. should be initialized to knnSize each.\n @group(0) @binding(2) var<storage, read_write> resUnionMatrixSizes: array<atomic<u32>, ${entryLen}>;\n\n @compute @workgroup_size(${threadsPerWorkgroupDim}, ${threadsPerWorkgroupDim}) fn countTransposedCols(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let col: u32 = id.x;\n let row: u32 = id.y;\n let workingIndex: u32 = row * ${threadsPerYDimension} + col;\n\n if (workingIndex >= ${entryLen}) {\n return;\n }\n \n for (var i = 0u; i < ${knnSize}u; i++) {\n let otherIndex: i32 = knnIndexes[workingIndex][i];\n if (otherIndex != -1 && otherIndex < ${entryLen}) {\n atomicAdd(&resTransposedSizes[otherIndex], 1u);\n atomicAdd(&resUnionMatrixSizes[otherIndex], 1u);\n let otherIndexes = &knnIndexes[otherIndex];\n for(var j = 0u; j < ${knnSize}; j++) {\n if ((*otherIndexes)[j] == i32(workingIndex)) {\n atomicSub(&resUnionMatrixSizes[workingIndex], 1u);\n // if same is found in other array, decrement by one;\n break;\n }\n }\n }\n\n }\n }\n `;\n}\n//# sourceMappingURL=knn-sparse-info.wgsl.js.map","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 { getGPUDevice } from '../getGPUDevice';\nimport { smoothKNNDistanceWGSL } from './wgsl/smooth-knn-distance.wgsl';\nexport function smoothKNNDistance(knnDistances, nNeighbors = 15, localConnectivity = 1.0, nIter = 64, bandwidth = 1.0) {\n return __awaiter(this, void 0, void 0, function* () {\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const numOfEntries = knnDistances.length;\n const requiredWorkgroups = Math.ceil(numOfEntries / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const processWgsl = smoothKNNDistanceWGSL(threadsPerWorkgroupDim, threadsPerWorkgroupDim * numOfWorkgroupsPerDim, knnDistances, nNeighbors, localConnectivity, nIter, bandwidth);\n const distanceBuffer32Size = numOfEntries * knnDistances[0].length;\n // const flatDistanceArray = new Float32Array(distanceBuffer32Size);\n // for (let i = 0; i < knnDistances.length; i ++) {\n // flatDistanceArray.set(knnDistances[i], i * knnDistances[i].length);\n // }\n const device = yield getGPUDevice();\n if (device == null)\n return;\n const resultSigmas = new Float32Array(numOfEntries);\n const resultRhos = new Float32Array(numOfEntries);\n const module = device.createShaderModule({\n label: 'sigmaRhoCalulation',\n code: processWgsl\n });\n const pipeline = device.createComputePipeline({\n label: 'sigmaRhoPipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'smoothKNNDistance',\n },\n });\n const distancesBuffer = device.createBuffer({\n label: 'distance buffer',\n size: distanceBuffer32Size * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedDistanceBuffer = distancesBuffer.getMappedRange();\n const mappedDistanceArray = new Float32Array(mappedDistanceBuffer);\n for (let i = 0; i < knnDistances.length; i++)\n mappedDistanceArray.set(knnDistances[i], i * knnDistances[i].length);\n distancesBuffer.unmap();\n const bufferSigmas = device.createBuffer({\n label: 'buffer sigmas',\n size: numOfEntries * 4,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n const bufferRhos = device.createBuffer({\n label: 'buffer Rhos',\n size: numOfEntries * 4,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for sigmarho buffers',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: bufferSigmas } },\n { binding: 1, resource: { buffer: bufferRhos } },\n { binding: 2, resource: { buffer: distancesBuffer } },\n // { binding: 4, resource: { buffer: arraySizesBuffer } },\n ],\n });\n const encoder = device.createCommandEncoder({\n label: 'sigmarho encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'sigmarho compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n const resultBufferRhos = device.createBuffer({\n label: 'result buffer rhos',\n size: bufferRhos.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n const resultBufferSigmas = device.createBuffer({\n label: 'result buffer sigmas',\n size: bufferSigmas.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n encoder.copyBufferToBuffer(bufferRhos, 0, resultBufferRhos, 0, resultBufferRhos.size);\n encoder.copyBufferToBuffer(bufferSigmas, 0, resultBufferSigmas, 0, resultBufferSigmas.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n yield resultBufferRhos.mapAsync(GPUMapMode.READ);\n yield resultBufferSigmas.mapAsync(GPUMapMode.READ);\n resultRhos.set(new Float32Array(resultBufferRhos.getMappedRange()));\n resultSigmas.set(new Float32Array(resultBufferSigmas.getMappedRange()));\n resultBufferRhos.unmap();\n resultBufferSigmas.unmap();\n distancesBuffer.destroy();\n bufferSigmas.destroy();\n bufferRhos.destroy();\n resultBufferRhos.destroy();\n resultBufferSigmas.destroy();\n return { resultRhos, resultSigmas };\n });\n}\n//# sourceMappingURL=smooth-knn-distance.js.map","export function smoothKNNDistanceWGSL(threadsPerWorkgroupDim = 10, threadsPerYDimension, knnDistances, nNeighbors = 15, localConnectivity = 1.0, nIter = 64, bandwidth = 1.0) {\n const numOfEntries = knnDistances.length;\n let meanDistancesSum = 0.0;\n for (let i = 0; i < numOfEntries; i++) {\n let currentMean = 0.0;\n for (let j = 0; j < nNeighbors; j++)\n currentMean += knnDistances[i][j];\n meanDistancesSum += currentMean / nNeighbors;\n }\n const meanDistances = meanDistancesSum / numOfEntries;\n const target = Math.log(nNeighbors) / Math.log(2) * bandwidth;\n return ` \n var<private> SMOOTH_K_TOLERANCE: f32 = 1e-5;\n var<private> MIN_K_DIST_SCALE: f32 = 1e-3;\n var<private> nNeighbors: u32 = ${nNeighbors};\n var<private> localConnectivity: f32 = ${localConnectivity}; \n var<private> nIter: u32 = ${nIter};\n var<private> bandwidth: u32 = ${bandwidth};\n var<private> meanDistances: f32 = ${meanDistances};\n var<private> targetValue: f32 = ${target};\n @group(0) @binding(0) var<storage, read_write> sigmas: array<f32, ${numOfEntries}>;\n @group(0) @binding(1) var<storage, read_write> rhos: array<f32, ${numOfEntries}>;\n @group(0) @binding(2) var<storage, read> distances: array<array<f32, ${nNeighbors}>, ${numOfEntries}>;\n @compute @workgroup_size(${threadsPerWorkgroupDim}, ${threadsPerWorkgroupDim}) fn smoothKNNDistance(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let col: u32 = id.x;\n let row: u32 = id.y;\n let workingIndex: u32 = row * ${threadsPerYDimension} + col;\n\n if (workingIndex >= ${numOfEntries}) {\n return;\n }\n\n var lo: f32 = 0.0;\n var hi: f32 = 1.0e+30; // treated as Infinity\n var mid: f32 = 1.0;\n\n var nonZeroDists: array<f32, ${nNeighbors}>;\n var nonZeroDistsSize: u32 = 0;\n for (var j = 0u; j < nNeighbors; j = j + 1u) {\n if (distances[workingIndex][j] > 0.0) {\n nonZeroDists[nonZeroDistsSize] = distances[workingIndex][j];\n nonZeroDistsSize = nonZeroDistsSize + 1u;\n }\n }\n\n if (f32(nonZeroDistsSize) >= localConnectivity) {\n let index: u32 = u32(floor(localConnectivity));\n let interpolation: f32 = localConnectivity - f32(index);\n if (index > 0) {\n rhos[workingIndex] = nonZeroDists[index - 1];\n if (interpolation > SMOOTH_K_TOLERANCE) {\n rhos[workingIndex] += interpolation * (nonZeroDists[index] - nonZeroDists[index - 1]);\n }\n }\n else {\n rhos[workingIndex] = interpolation * nonZeroDists[0];\n }\n }\n else if (nonZeroDistsSize > 0u) {\n var maxDist: f32 = 0.0;\n for (var j = 0u; j < nonZeroDistsSize; j = j + 1u) {\n maxDist = max(nonZeroDists[j], maxDist);\n }\n rhos[workingIndex] = maxDist;\n }\n\n for (var n = 0u; n < nIter; n = n + 1u) {\n var psum: f32 = 0.0;\n for (var j = 1u; j < ${nNeighbors}; j = j + 1u) {\n let d: f32 = distances[workingIndex][j] - rhos[workingIndex];\n if (d > 0.0) {\n psum += exp(0.0 - (d / mid));\n }\n else {\n psum += 1.0;\n }\n }\n\n if (abs(psum - targetValue) < SMOOTH_K_TOLERANCE) {\n break;\n }\n\n if (psum > targetValue) {\n hi = mid;\n mid = (lo + hi) / 2.0;\n }\n else {\n lo = mid;\n if (hi == 1.0e+30) {\n mid *= 2.0;\n }\n else {\n mid = (lo + hi) / 2.0;\n }\n }\n }\n\n sigmas[workingIndex] = mid;\n\n if (rhos[workingIndex] > 0.0) {\n var sum: f32 = 0.0;\n for (var j = 0u; j < ${nNeighbors}; j = j + 1u) {\n sum += distances[workingIndex][j];\n }\n let meanIthDistances: f32 = sum / ${nNeighbors}.0;\n if (sigmas[workingIndex] < MIN_K_DIST_SCALE * meanIthDistances) {\n sigmas[workingIndex] = MIN_K_DIST_SCALE * meanIthDistances;\n }\n }\n else {\n if (sigmas[workingIndex] < MIN_K_DIST_SCALE * meanDistances) {\n sigmas[workingIndex] = MIN_K_DIST_SCALE * meanDistances;\n }\n }\n }\n `;\n}\n//# sourceMappingURL=smooth-knn-distance.wgsl.js.map","/* eslint-disable max-len */\nvar __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 { performMatrixOps } from './fuzzy-simplical-set';\nimport { computeMembershipStrengths } from './membership-strengths';\nimport { optimizationLoop } from './optimization-loop';\nimport { initializeSimplicialSetEmbedding } from './simplical-set-embedding';\nimport { smoothKNNDistance } from './smooth-knn-distance';\n// TODO: FIT ASYNC METHOD WITH CALLBACKS on each step\n// TODO: random function passing in params\nexport class UmapParams {\n constructor() {\n this.nComponents = 2;\n this.gamma = 1;\n this.alpha = 1;\n this.entryLen = 0;\n this.nNeighbours = 15;\n this.spread = 1;\n this.minDist = 0.1;\n this.negativeSampleRate = 5;\n this.localConnectivity = 1.0;\n this.setOpMixRatio = 1.0;\n }\n}\nexport class WebGPUUMAP {\n constructor(entryLen, params) {\n this.params = new UmapParams();\n this.knnIndexes = null;\n this.knnDistances = null;\n this.rhos = null;\n this.sigmas = null;\n this.membershipStrengths = null;\n this.params.entryLen = entryLen;\n Object.assign(this.params, params);\n }\n setPrecomputedKNN(knnIndexes, knnDistances) {\n this.knnIndexes = knnIndexes;\n this.knnDistances = knnDistances;\n }\n // for now, not sure if we should include this, maybe webGPU UMAP should be stand alone.\n // eslint-disable-next-line max-len\n // async calcKNN(entryList: SupportedEntryTypes[][], distanceMetrics: WEBGPUDISTANCE[], aggregationFunction: WEBGSLAGGREGATION, weights: number[], options: {\n // [key: string]: any;\n // }[]) {\n // try {\n // const knnRes = await multiColWebGPUKNN(entryList, this.params.nNeighbours, distanceMetrics, aggregationFunction, weights, options);\n // if (knnRes) {\n // this.knnIndexes = knnRes.knnIndexes;\n // this.knnDistances = knnRes.knnDistances;\n // }\n // } catch (e) {\n // console.error(e);\n // }\n // if (!this.knnIndexes || !this.knnDistances)\n // throw new Error('failed to compute knn indexes and distances');\n // }\n // async calcKNNSingle(entryList: SupportedEntryTypes[], distanceMetrics: WEBGPUDISTANCE, options?: {\n // [key: string]: any;\n // }) {\n // if (!options)\n // options = {};\n // await this.calcKNN([entryList], [distanceMetrics], WEBGSLAGGREGATION.MANHATTAN, [1], [options]);\n // }\n initializeFit() {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.calcSmoothKNNDistances();\n yield this.calcMembershipStrengths();\n });\n }\n fit() {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.initializeFit();\n const umapParams = yield this.initializeSimplicialSetEmbedding();\n if (!umapParams)\n throw new Error('failed to compute umap simplistical set embeddings');\n const { head, tail, epochsPerSample, epochsPerNegativeSample, a, b, gamma, initialAlpha, nComponents, nEpochs, entryLen } = umapParams;\n const resEmbeddings = yield optimizationLoop(head, tail, entryLen, epochsPerSample, epochsPerNegativeSample, initialAlpha, gamma, a, b, nComponents, nEpochs, entryLen);\n return resEmbeddings;\n });\n }\n calcSmoothKNNDistances() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!this.knnIndexes || !this.knnDistances)\n throw new Error('knn indexes and distances must be set before calling fit');\n const res = yield smoothKNNDistance(this.knnDistances, this.params.nNeighbours, this.params.localConnectivity, 64);\n if (!res)\n throw new Error('failed to compute smooth knn distances');\n this.rhos = res.resultRhos;\n this.sigmas = res.resultSigmas;\n });\n }\n calcMembershipStrengths() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!this.knnIndexes || !this.knnDistances || !this.rhos || !this.sigmas)\n throw new Error('knn indexes, distances, rhos, and sigmas must be set before calling fit');\n const res = yield computeMembershipStrengths(this.knnDistances, this.sigmas, this.rhos);\n if (!res)\n throw new Error('failed to compute membership strengths');\n this.membershipStrengths = res;\n });\n }\n fuzzySimplicialSet() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!this.knnIndexes || !this.knnDistances || !this.rhos || !this.sigmas || !this.membershipStrengths)\n throw new Error('knn indexes, distances, rhos, sigmas, and membership strengths must be set before calling fit');\n const res = yield performMatrixOps(this.knnIndexes, this.membershipStrengths, this.params.setOpMixRatio);\n if (!res)\n throw new Error('failed to compute pairwise multiply with transpose');\n return res;\n });\n }\n initializeSimplicialSetEmbedding() {\n return __awaiter(this, void 0, void 0, function* () {\n const fuzzySimplicialSetRes = yield this.fuzzySimplicialSet();\n if (!fuzzySimplicialSetRes || !fuzzySimplicialSetRes.res || !fuzzySimplicialSetRes.unionMatrixOffsets || !fuzzySimplicialSetRes.unionSizes)\n throw new Error('failed to compute fuzzy simplicial set');\n const eRes = yield initializeSimplicialSetEmbedding(fuzzySimplicialSetRes, this.params.entryLen, this.params.spread, this.params.minDist, this.params.negativeSampleRate);\n if (!eRes)\n throw new Error('failed to compute umap simplistical set embeddings');\n return eRes;\n });\n }\n}\n//# sourceMappingURL=WEBGPU-UMAP.js.map","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 { getGPUDevice } from '../getGPUDevice';\nimport { optimizeLayoutWGSL } from './wgsl/optimization-loop.wgsl';\nexport function optimizationLoop(head, tail, embeddingSize, epochsPerSample, epochsPerNegativeSample, initialAlpha, gamma, a, b, dim, nEpochs, nVertices) {\n return __awaiter(this, void 0, void 0, function* () {\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const requiredWorkgroups = Math.ceil(head.length / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const threadsPerYDimension = threadsPerWorkgroupDim * numOfWorkgroupsPerDim;\n const device = yield getGPUDevice();\n if (!device)\n return;\n const divisionFactor = 10000000;\n const headSize = head.length;\n const processWGSL = optimizeLayoutWGSL(headSize, embeddingSize, true, initialAlpha, gamma, a, b, dim, nEpochs, nVertices, threadsPerWorkgroupDim, threadsPerYDimension, divisionFactor);\n // head/tail\n const matrixStorage32Size = headSize * 2;\n let paddedMatrixStorageSize = matrixStorage32Size * 4;\n const remainder1 = paddedMatrixStorageSize & 15;\n if (remainder1 !== 0)\n paddedMatrixStorageSize += 16 - remainder1;\n const epochStorage32Size = headSize * 4;\n let paddedepochStorageSize = epochStorage32Size * 4;\n const remainder2 = paddedepochStorageSize & 15;\n if (remainder2 !== 0)\n paddedepochStorageSize += 16 - remainder2;\n const embedStorage32Size = embeddingSize * 2 * 2;\n let paddedembedStorageSize = embedStorage32Size * 4;\n const remainder3 = paddedembedStorageSize & 15;\n if (remainder3 !== 0)\n paddedembedStorageSize += 16 - remainder3;\n const comuteInfo32Size = 2 + headSize;\n let paddedComputeInfoSize = comuteInfo32Size * 4;\n const remainder4 = paddedComputeInfoSize & 15;\n if (remainder4 !== 0)\n paddedComputeInfoSize += 16 - remainder4;\n const module = device.createShaderModule({\n label: 'optimizeShader',\n code: processWGSL\n });\n const pipeline = device.createComputePipeline({\n label: 'optimizePipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'optimizeStep',\n },\n });\n const matrixStorageBuffer = device.createBuffer({\n label: 'matrix storage buffer',\n size: paddedMatrixStorageSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const matrixStorageArrayBuffer = matrixStorageBuffer.getMappedRange();\n const headView = new Uint32Array(matrixStorageArrayBuffer, 0, headSize);\n headView.set(head);\n const tailView = new Uint32Array(matrixStorageArrayBuffer, headSize * 4, headSize);\n tailView.set(tail);\n matrixStorageBuffer.unmap();\n const epochStorageBuffer = device.createBuffer({\n label: 'epoch storage buffer',\n size: paddedepochStorageSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const epochStorageArrayBuffer = epochStorageBuffer.getMappedRange();\n // all are float32 so we get the whole view\n const epochStorageArrayView = new Float32Array(epochStorageArrayBuffer);\n // first epochsPerSample\n epochStorageArrayView.set(epochsPerSample, 0);\n //epochOfNextSample, set to same\n epochStorageArrayView.set(epochsPerSample, headSize);\n //epochsPerNegativeSample\n epochStorageArrayView.set(epochsPerNegativeSample, headSize * 2);\n //epochOfNextNegativeSample\n epochStorageArrayView.set(epochsPerNegativeSample, headSize * 3);\n epochStorageBuffer.unmap();\n const headEmbeddings = new Int32Array(embeddingSize * dim).map(() => Math.floor((Math.random() * 2 - 1) * divisionFactor));\n const tailEmbeddings = new Int32Array(embeddingSize * dim);\n tailEmbeddings.set(headEmbeddings);\n const embeddingStorageBuffer = device.createBuffer({\n label: 'embedding storage buffer',\n size: paddedembedStorageSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedEmbeddingStorageBuffer = embeddingStorageBuffer.getMappedRange();\n const mappedEmbeddingStorageArray = new Int32Array(mappedEmbeddingStorageBuffer);\n mappedEmbeddingStorageArray.set(headEmbeddings, 0);\n mappedEmbeddingStorageArray.set(headEmbeddings, headEmbeddings.length);\n embeddingStorageBuffer.unmap();\n const computeInfoBuffer = device.createBuffer({\n label: 'compute info buffer',\n size: paddedComputeInfoSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const randomNumbers = new Uint32Array(headSize).map(() => Math.floor(Math.random() * divisionFactor));\n const computeInfoArrayBuffer = computeInfoBuffer.getMappedRange();\n const computeInfoMappedArray = new Float32Array(computeInfoArrayBuffer, 0, 2);\n computeInfoMappedArray.set([0.0, initialAlpha]);\n const randomNumbersView = new Uint32Array(computeInfoArrayBuffer, 8, headSize);\n randomNumbersView.set(randomNumbers);\n computeInfoBuffer.unmap();\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for optimize',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: matrixStorageBuffer } },\n { binding: 1, resource: { buffer: epochStorageBuffer } },\n { binding: 2, resource: { buffer: embeddingStorageBuffer } },\n { binding: 3, resource: { buffer: computeInfoBuffer } }\n ],\n });\n let alpha = initialAlpha;\n const outEmbedViewBuffer = device.createBuffer({\n label: 'result buffer',\n size: embeddingStorageBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n for (let iter = 0; iter < nEpochs; iter++) {\n // write n and alpha\n device.queue.writeBuffer(computeInfoBuffer, 0, new Float32Array([iter, alpha]), 0);\n const encoder = device.createCommandEncoder({\n label: 'matrix ops encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'matrix ops compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n // here, we copy the head/tail views to their correct places in embeddings.\n if (iter === nEpochs - 1)\n encoder.copyBufferToBuffer(embeddingStorageBuffer, 0, outEmbedViewBuffer, 0, outEmbedViewBuffer.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n alpha = initialAlpha * (1.0 - iter / nEpochs);\n }\n yield outEmbedViewBuffer.mapAsync(GPUMapMode.READ);\n const resArrayBuffer = outEmbedViewBuffer.getMappedRange();\n const headEmbeddingsView = new Int32Array(resArrayBuffer, 0, headEmbeddings.length);\n headEmbeddings.set(headEmbeddingsView);\n outEmbedViewBuffer.unmap();\n const result = new Array(dim).fill(null).map((_) => new Float32Array(embeddingSize));\n for (let i = 0; i < embeddingSize; i++) {\n for (let j = 0; j < dim; j++)\n result[j][i] = headEmbeddings[i * dim + j] / divisionFactor;\n }\n matrixStorageBuffer.destroy();\n epochStorageBuffer.destroy();\n embeddingStorageBuffer.destroy();\n computeInfoBuffer.destroy();\n outEmbedViewBuffer.destroy();\n return result;\n });\n}\n//# sourceMappingURL=optimization-loop.js.map","/* eslint-disable max-len */\nexport function optimizeLayoutWGSL(headSize, embedSize, moveOther, initialAlpha, gamma, a, b, dim, nEpochs, nVertices, workgroupDim, threadsPerRow, divisionFactor = 100000) {\n return `\n// first define some functions\n\nfn rDist(ar1: array<f32, ${dim}>, ar2: array<f32, ${dim}>) -> f32 {\n var res = 0.0;\n for (var i1 = 0u; i1 < ${dim}; i1++) {\n let diff = ar1[i1] - ar2[i1];\n res += pow(diff, 2);\n }\n return res;\n}\n\nfn clip(x: f32, clipValue: f32) -> f32 {\n if (x > clipValue) {\n return clipValue;\n }\n else if (x < 0.0 - clipValue) {\n return 0.0 - clipValue;\n }\n return x;\n}\n\nvar<private> randomSeedInt: u32 = 0;\nvar<private> nVertices: u32 = ${nVertices};\nvar<private> initialAlpha: f32 = ${initialAlpha};\nvar<private> gamma: f32 = ${gamma};\nvar<private> a: f32 = ${a};\nvar<private> b: f32 = ${b};\nvar<private> dim: u32 = ${dim};\nvar<private> nEpochs: f32 = ${nEpochs};\nvar<private> moveOther: u32 = ${moveOther === true ? 1 : 0};\n\nfn random() -> u32 {\n randomSeedInt = (randomSeedInt ^ 61) ^ (randomSeedInt >> 16);\n randomSeedInt *= 9;\n randomSeedInt = randomSeedInt ^ (randomSeedInt >> 4);\n randomSeedInt *= 0x27d4eb2d;\n randomSeedInt = randomSeedInt ^ (randomSeedInt >> 15);\n return randomSeedInt;\n}\n\nfn randInt(maxVal: u32) -> u32 {\n let nextRandomNum = random();\n return u32(floor((f32(nextRandomNum) * (f32(maxVal) / 4294967296.0))));\n}\n\nstruct MatrixStorage {\n head: array<u32, ${headSize}>,\n tail: array<u32, ${headSize}>,\n}\n\nstruct EpochStorage {\n epochsPerSample: array<f32, ${headSize}>,\n epochOfNextSample: array<f32, ${headSize}>,\n epochsPerNegativeSample: array<f32, ${headSize}>,\n epochOfNextNegativeSample: array<f32, ${headSize}>\n}\n\nstruct EmbeddingStorage {\n // embeddings will be in range of -10 to 10, as atomics only can store i32 or u32, we will store them as floor(f32 * 100_000)\n headEmbeddings: array<array<atomic<i32>, ${dim}>, ${embedSize}>,\n tailEmbeddings: array<array<atomic<i32>, ${dim}>, ${embedSize}>\n}\n\nstruct ComputeInfo {\n n: f32,\n alpha: f32,\n randomNumbers: array<u32, ${headSize}>,\n //tailOffsets: array<u32, ${embedSize + 1}>\n}\n @group(0) @binding(0) var<storage, read_write> matrixStorage: MatrixStorage;\n @group(0) @binding(1) var<storage, read_write> epochStorage: EpochStorage;\n @group(0) @binding(2) var<storage, read_write> embedStorage: EmbeddingStorage;\n @group(0) @binding(3) var<storage, read_write> computeInfo: ComputeInfo;\n @compute @workgroup_size(${workgroupDim}, ${workgroupDim}) fn optimizeStep(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let divisionFactor: f32 = ${divisionFactor};\n let col: u32 = id.x;\n let row: u32 = id.y;\n let threadIndex: u32 = row * ${threadsPerRow} + col;\n let clipValue: f32 = 4.0;\n\n if (threadIndex >= ${headSize}) {\n return;\n }\n\n let workingIndex = threadIndex;\n //let startAtOffset = computeInfo.tailOffsets[threadIndex];\n //let endAtOffset = computeInfo.tailOffsets[threadIndex + 1];\n //for (var workingIndex = startAtOffset; workingIndex < endAtOffset; workingIndex++) {\n randomSeedInt = computeInfo.randomNumbers[workingIndex] * u32(computeInfo.n);\n\n let epochOfNextSample = epochStorage.epochOfNextSample[workingIndex];\n if (epochOfNextSample > computeInfo.n) {\n return;\n }\n\n let j = matrixStorage.head[workingIndex];\n let k = matrixStorage.tail[workingIndex];\n\n // as said before, we will store embeddings as floor(f32 * 100_000)\n var current: array<f32, ${dim}>;\n var other: array<f32, ${dim}>;\n for (var i = 0u; i < ${dim}u; i++) {\n current[i] = f32(atomicLoad(&embedStorage.headEmbeddings[j][i])) / divisionFactor;\n other[i] = f32(atomicLoad(&embedStorage.tailEmbeddings[k][i])) / divisionFactor;\n }\n\n let distSquared = rDist(current, other);\n \n var gradCoeff: f32 = 0.0;\n if (distSquared > 0.0) {\n gradCoeff = (0.0 - 2.0) * ${a} * ${b} * pow(distSquared, b - 1.0);\n gradCoeff /= (a * pow(distSquared, b) + 1.0);\n }\n\n var gradBuff: array<i32, ${dim}>;\n for (var d = 0u; d < ${dim}u; d++) {\n let gradD = clip((gradCoeff * (current[d] - other[d])), clipValue);\n let toAdd = gradD * computeInfo.alpha;\n gradBuff[d] = i32(floor(toAdd * divisionFactor));\n current[d] += toAdd;\n other[d] -= toAdd;\n }\n\n for (var d = 0u; d < ${dim}u; d++) {\n atomicAdd(&embedStorage.headEmbeddings[j][d], gradBuff[d]);\n atomicSub(&embedStorage.tailEmbeddings[k][d], gradBuff[d]);\n }\n\n epochStorage.epochOfNextSample[workingIndex] += epochStorage.epochsPerSample[workingIndex];\n var nNegSamples: i32 = i32(floor((computeInfo.n - epochStorage.epochOfNextNegativeSample[workingIndex]) / epochStorage.epochsPerNegativeSample[workingIndex]));\n\n for (var p = 0i; p < nNegSamples; p++) {\n let k1 = randInt(nVertices);\n var other1: array<f32, ${dim}>;\n for (var i = 0u; i < ${dim}u; i++) {\n other1[i] = f32(atomicLoad(&embedStorage.tailEmbeddings[k1][i])) / divisionFactor;\n }\n\n let distSquared1 = rDist(current, other1);\n\n var gradCoeff1: f32 = 0.0;\n if (distSquared1 > 0.0) {\n gradCoeff1 = 2.0 * gamma * b;\n gradCoeff1 /= (0.001 + distSquared1) * (a * pow(distSquared1, b) + 1);\n }\n else if (j == k1) {\n continue;\n }\n\n var gradDBuff: array<i32, ${dim}>;\n for (var d = 0u; d < ${dim}u; d++) {\n var gradD: f32 = 4.0;\n if (gradCoeff1 > 0.0) {\n gradD = clip(gradCoeff1 * (current[d] - other1[d]), clipValue);\n }\n\n gradDBuff[d] = i32(floor(gradD * computeInfo.alpha * divisionFactor));\n \n }\n for (var d = 0u; d < ${dim}u; d++) {\n atomicAdd(&embedStorage.headEmbeddings[j][d], gradDBuff[d]);\n }\n }\n epochStorage.epochOfNextNegativeSample[workingIndex] += f32(nNegSamples) * epochStorage.epochsPerNegativeSample[workingIndex];\n //}\n }\n`;\n}\n//# sourceMappingURL=optimization-loop.wgsl.js.map","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 { getGPUDevice } from '../getGPUDevice';\nimport { computeMembershipStrengthsWGSL } from './wgsl/membership-strengths.wgsl';\nexport function computeMembershipStrengths(knnDistances, sigmas, rhos) {\n return __awaiter(this, void 0, void 0, function* () {\n const threadsPerWorkgroupDim = 10;\n const threadsPerWorkgroup = threadsPerWorkgroupDim * threadsPerWorkgroupDim;\n const numOfEntries = knnDistances.length;\n const requiredWorkgroups = Math.ceil(numOfEntries / threadsPerWorkgroup);\n const numOfWorkgroupsPerDim = Math.ceil(Math.sqrt(requiredWorkgroups));\n const processWgsl = computeMembershipStrengthsWGSL(threadsPerWorkgroupDim, threadsPerWorkgroupDim * numOfWorkgroupsPerDim, knnDistances, sigmas, rhos);\n const distanceBuffer32Size = numOfEntries * knnDistances[0].length;\n const device = yield getGPUDevice();\n if (device == null)\n return;\n const module = device.createShaderModule({\n label: 'rowsColsValsCalulation',\n code: processWgsl\n });\n const pipeline = device.createComputePipeline({\n label: 'rowsColsValsPipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'computeMembershipStrengths',\n },\n });\n const rhos32Size = rhos.length;\n const sigmas32Size = sigmas.length;\n const combinedMembershipStrengthsInfo32Size = rhos32Size + sigmas32Size + distanceBuffer32Size;\n let paddedCombinedMembershipStructByteSize = combinedMembershipStrengthsInfo32Size * 4;\n const remainder = paddedCombinedMembershipStructByteSize & 15;\n if (remainder != 0)\n paddedCombinedMembershipStructByteSize += 16 - remainder;\n // input params\n const membershipStrengthsInfoBuffer = device.createBuffer({\n label: 'info buffer',\n size: paddedCombinedMembershipStructByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedInfoBuffer = membershipStrengthsInfoBuffer.getMappedRange();\n const mappedInfoArray = new Float32Array(mappedInfoBuffer);\n // first set knn distances\n for (let i = 0; i < knnDistances.length; i++)\n mappedInfoArray.set(knnDistances[i], i * knnDistances[i].length);\n let offset = knnDistances[0].length * knnDistances.length;\n // now set sigmas\n mappedInfoArray.set(sigmas, offset);\n offset += sigmas.length;\n // now set rhos\n mappedInfoArray.set(rhos, offset);\n membershipStrengthsInfoBuffer.unmap();\n const knnDistancesBuffer = device.createBuffer({\n label: 'knn distance buffer',\n size: knnDistances[0].length * knnDistances.length * Float32Array.BYTES_PER_ELEMENT,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n });\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for membership strhegths buffers',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: membershipStrengthsInfoBuffer } },\n { binding: 1, resource: { buffer: knnDistancesBuffer } },\n // { binding: 4, resource: { buffer: arraySizesBuffer } },\n ],\n });\n const encoder = device.createCommandEncoder({\n label: 'membership strengths encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'membership strengths compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(numOfWorkgroupsPerDim, numOfWorkgroupsPerDim);\n pass.end();\n const resultBufferDistances = device.createBuffer({\n label: 'result buffer distances',\n size: knnDistancesBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n encoder.copyBufferToBuffer(knnDistancesBuffer, 0, resultBufferDistances, 0, resultBufferDistances.size);\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n yield device.queue.onSubmittedWorkDone();\n yield resultBufferDistances.mapAsync(GPUMapMode.READ);\n const resultKnnDistancesArrayBuffer = resultBufferDistances.getMappedRange();\n const bytesPerKnnRow = knnDistances[0].length * Float32Array.BYTES_PER_ELEMENT;\n const resKnnDistances = new Array(knnDistances.length).fill(null).map((_, i) => {\n const dataView = new Float32Array(resultKnnDistancesArrayBuffer, bytesPerKnnRow * i, knnDistances[0].length);\n const out = new Float32Array(knnDistances[0].length);\n out.set(dataView);\n return out;\n });\n resultBufferDistances.unmap();\n resultBufferDistances.destroy();\n knnDistancesBuffer.destroy();\n membershipStrengthsInfoBuffer.destroy();\n return resKnnDistances;\n });\n}\n//# sourceMappingURL=membership-strengths.js.map","/* eslint-disable max-len */\nexport function computeMembershipStrengthsWGSL(threadsPerWorkgroupDim = 10, threadsPerYDimension, knnDistances, sigmas, rhos) {\n const numOfEntries = knnDistances.length;\n const sigmasLength = sigmas.length;\n const rhosLength = rhos.length;\n // TODO: do it with structs\n return `\n struct MembershipStrengthsInfo {\n knnDistances: array<array<f32, ${knnDistances[0].length}>, ${numOfEntries}>,\n sigmas: array<f32, ${sigmasLength}>,\n rhos: array<f32, ${rhosLength}>\n };\n var<private> nNeighbors: u32 = ${knnDistances[0].length};\n @group(0) @binding(0) var<storage, read> membershipStrengthsInfo: MembershipStrengthsInfo;\n @group(0) @binding(1) var<storage, read_write> resultKnnDistances: array<array<f32, ${knnDistances[0].length}>, ${numOfEntries}>;\n @compute @workgroup_size(${threadsPerWorkgroupDim}, ${threadsPerWorkgroupDim}) fn computeMembershipStrengths(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let col: u32 = id.x;\n let row: u32 = id.y;\n let workingIndex: u32 = row * ${threadsPerYDimension} + col;\n\n if (workingIndex >= ${numOfEntries}) {\n return;\n }\n\n let workingResKnnDistances = &resultKnnDistances[workingIndex];\n let knnDistances = &membershipStrengthsInfo.knnDistances[workingIndex];\n for (var j = 0u; j < nNeighbors; j = j + 1u) {\n var val: f32 = 0.0;\n\n if ((*knnDistances)[j] - membershipStrengthsInfo.rhos[workingIndex] <= 0.0) {\n val = 1.0;\n } else {\n val = exp(0.0 - ((knnDistances[j] - membershipStrengthsInfo.rhos[workingIndex]) / membershipStrengthsInfo.sigmas[workingIndex])); \n }\n\n (*workingResKnnDistances)[j] = val;\n }\n }\n `;\n}\n//# sourceMappingURL=membership-strengths.wgsl.js.map","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 { findABParams, getNEpochs, toOffsetForm } from './utils';\nexport function initializeSimplicialSetEmbedding(graph, entryLen, spread, minDist, negativeSampleRate = 5) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!graph.unionSizes)\n return;\n const nEpochs = getNEpochs(entryLen);\n const nComponents = 2; // todo: support mult dims\n // get max value:\n const maxVal = graph.res.resultKnnDistances.reduce((prev, cur) => Math.max(prev, cur));\n //let offsetAccum = 0;\n // for (let i = 0; i < graph.unionSizes.length; i++) {\n // for (let j = 0; j < graph.unionSizes)\n // }\n const minGraphVal = maxVal / nEpochs;\n // this will hold the sizes of arrays with all zeros removed.\n const unionSizesCopy = new Uint32Array(graph.unionSizes.length);\n unionSizesCopy.set(graph.unionSizes);\n let offsetAccum = 0;\n for (let i = 0; i < graph.unionSizes.length; i++) {\n for (let j = 0; j < graph.unionSizes[i]; j++) {\n const index = offsetAccum + j;\n if (graph.res.resultKnnDistances[index] < minGraphVal) {\n graph.res.resultKnnDistances[index] = 0;\n unionSizesCopy[i]--;\n }\n }\n offsetAccum += graph.unionSizes[i];\n }\n const nonZeroGraphOffsets = toOffsetForm(unionSizesCopy);\n const nonZeroGraphSize = nonZeroGraphOffsets[nonZeroGraphOffsets.length - 1];\n const weights = new Float32Array(nonZeroGraphSize);\n const head = new Uint32Array(nonZeroGraphSize);\n const tail = new Uint32Array(nonZeroGraphSize);\n offsetAccum = 0;\n for (let i = 0; i < graph.unionSizes.length; i++) {\n for (let j = 0; j < graph.unionSizes[i]; j++) {\n const index = graph.unionMatrixOffsets[i] + j;\n if (graph.res.resultKnnDistances[index] != 0) {\n weights[offsetAccum] = graph.res.resultKnnDistances[index];\n head[offsetAccum] = graph.res.resultKnnIndexes[index];\n tail[offsetAccum] = i;\n offsetAccum += 1;\n }\n }\n }\n const epochsPerSample = new Float32Array(weights.length).fill(-1);\n const nSamples = weights.map((w) => (w / maxVal) * nEpochs);\n nSamples.forEach((n, i) => {\n if (n > 0)\n epochsPerSample[i] = nEpochs / nSamples[i];\n });\n const { a, b } = findABParams(spread, minDist);\n const epochsPerNegativeSample = epochsPerSample.map((e) => e / negativeSampleRate);\n const gamma = 1.0;\n const initialAlpha = 1.0;\n return { epochsPerSample, epochsPerNegativeSample, a, b,\n head, tail, entryLen, nEpochs, nComponents, initialAlpha, gamma };\n });\n}\n//# sourceMappingURL=simplical-set-embedding.js.map","import { Vector } from '@datagrok-libraries/utils/src/type-declarations';\nimport { AvailableMetrics, Measure, isBitArrayMetric } from '../typed-metrics';\nimport { DistanceMatrixService } from '../distance-matrix';\nimport { UMAP } from '../umap';\nimport { assert, transposeMatrix } from '@datagrok-libraries/utils/src/vector-operations';\nimport { SparseMatrixService } from '../distance-matrix/sparse-matrix-service';\nimport BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport seedRandom from 'seedrandom';\n//import {TSNE} from '@keckelt/tsne';\nimport { TSNE } from '../t-sne/t-sne';\nimport { multiColWebGPUKNN } from '@datagrok-libraries/math';\nimport { WebGPUUMAP } from '@datagrok-libraries/math/src/webGPU/umap';\nclass MultiColumnReducer {\n constructor(options) {\n this.data = options.data;\n this.weights = options.weights;\n this.aggregationMethod = options.aggregationMethod;\n }\n}\nclass TSNEReducer extends MultiColumnReducer {\n /**\n * Creates an instance of TSNEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof TSNEReducer\n */\n constructor(options) {\n super(options);\n const randomSeed = options.randomSeed ?? Date();\n const randomFn = seedRandom(randomSeed);\n options.dim = 2; // TODO: make it configurable\n options.random = randomFn;\n this.reducer = new TSNE(options);\n this.iterations = options?.iterations ?? this.reducer.getIterSize(this.data[0].length);\n this.distanceFnames = options.distanceFnames;\n this.distanceFns = options.distanceFns;\n this.distanceFnArgs = options.distanceFnArgs;\n this.progressFunc = options.progressFunc;\n }\n /**\n * Embeds the data given into the two-dimensional space using t-SNE method.\\\n * @param {boolean} [parallelDistanceWorkers] Whether to use parallel distance workers.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n if (this.data[0].length > 10000)\n throw new Error('Maximum number of samples for T-SNE is 10000');\n const matrixService = new DistanceMatrixService(true, false);\n try {\n // const aggregate = getAggregationFunction(this.aggregationMethod, this.weights);\n // const distances: Array<Float32Array> = [];\n // for (let i = 0; i < this.data.length; ++i) {\n // const dist = await matrixService.calc(this.data[i], this.distanceFnames[i], false, this.distanceFnArgs[i]);\n // distances.push(dist);\n // }\n // const distance = new Float32Array(distances[0].length).fill(0);\n // for (let i = 0; i < distances[0].length; ++i)\n // distance[i] = aggregate(distances.map((d) => d[i]));\n const distance = await matrixService.calcMulti(this.data, this.distanceFnames, false, this.distanceFnArgs, this.weights, this.aggregationMethod);\n matrixService.terminate();\n // const matrixProxy = distanceMatrixProxy(distance, this.data[0].length);\n this.reducer.initDataDist(distance, this.data[0].length);\n for (let i = 0; i < this.iterations; ++i) {\n this.reducer.step(); // every time you call this, solution gets better\n if (this.progressFunc)\n this.progressFunc(i, this.iterations, []);\n }\n return this.reducer.getSolution();\n }\n catch (e) {\n matrixService.terminate();\n throw e;\n }\n }\n}\nclass UMAPReducer extends MultiColumnReducer {\n /**\n * Creates an instance of UMAPReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof UMAPReducer\n */\n constructor(options) {\n const randomSeed = options.randomSeed ?? Date();\n const randomFn = seedRandom(randomSeed);\n super(options);\n this.useWebGPU = false;\n assert('distanceFnames' in options);\n assert('distanceFns' in options);\n this.distanceFnArgs = options.distanceFnArgs;\n this.distanceFns = options.distanceFns;\n this.progressFunc = options.progressFunc;\n this.useWebGPU = options.useWebGPU ?? false;\n this.distanceFnames = options.distanceFnames;\n options.nComponents = 2; // TODO: make it configurable\n //Umap uses vector indexing, so we need to create an array of vectors as indeces.\n this.vectors = new Array(this.data[0].length).fill(0).map((_, i) => i);\n if (this.data[0].length <= (options.nNeighbors ?? 15))\n options.nNeighbors = this.data[0].length - 1;\n options.random = randomFn;\n this.reducer = new UMAP(options);\n // this.reducer.distanceFn = this._encodedDistance.bind(this);\n }\n /**\n * Embeds the data given into the two-dimensional space using UMAP method.\n * @param {boolean} [_parallelDistanceWorkers] Whether to use parallel distance matrix workers.\n * @return {any} Cartesian coordinate of this embedding.\n */\n async transform(_parallelDistanceWorkers) {\n console.time('knn graph');\n let knnGraph = undefined;\n if (this.useWebGPU) {\n try {\n knnGraph = await multiColWebGPUKNN(this.data, this.reducer.neighbors, this.distanceFnames, this.aggregationMethod, this.weights, this.distanceFnArgs);\n }\n catch (e) {\n console.error(e);\n }\n }\n if (!knnGraph) {\n if (this.useWebGPU)\n console.error('WEBGPU KNN failed, falling back to multithreaded CPU implementation');\n knnGraph = await new SparseMatrixService()\n .multiColumnKNN(this.data, this.distanceFnames, this.reducer.neighbors, this.distanceFnArgs, this.weights, this.aggregationMethod);\n }\n console.timeEnd('knn graph');\n if (this.useWebGPU) {\n this.webGPUReducer = new WebGPUUMAP(this.vectors.length, {\n nComponents: this.reducer.nComponents,\n gamma: this.reducer.repulsionStrength,\n alpha: this.reducer.learningRate,\n nNeighbours: this.reducer.neighbors,\n spread: this.reducer.spread,\n minDist: this.reducer.minDist,\n negativeSampleRate: this.reducer.negativeSampleRate,\n localConnectivity: this.reducer.localConnectivity,\n setOpMixRatio: this.reducer.setOpMixRatio,\n });\n this.webGPUReducer.setPrecomputedKNN(knnGraph.knnIndexes, knnGraph.knnDistances);\n }\n else {\n this.reducer.setPrecomputedKNN(knnGraph.knnIndexes, knnGraph.knnDistances);\n }\n // needed so that garbage collector can free memory from distance matrix\n await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, 300);\n });\n let embedding = null;\n console.time('fit');\n try {\n if (this.useWebGPU && this.webGPUReducer) {\n embedding = await this.webGPUReducer.fit();\n if (!embedding)\n throw new Error('Failed to compute embedding');\n embedding = // transpose TODO: do a better job here\n new Array(embedding[0].length).fill(null).map((_, i) => new Float32Array(embedding.map((v) => v[i])));\n }\n }\n catch (e) {\n console.error(e);\n }\n if (!embedding) {\n if (this.useWebGPU)\n console.error('WEBGPU UMAP failed, falling back to CPU implementation');\n embedding = await this.reducer.fitAsync(this.vectors, (epoc) => {\n if (this.progressFunc)\n this.progressFunc(epoc, this.reducer.getNEpochs(), this.reducer.getEmbedding());\n });\n }\n console.timeEnd('fit');\n return arrayCast2Coordinates(embedding);\n function arrayCast2Coordinates(data) {\n return new Array(data.length).fill(0).map((_, i) => (Vector.from(data[i])));\n }\n }\n}\nconst AvailableReducers = {\n 'UMAP': UMAPReducer,\n 't-SNE': TSNEReducer,\n};\nexport class MultiColDimReducer {\n /**\n * Creates an instance of DimensionalityReducer.\n * @param {any[]} data Vectors to embed.\n * @param {KnownMethods} method Embedding method to be applied\n * @param {KnownMetrics} metric Distance metric to be computed between each of the vectors.\n * @param {Options} [options] Options to pass to the implementing embedders.\n * @memberof DimensionalityReducer\n */\n constructor(data, method, metrics, weights, distanceAggregation, options) {\n const measures = [];\n for (let idx = 0; idx < metrics.length; ++idx) {\n const measure = new Measure(metrics[idx]).getMeasure(options.distanceFnArgs[idx]);\n measures.push(measure);\n let bitArrayLength = 2048;\n for (let i = 0; i < data[idx].length; ++i) {\n if (data[idx][i] && data[idx][i]._length) {\n bitArrayLength = data[idx][i]._length;\n break;\n }\n }\n if (isBitArrayMetric(metrics[idx])) {\n for (let i = 0; i < data[idx].length; ++i) {\n if (data[idx][i] && data[idx][i]._data)\n data[idx][i] = new BitArray(data[idx][i]._data, data[idx][i]._length);\n else\n data[idx][i] = new BitArray(bitArrayLength);\n }\n }\n }\n if (method == 'UMAP') {\n this.reducer = new UMAPReducer({\n data: data,\n distanceFnames: metrics,\n distanceFns: measures,\n distanceFnArgs: options.distanceFnArgs,\n weights: weights,\n aggregationMethod: distanceAggregation,\n ...options\n });\n }\n else if (method == 't-SNE') {\n this.reducer = new TSNEReducer({\n data: data,\n distanceFnames: metrics,\n distanceFns: measures,\n distanceFnArgs: options.distanceFnArgs,\n weights: weights,\n aggregationMethod: distanceAggregation,\n ...options\n });\n }\n }\n /**\n * Embeds the data given into the two-dimensional space using the chosen method.\n *\n * @param {boolean} transpose Whether to transform coordinates to have columns-first orientation.\n * @param {boolean} parallelDistanceWorkers Whether to use parallel distance computation.\n * @throws {Error} If the embedding method was not found.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n * @memberof DimensionalityReducer\n */\n async transform(transpose = false) {\n if (this.reducer === undefined)\n throw new Error('Reducer was not defined.');\n let embedding = await this.reducer.transform();\n if (transpose)\n embedding = transposeMatrix(embedding);\n return embedding;\n }\n /**\n * Returns metrics available by type.\n *\n * @param {AvailableDataTypes} typeName type name\n * @return {string[]} Metric names which expects the given data type\n * @memberof DimensionalityReducer\n */\n static availableMetricsByType(typeName) {\n return Object.keys(AvailableMetrics[typeName]);\n }\n /**\n * Returns dimensionality reduction methods available.\n *\n * @readonly\n * @memberof DimensionalityReducer\n */\n static get availableMethods() {\n return Object.keys(AvailableReducers);\n }\n /**\n * Returns metrics available.\n *\n * @readonly\n * @memberof DimensionalityReducer\n */\n static get availableMetrics() {\n let ans = [];\n Object.values(AvailableMetrics).forEach((obj) => {\n const array = Object.values(obj);\n ans = [...ans, ...array];\n });\n return ans;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktY29sdW1uLWRpbS1yZWR1Y2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibXVsdGktY29sdW1uLWRpbS1yZWR1Y2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBK0MsTUFBTSxFQUFVLE1BQy9ELGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBcUIsZ0JBQWdCLEVBQWdCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQy9HLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBRXpELE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFDN0IsT0FBTyxFQUFDLE1BQU0sRUFBRSxlQUFlLEVBQUMsTUFBTSxpREFBaUQsQ0FBQztBQUN4RixPQUFPLEVBQVksbUJBQW1CLEVBQUMsTUFBTSwwQ0FBMEMsQ0FBQztBQUV4RixPQUFPLFFBQVEsTUFBTSx5Q0FBeUMsQ0FBQztBQUMvRCxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFDcEMscUNBQXFDO0FBQ3JDLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwQyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sMENBQTBDLENBQUM7QUFpQ3BFLE1BQWUsa0JBQWtCO0lBSTdCLFlBQVksT0FBZ0I7UUFDMUIsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztRQUMvQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDO0lBQ3JELENBQUM7Q0FLSjtBQUVELE1BQU0sV0FBWSxTQUFRLGtCQUFrQjtJQU94Qzs7OztPQUlHO0lBQ0gsWUFBWSxPQUFnQjtRQUMxQixLQUFLLENB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Q0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUM5QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pDLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29vcmRpbmF0ZXMsIERpc3RhbmNlTWV0cmljLCBNYXRyaXgsIE9wdGlvbnMsIFZlY3RvciwgVmVjdG9yc31cbiAgZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdHlwZS1kZWNsYXJhdGlvbnMnO1xuaW1wb3J0IHtBdmFpbGFibGVEYXRhVHlwZXMsIEF2YWlsYWJsZU1ldHJpY3MsIEtub3duTWV0cmljcywgTWVhc3VyZSwgaXNCaXRBcnJheU1ldHJpY30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQge0Rpc3RhbmNlTWF0cml4U2VydmljZX0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4JztcbmltcG9ydCB7RGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZH0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3R5cGVzJztcbmltcG9ydCB7VU1BUH0gZnJvbSAnLi4vdW1hcCc7XG5pbXBvcnQge2Fzc2VydCwgdHJhbnNwb3NlTWF0cml4fSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy92ZWN0b3Itb3BlcmF0aW9ucyc7XG5pbXBvcnQge0tublJlc3VsdCwgU3BhcnNlTWF0cml4U2VydmljZX0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3NwYXJzZS1tYXRyaXgtc2VydmljZSc7XG5pbXBvcnQge0RpbVJlZHVjdGlvbk1ldGhvZHN9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQgc2VlZFJhbmRvbSBmcm9tICdzZWVkcmFuZG9tJztcbi8vaW1wb3J0IHtUU05FfSBmcm9tICdAa2Vja2VsdC90c25lJztcbmltcG9ydCB7VFNORX0gZnJvbSAnLi4vdC1zbmUvdC1zbmUnO1xuaW1wb3J0IHttdWx0aUNvbFdlYkdQVUtOTn0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy9tYXRoJztcbmltcG9ydCB7V2ViR1BVVU1BUH0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy9tYXRoL3NyYy93ZWJHUFUvdW1hcCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVVNQVBPcHRpb25zIHtcbiAgICBsZWFybmluZ1JhdGU/OiBudW1iZXI7XG4gICAgbkNvbXBvbmVudHM/OiBudW1iZXI7XG4gICAgbkVwb2Nocz86IG51bWJlcjtcbiAgICBuTmVpZ2hib3JzPzogbnVtYmVyO1xuICAgIHNwcmVhZD86IG51bWJlcjtcbiAgICBtaW5EaXN0PzogbnVtYmVyO1xuICAgIHByb2dyZXNzRnVuYz86IChlcG9jOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmdzOiBudW1iZXJbXVtdKSA9PiB2b2lkO1xuICAgIHJhbmRvbVNlZWQ/OiBzdHJpbmc7XG4gICAgdXNlV2ViR1BVPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVFNORU9wdGlvbnMge1xuICAgIGVwc2lsb24/OiBudW1iZXI7XG4gICAgcGVycGxleGl0eT86IG51bWJlcjtcbiAgICBkaW0/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSURpbVJlZHVjdGlvblBhcmFtPFQgZXh0ZW5kcyBudW1iZXIgfCBzdHJpbmcgfCBib29sZWFuID0gbnVtYmVyPiB7XG4gICAgdWlOYW1lOiBzdHJpbmc7XG4gICAgdmFsdWU6IChUIGV4dGVuZHMgbnVtYmVyID8gbnVtYmVyIDogVCBleHRlbmRzIHN0cmluZyA/IHN0cmluZyA6IGJvb2xlYW4pIHwgbnVsbDtcbiAgICB0b29sdGlwOiBzdHJpbmc7XG4gICAgdHlwZT86IFQgZXh0ZW5kcyBudW1iZXIgPyAnbnVtYmVyJyA6IFQgZXh0ZW5kcyBzdHJpbmcgPyAnc3RyaW5nJyA6ICdib29sZWFuJztcbiAgICBwbGFjZWhvbGRlcj86IHN0cmluZztcbiAgICBtaW4/OiBudW1iZXI7XG4gICAgbWF4PzogbnVtYmVyO1xuICAgIHN0ZXA/OiBudW1iZXI7XG4gICAgZGlzYWJsZT86IGJvb2xlYW47XG4gICAgZGlzYWJsZVRvb2x0aXA/OiBzdHJpbmc7XG59XG5cbmFic3RyYWN0IGNsYXNzIE11bHRpQ29sdW1uUmVkdWNlciB7XG4gICAgcHJvdGVjdGVkIGRhdGE6IFZlY3RvcnNbXTtcbiAgICBwcm90ZWN0ZWQgd2VpZ2h0czogbnVtYmVyW107XG4gICAgcHJvdGVjdGVkIGFnZ3JlZ2F0aW9uTWV0aG9kOiBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kO1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICAgIHRoaXMuZGF0YSA9IG9wdGlvbnMuZGF0YTtcbiAgICAgIHRoaXMud2VpZ2h0cyA9IG9wdGlvbnMud2VpZ2h0cztcbiAgICAgIHRoaXMuYWdncmVnYXRpb25NZXRob2QgPSBvcHRpb25zLmFnZ3JlZ2F0aW9uTWV0aG9kO1xuICAgIH1cblxuICAgIC8qKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlLlxuICAgICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLiAqL1xuICAgIGFic3RyYWN0IHRyYW5zZm9ybSgpOiBQcm9taXNlPE1hdHJpeD47XG59XG5cbmNsYXNzIFRTTkVSZWR1Y2VyIGV4dGVuZHMgTXVsdGlDb2x1bW5SZWR1Y2VyIHtcbiAgICBwcm90ZWN0ZWQgcmVkdWNlcjogVFNORTtcbiAgICBwcm90ZWN0ZWQgaXRlcmF0aW9uczogbnVtYmVyO1xuICAgIHByb3RlY3RlZCBkaXN0YW5jZUZuYW1lczogS25vd25NZXRyaWNzW107XG4gICAgcHJvdGVjdGVkIGRpc3RhbmNlRm5zOiAoKGE6IGFueSwgYjogYW55KSA9PiBudW1iZXIpW107XG4gICAgcHJvdGVjdGVkIGRpc3RhbmNlRm5BcmdzOiB7W186IHN0cmluZ106IGFueX1bXTtcbiAgICBwcm90ZWN0ZWQgcHJvZ3Jlc3NGdW5jPzogKGVwb2M6IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZ3M/OiBudW1iZXJbXVtdKSA9PiB2b2lkO1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgVFNORVJlZHVjZXIuXG4gICAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgY29uc3RydWN0b3IuXG4gICAgICogQG1lbWJlcm9mIFRTTkVSZWR1Y2VyXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucykge1xuICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICBjb25zdCByYW5kb21TZWVkOiBzdHJpbmcgPSBvcHRpb25zLnJhbmRvbVNlZWQgPz8gRGF0ZSgpO1xuICAgICAgY29uc3QgcmFuZG9tRm4gPSBzZWVkUmFuZG9tKHJhbmRvbVNlZWQpO1xuICAgICAgb3B0aW9ucy5kaW0gPSAyOyAvLyBUT0RPOiBtYWtlIGl0IGNvbmZpZ3VyYWJsZVxuICAgICAgb3B0aW9ucy5yYW5kb20gPSByYW5kb21GbjtcbiAgICAgIHRoaXMucmVkdWNlciA9IG5ldyBUU05FKG9wdGlvbnMpO1xuICAgICAgdGhpcy5pdGVyYXRpb25zID0gb3B0aW9ucz8uaXRlcmF0aW9ucyA/PyB0aGlzLnJlZHVjZXIuZ2V0SXRlclNpemUodGhpcy5kYXRhWzBdLmxlbmd0aCk7XG4gICAgICB0aGlzLmRpc3RhbmNlRm5hbWVzID0gb3B0aW9ucy5kaXN0YW5jZUZuYW1lcztcbiAgICAgIHRoaXMuZGlzdGFuY2VGbnMgPSBvcHRpb25zLmRpc3RhbmNlRm5zO1xuICAgICAgdGhpcy5kaXN0YW5jZUZuQXJncyA9IG9wdGlvbnMuZGlzdGFuY2VGbkFyZ3M7XG4gICAgICB0aGlzLnByb2dyZXNzRnVuYyA9IG9wdGlvbnMucHJvZ3Jlc3NGdW5jO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgdC1TTkUgbWV0aG9kLlxcXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnNdIFdoZXRoZXIgdG8gdXNlIHBhcmFsbGVsIGRpc3RhbmNlIHdvcmtlcnMuXG4gICAgICogQHJldHVybiB7YW55fSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBvZiB0aGlzIGVtYmVkZGluZyBhbmQgZGlzdGFuY2UgbWF0cml4IHdoZXJlIGFwcGxpY2FibGUuXG4gICAgICovXG4gICAgcHVibGljIGFzeW5jIHRyYW5zZm9ybSgpOiBQcm9taXNlPE1hdHJpeD4ge1xuICAgICAgaWYgKHRoaXMuZGF0YVswXS5sZW5ndGggPiAxMDAwMClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYXhpbXVtIG51bWJlciBvZiBzYW1wbGVzIGZvciBULVNORSBpcyAxMDAwMCcpO1xuICAgICAgY29uc3QgbWF0cml4U2VydmljZSA9IG5ldyBEaXN0YW5jZU1hdHJpeFNlcnZpY2UodHJ1ZSwgZmFsc2UpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gY29uc3QgYWdncmVnYXRlID0gZ2V0QWdncmVnYXRpb25GdW5jdGlvbih0aGlzLmFnZ3JlZ2F0aW9uTWV0aG9kLCB0aGlzLndlaWdodHMpO1xuICAgICAgICAvLyBjb25zdCBkaXN0YW5jZXM6IEFycmF5PEZsb2F0MzJBcnJheT4gPSBbXTtcbiAgICAgICAgLy8gZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmRhdGEubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgLy8gICBjb25zdCBkaXN0ID0gYXdhaXQgbWF0cml4U2VydmljZS5jYWxjKHRoaXMuZGF0YVtpXSwgdGhpcy5kaXN0YW5jZUZuYW1lc1tpXSwgZmFsc2UsIHRoaXMuZGlzdGFuY2VGbkFyZ3NbaV0pO1xuICAgICAgICAvLyAgIGRpc3RhbmNlcy5wdXNoKGRpc3QpO1xuICAgICAgICAvLyB9XG4gICAgICAgIC8vIGNvbnN0IGRpc3RhbmNlID0gbmV3IEZsb2F0MzJBcnJheShkaXN0YW5jZXNbMF0ubGVuZ3RoKS5maWxsKDApO1xuICAgICAgICAvLyBmb3IgKGxldCBpID0gMDsgaSA8IGRpc3RhbmNlc1swXS5sZW5ndGg7ICsraSlcbiAgICAgICAgLy8gICBkaXN0YW5jZVtpXSA9IGFnZ3JlZ2F0ZShkaXN0YW5jZXMubWFwKChkKSA9PiBkW2ldKSk7XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gYXdhaXQgbWF0cml4U2VydmljZS5jYWxjTXVsdGkodGhpcy5kYXRhLCB0aGlzLmRpc3RhbmNlRm5hbWVzLCBmYWxzZSwgdGhpcy5kaXN0YW5jZUZuQXJncyxcbiAgICAgICAgICB0aGlzLndlaWdodHMsIHRoaXMuYWdncmVnYXRpb25NZXRob2QpO1xuICAgICAgICBtYXRyaXhTZXJ2aWNlLnRlcm1pbmF0ZSgpO1xuICAgICAgICAvLyBjb25zdCBtYXRyaXhQcm94eSA9IGRpc3RhbmNlTWF0cml4UHJveHkoZGlzdGFuY2UsIHRoaXMuZGF0YVswXS5sZW5ndGgpO1xuICAgICAgICB0aGlzLnJlZHVjZXIuaW5pdERhdGFEaXN0KGRpc3RhbmNlLCB0aGlzLmRhdGFbMF0ubGVuZ3RoKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuaXRlcmF0aW9uczsgKytpKSB7XG4gICAgICAgICAgdGhpcy5yZWR1Y2VyLnN0ZXAoKTsgLy8gZXZlcnkgdGltZSB5b3UgY2FsbCB0aGlzLCBzb2x1dGlvbiBnZXRzIGJldHRlclxuICAgICAgICAgIGlmICh0aGlzLnByb2dyZXNzRnVuYylcbiAgICAgICAgICAgIHRoaXMucHJvZ3Jlc3NGdW5jKGksIHRoaXMuaXRlcmF0aW9ucywgW10pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnJlZHVjZXIuZ2V0U29sdXRpb24oKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbWF0cml4U2VydmljZS50ZXJtaW5hdGUoKTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIFVNQVBSZWR1Y2VyIGV4dGVuZHMgTXVsdGlDb2x1bW5SZWR1Y2VyIHtcbiAgICBwcm90ZWN0ZWQgcmVkdWNlcjogVU1BUDtcbiAgICBwcm90ZWN0ZWQgZGlzdGFuY2VGbmFtZXM6IEtub3duTWV0cmljc1tdO1xuICAgIHByb3RlY3RlZCBkaXN0YW5jZUZuczogRnVuY3Rpb25bXTtcbiAgICBwcm90ZWN0ZWQgdmVjdG9yczogbnVtYmVyW107XG4gICAgcHJvdGVjdGVkIHByb2dyZXNzRnVuYz86IChlcG9jOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmc6IG51bWJlcltdW10pID0+IHZvaWQ7XG4gICAgcHJvdGVjdGVkIGRpc3RhbmNlRm5BcmdzOiB7W186IHN0cmluZ106IGFueX1bXTtcbiAgICBwcm90ZWN0ZWQgdXNlV2ViR1BVOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIHdlYkdQVVJlZHVjZXI6IFdlYkdQVVVNQVAgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBVTUFQUmVkdWNlci5cbiAgICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKiBAbWVtYmVyb2YgVU1BUFJlZHVjZXJcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zKSB7XG4gICAgICBjb25zdCByYW5kb21TZWVkOiBzdHJpbmcgPSBvcHRpb25zLnJhbmRvbVNlZWQgPz8gRGF0ZSgpO1xuICAgICAgY29uc3QgcmFuZG9tRm4gPSBzZWVkUmFuZG9tKHJhbmRvbVNlZWQpO1xuICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICBhc3NlcnQoJ2Rpc3RhbmNlRm5hbWVzJyBpbiBvcHRpb25zKTtcbiAgICAgIGFzc2VydCgnZGlzdGFuY2VGbnMnIGluIG9wdGlvbnMpO1xuICAgICAgdGhpcy5kaXN0YW5jZUZuQXJncyA9IG9wdGlvbnMuZGlzdGFuY2VGbkFyZ3M7XG4gICAgICB0aGlzLmRpc3RhbmNlRm5zID0gb3B0aW9ucy5kaXN0YW5jZUZucyE7XG4gICAgICB0aGlzLnByb2dyZXNzRnVuYyA9IG9wdGlvbnMucHJvZ3Jlc3NGdW5jO1xuICAgICAgdGhpcy51c2VXZWJHUFUgPSBvcHRpb25zLnVzZVdlYkdQVSA/PyBmYWxzZTtcbiAgICAgIHRoaXMuZGlzdGFuY2VGbmFtZXMgPSBvcHRpb25zLmRpc3RhbmNlRm5hbWVzITtcbiAgICAgIG9wdGlvbnMubkNvbXBvbmVudHMgPSAyOyAvLyBUT0RPOiBtYWtlIGl0IGNvbmZpZ3VyYWJsZVxuICAgICAgLy9VbWFwIHVzZXMgdmVjdG9yIGluZGV4aW5nLCBzbyB3ZSBuZWVkIHRvIGNyZWF0ZSBhbiBhcnJheSBvZiB2ZWN0b3JzIGFzIGluZGVjZXMuXG4gICAgICB0aGlzLnZlY3RvcnMgPSBuZXcgQXJyYXkodGhpcy5kYXRhWzBdLmxlbmd0aCkuZmlsbCgwKS5tYXAoKF8sIGkpID0+IGkpO1xuXG4gICAgICBpZiAodGhpcy5kYXRhWzBdLmxlbmd0aCA8PSAob3B0aW9ucy5uTmVpZ2hib3JzID8/IDE1KSlcbiAgICAgICAgb3B0aW9ucy5uTmVpZ2hib3JzID0gdGhpcy5kYXRhWzBdLmxlbmd0aCAtIDE7XG4gICAgICBvcHRpb25zLnJhbmRvbSA9IHJhbmRvbUZuO1xuICAgICAgdGhpcy5yZWR1Y2VyID0gbmV3IFVNQVAob3B0aW9ucyk7XG4gICAgICAvLyB0aGlzLnJlZHVjZXIuZGlzdGFuY2VGbiA9IHRoaXMuX2VuY29kZWREaXN0YW5jZS5iaW5kKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgVU1BUCBtZXRob2QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbX3BhcmFsbGVsRGlzdGFuY2VXb3JrZXJzXSBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSBtYXRyaXggd29ya2Vycy5cbiAgICAgKiBAcmV0dXJuIHthbnl9IENhcnRlc2lhbiBjb29yZGluYXRlIG9mIHRoaXMgZW1iZWRkaW5nLlxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0oX3BhcmFsbGVsRGlzdGFuY2VXb3JrZXJzPzogYm9vbGVhbik6IFByb21pc2U8TWF0cml4PiB7XG4gICAgICBjb25zb2xlLnRpbWUoJ2tubiBncmFwaCcpO1xuICAgICAgbGV0IGtubkdyYXBoOiBLbm5SZXN1bHQgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICBpZiAodGhpcy51c2VXZWJHUFUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBrbm5HcmFwaCA9IGF3YWl0IG11bHRpQ29sV2ViR1BVS05OKFxuICAgICAgICAgICAgdGhpcy5kYXRhLCB0aGlzLnJlZHVjZXIubmVpZ2hib3JzLCB0aGlzLmRpc3RhbmNlRm5hbWVzIGFzIGFueSwgdGhpcy5hZ2dyZWdhdGlvbk1ldGhvZCBhcyBhbnksXG4gICAgICAgICAgICB0aGlzLndlaWdodHMsIHRoaXMuZGlzdGFuY2VGbkFyZ3NcbiAgICAgICAgICApIGFzIHVua25vd24gYXMgS25uUmVzdWx0O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFrbm5HcmFwaCkge1xuICAgICAgICBpZiAodGhpcy51c2VXZWJHUFUpXG4gICAgICAgICAgY29uc29sZS5lcnJvcignV0VCR1BVIEtOTiBmYWlsZWQsIGZhbGxpbmcgYmFjayB0byBtdWx0aXRocmVhZGVkIENQVSBpbXBsZW1lbnRhdGlvbicpO1xuICAgICAgICBrbm5HcmFwaCA9IGF3YWl0IG5ldyBTcGFyc2VNYXRyaXhTZXJ2aWNlKClcbiAgICAgICAgICAubXVsdGlDb2x1bW5LTk4odGhpcy5kYXRhLCB0aGlzLmRpc3RhbmNlRm5hbWVzLCB0aGlzLnJlZHVjZXIubmVpZ2hib3JzLFxuICAgICAgICAgICAgdGhpcy5kaXN0YW5jZUZuQXJncywgdGhpcy53ZWlnaHRzLCB0aGlzLmFnZ3JlZ2F0aW9uTWV0aG9kKTtcbiAgICAgIH1cbiAgICAgIGNvbnNvbGUudGltZUVuZCgna25uIGdyYXBoJyk7XG4gICAgICBpZiAodGhpcy51c2VXZWJHUFUpIHtcbiAgICAgICAgdGhpcy53ZWJHUFVSZWR1Y2VyID0gbmV3IFdlYkdQVVVNQVAodGhpcy52ZWN0b3JzLmxlbmd0aCwge1xuICAgICAgICAgIG5Db21wb25lbnRzOiB0aGlzLnJlZHVjZXIubkNvbXBvbmVudHMsXG4gICAgICAgICAgZ2FtbWE6IHRoaXMucmVkdWNlci5yZXB1bHNpb25TdHJlbmd0aCxcbiAgICAgICAgICBhbHBoYTogdGhpcy5yZWR1Y2VyLmxlYXJuaW5nUmF0ZSxcbiAgICAgICAgICBuTmVpZ2hib3VyczogdGhpcy5yZWR1Y2VyLm5laWdoYm9ycyxcbiAgICAgICAgICBzcHJlYWQ6IHRoaXMucmVkdWNlci5zcHJlYWQsXG4gICAgICAgICAgbWluRGlzdDogdGhpcy5yZWR1Y2VyLm1pbkRpc3QsXG4gICAgICAgICAgbmVnYXRpdmVTYW1wbGVSYXRlOiB0aGlzLnJlZHVjZXIubmVnYXRpdmVTYW1wbGVSYXRlLFxuICAgICAgICAgIGxvY2FsQ29ubmVjdGl2aXR5OiB0aGlzLnJlZHVjZXIubG9jYWxDb25uZWN0aXZpdHksXG4gICAgICAgICAgc2V0T3BNaXhSYXRpbzogdGhpcy5yZWR1Y2VyLnNldE9wTWl4UmF0aW8sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLndlYkdQVVJlZHVjZXIuc2V0UHJlY29tcHV0ZWRLTk4oa25uR3JhcGgua25uSW5kZXhlcywga25uR3JhcGgua25uRGlzdGFuY2VzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVkdWNlci5zZXRQcmVjb21wdXRlZEtOTihrbm5HcmFwaC5rbm5JbmRleGVzLCBrbm5HcmFwaC5rbm5EaXN0YW5jZXMpO1xuICAgICAgfVxuXG4gICAgICAvLyBuZWVkZWQgc28gdGhhdCBnYXJiYWdlIGNvbGxlY3RvciBjYW4gZnJlZSBtZW1vcnkgZnJvbSBkaXN0YW5jZSBtYXRyaXhcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSwgMzAwKTtcbiAgICAgIH0pO1xuXG4gICAgICBsZXQgZW1iZWRkaW5nOiBudW1iZXJbXVtdIHwgRmxvYXQzMkFycmF5W10gfCB1bmRlZmluZWQgfG51bGwgPSBudWxsO1xuICAgICAgY29uc29sZS50aW1lKCdmaXQnKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICh0aGlzLnVzZVdlYkdQVSAmJiB0aGlzLndlYkdQVVJlZHVjZXIpIHtcbiAgICAgICAgICBlbWJlZGRpbmcgPSBhd2FpdCB0aGlzLndlYkdQVVJlZHVjZXIuZml0KCk7XG4gICAgICAgICAgaWYgKCFlbWJlZGRpbmcpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBjb21wdXRlIGVtYmVkZGluZycpO1xuICAgICAgICAgIGVtYmVkZGluZyA9IC8vIHRyYW5zcG9zZSBUT0RPOiBkbyBhIGJldHRlciBqb2IgaGVyZVxuICAgICAgICAgICAgbmV3IEFycmF5KGVtYmVkZGluZ1swXS5sZW5ndGgpLmZpbGwobnVsbCkubWFwKChfLCBpKSA9PiBuZXcgRmxvYXQzMkFycmF5KGVtYmVkZGluZyEubWFwKCh2KSA9PiB2W2ldKSkpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICB9XG4gICAgICBpZiAoIWVtYmVkZGluZykge1xuICAgICAgICBpZiAodGhpcy51c2VXZWJHUFUpXG4gICAgICAgICAgY29uc29sZS5lcnJvcignV0VCR1BVIFVNQVAgZmFpbGVkLCBmYWxsaW5nIGJhY2sgdG8gQ1BVIGltcGxlbWVudGF0aW9uJyk7XG4gICAgICAgIGVtYmVkZGluZyA9IGF3YWl0IHRoaXMucmVkdWNlci5maXRBc3luYyh0aGlzLnZlY3RvcnMsIChlcG9jKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMucHJvZ3Jlc3NGdW5jKVxuICAgICAgICAgICAgdGhpcy5wcm9ncmVzc0Z1bmMoZXBvYywgdGhpcy5yZWR1Y2VyLmdldE5FcG9jaHMoKSwgdGhpcy5yZWR1Y2VyLmdldEVtYmVkZGluZygpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zb2xlLnRpbWVFbmQoJ2ZpdCcpO1xuICAgICAgcmV0dXJuIGFycmF5Q2FzdDJDb29yZGluYXRlcyhlbWJlZGRpbmcpO1xuICAgICAgZnVuY3Rpb24gYXJyYXlDYXN0MkNvb3JkaW5hdGVzKGRhdGE6IG51bWJlcltdW10gfCBGbG9hdDMyQXJyYXlbXSk6IENvb3JkaW5hdGVzIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBcnJheShkYXRhLmxlbmd0aCkuZmlsbCgwKS5tYXAoKF8sIGkpID0+IChWZWN0b3IuZnJvbShkYXRhW2ldKSkpO1xuICAgICAgfVxuICAgIH1cbn1cblxuY29uc3QgQXZhaWxhYmxlUmVkdWNlcnMgPSB7XG4gICdVTUFQJzogVU1BUFJlZHVjZXIsXG4gICd0LVNORSc6IFRTTkVSZWR1Y2VyLFxufTtcblxuZXhwb3J0IHR5cGUgS25vd25NZXRob2RzID0ga2V5b2YgdHlwZW9mIEF2YWlsYWJsZVJlZHVjZXJzO1xuXG5leHBvcnQgY2xhc3MgTXVsdGlDb2xEaW1SZWR1Y2VyIHtcbiAgICBwcml2YXRlIHJlZHVjZXI6IE11bHRpQ29sdW1uUmVkdWNlciB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXIuXG4gICAqIEBwYXJhbSB7YW55W119IGRhdGEgVmVjdG9ycyB0byBlbWJlZC5cbiAgICogQHBhcmFtIHtLbm93bk1ldGhvZHN9IG1ldGhvZCBFbWJlZGRpbmcgbWV0aG9kIHRvIGJlIGFwcGxpZWRcbiAgICogQHBhcmFtIHtLbm93bk1ldHJpY3N9IG1ldHJpYyBEaXN0YW5jZSBtZXRyaWMgdG8gYmUgY29tcHV0ZWQgYmV0d2VlbiBlYWNoIG9mIHRoZSB2ZWN0b3JzLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IFtvcHRpb25zXSBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGltcGxlbWVudGluZyBlbWJlZGRlcnMuXG4gICAqIEBtZW1iZXJvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAgICovXG4gICAgY29uc3RydWN0b3IoZGF0YTogQXJyYXk8YW55W10+LCBtZXRob2Q6IERpbVJlZHVjdGlvbk1ldGhvZHMsIG1ldHJpY3M6IEtub3duTWV0cmljc1tdLFxuICAgICAgd2VpZ2h0czogbnVtYmVyW10sIGRpc3RhbmNlQWdncmVnYXRpb246IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsIG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IG1lYXN1cmVzOiBEaXN0YW5jZU1ldHJpY1tdID0gW107XG4gICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCBtZXRyaWNzLmxlbmd0aDsgKytpZHgpIHtcbiAgICAgICAgY29uc3QgbWVhc3VyZSA9IG5ldyBNZWFzdXJlKG1ldHJpY3NbaWR4XSkuZ2V0TWVhc3VyZShvcHRpb25zLmRpc3RhbmNlRm5BcmdzW2lkeF0pO1xuICAgICAgICBtZWFzdXJlcy5wdXNoKG1lYXN1cmUpO1xuICAgICAgICBsZXQgYml0QXJyYXlMZW5ndGggPSAyMDQ4O1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFbaWR4XS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmIChkYXRhW2lkeF1baV0gJiYgZGF0YVtpZHhdW2ldLl9sZW5ndGgpIHtcbiAgICAgICAgICAgIGJpdEFycmF5TGVuZ3RoID0gZGF0YVtpZHhdW2ldLl9sZW5ndGg7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQml0QXJyYXlNZXRyaWMobWV0cmljc1tpZHhdKSkge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YVtpZHhdLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAoZGF0YVtpZHhdW2ldICYmIGRhdGFbaWR4XVtpXS5fZGF0YSlcbiAgICAgICAgICAgICAgZGF0YVtpZHhdW2ldID0gbmV3IEJpdEFycmF5KGRhdGFbaWR4XVtpXS5fZGF0YSwgZGF0YVtpZHhdW2ldLl9sZW5ndGgpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBkYXRhW2lkeF1baV0gPSBuZXcgQml0QXJyYXkoYml0QXJyYXlMZW5ndGgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobWV0aG9kID09ICdVTUFQJykge1xuICAgICAgICB0aGlzLnJlZHVjZXIgPSBuZXcgVU1BUFJlZHVjZXIoe1xuICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgZGlzdGFuY2VGbmFtZXM6IG1ldHJpY3MsXG4gICAgICAgICAgZGlzdGFuY2VGbnM6IG1lYXN1cmVzLFxuICAgICAgICAgIGRpc3RhbmNlRm5BcmdzOiBvcHRpb25zLmRpc3RhbmNlRm5BcmdzLFxuICAgICAgICAgIHdlaWdodHM6IHdlaWdodHMsXG4gICAgICAgICAgYWdncmVnYXRpb25NZXRob2Q6IGRpc3RhbmNlQWdncmVnYXRpb24sXG4gICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09ICd0LVNORScpIHtcbiAgICAgICAgdGhpcy5yZWR1Y2VyID0gbmV3IFRTTkVSZWR1Y2VyKHtcbiAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgIGRpc3RhbmNlRm5hbWVzOiBtZXRyaWNzLFxuICAgICAgICAgIGRpc3RhbmNlRm5zOiBtZWFzdXJlcyxcbiAgICAgICAgICBkaXN0YW5jZUZuQXJnczogb3B0aW9ucy5kaXN0YW5jZUZuQXJncyxcbiAgICAgICAgICB3ZWlnaHRzOiB3ZWlnaHRzLFxuICAgICAgICAgIGFnZ3JlZ2F0aW9uTWV0aG9kOiBkaXN0YW5jZUFnZ3JlZ2F0aW9uLFxuICAgICAgICAgIC4uLm9wdGlvbnNcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgdGhlIGNob3NlbiBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdHJhbnNwb3NlIFdoZXRoZXIgdG8gdHJhbnNmb3JtIGNvb3JkaW5hdGVzIHRvIGhhdmUgY29sdW1ucy1maXJzdCBvcmllbnRhdGlvbi5cbiAgICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSBjb21wdXRhdGlvbi5cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBlbWJlZGRpbmcgbWV0aG9kIHdhcyBub3QgZm91bmQuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLlxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICAgIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0odHJhbnNwb3NlOiBib29sZWFuID0gZmFsc2UpOiBQcm9taXNlPE1hdHJpeD4ge1xuICAgICAgaWYgKHRoaXMucmVkdWNlciA9PT0gdW5kZWZpbmVkKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZHVjZXIgd2FzIG5vdCBkZWZpbmVkLicpO1xuXG4gICAgICBsZXQgZW1iZWRkaW5nID0gYXdhaXQgdGhpcy5yZWR1Y2VyLnRyYW5zZm9ybSgpO1xuXG4gICAgICBpZiAodHJhbnNwb3NlKVxuICAgICAgICBlbWJlZGRpbmcgPSB0cmFuc3Bvc2VNYXRyaXgoZW1iZWRkaW5nKTtcblxuICAgICAgcmV0dXJuIGVtYmVkZGluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICogUmV0dXJucyBtZXRyaWNzIGF2YWlsYWJsZSBieSB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0ge0F2YWlsYWJsZURhdGFUeXBlc30gdHlwZU5hbWUgdHlwZSBuYW1lXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBNZXRyaWMgbmFtZXMgd2hpY2ggZXhwZWN0cyB0aGUgZ2l2ZW4gZGF0YSB0eXBlXG4gICAqIEBtZW1iZXJvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAgICovXG4gICAgc3RhdGljIGF2YWlsYWJsZU1ldHJpY3NCeVR5cGUodHlwZU5hbWU6IEF2YWlsYWJsZURhdGFUeXBlcykge1xuICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3NbdHlwZU5hbWVdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICogUmV0dXJucyBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gbWV0aG9kcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEByZWFkb25seVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICAgIHN0YXRpYyBnZXQgYXZhaWxhYmxlTWV0aG9kcygpIHtcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhBdmFpbGFibGVSZWR1Y2Vycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAqIFJldHVybnMgbWV0cmljcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEByZWFkb25seVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICAgIHN0YXRpYyBnZXQgYXZhaWxhYmxlTWV0cmljcygpIHtcbiAgICAgIGxldCBhbnM6IHN0cmluZ1tdID0gW107XG4gICAgICBPYmplY3QudmFsdWVzKEF2YWlsYWJsZU1ldHJpY3MpLmZvckVhY2goKG9iaikgPT4ge1xuICAgICAgICBjb25zdCBhcnJheSA9IE9iamVjdC52YWx1ZXMob2JqKTtcbiAgICAgICAgYW5zID0gWy4uLmFucywgLi4uYXJyYXldO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYW5zO1xuICAgIH1cbn1cbiJdfQ==","import { MultiColDimReducer } from './multi-column-dim-reducer';\n/**\n * Worker thread receiving data function.\n *\n * @param {any[]} columnData Samples to process.\n * @param {KnownMethods} method Embedding method.\n * @param {KnownMetrics} measure Distance metric.\n * @param {any} options Options to pass to algorithm.\n * @param {boolean} parallelDistanceWorkers Whether to use parallel distance workers.\n * @return {any} Embedding (and distance matrix where applicable).\n */\nasync function onMessage(columnsData, method, metrics, weights, aggregationMethod, options) {\n const reducer = new MultiColDimReducer(columnsData, method, metrics, weights, aggregationMethod, { ...options, progressFunc });\n return await reducer.transform(true);\n}\nasync function progressFunc(epochNum, epochsLength, embedding) {\n if (epochNum % 5 === 0)\n self.postMessage({ epochNum, epochsLength, embedding });\n}\nself.onmessage = async ({ data: { columnsData, method, distanceMetrics, options, weights, aggregationMethod } }) => {\n let data;\n try {\n const embedding = await onMessage(columnsData, method, distanceMetrics, weights, aggregationMethod, options);\n data = { embedding };\n }\n catch (e) {\n data = { error: e };\n }\n self.postMessage({\n error: data.error,\n embedding: data.embedding,\n });\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsaXQtY29sdW1uLWRpbS1yZWR1Y2VyLXdvcmtlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm11bGl0LWNvbHVtbi1kaW0tcmVkdWNlci13b3JrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFFOUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsS0FBSyxVQUFVLFNBQVMsQ0FBQyxXQUF5QixFQUFFLE1BQTJCLEVBQUUsT0FBdUIsRUFDdEcsT0FBaUIsRUFBRSxpQkFBNEMsRUFDL0QsT0FBWTtJQUNaLE1BQU0sT0FBTyxHQUFHLElBQUksa0JBQWtCLENBQ3BDLFdBQVcsRUFDWCxNQUFNLEVBQ04sT0FBTyxFQUNQLE9BQU8sRUFDUCxpQkFBaUIsRUFDakIsRUFBQyxHQUFHLE9BQU8sRUFBRSxZQUFZLEVBQUMsQ0FDM0IsQ0FBQztJQUNGLE9BQU8sTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3ZDLENBQUM7QUFFRCxLQUFLLFVBQVUsWUFBWSxDQUFDLFFBQWdCLEVBQUUsWUFBb0IsRUFBRSxTQUFxQjtJQUN2RixJQUFJLFFBQVEsR0FBRyxDQUFDLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUMsQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssRUFBRSxFQUFDLElBQUksRUFBRSxFQUFDLFdBQVcsRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUMsRUFBQyxFQUFFLEVBQUU7SUFDN0csSUFBSSxJQUFvQyxDQUFDO0lBQ3pDLElBQUksQ0FBQztRQUNILE1BQU0sU0FBUyxHQUFHLE1BQU0sU0FBUyxDQUFDLFdBQVcsRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM3RyxJQUFJLEdBQUcsRUFBQyxTQUFTLEVBQUMsQ0FBQztJQUNyQixDQUFDO0lBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztRQUNoQixJQUFJLEdBQUcsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUM7SUFDcEIsQ0FBQztJQUNELElBQUksQ0FBQyxXQUFXLENBQUM7UUFDZixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7UUFDakIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO0tBQzFCLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TWF0cml4fSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge0tub3duTWV0cmljc30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcy90eXBlZC1tZXRyaWNzJztcbmltcG9ydCB7RGltUmVkdWN0aW9uTWV0aG9kc30gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge0Rpc3RhbmNlQWdncmVnYXRpb25NZXRob2R9IGZyb20gJy4uL2Rpc3RhbmNlLW1hdHJpeC90eXBlcyc7XG5pbXBvcnQge011bHRpQ29sRGltUmVkdWNlcn0gZnJvbSAnLi9tdWx0aS1jb2x1bW4tZGltLXJlZHVjZXInO1xuXG4vKipcbiAqIFdvcmtlciB0aHJlYWQgcmVjZWl2aW5nIGRhdGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHthbnlbXX0gY29sdW1uRGF0YSBTYW1wbGVzIHRvIHByb2Nlc3MuXG4gKiBAcGFyYW0ge0tub3duTWV0aG9kc30gbWV0aG9kIEVtYmVkZGluZyBtZXRob2QuXG4gKiBAcGFyYW0ge0tub3duTWV0cmljc30gbWVhc3VyZSBEaXN0YW5jZSBtZXRyaWMuXG4gKiBAcGFyYW0ge2FueX0gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gYWxnb3JpdGhtLlxuICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSB3b3JrZXJzLlxuICogQHJldHVybiB7YW55fSBFbWJlZGRpbmcgKGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZSkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG9uTWVzc2FnZShjb2x1bW5zRGF0YTogQXJyYXk8YW55W10+LCBtZXRob2Q6IERpbVJlZHVjdGlvbk1ldGhvZHMsIG1ldHJpY3M6IEtub3duTWV0cmljc1tdLFxuICB3ZWlnaHRzOiBudW1iZXJbXSwgYWdncmVnYXRpb25NZXRob2Q6IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsXG4gIG9wdGlvbnM6IGFueSk6IFByb21pc2U8TWF0cml4PiB7XG4gIGNvbnN0IHJlZHVjZXIgPSBuZXcgTXVsdGlDb2xEaW1SZWR1Y2VyKFxuICAgIGNvbHVtbnNEYXRhLFxuICAgIG1ldGhvZCxcbiAgICBtZXRyaWNzLFxuICAgIHdlaWdodHMsXG4gICAgYWdncmVnYXRpb25NZXRob2QsXG4gICAgey4uLm9wdGlvbnMsIHByb2dyZXNzRnVuY31cbiAgKTtcbiAgcmV0dXJuIGF3YWl0IHJlZHVjZXIudHJhbnNmb3JtKHRydWUpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwcm9ncmVzc0Z1bmMoZXBvY2hOdW06IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZzogbnVtYmVyW11bXSkge1xuICBpZiAoZXBvY2hOdW0gJSA1ID09PSAwKVxuICAgIHNlbGYucG9zdE1lc3NhZ2Uoe2Vwb2NoTnVtLCBlcG9jaHNMZW5ndGgsIGVtYmVkZGluZ30pO1xufVxuXG5zZWxmLm9ubWVzc2FnZSA9IGFzeW5jICh7ZGF0YToge2NvbHVtbnNEYXRhLCBtZXRob2QsIGRpc3RhbmNlTWV0cmljcywgb3B0aW9ucywgd2VpZ2h0cywgYWdncmVnYXRpb25NZXRob2R9fSkgPT4ge1xuICBsZXQgZGF0YToge2Vycm9yPzogYW55LCBlbWJlZGRpbmc/OiBhbnl9O1xuICB0cnkge1xuICAgIGNvbnN0IGVtYmVkZGluZyA9IGF3YWl0IG9uTWVzc2FnZShjb2x1bW5zRGF0YSwgbWV0aG9kLCBkaXN0YW5jZU1ldHJpY3MsIHdlaWdodHMsIGFnZ3JlZ2F0aW9uTWV0aG9kLCBvcHRpb25zKTtcbiAgICBkYXRhID0ge2VtYmVkZGluZ307XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGRhdGEgPSB7ZXJyb3I6IGV9O1xuICB9XG4gIHNlbGYucG9zdE1lc3NhZ2Uoe1xuICAgIGVycm9yOiBkYXRhLmVycm9yLFxuICAgIGVtYmVkZGluZzogZGF0YS5lbWJlZGRpbmcsXG4gIH0pO1xufTtcbiJdfQ==","// A library of seedable RNGs implemented in Javascript.\n//\n// Usage:\n//\n// var seedrandom = require('seedrandom');\n// var random = seedrandom(1); // or any seed.\n// var x = random(); // 0 <= x < 1. Every bit is random.\n// var x = random.quick(); // 0 <= x < 1. 32 bits of randomness.\n\n// alea, a 53-bit multiply-with-carry generator by Johannes Baagøe.\n// Period: ~2^116\n// Reported to pass all BigCrush tests.\nvar alea = require('./lib/alea');\n\n// xor128, a pure xor-shift generator by George Marsaglia.\n// Period: 2^128-1.\n// Reported to fail: MatrixRank and LinearComp.\nvar xor128 = require('./lib/xor128');\n\n// xorwow, George Marsaglia's 160-bit xor-shift combined plus weyl.\n// Period: 2^192-2^32\n// Reported to fail: CollisionOver, SimpPoker, and LinearComp.\nvar xorwow = require('./lib/xorwow');\n\n// xorshift7, by François Panneton and Pierre L'ecuyer, takes\n// a different approach: it adds robustness by allowing more shifts\n// than Marsaglia's original three. It is a 7-shift generator\n// with 256 bits, that passes BigCrush with no systmatic failures.\n// Period 2^256-1.\n// No systematic BigCrush failures reported.\nvar xorshift7 = require('./lib/xorshift7');\n\n// xor4096, by Richard Brent, is a 4096-bit xor-shift with a\n// very long period that also adds a Weyl generator. It also passes\n// BigCrush with no systematic failures. Its long period may\n// be useful if you have many generators and need to avoid\n// collisions.\n// Period: 2^4128-2^32.\n// No systematic BigCrush failures reported.\nvar xor4096 = require('./lib/xor4096');\n\n// Tyche-i, by Samuel Neves and Filipe Araujo, is a bit-shifting random\n// number generator derived from ChaCha, a modern stream cipher.\n// https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf\n// Period: ~2^127\n// No systematic BigCrush failures reported.\nvar tychei = require('./lib/tychei');\n\n// The original ARC4-based prng included in this library.\n// Period: ~2^1600\nvar sr = require('./seedrandom');\n\nsr.alea = alea;\nsr.xor128 = xor128;\nsr.xorwow = xorwow;\nsr.xorshift7 = xorshift7;\nsr.xor4096 = xor4096;\nsr.tychei = tychei;\n\nmodule.exports = sr;\n","// A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010\n// http://baagoe.com/en/RandomMusings/javascript/\n// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror\n// Original work is under MIT license -\n\n// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n\n\n(function(global, module, define) {\n\nfunction Alea(seed) {\n var me = this, mash = Mash();\n\n me.next = function() {\n var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32\n me.s0 = me.s1;\n me.s1 = me.s2;\n return me.s2 = t - (me.c = t | 0);\n };\n\n // Apply the seeding algorithm from Baagoe.\n me.c = 1;\n me.s0 = mash(' ');\n me.s1 = mash(' ');\n me.s2 = mash(' ');\n me.s0 -= mash(seed);\n if (me.s0 < 0) { me.s0 += 1; }\n me.s1 -= mash(seed);\n if (me.s1 < 0) { me.s1 += 1; }\n me.s2 -= mash(seed);\n if (me.s2 < 0) { me.s2 += 1; }\n mash = null;\n}\n\nfunction copy(f, t) {\n t.c = f.c;\n t.s0 = f.s0;\n t.s1 = f.s1;\n t.s2 = f.s2;\n return t;\n}\n\nfunction impl(seed, opts) {\n var xg = new Alea(seed),\n state = opts && opts.state,\n prng = xg.next;\n prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }\n prng.double = function() {\n return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53\n };\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nfunction Mash() {\n var n = 0xefc8249d;\n\n var mash = function(data) {\n data = String(data);\n for (var i = 0; i < data.length; i++) {\n n += data.charCodeAt(i);\n var h = 0.02519603282416938 * n;\n n = h >>> 0;\n h -= n;\n h *= n;\n n = h >>> 0;\n h -= n;\n n += h * 0x100000000; // 2^32\n }\n return (n >>> 0) * 2.3283064365386963e-10; // 2^-32\n };\n\n return mash;\n}\n\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.alea = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","// A Javascript implementaion of the \"Tyche-i\" prng algorithm by\n// Samuel Neves and Filipe Araujo.\n// See https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this, strseed = '';\n\n // Set up generator function.\n me.next = function() {\n var b = me.b, c = me.c, d = me.d, a = me.a;\n b = (b << 25) ^ (b >>> 7) ^ c;\n c = (c - d) | 0;\n d = (d << 24) ^ (d >>> 8) ^ a;\n a = (a - b) | 0;\n me.b = b = (b << 20) ^ (b >>> 12) ^ c;\n me.c = c = (c - d) | 0;\n me.d = (d << 16) ^ (c >>> 16) ^ a;\n return me.a = (a - b) | 0;\n };\n\n /* The following is non-inverted tyche, which has better internal\n * bit diffusion, but which is about 25% slower than tyche-i in JS.\n me.next = function() {\n var a = me.a, b = me.b, c = me.c, d = me.d;\n a = (me.a + me.b | 0) >>> 0;\n d = me.d ^ a; d = d << 16 ^ d >>> 16;\n c = me.c + d | 0;\n b = me.b ^ c; b = b << 12 ^ d >>> 20;\n me.a = a = a + b | 0;\n d = d ^ a; me.d = d = d << 8 ^ d >>> 24;\n me.c = c = c + d | 0;\n b = b ^ c;\n return me.b = (b << 7 ^ b >>> 25);\n }\n */\n\n me.a = 0;\n me.b = 0;\n me.c = 2654435769 | 0;\n me.d = 1367130551;\n\n if (seed === Math.floor(seed)) {\n // Integer seed.\n me.a = (seed / 0x100000000) | 0;\n me.b = seed | 0;\n } else {\n // String seed.\n strseed += seed;\n }\n\n // Mix in string seed, then discard an initial batch of 64 values.\n for (var k = 0; k < strseed.length + 20; k++) {\n me.b ^= strseed.charCodeAt(k) | 0;\n me.next();\n }\n}\n\nfunction copy(f, t) {\n t.a = f.a;\n t.b = f.b;\n t.c = f.c;\n t.d = f.d;\n return t;\n};\n\nfunction impl(seed, opts) {\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.tychei = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","// A Javascript implementaion of the \"xor128\" prng algorithm by\n// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this, strseed = '';\n\n me.x = 0;\n me.y = 0;\n me.z = 0;\n me.w = 0;\n\n // Set up generator function.\n me.next = function() {\n var t = me.x ^ (me.x << 11);\n me.x = me.y;\n me.y = me.z;\n me.z = me.w;\n return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8);\n };\n\n if (seed === (seed | 0)) {\n // Integer seed.\n me.x = seed;\n } else {\n // String seed.\n strseed += seed;\n }\n\n // Mix in string seed, then discard an initial batch of 64 values.\n for (var k = 0; k < strseed.length + 64; k++) {\n me.x ^= strseed.charCodeAt(k) | 0;\n me.next();\n }\n}\n\nfunction copy(f, t) {\n t.x = f.x;\n t.y = f.y;\n t.z = f.z;\n t.w = f.w;\n return t;\n}\n\nfunction impl(seed, opts) {\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.xor128 = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","// A Javascript implementaion of Richard Brent's Xorgens xor4096 algorithm.\n//\n// This fast non-cryptographic random number generator is designed for\n// use in Monte-Carlo algorithms. It combines a long-period xorshift\n// generator with a Weyl generator, and it passes all common batteries\n// of stasticial tests for randomness while consuming only a few nanoseconds\n// for each prng generated. For background on the generator, see Brent's\n// paper: \"Some long-period random number generators using shifts and xors.\"\n// http://arxiv.org/pdf/1004.3115v1.pdf\n//\n// Usage:\n//\n// var xor4096 = require('xor4096');\n// random = xor4096(1); // Seed with int32 or string.\n// assert.equal(random(), 0.1520436450538547); // (0, 1) range, 53 bits.\n// assert.equal(random.int32(), 1806534897); // signed int32, 32 bits.\n//\n// For nonzero numeric keys, this impelementation provides a sequence\n// identical to that by Brent's xorgens 3 implementaion in C. This\n// implementation also provides for initalizing the generator with\n// string seeds, or for saving and restoring the state of the generator.\n//\n// On Chrome, this prng benchmarks about 2.1 times slower than\n// Javascript's built-in Math.random().\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this;\n\n // Set up generator function.\n me.next = function() {\n var w = me.w,\n X = me.X, i = me.i, t, v;\n // Update Weyl generator.\n me.w = w = (w + 0x61c88647) | 0;\n // Update xor generator.\n v = X[(i + 34) & 127];\n t = X[i = ((i + 1) & 127)];\n v ^= v << 13;\n t ^= t << 17;\n v ^= v >>> 15;\n t ^= t >>> 12;\n // Update Xor generator array state.\n v = X[i] = v ^ t;\n me.i = i;\n // Result is the combination.\n return (v + (w ^ (w >>> 16))) | 0;\n };\n\n function init(me, seed) {\n var t, v, i, j, w, X = [], limit = 128;\n if (seed === (seed | 0)) {\n // Numeric seeds initialize v, which is used to generates X.\n v = seed;\n seed = null;\n } else {\n // String seeds are mixed into v and X one character at a time.\n seed = seed + '\\0';\n v = 0;\n limit = Math.max(limit, seed.length);\n }\n // Initialize circular array and weyl value.\n for (i = 0, j = -32; j < limit; ++j) {\n // Put the unicode characters into the array, and shuffle them.\n if (seed) v ^= seed.charCodeAt((j + 32) % seed.length);\n // After 32 shuffles, take v as the starting w value.\n if (j === 0) w = v;\n v ^= v << 10;\n v ^= v >>> 15;\n v ^= v << 4;\n v ^= v >>> 13;\n if (j >= 0) {\n w = (w + 0x61c88647) | 0; // Weyl.\n t = (X[j & 127] ^= (v + w)); // Combine xor and weyl to init array.\n i = (0 == t) ? i + 1 : 0; // Count zeroes.\n }\n }\n // We have detected all zeroes; make the key nonzero.\n if (i >= 128) {\n X[(seed && seed.length || 0) & 127] = -1;\n }\n // Run the generator 512 times to further mix the state before using it.\n // Factoring this as a function slows the main generator, so it is just\n // unrolled here. The weyl generator is not advanced while warming up.\n i = 127;\n for (j = 4 * 128; j > 0; --j) {\n v = X[(i + 34) & 127];\n t = X[i = ((i + 1) & 127)];\n v ^= v << 13;\n t ^= t << 17;\n v ^= v >>> 15;\n t ^= t >>> 12;\n X[i] = v ^ t;\n }\n // Storing state as object members is faster than using closure variables.\n me.w = w;\n me.X = X;\n me.i = i;\n }\n\n init(me, seed);\n}\n\nfunction copy(f, t) {\n t.i = f.i;\n t.w = f.w;\n t.X = f.X.slice();\n return t;\n};\n\nfunction impl(seed, opts) {\n if (seed == null) seed = +(new Date);\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (state.X) copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.xor4096 = impl;\n}\n\n})(\n this, // window object or global\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n","// A Javascript implementaion of the \"xorshift7\" algorithm by\n// François Panneton and Pierre L'ecuyer:\n// \"On the Xorgshift Random Number Generators\"\n// http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this;\n\n // Set up generator function.\n me.next = function() {\n // Update xor generator.\n var X = me.x, i = me.i, t, v, w;\n t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24);\n t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10);\n t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3);\n t = X[(i + 4) & 7]; v ^= t ^ (t << 7);\n t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9);\n X[i] = v;\n me.i = (i + 1) & 7;\n return v;\n };\n\n function init(me, seed) {\n var j, w, X = [];\n\n if (seed === (seed | 0)) {\n // Seed state array using a 32-bit integer.\n w = X[0] = seed;\n } else {\n // Seed state using a string.\n seed = '' + seed;\n for (j = 0; j < seed.length; ++j) {\n X[j & 7] = (X[j & 7] << 15) ^\n (seed.charCodeAt(j) + X[(j + 1) & 7] << 13);\n }\n }\n // Enforce an array length of 8, not all zeroes.\n while (X.length < 8) X.push(0);\n for (j = 0; j < 8 && X[j] === 0; ++j);\n if (j == 8) w = X[7] = -1; else w = X[j];\n\n me.x = X;\n me.i = 0;\n\n // Discard an initial 256 values.\n for (j = 256; j > 0; --j) {\n me.next();\n }\n }\n\n init(me, seed);\n}\n\nfunction copy(f, t) {\n t.x = f.x.slice();\n t.i = f.i;\n return t;\n}\n\nfunction impl(seed, opts) {\n if (seed == null) seed = +(new Date);\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (state.x) copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.xorshift7 = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n","// A Javascript implementaion of the \"xorwow\" prng algorithm by\n// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper\n\n(function(global, module, define) {\n\nfunction XorGen(seed) {\n var me = this, strseed = '';\n\n // Set up generator function.\n me.next = function() {\n var t = (me.x ^ (me.x >>> 2));\n me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v;\n return (me.d = (me.d + 362437 | 0)) +\n (me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0;\n };\n\n me.x = 0;\n me.y = 0;\n me.z = 0;\n me.w = 0;\n me.v = 0;\n\n if (seed === (seed | 0)) {\n // Integer seed.\n me.x = seed;\n } else {\n // String seed.\n strseed += seed;\n }\n\n // Mix in string seed, then discard an initial batch of 64 values.\n for (var k = 0; k < strseed.length + 64; k++) {\n me.x ^= strseed.charCodeAt(k) | 0;\n if (k == strseed.length) {\n me.d = me.x << 10 ^ me.x >>> 4;\n }\n me.next();\n }\n}\n\nfunction copy(f, t) {\n t.x = f.x;\n t.y = f.y;\n t.z = f.z;\n t.w = f.w;\n t.v = f.v;\n t.d = f.d;\n return t;\n}\n\nfunction impl(seed, opts) {\n var xg = new XorGen(seed),\n state = opts && opts.state,\n prng = function() { return (xg.next() >>> 0) / 0x100000000; };\n prng.double = function() {\n do {\n var top = xg.next() >>> 11,\n bot = (xg.next() >>> 0) / 0x100000000,\n result = (top + bot) / (1 << 21);\n } while (result === 0);\n return result;\n };\n prng.int32 = xg.next;\n prng.quick = prng;\n if (state) {\n if (typeof(state) == 'object') copy(state, xg);\n prng.state = function() { return copy(xg, {}); }\n }\n return prng;\n}\n\nif (module && module.exports) {\n module.exports = impl;\n} else if (define && define.amd) {\n define(function() { return impl; });\n} else {\n this.xorwow = impl;\n}\n\n})(\n this,\n (typeof module) == 'object' && module, // present in node.js\n (typeof define) == 'function' && define // present with an AMD loader\n);\n\n\n","/*\nCopyright 2019 David Bau.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n*/\n\n(function (global, pool, math) {\n//\n// The following constants are related to IEEE 754 limits.\n//\n\nvar width = 256, // each RC4 output is 0 <= x < 256\n chunks = 6, // at least six RC4 outputs for each double\n digits = 52, // there are 52 significant digits in a double\n rngname = 'random', // rngname: name for Math.random and Math.seedrandom\n startdenom = math.pow(width, chunks),\n significance = math.pow(2, digits),\n overflow = significance * 2,\n mask = width - 1,\n nodecrypto; // node.js crypto module, initialized at the bottom.\n\n//\n// seedrandom()\n// This is the seedrandom function described above.\n//\nfunction seedrandom(seed, options, callback) {\n var key = [];\n options = (options == true) ? { entropy: true } : (options || {});\n\n // Flatten the seed string or build one from local entropy if needed.\n var shortseed = mixkey(flatten(\n options.entropy ? [seed, tostring(pool)] :\n (seed == null) ? autoseed() : seed, 3), key);\n\n // Use the seed to initialize an ARC4 generator.\n var arc4 = new ARC4(key);\n\n // This function returns a random double in [0, 1) that contains\n // randomness in every bit of the mantissa of the IEEE 754 value.\n var prng = function() {\n var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48\n d = startdenom, // and denominator d = 2 ^ 48.\n x = 0; // and no 'extra last byte'.\n while (n < significance) { // Fill up all significant digits by\n n = (n + x) * width; // shifting numerator and\n d *= width; // denominator and generating a\n x = arc4.g(1); // new least-significant-byte.\n }\n while (n >= overflow) { // To avoid rounding up, before adding\n n /= 2; // last byte, shift everything\n d /= 2; // right using integer math until\n x >>>= 1; // we have exactly the desired bits.\n }\n return (n + x) / d; // Form the number within [0, 1).\n };\n\n prng.int32 = function() { return arc4.g(4) | 0; }\n prng.quick = function() { return arc4.g(4) / 0x100000000; }\n prng.double = prng;\n\n // Mix the randomness into accumulated entropy.\n mixkey(tostring(arc4.S), pool);\n\n // Calling convention: what to return as a function of prng, seed, is_math.\n return (options.pass || callback ||\n function(prng, seed, is_math_call, state) {\n if (state) {\n // Load the arc4 state from the given state if it has an S array.\n if (state.S) { copy(state, arc4); }\n // Only provide the .state method if requested via options.state.\n prng.state = function() { return copy(arc4, {}); }\n }\n\n // If called as a method of Math (Math.seedrandom()), mutate\n // Math.random because that is how seedrandom.js has worked since v1.0.\n if (is_math_call) { math[rngname] = prng; return seed; }\n\n // Otherwise, it is a newer calling convention, so return the\n // prng directly.\n else return prng;\n })(\n prng,\n shortseed,\n 'global' in options ? options.global : (this == math),\n options.state);\n}\n\n//\n// ARC4\n//\n// An ARC4 implementation. The constructor takes a key in the form of\n// an array of at most (width) integers that should be 0 <= x < (width).\n//\n// The g(count) method returns a pseudorandom integer that concatenates\n// the next (count) outputs from ARC4. Its return value is a number x\n// that is in the range 0 <= x < (width ^ count).\n//\nfunction ARC4(key) {\n var t, keylen = key.length,\n me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];\n\n // The empty key [] is treated as [0].\n if (!keylen) { key = [keylen++]; }\n\n // Set up S using the standard key scheduling algorithm.\n while (i < width) {\n s[i] = i++;\n }\n for (i = 0; i < width; i++) {\n s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];\n s[j] = t;\n }\n\n // The \"g\" method returns the next (count) outputs as one number.\n (me.g = function(count) {\n // Using instance members instead of closure state nearly doubles speed.\n var t, r = 0,\n i = me.i, j = me.j, s = me.S;\n while (count--) {\n t = s[i = mask & (i + 1)];\n r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];\n }\n me.i = i; me.j = j;\n return r;\n // For robust unpredictability, the function call below automatically\n // discards an initial batch of values. This is called RC4-drop[256].\n // See http://google.com/search?q=rsa+fluhrer+response&btnI\n })(width);\n}\n\n//\n// copy()\n// Copies internal state of ARC4 to or from a plain object.\n//\nfunction copy(f, t) {\n t.i = f.i;\n t.j = f.j;\n t.S = f.S.slice();\n return t;\n};\n\n//\n// flatten()\n// Converts an object tree to nested arrays of strings.\n//\nfunction flatten(obj, depth) {\n var result = [], typ = (typeof obj), prop;\n if (depth && typ == 'object') {\n for (prop in obj) {\n try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}\n }\n }\n return (result.length ? result : typ == 'string' ? obj : obj + '\\0');\n}\n\n//\n// mixkey()\n// Mixes a string seed into a key that is an array of integers, and\n// returns a shortened string seed that is equivalent to the result key.\n//\nfunction mixkey(seed, key) {\n var stringseed = seed + '', smear, j = 0;\n while (j < stringseed.length) {\n key[mask & j] =\n mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));\n }\n return tostring(key);\n}\n\n//\n// autoseed()\n// Returns an object for autoseeding, using window.crypto and Node crypto\n// module if available.\n//\nfunction autoseed() {\n try {\n var out;\n if (nodecrypto && (out = nodecrypto.randomBytes)) {\n // The use of 'out' to remember randomBytes makes tight minified code.\n out = out(width);\n } else {\n out = new Uint8Array(width);\n (global.crypto || global.msCrypto).getRandomValues(out);\n }\n return tostring(out);\n } catch (e) {\n var browser = global.navigator,\n plugins = browser && browser.plugins;\n return [+new Date, global, plugins, global.screen, tostring(pool)];\n }\n}\n\n//\n// tostring()\n// Converts an array of charcodes to a string\n//\nfunction tostring(a) {\n return String.fromCharCode.apply(0, a);\n}\n\n//\n// When seedrandom.js is loaded, we immediately mix a few bits\n// from the built-in RNG into the entropy pool. Because we do\n// not want to interfere with deterministic PRNG state later,\n// seedrandom will not call math.random on its own again after\n// initialization.\n//\nmixkey(math.random(), pool);\n\n//\n// Nodejs and AMD support: export the implementation as a module using\n// either convention.\n//\nif ((typeof module) == 'object' && module.exports) {\n module.exports = seedrandom;\n // When in node.js, try using crypto package for autoseeding.\n try {\n nodecrypto = require('crypto');\n } catch (ex) {}\n} else if ((typeof define) == 'function' && define.amd) {\n define(function() { return seedrandom; });\n} else {\n // When included as a plain script, set up Math.seedrandom global.\n math['seed' + rngname] = seedrandom;\n}\n\n\n// End anonymous scope, and pass initial values.\n})(\n // global: `self` in browsers (including strict mode and web workers),\n // otherwise `this` in Node and other environments\n (typeof self !== 'undefined') ? self : this,\n [], // pool: entropy pool starts empty\n Math // math: package containing random, pow, and seedrandom\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","isNil","insertSmaller","distancesAr","indexes","index","newPosition","findIndex","v","splice","assert","condition","message","Error","vectorDistanceMetricsMethods","Euclidean","p","q","pow","sqrt","stringDistanceMetricsMethods","Levenshtein","JaroWinkler","Manhattan","s1","s2","dist","Onehot","bitArrayDistanceMetricsMethods","Tanimoto","Dice","Asymmetric","BraunBlanquet","Cosine","Kulczynski","McConnaughey","RogotGoldberg","Russel","Sokal","Hamming","intArrayDistanceMetricsMethods","TanimotoIntArray","numberDistanceMetricsMethods","Difference","numberArrayDistanceMetrics","CommonItems","AvailableMetrics","Vector","BitArray","MacroMolecule","HAMMING","LEVENSHTEIN","NEEDLEMANN_WUNSCH","MONOMER_CHEMICAL_DISTANCE","Number","IntArray","NumberArray","MetricToDataType","keys","reduce","key","val","Measure","constructor","method","dataType","metricNeedsArgs","toString","name","isNumberArrayMetric","getMeasure","dict","hasOwnProperty","getMetricByDataType","availableMeasures","DistanceMatrixService","useConcurrentWorkers","terminateOnComplete","threadCount","navigator","hardwareConcurrency","_workerCount","_workers","Array","fill","map","Worker","URL","_terminateOnComplete","calc","values","fnName","normalize","calcMulti","MANHATTAN","fnNames","weights","aggregationMethod","async","promises","totalLength","chunkSize","distanceMatrix","endRow","endCol","lmin","lmax","MIN_VALUE","start","floor","end","startRow","startCol","postMessage","chunckSize","resolveWorker","rejectWorker","onmessage","data","error","distanceMatrixData","terminate","all","forEach","value","worker","tauRandInt","n","random","tauRand","empty","output","push","range","_","filled","zeros","mean","input","sum","rejectionSample","nSamples","poolSize","rejectSample","j","broken","k","reshape2d","a","rows","col","makeHeap","nPoints","makeArrays","fillValue","Infinity","heapPush","row","weight","flag","indices","uncheckedHeapPush","isNew","iSwap","ic1","ic2","heapShape2","buildCandidates","currentGraph","nVertices","nNeighbors","maxCandidates","candidateNeighbors","isn","d","deheapSort","indHeap","distHeap","indHeapIndex","distHeapIndex","temp1","temp2","siftDown","heap1","heap2","ceiling","elt","leftChild","rightChild","swap","smallestFlagged","ind","minDist","resultIndex","SparseMatrix","cols","dims","entries","Map","nRows","nCols","checkDims","makeKey","has","get","defaultValue","getAll","ordered","rowColValues","sort","getDims","getRows","from","_key","getCols","getValues","fn","vals","toArray","matrix","oldRows","oldCols","oldVals","matlen","pairwiseMultiply","elementWise","y","add","subtract","multiplyScalar","scalar","eliminateZeros","m","zeroIndices","Set","removeByZeroIndex","nextValues","filter","nextRows","nextCols","normType","normFn","normFns","colsByRow","nextMatrix","norm","xs","op","visited","operate","nextValue","valuesA","rowsA","colsA","valuesB","rowsB","colsB","getCSR","indptr","currentRow","FlatTree","hyperplanes","offsets","children","makeForest","nTrees","leafSize","trees","makeEuclideanTree","makeTree","forest","tree","nNodes","numNodes","nLeaves","numLeaves","hyperplane","recursiveFlatten","flattenTree","splitResults","leftIndex","rightIndex","left","right","hyperplaneOffset","hyperplaneVector","nLeft","nRight","side","margin","indicesLeft","indicesRight","offset","euclideanRandomProjectionSplit","isLeaf","nodeNum","leafNum","oldNodeNum","res","selectSide","point","searchFlatTree","prototype","isAnyArray","object","call","endsWith","errorCalculation","parameters","parameterizedFunction","abs","step","params","damping","gradientDifference","identity","eye","evaluatedData","gradientFunc","paramFunction","ans","param","auxParams","slice","funcParam","gradientFunction","matrixFunc","matrixFunction","inverseMatrix","mmul","transpose","sub","mul","to1DArray","SMOOTH_K_TOLERANCE","MIN_K_DIST_SCALE","UMAP","neighbors","learningRate","localConnectivity","nComponents","nEpochs","negativeSampleRate","repulsionStrength","setOpMixRatio","spread","transformQueueSize","targetMetric","targetWeight","targetNNeighbors","distanceFn","numeric","isInitialized","rpForest","embedding","optimizationState","OptimizationState","setParam","fit","X","initializeFit","optimizeLayout","fitAsync","optimizeLayoutAsync","setSupervisedProjection","Y","setPrecomputedKNN","knnIndices","knnDistances","getNEpochs","knnResults","nearestNeighbors","graph","fuzzySimplicialSet","makeSearchFns","searchGraph","makeSearchGraph","processGraphForSupervisedProjection","head","tail","epochsPerSample","initializeSimplicialSetEmbedding","initializeOptimization","prepareForOptimizationLoop","initFromTree","initFromRandom","queryPoints","_heap","_tree","search","initialization","tried","vertex","candidates","candidate","knn","distances","neighbor","distance","transform","toTransform","rawData","results","adjustedLocalConnectivity","sigmas","rhos","smoothKNNDistance","computeMembershipStrengths","csrMatrix","_z","initTransform","graphMax","makeEpochsPerSample","assignOptimizationStateParameters","headEmbedding","tailEmbedding","currentEpoch","farDist","categoricalSimplicialSetIntersection","optimizeLayoutStep","getEmbedding","metricNNDescent","leafArray","nIters","delta","rho","rpTreeInit","cj","ck","round","log2","sparseMatrix","prodMatrix","simplicialSet","target","unknownDist","intersection","exp","fastIntersection","resetLocalConnectivity","nIter","bandwidth","lo","hi","mid","ithDistances","nonZeroDists","interpolation","psum","meanIthDistances","meanDistances","graphValues","entry","w","state","dim","moveOther","epochsPerNegativeSample","epochOfNextNegativeSample","epochOfNextSample","initialAlpha","alpha","gamma","xv","yv","parameterValues","options","maxIterations","errorTolerance","minValues","maxValues","initialValues","parLen","MAX_SAFE_INTEGER","MIN_SAFE_INTEGER","iteration","converged","isNaN","parameterError","iterations","findABParams","current","other","distSquared","rDist","gradCoeff","gradD","clip","nNegSamples","epochCallback","epochCompleted","shouldStop","isFinished","clipValue","TSNE","getopt","opt","field","defaultval","gaussRandom","returnV","vValue","r","randn","mu","std","ArrayBuffer","randn2d","s","uses","l2","x1","x2","D","x1i","x2i","xtod","N","getIterSize","rowSize","d2p","perplexity","tol","indexer","hTarget","P","prow","betamin","betamax","beta","done","maxtries","pj","nHere","pOut","N2","sign","iter","epsilon","initDataRaw","dists","initSolution","initDataDist","time","timeEnd","gains","ystep","getSolution","cg","costGrad","cost","grad","ymean","gid","sid","gainid","newgain","newsid","debugGrad","yold","cg0","cg1","analytic","numerical","pmul","quArr","qsum","qu","prev","Q","premult","thisArg","_arguments","generator","fulfilled","next","rejected","gpuAdapter","gpuDevice","gpu","requestAdapter","powerPreference","isLost","lost","requiredBufferSize","adapterLimits","limits","buffferSizeLimit","maxBufferSize","storageBufferSizeLimit","maxStorageBufferBindingSize","requestDevice","requiredLimits","WEBGSLAGGREGATION","EUCLIDEAN","arraySize","WEBGPUDISTANCE","_maxArraySize","entryIndex","maxArraySize","_entryIndex","TANIMOTO","LEVENSTEIN","NEEDLEMAN_WUNSCH","SOKAL","COSINE","ASYMMETRIC","OneHot","distanceFunctionComplexity","maxEntrySize","ceil","_maxEntrySize","TypeSupportedDistances","MatrixMatrixOpType","MatrixOpType","MatrixScalarOpType","multiColWebGPUKNN","entryList","knnSize","distanceMetrics","aggregationFunction","some","list","availableDistanceMetrics","metric","includes","join","numOfColumns","device","deviceLost","listSize","processInfo","distanceMetric","gapOpenPenalty","gapExtensionPenalty","_a","_b","entryType","encodedList","split","_data","encodedListType","arraySizes","maxEntryLen","complexity","EncodedArrayConstructor","flatSourceArray","seq","suppInfoStructWgsl","suppInfoSize","suppInfoType","suppInfoBuffer","maxMonomerIndex","scoringMatrix","alphabetIndexes","similarityMatrixSize","transferedSimilarityMatrix","key2","dataTypeWGSL","dataStructWgsl","sourceArraySize","suppInfoWgsl","wgsl","needsDummy","trim","combinedComplexity","dataWgsl","computationsPerPass","pairComparisonsPerPass","workgroupsDim","globalThreadDimSize","resultIndexes","resultDistances","createShaderModule","label","code","getCombinedDistanceScript","pipeline","createComputePipeline","layout","compute","entryPoint","computeInfo32Size","suppInfo32Size","computeInfoBufferSize","BYTES_PER_ELEMENT","paddedComputeInfoBufferSize","remainder","computeInfoBuffer","createBuffer","usage","GPUBufferUsage","STORAGE","COPY_SRC","COPY_DST","mappedAtCreation","mappedComputeInfoArrayBuffer","getMappedRange","startAt","endAt","pairComparisonStartAt","pairComparisonEndAt","computeInfoOffSet","ArrayConstructor","unmap","suppInfoBufferSize","paddedSuppInfoBufferSize","suppInfoRemainder","mappedSuppInfoArrayBuffer","suppInfoOffSet","outKnnArraySize","bufferDistances","bufferIndexes","bytesPerOutArrayRow","bindGroup","createBindGroup","getBindGroupLayout","binding","resource","resultBufferDistances","MAP_READ","resultBufferIndexes","pairComparisonPasses","pairIter","queue","writeBuffer","encoder","createCommandEncoder","pass","beginComputePass","setPipeline","setBindGroup","dispatchWorkgroups","workGroupDivision","copyBufferToBuffer","commandBuffer","finish","submit","onSubmittedWorkDone","mapAsync","GPUMapMode","READ","destroy","knnIndexes","maxEntryLens","aggregation","pairwiseOpSparse","indexes1","distances1","offsets1","indexes2","distances2","offsets2","numOfEntries","unionMatrixOffsets","requiredWorkgroups","threadsPerWorkgroupDim","numOfWorkgroupsPerDim","threadsPerYDimension","sparseSize1","sparseSize2","unionMatrixSize","processWgsl","paddedStorage1ByteSize","remainder1","paddedStorage2ByteSize","remainder2","paddedResStorageByteSize","remainder3","source1Buffer","mappedSource1Buffer","source2Buffer","mappedSource2Buffer","resBuffer","unionMatrixOffsetsBuffer","mappedUnionMatrixOffsetsBuffer","resultBuffer","resultArrayBuffer","resultKnnIndexes","resultKnnDistances","weightSquare","centralDifference","nbParams","nbPoints","rowIndex","funcParam2","residualError","scale","jacobianWeightResidualError","perturbations","checkTimeout","dampingStepUp","dampingStepDown","improvementThreshold","timeout","filler","endTime","Date","now","checkOptions","optimalError","optimalParameters","previousError","toOffsetForm","ar","performMatrixOps","flatKnnIndexes","flatKnnDistances","unionInfo","entryLen","knnMatrixOpInfoWGSL","indexesBuffer32Size","indexBuffer","mappedIndexesBuffer","mappedIndexesArray","sizesBuffer","unionSizesBuffer","mappedUnionSizesBuffer","resultTransposeSizesBuffer","resultUnionSizesBuffer","resultTransposeSizesArrayBuffer","resultUnionSizesArrayBuffer","resultTransposeSizesArray","resultUnionSizesArray","old","getKnnSparseOpInfo","transposed","knnSparseInfo","fullKnnEntrySize","transposeOffsets","offsetsCopy","transposeKNNIndexes","transposeKNNDistances","otherIndex","otherIndexOffset","transposeKNN","sourceOffsets","transposeMultRes","addRes","subtRes","unionSizes","meanDistancesSum","currentMean","smoothKNNDistanceWGSL","distanceBuffer32Size","resultSigmas","resultRhos","distancesBuffer","mappedDistanceBuffer","mappedDistanceArray","bufferSigmas","bufferRhos","resultBufferRhos","resultBufferSigmas","UmapParams","nNeighbours","WebGPUUMAP","membershipStrengths","calcSmoothKNNDistances","calcMembershipStrengths","umapParams","resEmbeddings","embeddingSize","divisionFactor","headSize","processWGSL","embedSize","workgroupDim","threadsPerRow","optimizeLayoutWGSL","paddedMatrixStorageSize","paddedepochStorageSize","paddedembedStorageSize","paddedComputeInfoSize","remainder4","matrixStorageBuffer","matrixStorageArrayBuffer","epochStorageBuffer","epochStorageArrayBuffer","epochStorageArrayView","headEmbeddings","embeddingStorageBuffer","mappedEmbeddingStorageBuffer","mappedEmbeddingStorageArray","randomNumbers","computeInfoArrayBuffer","outEmbedViewBuffer","resArrayBuffer","headEmbeddingsView","optimizationLoop","sigmasLength","rhosLength","computeMembershipStrengthsWGSL","paddedCombinedMembershipStructByteSize","membershipStrengthsInfoBuffer","mappedInfoBuffer","mappedInfoArray","knnDistancesBuffer","resultKnnDistancesArrayBuffer","bytesPerKnnRow","resKnnDistances","dataView","out","fuzzySimplicialSetRes","eRes","maxVal","cur","minGraphVal","unionSizesCopy","offsetAccum","nonZeroGraphOffsets","nonZeroGraphSize","MultiColumnReducer","TSNEReducer","super","randomSeed","randomFn","reducer","distanceFnames","distanceFns","distanceFnArgs","progressFunc","matrixService","UMAPReducer","useWebGPU","vectors","_parallelDistanceWorkers","knnGraph","multiColumnKNN","webGPUReducer","epoc","AvailableReducers","MultiColDimReducer","metrics","distanceAggregation","measures","measure","bitArrayLength","_length","transposeMatrix","availableMetricsByType","typeName","availableMethods","availableMetrics","obj","epochNum","epochsLength","columnsData","onMessage","alea","xor128","xorwow","xorshift7","xor4096","tychei","sr","global","Alea","seed","me","mash","h","t","s0","copy","f","impl","xg","prng","int32","double","quick","XorGen","strseed","z","limit","pool","math","nodecrypto","width","startdenom","significance","overflow","mask","seedrandom","shortseed","mixkey","flatten","entropy","tostring","randomBytes","crypto","msCrypto","getRandomValues","browser","plugins","screen","autoseed","arc4","ARC4","g","S","is_math_call","keylen","count","depth","prop","typ","smear","stringseed","ex"],"sourceRoot":""}
|