@datagrok/bio 2.11.2 → 2.11.5

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/196.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"196.js","mappings":"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","sources":["webpack://bio/webpack/runtime/chunk loaded","webpack://bio/webpack/runtime/startup chunk dependencies","webpack://bio/./node_modules/@datagrok-libraries/utils/src/random.js","webpack://bio/./node_modules/@datagrok-libraries/utils/src/vector-operations.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/proxy.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/distance-matrix-service.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/spe.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/typed-metrics/consts.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-metrics-methods.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/typed-metrics/typed-metrics.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/utils.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/heap.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/matrix.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/tree.js","webpack://bio/./node_modules/is-any-array/src/index.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/errorCalculation.js","webpack://bio/./node_modules/ml-matrix/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-rescale/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-max/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-min/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-rescale/lib-es6/index.js","webpack://bio/./node_modules/ml-array-min/lib-es6/index.js","webpack://bio/./node_modules/ml-array-max/lib-es6/index.js","webpack://bio/./node_modules/ml-matrix/src/inspect.js","webpack://bio/./node_modules/ml-matrix/src/util.js","webpack://bio/./node_modules/ml-matrix/src/matrix.js","webpack://bio/./node_modules/ml-matrix/src/stat.js","webpack://bio/./node_modules/ml-matrix/src/mathOperations.js","webpack://bio/./node_modules/ml-matrix/src/wrap/WrapperMatrix2D.js","webpack://bio/./node_modules/ml-matrix/src/dc/lu.js","webpack://bio/./node_modules/ml-matrix/src/dc/util.js","webpack://bio/./node_modules/ml-matrix/src/dc/qr.js","webpack://bio/./node_modules/ml-matrix/src/dc/svd.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/step.js","webpack://bio/./node_modules/ml-matrix/src/decompositions.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/umap.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/nn_descent.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/index.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/reduce-dimensionality.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/distance-matrix.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/sparse-matrix-service.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/knnGraph.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/workers/dimensionality-reducer.js","webpack://bio/./node_modules/@keckelt/tsne/lib/index.js","webpack://bio/./node_modules/@keckelt/tsne/lib/tsne.js","webpack://bio/webpack/bootstrap","webpack://bio/webpack/runtime/define property getters","webpack://bio/webpack/runtime/ensure chunk","webpack://bio/webpack/runtime/get javascript chunk filename","webpack://bio/webpack/runtime/global","webpack://bio/webpack/runtime/hasOwnProperty shorthand","webpack://bio/webpack/runtime/publicPath","webpack://bio/webpack/runtime/importScripts chunk loading","webpack://bio/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var next = __webpack_require__.x;\n__webpack_require__.x = () => {\n\treturn Promise.all([\n\t\t__webpack_require__.e(1),\n\t\t__webpack_require__.e(172)\n\t]).then(next);\n};","/**\n * Generates single random float from 0 to range.\n *\n * @export\n * @param {number} range Max generating value.\n * @return {number} A random float generated.\n */\nexport function randomFloat(range) {\n return Math.random() * range;\n}\n/**\n * Generates single random integer from 0 to range.\n *\n * @export\n * @param {number} range Max generating value.\n * @return {number} A random integer generated.\n */\nexport function randomInt(range) {\n return Math.floor(randomFloat(range));\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZG9tLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmFuZG9tLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBYTtJQUN2QyxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFDL0IsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsS0FBYTtJQUNyQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDeEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVzIHNpbmdsZSByYW5kb20gZmxvYXQgZnJvbSAwIHRvIHJhbmdlLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSByYW5nZSBNYXggZ2VuZXJhdGluZyB2YWx1ZS5cbiAqIEByZXR1cm4ge251bWJlcn0gQSByYW5kb20gZmxvYXQgZ2VuZXJhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tRmxvYXQocmFuZ2U6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLnJhbmRvbSgpICogcmFuZ2U7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHNpbmdsZSByYW5kb20gaW50ZWdlciBmcm9tIDAgdG8gcmFuZ2UuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHJhbmdlIE1heCBnZW5lcmF0aW5nIHZhbHVlLlxuICogQHJldHVybiB7bnVtYmVyfSBBIHJhbmRvbSBpbnRlZ2VyIGdlbmVyYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbUludChyYW5nZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IocmFuZG9tRmxvYXQocmFuZ2UpKTtcbn1cbiJdfQ==","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 */\nfunction 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 const diff = vectorAdd(p, q, -1);\n const sqdiff = vectorSquare(diff);\n const sqdiffSumm = itemsSum(sqdiff);\n return Math.sqrt(sqdiffSumm);\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 * @param {Vector} data numerical array\n */\nexport function normalize(data) {\n let mean = 0;\n let std = 0;\n for (let i = 0; i < data.length; ++i)\n mean += data[i];\n mean /= data.length;\n for (let i = 0; i < data.length; ++i)\n std += (data[i] - mean) * (data[i] - mean);\n std = Math.sqrt(std / data.length);\n for (let i = 0; i < data.length; ++i)\n data[i] = (data[i] - mean) / std;\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yLW9wZXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ2ZWN0b3Itb3BlcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVMsTUFBTSxFQUF1QyxNQUFNLHFCQUFxQixDQUFDO0FBQ3pGLE9BQU8sRUFBQyxXQUFXLEVBQUUsU0FBUyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBRWhEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLFlBQXFCLEtBQUssRUFBRSxVQUFrQixrQkFBa0I7SUFDckYsSUFBSSxDQUFDLFNBQVM7UUFDWixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsZUFBZSxDQUFDLFVBQWtCLEVBQUUsVUFBa0IsRUFBRSxPQUFlLENBQUM7SUFDL0UsT0FBTyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6RixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsTUFBYztJQUM1QyxPQUFPLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1NBQ3ZDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RGLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxhQUFxQixDQUFDO0lBQ3BFLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFFeEIsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLDhCQUE4QixDQUFDLENBQUM7SUFFM0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFakMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQy9CLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV0QyxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsUUFBUSxDQUFDLENBQVM7SUFDekIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBRWQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQy9CLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFaEIsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLFlBQVksQ0FBQyxDQUFTO0lBQzdCLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDeEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFakMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQy9CLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXpCLE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELE1BQU0sVUFBVSxZQUFZLENBQUMsQ0FBUztJQUNwQyxJQUFJLE1BQU0sR0FBVyxDQUFDLENBQUM7SUFDdkIsS0FBSyxJQUFJLENBQUMsR0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFO1FBQ3ZDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMzQixDQUFDO0FBRUQsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEVBQVUsRUFBRSxFQUFVO0lBQ3JELElBQUksRUFBRSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsTUFBTTtRQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7SUFDbEUsSUFBSSxJQUFJLEdBQVcsQ0FBQyxDQUFDO0lBQ3JCLEtBQUssSUFBSSxDQUFDLEdBQVcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtRQUN4QyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4QixPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxVQUFrQixFQUFFLFVBQWtCLEVBQUUsUUFBZ0IsRUFBRTtJQUN6RixNQUFNLE1BQU0sR0FBRyxlQUFlLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRXZELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLEVBQUUsRUFBRSxDQUFDLEVBQUU7UUFDbkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsRUFBRSxFQUFFLENBQUM7WUFDakMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNyQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUFDLENBQVMsRUFBRSxDQUFTO0lBQzdELE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakMsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNwQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsSUFBYSxFQUFFLFFBQXdCO0lBQ3hFLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDM0IsTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFbEQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtRQUMvQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtZQUNuQyxNQUFNLENBQUMsR0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFGLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ2pDO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSw0QkFBNEIsQ0FBQyxJQUFhLEVBQUUsUUFBd0I7SUFDbEYsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUMzQixNQUFNLE1BQU0sR0FBRyxlQUFlLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNsRCxJQUFJLEdBQUcsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO0lBQzNCLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7SUFDM0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtRQUMvQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFO1lBQy9CLE1BQU0sQ0FBQyxHQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoQyxJQUFJLENBQUMsR0FBRyxHQUFHO2dCQUFFLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDckIsSUFBSSxDQUFDLEdBQUcsR0FBRztnQkFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1NBQ3RCO0tBQ0Y7SUFDRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFO1FBQy9CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUNqQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0tBQ3BFO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELGtGQUFrRjtBQUNsRixNQUFNLFVBQVUsUUFBUSxDQUFDLEtBQWEsRUFBRSxHQUFXLEVBQUUsWUFBWSxHQUFHLEtBQUs7SUFDdkUsTUFBTSxNQUFNLEdBQUcsR0FBRyxHQUFHLEtBQUssR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwRCxNQUFNLE1BQU0sR0FBRyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUV0QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLEVBQUUsQ0FBQztRQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUV4QixPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxPQUFPLENBQUMsTUFBYSxFQUFFLE9BQU8sR0FBRyxLQUFLO0lBQ3BELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFRLEVBQUUsQ0FBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFRLEVBQUUsQ0FBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2RyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQU0sRUFBRSxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCO0lBQ2xFLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUI7SUFDdkQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFVLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxRSxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMxQixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxNQUFjLEVBQUUsQ0FBUyxFQUFFLElBQXdDO0lBQ2xHLFNBQVMsS0FBSyxDQUFDLE1BQWdDLEVBQUUsT0FBOEI7UUFDN0UsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLElBQUksVUFBVSxHQUFHLElBQUksQ0FBQztRQUV0QixLQUFLLE1BQU0sT0FBTyxJQUFJLE1BQU0sRUFBRTtZQUM1QixNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDeEMsSUFBSSxVQUFVLElBQUksSUFBSSxJQUFJLGNBQWMsR0FBRyxVQUFVLEVBQUU7Z0JBQ3JELFFBQVEsR0FBRyxPQUFPLENBQUM7Z0JBQ25CLFVBQVUsR0FBRyxjQUFjLENBQUM7YUFDN0I7U0FDRjtRQUNELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QyxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTdCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUU7UUFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ3JCLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDckI7SUFFRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3hCLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FDZixVQUFVLENBQUMsTUFBTSxFQUE4QixFQUMvQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBUyxHQUFHLEVBQUUsS0FBSztZQUN4RCxPQUFPLElBQUksQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ1AsSUFBSSxHQUFHLEVBQUU7WUFDUCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDeEI7S0FDRjtJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLElBQVk7SUFDcEMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBRVosS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQ2xDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFbEIsSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUM7SUFFcEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQ2xDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUU3QyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRW5DLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBRW5DLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxDQUFRLEVBQUUsQ0FBUTtJQUM5QyxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4QixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0FBQ3JFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge01hdHJpeCwgVmVjdG9yLCBDb29yZGluYXRlcywgVmVjdG9ycywgRGlzdGFuY2VNZXRyaWN9IGZyb20gJy4vdHlwZS1kZWNsYXJhdGlvbnMnO1xuaW1wb3J0IHtyYW5kb21GbG9hdCwgcmFuZG9tSW50fSBmcm9tICcuL3JhbmRvbSc7XG5cbi8qKlxuICogQXNzZXJ0cyBhIGNvbmRpdGlvbiBieSB0aHJvd2luZyBhbiBFcnJvci5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtjb25kaXRpb249ZmFsc2VdIENvbmRpdGlvbiB0byBhc3NlcnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2U9J0Fzc2VydGlvbiBlcnJvci4nXSBNZXNzYWdlIHRvIG91dHB1dC5cbiAqIEB0aHJvd3Mge0Vycm9yfVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0KGNvbmRpdGlvbjogYm9vbGVhbiA9IGZhbHNlLCBtZXNzYWdlOiBzdHJpbmcgPSAnQXNzZXJ0aW9uIGVycm9yLicpIHtcbiAgaWYgKCFjb25kaXRpb24pXG4gICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgbmV3IHR3by1kaW1lbnNpb25hbCBhcnJheSBhbmQgZmlsbHMgaXQgd2l0aCB0aGUgdmFsdWUgZ2l2ZW4uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGRpbWVuc2lvbjEgVGhlIGZpcnN0IGRpbWVuc2lvbiBvZiB0aGUgY29vcmRpbmF0ZXMgKG51bWJlciBvZiByb3dzKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkaW1lbnNpb24yIFRoZSBzZWNvbmQgZGltZW5zaW9uIG9mIHRoZSBjb29yZGluYXRlcyAobnVtYmVyIG9mIGNvbHVtbnMpLlxuICogQHBhcmFtIHtudW1iZXJ9IFtmaWxsPTBdIEEgdmFsdWUgdG8gZmlsbCB0aGUgY29vcmRpbmF0ZXMgd2l0aC5cbiAqIEByZXR1cm4ge0Nvb3JkaW5hdGVzfSBBIHR3by1kaW1lbnNpb25hbCBmaWxsZWQgd2l0aCB0aGUgdmFsdWUgZ2l2ZW4uXG4gKiBAdG9kbyBNaWdodCBiZSBzbG93IHNpbmNlIHVzZWQgQXJyYXkubWFwLiBQcm9iYWJseSBuZWVkcyBwZXJmb3JtYW5jZSByZXZpc2lvbi5cbiAqL1xuZnVuY3Rpb24gaW5pdENvb3JkaW5hdGVzKGRpbWVuc2lvbjE6IG51bWJlciwgZGltZW5zaW9uMjogbnVtYmVyLCBmaWxsOiBudW1iZXIgPSAwKTogQ29vcmRpbmF0ZXMge1xuICByZXR1cm4gbmV3IEFycmF5KGRpbWVuc2lvbjEpLmZpbGwoZmlsbCkubWFwKCgpID0+IChuZXcgVmVjdG9yKGRpbWVuc2lvbjIpLmZpbGwoZmlsbCkpKTtcbn1cblxuLyoqXG4gKiBUcmFuc3Bvc2UgbWF0cml4LlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7TWF0cml4fSBtYXRyaXggVGhlIG1hdHJpeCB0byBiZSB0cmFuc3Bvc2VkLlxuICogQHJldHVybiB7TWF0cml4fSBUcmFuc3Bvc2VkIG1hdHJpeC5cbiAqIEB0b2RvIE1pZ2h0IGJlIHNsb3cgc2luY2UgdXNlZCBBcnJheS5tYXAuIFByb2JhYmx5IG5lZWRzIHBlcmZvcm1hbmNlIHJldmlzaW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNwb3NlTWF0cml4KG1hdHJpeDogTWF0cml4KTogTWF0cml4IHtcbiAgcmV0dXJuIG5ldyBBcnJheShtYXRyaXhbMF0ubGVuZ3RoKS5maWxsKDApXG4gICAgLm1hcCgoXywgaSkgPT4gKG5ldyBWZWN0b3IobWF0cml4Lmxlbmd0aCkuZmlsbCgwKS5tYXAoKF8sIGopID0+IChtYXRyaXhbal1baV0pKSkpO1xufVxuXG4vKipcbiAqIEFkZHMgdHdvIHZlY3RvcnMgd2l0aCB0aGUgc2Vjb25kIG9uZSB0byBiZSBtdWx0aXBsaWVkIGJ5IHRoZSBnaXZlbiByYXRpby5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3Rvcn0gcCBUaGUgZmlyc3QgdmVjdG9yIHRvIGFkZC5cbiAqIEBwYXJhbSB7VmVjdG9yfSBxIFRoZSBzZWNvbmQgdmVjdG9yIHRvIGFkZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbXVsdGlwbGllcj0xXSBBIG11bHRpcGxpZXIgdG8gYmUgdXNlZCBiZWZvcmUgdGhlIHNlY29uZCB2ZWN0b3IgaXMgYWRkZWQuXG4gKiBAcmV0dXJuIHtWZWN0b3J9IE5ldyB2ZWN0b3IgY29udGFpbmVkIHRoZSByZXN1bHQgb2Ygb3BlcmF0aW9uIHArbXVsdGlwbGllcipxLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVjdG9yQWRkKHA6IFZlY3RvciwgcTogVmVjdG9yLCBtdWx0aXBsaWVyOiBudW1iZXIgPSAxKTogVmVjdG9yIHtcbiAgY29uc3Qgbkl0ZW1zID0gcC5sZW5ndGg7XG5cbiAgYXNzZXJ0KG5JdGVtcyA9PSBxLmxlbmd0aCwgJ1ZlY3RvciBsZW5ndGhzIGRvIG5vdCBtYXRjaC4nKTtcblxuICBjb25zdCB0b3RhbCA9IG5ldyBWZWN0b3Iobkl0ZW1zKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHAubGVuZ3RoOyArK2kpXG4gICAgdG90YWxbaV0gPSBwW2ldICsgbXVsdGlwbGllciAqIHFbaV07XG5cbiAgcmV0dXJuIHRvdGFsO1xufVxuXG4vKipcbiAqIFN1bXMgdGhlIHZlY3RvcidzIGl0ZW1zLlxuICpcbiAqIEBwYXJhbSB7VmVjdG9yfSB2IFRoZSB2ZWN0b3IgdG8gYmUgc3VtbWVkLlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgdmVjdG9yJ3MgaXRlbXMgc3VtLlxuICovXG5mdW5jdGlvbiBpdGVtc1N1bSh2OiBWZWN0b3IpOiBudW1iZXIge1xuICBsZXQgdG90YWwgPSAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdi5sZW5ndGg7ICsraSlcbiAgICB0b3RhbCArPSB2W2ldO1xuXG4gIHJldHVybiB0b3RhbDtcbn1cblxuLyoqXG4gKiBTdXFhcmVzIHRoZSB2ZWN0b3IncyBpdGVtcy5cbiAqXG4gKiBAcGFyYW0ge1ZlY3Rvcn0gdiBUaGUgdmVjdG9yIHRvIHNxdWFyZS5cbiAqIEByZXR1cm4ge1ZlY3Rvcn0gQSBuZXcgdmVjdG9yIGNvbnRhaW5pbmcgdGhlIG9yaWdpbmFsJ3MgaXRlbXMgc3F1YXJlZC5cbiAqL1xuZnVuY3Rpb24gdmVjdG9yU3F1YXJlKHY6IFZlY3Rvcik6IFZlY3RvciB7XG4gIGNvbnN0IG5JdGVtcyA9IHYubGVuZ3RoO1xuICBjb25zdCB0b3RhbCA9IG5ldyBWZWN0b3Iobkl0ZW1zKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHYubGVuZ3RoOyArK2kpXG4gICAgdG90YWxbaV0gPSB2W2ldICogdltpXTtcblxuICByZXR1cm4gdG90YWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2ZWN0b3JMZW5ndGgodjogVmVjdG9yKTogbnVtYmVyIHtcbiAgbGV0IHNxclN1bTogbnVtYmVyID0gMDtcbiAgZm9yIChsZXQgaTogbnVtYmVyID0gMDsgaSA8IHYubGVuZ3RoOyBpKyspXG4gICAgc3FyU3VtICs9IHZbaV0gKiB2W2ldO1xuICByZXR1cm4gTWF0aC5zcXJ0KHNxclN1bSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2ZWN0b3JEb3RQcm9kdWN0KHYxOiBWZWN0b3IsIHYyOiBWZWN0b3IpOiBudW1iZXIge1xuICBpZiAodjEubGVuZ3RoICE9IHYyLmxlbmd0aClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBkaW1lbnNpb25hbGl0eSBvZiB0aGUgdmVjdG9ycyBtdXN0IG1hdGNoJyk7XG4gIGxldCBwcm9kOiBudW1iZXIgPSAwO1xuICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgdjEubGVuZ3RoOyBpKyspXG4gICAgcHJvZCArPSB2MVtpXSAqIHYyW2ldO1xuICByZXR1cm4gcHJvZDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZpbGxlZCB3aXRoIHJhbmRvbSBmbG9hdGluZyBwb2ludCB2YWx1ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IGRpbWVuc2lvbjEgVGhlIGZpcnN0IGRpbWVuc2lvbiBvZiB0aGUgbWF0cml4LlxuICogQHBhcmFtIHtudW1iZXJ9IGRpbWVuc2lvbjIgVGhlIHNlY29uZCBkaW1lbnNpb24gb2YgdGhlIG1hdHJpeC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2NhbGU9MS5dIE1heCB2YWx1ZSBnaXZlbiBieSByYW5kb20gZ2VuZXJhdG9yLlxuICogQHJldHVybiB7TWF0cml4fSBBIG5ldyBtYXRyaXggZmlsbGVkIHdpdGggcmFuZG9tIGZsb2F0aW5nIHBvaW50ICB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWxsUmFuZG9tTWF0cml4KGRpbWVuc2lvbjE6IG51bWJlciwgZGltZW5zaW9uMjogbnVtYmVyLCBzY2FsZTogbnVtYmVyID0gMS4pOiBNYXRyaXgge1xuICBjb25zdCBtYXRyaXggPSBpbml0Q29vcmRpbmF0ZXMoZGltZW5zaW9uMSwgZGltZW5zaW9uMik7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1lbnNpb24xOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGRpbWVuc2lvbjI7ICsrailcbiAgICAgIG1hdHJpeFtpXVtqXSA9IHJhbmRvbUZsb2F0KHNjYWxlKTtcbiAgfVxuICByZXR1cm4gbWF0cml4O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgRXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3J9IHAgVGhlIGZpcnN0IHZlY3Rvci5cbiAqIEBwYXJhbSB7VmVjdG9yfSBxIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBFdWNsaWRlYW4gZGlzdGFuY2UgYmV0d2VlbiB0aGUgZ2l2ZW4gdmVjdG9ycy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlKHA6IFZlY3RvciwgcTogVmVjdG9yKTogbnVtYmVyIHtcbiAgY29uc3QgZGlmZiA9IHZlY3RvckFkZChwLCBxLCAtMSk7XG4gIGNvbnN0IHNxZGlmZiA9IHZlY3RvclNxdWFyZShkaWZmKTtcbiAgY29uc3Qgc3FkaWZmU3VtbSA9IGl0ZW1zU3VtKHNxZGlmZik7XG4gIHJldHVybiBNYXRoLnNxcnQoc3FkaWZmU3VtbSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRpc3RhbmNlIG1hdHJpeCB1c2luZyBhIGN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3RvcnN9IGRhdGEgSW5wdXQgdmVjdG9ycyB0byBjYWxjdWxhdGUgZGlzdGFuY2VzLlxuICogQHBhcmFtIHtEaXN0YW5jZU1ldHJpY30gZGlzdGFuY2UgQ3VzdG9tIGRpc3RhbmNlIGZ1bmN0aW9uLlxuICogQHJldHVybiB7TWF0cml4fSBDYWxjdWxhdGVkIGN1c3RvbSBkaXN0YW5jZSBtYXRyaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjRGlzdGFuY2VNYXRyaXgoZGF0YTogVmVjdG9ycywgZGlzdGFuY2U6IERpc3RhbmNlTWV0cmljKTogTWF0cml4IHtcbiAgY29uc3Qgbkl0ZW1zID0gZGF0YS5sZW5ndGg7XG4gIGNvbnN0IG1hdHJpeCA9IGluaXRDb29yZGluYXRlcyhuSXRlbXMsIG5JdGVtcywgMCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuSXRlbXM7ICsraSkge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IG5JdGVtczsgKytqKSB7XG4gICAgICBjb25zdCBkOiBudW1iZXIgPSAoZGF0YVtpXSA9PSBudWxsKSB8fCAoZGF0YVtqXSA9PSBudWxsKSA/IDAgOiBkaXN0YW5jZShkYXRhW2ldLCBkYXRhW2pdKTtcbiAgICAgIG1hdHJpeFtpXVtqXSA9IG1hdHJpeFtqXVtpXSA9IGQ7XG4gICAgfVxuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRpc3RhbmNlIG1hdHJpeCB1c2luZyBhIGN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3RvcnN9IGRhdGEgSW5wdXQgdmVjdG9ycyB0byBjYWxjdWxhdGUgZGlzdGFuY2VzLlxuICogQHBhcmFtIHtEaXN0YW5jZU1ldHJpY30gZGlzdGFuY2UgQ3VzdG9tIGRpc3RhbmNlIGZ1bmN0aW9uLlxuICogQHJldHVybiB7TWF0cml4fSBDYWxjdWxhdGVkIGN1c3RvbSBkaXN0YW5jZSBtYXRyaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjTm9ybWFsaXplZERpc3RhbmNlTWF0cml4KGRhdGE6IFZlY3RvcnMsIGRpc3RhbmNlOiBEaXN0YW5jZU1ldHJpYyk6IE1hdHJpeCB7XG4gIGNvbnN0IG5JdGVtcyA9IGRhdGEubGVuZ3RoO1xuICBjb25zdCBtYXRyaXggPSBpbml0Q29vcmRpbmF0ZXMobkl0ZW1zLCBuSXRlbXMsIDApO1xuICBsZXQgbWF4ID0gTnVtYmVyLk1JTl9WQUxVRTtcbiAgbGV0IG1pbiA9IE51bWJlci5NQVhfVkFMVUU7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gaTsgaiA8IG5JdGVtczsgKytqKSB7XG4gICAgICBjb25zdCBkOiBudW1iZXIgPSAoZGF0YVtpXSA9PSBudWxsKSB8fCAoZGF0YVtqXSA9PSBudWxsIHx8IGkgPT09IGopID8gMCA6IGRpc3RhbmNlKGRhdGFbaV0sIGRhdGFbal0pO1xuICAgICAgbWF0cml4W2ldW2pdID0gbWF0cml4W2pdW2ldID0gZDtcbiAgICAgIGlmIChkID4gbWF4KSBtYXggPSBkO1xuICAgICAgaWYgKGQgPCBtaW4pIG1pbiA9IGQ7XG4gICAgfVxuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBuSXRlbXM7ICsrailcbiAgICAgIG1hdHJpeFtpXVtqXSA9IG1hdHJpeFtqXVtpXSA9IChtYXRyaXhbaV1bal0gLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gIH1cbiAgcmV0dXJuIG1hdHJpeDtcbn1cblxuLyoqIEdlbmVyYXRlcyBhcnJheSBmcm9tIGEgcmFuZ2UgW2JlZ2luOyBlbmRdIG9yIFtiZWdpbjsgZW5kKSBpZiBlbmRFeGNsdXNpdmUuICoqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlblJhbmdlKGJlZ2luOiBudW1iZXIsIGVuZDogbnVtYmVyLCBlbmRFeGNsdXNpdmUgPSBmYWxzZSk6IEludDMyQXJyYXkge1xuICBjb25zdCBuSXRlbXMgPSBlbmQgLSBiZWdpbiArIChlbmRFeGNsdXNpdmUgPyAwIDogMSk7XG4gIGNvbnN0IHNlcmllcyA9IG5ldyBJbnQzMkFycmF5KG5JdGVtcyk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuSXRlbXM7ICsraSlcbiAgICBzZXJpZXNbaV0gPSBiZWdpbiArIGk7XG5cbiAgcmV0dXJuIHNlcmllcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIG9yZGVyIG9mIHZhbHVlcyBhcyBpZiB0aGV5IGFyZSBzb3J0ZWQuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHthbnlbXX0gdmFsdWVzIElucHV0IGFycmF5LlxuICogQHBhcmFtIHtib29sZWFufSBbcmV2ZXJzZT1mYWxzZV0gV2hldGhlciB0byByZXR1cm4gcmV2ZXJzZWQgb3JkZXIuXG4gKiBAcmV0dXJuIHtudW1iZXJbXX0gVGhlIG9yZGVyIGNvbXB1dGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXJnU29ydCh2YWx1ZXM6IGFueVtdLCByZXZlcnNlID0gZmFsc2UpOiBudW1iZXJbXSB7XG4gIGNvbnN0IHNvcnRmbiA9IHJldmVyc2UgPyAoYTogYW55W10sIGI6IGFueVtdKSA9PiAoYlswXSAtIGFbMF0pIDogKGE6IGFueVtdLCBiOiBhbnlbXSkgPT4gKGFbMF0gLSBiWzBdKTtcbiAgY29uc3QgZGVjb3IgPSAodjogYW55LCBpOiBudW1iZXIpID0+IFt2LCBpXTsgLy8gc2V0IGluZGV4IHRvIHZhbHVlXG4gIGNvbnN0IHVuZGVjb3IgPSAoYTogYW55W10pID0+IGFbMV07IC8vIGxlYXZlIG9ubHkgaW5kZXhcbiAgY29uc3QgX2FyZ3NvcnQgPSAoYXJyOiBhbnlbXSkgPT4gYXJyLm1hcChkZWNvcikuc29ydChzb3J0Zm4pLm1hcCh1bmRlY29yKTtcbiAgcmV0dXJuIF9hcmdzb3J0KHZhbHVlcyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgaW5kZXhlcyBvZiB0aGUgbW9zdCBkaXZlcnNlIG9iamVjdHMgYWNjb3JkaW5nIHRvIHRoZSBkaXN0IGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIHRvdGFsIG51bWJlciBvZiBvYmplY3RzXG4gKiBAcGFyYW0ge251bWJlcn0gbiBudW1iZXIgb2YgZGl2ZXJzZSBlbGVtZW50cyB0byBmaW5kXG4gKiBAcGFyYW0geyhpMTogbnVtYmVyLCBpMjogbnVtYmVyKSA9PiBudW1iZXJ9IGRpc3QgYSBmdW5jdGlvbiB3aGljaCBjYWxjdWxhdGVzIGRpc3RhbmNlIGJldHdlZW5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0d28gb2JqZWN0cyB1c2luZyB0aGVpciBpbmRleGVzXG4gKiBAcmV0dXJucyB7bnVtYmVyW119IFRoZSBpbmRleGVzIG9mIHRoZSBtb3N0IGRpdmVyc2Ugb2JqZWN0c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGl2ZXJzZVN1YnNldChsZW5ndGg6IG51bWJlciwgbjogbnVtYmVyLCBkaXN0OiAoaTE6IG51bWJlciwgaTI6IG51bWJlcikgPT4gbnVtYmVyKTogbnVtYmVyW10ge1xuICBmdW5jdGlvbiBtYXhCeSh2YWx1ZXM6IEl0ZXJhYmxlSXRlcmF0b3I8bnVtYmVyPiwgb3JkZXJCeTogKGk6IG51bWJlcikgPT4gbnVtYmVyKSB7XG4gICAgbGV0IG1heFZhbHVlID0gbnVsbDtcbiAgICBsZXQgbWF4T3JkZXJCeSA9IG51bGw7XG5cbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdmFsdWVzKSB7XG4gICAgICBjb25zdCBlbGVtZW50T3JkZXJCeSA9IG9yZGVyQnkoZWxlbWVudCk7XG4gICAgICBpZiAobWF4T3JkZXJCeSA9PSBudWxsIHx8IGVsZW1lbnRPcmRlckJ5ID4gbWF4T3JkZXJCeSkge1xuICAgICAgICBtYXhWYWx1ZSA9IGVsZW1lbnQ7XG4gICAgICAgIG1heE9yZGVyQnkgPSBlbGVtZW50T3JkZXJCeTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1heFZhbHVlO1xuICB9XG5cbiAgY29uc3Qgc3Vic2V0ID0gW3JhbmRvbUludChsZW5ndGggLSAxKV07XG4gIGNvbnN0IGNvbXBsZW1lbnQgPSBuZXcgU2V0KCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICghc3Vic2V0LmluY2x1ZGVzKGkpKVxuICAgICAgY29tcGxlbWVudC5hZGQoaSk7XG4gIH1cblxuICB3aGlsZSAoc3Vic2V0Lmxlbmd0aCA8IG4pIHtcbiAgICBjb25zdCBpZHggPSBtYXhCeShcbiAgICAgIGNvbXBsZW1lbnQudmFsdWVzKCkgYXMgSXRlcmFibGVJdGVyYXRvcjxudW1iZXI+LFxuICAgICAgKGkpID0+IE1hdGgubWluLmFwcGx5KE1hdGgsIHN1YnNldC5tYXAoZnVuY3Rpb24odmFsLCBpbmRleCkge1xuICAgICAgICByZXR1cm4gZGlzdChpLCB2YWwpO1xuICAgICAgfSkpKTtcbiAgICBpZiAoaWR4KSB7XG4gICAgICBzdWJzZXQucHVzaChpZHgpO1xuICAgICAgY29tcGxlbWVudC5kZWxldGUoaWR4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN1YnNldDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIG5vcm1hbGl6ZWQgdmVjdG9yXG4gKiBAcGFyYW0ge1ZlY3Rvcn0gZGF0YSBudW1lcmljYWwgYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShkYXRhOiBWZWN0b3IpOiBWZWN0b3Ige1xuICBsZXQgbWVhbiA9IDA7XG4gIGxldCBzdGQgPSAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSlcbiAgICBtZWFuICs9IGRhdGFbaV07XG5cbiAgbWVhbiAvPSBkYXRhLmxlbmd0aDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpXG4gICAgc3RkICs9IChkYXRhW2ldIC0gbWVhbikgKiAoZGF0YVtpXSAtIG1lYW4pO1xuXG4gIHN0ZCA9IE1hdGguc3FydChzdGQgLyBkYXRhLmxlbmd0aCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgKytpKVxuICAgIGRhdGFbaV0gPSAoZGF0YVtpXSAtIG1lYW4pIC8gc3RkO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG4vKipcbiAqIEZpbmRzIHNldCBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIGxpc3RzLlxuICogQHBhcmFtIHthbnlbXX0gYSBUaGUgZmlyc3QgbGlzdC5cbiAqIEBwYXJhbSB7YW55W119IGIgVGhlIHNlY29uZCBsaXN0LlxuICogQHJldHVybiB7YW55W119XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXREaWZmZXJlbmNlKGE6IGFueVtdLCBiOiBhbnlbXSk6IGFueVtdIHtcbiAgY29uc3QgYlNldCA9IG5ldyBTZXQoYik7XG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoYS5maWx0ZXIoKHgpID0+ICFiU2V0Lmhhcyh4KSkpLnZhbHVlcygpKTtcbn1cbiJdfQ==","/** 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=","export 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 new Promise(async (resolve, reject) => {\n try {\n const len = values.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, fnName, startRow, startCol, chunckSize: end - start, opts });\n promises[i] = new Promise((resolveWorker, rejectWorker) => {\n this._workers[i].onmessage = ({ data: { error, distanceMatrixData, min, max } }) => {\n this._terminateOnComplete && 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWF0cml4LXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkaXN0YW5jZS1tYXRyaXgtc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLE9BQU8scUJBQXFCO0lBSTlCLFlBQW1CLG9CQUFvQixHQUFHLElBQUksRUFBRSxtQkFBbUIsR0FBRyxJQUFJO1FBQ3hFLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQztRQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ3BELEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQywwQkFBMEIsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsbUJBQW1CLENBQUM7SUFDbEQsQ0FBQztJQUFBLENBQUM7SUFFSyxLQUFLLENBQUMsSUFBSSxDQUFJLE1BQStCLEVBQUUsTUFBb0IsRUFDeEUsU0FBUyxHQUFHLElBQUksRUFBRSxJQUF5QjtRQUMzQyxPQUFPLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDM0MsSUFBSTtnQkFDRixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO2dCQUMxQixNQUFNLFFBQVEsR0FBRyxJQUFJLEtBQUssQ0FBZ0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUM3RCxNQUFNLFdBQVcs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Q2IsSUFBSSxHQUFHLEdBQUcsSUFBSTtvQ0FDWixJQUFJLEdBQUcsR0FBRyxDQUFDO2dDQUNiLGFBQWEsRUFBRSxDQUFDOzZCQUNqQjt3QkFDSCxDQUFDLENBQUM7b0JBQ0osQ0FBQyxDQUFDLENBQUM7aUJBQ0o7Z0JBQ0QsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM1QixJQUFJLFNBQVM7b0JBQ1gsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4RyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7YUFDekI7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDWDtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFNBQVM7UUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtLbm93bk1ldHJpY3N9IGZyb20gJy4uL3R5cGVkLW1ldHJpY3MnO1xuXG5leHBvcnQgY2xhc3MgRGlzdGFuY2VNYXRyaXhTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF93b3JrZXJzOiBXb3JrZXJbXTtcbiAgICBwcml2YXRlIF93b3JrZXJDb3VudDogbnVtYmVyO1xuICAgIHByaXZhdGUgX3Rlcm1pbmF0ZU9uQ29tcGxldGU6IGJvb2xlYW47XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHVzZUNvbmN1cnJlbnRXb3JrZXJzID0gdHJ1ZSwgdGVybWluYXRlT25Db21wbGV0ZSA9IHRydWUpIHtcbiAgICAgIGNvbnN0IHRocmVhZENvdW50ID0gbmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3k7XG4gICAgICB0aGlzLl93b3JrZXJDb3VudCA9IHVzZUNvbmN1cnJlbnRXb3JrZXJzID8gTWF0aC5tYXgodGhyZWFkQ291bnQgLSAyLCAxKSA6IDE7XG4gICAgICB0aGlzLl93b3JrZXJzID0gbmV3IEFycmF5KHRoaXMuX3dvcmtlckNvdW50KS5maWxsKG51bGwpXG4gICAgICAgIC5tYXAoKCkgPT4gbmV3IFdvcmtlcihuZXcgVVJMKCcuL2Rpc3RhbmNlLW1hdHJpeC13b3JrZXInLCBpbXBvcnQubWV0YS51cmwpKSk7XG4gICAgICB0aGlzLl90ZXJtaW5hdGVPbkNvbXBsZXRlID0gdGVybWluYXRlT25Db21wbGV0ZTtcbiAgICB9O1xuXG4gICAgcHVibGljIGFzeW5jIGNhbGM8VD4odmFsdWVzOiBBcnJheTxUPiB8IEFycmF5TGlrZTxUPiwgZm5OYW1lOiBLbm93bk1ldHJpY3MsXG4gICAgICBub3JtYWxpemUgPSB0cnVlLCBvcHRzPzoge1tfOiBzdHJpbmddOiBhbnl9KTogUHJvbWlzZTxGbG9hdDMyQXJyYXk+IHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgbGVuID0gdmFsdWVzLmxlbmd0aDtcbiAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHZvaWQ+Pih0aGlzLl93b3JrZXJDb3VudCk7XG4gICAgICAgICAgY29uc3QgdG90YWxMZW5ndGggPSBsZW4gKiAobGVuIC0gMSkgLyAyOyAvLyBzaXplIG9mIHJlZHVjZWQgZGlzdGFuY2UgbWF0cml4XG4gICAgICAgICAgdGhpcy5fd29ya2VyQ291bnQgPSBNYXRoLm1pbih0aGlzLl93b3JrZXJDb3VudCwgdG90YWxMZW5ndGgpO1xuICAgICAgICAgIGNvbnN0IGNodW5rU2l6ZSA9IHRvdGFsTGVuZ3RoIC8gdGhpcy5fd29ya2VyQ291bnQ7XG4gICAgICAgICAgY29uc3QgZGlzdGFuY2VNYXRyaXggPSBuZXcgRmxvYXQzMkFycmF5KHRvdGFsTGVuZ3RoKTtcbiAgICAgICAgICBsZXQgZW5kUm93ID0gMDtcbiAgICAgICAgICBsZXQgZW5kQ29sID0gMTtcbiAgICAgICAgICAvLyBtaW5tYXggZm9yIG5vcm1hbGl6YXRpb25cbiAgICAgICAgICBsZXQgbG1pbiA9IDA7XG4gICAgICAgICAgbGV0IGxtYXggPSBOdW1iZXIuTUlOX1ZBTFVFO1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fd29ya2VyQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSBNYXRoLmZsb29yKGkgKiBjaHVua1NpemUpO1xuICAgICAgICAgICAgY29uc3QgZW5kID0gKGkgPT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSkgPyB0b3RhbExlbmd0aCA6IE1hdGguZmxvb3IoKGkgKyAxKSAqIGNodW5rU2l6ZSk7XG4gICAgICAgICAgICBjb25zdCBzdGFydFJvdyA9IGVuZFJvdztcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0Q29sID0gZW5kQ29sO1xuICAgICAgICAgICAgaWYgKGkgIT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSkge1xuICAgICAgICAgICAgICAvLyBUaGVzZSBmb3JtdWxhcyBtYXAgdGhlIGxpbmVhciBpbmRleCB0byB0aGUgdXBwZXIgdHJpYW5ndWxhciBtYXRyaXggaW5kaWNlc1xuICAgICAgICAgICAgICBlbmRSb3cgPSBsZW4gLSAyIC0gTWF0aC5mbG9vcihNYXRoLnNxcnQoLTggKiBlbmQgKyA0ICogbGVuICogKGxlbiAtIDEpIC0gNykgLyAyIC0gMC41KTtcbiAgICAgICAgICAgICAgZW5kQ29sID0gZW5kIC0gbGVuICogZW5kUm93ICsgTWF0aC5mbG9vcigoZW5kUm93ICsgMSkgKiAoZW5kUm93ICsgMikgLyAyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3dvcmtlcnNbaV0ucG9zdE1lc3NhZ2Uoe3ZhbHVlcywgZm5OYW1lLCBzdGFydFJvdywgc3RhcnRDb2wsIGNodW5ja1NpemU6IGVuZCAtIHN0YXJ0LCBvcHRzfSk7XG4gICAgICAgICAgICBwcm9taXNlc1tpXSA9IG5ldyBQcm9taXNlKChyZXNvbHZlV29ya2VyLCByZWplY3RXb3JrZXIpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5fd29ya2Vyc1tpXS5vbm1lc3NhZ2UgPSAoe2RhdGE6IHtlcnJvciwgZGlzdGFuY2VNYXRyaXhEYXRhLCBtaW4sIG1heH19KTogdm9pZCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGVybWluYXRlT25Db21wbGV0ZSAmJiB0aGlzLl93b3JrZXJzW2ldLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgcmVqZWN0V29ya2VyKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgZGlzdGFuY2VNYXRyaXguc2V0KGRpc3RhbmNlTWF0cml4RGF0YSwgc3RhcnQpO1xuICAgICAgICAgICAgICAgICAgaWYgKG1pbiA8IGxtaW4pXG4gICAgICAgICAgICAgICAgICAgIGxtaW4gPSBtaW47XG4gICAgICAgICAgICAgICAgICBpZiAobWF4ID4gbG1heClcbiAgICAgICAgICAgICAgICAgICAgbG1heCA9IG1heDtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmVXb3JrZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgICAgIGlmIChub3JtYWxpemUpXG4gICAgICAgICAgICBkaXN0YW5jZU1hdHJpeC5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHsgZGlzdGFuY2VNYXRyaXhbaW5kZXhdID0gKHZhbHVlIC0gbG1pbikgLyAobG1heCAtIGxtaW4pOyB9KTtcbiAgICAgICAgICByZXNvbHZlKGRpc3RhbmNlTWF0cml4KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHRlcm1pbmF0ZSgpOiB2b2lkIHtcbiAgICAgIHRoaXMuX3dvcmtlcnMuZm9yRWFjaCgod29ya2VyKSA9PiB3b3JrZXIudGVybWluYXRlKCkpO1xuICAgIH1cbn1cbiJdfQ==","import { calculateEuclideanDistance, fillRandomMatrix, vectorAdd, } from '@datagrok-libraries/utils/src/vector-operations';\nimport { randomInt } from '@datagrok-libraries/utils/src/random';\nimport { DistanceMatrixService, dmLinearIndex } from './distance-matrix';\n/**\n * Implements stochastic proximity embedding.\n *\n * @export\n * @class SPEBase\n * @link doi:10.1016/S1093-3263(03)00155-4\n */\nclass SPEBase {\n /**\n * Creates an instance of SPEBase.\n * @param {Options} [options] Options to pass to the constructor.\n * @memberof SPEBase\n */\n constructor(options) {\n this.steps = options?.steps ?? 0;\n this.cycles = options?.cycles ?? 1e6;\n // Select a cutoff distance {cutoff} and ...\n this.cutoff = options?.cutoff ?? 0;\n // ... an initial learning rate {lambda} > 0\n this.lambda = options?.lambda ?? 2.0;\n this.dlambda = options?.dlambda ?? 0.01;\n this.lambda2 = this.lambda / 2.;\n this.dlambda2 = this.dlambda / 2.;\n this.epsilon = options?.epsilon ?? 1e-10;\n // eslint-disable-next-line brace-style\n this.distanceFunction = options?.distance ?? calculateEuclideanDistance;\n this.distance = new Float32Array();\n this.distanceFunctionName = options?.distanceFunctionName;\n }\n /**\n * Initializes distance matrix.\n *\n * @param {Vectors} vectors Input vectors to calculate distance between.\n * @memberof SPEBase\n */\n async initDistance(vectors) {\n this.dmIndexFunct = dmLinearIndex(vectors.length);\n const matrixService = new DistanceMatrixService(true, false);\n this.distance = await matrixService.calc(vectors, this.distanceFunctionName);\n matrixService.terminate();\n }\n /**\n * Calculates distance between the two vectors given.\n *\n * @param {Vectors} vectors Set of vectors to calculate distances between.\n * @param {number} index1 Index of the first vector of the pair.\n * @param {number} index2 Index of the second vector of the pair.\n * @return {number} Distance between these two vectors.\n */\n calcDistance(vectors, index1, index2) {\n return this.distance[this.dmIndexFunct(index1, index2)];\n }\n /**\n * Embeds the vectors given into a two-dimensional space.\n *\n * @param {Vectors} vectors D-dimensional coordinates.\n * @return {Coordinates} SPE coordinates in D space.\n */\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, SPEBase.dimension, areaWidth);\n let lambda2 = this.lambda2;\n if (this.steps === 0)\n this.steps = vectors.length - 1;\n await this.initDistance(vectors);\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n for (let step = 0; step < this.steps; ++step) {\n // Select two points, i and j, at random, ...\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const rowi = coordinates[i];\n const rowj = coordinates[j];\n // ... retrieve (or evaluate) their proximity in the input space, rij and ...\n const r = this.calcDistance(vectors, i, j);\n // ... compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n // If rij <= rc, or if rij > rc and dij < rij ...\n if ((this.cutoff == 0) || (r <= this.cutoff) || (d < r)) {\n const multiplier = lambda2 * (r - d) / (d + this.epsilon);\n // ... update the coordinates xi and xj.\n const diffIJ = vectorAdd(rowi, rowj, -1);\n coordinates[i] = vectorAdd(rowi, diffIJ, multiplier);\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n // Decrease the learning rate {lambda} by a prescribed {dlambda}.\n lambda2 -= this.dlambda2;\n if (lambda2 <= 0.)\n break;\n }\n return coordinates;\n }\n}\nSPEBase.dimension = 2;\nexport { SPEBase };\n/**\n * Implements modified stochastic proximity embedding.\n *\n * @export\n * @class PSPEBase\n * @link doi:10.1016/S1093-3263(03)00155-4\n */\nexport class PSPEBase extends SPEBase {\n /**\n * Embeds the vectors given into a two-dimensional space using a modified update rule.\n *\n * @param {Vectors} vectors D-dimensional coordinates.\n * @return {Coordinates} SPE coordinates in D space.\n */\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, PSPEBase.dimension, areaWidth);\n let lambda = this.lambda;\n await this.initDistance(vectors);\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n // Select a point, i, at random (pivot).\n const i = randomInt(nItems);\n const rowi = coordinates[i];\n // For every point j != i ...\n for (let j = 0; j < nItems; ++j) {\n if (i == j)\n continue;\n const rowj = coordinates[j];\n // ... retrieve (or evaluate) its proximity to i in the input space, rij ...\n const r = this.calcDistance(vectors, i, j);\n // ... and compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n // If rij <= rc, or if rij > rc and dij < rij ...\n if ((this.cutoff == 0) || (r <= this.cutoff) || (d < r)) {\n const multiplier = lambda * (r - d) / (d + this.epsilon);\n const diffIJ = vectorAdd(rowi, rowj, -1);\n // ... update the coordinates xj.\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n // Decrease the learning rate {lambda} by a prescribed {dlambda}.\n lambda -= this.dlambda;\n if (lambda <= 0.)\n break;\n }\n return coordinates;\n }\n}\n/**\n * Implements modified stochastic proximity embedding.\n *\n * @export\n * @class OriginalSPE\n * @link doi:10.1002/jcc.10234\n */\nexport class OriginalSPE extends SPEBase {\n constructor(options) {\n super(options);\n this.cycles = options?.cycles ?? 1e3;\n this.steps = options?.steps ?? 100000;\n this.radiusPercent = options?.radiusPercent ?? 1.0;\n this.maxDistance = options?.maxDistance ?? null;\n this.maxDistanceSteps = options?.maxDistanceSteps ?? null;\n }\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, OriginalSPE.dimension, areaWidth);\n await this.initDistance(vectors);\n if (this.maxDistanceSteps === null)\n this.maxDistanceSteps = nItems * Math.floor((nItems - 1) / 2);\n if (this.maxDistance === null) {\n this.maxDistance = -1e37;\n for (let n = 0; n < this.maxDistanceSteps; n++) {\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const d = this.calcDistance(vectors, i, j);\n if (d > this.maxDistance)\n this.maxDistance = d;\n }\n }\n let lambda = this.lambda;\n const radius = (this.radiusPercent == 0.0) ? this.maxDistance : this.maxDistance * this.radiusPercent;\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n for (let step = 0; step < this.steps; ++step) {\n // Select two points, i and j, at random, ...\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const rowi = coordinates[i];\n const rowj = coordinates[j];\n // retrieve (or evaluate) their proximity in the input space, rij and ...\n const r = this.calcDistance(vectors, i, j);\n // compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n if ((r <= radius) || (d < r)) {\n const multiplier = lambda * 0.5 * (r - d) / (d + this.epsilon);\n // ... update the coordinates xi and xj.\n const diffIJ = vectorAdd(rowi, rowj, -1);\n coordinates[i] = vectorAdd(rowi, diffIJ, multiplier);\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n lambda -= ((this.lambda - this.dlambda) / (this.cycles - 1.0));\n ;\n if (lambda < this.dlambda)\n break;\n }\n return coordinates;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3BlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsZ0JBQWdCLEVBQ2hCLFNBQVMsR0FDVixNQUFNLGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUUvRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsYUFBYSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFFdkU7Ozs7OztHQU1HO0FBQ0gsTUFBYSxPQUFPO0lBZWxCOzs7O09BSUc7SUFDSCxZQUFZLE9BQWlCO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLEdBQUcsQ0FBQztRQUNyQyw0Q0FBNEM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUNuQyw0Q0FBNEM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLEdBQUcsQ0FBQztRQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksSUFBSSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksS0FBSyxDQUFDO1FBQ3pDLHVDQUF1QztRQUN2QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSwwQkFBMEIsQ0FBQztRQUN4RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksWUFBWSxF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IFZlY3RvcnMsIERpc3RhbmNlTWV0cmljfSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZSxcbiAgZmlsbFJhbmRvbU1hdHJpeCxcbiAgdmVjdG9yQWRkLFxufSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy92ZWN0b3Itb3BlcmF0aW9ucyc7XG5pbXBvcnQge3JhbmRvbUludH0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvcmFuZG9tJztcbmltcG9ydCB7S25vd25NZXRyaWNzfSBmcm9tICcuL3R5cGVkLW1ldHJpY3MnO1xuaW1wb3J0IHtEaXN0YW5jZU1hdHJpeFNlcnZpY2UsIGRtTGluZWFySW5kZXh9IGZyb20gJy4vZGlzdGFuY2UtbWF0cml4JztcblxuLyoqXG4gKiBJbXBsZW1lbnRzIHN0b2NoYXN0aWMgcHJveGltaXR5IGVtYmVkZGluZy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgU1BFQmFzZVxuICogQGxpbmsgZG9pOjEwLjEwMTYvUzEwOTMtMzI2MygwMykwMDE1NS00XG4gKi9cbmV4cG9ydCBjbGFzcyBTUEVCYXNlIHtcbiAgcHJvdGVjdGVkIHN0YXRpYyBkaW1lbnNpb24gPSAyO1xuICBwcm90ZWN0ZWQgc3RlcHM6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGN5Y2xlczogbnVtYmVyO1xuICBwcm90ZWN0ZWQgY3V0b2ZmOiBudW1iZXI7XG4gIHByb3RlY3RlZCBsYW1iZGE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGRsYW1iZGE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGxhbWJkYTI6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGRsYW1iZGEyOiBudW1iZXI7XG4gIHByb3RlY3RlZCBlcHNpbG9uOiBudW1iZXI7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZ1bmN0aW9uOiBEaXN0YW5jZU1ldHJpYztcbiAgcHJvdGVjdGVkIGRpc3RhbmNlRnVuY3Rpb25OYW1lOiBLbm93bk1ldHJpY3M7XG4gIGRpc3RhbmNlOiBGbG9hdDMyQXJyYXk7XG4gIHByb3RlY3RlZCBkbUluZGV4RnVuY3Q/OiAoaTogbnVtYmVyLCBqOiBudW1iZXIpID0+IG51bWJlcjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBTUEVCYXNlLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IFtvcHRpb25zXSBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgKiBAbWVtYmVyb2YgU1BFQmFzZVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE9wdGlvbnMpIHtcbiAgICB0aGlzLnN0ZXBzID0gb3B0aW9ucz8uc3RlcHMgPz8gMDtcbiAgICB0aGlzLmN5Y2xlcyA9IG9wdGlvbnM/LmN5Y2xlcyA/PyAxZTY7XG4gICAgLy8gU2VsZWN0IGEgY3V0b2ZmIGRpc3RhbmNlIHtjdXRvZmZ9IGFuZCAuLi5cbiAgICB0aGlzLmN1dG9mZiA9IG9wdGlvbnM/LmN1dG9mZiA/PyAwO1xuICAgIC8vIC4uLiBhbiBpbml0aWFsIGxlYXJuaW5nIHJhdGUge2xhbWJkYX0gPiAwXG4gICAgdGhpcy5sYW1iZGEgPSBvcHRpb25zPy5sYW1iZGEgPz8gMi4wO1xuICAgIHRoaXMuZGxhbWJkYSA9IG9wdGlvbnM/LmRsYW1iZGEgPz8gMC4wMTtcbiAgICB0aGlzLmxhbWJkYTIgPSB0aGlzLmxhbWJkYSAvIDIuO1xuICAgIHRoaXMuZGxhbWJkYTIgPSB0aGlzLmRsYW1iZGEgLyAyLjtcbiAgICB0aGlzLmVwc2lsb24gPSBvcHRpb25zPy5lcHNpbG9uID8/IDFlLTEwO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBicmFjZS1zdHlsZVxuICAgIHRoaXMuZGlzdGFuY2VGdW5jdGlvbiA9IG9wdGlvbnM/LmRpc3RhbmNlID8/IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlO1xuICAgIHRoaXMuZGlzdGFuY2UgPSBuZXcgRmxvYXQzMkFycmF5KCk7XG4gICAgdGhpcy5kaXN0YW5jZUZ1bmN0aW9uTmFtZSA9IG9wdGlvbnM/LmRpc3RhbmNlRnVuY3Rpb25OYW1lITtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBkaXN0YW5jZSBtYXRyaXguXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBJbnB1dCB2ZWN0b3JzIHRvIGNhbGN1bGF0ZSBkaXN0YW5jZSBiZXR3ZWVuLlxuICAgKiBAbWVtYmVyb2YgU1BFQmFzZVxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGluaXREaXN0YW5jZSh2ZWN0b3JzOiBWZWN0b3JzKSB7XG4gICAgdGhpcy5kbUluZGV4RnVuY3QgPSBkbUxpbmVhckluZGV4KHZlY3RvcnMubGVuZ3RoKTtcbiAgICBjb25zdCBtYXRyaXhTZXJ2aWNlID0gbmV3IERpc3RhbmNlTWF0cml4U2VydmljZSh0cnVlLCBmYWxzZSk7XG4gICAgdGhpcy5kaXN0YW5jZSA9IGF3YWl0IG1hdHJpeFNlcnZpY2UuY2FsYyh2ZWN0b3JzLCB0aGlzLmRpc3RhbmNlRnVuY3Rpb25OYW1lKTtcbiAgICBtYXRyaXhTZXJ2aWNlLnRlcm1pbmF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgZGlzdGFuY2UgYmV0d2VlbiB0aGUgdHdvIHZlY3RvcnMgZ2l2ZW4uXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBTZXQgb2YgdmVjdG9ycyB0byBjYWxjdWxhdGUgZGlzdGFuY2VzIGJldHdlZW4uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleDEgSW5kZXggb2YgdGhlIGZpcnN0IHZlY3RvciBvZiB0aGUgcGFpci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4MiBJbmRleCBvZiB0aGUgc2Vjb25kIHZlY3RvciBvZiB0aGUgcGFpci5cbiAgICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNhbGNEaXN0YW5jZSh2ZWN0b3JzOiBWZWN0b3JzLCBpbmRleDE6IG51bWJlciwgaW5kZXgyOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmRpc3RhbmNlW3RoaXMuZG1JbmRleEZ1bmN0IShpbmRleDEsIGluZGV4MildO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgdmVjdG9ycyBnaXZlbiBpbnRvIGEgdHdvLWRpbWVuc2lvbmFsIHNwYWNlLlxuICAgKlxuICAgKiBAcGFyYW0ge1ZlY3RvcnN9IHZlY3RvcnMgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcy5cbiAgICogQHJldHVybiB7Q29vcmRpbmF0ZXN9IFNQRSBjb29yZGluYXRlcyBpbiBEIHNwYWNlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGVtYmVkKHZlY3RvcnM6IFZlY3RvcnMpOiBQcm9taXNlPENvb3JkaW5hdGVzPiB7XG4gICAgY29uc3Qgbkl0ZW1zID0gdmVjdG9ycy5sZW5ndGg7XG4gICAgY29uc3QgYXJlYVdpZHRoID0gNDA7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcyBvZiB0aGUgTiBwb2ludHMuXG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSBmaWxsUmFuZG9tTWF0cml4KG5JdGVtcywgU1BFQmFzZS5kaW1lbnNpb24sIGFyZWFXaWR0aCk7XG5cbiAgICBsZXQgbGFtYmRhMiA9IHRoaXMubGFtYmRhMjtcblxuICAgIGlmICh0aGlzLnN0ZXBzID09PSAwKVxuICAgICAgdGhpcy5zdGVwcyA9IHZlY3RvcnMubGVuZ3RoIC0gMTtcblxuXG4gICAgYXdhaXQgdGhpcy5pbml0RGlzdGFuY2UodmVjdG9ycyk7XG5cbiAgICBmb3IgKGxldCBjeWNsZSA9IDA7IGN5Y2xlIDwgdGhpcy5jeWNsZXM7ICsrY3ljbGUpIHtcbiAgICAgIGZvciAobGV0IHN0ZXAgPSAwOyBzdGVwIDwgdGhpcy5zdGVwczsgKytzdGVwKSB7XG4gICAgICAgIC8vIFNlbGVjdCB0d28gcG9pbnRzLCBpIGFuZCBqLCBhdCByYW5kb20sIC4uLlxuICAgICAgICBjb25zdCBpID0gcmFuZG9tSW50KG5JdGVtcyk7XG4gICAgICAgIGxldCBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG4gICAgICAgIHdoaWxlIChpID09IGopIGogPSByYW5kb21JbnQobkl0ZW1zKTtcblxuICAgICAgICBjb25zdCByb3dpID0gY29vcmRpbmF0ZXNbaV07XG4gICAgICAgIGNvbnN0IHJvd2ogPSBjb29yZGluYXRlc1tqXTtcblxuICAgICAgICAvLyAuLi4gcmV0cmlldmUgKG9yIGV2YWx1YXRlKSB0aGVpciBwcm94aW1pdHkgaW4gdGhlIGlucHV0IHNwYWNlLCByaWogYW5kIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIC4uLiBjb21wdXRlIHRoZWlyIEV1Y2xpZGVhbiBkaXN0YW5jZSBvbiB0aGUgRC1kaW1lbnNpb25hbCBtYXAsIGRpai5cbiAgICAgICAgY29uc3QgZCA9IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlKHJvd2ksIHJvd2opO1xuXG4gICAgICAgIC8vIElmIHJpaiA8PSByYywgb3IgaWYgcmlqID4gcmMgYW5kIGRpaiA8IHJpaiAuLi5cbiAgICAgICAgaWYgKCh0aGlzLmN1dG9mZiA9PSAwKSB8fCAociA8PSB0aGlzLmN1dG9mZikgfHwgKGQgPCByKSkge1xuICAgICAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSBsYW1iZGEyICogKHIgLSBkKSAvIChkICsgdGhpcy5lcHNpbG9uKTtcbiAgICAgICAgICAvLyAuLi4gdXBkYXRlIHRoZSBjb29yZGluYXRlcyB4aSBhbmQgeGouXG4gICAgICAgICAgY29uc3QgZGlmZklKID0gdmVjdG9yQWRkKHJvd2ksIHJvd2osIC0xKTtcbiAgICAgICAgICBjb29yZGluYXRlc1tpXSA9IHZlY3RvckFkZChyb3dpLCBkaWZmSUosIG11bHRpcGxpZXIpO1xuICAgICAgICAgIGNvb3JkaW5hdGVzW2pdID0gdmVjdG9yQWRkKHJvd2osIGRpZmZJSiwgLW11bHRpcGxpZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBEZWNyZWFzZSB0aGUgbGVhcm5pbmcgcmF0ZSB7bGFtYmRhfSBieSBhIHByZXNjcmliZWQge2RsYW1iZGF9LlxuICAgICAgbGFtYmRhMiAtPSB0aGlzLmRsYW1iZGEyO1xuICAgICAgaWYgKGxhbWJkYTIgPD0gMC4pXG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gY29vcmRpbmF0ZXM7XG4gIH1cbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRzIG1vZGlmaWVkIHN0b2NoYXN0aWMgcHJveGltaXR5IGVtYmVkZGluZy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgUFNQRUJhc2VcbiAqIEBsaW5rIGRvaToxMC4xMDE2L1MxMDkzLTMyNjMoMDMpMDAxNTUtNFxuICovXG5leHBvcnQgY2xhc3MgUFNQRUJhc2UgZXh0ZW5kcyBTUEVCYXNlIHtcbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgdmVjdG9ycyBnaXZlbiBpbnRvIGEgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIGEgbW9kaWZpZWQgdXBkYXRlIHJ1bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBELWRpbWVuc2lvbmFsIGNvb3JkaW5hdGVzLlxuICAgKiBAcmV0dXJuIHtDb29yZGluYXRlc30gU1BFIGNvb3JkaW5hdGVzIGluIEQgc3BhY2UuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZW1iZWQodmVjdG9yczogVmVjdG9ycyk6IFByb21pc2U8Q29vcmRpbmF0ZXM+IHtcbiAgICBjb25zdCBuSXRlbXMgPSB2ZWN0b3JzLmxlbmd0aDtcbiAgICBjb25zdCBhcmVhV2lkdGggPSA0MDtcbiAgICAvLyAgSW5pdGlhbGl6ZSB0aGUgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcyBvZiB0aGUgTiBwb2ludHMuXG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSBmaWxsUmFuZG9tTWF0cml4KG5JdGVtcywgUFNQRUJhc2UuZGltZW5zaW9uLCBhcmVhV2lkdGgpO1xuICAgIGxldCBsYW1iZGEgPSB0aGlzLmxhbWJkYTtcblxuICAgIGF3YWl0IHRoaXMuaW5pdERpc3RhbmNlKHZlY3RvcnMpO1xuXG4gICAgZm9yIChsZXQgY3ljbGUgPSAwOyBjeWNsZSA8IHRoaXMuY3ljbGVzOyArK2N5Y2xlKSB7XG4gICAgICAvLyBTZWxlY3QgYSBwb2ludCwgaSwgYXQgcmFuZG9tIChwaXZvdCkuXG4gICAgICBjb25zdCBpOiBudW1iZXIgPSByYW5kb21JbnQobkl0ZW1zKTtcbiAgICAgIGNvbnN0IHJvd2kgPSBjb29yZGluYXRlc1tpXTtcblxuICAgICAgLy8gRm9yIGV2ZXJ5IHBvaW50IGogIT0gaSAuLi5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbkl0ZW1zOyArK2opIHtcbiAgICAgICAgaWYgKGkgPT0gaikgY29udGludWU7XG4gICAgICAgIGNvbnN0IHJvd2ogPSBjb29yZGluYXRlc1tqXTtcbiAgICAgICAgLy8gLi4uIHJldHJpZXZlIChvciBldmFsdWF0ZSkgaXRzIHByb3hpbWl0eSB0byBpIGluIHRoZSBpbnB1dCBzcGFjZSwgcmlqIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIC4uLiBhbmQgY29tcHV0ZSB0aGVpciBFdWNsaWRlYW4gZGlzdGFuY2Ugb24gdGhlIEQtZGltZW5zaW9uYWwgbWFwLCBkaWouXG4gICAgICAgIGNvbnN0IGQgPSBjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZShyb3dpLCByb3dqKTtcbiAgICAgICAgLy8gSWYgcmlqIDw9IHJjLCBvciBpZiByaWogPiByYyBhbmQgZGlqIDwgcmlqIC4uLlxuICAgICAgICBpZiAoKHRoaXMuY3V0b2ZmID09IDApIHx8IChyIDw9IHRoaXMuY3V0b2ZmKSB8fCAoZCA8IHIpKSB7XG4gICAgICAgICAgY29uc3QgbXVsdGlwbGllciA9IGxhbWJkYSAqIChyIC0gZCkgLyAoZCArIHRoaXMuZXBzaWxvbik7XG4gICAgICAgICAgY29uc3QgZGlmZklKID0gdmVjdG9yQWRkKHJvd2ksIHJvd2osIC0xKTtcbiAgICAgICAgICAvLyAuLi4gdXBkYXRlIHRoZSBjb29yZGluYXRlcyB4ai5cbiAgICAgICAgICBjb29yZGluYXRlc1tqXSA9IHZlY3RvckFkZChyb3dqLCBkaWZmSUosIC1tdWx0aXBsaWVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGVjcmVhc2UgdGhlIGxlYXJuaW5nIHJhdGUge2xhbWJkYX0gYnkgYSBwcmVzY3JpYmVkIHtkbGFtYmRhfS5cbiAgICAgIGxhbWJkYSAtPSB0aGlzLmRsYW1iZGE7XG4gICAgICBpZiAobGFtYmRhIDw9IDAuKVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvb3JkaW5hdGVzO1xuICB9XG59XG5cbi8qKlxuICogSW1wbGVtZW50cyBtb2RpZmllZCBzdG9jaGFzdGljIHByb3hpbWl0eSBlbWJlZGRpbmcuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE9yaWdpbmFsU1BFXG4gKiBAbGluayBkb2k6MTAuMTAwMi9qY2MuMTAyMzRcbiAqL1xuZXhwb3J0IGNsYXNzIE9yaWdpbmFsU1BFIGV4dGVuZHMgU1BFQmFzZSB7XG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIHZlY3RvcnMgZ2l2ZW4gaW50byBhIHR3by1kaW1lbnNpb25hbCBzcGFjZSB1c2luZyBhIG1vZGlmaWVkIHVwZGF0ZSBydWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge1ZlY3RvcnN9IHZlY3RvcnMgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcy5cbiAgICogQHJldHVybiB7Q29vcmRpbmF0ZXN9IFNQRSBjb29yZGluYXRlcyBpbiBEIHNwYWNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJhZGl1c1BlcmNlbnQ6IG51bWJlcjtcbiAgcHJvdGVjdGVkIG1heERpc3RhbmNlOiBudW1iZXI7XG4gIHByb3RlY3RlZCBtYXhEaXN0YW5jZVN0ZXBzOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgICB0aGlzLmN5Y2xlcyA9IG9wdGlvbnM/LmN5Y2xlcyA/PyAxZTM7XG4gICAgdGhpcy5zdGVwcyA9IG9wdGlvbnM/LnN0ZXBzID8/IDEwMDAwMDtcbiAgICB0aGlzLnJhZGl1c1BlcmNlbnQgPSBvcHRpb25zPy5yYWRpdXNQZXJjZW50ID8/IDEuMDtcbiAgICB0aGlzLm1heERpc3RhbmNlID0gb3B0aW9ucz8ubWF4RGlzdGFuY2UgPz8gbnVsbDtcbiAgICB0aGlzLm1heERpc3RhbmNlU3RlcHMgPSBvcHRpb25zPy5tYXhEaXN0YW5jZVN0ZXBzID8/IG51bGw7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZW1iZWQodmVjdG9yczogVmVjdG9ycyk6IFByb21pc2U8Q29vcmRpbmF0ZXM+IHtcbiAgICBjb25zdCBuSXRlbXMgPSB2ZWN0b3JzLmxlbmd0aDtcbiAgICBjb25zdCBhcmVhV2lkdGggPSA0MDtcbiAgICAvLyBJbml0aWFsaXplIHRoZSBELWRpbWVuc2lvbmFsIGNvb3JkaW5hdGVzIG9mIHRoZSBOIHBvaW50cy5cbiAgICBjb25zdCBjb29yZGluYXRlcyA9IGZpbGxSYW5kb21NYXRyaXgobkl0ZW1zLCBPcmlnaW5hbFNQRS5kaW1lbnNpb24sIGFyZWFXaWR0aCk7XG5cbiAgICBhd2FpdCB0aGlzLmluaXREaXN0YW5jZSh2ZWN0b3JzKTtcblxuICAgIGlmICh0aGlzLm1heERpc3RhbmNlU3RlcHMgPT09IG51bGwpXG4gICAgICB0aGlzLm1heERpc3RhbmNlU3RlcHMgPSBuSXRlbXMgKiBNYXRoLmZsb29yKChuSXRlbXMgLSAxKSAvIDIpO1xuXG4gICAgaWYgKHRoaXMubWF4RGlzdGFuY2UgPT09IG51bGwpIHtcbiAgICAgIHRoaXMubWF4RGlzdGFuY2UgPSAtMWUzNztcbiAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgdGhpcy5tYXhEaXN0YW5jZVN0ZXBzOyBuKyspIHtcbiAgICAgICAgY29uc3QgaSA9IHJhbmRvbUludChuSXRlbXMpOyBsZXQgaiA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICB3aGlsZSAoaSA9PSBqKSBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG5cbiAgICAgICAgY29uc3QgZCA9IHRoaXMuY2FsY0Rpc3RhbmNlKHZlY3RvcnMsIGksIGopO1xuICAgICAgICBpZiAoZCA+IHRoaXMubWF4RGlzdGFuY2UpXG4gICAgICAgICAgdGhpcy5tYXhEaXN0YW5jZSA9IGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGxhbWJkYSA9IHRoaXMubGFtYmRhO1xuICAgIGNvbnN0IHJhZGl1cyA9ICh0aGlzLnJhZGl1c1BlcmNlbnQgPT0gMC4wKSA/IHRoaXMubWF4RGlzdGFuY2UgOiB0aGlzLm1heERpc3RhbmNlICogdGhpcy5yYWRpdXNQZXJjZW50O1xuXG4gICAgZm9yIChsZXQgY3ljbGUgPSAwOyBjeWNsZSA8IHRoaXMuY3ljbGVzOyArK2N5Y2xlKSB7XG4gICAgICBmb3IgKGxldCBzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7ICsrc3RlcCkge1xuICAgICAgICAvLyBTZWxlY3QgdHdvIHBvaW50cywgaSBhbmQgaiwgYXQgcmFuZG9tLCAuLi5cbiAgICAgICAgY29uc3QgaSA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICBsZXQgaiA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICB3aGlsZSAoaSA9PSBqKSBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG5cbiAgICAgICAgY29uc3Qgcm93aSA9IGNvb3JkaW5hdGVzW2ldO1xuICAgICAgICBjb25zdCByb3dqID0gY29vcmRpbmF0ZXNbal07XG5cbiAgICAgICAgLy8gcmV0cmlldmUgKG9yIGV2YWx1YXRlKSB0aGVpciBwcm94aW1pdHkgaW4gdGhlIGlucHV0IHNwYWNlLCByaWogYW5kIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIGNvbXB1dGUgdGhlaXIgRXVjbGlkZWFuIGRpc3RhbmNlIG9uIHRoZSBELWRpbWVuc2lvbmFsIG1hcCwgZGlqLlxuICAgICAgICBjb25zdCBkID0gY2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2Uocm93aSwgcm93aik7XG5cbiAgICAgICAgaWYgKChyIDw9IHJhZGl1cykgfHwgKGQgPCByKSkge1xuICAgICAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSBsYW1iZGEgKiAwLjUgKiAociAtIGQpIC8gKGQgKyB0aGlzLmVwc2lsb24pO1xuICAgICAgICAgIC8vIC4uLiB1cGRhdGUgdGhlIGNvb3JkaW5hdGVzIHhpIGFuZCB4ai5cbiAgICAgICAgICBjb25zdCBkaWZmSUogPSB2ZWN0b3JBZGQocm93aSwgcm93aiwgLTEpO1xuICAgICAgICAgIGNvb3JkaW5hdGVzW2ldID0gdmVjdG9yQWRkKHJvd2ksIGRpZmZJSiwgbXVsdGlwbGllcik7XG4gICAgICAgICAgY29vcmRpbmF0ZXNbal0gPSB2ZWN0b3JBZGQocm93aiwgZGlmZklKLCAtbXVsdGlwbGllcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxhbWJkYSAtPSAoKHRoaXMubGFtYmRhIC0gdGhpcy5kbGFtYmRhKSAvICh0aGlzLmN5Y2xlcyAtIDEuMCkpOyA7XG4gICAgICBpZiAobGFtYmRhIDwgdGhpcy5kbGFtYmRhKVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvb3JkaW5hdGVzO1xuICB9XG59XG4iXX0=","export var StringMetricsNames;\n(function (StringMetricsNames) {\n StringMetricsNames[\"Levenshtein\"] = \"Levenshtein\";\n StringMetricsNames[\"JaroWinkler\"] = \"Jaro-Winkler\";\n StringMetricsNames[\"Manhattan\"] = \"Manhattan\";\n})(StringMetricsNames || (StringMetricsNames = {}));\nexport var VectorMetricsNames;\n(function (VectorMetricsNames) {\n VectorMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(VectorMetricsNames || (VectorMetricsNames = {}));\nexport var BitArrayMetricsNames;\n(function (BitArrayMetricsNames) {\n BitArrayMetricsNames[\"Tanimoto\"] = \"Tanimoto\";\n BitArrayMetricsNames[\"Dice\"] = \"Dice\";\n BitArrayMetricsNames[\"Asymmetric\"] = \"Asymmetric\";\n BitArrayMetricsNames[\"BraunBlanquet\"] = \"Braun-Blanquet\";\n BitArrayMetricsNames[\"Cosine\"] = \"Cosine\";\n BitArrayMetricsNames[\"Kulczynski\"] = \"Kulczynski\";\n BitArrayMetricsNames[\"McConnaughey\"] = \"Mc-Connaughey\";\n BitArrayMetricsNames[\"RogotGoldberg\"] = \"Rogot-Goldberg\";\n BitArrayMetricsNames[\"Russel\"] = \"Russel\";\n BitArrayMetricsNames[\"Sokal\"] = \"Sokal\";\n BitArrayMetricsNames[\"Hamming\"] = \"Hamming\";\n BitArrayMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(BitArrayMetricsNames || (BitArrayMetricsNames = {}));\nexport var IntArrayMetricsNames;\n(function (IntArrayMetricsNames) {\n IntArrayMetricsNames[\"TanimotoIntArray\"] = \"TanimotoIntArray\";\n})(IntArrayMetricsNames || (IntArrayMetricsNames = {}));\nexport var DistanceMetricsSubjects;\n(function (DistanceMetricsSubjects) {\n DistanceMetricsSubjects[\"Vector\"] = \"Vector\";\n DistanceMetricsSubjects[\"String\"] = \"String\";\n DistanceMetricsSubjects[\"BitArray\"] = \"BitArray\";\n DistanceMetricsSubjects[\"MacroMolecule\"] = \"MacroMolecule\";\n DistanceMetricsSubjects[\"Number\"] = \"Number\";\n DistanceMetricsSubjects[\"IntArray\"] = \"IntArray\";\n})(DistanceMetricsSubjects || (DistanceMetricsSubjects = {}));\nexport var NumberMetricsNames;\n(function (NumberMetricsNames) {\n NumberMetricsNames[\"NumericDistance\"] = \"NumericDistance\";\n})(NumberMetricsNames || (NumberMetricsNames = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBTixJQUFZLGtCQUlUO0FBSkgsV0FBWSxrQkFBa0I7SUFDMUIsaURBQTJCLENBQUE7SUFDM0Isa0RBQTRCLENBQUE7SUFDNUIsNkNBQXVCLENBQUE7QUFDekIsQ0FBQyxFQUpTLGtCQUFrQixLQUFsQixrQkFBa0IsUUFJM0I7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFVDtBQUZILFdBQVksa0JBQWtCO0lBQzFCLDZDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFGUyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTNCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBYVQ7QUFiSCxXQUFZLG9CQUFvQjtJQUM1Qiw2Q0FBcUIsQ0FBQTtJQUNyQixxQ0FBYSxDQUFBO0lBQ2IsaURBQXlCLENBQUE7SUFDekIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsaURBQXlCLENBQUE7SUFDekIsc0RBQThCLENBQUE7SUFDOUIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsdUNBQWUsQ0FBQTtJQUNmLDJDQUFtQixDQUFBO0lBQ25CLCtDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFiUyxvQkFBb0IsS0FBcEIsb0JBQW9CLFFBYTdCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBRVg7QUFGRCxXQUFZLG9CQUFvQjtJQUM5Qiw2REFBcUMsQ0FBQTtBQUN2QyxDQUFDLEVBRlcsb0JBQW9CLEtBQXBCLG9CQUFvQixRQUUvQjtBQUVELE1BQU0sQ0FBTixJQUFZLHVCQU9UO0FBUEgsV0FBWSx1QkFBdUI7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7SUFDckIsMERBQStCLENBQUE7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQVBTLHVCQUF1QixLQUF2Qix1QkFBdUIsUUFPaEM7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFWDtBQUZELFdBQVksa0JBQWtCO0lBQzVCLHlEQUFtQyxDQUFBO0FBQ3JDLENBQUMsRUFGVyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGVudW0gU3RyaW5nTWV0cmljc05hbWVzIHtcbiAgICBMZXZlbnNodGVpbiA9ICdMZXZlbnNodGVpbicsXG4gICAgSmFyb1dpbmtsZXIgPSAnSmFyby1XaW5rbGVyJyxcbiAgICBNYW5oYXR0YW4gPSAnTWFuaGF0dGFuJyxcbiAgfVxuXG5leHBvcnQgZW51bSBWZWN0b3JNZXRyaWNzTmFtZXMge1xuICAgIEV1Y2xpZGVhbiA9ICdFdWNsaWRlYW4nLFxuICB9XG5cbmV4cG9ydCBlbnVtIEJpdEFycmF5TWV0cmljc05hbWVzIHtcbiAgICBUYW5pbW90byA9ICdUYW5pbW90bycsXG4gICAgRGljZSA9ICdEaWNlJyxcbiAgICBBc3ltbWV0cmljID0gJ0FzeW1tZXRyaWMnLFxuICAgIEJyYXVuQmxhbnF1ZXQgPSAnQnJhdW4tQmxhbnF1ZXQnLFxuICAgIENvc2luZSA9ICdDb3NpbmUnLFxuICAgIEt1bGN6eW5za2kgPSAnS3VsY3p5bnNraScsXG4gICAgTWNDb25uYXVnaGV5ID0gJ01jLUNvbm5hdWdoZXknLFxuICAgIFJvZ290R29sZGJlcmcgPSAnUm9nb3QtR29sZGJlcmcnLFxuICAgIFJ1c3NlbCA9ICdSdXNzZWwnLFxuICAgIFNva2FsID0gJ1Nva2FsJyxcbiAgICBIYW1taW5nID0gJ0hhbW1pbmcnLFxuICAgIEV1Y2xpZGVhbiA9ICdFdWNsaWRlYW4nLFxuICB9XG5cbmV4cG9ydCBlbnVtIEludEFycmF5TWV0cmljc05hbWVzIHtcbiAgVGFuaW1vdG9JbnRBcnJheSA9ICdUYW5pbW90b0ludEFycmF5Jyxcbn1cblxuZXhwb3J0IGVudW0gRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMge1xuICAgIFZlY3RvciA9ICdWZWN0b3InLFxuICAgIFN0cmluZyA9ICdTdHJpbmcnLFxuICAgIEJpdEFycmF5ID0gJ0JpdEFycmF5JyxcbiAgICBNYWNyb01vbGVjdWxlID0gJ01hY3JvTW9sZWN1bGUnLFxuICAgIE51bWJlciA9ICdOdW1iZXInLFxuICAgIEludEFycmF5ID0gJ0ludEFycmF5JyxcbiAgfVxuXG5leHBvcnQgZW51bSBOdW1iZXJNZXRyaWNzTmFtZXMge1xuICBOdW1lcmljRGlzdGFuY2UgPSAnTnVtZXJpY0Rpc3RhbmNlJyxcbn1cblxuIl19","import BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport { BitArrayMetricsNames } from './typed-metrics/consts';\nimport { MmDistanceFunctionsNames } from './macromolecule-distance-functions';\nexport const similarityMetric = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoSimilarity,\n [BitArrayMetricsNames.Dice]: diceSimilarity,\n [BitArrayMetricsNames.Asymmetric]: asymmetricSimilarity,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetSimilarity,\n [BitArrayMetricsNames.Cosine]: cosineSimilarity,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiSimilarity,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheySimilarity,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergSimilarity,\n [BitArrayMetricsNames.Russel]: russelSimilarity,\n [BitArrayMetricsNames.Sokal]: sokalSimilarity,\n [BitArrayMetricsNames.Hamming]: hammingSimilarity,\n [BitArrayMetricsNames.Euclidean]: euclideanSimilarity,\n};\nexport const distanceMetrics = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoDistance,\n [BitArrayMetricsNames.Dice]: diceDistance,\n [BitArrayMetricsNames.Asymmetric]: asymmetricDistance,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetDistance,\n [BitArrayMetricsNames.Cosine]: cosineDistance,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiDistance,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheyDistance,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergDistance,\n [BitArrayMetricsNames.Russel]: russelDistance,\n [BitArrayMetricsNames.Sokal]: sokalDistance,\n [BitArrayMetricsNames.Hamming]: hammingDistance,\n [BitArrayMetricsNames.Euclidean]: euclideanDistance,\n};\nexport const CHEM_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Dice,\n BitArrayMetricsNames.Cosine\n];\nexport const SEQ_SPACE_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Asymmetric,\n BitArrayMetricsNames.Cosine,\n BitArrayMetricsNames.Sokal\n];\nexport const MACROMOLECULE_SIMILARITY_METRICS = [\n MmDistanceFunctionsNames.HAMMING,\n MmDistanceFunctionsNames.LEVENSHTEIN,\n MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE\n];\nexport function tanimotoSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 1.0;\n const common = x.andWithCountBits(y, true);\n return common / (total - common);\n}\nexport function tanimotoDistance(x, y) {\n return getDistanceFromSimilarity(tanimotoSimilarity(x, y));\n}\nexport function tanimotoDistanceIntArray(x, y) {\n const xb = new BitArray(x, x.length * 32);\n const yb = new BitArray(y, y.length * 32);\n return getDistanceFromSimilarity(tanimotoSimilarity(xb, yb));\n}\nexport function diceSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return 2 * common / total;\n}\nexport function diceDistance(x, y) {\n return getDistanceFromSimilarity(diceSimilarity(x, y));\n}\nexport function cosineSimilarity(x, y) {\n const total = x.trueCount() * y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / Math.sqrt(total);\n}\nexport function cosineDistance(x, y) {\n return getDistanceFromSimilarity(cosineSimilarity(x, y));\n}\nexport function euclideanSimilarity(x, y) {\n return getSimilarityFromDistance(euclideanDistance(x, y));\n}\nexport function euclideanDistance(x, y) {\n return Math.sqrt(x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true));\n}\nexport function hammingSimilarity(x, y) {\n return getSimilarityFromDistance(hammingDistance(x, y));\n}\nexport function hammingDistance(x, y) {\n return x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true);\n}\nexport function sokalSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const common = x.andWithCountBits(y, true);\n return common / (2 * total - 3 * common);\n}\nexport function sokalDistance(x, y) {\n return getDistanceFromSimilarity(sokalSimilarity(x, y));\n}\nexport function kulczynskiSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total) / (2 * totalProd);\n}\nexport function kulczynskiDistance(x, y) {\n return getDistanceFromSimilarity(kulczynskiSimilarity(x, y));\n}\nexport function mcConnaugheySimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total - totalProd) / totalProd;\n}\nexport function mcConnaugheyDistance(x, y) {\n return getDistanceFromSimilarity(mcConnaugheySimilarity(x, y));\n}\nexport function asymmetricSimilarity(x, y) {\n const min = Math.min(x.trueCount(), y.trueCount());\n if (min == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / min;\n}\nexport function asymmetricDistance(x, y) {\n return getDistanceFromSimilarity(asymmetricSimilarity(x, y));\n}\nexport function braunBlanquetSimilarity(x, y) {\n const max = Math.max(x.trueCount(), y.trueCount());\n if (max == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / max;\n}\nexport function braunBlanquetDistance(x, y) {\n return getDistanceFromSimilarity(braunBlanquetSimilarity(x, y));\n}\nexport function russelSimilarity(x, y) {\n if (x.length == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / x.length;\n}\nexport function russelDistance(x, y) {\n return getDistanceFromSimilarity(russelSimilarity(x, y));\n}\nexport function rogotGoldbergSimilarity(x, y) {\n const common = x.andWithCountBits(y, true);\n const total = x.countBits(true) + y.countBits(true);\n const len = x.length;\n const diff = len - total + common;\n if ((common == len) || (diff == len))\n return 1.0;\n else\n return common / total + diff / (2 * len - total);\n}\nexport function rogotGoldbergDistance(x, y) {\n return getDistanceFromSimilarity(rogotGoldbergSimilarity(x, y));\n}\nexport function getSimilarityFromDistance(distance) {\n return 1 / (1 + distance);\n}\nexport function getDistanceFromSimilarity(similarity) {\n return similarity === 0 ? 3.402823E+38 : (1 / similarity) - 1;\n}\nexport function numericDistance(x, y) {\n return Math.abs(x - y);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sUUFBUSxNQUFNLHlDQUF5QyxDQUFDO0FBQy9ELE9BQU8sRUFBQyxvQkFBb0IsRUFBdUIsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUU5RSxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBNkQ7SUFDeEYsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSxrQkFBa0I7SUFDbkQsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFjO0lBQzNDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsb0JBQW9CO0lBQ3ZELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUsdUJBQXVCO0lBQzdELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsZ0JBQWdCO0lBQy9DLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsb0JBQW9CO0lBQ3ZELENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLEVBQUUsc0JBQXNCO0lBQzNELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUsdUJBQXVCO0lBQzdELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsZ0JBQWdCO0lBQy9DLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLEVBQUUsZUFBZTtJQUM3QyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxFQUFFLGlCQUFpQjtJQUNqRCxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxFQUFFLG1CQUFtQjtDQUN0RCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUE2RDtJQUN2RixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxF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QUFDO0FBRUQsTUFBTSxVQUFVLGVBQWUsQ0FBQyxDQUFTLEVBQUUsQ0FBUztJQUNsRCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQml0QXJyYXkgZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvYml0LWFycmF5JztcbmltcG9ydCB7Qml0QXJyYXlNZXRyaWNzTmFtZXMsIEludEFycmF5TWV0cmljc05hbWVzfSBmcm9tICcuL3R5cGVkLW1ldHJpY3MvY29uc3RzJztcbmltcG9ydCB7IE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB9IGZyb20gJy4vbWFjcm9tb2xlY3VsZS1kaXN0YW5jZS1mdW5jdGlvbnMnO1xuXG5leHBvcnQgY29uc3Qgc2ltaWxhcml0eU1ldHJpYzogeyBbbmFtZTogc3RyaW5nXTogKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSkgPT4gbnVtYmVyIH0gPSB7XG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b106IHRhbmltb3RvU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkRpY2VdOiBkaWNlU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkFzeW1tZXRyaWNdOiBhc3ltbWV0cmljU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkJyYXVuQmxhbnF1ZXRdOiBicmF1bkJsYW5xdWV0U2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV06IGNvc2luZVNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5LdWxjenluc2tpXToga3VsY3p5bnNraVNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldOiBtY0Nvbm5hdWdoZXlTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUm9nb3RHb2xkYmVyZ106IHJvZ290R29sZGJlcmdTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXTogcnVzc2VsU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXTogc29rYWxTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuSGFtbWluZ106IGhhbW1pbmdTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogZXVjbGlkZWFuU2ltaWxhcml0eSxcbn07XG5cbmV4cG9ydCBjb25zdCBkaXN0YW5jZU1ldHJpY3M6IHsgW25hbWU6IHN0cmluZ106ICh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9dOiB0YW5pbW90b0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV06IGRpY2VEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkFzeW1tZXRyaWNdOiBhc3ltbWV0cmljRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XTogYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTogY29zaW5lRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5LdWxjenluc2tpXToga3VsY3p5bnNraURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuTWNDb25uYXVnaGV5XTogbWNDb25uYXVnaGV5RGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXTogcm9nb3RHb2xkYmVyZ0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXTogcnVzc2VsRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF06IHNva2FsRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5IYW1taW5nXTogaGFtbWluZ0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogZXVjbGlkZWFuRGlzdGFuY2UsXG59O1xuXG5leHBvcnQgY29uc3QgQ0hFTV9TSU1JTEFSSVRZX01FVFJJQ1MgPSBbXG4gIEJpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdO1xuZXhwb3J0IGNvbnN0IFNFUV9TUEFDRV9TSU1JTEFSSVRZX01FVFJJQ1MgPSBbXG4gIEJpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmUsXG4gIEJpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXTtcbmV4cG9ydCBjb25zdCBNQUNST01PTEVDVUxFX1NJTUlMQVJJVFlfTUVUUklDUyA9IFtcbiAgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkcsXG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5MRVZFTlNIVEVJTixcbiAgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk1PTk9NRVJfQ0hFTUlDQUxfRElTVEFOQ0VdO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiB0YW5pbW90b1NpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgdG90YWwgPSB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKTtcbiAgaWYgKHRvdGFsID09IDApIHJldHVybiAxLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvICh0b3RhbCAtIGNvbW1vbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0YW5pbW90b0Rpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KHRhbmltb3RvU2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0YW5pbW90b0Rpc3RhbmNlSW50QXJyYXkoeDogVWludDMyQXJyYXksIHk6IFVpbnQzMkFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgeGIgPSBuZXcgQml0QXJyYXkoeCwgeC5sZW5ndGggKiAzMik7XG4gIGNvbnN0IHliID0gbmV3IEJpdEFycmF5KHksIHkubGVuZ3RoICogMzIpO1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eSh0YW5pbW90b1NpbWlsYXJpdHkoeGIsIHliKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWNlU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWwgPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gMiAqIGNvbW1vbiAvIHRvdGFsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGljZURpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KGRpY2VTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvc2luZVNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgdG90YWwgPSB4LnRydWVDb3VudCgpICogeS50cnVlQ291bnQoKTtcbiAgaWYgKHRvdGFsID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvIE1hdGguc3FydCh0b3RhbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmVEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShjb3NpbmVTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV1Y2xpZGVhblNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UoZXVjbGlkZWFuRGlzdGFuY2UoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXVjbGlkZWFuRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguc3FydCh4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKSAtIDIgKiB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFtbWluZ1NpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UoaGFtbWluZ0Rpc3RhbmNlKHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhbW1pbmdEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCkgLSAyICogeC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc29rYWxTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCk7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvICgyICogdG90YWwgLSAzICogY29tbW9uKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNva2FsRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoc29rYWxTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGt1bGN6eW5za2lTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCk7XG4gIGNvbnN0IHRvdGFsUHJvZCA9IHgudHJ1ZUNvdW50KCkgKiB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWxQcm9kID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIChjb21tb24gKiB0b3RhbCkgLyAoMiAqIHRvdGFsUHJvZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBrdWxjenluc2tpRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoa3VsY3p5bnNraVNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWNDb25uYXVnaGV5U2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBjb25zdCB0b3RhbFByb2QgPSB4LnRydWVDb3VudCgpICogeS50cnVlQ291bnQoKTtcbiAgaWYgKHRvdGFsUHJvZCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiAoY29tbW9uICogdG90YWwgLSB0b3RhbFByb2QpIC8gdG90YWxQcm9kO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWNDb25uYXVnaGV5RGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkobWNDb25uYXVnaGV5U2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3ltbWV0cmljU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCBtaW4gPSBNYXRoLm1pbih4LnRydWVDb3VudCgpLCB5LnRydWVDb3VudCgpKTtcbiAgaWYgKG1pbiA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyBtaW47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3ltbWV0cmljRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoYXN5bW1ldHJpY1NpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnJhdW5CbGFucXVldFNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgbWF4ID0gTWF0aC5tYXgoeC50cnVlQ291bnQoKSwgeS50cnVlQ291bnQoKSk7XG4gIGlmIChtYXggPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gbWF4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnJhdW5CbGFucXVldERpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KGJyYXVuQmxhbnF1ZXRTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1c3NlbFNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgaWYgKHgubGVuZ3RoID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvIHgubGVuZ3RoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcnVzc2VsRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkocnVzc2VsU2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByb2dvdEdvbGRiZXJnU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIGNvbnN0IHRvdGFsID0geC5jb3VudEJpdHModHJ1ZSkgKyB5LmNvdW50Qml0cyh0cnVlKTtcbiAgY29uc3QgbGVuID0geC5sZW5ndGg7XG4gIGNvbnN0IGRpZmYgPSBsZW4gLSB0b3RhbCArIGNvbW1vbjtcbiAgaWYgKChjb21tb24gPT0gbGVuKSB8fCAoZGlmZiA9PSBsZW4pKSByZXR1cm4gMS4wO1xuICBlbHNlIHJldHVybiBjb21tb24gLyB0b3RhbCArIGRpZmYgLyAoMiAqIGxlbiAtIHRvdGFsKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJvZ290R29sZGJlcmdEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShyb2dvdEdvbGRiZXJnU2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTaW1pbGFyaXR5RnJvbURpc3RhbmNlKGRpc3RhbmNlOiBudW1iZXIpIHtcbiAgcmV0dXJuIDEgLyAoMSArIGRpc3RhbmNlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoc2ltaWxhcml0eTogbnVtYmVyKSB7IC8vaW4gY2FzZSBzaW1pbGFyaXR5IGlzIDAsIHVzZSBtYXggbnVtYmVyIGZvciBmbG9hdDMyXG4gIHJldHVybiBzaW1pbGFyaXR5ID09PSAwID8gMy40MDI4MjNFKzM4IDogKDEgLyBzaW1pbGFyaXR5KSAtIDE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBudW1lcmljRGlzdGFuY2UoeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgcmV0dXJuIE1hdGguYWJzKHggLSB5KTtcbn1cbiJdfQ==","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, } 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 } 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};\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.NumericDistance]: numericDistance,\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 },\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.NumericDistance]: numberDistanceMetricsMethods[NumberMetricsNames.NumericDistance],\n },\n [DistanceMetricsSubjects.IntArray]: {\n [IntArrayMetricsNames.TanimotoIntArray]: intArrayDistanceMetricsMethods[IntArrayMetricsNames.TanimotoIntArray],\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}\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}\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 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 isMacroMoleculeMetric(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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWQtbWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInR5cGVkLW1ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxQyxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFcEQsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixxQkFBcUIsRUFDckIsY0FBYyxFQUNkLFlBQVksRUFDWixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZix3QkFBd0IsR0FDekIsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQUMsMEJBQTBCLEVBQUMsTUFBTSxpREFBaUQsQ0FBQztBQUczRixPQUFPLEVBQUMsbUJBQW1CLEVBQUUsd0JBQXdCLEVBQUMsTUFBTSxxQ0FBcUMsQ0FBQztBQUNsRyxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQ25ELGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLG9CQUFvQixFQUFDLE1BQU0sVUFBVSxDQUFDO0FBR3BHLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUF5RDtJQUNoRyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLDBCQUEwQjtDQUMzRCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQXlEO0lBQ2hHLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVE7SUFDN0MsQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxXQUFXO0lBQzdDLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsaUJBQWlCO0NBQ2xELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBNkQ7SUFDdEcsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSxnQkFBZ0I7SUFDakQsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxZQUFZO0lBQ3pDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsa0JBQWtCO0lBQ3JELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUscUJBQXFCO0lBQzNELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsY0FBYztJQUM3QyxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLGtCQUFrQjtJQUNyRCxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxFQUFFLG9CQUFvQjtJQUN6RCxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLHFCQUFxQjtJQUMzRCxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLGNBQWM7SUFDN0MsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhO0lBQzNDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLEVBQUUsZUFBZTtJQUMvQyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxFQUFFLGlCQUFpQjtDQUNwRCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQW1FO0lBQzVHLENBQUMsb0JBQW9CLENBQUMsZ0JBQWdCLENBQUMsRUFBRSx3QkFBd0I7Q0FDbEUsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUF5RDtJQUNoRyxDQUFDLGtCQUFrQixDQUFDLGVBQWUsQ0FBQyxFQUFFLGVBQWU7Q0FDdEQsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHO0lBQzlCLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDaEMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFBRSw0QkFBNEIsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUM7S0FDM0Y7SUFDRCxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQ2hDLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDO1FBQzlGLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDO1FBQzlGLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDO0tBQzNGO0lBQ0QsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUNsQyxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQztRQUM5RixDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQztRQUN0RixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQztRQUNsRyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQztRQUN4RyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQztRQUMxRixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQztRQUNsRyxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQztRQUN0RyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQztRQUN4RyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFD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dCB7amFyb1dpbmtsZXJ9IGZyb20gJ2phcm8td2lua2xlci10eXBlc2NyaXB0JztcbmltcG9ydCB7RGlzdGFuY2VNZXRyaWN9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7XG4gIGFzeW1tZXRyaWNEaXN0YW5jZSxcbiAgYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBjb3NpbmVEaXN0YW5jZSxcbiAgZGljZURpc3RhbmNlLFxuICBldWNsaWRlYW5EaXN0YW5jZSxcbiAgaGFtbWluZ0Rpc3RhbmNlLFxuICBrdWxjenluc2tpRGlzdGFuY2UsXG4gIG1jQ29ubmF1Z2hleURpc3RhbmNlLFxuICByb2dvdEdvbGRiZXJnRGlzdGFuY2UsXG4gIHJ1c3NlbERpc3RhbmNlLFxuICBzb2thbERpc3RhbmNlLFxuICB0YW5pbW90b0Rpc3RhbmNlLFxuICBudW1lcmljRGlzdGFuY2UsXG4gIHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSxcbn0gZnJvbSAnLi4vZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzJztcblxuaW1wb3J0IHtjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZX0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdmVjdG9yLW9wZXJhdGlvbnMnO1xuaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQge1ZlY3RvciwgU3RyaW5nRGljdGlvbmFyeX0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdHlwZS1kZWNsYXJhdGlvbnMnO1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25zLCBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXN9IGZyb20gJy4uL21hY3JvbW9sZWN1bGUtZGlzdGFuY2UtZnVuY3Rpb25zJztcbmltcG9ydCB7RGlzdGFuY2VNZXRyaWNzU3ViamVjdHMsIEJpdEFycmF5TWV0cmljc05hbWVzLFxuICBTdHJpbmdNZXRyaWNzTmFtZXMsIFZlY3Rvck1ldHJpY3NOYW1lcywgTnVtYmVyTWV0cmljc05hbWVzLCBJbnRBcnJheU1ldHJpY3NOYW1lc30gZnJvbSAnLi9jb25zdHMnO1xuXG5cbmV4cG9ydCBjb25zdCB2ZWN0b3JEaXN0YW5jZU1ldHJpY3NNZXRob2RzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogVmVjdG9yLCB5OiBWZWN0b3IpID0+IG51bWJlciB9ID0ge1xuICBbVmVjdG9yTWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IHN0cmluZ0Rpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBzdHJpbmcsIHk6IHN0cmluZykgPT4gbnVtYmVyIH0gPSB7XG4gIFtTdHJpbmdNZXRyaWNzTmFtZXMuTGV2ZW5zaHRlaW5dOiBmbC5kaXN0YW5jZSxcbiAgW1N0cmluZ01ldHJpY3NOYW1lcy5KYXJvV2lua2xlcl06IGphcm9XaW5rbGVyLFxuICBbU3RyaW5nTWV0cmljc05hbWVzLk1hbmhhdHRhbl06IG1hbmhhdHRhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kczogeyBbbmFtZTogc3RyaW5nXTogKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSkgPT4gbnVtYmVyIH0gPSB7XG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b106IHRhbmltb3RvRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXTogZGljZURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpY106IGFzeW1tZXRyaWNEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkJyYXVuQmxhbnF1ZXRdOiBicmF1bkJsYW5xdWV0RGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdOiBjb3NpbmVEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkt1bGN6eW5za2ldOiBrdWxjenluc2tpRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldOiBtY0Nvbm5hdWdoZXlEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddOiByb2dvdEdvbGRiZXJnRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5SdXNzZWxdOiBydXNzZWxEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXTogc29rYWxEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkhhbW1pbmddOiBoYW1taW5nRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5FdWNsaWRlYW5dOiBldWNsaWRlYW5EaXN0YW5jZSxcbn07XG5cbmV4cG9ydCBjb25zdCBpbnRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBVaW50MzJBcnJheSwgeTogVWludDMyQXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbSW50QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9JbnRBcnJheV06IHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSxcbn07XG5cbmV4cG9ydCBjb25zdCBudW1iZXJEaXN0YW5jZU1ldHJpY3NNZXRob2RzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IG51bWJlciB9ID0ge1xuICBbTnVtYmVyTWV0cmljc05hbWVzLk51bWVyaWNEaXN0YW5jZV06IG51bWVyaWNEaXN0YW5jZSxcbn07XG5cbmV4cG9ydCBjb25zdCBBdmFpbGFibGVNZXRyaWNzID0ge1xuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuVmVjdG9yXToge1xuICAgIFtWZWN0b3JNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogdmVjdG9yRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tWZWN0b3JNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXSxcbiAgfSxcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLlN0cmluZ106IHtcbiAgICBbU3RyaW5nTWV0cmljc05hbWVzLkxldmVuc2h0ZWluXTogc3RyaW5nRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tTdHJpbmdNZXRyaWNzTmFtZXMuTGV2ZW5zaHRlaW5dLFxuICAgIFtTdHJpbmdNZXRyaWNzTmFtZXMuSmFyb1dpbmtsZXJdOiBzdHJpbmdEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1N0cmluZ01ldHJpY3NOYW1lcy5KYXJvV2lua2xlcl0sXG4gICAgW1N0cmluZ01ldHJpY3NOYW1lcy5NYW5oYXR0YW5dOiBzdHJpbmdEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1N0cmluZ01ldHJpY3NOYW1lcy5NYW5oYXR0YW5dLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuQml0QXJyYXldOiB7XG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpY106IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQnJhdW5CbGFucXVldF06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLkt1bGN6eW5za2ldOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLk1jQ29ubmF1Z2hleV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5SdXNzZWxdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuTWFjcm9Nb2xlY3VsZV06IHsgLy8gb3B0aW9uYWwgYXJncyBuZWVkZWQgZm9yIG1hY3JvbW9sZWN1bGUgZnVuY3Rpb25zIHdoaWNoIGluaXRpYWxpemUgdGhlbVxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuSEFNTUlOR106IG1tRGlzdGFuY2VGdW5jdGlvbnNbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkddLFxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU5dOiBtbURpc3RhbmNlRnVuY3Rpb25zW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5MRVZFTlNIVEVJTl0sXG4gICAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5ORUVETEVNQU5OX1dVTlNDSF06IG1tRGlzdGFuY2VGdW5jdGlvbnNbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk5FRURMRU1BTk5fV1VOU0NIXSxcbiAgICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk1PTk9NRVJfQ0hFTUlDQUxfRElTVEFOQ0VdOiBtbURpc3RhbmNlRnVuY3Rpb25zW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5NT05PTUVSX0NIRU1JQ0FMX0RJU1RBTkNFXSxcbiAgfSxcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLk51bWJlcl06IHtcbiAgICBbTnVtYmVyTWV0cmljc05hbWVzLk51bWVyaWNEaXN0YW5jZV06IG51bWJlckRpc3RhbmNlTWV0cmljc01ldGhvZHNbTnVtYmVyTWV0cmljc05hbWVzLk51bWVyaWNEaXN0YW5jZV0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5JbnRBcnJheV06IHtcbiAgICBbSW50QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9JbnRBcnJheV06IGludEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tJbnRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b0ludEFycmF5XSxcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IE1ldHJpY1RvRGF0YVR5cGU6IFN0cmluZ0RpY3Rpb25hcnkgPSBPYmplY3Qua2V5cyhBdmFpbGFibGVNZXRyaWNzKVxuICAucmVkdWNlKChyZXQ6IFN0cmluZ0RpY3Rpb25hcnksIGtleSkgPT4ge1xuICAgIGZvciAoY29uc3QgdmFsIG9mIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3Nba2V5IGFzIEF2YWlsYWJsZURhdGFUeXBlc10pKVxuICAgICAgcmV0W3ZhbCBhcyBBdmFpbGFibGVEYXRhVHlwZXNdID0ga2V5O1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfSwge30pO1xuXG5leHBvcnQgdHlwZSBBdmFpbGFibGVEYXRhVHlwZXMgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljcztcbmV4cG9ydCB0eXBlIFZlY3Rvck1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5WZWN0b3JdO1xuZXhwb3J0IHR5cGUgU3RyaW5nTWV0cmljcyA9IGtleW9mIHR5cGVvZiBBdmFpbGFibGVNZXRyaWNzW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLlN0cmluZ107XG5leHBvcnQgdHlwZSBCaXRBcnJheU1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5CaXRBcnJheV07XG5leHBvcnQgdHlwZSBLbm93bk1ldHJpY3MgPSBTdHJpbmdNZXRyaWNzIHwgQml0QXJyYXlNZXRyaWNzIHwgVmVjdG9yTWV0cmljcyB8XG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB8IE51bWJlck1ldHJpY3NOYW1lcyB8IEludEFycmF5TWV0cmljc05hbWVzO1xuXG5leHBvcnQgdHlwZSBWYWxpZFR5cGVzID1cbiAgeyBkYXRhOiBzdHJpbmdbXSwgbWV0cmljOiBTdHJpbmdNZXRyaWNzIHwgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzIH0gfFxuICB7IGRhdGE6IFZlY3RvcltdLCBtZXRyaWM6IFZlY3Rvck1ldHJpY3MgfSB8XG4gIHsgZGF0YTogQml0QXJyYXlbXSwgbWV0cmljOiBCaXRBcnJheU1ldHJpY3MgfSB8XG4gIHsgZGF0YTogbnVtYmVyW10sIG1ldHJpYzogTnVtYmVyTWV0cmljc05hbWVzIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZ01ldHJpYyhuYW1lOiBLbm93bk1ldHJpY3MpIHtcbiAgcmV0dXJuIE1ldHJpY1RvRGF0YVR5cGVbbmFtZV0gPT0gJ1N0cmluZyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0JpdEFycmF5TWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSAnQml0QXJyYXknO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZWN0b3JNZXRyaWMobmFtZTogS25vd25NZXRyaWNzKSB7XG4gIHJldHVybiBNZXRyaWNUb0RhdGFUeXBlW25hbWVdID09ICdWZWN0b3InO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNYWNyb01vbGVjdWxlTWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSBEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5NYWNyb01vbGVjdWxlLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBNYW5oYXR0YW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gc2VxdWVuY2VzIChtYXRjaCAtIDAsIG1pc21hdGNoIC0gMSkgbm9ybWFsaXplZCBmb3IgbGVuZ3RoLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hbmhhdHRhbkRpc3RhbmNlKHMxOiBzdHJpbmcsIHMyOiBzdHJpbmcpOiBudW1iZXIge1xuICBpZiAoczEubGVuZ3RoICE9PSBzMi5sZW5ndGgpIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgZGlzdDogbnVtYmVyID0gMDtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHMxLmxlbmd0aDsgaSsrKVxuICAgICAgZGlzdCArPSBzMVtpXSA9PSBzMltpXSA/IDAgOiAxO1xuICAgIHJldHVybiBkaXN0IC8gczEubGVuZ3RoO1xuICB9XG59XG5cbi8qKiBVbmlmaWVkIGNsYXNzIGltcGxlbWVudGluZyBkaWZmZXJlbnQgc3RyaW5nIG1lYXN1cmVzLiAqL1xuZXhwb3J0IGNsYXNzIE1lYXN1cmUge1xuICBwcm90ZWN0ZWQgbWV0aG9kOiBLbm93bk1ldHJpY3M7XG4gIHByb3RlY3RlZCBkYXRhVHlwZTogQXZhaWxhYmxlRGF0YVR5cGVzO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIE1lYXN1cmUgd2l0aCAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QgTWV0aG9kIHRvIGNhbGN1bGF0ZSBkaXN0YW5jZSBiZXR3ZWVuIHN0cmluZ3MuXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgY29uc3RydWN0b3IobWV0aG9kOiBLbm93bk1ldHJpY3MpIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgICB0aGlzLmRhdGFUeXBlID0gTWV0cmljVG9EYXRhVHlwZVttZXRob2RdIGFzIEF2YWlsYWJsZURhdGFUeXBlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGN1c3RvbSBzdHJpbmcgZGlzdGFuY2UgZnVuY3Rpb24gc3BlY2lmaWVkLlxuICAgKiBAcGFyYW0ge29wdHN9IG9wdHMgT3B0aW9ucyBmb3IgdGhlIG1lYXN1cmUuIHVzZWQgZm9yIG1hY3JvbW9sZWN1bGUgZGlzdGFuY2VzXG4gICAqIEByZXR1cm4ge0Rpc3RhbmNlTWV0cmljfSBDYWxsYmFjayBvZiB0aGUgbWVhc3VyZSBjaG9zZW4uXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgcHVibGljIGdldE1lYXN1cmUob3B0cz86IGFueSk6IERpc3RhbmNlTWV0cmljIHtcbiAgICBjb25zdCBkaWN0OiB7IFtrZXk6IHN0cmluZ106XG4gICAgICB7W2tleTI6IHN0cmluZ106IERpc3RhbmNlTWV0cmljIHwgKChvcHRzOiBhbnkpID0+IERpc3RhbmNlTWV0cmljKX1cbiAgICB9ID0gQXZhaWxhYmxlTWV0cmljcztcbiAgICBpZiAoIWRpY3QuaGFzT3duUHJvcGVydHkodGhpcy5kYXRhVHlwZSkgfHwgIWRpY3RbdGhpcy5kYXRhVHlwZV0uaGFzT3duUHJvcGVydHkodGhpcy5tZXRob2QpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIG1lYXN1cmUgJHt0aGlzLm1ldGhvZH0gZm9yIGRhdGEgdHlwZSAke3RoaXMuZGF0YVR5cGV9YCk7XG4gICAgcmV0dXJuIGlzTWFjcm9Nb2xlY3VsZU1ldHJpYyh0aGlzLm1ldGhvZCkgP1xuICAgICAgKGRpY3RbdGhpcy5kYXRhVHlwZV1bdGhpcy5tZXRob2RdIGFzICgob3B0czogYW55KSA9PiBEaXN0YW5jZU1ldHJpYykpKG9wdHMpIDpcbiAgICAgIGRpY3RbdGhpcy5kYXRhVHlwZV1bdGhpcy5tZXRob2RdIGFzIERpc3RhbmNlTWV0cmljO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgY3VzdG9tIHN0cmluZyBkaXN0YW5jZSBieSB0aGUgZ2l2ZW4gZGF0YSB0eXBlLlxuICAgKiBAcGFyYW0ge0F2YWlsYWJsZURhdGFUeXBlc30gZGF0YVR5cGUgTWV0cmljJ3MgZGF0YSB0eXBlXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBNZXRyaWMgbmFtZXMgd2hpY2ggZXhwZWN0cyB0aGUgZ2l2ZW4gZGF0YSB0eXBlXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBnZXRNZXRyaWNCeURhdGFUeXBlKGRhdGFUeXBlOiBBdmFpbGFibGVEYXRhVHlwZXMpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3NbZGF0YVR5cGVdKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIG1ldHJpYyBuYW1lcyBhdmFpbGFibGUuXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgc3RhdGljIGdldCBhdmFpbGFibGVNZWFzdXJlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3MpO1xuICB9XG59XG4iXX0=","/**\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 (let item of vec) {\n result += item ** 2;\n }\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 }\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 }\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 }\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 }\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 }\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFJSDs7R0FFRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsQ0FBUyxFQUFFLE1BQWdCO0lBQ3BELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLE1BQWdCO0lBQ3RDLE9BQU8sTUFBTSxFQUFFLENBQUM7QUFDbEIsQ0FBQztBQUNEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FBQyxHQUFhO0lBQ2hDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNmLEtBQUssSUFBSSxJQUFJLElBQUksR0FBRyxFQUFFO1FBQ3BCLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDO0tBQ3JCO0lBQ0QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzNCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxLQUFLLENBQUMsQ0FBUztJQUM3QixNQUFNLE1BQU0sR0FBZ0IsRUFBRSxDQUFDO0lBQy9CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDMUIsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUN4QjtJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxLQUFLLENBQUMsQ0FBUztJQUM3QixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FB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QUMsQ0FBQztTQUNaO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNmLEtBQUssSUFBSSxDQUFDLENBQUM7S0FDWjtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCB7IFJhbmRvbUZuIH0gZnJvbSAnLi91bWFwJztcblxuLyoqXG4gKiBTaW1wbGUgcmFuZG9tIGludGVnZXIgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRhdVJhbmRJbnQobjogbnVtYmVyLCByYW5kb206IFJhbmRvbUZuKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKHJhbmRvbSgpICogbik7XG59XG5cbi8qKlxuICogU2ltcGxlIHJhbmRvbSBmbG9hdCBmdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdGF1UmFuZChyYW5kb206IFJhbmRvbUZuKSB7XG4gIHJldHVybiByYW5kb20oKTtcbn1cbi8qKlxuICogQ29tcHV0ZSB0aGUgKHN0YW5kYXJkIGwyKSBub3JtIG9mIGEgdmVjdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybSh2ZWM6IG51bWJlcltdKSB7XG4gIGxldCByZXN1bHQgPSAwO1xuICBmb3IgKGxldCBpdGVtIG9mIHZlYykge1xuICAgIHJlc3VsdCArPSBpdGVtICoqIDI7XG4gIH1cbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4gZW1wdHkgYXJyYXkgKGZpbGxlZCB3aXRoIHVuZGVmaW5lZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtcHR5KG46IG51bWJlcik6IHVuZGVmaW5lZFtdIHtcbiAgY29uc3Qgb3V0cHV0OiB1bmRlZmluZWRbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgIG91dHB1dC5wdXNoKHVuZGVmaW5lZCk7XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGluZGV4IHZhbHVlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2UobjogbnVtYmVyKTogbnVtYmVyW10ge1xuICByZXR1cm4gZW1wdHkobikubWFwKChfLCBpKSA9PiBpKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGEgc3BlY2lmaWMgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGxlZChuOiBudW1iZXIsIHY6IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGVtcHR5KG4pLm1hcCgoKSA9PiB2KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIHplcm9zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvcyhuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBmaWxsZWQobiwgMCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBmaWxsZWQgd2l0aCBvbmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVzKG46IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGZpbGxlZChuLCAxKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZyb20gYSB0byBiLCBvZiBsZW5ndGggbGVuLCBpbmNsdXNpdmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhcihhOiBudW1iZXIsIGI6IG51bWJlciwgbGVuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBlbXB0eShsZW4pLm1hcCgoXywgaSkgPT4ge1xuICAgIHJldHVybiBhICsgaSAqICgoYiAtIGEpIC8gKGxlbiAtIDEpKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3VtIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdW0oaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgcmV0dXJuIGlucHV0LnJlZHVjZSgoc3VtLCB2YWwpID0+IHN1bSArIHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWVhbiBvZiBhbiBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVhbihpbnB1dDogbnVtYmVyW10pOiBudW1iZXIge1xuICByZXR1cm4gc3VtKGlucHV0KSAvIGlucHV0Lmxlbmd0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgoaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgbGV0IG1heCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICBtYXggPSBpbnB1dFtpXSA+IG1heCA/IGlucHV0W2ldIDogbWF4O1xuICB9XG4gIHJldHVybiBtYXg7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZSBvZiBhIDJkIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgyZChpbnB1dDogbnVtYmVyW11bXSk6IG51bWJlciB7XG4gIGxldCBtYXggPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dFtpXS5sZW5ndGg7IGorKykge1xuICAgICAgbWF4ID0gaW5wdXRbaV1bal0gPiBtYXggPyBpbnB1dFtpXVtqXSA6IG1heDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1heDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBuU2FtcGxlcyBtYW55IGludGVnZXJzIGZyb20gMCB0byBwb29sU2l6ZSBzdWNoIHRoYXQgbm9cbiAqIGludGVnZXIgaXMgc2VsZWN0ZWQgdHdpY2UuIFRoZSBkdXBsaWNhdGlvbiBjb25zdHJhaW50IGlzIGFjaGlldmVkIHZpYVxuICogcmVqZWN0aW9uIHNhbXBsaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVqZWN0aW9uU2FtcGxlKFxuICBuU2FtcGxlczogbnVtYmVyLFxuICBwb29sU2l6ZTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBudW1iZXJbXSB7XG4gIGNvbnN0IHJlc3VsdCA9IHplcm9zKG5TYW1wbGVzKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuU2FtcGxlczsgaSsrKSB7XG4gICAgbGV0IHJlamVjdFNhbXBsZSA9IHRydWU7XG4gICAgd2hpbGUgKHJlamVjdFNhbXBsZSkge1xuICAgICAgY29uc3QgaiA9IHRhdVJhbmRJbnQocG9vbFNpemUsIHJhbmRvbSk7XG4gICAgICBsZXQgYnJva2VuID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykge1xuICAgICAgICBpZiAoaiA9PT0gcmVzdWx0W2tdKSB7XG4gICAgICAgICAgYnJva2VuID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFicm9rZW4pIHtcbiAgICAgICAgcmVqZWN0U2FtcGxlID0gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXN1bHRbaV0gPSBqO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJlc2hhcGVzIGEgMWQgYXJyYXkgaW50byBhIDJEIG9mIGdpdmVuIGRpbWVuc2lvbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNoYXBlMmQ8VD4oeDogVFtdLCBhOiBudW1iZXIsIGI6IG51bWJlcik6IFRbXVtdIHtcbiAgY29uc3Qgcm93czogVFtdW10gPSBbXTtcbiAgbGV0IGNvdW50ID0gMDtcbiAgbGV0IGluZGV4ID0gMDtcblxuICBpZiAoeC5sZW5ndGggIT09IGEgKiBiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBkaW1lbnNpb25zIG11c3QgbWF0Y2ggaW5wdXQgbGVuZ3RoLicpO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhOyBpKyspIHtcbiAgICBjb25zdCBjb2w6IFRbXSA9IFtdO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgYjsgaisrKSB7XG4gICAgICBjb2wucHVzaCh4W2luZGV4XSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cbiAgICByb3dzLnB1c2goY29sKTtcbiAgICBjb3VudCArPSAxO1xuICB9XG4gIHJldHVybiByb3dzO1xufVxuIl19","/**\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 }\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 }\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 }\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 }\n else {\n break;\n }\n }\n else if (weights[ic1] >= weights[ic2]) {\n if (weight < weights[ic1]) {\n iSwap = ic1;\n }\n else {\n break;\n }\n }\n else {\n if (weight < weights[ic2]) {\n iSwap = ic2;\n }\n else {\n break;\n }\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 }\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 }\n if (rightChild < ceiling && heap1[swap] < heap1[rightChild]) {\n swap = rightChild;\n }\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhlYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBMkNILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsT0FBZSxFQUFFLElBQVk7SUFDcEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxTQUFpQixFQUFFLEVBQUU7UUFDdkMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDbkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztJQUVGLE1BQU0sSUFBSSxHQUFTLEVBQUUsQ0FBQztJQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUM3QixRQUFnQixFQUNoQixRQUFnQixFQUNoQixNQUFnQjtJQUVoQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDakMsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMs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SSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUxQixJQUFJLE9BQU8sR0FBRyxRQUFRLENBQUM7SUFDdkIsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDbkMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUU7WUFDdEMsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsQixXQUFXLEdBQUcsQ0FBQyxDQUFDO1NBQ2pCO0tBQ0Y7SUFFRCxJQUFJLFdBQVcsSUFBSSxDQUFDLEVBQUU7UUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN0QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7S0FDckM7U0FBTTtRQUNMLE9BQU8sQ0FBQyxDQUFDLENBQUM7S0FDWDtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgeyBSYW5kb21GbiB9IGZyb20gJy4vdW1hcCc7XG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IHR5cGUgSGVhcCA9IG51bWJlcltdW11bXTtcblxuLyoqXG4gKiAgQ29uc3RydWN0b3IgZm9yIHRoZSBoZWFwIG9iamVjdHMuIFRoZSBoZWFwcyBhcmUgdXNlZFxuICogZm9yIGFwcHJveGltYXRlIG5lYXJlc3QgbmVpZ2hib3Igc2VhcmNoLCBtYWludGFpbmluZyBhIGxpc3Qgb2YgcG90ZW50aWFsXG4gKiBuZWlnaGJvcnMgc29ydGVkIGJ5IHRoZWlyIGRpc3RhbmNlLiBXZSBhbHNvIGZsYWcgaWYgcG90ZW50aWFsIG5laWdoYm9yc1xuICogYXJlIG5ld2x5IGFkZGVkIHRvIHRoZSBsaXN0IG9yIG5vdC4gSW50ZXJuYWxseSB0aGlzIGlzIHN0b3JlZCBhc1xuICogYSBzaW5nbGUgYXJyYXk7IHRoZSBmaXJzdCBheGlzIGRldGVybWluZXMgd2hldGhlciB3ZSBhcmUgbG9va2luZyBhdCB0aGVcbiAqIGFycmF5IG9mIGNhbmRpZGF0ZSBpbmRpY2VzLCB0aGUgYXJyYXkgb2YgZGlzdGFuY2VzLCBvciB0aGUgZmxhZyBhcnJheSBmb3JcbiAqIHdoZXRoZXIgZWxlbWVudHMgYXJlIG5ldyBvciBub3QuIEVhY2ggb2YgdGhlc2UgYXJyYXlzIGFyZSBvZiBzaGFwZVxuICogKGBgblBvaW50c2BgLCBgYHNpemVgYClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VIZWFwKG5Qb2ludHM6IG51bWJlciwgc2l6ZTogbnVtYmVyKTogSGVhcCB7XG4gIGNvbnN0IG1ha2VBcnJheXMgPSAoZmlsbFZhbHVlOiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gdXRpbHMuZW1wdHkoblBvaW50cykubWFwKCgpID0+IHtcbiAgICAgIHJldHVybiB1dGlscy5maWxsZWQoc2l6ZSwgZmlsbFZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBoZWFwOiBIZWFwID0gW107XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKC0xKSk7XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKEluZmluaXR5KSk7XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKDApKTtcbiAgcmV0dXJuIGhlYXA7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgbl9zYW1wbGVzIG1hbnkgaW50ZWdlcnMgZnJvbSAwIHRvIHBvb2xfc2l6ZSBzdWNoIHRoYXQgbm9cbiAqIGludGVnZXIgaXMgc2VsZWN0ZWQgdHdpY2UuIFRoZSBkdXBsaWNhdGlvbiBjb25zdHJhaW50IGlzIGFjaGlldmVkIHZpYVxuICogcmVqZWN0aW9uIHNhbXBsaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVqZWN0aW9uU2FtcGxlKFxuICBuU2FtcGxlczogbnVtYmVyLFxuICBwb29sU2l6ZTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgY29uc3QgcmVzdWx0ID0gdXRpbHMuemVyb3MoblNhbXBsZXMpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHtcbiAgICBsZXQgcmVqZWN0U2FtcGxlID0gdHJ1ZTtcbiAgICBsZXQgaiA9IDA7XG4gICAgd2hpbGUgKHJlamVjdFNhbXBsZSkge1xuICAgICAgaiA9IHV0aWxzLnRhdVJhbmRJbnQocG9vbFNpemUsIHJhbmRvbSk7XG4gICAgICBsZXQgYnJva2VuID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykge1xuICAgICAgICBpZiAoaiA9PT0gcmVzdWx0W2tdKSB7XG4gICAgICAgICAgYnJva2VuID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFicm9rZW4pIHJlamVjdFNhbXBsZSA9IGZhbHNlO1xuICAgIH1cbiAgICByZXN1bHRbaV0gPSBqO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUHVzaCBhIG5ldyBlbGVtZW50IG9udG8gdGhlIGhlYXAuIFRoZSBoZWFwIHN0b3JlcyBwb3RlbnRpYWwgbmVpZ2hib3JzXG4gKiBmb3IgZWFjaCBkYXRhIHBvaW50LiBUaGUgYGByb3dgYCBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB3aGljaCBkYXRhIHBvaW50IHdlXG4gKiBhcmUgYWRkcmVzc2luZywgdGhlIGBgd2VpZ2h0YGAgZGV0ZXJtaW5lcyB0aGUgZGlzdGFuY2UgKGZvciBoZWFwIHNvcnRpbmcpLFxuICogdGhlIGBgaW5kZXhgYCBpcyB0aGUgZWxlbWVudCB0byBhZGQsIGFuZCB0aGUgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhpc1xuICogaXMgdG8gYmUgY29uc2lkZXJlZCBhIG5ldyBhZGRpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhlYXBQdXNoKFxuICBoZWFwOiBIZWFwLFxuICByb3c6IG51bWJlcixcbiAgd2VpZ2h0OiBudW1iZXIsXG4gIGluZGV4OiBudW1iZXIsXG4gIGZsYWc6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgcm93ID0gTWF0aC5mbG9vcihyb3cpO1xuICBjb25zdCBpbmRpY2VzID0gaGVhcFswXVtyb3ddO1xuICBjb25zdCB3ZWlnaHRzID0gaGVhcFsxXVtyb3ddO1xuICBjb25zdCBpc05ldyA9IGhlYXBbMl1bcm93XTtcblxuICBpZiAod2VpZ2h0ID49IHdlaWdodHNbMF0pIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8vIEJyZWFrIGlmIHdlIGFscmVhZHkgaGF2ZSB0aGlzIGVsZW1lbnQuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpbmRleCA9PT0gaW5kaWNlc1tpXSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuY2hlY2tlZEhlYXBQdXNoKGhlYXAsIHJvdywgd2VpZ2h0LCBpbmRleCwgZmxhZyk7XG59XG5cbi8qKlxuICogUHVzaCBhIG5ldyBlbGVtZW50IG9udG8gdGhlIGhlYXAuIFRoZSBoZWFwIHN0b3JlcyBwb3RlbnRpYWwgbmVpZ2hib3JzXG4gKiBmb3IgZWFjaCBkYXRhIHBvaW50LiBUaGUgYGByb3dgYCBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB3aGljaCBkYXRhIHBvaW50IHdlXG4gKiBhcmUgYWRkcmVzc2luZywgdGhlIGBgd2VpZ2h0YGAgZGV0ZXJtaW5lcyB0aGUgZGlzdGFuY2UgKGZvciBoZWFwIHNvcnRpbmcpLFxuICogdGhlIGBgaW5kZXhgYCBpcyB0aGUgZWxlbWVudCB0byBhZGQsIGFuZCB0aGUgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhpc1xuICogaXMgdG8gYmUgY29uc2lkZXJlZCBhIG5ldyBhZGRpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuY2hlY2tlZEhlYXBQdXNoKFxuICBoZWFwOiBIZWFwLFxuICByb3c6IG51bWJlcixcbiAgd2VpZ2h0OiBudW1iZXIsXG4gIGluZGV4OiBudW1iZXIsXG4gIGZsYWc6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgY29uc3QgaW5kaWNlcyA9IGhlYXBbMF1bcm93XTtcbiAgY29uc3Qgd2VpZ2h0cyA9IGhlYXBbMV1bcm93XTtcbiAgY29uc3QgaXNOZXcgPSBoZWFwWzJdW3Jvd107XG5cbiAgaWYgKHdlaWdodCA+PSB3ZWlnaHRzWzBdKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvLyBJbnNlcnQgdmFsIGF0IHBvc2l0aW9uIHplcm9cbiAgd2VpZ2h0c1swXSA9IHdlaWdodDtcbiAgaW5kaWNlc1swXSA9IGluZGV4O1xuICBpc05ld1swXSA9IGZsYWc7XG5cbiAgLy8gRGVzY2VuZCB0aGUgaGVhcCwgc3dhcHBpbmcgdmFsdWVzIHVudGlsIHRoZSBtYXggaGVhcCBjcml0ZXJpb24gaXMgbWV0XG4gIGxldCBpID0gMDtcbiAgbGV0IGlTd2FwID0gMDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCBpYzEgPSAyICogaSArIDE7XG4gICAgY29uc3QgaWMyID0gaWMxICsgMTtcblxuICAgIGNvbnN0IGhlYXBTaGFwZTIgPSBoZWFwWzBdWzBdLmxlbmd0aDtcbiAgICBpZiAoaWMxID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoaWMyID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGlmICh3ZWlnaHRzW2ljMV0gPiB3ZWlnaHQpIHtcbiAgICAgICAgaVN3YXAgPSBpYzE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHdlaWdodHNbaWMxXSA+PSB3ZWlnaHRzW2ljMl0pIHtcbiAgICAgIGlmICh3ZWlnaHQgPCB3ZWlnaHRzW2ljMV0pIHtcbiAgICAgICAgaVN3YXAgPSBpYzE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHdlaWdodCA8IHdlaWdodHNbaWMyXSkge1xuICAgICAgICBpU3dhcCA9IGljMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdlaWdodHNbaV0gPSB3ZWlnaHRzW2lTd2FwXTtcbiAgICBpbmRpY2VzW2ldID0gaW5kaWNlc1tpU3dhcF07XG4gICAgaXNOZXdbaV0gPSBpc05ld1tpU3dhcF07XG5cbiAgICBpID0gaVN3YXA7XG4gIH1cblxuICB3ZWlnaHRzW2ldID0gd2VpZ2h0O1xuICBpbmRpY2VzW2ldID0gaW5kZXg7XG4gIGlzTmV3W2ldID0gZmxhZztcbiAgcmV0dXJuIDE7XG59XG5cbi8qKlxuICogQnVpbGQgYSBoZWFwIG9mIGNhbmRpZGF0ZSBuZWlnaGJvcnMgZm9yIG5lYXJlc3QgbmVpZ2hib3IgZGVzY2VudC4gRm9yXG4gKiBlYWNoIHZlcnRleCB0aGUgY2FuZGlkYXRlIG5laWdoYm9ycyBhcmUgYW55IGN1cnJlbnQgbmVpZ2hib3JzLCBhbmQgYW55XG4gKiB2ZXJ0aWNlcyB0aGF0IGhhdmUgdGhlIHZlcnRleCBhcyBvbmUgb2YgdGhlaXIgbmVhcmVzdCBuZWlnaGJvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENhbmRpZGF0ZXMoXG4gIGN1cnJlbnRHcmFwaDogSGVhcCxcbiAgblZlcnRpY2VzOiBudW1iZXIsXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgbWF4Q2FuZGlkYXRlczogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgY29uc3QgY2FuZGlkYXRlTmVpZ2hib3JzID0gbWFrZUhlYXAoblZlcnRpY2VzLCBtYXhDYW5kaWRhdGVzKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuVmVydGljZXM7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICBpZiAoY3VycmVudEdyYXBoWzBdW2ldW2pdIDwgMCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGlkeCA9IGN1cnJlbnRHcmFwaFswXVtpXVtqXTtcbiAgICAgIGNvbnN0IGlzbiA9IGN1cnJlbnRHcmFwaFsyXVtpXVtqXTtcbiAgICAgIGNvbnN0IGQgPSB1dGlscy50YXVSYW5kKHJhbmRvbSk7XG4gICAgICBoZWFwUHVzaChjYW5kaWRhdGVOZWlnaGJvcnMsIGksIGQsIGlkeCwgaXNuKTtcbiAgICAgIGhlYXBQdXNoKGNhbmRpZGF0ZU5laWdoYm9ycywgaWR4LCBkLCBpLCBpc24pO1xuICAgICAgY3VycmVudEdyYXBoWzJdW2ldW2pdID0gMDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNhbmRpZGF0ZU5laWdoYm9ycztcbn1cblxuLyoqXG4gKiBHaXZlbiBhbiBhcnJheSBvZiBoZWFwcyAob2YgaW5kaWNlcyBhbmQgd2VpZ2h0cyksIHVucGFjayB0aGUgaGVhcFxuICogb3V0IHRvIGdpdmUgYW5kIGFycmF5IG9mIHNvcnRlZCBsaXN0cyBvZiBpbmRpY2VzIGFuZCB3ZWlnaHRzIGJ5IGluY3JlYXNpbmdcbiAqIHdlaWdodC4gVGhpcyBpcyBlZmZlY3RpdmVseSBqdXN0IHRoZSBzZWNvbmQgaGFsZiBvZiBoZWFwIHNvcnQgKHRoZSBmaXJzdFxuICogaGFsZiBub3QgYmVpbmcgcmVxdWlyZWQgc2luY2Ugd2UgYWxyZWFkeSBoYXZlIHRoZSBkYXRhIGluIGEgaGVhcCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWhlYXBTb3J0KGhlYXA6IEhlYXApIHtcbiAgY29uc3QgaW5kaWNlcyA9IGhlYXBbMF07XG4gIGNvbnN0IHdlaWdodHMgPSBoZWFwWzFdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGluZEhlYXAgPSBpbmRpY2VzW2ldO1xuICAgIGNvbnN0IGRpc3RIZWFwID0gd2VpZ2h0c1tpXTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kSGVhcC5sZW5ndGggLSAxOyBqKyspIHtcbiAgICAgIGNvbnN0IGluZEhlYXBJbmRleCA9IGluZEhlYXAubGVuZ3RoIC0gaiAtIDE7XG4gICAgICBjb25zdCBkaXN0SGVhcEluZGV4ID0gZGlzdEhlYXAubGVuZ3RoIC0gaiAtIDE7XG5cbiAgICAgIGNvbnN0IHRlbXAxID0gaW5kSGVhcFswXTtcbiAgICAgIGluZEhlYXBbMF0gPSBpbmRIZWFwW2luZEhlYXBJbmRleF07XG4gICAgICBpbmRIZWFwW2luZEhlYXBJbmRleF0gPSB0ZW1wMTtcblxuICAgICAgY29uc3QgdGVtcDIgPSBkaXN0SGVhcFswXTtcbiAgICAgIGRpc3RIZWFwWzBdID0gZGlzdEhlYXBbZGlzdEhlYXBJbmRleF07XG4gICAgICBkaXN0SGVhcFtkaXN0SGVhcEluZGV4XSA9IHRlbXAyO1xuXG4gICAgICBzaWZ0RG93bihkaXN0SGVhcCwgaW5kSGVhcCwgZGlzdEhlYXBJbmRleCwgMCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IGluZGljZXMsIHdlaWdodHMgfTtcbn1cblxuLyoqXG4gKiBSZXN0b3JlIHRoZSBoZWFwIHByb3BlcnR5IGZvciBhIGhlYXAgd2l0aCBhbiBvdXQgb2YgcGxhY2UgZWxlbWVudFxuICogYXQgcG9zaXRpb24gYGBlbHRgYC4gVGhpcyB3b3JrcyB3aXRoIGEgaGVhcCBwYWlyIHdoZXJlIGhlYXAxIGNhcnJpZXNcbiAqIHRoZSB3ZWlnaHRzIGFuZCBoZWFwMiBob2xkcyB0aGUgY29ycmVzcG9uZGluZyBlbGVtZW50cy5cbiAqL1xuZnVuY3Rpb24gc2lmdERvd24oXG4gIGhlYXAxOiBudW1iZXJbXSxcbiAgaGVhcDI6IG51bWJlcltdLFxuICBjZWlsaW5nOiBudW1iZXIsXG4gIGVsdDogbnVtYmVyXG4pIHtcbiAgd2hpbGUgKGVsdCAqIDIgKyAxIDwgY2VpbGluZykge1xuICAgIGNvbnN0IGxlZnRDaGlsZCA9IGVsdCAqIDIgKyAxO1xuICAgIGNvbnN0IHJpZ2h0Q2hpbGQgPSBsZWZ0Q2hpbGQgKyAxO1xuICAgIGxldCBzd2FwID0gZWx0O1xuXG4gICAgaWYgKGhlYXAxW3N3YXBdIDwgaGVhcDFbbGVmdENoaWxkXSkge1xuICAgICAgc3dhcCA9IGxlZnRDaGlsZDtcbiAgICB9XG4gICAgaWYgKHJpZ2h0Q2hpbGQgPCBjZWlsaW5nICYmIGhlYXAxW3N3YXBdIDwgaGVhcDFbcmlnaHRDaGlsZF0pIHtcbiAgICAgIHN3YXAgPSByaWdodENoaWxkO1xuICAgIH1cblxuICAgIGlmIChzd2FwID09PSBlbHQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0ZW1wMSA9IGhlYXAxW2VsdF07XG4gICAgICBoZWFwMVtlbHRdID0gaGVhcDFbc3dhcF07XG4gICAgICBoZWFwMVtzd2FwXSA9IHRlbXAxO1xuXG4gICAgICBjb25zdCB0ZW1wMiA9IGhlYXAyW2VsdF07XG4gICAgICBoZWFwMltlbHRdID0gaGVhcDJbc3dhcF07XG4gICAgICBoZWFwMltzd2FwXSA9IHRlbXAyO1xuICAgICAgZWx0ID0gc3dhcDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBTZWFyY2ggdGhlIGhlYXAgZm9yIHRoZSBzbWFsbGVzdCBlbGVtZW50IHRoYXQgaXMgc3RpbGwgZmxhZ2dlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNtYWxsZXN0RmxhZ2dlZChoZWFwOiBIZWFwLCByb3c6IG51bWJlcikge1xuICBjb25zdCBpbmQgPSBoZWFwWzBdW3Jvd107XG4gIGNvbnN0IGRpc3QgPSBoZWFwWzFdW3Jvd107XG4gIGNvbnN0IGZsYWcgPSBoZWFwWzJdW3Jvd107XG5cbiAgbGV0IG1pbkRpc3QgPSBJbmZpbml0eTtcbiAgbGV0IHJlc3VsdEluZGV4ID0gLTE7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPiBpbmQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZmxhZ1tpXSA9PT0gMSAmJiBkaXN0W2ldIDwgbWluRGlzdCkge1xuICAgICAgbWluRGlzdCA9IGRpc3RbaV07XG4gICAgICByZXN1bHRJbmRleCA9IGk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3VsdEluZGV4ID49IDApIHtcbiAgICBmbGFnW3Jlc3VsdEluZGV4XSA9IDA7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoaW5kW3Jlc3VsdEluZGV4XSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG59XG4iXX0=","/**\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 }\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 }\n else {\n this.entries.get(key).value = value;\n }\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 }\n else {\n return defaultValue;\n }\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 }\n else {\n return a.row - b.row;\n }\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 }\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 }\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 (let 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 }\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 }\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 }\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 }\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 }\n else {\n return a.row - b.row;\n }\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0cml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibWF0cml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFNdkIsWUFDRSxJQUEyQixFQUMzQixJQUEyQixFQUMzQixNQUErQixFQUMvQixJQUFjO1FBVFIsWUFBTyxHQUFHLElBQUksR0FBRyxFQUFpQixDQUFDO1FBRWxDLFVBQUssR0FBVyxDQUFDLENBQUM7UUFDbEIsVUFBSyxHQUFXLENBQUMsQ0FBQztRQVF6QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDaEUsTUFBTSxJQUFJLEtBQUssQ0FDYiw0REFBNEQsQ0FDN0QsQ0FBQztTQUNIO1FBRUQsb0NBQW9DO1FBQ3BDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3RDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxH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LElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdELDJDQUEyQztJQUM1QyxDQUFDO0lBRUQsT0FBTztRQUNOLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3RCwyQ0FBMkM7SUFDNUMsQ0FBQztJQUVELFNBQVM7UUFDVCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0QsNENBQTRDO0lBQzVDLENBQUM7SUFFRCxPQUFPLENBQUMsRUFBcUQ7UUFDM0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxHQUFHLENBQUMsRUFBdUQ7UUFDekQsTUFBTSxJQUFJLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDVCxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUMzQixJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztRQUNI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QUVILE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUM3QixNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFDNUIsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO0lBRTVCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3BCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3ZDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxJQUFJLEdBQUcsS0FBSyxVQUFVLEVBQUU7WUFDdEIsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2hCO1FBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3BCO0lBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDckMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG50eXBlIEVudHJ5ID0geyB2YWx1ZTogbnVtYmVyOyByb3c6IG51bWJlcjsgY29sOiBudW1iZXIgfTtcblxuLyoqXG4gKiBJbnRlcm5hbCAyLWRpbWVuc2lvbmFsIHNwYXJzZSBtYXRyaXggY2xhc3NcbiAqL1xuZXhwb3J0IGNsYXNzIFNwYXJzZU1hdHJpeCB7XG4gIHByaXZhdGUgZW50cmllcyA9IG5ldyBNYXA8c3RyaW5nLCBFbnRyeT4oKTtcblxuICByZWFkb25seSBuUm93czogbnVtYmVyID0gMDtcbiAgcmVhZG9ubHkgbkNvbHM6IG51bWJlciA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcm93czogbnVtYmVyW10gfCBJbnQzMkFycmF5LFxuICAgIGNvbHM6IG51bWJlcltdIHwgSW50MzJBcnJheSxcbiAgICB2YWx1ZXM6IG51bWJlcltdIHwgRmxvYXQzMkFycmF5LFxuICAgIGRpbXM6IG51bWJlcltdXG4gICkge1xuICAgIGlmIChyb3dzLmxlbmd0aCAhPT0gY29scy5sZW5ndGggfHwgcm93cy5sZW5ndGggIT09IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ3Jvd3MsIGNvbHMgYW5kIHZhbHVlcyBhcnJheXMgbXVzdCBhbGwgaGF2ZSB0aGUgc2FtZSBsZW5ndGgnXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFRPRE86IEFzc2VydCB0aGF0IGRpbXMgYXJlIGxlZ2l0LlxuICAgIHRoaXMublJvd3MgPSBkaW1zWzBdO1xuICAgIHRoaXMubkNvbHMgPSBkaW1zWzFdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByb3cgPSByb3dzW2ldO1xuICAgICAgY29uc3QgY29sID0gY29sc1tpXTtcbiAgICAgIHRoaXMuY2hlY2tEaW1zKHJvdywgY29sKTtcbiAgICAgIGNvbnN0IGtleSA9IHRoaXMubWFrZUtleShyb3csIGNvbCk7XG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwgeyB2YWx1ZTogdmFsdWVzW2ldLCByb3csIGNvbCB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1ha2VLZXkocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7cm93fToke2NvbH1gO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0RpbXMocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKSB7XG4gICAgY29uc3Qgd2l0aGluQm91bmRzID0gcm93IDwgdGhpcy5uUm93cyAmJiBjb2wgPCB0aGlzLm5Db2xzO1xuICAgIGlmICghd2l0aGluQm91bmRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3JvdyBhbmQvb3IgY29sIHNwZWNpZmllZCBvdXRzaWRlIG9mIG1hdHJpeCBkaW1lbnNpb25zJyk7XG4gICAgfVxuICB9XG5cbiAgc2V0KHJvdzogbnVtYmVyLCBjb2w6IG51bWJlciwgdmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuY2hlY2tEaW1zKHJvdywgY29sKTtcbiAgICBjb25zdCBrZXkgPSB0aGlzLm1ha2VLZXkocm93LCBjb2wpO1xuICAgIGlmICghdGhpcy5lbnRyaWVzLmhhcyhrZXkpKSB7XG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwgeyB2YWx1ZSwgcm93LCBjb2wgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW50cmllcy5nZXQoa2V5KSEudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICBnZXQocm93OiBudW1iZXIsIGNvbDogbnVtYmVyLCBkZWZhdWx0VmFsdWUgPSAwKSB7XG4gICAgLy90aGlzLmNoZWNrRGltcyhyb3csIGNvbCk7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5tYWtlS2V5KHJvdywgY29sKTtcbiAgICBpZiAodGhpcy5lbnRyaWVzLmhhcyhrZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbnRyaWVzLmdldChrZXkpIS52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG4gIH1cblxuICBnZXRBbGwob3JkZXJlZCA9IHRydWUpOiB7IHZhbHVlOiBudW1iZXI7IHJvdzogbnVtYmVyOyBjb2w6IG51bWJlciB9W10ge1xuICAgIGNvbnN0IHJvd0NvbFZhbHVlczogRW50cnlbXSA9IG5ldyBBcnJheSh0aGlzLmVudHJpZXMuc2l6ZSkuZmlsbChudWxsKTtcbiAgICBsZXQgaSA9IDA7XG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgcm93Q29sVmFsdWVzW2krK10gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICBpZiAob3JkZXJlZCkge1xuICAgICAgLy8gT3JkZXJpbmcgdGhlIHJlc3VsdCBpc24ndCByZXF1aXJlZCBmb3IgcHJvY2Vzc2luZyBidXQgaXQgZG9lcyBtYWtlIGl0IGVhc2llciB0byB3cml0ZSB0ZXN0c1xuICAgICAgcm93Q29sVmFsdWVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgaWYgKGEucm93ID09PSBiLnJvdykge1xuICAgICAgICAgIHJldHVybiBhLmNvbCAtIGIuY29sO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBhLnJvdyAtIGIucm93O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJvd0NvbFZhbHVlcztcbiAgfVxuXG4gIGdldERpbXMoKTogbnVtYmVyW10ge1xuICAgIHJldHVybiBbdGhpcy5uUm93cywgdGhpcy5uQ29sc107XG4gIH1cblxuICBnZXRSb3dzKCk6IG51bWJlcltdIHtcbiAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuZW50cmllcywgKFtrZXksIHZhbHVlXSkgPT4gdmFsdWUucm93KTtcbiAgIC8vIHJldHVybiB0aGlzLnJvd3MgYXMgdW5rbm93biBhcyBudW1iZXJbXTtcbiAgfVxuXG4gIGdldENvbHMoKTogbnVtYmVyW117XG4gICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMsIChba2V5LCB2YWx1ZV0pID0+IHZhbHVlLmNvbCk7XG4gICAvLyByZXR1cm4gdGhpcy5jb2xzIGFzIHVua25vd24gYXMgbnVtYmVyW107XG4gIH1cblxuICBnZXRWYWx1ZXMoKTogbnVtYmVyW10ge1xuICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMsIChba2V5LCB2YWx1ZV0pID0+IHZhbHVlLnZhbHVlKTtcbiAgLy9yZXR1cm4gdGhpcy52YWx1ZXMgYXMgdW5rbm93biBhcyBudW1iZXJbXTtcbiAgfVxuXG4gIGZvckVhY2goZm46ICh2YWx1ZTogbnVtYmVyLCByb3c6IG51bWJlciwgY29sOiBudW1iZXIpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCh2YWx1ZSA9PiBmbih2YWx1ZS52YWx1ZSwgdmFsdWUucm93LCB2YWx1ZS5jb2wpKTtcbiAgfVxuXG4gIG1hcChmbjogKHZhbHVlOiBudW1iZXIsIHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcikgPT4gbnVtYmVyKTogU3BhcnNlTWF0cml4IHtcbiAgICBjb25zdCB2YWxzID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmVudHJpZXMuc2l6ZSk7XG4gICAgbGV0IGkgPSAwXG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgdmFsc1tpKytdID0gZm4odmFsdWUudmFsdWUsIHZhbHVlLnJvdywgdmFsdWUuY29sKTtcbiAgICB9KTtcbiAgICBjb25zdCBkaW1zID0gW3RoaXMublJvd3MsIHRoaXMubkNvbHNdO1xuICAgIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHRoaXMuZ2V0Um93cygpLCB0aGlzLmdldENvbHMoKSwgdmFscyBhcyB1bmtub3duIGFzIG51bWJlcltdLCBkaW1zKTtcbiAgfVxuXG4gIHRvQXJyYXkoKSB7XG4gICAgY29uc3Qgcm93czogdW5kZWZpbmVkW10gPSB1dGlscy5lbXB0eSh0aGlzLm5Sb3dzKTtcbiAgICBjb25zdCBvdXRwdXQgPSByb3dzLm1hcCgoKSA9PiB7XG4gICAgICByZXR1cm4gdXRpbHMuemVyb3ModGhpcy5uQ29scyk7XG4gICAgfSk7XG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgb3V0cHV0W3ZhbHVlLnJvd11bdmFsdWUuY29sXSA9IHZhbHVlLnZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn1cblxuLyoqXG4gKiBUcmFuc3Bvc2UgYSBzcGFyc2UgbWF0cml4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2UobWF0cml4OiBTcGFyc2VNYXRyaXgpOiBTcGFyc2VNYXRyaXgge1xuICBjb25zdCBvbGRSb3dzID0gbWF0cml4LmdldFJvd3MoKTtcbiAgY29uc3Qgb2xkQ29scyA9IG1hdHJpeC5nZXRDb2xzKCk7XG4gIGNvbnN0IG9sZFZhbHMgPSBtYXRyaXguZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IG1hdGxlbiA9IG9sZENvbHMubGVuZ3RoO1xuICBjb25zdCBjb2xzID0gbmV3IEludDMyQXJyYXkobWF0bGVuKTtcbiAgY29uc3Qgcm93cyA9IG5ldyBJbnQzMkFycmF5KG1hdGxlbik7XG4gIGNvbnN0IHZhbHMgPSBuZXcgRmxvYXQzMkFycmF5KG1hdGxlbik7XG5cbiAgY29scy5zZXQob2xkUm93cyk7XG4gIHJvd3Muc2V0KG9sZENvbHMpO1xuICB2YWxzLnNldChvbGRWYWxzKTtcbiAgY29uc3QgZGltcyA9IFttYXRyaXgubkNvbHMsIG1hdHJpeC5uUm93c107XG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIGRpbXMpO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHNwYXJzZSBpZGVudGl0eSBtYXRyaXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KHNpemU6IG51bWJlcltdKTogU3BhcnNlTWF0cml4IHtcbiAgY29uc3QgW3Jvd3NdID0gc2l6ZTtcbiAgY29uc3QgbWF0cml4ID0gbmV3IFNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBzaXplKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHtcbiAgICBtYXRyaXguc2V0KGksIGksIDEpO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKlxuICogRWxlbWVudC13aXNlIG11bHRpcGxpY2F0aW9uIG9mIHR3byBtYXRyaWNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFpcndpc2VNdWx0aXBseShcbiAgYTogU3BhcnNlTWF0cml4LFxuICBiOiBTcGFyc2VNYXRyaXhcbik6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4geCAqIHkpO1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBhZGRpdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZChhOiBTcGFyc2VNYXRyaXgsIGI6IFNwYXJzZU1hdHJpeCk6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4geCArIHkpO1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBzdWJ0cmFjdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1YnRyYWN0KGE6IFNwYXJzZU1hdHJpeCwgYjogU3BhcnNlTWF0cml4KTogU3BhcnNlTWF0cml4IHtcbiAgcmV0dXJuIGVsZW1lbnRXaXNlKGEsIGIsICh4LCB5KSA9PiB4IC0geSk7XG59XG5cbi8qKlxuICogRWxlbWVudC13aXNlIG1heGltdW0gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXhpbXVtKGE6IFNwYXJzZU1hdHJpeCwgYjogU3BhcnNlTWF0cml4KTogU3BhcnNlTWF0cml4IHtcbiAgcmV0dXJuIGVsZW1lbnRXaXNlKGEsIGIsICh4LCB5KSA9PiAoeCA+IHkgPyB4IDogeSkpO1xufVxuXG4vKipcbiAqIFNjYWxhciBtdWx0aXBsaWNhdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5U2NhbGFyKGE6IFNwYXJzZU1hdHJpeCwgc2NhbGFyOiBudW1iZXIpOiBTcGFyc2VNYXRyaXgge1xuICByZXR1cm4gYS5tYXAoKHZhbHVlOiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gdmFsdWUgKiBzY2FsYXI7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgbWF0cml4IHdpdGggemVybyBlbnRyaWVzIHJlbW92ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbGltaW5hdGVaZXJvcyhtOiBTcGFyc2VNYXRyaXgpIHtcbiAgY29uc3QgemVyb0luZGljZXMgPSBuZXcgU2V0KCk7XG4gIGNvbnN0IHZhbHVlcyA9IG0uZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3MgPSBtLmdldFJvd3MoKTtcbiAgY29uc3QgY29scyA9IG0uZ2V0Q29scygpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh2YWx1ZXNbaV0gPT09IDApIHtcbiAgICAgIHplcm9JbmRpY2VzLmFkZChpKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgcmVtb3ZlQnlaZXJvSW5kZXggPSAoXzogYW55LCBpbmRleDogbnVtYmVyKSA9PiAhemVyb0luZGljZXMuaGFzKGluZGV4KTtcbiAgY29uc3QgbmV4dFZhbHVlcyA9IHZhbHVlcy5maWx0ZXIocmVtb3ZlQnlaZXJvSW5kZXgpO1xuICBjb25zdCBuZXh0Um93cyA9IHJvd3MuZmlsdGVyKHJlbW92ZUJ5WmVyb0luZGV4KTtcbiAgY29uc3QgbmV4dENvbHMgPSBjb2xzLmZpbHRlcihyZW1vdmVCeVplcm9JbmRleCk7XG5cbiAgcmV0dXJuIG5ldyBTcGFyc2VNYXRyaXgobmV4dFJvd3MsIG5leHRDb2xzLCBuZXh0VmFsdWVzLCBtLmdldERpbXMoKSk7XG59XG5cbi8qKlxuICogTm9ybWFsaXphdGlvbiBvZiBhIHNwYXJzZSBtYXRyaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUobTogU3BhcnNlTWF0cml4LCBub3JtVHlwZSA9IE5vcm1UeXBlLmwyKSB7XG4gIGNvbnN0IG5vcm1GbiA9IG5vcm1GbnNbbm9ybVR5cGVdO1xuXG4gIGNvbnN0IGNvbHNCeVJvdyA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXJbXT4oKTtcbiAgbS5mb3JFYWNoKChfLCByb3csIGNvbCkgPT4ge1xuICAgIGNvbnN0IGNvbHMgPSBjb2xzQnlSb3cuZ2V0KHJvdykgfHwgW107XG4gICAgY29scy5wdXNoKGNvbCk7XG4gICAgY29sc0J5Um93LnNldChyb3csIGNvbHMpO1xuICB9KTtcblxuICBjb25zdCBuZXh0TWF0cml4ID0gbmV3IFNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBtLmdldERpbXMoKSk7XG5cbiAgZm9yIChsZXQgcm93IG9mIGNvbHNCeVJvdy5rZXlzKCkpIHtcbiAgICBjb25zdCBjb2xzID0gY29sc0J5Um93LmdldChyb3cpIS5zb3J0KCk7XG5cbiAgICBjb25zdCB2YWxzID0gY29scy5tYXAoY29sID0+IG0uZ2V0KHJvdywgY29sKSk7XG4gICAgY29uc3Qgbm9ybSA9IG5vcm1Gbih2YWxzKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vcm0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIG5leHRNYXRyaXguc2V0KHJvdywgY29sc1tpXSwgbm9ybVtpXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHRNYXRyaXg7XG59XG5cbi8qKlxuICogVmVjdG9yIG5vcm1hbGl6YXRpb24gZnVuY3Rpb25zXG4gKi9cbnR5cGUgTm9ybUZucyA9IHsgW2tleSBpbiBOb3JtVHlwZV06ICh2OiBudW1iZXJbXSkgPT4gbnVtYmVyW10gfTtcbmNvbnN0IG5vcm1GbnM6IE5vcm1GbnMgPSB7XG4gIFtOb3JtVHlwZS5tYXhdOiAoeHM6IG51bWJlcltdKSA9PiB7XG4gICAgbGV0IG1heCA9IC1JbmZpbml0eTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBtYXggPSB4c1tpXSA+IG1heCA/IHhzW2ldIDogbWF4O1xuICAgIH1cbiAgICByZXR1cm4geHMubWFwKHggPT4geCAvIG1heCk7XG4gIH0sXG4gIFtOb3JtVHlwZS5sMV06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBzdW0gKz0geHNbaV07XG4gICAgfVxuICAgIHJldHVybiB4cy5tYXAoeCA9PiB4IC8gc3VtKTtcbiAgfSxcbiAgW05vcm1UeXBlLmwyXTogKHhzOiBudW1iZXJbXSkgPT4ge1xuICAgIGxldCBzdW0gPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHN1bSArPSB4c1tpXSAqKiAyO1xuICAgIH1cbiAgICByZXR1cm4geHMubWFwKHggPT4gTWF0aC5zcXJ0KHggKiogMiAvIHN1bSkpO1xuICB9LFxufTtcblxuZXhwb3J0IGNvbnN0IGVudW0gTm9ybVR5cGUge1xuICBtYXggPSAnbWF4JyxcbiAgbDEgPSAnbDEnLFxuICBsMiA9ICdsMicsXG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIGZvciBlbGVtZW50LXdpc2Ugb3BlcmF0aW9ucy5cbiAqL1xuZnVuY3Rpb24gZWxlbWVudFdpc2UoXG4gIGE6IFNwYXJzZU1hdHJpeCxcbiAgYjogU3BhcnNlTWF0cml4LFxuICBvcDogKHg6IG51bWJlciwgeTogbnVtYmVyKSA9PiBudW1iZXJcbik6IFNwYXJzZU1hdHJpeCB7XG4gIGNvbnN0IHZpc2l0ZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3Qgcm93czogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgY29sczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgdmFsczogbnVtYmVyW10gPSBbXTtcblxuICBjb25zdCBvcGVyYXRlID0gKHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcikgPT4ge1xuICAgIHJvd3MucHVzaChyb3cpO1xuICAgIGNvbHMucHVzaChjb2wpO1xuICAgIGNvbnN0IG5leHRWYWx1ZSA9IG9wKGEuZ2V0KHJvdywgY29sKSwgYi5nZXQocm93LCBjb2wpKTtcbiAgICB2YWxzLnB1c2gobmV4dFZhbHVlKTtcbiAgfTtcbiAgY29uc3QgdmFsdWVzQSA9IGEuZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3NBID0gYS5nZXRSb3dzKCk7XG4gIGNvbnN0IGNvbHNBID0gYS5nZXRDb2xzKCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzQS5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHJvdyA9IHJvd3NBW2ldO1xuICAgIGNvbnN0IGNvbCA9IGNvbHNBW2ldO1xuICAgIGNvbnN0IGtleSA9IGAke3Jvd306JHtjb2x9YDtcbiAgICB2aXNpdGVkLmFkZChrZXkpO1xuICAgIG9wZXJhdGUocm93LCBjb2wpO1xuICB9XG5cbiAgY29uc3QgdmFsdWVzQiA9IGIuZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3NCID0gYi5nZXRSb3dzKCk7XG4gIGNvbnN0IGNvbHNCID0gYi5nZXRDb2xzKCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzQi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHJvdyA9IHJvd3NCW2ldO1xuICAgIGNvbnN0IGNvbCA9IGNvbHNCW2ldO1xuICAgIGNvbnN0IGtleSA9IGAke3Jvd306JHtjb2x9YDtcbiAgICBpZiAodmlzaXRlZC5oYXMoa2V5KSkgY29udGludWU7XG4gICAgb3BlcmF0ZShyb3csIGNvbCk7XG4gIH1cblxuICBjb25zdCBkaW1zID0gW2EublJvd3MsIGEubkNvbHNdO1xuICByZXR1cm4gbmV3IFNwYXJzZU1hdHJpeChyb3dzLCBjb2xzLCB2YWxzLCBkaW1zKTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGdldHRpbmcgZGF0YSwgaW5kaWNlcywgYW5kIGlucHRyIGFycmF5cyBmcm9tIGEgc3BhcnNlXG4gKiBtYXRyaXggdG8gZm9sbG93IGNzciBtYXRyaXggY29udmVudGlvbnMuIFN1cGVyIGluZWZmaWNpZW50IChhbmQga2luZCBvZlxuICogZGVmZWF0cyB0aGUgcHVycG9zZSBvZiB0aGlzIGNvbnZlbnRpb24pIGJ1dCBhIGxvdCBvZiB0aGUgcG9ydGVkIHB5dGhvbiB0cmVlXG4gKiBzZWFyY2ggbG9naWMgZGVwZW5kcyBvbiB0aGlzIGRhdGEgZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q1NSKHg6IFNwYXJzZU1hdHJpeCkge1xuICBjb25zdCBlbnRyaWVzOiBFbnRyeVtdID0gW107XG5cbiAgeC5mb3JFYWNoKCh2YWx1ZSwgcm93LCBjb2wpID0+IHtcbiAgICBlbnRyaWVzLnB1c2goeyB2YWx1ZSwgcm93LCBjb2wgfSk7XG4gIH0pO1xuXG4gIGVudHJpZXMuc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhLnJvdyA9PT0gYi5yb3cpIHtcbiAgICAgIHJldHVybiBhLmNvbCAtIGIuY29sO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYS5yb3cgLSBiLnJvdztcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gW107XG4gIGNvbnN0IHZhbHVlczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaW5kcHRyOiBudW1iZXJbXSA9IFtdO1xuXG4gIGxldCBjdXJyZW50Um93ID0gLTE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHsgcm93LCBjb2wsIHZhbHVlIH0gPSBlbnRyaWVzW2ldO1xuICAgIGlmIChyb3cgIT09IGN1cnJlbnRSb3cpIHtcbiAgICAgIGN1cnJlbnRSb3cgPSByb3c7XG4gICAgICBpbmRwdHIucHVzaChpKTtcbiAgICB9XG4gICAgaW5kaWNlcy5wdXNoKGNvbCk7XG4gICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHsgaW5kaWNlcywgdmFsdWVzLCBpbmRwdHIgfTtcbn1cbiJdfQ==","/**\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 let 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 }\n else {\n nRight += 1;\n }\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 }\n else {\n return 1 + numNodes(tree.leftChild) + numNodes(tree.rightChild);\n }\n}\nfunction numLeaves(tree) {\n if (tree.isLeaf) {\n return 1;\n }\n else {\n return numLeaves(tree.leftChild) + numLeaves(tree.rightChild);\n }\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 (let tree of rpForest) {\n output.push(...tree.indices);\n }\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 }\n else {\n node = tree.children[node][1];\n }\n }\n const index = -1 * tree.children[node][0];\n return tree.indices[index];\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBZWpDLE1BQU0sT0FBTyxRQUFRO0lBQ25CLFlBQ1MsV0FBcUIsRUFDckIsT0FBaUIsRUFDakIsUUFBb0IsRUFDcEIsT0FBbUI7UUFIbkIsZ0JBQVcsR0FBWCxXQUFXLENBQVU7UUFDckIsWUFBTyxHQUFQLE9BQU8sQ0FBVTtRQUNqQixhQUFRLEdBQVIsUUFBUSxDQUFZO1FBQ3BCLFlBQU8sR0FBUCxPQUFPLENBQVk7SUFDekIsQ0FBQztDQUNMO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUN4QixJQUFZLEVBQ1osVUFBa0IsRUFDbEIsTUFBYyxFQUNkLE1BQWdCO0lBRWhCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRTFDLE1BQU0sS0FBSyxHQUFHLEtBQUs7U0FDaEIsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUNiLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFFOUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsUUFBUSxDQUNmLElBQVksRUFDWixRQUFRLEdBQUcsRUFBRSxFQUNi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QUMvQjthQUFNO1lBQ0wsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDL0I7S0FDRjtJQUVELE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IFJhbmRvbUZuLCBWZWN0b3IsIFZlY3RvcnMgfSBmcm9tICcuL3VtYXAnO1xuXG4vKipcbiAqIFRyZWUgZnVuY3Rpb25hbGl0eSBmb3IgYXBwcm94aW1hdGluZyBuZWFyZXN0IG5laWdoYm9yc1xuICovXG5pbnRlcmZhY2UgUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlIHtcbiAgaXNMZWFmOiBib29sZWFuO1xuICBpbmRpY2VzPzogbnVtYmVyW107XG4gIGxlZnRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgcmlnaHRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgaHlwZXJwbGFuZT86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgRmxhdFRyZWUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgaHlwZXJwbGFuZXM6IG51bWJlcltdLFxuICAgIHB1YmxpYyBvZmZzZXRzOiBudW1iZXJbXSxcbiAgICBwdWJsaWMgY2hpbGRyZW46IG51bWJlcltdW10sXG4gICAgcHVibGljIGluZGljZXM6IG51bWJlcltdW11cbiAgKSB7fVxufVxuXG4vKipcbiAqIEJ1aWxkIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IHdpdGggYGBuVHJlZXNgYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VGb3Jlc3QoXG4gIGRhdGE6IFZlY3RvcixcbiAgbk5laWdoYm9yczogbnVtYmVyLFxuICBuVHJlZXM6IG51bWJlcixcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IGxlYWZTaXplID0gTWF0aC5tYXgoMTAsIG5OZWlnaGJvcnMpO1xuXG4gIGNvbnN0IHRyZWVzID0gdXRpbHNcbiAgICAucmFuZ2UoblRyZWVzKVxuICAgIC5tYXAoKF8sIGkpID0+IG1ha2VUcmVlKGRhdGEsIGxlYWZTaXplLCBpLCByYW5kb20pKTtcbiAgY29uc3QgZm9yZXN0ID0gdHJlZXMubWFwKHRyZWUgPT4gZmxhdHRlblRyZWUodHJlZSwgbGVhZlNpemUpKTtcblxuICByZXR1cm4gZm9yZXN0O1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHJhbmRvbSBwcm9qZWN0aW9uIHRyZWUgYmFzZWQgb24gYGBkYXRhYGAgd2l0aCBsZWF2ZXNcbiAqIG9mIHNpemUgYXQgbW9zdCBgYGxlYWZTaXplYGBcbiAqL1xuZnVuY3Rpb24gbWFrZVRyZWUoXG4gIGRhdGE6IFZlY3RvcixcbiAgbGVhZlNpemUgPSAzMCxcbiAgbjogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUge1xuICBjb25zdCBpbmRpY2VzID0gdXRpbHMucmFuZ2UoZGF0YS5sZW5ndGgpO1xuICBjb25zdCB0cmVlID0gbWFrZUV1Y2xpZGVhblRyZWUoZGF0YSwgaW5kaWNlcywgbGVhZlNpemUsIG4sIHJhbmRvbSk7XG4gIHJldHVybiB0cmVlO1xufVxuXG5mdW5jdGlvbiBtYWtlRXVjbGlkZWFuVHJlZShcbiAgZGF0YTogVmVjdG9yLFxuICBpbmRpY2VzOiBudW1iZXJbXSxcbiAgbGVhZlNpemUgPSAzMCxcbiAgcTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUge1xuICBpZiAoaW5kaWNlcy5sZW5ndGggPiBsZWFmU2l6ZSkge1xuICAgIGNvbnN0IHNwbGl0UmVzdWx0cyA9IGV1Y2xpZGVhblJhbmRvbVByb2plY3Rpb25TcGxpdChkYXRhLCBpbmRpY2VzLCByYW5kb20pO1xuICAgIGNvbnN0IHsgaW5kaWNlc0xlZnQsIGluZGljZXNSaWdodCwgaHlwZXJwbGFuZSwgb2Zmc2V0IH0gPSBzcGxpdFJlc3VsdHM7XG5cbiAgICBjb25zdCBsZWZ0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzTGVmdCxcbiAgICAgIGxlYWZTaXplLFxuICAgICAgcSArIDEsXG4gICAgICByYW5kb21cbiAgICApO1xuICAgIGNvbnN0IHJpZ2h0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzUmlnaHQsXG4gICAgICBsZWFmU2l6ZSxcbiAgICAgIHEgKyAxLFxuICAgICAgcmFuZG9tXG4gICAgKTtcblxuICAgIGNvbnN0IG5vZGUgPSB7IGxlZnRDaGlsZCwgcmlnaHRDaGlsZCwgaXNMZWFmOiBmYWxzZSwgaHlwZXJwbGFuZSwgb2Zmc2V0IH07XG4gICAgcmV0dXJuIG5vZGU7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgbm9kZSA9IHsgaW5kaWNlcywgaXNMZWFmOiB0cnVlIH07XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cbn1cblxuLyoqXG4gKiBHaXZlbiBhIHNldCBvZiBgYGluZGljZXNgYCBmb3IgZGF0YSBwb2ludHMgZnJvbSBgYGRhdGFgYCwgY3JlYXRlXG4gKiBhIHJhbmRvbSBoeXBlcnBsYW5lIHRvIHNwbGl0IHRoZSBkYXRhLCByZXR1cm5pbmcgdHdvIGFycmF5cyBpbmRpY2VzXG4gKiB0aGF0IGZhbGwgb24gZWl0aGVyIHNpZGUgb2YgdGhlIGh5cGVycGxhbmUuIFRoaXMgaXMgdGhlIGJhc2lzIGZvciBhXG4gKiByYW5kb20gcHJvamVjdGlvbiB0cmVlLCB3aGljaCBzaW1wbHkgdXNlcyB0aGlzIHNwbGl0dGluZyByZWN1cnNpdmVseS5cbiAqIFRoaXMgcGFydGljdWxhciBzcGxpdCB1c2VzIGV1Y2xpZGVhbiBkaXN0YW5jZSB0byBkZXRlcm1pbmUgdGhlIGh5cGVycGxhbmVcbiAqIGFuZCB3aGljaCBzaWRlIGVhY2ggZGF0YSBzYW1wbGUgZmFsbHMgb24uXG4gKi9cbmZ1bmN0aW9uIGV1Y2xpZGVhblJhbmRvbVByb2plY3Rpb25TcGxpdChcbiAgZGF0YTogVmVjdG9yLFxuICBpbmRpY2VzOiBudW1iZXJbXSxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IGRpbSA9IDE7XG5cbiAgLy8gU2VsZWN0IHR3byByYW5kb20gcG9pbnRzLCBzZXQgdGhlIGh5cGVycGxhbmUgYmV0d2VlbiB0aGVtXG4gIGxldCBsZWZ0SW5kZXggPSB1dGlscy50YXVSYW5kSW50KGluZGljZXMubGVuZ3RoLCByYW5kb20pO1xuICBsZXQgcmlnaHRJbmRleCA9IHV0aWxzLnRhdVJhbmRJbnQoaW5kaWNlcy5sZW5ndGgsIHJhbmRvbSk7XG4gIHJpZ2h0SW5kZXggKz0gbGVmdEluZGV4ID09PSByaWdodEluZGV4ID8gMSA6IDA7XG4gIHJpZ2h0SW5kZXggPSByaWdodEluZGV4ICUgaW5kaWNlcy5sZW5ndGg7XG4gIGNvbnN0IGxlZnQgPSBpbmRpY2VzW2xlZnRJbmRleF07XG4gIGNvbnN0IHJpZ2h0ID0gaW5kaWNlc1tyaWdodEluZGV4XTtcblxuICAvLyBDb21wdXRlIHRoZSBub3JtYWwgdmVjdG9yIHRvIHRoZSBoeXBlcnBsYW5lICh0aGUgdmVjdG9yIGJldHdlZW4gdGhlIHR3b1xuICAvLyBwb2ludHMpIGFuZCB0aGUgb2Zmc2V0IGZyb20gdGhlIG9yaWdpblxuICBsZXQgaHlwZXJwbGFuZU9mZnNldCA9IDA7XG4gIGxldCBoeXBlcnBsYW5lVmVjdG9yID0gMDtcblxuICBcbiAgaHlwZXJwbGFuZVZlY3RvciA9IGRhdGFbbGVmdF0gLSBkYXRhW3JpZ2h0XTtcbiAgaHlwZXJwbGFuZU9mZnNldCAtPVxuICAgIChoeXBlcnBsYW5lVmVjdG9yICogKGRhdGFbbGVmdF0gKyBkYXRhW3JpZ2h0XSkpIC8gMi4wO1xuICBcblxuICAvLyBGb3IgZWFjaCBwb2ludCBjb21wdXRlIHRoZSBtYXJnaW4gKHByb2plY3QgaW50byBub3JtYWwgdmVjdG9yKVxuICAvLyBJZiB3ZSBhcmUgb24gbG93ZXIgc2lkZSBvZiB0aGUgaHlwZXJwbGFuZSBwdXQgaW4gb25lIHBpbGUsIG90aGVyd2lzZVxuICAvLyBwdXQgaXQgaW4gdGhlIG90aGVyIHBpbGUgKGlmIHdlIGhpdCBoeXBlcnBsYW5lIG9uIHRoZSBub3NlLCBmbGlwIGEgY29pbilcbiAgbGV0IG5MZWZ0ID0gMDtcbiAgbGV0IG5SaWdodCA9IDA7XG4gIGNvbnN0IHNpZGUgPSB1dGlscy56ZXJvcyhpbmRpY2VzLmxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBtYXJnaW4gPSBoeXBlcnBsYW5lT2Zmc2V0O1xuICAgIFxuICAgICAgbWFyZ2luICs9IGh5cGVycGxhbmVWZWN0b3IgKiBkYXRhW2luZGljZXNbaV1dO1xuICAgIFxuICAgIGlmIChtYXJnaW4gPT09IDApIHtcbiAgICAgIHNpZGVbaV0gPSB1dGlscy50YXVSYW5kSW50KDIsIHJhbmRvbSk7XG4gICAgICBpZiAoc2lkZVtpXSA9PT0gMCkge1xuICAgICAgICBuTGVmdCArPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgblJpZ2h0ICs9IDE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChtYXJnaW4gPiAwKSB7XG4gICAgICBzaWRlW2ldID0gMDtcbiAgICAgIG5MZWZ0ICs9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNpZGVbaV0gPSAxO1xuICAgICAgblJpZ2h0ICs9IDE7XG4gICAgfVxuICB9XG5cbiAgLy8gTm93IHRoYXQgd2UgaGF2ZSB0aGUgY291bnRzLCBhbGxvY2F0ZSBhcnJheXNcbiAgY29uc3QgaW5kaWNlc0xlZnQgPSB1dGlscy56ZXJvcyhuTGVmdCk7XG4gIGNvbnN0IGluZGljZXNSaWdodCA9IHV0aWxzLnplcm9zKG5SaWdodCk7XG5cbiAgLy8gUG9wdWxhdGUgdGhlIGFycmF5cyB3aXRoIGluZGljZXMgYWNjb3JkaW5nIHRvIHdoaWNoIHNpZGUgdGhleSBmZWxsIG9uXG4gIG5MZWZ0ID0gMDtcbiAgblJpZ2h0ID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaWRlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHNpZGVbaV0gPT09IDApIHtcbiAgICAgIGluZGljZXNMZWZ0W25MZWZ0XSA9IGluZGljZXNbaV07XG4gICAgICBuTGVmdCArPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbmRpY2VzUmlnaHRbblJpZ2h0XSA9IGluZGljZXNbaV07XG4gICAgICBuUmlnaHQgKz0gMTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGluZGljZXNMZWZ0LFxuICAgIGluZGljZXNSaWdodCxcbiAgICBoeXBlcnBsYW5lOiBoeXBlcnBsYW5lVmVjdG9yLFxuICAgIG9mZnNldDogaHlwZXJwbGFuZU9mZnNldCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmxhdHRlblRyZWUodHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlLCBsZWFmU2l6ZTogbnVtYmVyKSB7XG4gIGNvbnN0IG5Ob2RlcyA9IG51bU5vZGVzKHRyZWUpO1xuICBjb25zdCBuTGVhdmVzID0gbnVtTGVhdmVzKHRyZWUpO1xuXG4gIC8vIFRPRE86IFZlcmlmeSB0aGF0IHNwYXJzZSBjb2RlIGlzIG5vdCByZWxldmFudC4uLlxuICBjb25zdCBoeXBlcnBsYW5lcyA9IHV0aWxzXG4gICAgLnJhbmdlKG5Ob2RlcylcbiAgICAubWFwKCgpID0+IHRyZWUuaHlwZXJwbGFuZSA/IDEgOiAwKTtcblxuICBjb25zdCBvZmZzZXRzID0gdXRpbHMuemVyb3Mobk5vZGVzKTtcbiAgY29uc3QgY2hpbGRyZW4gPSB1dGlscy5yYW5nZShuTm9kZXMpLm1hcCgoKSA9PiBbLTEsIC0xXSk7XG4gIGNvbnN0IGluZGljZXMgPSB1dGlsc1xuICAgIC5yYW5nZShuTGVhdmVzKVxuICAgIC5tYXAoKCkgPT4gdXRpbHMucmFuZ2UobGVhZlNpemUpLm1hcCgoKSA9PiAtMSkpO1xuICByZWN1cnNpdmVGbGF0dGVuKHRyZWUsIGh5cGVycGxhbmVzLCBvZmZzZXRzLCBjaGlsZHJlbiwgaW5kaWNlcywgMCwgMCk7XG4gIHJldHVybiBuZXcgRmxhdFRyZWUoaHlwZXJwbGFuZXMsIG9mZnNldHMsIGNoaWxkcmVuLCBpbmRpY2VzKTtcbn1cblxuZnVuY3Rpb24gcmVjdXJzaXZlRmxhdHRlbihcbiAgdHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlLFxuICBoeXBlcnBsYW5lczogbnVtYmVyW10sXG4gIG9mZnNldHM6IG51bWJlcltdLFxuICBjaGlsZHJlbjogbnVtYmVyW11bXSxcbiAgaW5kaWNlczogbnVtYmVyW11bXSxcbiAgbm9kZU51bTogbnVtYmVyLFxuICBsZWFmTnVtOiBudW1iZXJcbik6IHsgbm9kZU51bTogbnVtYmVyOyBsZWFmTnVtOiBudW1iZXIgfSB7XG4gIGlmICh0cmVlLmlzTGVhZikge1xuICAgIGNoaWxkcmVuW25vZGVOdW1dWzBdID0gLWxlYWZOdW07XG5cbiAgICAvLyBUT0RPOiBUcmlwbGUgY2hlY2sgdGhpcyBvcGVyYXRpb24gY29ycmVzcG9uZHMgdG9cbiAgICAvLyBpbmRpY2VzW2xlYWZOdW0gOiB0cmVlLmluZGljZXMuc2hhcGVbMF1dID0gdHJlZS5pbmRpY2VzXG4gICAgaW5kaWNlc1tsZWFmTnVtXS5zcGxpY2UoMCwgdHJlZS5pbmRpY2VzIS5sZW5ndGgsIC4uLnRyZWUuaW5kaWNlcyEpO1xuICAgIGxlYWZOdW0gKz0gMTtcbiAgICByZXR1cm4geyBub2RlTnVtLCBsZWFmTnVtIH07XG4gIH0gZWxzZSB7XG4gICAgaHlwZXJwbGFuZXNbbm9kZU51bV0gPSB0cmVlLmh5cGVycGxhbmUhO1xuICAgIG9mZnNldHNbbm9kZU51bV0gPSB0cmVlLm9mZnNldCE7XG4gICAgY2hpbGRyZW5bbm9kZU51bV1bMF0gPSBub2RlTnVtICsgMTtcbiAgICBjb25zdCBvbGROb2RlTnVtID0gbm9kZU51bTtcblxuICAgIGxldCByZXMgPSByZWN1cnNpdmVGbGF0dGVuKFxuICAgICAgdHJlZS5sZWZ0Q2hpbGQhLFxuICAgICAgaHlwZXJwbGFuZXMsXG4gICAgICBvZmZzZXRzLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBpbmRpY2VzLFxuICAgICAgbm9kZU51bSArIDEsXG4gICAgICBsZWFmTnVtXG4gICAgKTtcbiAgICBub2RlTnVtID0gcmVzLm5vZGVOdW07XG4gICAgbGVhZk51bSA9IHJlcy5sZWFmTnVtO1xuXG4gICAgY2hpbGRyZW5bb2xkTm9kZU51bV1bMV0gPSBub2RlTnVtICsgMTtcblxuICAgIHJlcyA9IHJlY3Vyc2l2ZUZsYXR0ZW4oXG4gICAgICB0cmVlLnJpZ2h0Q2hpbGQhLFxuICAgICAgaHlwZXJwbGFuZXMsXG4gICAgICBvZmZzZXRzLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBpbmRpY2VzLFxuICAgICAgbm9kZU51bSArIDEsXG4gICAgICBsZWFmTnVtXG4gICAgKTtcbiAgICByZXR1cm4geyBub2RlTnVtOiByZXMubm9kZU51bSwgbGVhZk51bTogcmVzLmxlYWZOdW0gfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1Ob2Rlcyh0cmVlOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUpOiBudW1iZXIge1xuICBpZiAodHJlZS5pc0xlYWYpIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMSArIG51bU5vZGVzKHRyZWUubGVmdENoaWxkISkgKyBudW1Ob2Rlcyh0cmVlLnJpZ2h0Q2hpbGQhKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1MZWF2ZXModHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlKTogbnVtYmVyIHtcbiAgaWYgKHRyZWUuaXNMZWFmKSB7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bUxlYXZlcyh0cmVlLmxlZnRDaGlsZCEpICsgbnVtTGVhdmVzKHRyZWUucmlnaHRDaGlsZCEpO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYW4gYXJyYXkgb2Ygc2V0cyBvZiBjYW5kaWRhdGUgbmVhcmVzdCBuZWlnaGJvcnMgYnlcbiAqIGNvbnN0cnVjdGluZyBhIHJhbmRvbSBwcm9qZWN0aW9uIGZvcmVzdCBhbmQgdGFraW5nIHRoZSBsZWF2ZXMgb2YgYWxsIHRoZVxuICogdHJlZXMuIEFueSBnaXZlbiB0cmVlIGhhcyBsZWF2ZXMgdGhhdCBhcmUgYSBzZXQgb2YgcG90ZW50aWFsIG5lYXJlc3RcbiAqIG5laWdoYm9ycy4gR2l2ZW4gZW5vdWdoIHRyZWVzIHRoZSBzZXQgb2YgYWxsIHN1Y2ggbGVhdmVzIGdpdmVzIGEgZ29vZFxuICogbGlrZWxpaG9vZCBvZiBnZXR0aW5nIGEgZ29vZCBzZXQgb2YgbmVhcmVzdCBuZWlnaGJvcnMgaW4gY29tcG9zaXRlLiBTaW5jZVxuICogc3VjaCBhIHJhbmRvbSBwcm9qZWN0aW9uIGZvcmVzdCBpcyBpbmV4cGVuc2l2ZSB0byBjb21wdXRlLCB0aGlzIGNhbiBiZSBhXG4gKiB1c2VmdWwgbWVhbnMgb2Ygc2VlZGluZyBvdGhlciBuZWFyZXN0IG5laWdoYm9yIGFsZ29yaXRobXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTGVhZkFycmF5KHJwRm9yZXN0OiBGbGF0VHJlZVtdKTogbnVtYmVyW11bXSB7XG4gIGlmIChycEZvcmVzdC5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qgb3V0cHV0OiBudW1iZXJbXVtdID0gW107XG4gICAgZm9yIChsZXQgdHJlZSBvZiBycEZvcmVzdCkge1xuICAgICAgb3V0cHV0LnB1c2goLi4udHJlZS5pbmRpY2VzISk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtbLTFdXTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbGVjdHMgdGhlIHNpZGUgb2YgdGhlIHRyZWUgdG8gc2VhcmNoIGR1cmluZyBmbGF0IHRyZWUgc2VhcmNoLlxuICovXG5mdW5jdGlvbiBzZWxlY3RTaWRlKFxuICBoeXBlcnBsYW5lOiBudW1iZXIsXG4gIG9mZnNldDogbnVtYmVyLFxuICBwb2ludDogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgbGV0IG1hcmdpbiA9IG9mZnNldDtcblxuICAgIG1hcmdpbiArPSBoeXBlcnBsYW5lICogcG9pbnQ7XG4gIFxuXG4gIGlmIChtYXJnaW4gPT09IDApIHtcbiAgICBjb25zdCBzaWRlID0gdXRpbHMudGF1UmFuZEludCgyLCByYW5kb20pO1xuICAgIHJldHVybiBzaWRlO1xuICB9IGVsc2UgaWYgKG1hcmdpbiA+IDApIHtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMTtcbiAgfVxufVxuXG4vKipcbiAqIFNlYXJjaGVzIGEgZmxhdHRlbmVkIHJwLXRyZWUgZm9yIGEgcG9pbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWFyY2hGbGF0VHJlZShcbiAgcG9pbnQ6IG51bWJlcixcbiAgdHJlZTogRmxhdFRyZWUsXG4gIHJhbmRvbTogUmFuZG9tRm5cbikge1xuICBsZXQgbm9kZSA9IDA7XG4gIHdoaWxlICh0cmVlLmNoaWxkcmVuW25vZGVdWzBdID4gMCkge1xuICAgIGNvbnN0IHNpZGUgPSBzZWxlY3RTaWRlKFxuICAgICAgdHJlZS5oeXBlcnBsYW5lc1tub2RlXSxcbiAgICAgIHRyZWUub2Zmc2V0c1tub2RlXSxcbiAgICAgIHBvaW50LFxuICAgICAgcmFuZG9tXG4gICAgKTtcbiAgICBpZiAoc2lkZSA9PT0gMCkge1xuICAgICAgbm9kZSA9IHRyZWUuY2hpbGRyZW5bbm9kZV1bMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGUgPSB0cmVlLmNoaWxkcmVuW25vZGVdWzFdO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGluZGV4ID0gLTEgKiB0cmVlLmNoaWxkcmVuW25vZGVdWzBdO1xuICByZXR1cm4gdHJlZS5pbmRpY2VzW2luZGV4XTtcbn1cbiJdfQ==","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","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","import { isAnyArray } from 'is-any-array';\nimport max from 'ml-array-max';\nimport min from 'ml-array-min';\n\nfunction rescale(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n } else if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var output;\n\n if (options.output !== undefined) {\n if (!isAnyArray(options.output)) {\n throw new TypeError('output option must be an array if specified');\n }\n\n output = options.output;\n } else {\n output = new Array(input.length);\n }\n\n var currentMin = min(input);\n var currentMax = max(input);\n\n if (currentMin === currentMax) {\n throw new RangeError('minimum and maximum input values are equal. Cannot rescale a constant array');\n }\n\n var _options$min = options.min,\n minValue = _options$min === void 0 ? options.autoMinMax ? currentMin : 0 : _options$min,\n _options$max = options.max,\n maxValue = _options$max === void 0 ? options.autoMinMax ? currentMax : 1 : _options$max;\n\n if (minValue >= maxValue) {\n throw new RangeError('min option must be smaller than max option');\n }\n\n var factor = (maxValue - minValue) / (currentMax - currentMin);\n\n for (var i = 0; i < input.length; i++) {\n output[i] = (input[i] - currentMin) * factor + minValue;\n }\n\n return output;\n}\n\nexport { rescale as default };\n","import { isAnyArray } from 'is-any-array';\n\nfunction min(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n }\n\n if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var _options$fromIndex = options.fromIndex,\n fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex,\n _options$toIndex = options.toIndex,\n toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex;\n\n if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) {\n throw new Error('fromIndex must be a positive integer smaller than length');\n }\n\n if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) {\n throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length');\n }\n\n var minValue = input[fromIndex];\n\n for (var i = fromIndex + 1; i < toIndex; i++) {\n if (input[i] < minValue) minValue = input[i];\n }\n\n return minValue;\n}\n\nexport { min as default };\n","import { isAnyArray } from 'is-any-array';\n\nfunction max(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n }\n\n if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var _options$fromIndex = options.fromIndex,\n fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex,\n _options$toIndex = options.toIndex,\n toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex;\n\n if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) {\n throw new Error('fromIndex must be a positive integer smaller than length');\n }\n\n if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) {\n throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length');\n }\n\n var maxValue = input[fromIndex];\n\n for (var i = fromIndex + 1; i < toIndex; i++) {\n if (input[i] > maxValue) maxValue = input[i];\n }\n\n return maxValue;\n}\n\nexport { max as default };\n","const indent = ' '.repeat(2);\nconst indentData = ' '.repeat(4);\n\nexport function inspectMatrix() {\n return inspectMatrixWithOptions(this);\n}\n\nexport function inspectMatrixWithOptions(matrix, options = {}) {\n const {\n maxRows = 15,\n maxColumns = 10,\n maxNumSize = 8,\n padMinus = 'auto',\n } = options;\n return `${matrix.constructor.name} {\n${indent}[\n${indentData}${inspectData(matrix, maxRows, maxColumns, maxNumSize, padMinus)}\n${indent}]\n${indent}rows: ${matrix.rows}\n${indent}columns: ${matrix.columns}\n}`;\n}\n\nfunction inspectData(matrix, maxRows, maxColumns, maxNumSize, padMinus) {\n const { rows, columns } = matrix;\n const maxI = Math.min(rows, maxRows);\n const maxJ = Math.min(columns, maxColumns);\n const result = [];\n\n if (padMinus === 'auto') {\n padMinus = false;\n loop: for (let i = 0; i < maxI; i++) {\n for (let j = 0; j < maxJ; j++) {\n if (matrix.get(i, j) < 0) {\n padMinus = true;\n break loop;\n }\n }\n }\n }\n\n for (let i = 0; i < maxI; i++) {\n let line = [];\n for (let j = 0; j < maxJ; j++) {\n line.push(formatNumber(matrix.get(i, j), maxNumSize, padMinus));\n }\n result.push(`${line.join(' ')}`);\n }\n if (maxJ !== columns) {\n result[result.length - 1] += ` ... ${columns - maxColumns} more columns`;\n }\n if (maxI !== rows) {\n result.push(`... ${rows - maxRows} more rows`);\n }\n return result.join(`\\n${indentData}`);\n}\n\nfunction formatNumber(num, maxNumSize, padMinus) {\n return (\n num >= 0 && padMinus\n ? ` ${formatNumber2(num, maxNumSize - 1)}`\n : formatNumber2(num, maxNumSize)\n ).padEnd(maxNumSize);\n}\n\nfunction formatNumber2(num, len) {\n // small.length numbers should be as is\n let str = num.toString();\n if (str.length <= len) return str;\n\n // (7)'0.00123' is better then (7)'1.23e-2'\n // (8)'0.000123' is worse then (7)'1.23e-3',\n let fix = num.toFixed(len);\n if (fix.length > len) {\n fix = num.toFixed(Math.max(0, len - (fix.length - len)));\n }\n if (\n fix.length <= len &&\n !fix.startsWith('0.000') &&\n !fix.startsWith('-0.000')\n ) {\n return fix;\n }\n\n // well, if it's still too long the user should've used longer numbers\n let exp = num.toExponential(len);\n if (exp.length > len) {\n exp = num.toExponential(Math.max(0, len - (exp.length - len)));\n }\n return exp.slice(0);\n}\n","import { isAnyArray } from 'is-any-array';\n\n/**\n * @private\n * Check that a row index is not out of bounds\n * @param {Matrix} matrix\n * @param {number} index\n * @param {boolean} [outer]\n */\nexport function checkRowIndex(matrix, index, outer) {\n let max = outer ? matrix.rows : matrix.rows - 1;\n if (index < 0 || index > max) {\n throw new RangeError('Row index out of range');\n }\n}\n\n/**\n * @private\n * Check that a column index is not out of bounds\n * @param {Matrix} matrix\n * @param {number} index\n * @param {boolean} [outer]\n */\nexport function checkColumnIndex(matrix, index, outer) {\n let max = outer ? matrix.columns : matrix.columns - 1;\n if (index < 0 || index > max) {\n throw new RangeError('Column index out of range');\n }\n}\n\n/**\n * @private\n * Check that the provided vector is an array with the right length\n * @param {Matrix} matrix\n * @param {Array|Matrix} vector\n * @return {Array}\n * @throws {RangeError}\n */\nexport function checkRowVector(matrix, vector) {\n if (vector.to1DArray) {\n vector = vector.to1DArray();\n }\n if (vector.length !== matrix.columns) {\n throw new RangeError(\n 'vector size must be the same as the number of columns',\n );\n }\n return vector;\n}\n\n/**\n * @private\n * Check that the provided vector is an array with the right length\n * @param {Matrix} matrix\n * @param {Array|Matrix} vector\n * @return {Array}\n * @throws {RangeError}\n */\nexport function checkColumnVector(matrix, vector) {\n if (vector.to1DArray) {\n vector = vector.to1DArray();\n }\n if (vector.length !== matrix.rows) {\n throw new RangeError('vector size must be the same as the number of rows');\n }\n return vector;\n}\n\nexport function checkRowIndices(matrix, rowIndices) {\n if (!isAnyArray(rowIndices)) {\n throw new TypeError('row indices must be an array');\n }\n\n for (let i = 0; i < rowIndices.length; i++) {\n if (rowIndices[i] < 0 || rowIndices[i] >= matrix.rows) {\n throw new RangeError('row indices are out of range');\n }\n }\n}\n\nexport function checkColumnIndices(matrix, columnIndices) {\n if (!isAnyArray(columnIndices)) {\n throw new TypeError('column indices must be an array');\n }\n\n for (let i = 0; i < columnIndices.length; i++) {\n if (columnIndices[i] < 0 || columnIndices[i] >= matrix.columns) {\n throw new RangeError('column indices are out of range');\n }\n }\n}\n\nexport function checkRange(matrix, startRow, endRow, startColumn, endColumn) {\n if (arguments.length !== 5) {\n throw new RangeError('expected 4 arguments');\n }\n checkNumber('startRow', startRow);\n checkNumber('endRow', endRow);\n checkNumber('startColumn', startColumn);\n checkNumber('endColumn', endColumn);\n if (\n startRow > endRow ||\n startColumn > endColumn ||\n startRow < 0 ||\n startRow >= matrix.rows ||\n endRow < 0 ||\n endRow >= matrix.rows ||\n startColumn < 0 ||\n startColumn >= matrix.columns ||\n endColumn < 0 ||\n endColumn >= matrix.columns\n ) {\n throw new RangeError('Submatrix indices are out of range');\n }\n}\n\nexport function newArray(length, value = 0) {\n let array = [];\n for (let i = 0; i < length; i++) {\n array.push(value);\n }\n return array;\n}\n\nfunction checkNumber(name, value) {\n if (typeof value !== 'number') {\n throw new TypeError(`${name} must be a number`);\n }\n}\n\nexport function checkNonEmpty(matrix) {\n if (matrix.isEmpty()) {\n throw new Error('Empty matrix has no elements to index');\n }\n}\n","import { isAnyArray } from 'is-any-array';\nimport rescale from 'ml-array-rescale';\n\nimport { inspectMatrix, inspectMatrixWithOptions } from './inspect';\nimport { installMathOperations } from './mathOperations';\nimport {\n sumByRow,\n sumByColumn,\n sumAll,\n productByRow,\n productByColumn,\n productAll,\n varianceByRow,\n varianceByColumn,\n varianceAll,\n centerByRow,\n centerByColumn,\n centerAll,\n scaleByRow,\n scaleByColumn,\n scaleAll,\n getScaleByRow,\n getScaleByColumn,\n getScaleAll,\n} from './stat';\nimport {\n checkRowVector,\n checkRowIndex,\n checkColumnIndex,\n checkColumnVector,\n checkRange,\n checkNonEmpty,\n checkRowIndices,\n checkColumnIndices,\n} from './util';\n\nexport class AbstractMatrix {\n static from1DArray(newRows, newColumns, newData) {\n let length = newRows * newColumns;\n if (length !== newData.length) {\n throw new RangeError('data length does not match given dimensions');\n }\n let newMatrix = new Matrix(newRows, newColumns);\n for (let row = 0; row < newRows; row++) {\n for (let column = 0; column < newColumns; column++) {\n newMatrix.set(row, column, newData[row * newColumns + column]);\n }\n }\n return newMatrix;\n }\n\n static rowVector(newData) {\n let vector = new Matrix(1, newData.length);\n for (let i = 0; i < newData.length; i++) {\n vector.set(0, i, newData[i]);\n }\n return vector;\n }\n\n static columnVector(newData) {\n let vector = new Matrix(newData.length, 1);\n for (let i = 0; i < newData.length; i++) {\n vector.set(i, 0, newData[i]);\n }\n return vector;\n }\n\n static zeros(rows, columns) {\n return new Matrix(rows, columns);\n }\n\n static ones(rows, columns) {\n return new Matrix(rows, columns).fill(1);\n }\n\n static rand(rows, columns, options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { random = Math.random } = options;\n let matrix = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n matrix.set(i, j, random());\n }\n }\n return matrix;\n }\n\n static randInt(rows, columns, options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1000, random = Math.random } = options;\n if (!Number.isInteger(min)) throw new TypeError('min must be an integer');\n if (!Number.isInteger(max)) throw new TypeError('max must be an integer');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let interval = max - min;\n let matrix = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n let value = min + Math.round(random() * interval);\n matrix.set(i, j, value);\n }\n }\n return matrix;\n }\n\n static eye(rows, columns, value) {\n if (columns === undefined) columns = rows;\n if (value === undefined) value = 1;\n let min = Math.min(rows, columns);\n let matrix = this.zeros(rows, columns);\n for (let i = 0; i < min; i++) {\n matrix.set(i, i, value);\n }\n return matrix;\n }\n\n static diag(data, rows, columns) {\n let l = data.length;\n if (rows === undefined) rows = l;\n if (columns === undefined) columns = rows;\n let min = Math.min(l, rows, columns);\n let matrix = this.zeros(rows, columns);\n for (let i = 0; i < min; i++) {\n matrix.set(i, i, data[i]);\n }\n return matrix;\n }\n\n static min(matrix1, matrix2) {\n matrix1 = this.checkMatrix(matrix1);\n matrix2 = this.checkMatrix(matrix2);\n let rows = matrix1.rows;\n let columns = matrix1.columns;\n let result = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n result.set(i, j, Math.min(matrix1.get(i, j), matrix2.get(i, j)));\n }\n }\n return result;\n }\n\n static max(matrix1, matrix2) {\n matrix1 = this.checkMatrix(matrix1);\n matrix2 = this.checkMatrix(matrix2);\n let rows = matrix1.rows;\n let columns = matrix1.columns;\n let result = new this(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n result.set(i, j, Math.max(matrix1.get(i, j), matrix2.get(i, j)));\n }\n }\n return result;\n }\n\n static checkMatrix(value) {\n return AbstractMatrix.isMatrix(value) ? value : new Matrix(value);\n }\n\n static isMatrix(value) {\n return value != null && value.klass === 'Matrix';\n }\n\n get size() {\n return this.rows * this.columns;\n }\n\n apply(callback) {\n if (typeof callback !== 'function') {\n throw new TypeError('callback must be a function');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n callback.call(this, i, j);\n }\n }\n return this;\n }\n\n to1DArray() {\n let array = [];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n array.push(this.get(i, j));\n }\n }\n return array;\n }\n\n to2DArray() {\n let copy = [];\n for (let i = 0; i < this.rows; i++) {\n copy.push([]);\n for (let j = 0; j < this.columns; j++) {\n copy[i].push(this.get(i, j));\n }\n }\n return copy;\n }\n\n toJSON() {\n return this.to2DArray();\n }\n\n isRowVector() {\n return this.rows === 1;\n }\n\n isColumnVector() {\n return this.columns === 1;\n }\n\n isVector() {\n return this.rows === 1 || this.columns === 1;\n }\n\n isSquare() {\n return this.rows === this.columns;\n }\n\n isEmpty() {\n return this.rows === 0 || this.columns === 0;\n }\n\n isSymmetric() {\n if (this.isSquare()) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j <= i; j++) {\n if (this.get(i, j) !== this.get(j, i)) {\n return false;\n }\n }\n }\n return true;\n }\n return false;\n }\n\n isEchelonForm() {\n let i = 0;\n let j = 0;\n let previousColumn = -1;\n let isEchelonForm = true;\n let checked = false;\n while (i < this.rows && isEchelonForm) {\n j = 0;\n checked = false;\n while (j < this.columns && checked === false) {\n if (this.get(i, j) === 0) {\n j++;\n } else if (this.get(i, j) === 1 && j > previousColumn) {\n checked = true;\n previousColumn = j;\n } else {\n isEchelonForm = false;\n checked = true;\n }\n }\n i++;\n }\n return isEchelonForm;\n }\n\n isReducedEchelonForm() {\n let i = 0;\n let j = 0;\n let previousColumn = -1;\n let isReducedEchelonForm = true;\n let checked = false;\n while (i < this.rows && isReducedEchelonForm) {\n j = 0;\n checked = false;\n while (j < this.columns && checked === false) {\n if (this.get(i, j) === 0) {\n j++;\n } else if (this.get(i, j) === 1 && j > previousColumn) {\n checked = true;\n previousColumn = j;\n } else {\n isReducedEchelonForm = false;\n checked = true;\n }\n }\n for (let k = j + 1; k < this.rows; k++) {\n if (this.get(i, k) !== 0) {\n isReducedEchelonForm = false;\n }\n }\n i++;\n }\n return isReducedEchelonForm;\n }\n\n echelonForm() {\n let result = this.clone();\n let h = 0;\n let k = 0;\n while (h < result.rows && k < result.columns) {\n let iMax = h;\n for (let i = h; i < result.rows; i++) {\n if (result.get(i, k) > result.get(iMax, k)) {\n iMax = i;\n }\n }\n if (result.get(iMax, k) === 0) {\n k++;\n } else {\n result.swapRows(h, iMax);\n let tmp = result.get(h, k);\n for (let j = k; j < result.columns; j++) {\n result.set(h, j, result.get(h, j) / tmp);\n }\n for (let i = h + 1; i < result.rows; i++) {\n let factor = result.get(i, k) / result.get(h, k);\n result.set(i, k, 0);\n for (let j = k + 1; j < result.columns; j++) {\n result.set(i, j, result.get(i, j) - result.get(h, j) * factor);\n }\n }\n h++;\n k++;\n }\n }\n return result;\n }\n\n reducedEchelonForm() {\n let result = this.echelonForm();\n let m = result.columns;\n let n = result.rows;\n let h = n - 1;\n while (h >= 0) {\n if (result.maxRow(h) === 0) {\n h--;\n } else {\n let p = 0;\n let pivot = false;\n while (p < n && pivot === false) {\n if (result.get(h, p) === 1) {\n pivot = true;\n } else {\n p++;\n }\n }\n for (let i = 0; i < h; i++) {\n let factor = result.get(i, p);\n for (let j = p; j < m; j++) {\n let tmp = result.get(i, j) - factor * result.get(h, j);\n result.set(i, j, tmp);\n }\n }\n h--;\n }\n }\n return result;\n }\n\n set() {\n throw new Error('set method is unimplemented');\n }\n\n get() {\n throw new Error('get method is unimplemented');\n }\n\n repeat(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { rows = 1, columns = 1 } = options;\n if (!Number.isInteger(rows) || rows <= 0) {\n throw new TypeError('rows must be a positive integer');\n }\n if (!Number.isInteger(columns) || columns <= 0) {\n throw new TypeError('columns must be a positive integer');\n }\n let matrix = new Matrix(this.rows * rows, this.columns * columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n matrix.setSubMatrix(this, this.rows * i, this.columns * j);\n }\n }\n return matrix;\n }\n\n fill(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, value);\n }\n }\n return this;\n }\n\n neg() {\n return this.mulS(-1);\n }\n\n getRow(index) {\n checkRowIndex(this, index);\n let row = [];\n for (let i = 0; i < this.columns; i++) {\n row.push(this.get(index, i));\n }\n return row;\n }\n\n getRowVector(index) {\n return Matrix.rowVector(this.getRow(index));\n }\n\n setRow(index, array) {\n checkRowIndex(this, index);\n array = checkRowVector(this, array);\n for (let i = 0; i < this.columns; i++) {\n this.set(index, i, array[i]);\n }\n return this;\n }\n\n swapRows(row1, row2) {\n checkRowIndex(this, row1);\n checkRowIndex(this, row2);\n for (let i = 0; i < this.columns; i++) {\n let temp = this.get(row1, i);\n this.set(row1, i, this.get(row2, i));\n this.set(row2, i, temp);\n }\n return this;\n }\n\n getColumn(index) {\n checkColumnIndex(this, index);\n let column = [];\n for (let i = 0; i < this.rows; i++) {\n column.push(this.get(i, index));\n }\n return column;\n }\n\n getColumnVector(index) {\n return Matrix.columnVector(this.getColumn(index));\n }\n\n setColumn(index, array) {\n checkColumnIndex(this, index);\n array = checkColumnVector(this, array);\n for (let i = 0; i < this.rows; i++) {\n this.set(i, index, array[i]);\n }\n return this;\n }\n\n swapColumns(column1, column2) {\n checkColumnIndex(this, column1);\n checkColumnIndex(this, column2);\n for (let i = 0; i < this.rows; i++) {\n let temp = this.get(i, column1);\n this.set(i, column1, this.get(i, column2));\n this.set(i, column2, temp);\n }\n return this;\n }\n\n addRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + vector[j]);\n }\n }\n return this;\n }\n\n subRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - vector[j]);\n }\n }\n return this;\n }\n\n mulRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * vector[j]);\n }\n }\n return this;\n }\n\n divRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / vector[j]);\n }\n }\n return this;\n }\n\n addColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + vector[i]);\n }\n }\n return this;\n }\n\n subColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - vector[i]);\n }\n }\n return this;\n }\n\n mulColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * vector[i]);\n }\n }\n return this;\n }\n\n divColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / vector[i]);\n }\n }\n return this;\n }\n\n mulRow(index, value) {\n checkRowIndex(this, index);\n for (let i = 0; i < this.columns; i++) {\n this.set(index, i, this.get(index, i) * value);\n }\n return this;\n }\n\n mulColumn(index, value) {\n checkColumnIndex(this, index);\n for (let i = 0; i < this.rows; i++) {\n this.set(i, index, this.get(i, index) * value);\n }\n return this;\n }\n\n max(by) {\n if (this.isEmpty()) {\n return NaN;\n }\n switch (by) {\n case 'row': {\n const max = new Array(this.rows).fill(Number.NEGATIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max[row]) {\n max[row] = this.get(row, column);\n }\n }\n }\n return max;\n }\n case 'column': {\n const max = new Array(this.columns).fill(Number.NEGATIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max[column]) {\n max[column] = this.get(row, column);\n }\n }\n }\n return max;\n }\n case undefined: {\n let max = this.get(0, 0);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max) {\n max = this.get(row, column);\n }\n }\n }\n return max;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n maxIndex() {\n checkNonEmpty(this);\n let v = this.get(0, 0);\n let idx = [0, 0];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n if (this.get(i, j) > v) {\n v = this.get(i, j);\n idx[0] = i;\n idx[1] = j;\n }\n }\n }\n return idx;\n }\n\n min(by) {\n if (this.isEmpty()) {\n return NaN;\n }\n\n switch (by) {\n case 'row': {\n const min = new Array(this.rows).fill(Number.POSITIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min[row]) {\n min[row] = this.get(row, column);\n }\n }\n }\n return min;\n }\n case 'column': {\n const min = new Array(this.columns).fill(Number.POSITIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min[column]) {\n min[column] = this.get(row, column);\n }\n }\n }\n return min;\n }\n case undefined: {\n let min = this.get(0, 0);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min) {\n min = this.get(row, column);\n }\n }\n }\n return min;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n minIndex() {\n checkNonEmpty(this);\n let v = this.get(0, 0);\n let idx = [0, 0];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n if (this.get(i, j) < v) {\n v = this.get(i, j);\n idx[0] = i;\n idx[1] = j;\n }\n }\n }\n return idx;\n }\n\n maxRow(row) {\n checkRowIndex(this, row);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(row, 0);\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) > v) {\n v = this.get(row, i);\n }\n }\n return v;\n }\n\n maxRowIndex(row) {\n checkRowIndex(this, row);\n checkNonEmpty(this);\n let v = this.get(row, 0);\n let idx = [row, 0];\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) > v) {\n v = this.get(row, i);\n idx[1] = i;\n }\n }\n return idx;\n }\n\n minRow(row) {\n checkRowIndex(this, row);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(row, 0);\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) < v) {\n v = this.get(row, i);\n }\n }\n return v;\n }\n\n minRowIndex(row) {\n checkRowIndex(this, row);\n checkNonEmpty(this);\n let v = this.get(row, 0);\n let idx = [row, 0];\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) < v) {\n v = this.get(row, i);\n idx[1] = i;\n }\n }\n return idx;\n }\n\n maxColumn(column) {\n checkColumnIndex(this, column);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(0, column);\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) > v) {\n v = this.get(i, column);\n }\n }\n return v;\n }\n\n maxColumnIndex(column) {\n checkColumnIndex(this, column);\n checkNonEmpty(this);\n let v = this.get(0, column);\n let idx = [0, column];\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) > v) {\n v = this.get(i, column);\n idx[0] = i;\n }\n }\n return idx;\n }\n\n minColumn(column) {\n checkColumnIndex(this, column);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(0, column);\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) < v) {\n v = this.get(i, column);\n }\n }\n return v;\n }\n\n minColumnIndex(column) {\n checkColumnIndex(this, column);\n checkNonEmpty(this);\n let v = this.get(0, column);\n let idx = [0, column];\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) < v) {\n v = this.get(i, column);\n idx[0] = i;\n }\n }\n return idx;\n }\n\n diag() {\n let min = Math.min(this.rows, this.columns);\n let diag = [];\n for (let i = 0; i < min; i++) {\n diag.push(this.get(i, i));\n }\n return diag;\n }\n\n norm(type = 'frobenius') {\n let result = 0;\n if (type === 'max') {\n return this.max();\n } else if (type === 'frobenius') {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n result = result + this.get(i, j) * this.get(i, j);\n }\n }\n return Math.sqrt(result);\n } else {\n throw new RangeError(`unknown norm type: ${type}`);\n }\n }\n\n cumulativeSum() {\n let sum = 0;\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n sum += this.get(i, j);\n this.set(i, j, sum);\n }\n }\n return this;\n }\n\n dot(vector2) {\n if (AbstractMatrix.isMatrix(vector2)) vector2 = vector2.to1DArray();\n let vector1 = this.to1DArray();\n if (vector1.length !== vector2.length) {\n throw new RangeError('vectors do not have the same size');\n }\n let dot = 0;\n for (let i = 0; i < vector1.length; i++) {\n dot += vector1[i] * vector2[i];\n }\n return dot;\n }\n\n mmul(other) {\n other = Matrix.checkMatrix(other);\n\n let m = this.rows;\n let n = this.columns;\n let p = other.columns;\n\n let result = new Matrix(m, p);\n\n let Bcolj = new Float64Array(n);\n for (let j = 0; j < p; j++) {\n for (let k = 0; k < n; k++) {\n Bcolj[k] = other.get(k, j);\n }\n\n for (let i = 0; i < m; i++) {\n let s = 0;\n for (let k = 0; k < n; k++) {\n s += this.get(i, k) * Bcolj[k];\n }\n\n result.set(i, j, s);\n }\n }\n return result;\n }\n\n strassen2x2(other) {\n other = Matrix.checkMatrix(other);\n let result = new Matrix(2, 2);\n const a11 = this.get(0, 0);\n const b11 = other.get(0, 0);\n const a12 = this.get(0, 1);\n const b12 = other.get(0, 1);\n const a21 = this.get(1, 0);\n const b21 = other.get(1, 0);\n const a22 = this.get(1, 1);\n const b22 = other.get(1, 1);\n\n // Compute intermediate values.\n const m1 = (a11 + a22) * (b11 + b22);\n const m2 = (a21 + a22) * b11;\n const m3 = a11 * (b12 - b22);\n const m4 = a22 * (b21 - b11);\n const m5 = (a11 + a12) * b22;\n const m6 = (a21 - a11) * (b11 + b12);\n const m7 = (a12 - a22) * (b21 + b22);\n\n // Combine intermediate values into the output.\n const c00 = m1 + m4 - m5 + m7;\n const c01 = m3 + m5;\n const c10 = m2 + m4;\n const c11 = m1 - m2 + m3 + m6;\n\n result.set(0, 0, c00);\n result.set(0, 1, c01);\n result.set(1, 0, c10);\n result.set(1, 1, c11);\n return result;\n }\n\n strassen3x3(other) {\n other = Matrix.checkMatrix(other);\n let result = new Matrix(3, 3);\n\n const a00 = this.get(0, 0);\n const a01 = this.get(0, 1);\n const a02 = this.get(0, 2);\n const a10 = this.get(1, 0);\n const a11 = this.get(1, 1);\n const a12 = this.get(1, 2);\n const a20 = this.get(2, 0);\n const a21 = this.get(2, 1);\n const a22 = this.get(2, 2);\n\n const b00 = other.get(0, 0);\n const b01 = other.get(0, 1);\n const b02 = other.get(0, 2);\n const b10 = other.get(1, 0);\n const b11 = other.get(1, 1);\n const b12 = other.get(1, 2);\n const b20 = other.get(2, 0);\n const b21 = other.get(2, 1);\n const b22 = other.get(2, 2);\n\n const m1 = (a00 + a01 + a02 - a10 - a11 - a21 - a22) * b11;\n const m2 = (a00 - a10) * (-b01 + b11);\n const m3 = a11 * (-b00 + b01 + b10 - b11 - b12 - b20 + b22);\n const m4 = (-a00 + a10 + a11) * (b00 - b01 + b11);\n const m5 = (a10 + a11) * (-b00 + b01);\n const m6 = a00 * b00;\n const m7 = (-a00 + a20 + a21) * (b00 - b02 + b12);\n const m8 = (-a00 + a20) * (b02 - b12);\n const m9 = (a20 + a21) * (-b00 + b02);\n const m10 = (a00 + a01 + a02 - a11 - a12 - a20 - a21) * b12;\n const m11 = a21 * (-b00 + b02 + b10 - b11 - b12 - b20 + b21);\n const m12 = (-a02 + a21 + a22) * (b11 + b20 - b21);\n const m13 = (a02 - a22) * (b11 - b21);\n const m14 = a02 * b20;\n const m15 = (a21 + a22) * (-b20 + b21);\n const m16 = (-a02 + a11 + a12) * (b12 + b20 - b22);\n const m17 = (a02 - a12) * (b12 - b22);\n const m18 = (a11 + a12) * (-b20 + b22);\n const m19 = a01 * b10;\n const m20 = a12 * b21;\n const m21 = a10 * b02;\n const m22 = a20 * b01;\n const m23 = a22 * b22;\n\n const c00 = m6 + m14 + m19;\n const c01 = m1 + m4 + m5 + m6 + m12 + m14 + m15;\n const c02 = m6 + m7 + m9 + m10 + m14 + m16 + m18;\n const c10 = m2 + m3 + m4 + m6 + m14 + m16 + m17;\n const c11 = m2 + m4 + m5 + m6 + m20;\n const c12 = m14 + m16 + m17 + m18 + m21;\n const c20 = m6 + m7 + m8 + m11 + m12 + m13 + m14;\n const c21 = m12 + m13 + m14 + m15 + m22;\n const c22 = m6 + m7 + m8 + m9 + m23;\n\n result.set(0, 0, c00);\n result.set(0, 1, c01);\n result.set(0, 2, c02);\n result.set(1, 0, c10);\n result.set(1, 1, c11);\n result.set(1, 2, c12);\n result.set(2, 0, c20);\n result.set(2, 1, c21);\n result.set(2, 2, c22);\n return result;\n }\n\n mmulStrassen(y) {\n y = Matrix.checkMatrix(y);\n let x = this.clone();\n let r1 = x.rows;\n let c1 = x.columns;\n let r2 = y.rows;\n let c2 = y.columns;\n if (c1 !== r2) {\n // eslint-disable-next-line no-console\n console.warn(\n `Multiplying ${r1} x ${c1} and ${r2} x ${c2} matrix: dimensions do not match.`,\n );\n }\n\n // Put a matrix into the top left of a matrix of zeros.\n // `rows` and `cols` are the dimensions of the output matrix.\n function embed(mat, rows, cols) {\n let r = mat.rows;\n let c = mat.columns;\n if (r === rows && c === cols) {\n return mat;\n } else {\n let resultat = AbstractMatrix.zeros(rows, cols);\n resultat = resultat.setSubMatrix(mat, 0, 0);\n return resultat;\n }\n }\n\n // Make sure both matrices are the same size.\n // This is exclusively for simplicity:\n // this algorithm can be implemented with matrices of different sizes.\n\n let r = Math.max(r1, r2);\n let c = Math.max(c1, c2);\n x = embed(x, r, c);\n y = embed(y, r, c);\n\n // Our recursive multiplication function.\n function blockMult(a, b, rows, cols) {\n // For small matrices, resort to naive multiplication.\n if (rows <= 512 || cols <= 512) {\n return a.mmul(b); // a is equivalent to this\n }\n\n // Apply dynamic padding.\n if (rows % 2 === 1 && cols % 2 === 1) {\n a = embed(a, rows + 1, cols + 1);\n b = embed(b, rows + 1, cols + 1);\n } else if (rows % 2 === 1) {\n a = embed(a, rows + 1, cols);\n b = embed(b, rows + 1, cols);\n } else if (cols % 2 === 1) {\n a = embed(a, rows, cols + 1);\n b = embed(b, rows, cols + 1);\n }\n\n let halfRows = parseInt(a.rows / 2, 10);\n let halfCols = parseInt(a.columns / 2, 10);\n // Subdivide input matrices.\n let a11 = a.subMatrix(0, halfRows - 1, 0, halfCols - 1);\n let b11 = b.subMatrix(0, halfRows - 1, 0, halfCols - 1);\n\n let a12 = a.subMatrix(0, halfRows - 1, halfCols, a.columns - 1);\n let b12 = b.subMatrix(0, halfRows - 1, halfCols, b.columns - 1);\n\n let a21 = a.subMatrix(halfRows, a.rows - 1, 0, halfCols - 1);\n let b21 = b.subMatrix(halfRows, b.rows - 1, 0, halfCols - 1);\n\n let a22 = a.subMatrix(halfRows, a.rows - 1, halfCols, a.columns - 1);\n let b22 = b.subMatrix(halfRows, b.rows - 1, halfCols, b.columns - 1);\n\n // Compute intermediate values.\n let m1 = blockMult(\n AbstractMatrix.add(a11, a22),\n AbstractMatrix.add(b11, b22),\n halfRows,\n halfCols,\n );\n let m2 = blockMult(AbstractMatrix.add(a21, a22), b11, halfRows, halfCols);\n let m3 = blockMult(a11, AbstractMatrix.sub(b12, b22), halfRows, halfCols);\n let m4 = blockMult(a22, AbstractMatrix.sub(b21, b11), halfRows, halfCols);\n let m5 = blockMult(AbstractMatrix.add(a11, a12), b22, halfRows, halfCols);\n let m6 = blockMult(\n AbstractMatrix.sub(a21, a11),\n AbstractMatrix.add(b11, b12),\n halfRows,\n halfCols,\n );\n let m7 = blockMult(\n AbstractMatrix.sub(a12, a22),\n AbstractMatrix.add(b21, b22),\n halfRows,\n halfCols,\n );\n\n // Combine intermediate values into the output.\n let c11 = AbstractMatrix.add(m1, m4);\n c11.sub(m5);\n c11.add(m7);\n let c12 = AbstractMatrix.add(m3, m5);\n let c21 = AbstractMatrix.add(m2, m4);\n let c22 = AbstractMatrix.sub(m1, m2);\n c22.add(m3);\n c22.add(m6);\n\n // Crop output to the desired size (undo dynamic padding).\n let resultat = AbstractMatrix.zeros(2 * c11.rows, 2 * c11.columns);\n resultat = resultat.setSubMatrix(c11, 0, 0);\n resultat = resultat.setSubMatrix(c12, c11.rows, 0);\n resultat = resultat.setSubMatrix(c21, 0, c11.columns);\n resultat = resultat.setSubMatrix(c22, c11.rows, c11.columns);\n return resultat.subMatrix(0, rows - 1, 0, cols - 1);\n }\n\n return blockMult(x, y, r, c);\n }\n\n scaleRows(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1 } = options;\n if (!Number.isFinite(min)) throw new TypeError('min must be a number');\n if (!Number.isFinite(max)) throw new TypeError('max must be a number');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let i = 0; i < this.rows; i++) {\n const row = this.getRow(i);\n if (row.length > 0) {\n rescale(row, { min, max, output: row });\n }\n newMatrix.setRow(i, row);\n }\n return newMatrix;\n }\n\n scaleColumns(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1 } = options;\n if (!Number.isFinite(min)) throw new TypeError('min must be a number');\n if (!Number.isFinite(max)) throw new TypeError('max must be a number');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let i = 0; i < this.columns; i++) {\n const column = this.getColumn(i);\n if (column.length) {\n rescale(column, {\n min: min,\n max: max,\n output: column,\n });\n }\n newMatrix.setColumn(i, column);\n }\n return newMatrix;\n }\n\n flipRows() {\n const middle = Math.ceil(this.columns / 2);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < middle; j++) {\n let first = this.get(i, j);\n let last = this.get(i, this.columns - 1 - j);\n this.set(i, j, last);\n this.set(i, this.columns - 1 - j, first);\n }\n }\n return this;\n }\n\n flipColumns() {\n const middle = Math.ceil(this.rows / 2);\n for (let j = 0; j < this.columns; j++) {\n for (let i = 0; i < middle; i++) {\n let first = this.get(i, j);\n let last = this.get(this.rows - 1 - i, j);\n this.set(i, j, last);\n this.set(this.rows - 1 - i, j, first);\n }\n }\n return this;\n }\n\n kroneckerProduct(other) {\n other = Matrix.checkMatrix(other);\n\n let m = this.rows;\n let n = this.columns;\n let p = other.rows;\n let q = other.columns;\n\n let result = new Matrix(m * p, n * q);\n for (let i = 0; i < m; i++) {\n for (let j = 0; j < n; j++) {\n for (let k = 0; k < p; k++) {\n for (let l = 0; l < q; l++) {\n result.set(p * i + k, q * j + l, this.get(i, j) * other.get(k, l));\n }\n }\n }\n }\n return result;\n }\n\n kroneckerSum(other) {\n other = Matrix.checkMatrix(other);\n if (!this.isSquare() || !other.isSquare()) {\n throw new Error('Kronecker Sum needs two Square Matrices');\n }\n let m = this.rows;\n let n = other.rows;\n let AxI = this.kroneckerProduct(Matrix.eye(n, n));\n let IxB = Matrix.eye(m, m).kroneckerProduct(other);\n return AxI.add(IxB);\n }\n\n transpose() {\n let result = new Matrix(this.columns, this.rows);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n result.set(j, i, this.get(i, j));\n }\n }\n return result;\n }\n\n sortRows(compareFunction = compareNumbers) {\n for (let i = 0; i < this.rows; i++) {\n this.setRow(i, this.getRow(i).sort(compareFunction));\n }\n return this;\n }\n\n sortColumns(compareFunction = compareNumbers) {\n for (let i = 0; i < this.columns; i++) {\n this.setColumn(i, this.getColumn(i).sort(compareFunction));\n }\n return this;\n }\n\n subMatrix(startRow, endRow, startColumn, endColumn) {\n checkRange(this, startRow, endRow, startColumn, endColumn);\n let newMatrix = new Matrix(\n endRow - startRow + 1,\n endColumn - startColumn + 1,\n );\n for (let i = startRow; i <= endRow; i++) {\n for (let j = startColumn; j <= endColumn; j++) {\n newMatrix.set(i - startRow, j - startColumn, this.get(i, j));\n }\n }\n return newMatrix;\n }\n\n subMatrixRow(indices, startColumn, endColumn) {\n if (startColumn === undefined) startColumn = 0;\n if (endColumn === undefined) endColumn = this.columns - 1;\n if (\n startColumn > endColumn ||\n startColumn < 0 ||\n startColumn >= this.columns ||\n endColumn < 0 ||\n endColumn >= this.columns\n ) {\n throw new RangeError('Argument out of range');\n }\n\n let newMatrix = new Matrix(indices.length, endColumn - startColumn + 1);\n for (let i = 0; i < indices.length; i++) {\n for (let j = startColumn; j <= endColumn; j++) {\n if (indices[i] < 0 || indices[i] >= this.rows) {\n throw new RangeError(`Row index out of range: ${indices[i]}`);\n }\n newMatrix.set(i, j - startColumn, this.get(indices[i], j));\n }\n }\n return newMatrix;\n }\n\n subMatrixColumn(indices, startRow, endRow) {\n if (startRow === undefined) startRow = 0;\n if (endRow === undefined) endRow = this.rows - 1;\n if (\n startRow > endRow ||\n startRow < 0 ||\n startRow >= this.rows ||\n endRow < 0 ||\n endRow >= this.rows\n ) {\n throw new RangeError('Argument out of range');\n }\n\n let newMatrix = new Matrix(endRow - startRow + 1, indices.length);\n for (let i = 0; i < indices.length; i++) {\n for (let j = startRow; j <= endRow; j++) {\n if (indices[i] < 0 || indices[i] >= this.columns) {\n throw new RangeError(`Column index out of range: ${indices[i]}`);\n }\n newMatrix.set(j - startRow, i, this.get(j, indices[i]));\n }\n }\n return newMatrix;\n }\n\n setSubMatrix(matrix, startRow, startColumn) {\n matrix = Matrix.checkMatrix(matrix);\n if (matrix.isEmpty()) {\n return this;\n }\n let endRow = startRow + matrix.rows - 1;\n let endColumn = startColumn + matrix.columns - 1;\n checkRange(this, startRow, endRow, startColumn, endColumn);\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n this.set(startRow + i, startColumn + j, matrix.get(i, j));\n }\n }\n return this;\n }\n\n selection(rowIndices, columnIndices) {\n checkRowIndices(this, rowIndices);\n checkColumnIndices(this, columnIndices);\n let newMatrix = new Matrix(rowIndices.length, columnIndices.length);\n for (let i = 0; i < rowIndices.length; i++) {\n let rowIndex = rowIndices[i];\n for (let j = 0; j < columnIndices.length; j++) {\n let columnIndex = columnIndices[j];\n newMatrix.set(i, j, this.get(rowIndex, columnIndex));\n }\n }\n return newMatrix;\n }\n\n trace() {\n let min = Math.min(this.rows, this.columns);\n let trace = 0;\n for (let i = 0; i < min; i++) {\n trace += this.get(i, i);\n }\n return trace;\n }\n\n clone() {\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n newMatrix.set(row, column, this.get(row, column));\n }\n }\n return newMatrix;\n }\n\n sum(by) {\n switch (by) {\n case 'row':\n return sumByRow(this);\n case 'column':\n return sumByColumn(this);\n case undefined:\n return sumAll(this);\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n product(by) {\n switch (by) {\n case 'row':\n return productByRow(this);\n case 'column':\n return productByColumn(this);\n case undefined:\n return productAll(this);\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n mean(by) {\n const sum = this.sum(by);\n switch (by) {\n case 'row': {\n for (let i = 0; i < this.rows; i++) {\n sum[i] /= this.columns;\n }\n return sum;\n }\n case 'column': {\n for (let i = 0; i < this.columns; i++) {\n sum[i] /= this.rows;\n }\n return sum;\n }\n case undefined:\n return sum / this.size;\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n variance(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { unbiased = true, mean = this.mean(by) } = options;\n if (typeof unbiased !== 'boolean') {\n throw new TypeError('unbiased must be a boolean');\n }\n switch (by) {\n case 'row': {\n if (!isAnyArray(mean)) {\n throw new TypeError('mean must be an array');\n }\n return varianceByRow(this, unbiased, mean);\n }\n case 'column': {\n if (!isAnyArray(mean)) {\n throw new TypeError('mean must be an array');\n }\n return varianceByColumn(this, unbiased, mean);\n }\n case undefined: {\n if (typeof mean !== 'number') {\n throw new TypeError('mean must be a number');\n }\n return varianceAll(this, unbiased, mean);\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n standardDeviation(by, options) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n const variance = this.variance(by, options);\n if (by === undefined) {\n return Math.sqrt(variance);\n } else {\n for (let i = 0; i < variance.length; i++) {\n variance[i] = Math.sqrt(variance[i]);\n }\n return variance;\n }\n }\n\n center(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { center = this.mean(by) } = options;\n switch (by) {\n case 'row': {\n if (!isAnyArray(center)) {\n throw new TypeError('center must be an array');\n }\n centerByRow(this, center);\n return this;\n }\n case 'column': {\n if (!isAnyArray(center)) {\n throw new TypeError('center must be an array');\n }\n centerByColumn(this, center);\n return this;\n }\n case undefined: {\n if (typeof center !== 'number') {\n throw new TypeError('center must be a number');\n }\n centerAll(this, center);\n return this;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n scale(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n let scale = options.scale;\n switch (by) {\n case 'row': {\n if (scale === undefined) {\n scale = getScaleByRow(this);\n } else if (!isAnyArray(scale)) {\n throw new TypeError('scale must be an array');\n }\n scaleByRow(this, scale);\n return this;\n }\n case 'column': {\n if (scale === undefined) {\n scale = getScaleByColumn(this);\n } else if (!isAnyArray(scale)) {\n throw new TypeError('scale must be an array');\n }\n scaleByColumn(this, scale);\n return this;\n }\n case undefined: {\n if (scale === undefined) {\n scale = getScaleAll(this);\n } else if (typeof scale !== 'number') {\n throw new TypeError('scale must be a number');\n }\n scaleAll(this, scale);\n return this;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n toString(options) {\n return inspectMatrixWithOptions(this, options);\n }\n}\n\nAbstractMatrix.prototype.klass = 'Matrix';\nif (typeof Symbol !== 'undefined') {\n AbstractMatrix.prototype[Symbol.for('nodejs.util.inspect.custom')] =\n inspectMatrix;\n}\n\nfunction compareNumbers(a, b) {\n return a - b;\n}\n\nfunction isArrayOfNumbers(array) {\n return array.every((element) => {\n return typeof element === 'number';\n });\n}\n\n// Synonyms\nAbstractMatrix.random = AbstractMatrix.rand;\nAbstractMatrix.randomInt = AbstractMatrix.randInt;\nAbstractMatrix.diagonal = AbstractMatrix.diag;\nAbstractMatrix.prototype.diagonal = AbstractMatrix.prototype.diag;\nAbstractMatrix.identity = AbstractMatrix.eye;\nAbstractMatrix.prototype.negate = AbstractMatrix.prototype.neg;\nAbstractMatrix.prototype.tensorProduct =\n AbstractMatrix.prototype.kroneckerProduct;\n\nexport default class Matrix extends AbstractMatrix {\n constructor(nRows, nColumns) {\n super();\n if (Matrix.isMatrix(nRows)) {\n // eslint-disable-next-line no-constructor-return\n return nRows.clone();\n } else if (Number.isInteger(nRows) && nRows >= 0) {\n // Create an empty matrix\n this.data = [];\n if (Number.isInteger(nColumns) && nColumns >= 0) {\n for (let i = 0; i < nRows; i++) {\n this.data.push(new Float64Array(nColumns));\n }\n } else {\n throw new TypeError('nColumns must be a positive integer');\n }\n } else if (isAnyArray(nRows)) {\n // Copy the values from the 2D array\n const arrayData = nRows;\n nRows = arrayData.length;\n nColumns = nRows ? arrayData[0].length : 0;\n if (typeof nColumns !== 'number') {\n throw new TypeError(\n 'Data must be a 2D array with at least one element',\n );\n }\n this.data = [];\n for (let i = 0; i < nRows; i++) {\n if (arrayData[i].length !== nColumns) {\n throw new RangeError('Inconsistent array dimensions');\n }\n if (!isArrayOfNumbers(arrayData[i])) {\n throw new TypeError('Input data contains non-numeric values');\n }\n this.data.push(Float64Array.from(arrayData[i]));\n }\n } else {\n throw new TypeError(\n 'First argument must be a positive number or an array',\n );\n }\n this.rows = nRows;\n this.columns = nColumns;\n }\n\n set(rowIndex, columnIndex, value) {\n this.data[rowIndex][columnIndex] = value;\n return this;\n }\n\n get(rowIndex, columnIndex) {\n return this.data[rowIndex][columnIndex];\n }\n\n removeRow(index) {\n checkRowIndex(this, index);\n this.data.splice(index, 1);\n this.rows -= 1;\n return this;\n }\n\n addRow(index, array) {\n if (array === undefined) {\n array = index;\n index = this.rows;\n }\n checkRowIndex(this, index, true);\n array = Float64Array.from(checkRowVector(this, array));\n this.data.splice(index, 0, array);\n this.rows += 1;\n return this;\n }\n\n removeColumn(index) {\n checkColumnIndex(this, index);\n for (let i = 0; i < this.rows; i++) {\n const newRow = new Float64Array(this.columns - 1);\n for (let j = 0; j < index; j++) {\n newRow[j] = this.data[i][j];\n }\n for (let j = index + 1; j < this.columns; j++) {\n newRow[j - 1] = this.data[i][j];\n }\n this.data[i] = newRow;\n }\n this.columns -= 1;\n return this;\n }\n\n addColumn(index, array) {\n if (typeof array === 'undefined') {\n array = index;\n index = this.columns;\n }\n checkColumnIndex(this, index, true);\n array = checkColumnVector(this, array);\n for (let i = 0; i < this.rows; i++) {\n const newRow = new Float64Array(this.columns + 1);\n let j = 0;\n for (; j < index; j++) {\n newRow[j] = this.data[i][j];\n }\n newRow[j++] = array[i];\n for (; j < this.columns + 1; j++) {\n newRow[j] = this.data[i][j - 1];\n }\n this.data[i] = newRow;\n }\n this.columns += 1;\n return this;\n }\n}\n\ninstallMathOperations(AbstractMatrix, Matrix);\n","import { newArray } from './util';\n\nexport function sumByRow(matrix) {\n let sum = newArray(matrix.rows);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[i] += matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function sumByColumn(matrix) {\n let sum = newArray(matrix.columns);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[j] += matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function sumAll(matrix) {\n let v = 0;\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n v += matrix.get(i, j);\n }\n }\n return v;\n}\n\nexport function productByRow(matrix) {\n let sum = newArray(matrix.rows, 1);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[i] *= matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function productByColumn(matrix) {\n let sum = newArray(matrix.columns, 1);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[j] *= matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function productAll(matrix) {\n let v = 1;\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n v *= matrix.get(i, j);\n }\n }\n return v;\n}\n\nexport function varianceByRow(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const variance = [];\n\n for (let i = 0; i < rows; i++) {\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let j = 0; j < cols; j++) {\n x = matrix.get(i, j) - mean[i];\n sum1 += x;\n sum2 += x * x;\n }\n if (unbiased) {\n variance.push((sum2 - (sum1 * sum1) / cols) / (cols - 1));\n } else {\n variance.push((sum2 - (sum1 * sum1) / cols) / cols);\n }\n }\n return variance;\n}\n\nexport function varianceByColumn(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const variance = [];\n\n for (let j = 0; j < cols; j++) {\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let i = 0; i < rows; i++) {\n x = matrix.get(i, j) - mean[j];\n sum1 += x;\n sum2 += x * x;\n }\n if (unbiased) {\n variance.push((sum2 - (sum1 * sum1) / rows) / (rows - 1));\n } else {\n variance.push((sum2 - (sum1 * sum1) / rows) / rows);\n }\n }\n return variance;\n}\n\nexport function varianceAll(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const size = rows * cols;\n\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n x = matrix.get(i, j) - mean;\n sum1 += x;\n sum2 += x * x;\n }\n }\n if (unbiased) {\n return (sum2 - (sum1 * sum1) / size) / (size - 1);\n } else {\n return (sum2 - (sum1 * sum1) / size) / size;\n }\n}\n\nexport function centerByRow(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean[i]);\n }\n }\n}\n\nexport function centerByColumn(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean[j]);\n }\n }\n}\n\nexport function centerAll(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean);\n }\n }\n}\n\nexport function getScaleByRow(matrix) {\n const scale = [];\n for (let i = 0; i < matrix.rows; i++) {\n let sum = 0;\n for (let j = 0; j < matrix.columns; j++) {\n sum += Math.pow(matrix.get(i, j), 2) / (matrix.columns - 1);\n }\n scale.push(Math.sqrt(sum));\n }\n return scale;\n}\n\nexport function scaleByRow(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale[i]);\n }\n }\n}\n\nexport function getScaleByColumn(matrix) {\n const scale = [];\n for (let j = 0; j < matrix.columns; j++) {\n let sum = 0;\n for (let i = 0; i < matrix.rows; i++) {\n sum += Math.pow(matrix.get(i, j), 2) / (matrix.rows - 1);\n }\n scale.push(Math.sqrt(sum));\n }\n return scale;\n}\n\nexport function scaleByColumn(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale[j]);\n }\n }\n}\n\nexport function getScaleAll(matrix) {\n const divider = matrix.size - 1;\n let sum = 0;\n for (let j = 0; j < matrix.columns; j++) {\n for (let i = 0; i < matrix.rows; i++) {\n sum += Math.pow(matrix.get(i, j), 2) / divider;\n }\n }\n return Math.sqrt(sum);\n}\n\nexport function scaleAll(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale);\n }\n }\n}\n","export function installMathOperations(AbstractMatrix, Matrix) {\n AbstractMatrix.prototype.add = function add(value) {\n if (typeof value === 'number') return this.addS(value);\n return this.addM(value);\n };\n\n AbstractMatrix.prototype.addS = function addS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.addM = function addM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.add = function add(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.add(value);\n };\n\n AbstractMatrix.prototype.sub = function sub(value) {\n if (typeof value === 'number') return this.subS(value);\n return this.subM(value);\n };\n\n AbstractMatrix.prototype.subS = function subS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.subM = function subM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.sub = function sub(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sub(value);\n };\n AbstractMatrix.prototype.subtract = AbstractMatrix.prototype.sub;\n AbstractMatrix.prototype.subtractS = AbstractMatrix.prototype.subS;\n AbstractMatrix.prototype.subtractM = AbstractMatrix.prototype.subM;\n AbstractMatrix.subtract = AbstractMatrix.sub;\n\n AbstractMatrix.prototype.mul = function mul(value) {\n if (typeof value === 'number') return this.mulS(value);\n return this.mulM(value);\n };\n\n AbstractMatrix.prototype.mulS = function mulS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.mulM = function mulM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.mul = function mul(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.mul(value);\n };\n AbstractMatrix.prototype.multiply = AbstractMatrix.prototype.mul;\n AbstractMatrix.prototype.multiplyS = AbstractMatrix.prototype.mulS;\n AbstractMatrix.prototype.multiplyM = AbstractMatrix.prototype.mulM;\n AbstractMatrix.multiply = AbstractMatrix.mul;\n\n AbstractMatrix.prototype.div = function div(value) {\n if (typeof value === 'number') return this.divS(value);\n return this.divM(value);\n };\n\n AbstractMatrix.prototype.divS = function divS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.divM = function divM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.div = function div(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.div(value);\n };\n AbstractMatrix.prototype.divide = AbstractMatrix.prototype.div;\n AbstractMatrix.prototype.divideS = AbstractMatrix.prototype.divS;\n AbstractMatrix.prototype.divideM = AbstractMatrix.prototype.divM;\n AbstractMatrix.divide = AbstractMatrix.div;\n\n AbstractMatrix.prototype.mod = function mod(value) {\n if (typeof value === 'number') return this.modS(value);\n return this.modM(value);\n };\n\n AbstractMatrix.prototype.modS = function modS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) % value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.modM = function modM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) % matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.mod = function mod(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.mod(value);\n };\n AbstractMatrix.prototype.modulus = AbstractMatrix.prototype.mod;\n AbstractMatrix.prototype.modulusS = AbstractMatrix.prototype.modS;\n AbstractMatrix.prototype.modulusM = AbstractMatrix.prototype.modM;\n AbstractMatrix.modulus = AbstractMatrix.mod;\n\n AbstractMatrix.prototype.and = function and(value) {\n if (typeof value === 'number') return this.andS(value);\n return this.andM(value);\n };\n\n AbstractMatrix.prototype.andS = function andS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) & value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.andM = function andM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) & matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.and = function and(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.and(value);\n };\n\n AbstractMatrix.prototype.or = function or(value) {\n if (typeof value === 'number') return this.orS(value);\n return this.orM(value);\n };\n\n AbstractMatrix.prototype.orS = function orS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) | value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.orM = function orM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) | matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.or = function or(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.or(value);\n };\n\n AbstractMatrix.prototype.xor = function xor(value) {\n if (typeof value === 'number') return this.xorS(value);\n return this.xorM(value);\n };\n\n AbstractMatrix.prototype.xorS = function xorS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) ^ value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.xorM = function xorM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) ^ matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.xor = function xor(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.xor(value);\n };\n\n AbstractMatrix.prototype.leftShift = function leftShift(value) {\n if (typeof value === 'number') return this.leftShiftS(value);\n return this.leftShiftM(value);\n };\n\n AbstractMatrix.prototype.leftShiftS = function leftShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) << value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.leftShiftM = function leftShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) << matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.leftShift = function leftShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.leftShift(value);\n };\n\n AbstractMatrix.prototype.signPropagatingRightShift = function signPropagatingRightShift(value) {\n if (typeof value === 'number') return this.signPropagatingRightShiftS(value);\n return this.signPropagatingRightShiftM(value);\n };\n\n AbstractMatrix.prototype.signPropagatingRightShiftS = function signPropagatingRightShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >> value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.signPropagatingRightShiftM = function signPropagatingRightShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >> matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.signPropagatingRightShift = function signPropagatingRightShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.signPropagatingRightShift(value);\n };\n\n AbstractMatrix.prototype.rightShift = function rightShift(value) {\n if (typeof value === 'number') return this.rightShiftS(value);\n return this.rightShiftM(value);\n };\n\n AbstractMatrix.prototype.rightShiftS = function rightShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >>> value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.rightShiftM = function rightShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >>> matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.rightShift = function rightShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.rightShift(value);\n };\n AbstractMatrix.prototype.zeroFillRightShift = AbstractMatrix.prototype.rightShift;\n AbstractMatrix.prototype.zeroFillRightShiftS = AbstractMatrix.prototype.rightShiftS;\n AbstractMatrix.prototype.zeroFillRightShiftM = AbstractMatrix.prototype.rightShiftM;\n AbstractMatrix.zeroFillRightShift = AbstractMatrix.rightShift;\n\n AbstractMatrix.prototype.not = function not() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, ~(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.not = function not(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.not();\n };\n\n AbstractMatrix.prototype.abs = function abs() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.abs(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.abs = function abs(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.abs();\n };\n\n AbstractMatrix.prototype.acos = function acos() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.acos(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.acos = function acos(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.acos();\n };\n\n AbstractMatrix.prototype.acosh = function acosh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.acosh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.acosh = function acosh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.acosh();\n };\n\n AbstractMatrix.prototype.asin = function asin() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.asin(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.asin = function asin(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.asin();\n };\n\n AbstractMatrix.prototype.asinh = function asinh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.asinh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.asinh = function asinh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.asinh();\n };\n\n AbstractMatrix.prototype.atan = function atan() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.atan(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.atan = function atan(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.atan();\n };\n\n AbstractMatrix.prototype.atanh = function atanh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.atanh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.atanh = function atanh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.atanh();\n };\n\n AbstractMatrix.prototype.cbrt = function cbrt() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cbrt(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cbrt = function cbrt(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cbrt();\n };\n\n AbstractMatrix.prototype.ceil = function ceil() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.ceil(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.ceil = function ceil(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.ceil();\n };\n\n AbstractMatrix.prototype.clz32 = function clz32() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.clz32(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.clz32 = function clz32(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.clz32();\n };\n\n AbstractMatrix.prototype.cos = function cos() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cos(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cos = function cos(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cos();\n };\n\n AbstractMatrix.prototype.cosh = function cosh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cosh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cosh = function cosh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cosh();\n };\n\n AbstractMatrix.prototype.exp = function exp() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.exp(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.exp = function exp(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.exp();\n };\n\n AbstractMatrix.prototype.expm1 = function expm1() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.expm1(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.expm1 = function expm1(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.expm1();\n };\n\n AbstractMatrix.prototype.floor = function floor() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.floor(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.floor = function floor(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.floor();\n };\n\n AbstractMatrix.prototype.fround = function fround() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.fround(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.fround = function fround(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.fround();\n };\n\n AbstractMatrix.prototype.log = function log() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log = function log(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log();\n };\n\n AbstractMatrix.prototype.log1p = function log1p() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log1p(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log1p = function log1p(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log1p();\n };\n\n AbstractMatrix.prototype.log10 = function log10() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log10(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log10 = function log10(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log10();\n };\n\n AbstractMatrix.prototype.log2 = function log2() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log2(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log2 = function log2(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log2();\n };\n\n AbstractMatrix.prototype.round = function round() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.round(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.round = function round(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.round();\n };\n\n AbstractMatrix.prototype.sign = function sign() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sign(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sign = function sign(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sign();\n };\n\n AbstractMatrix.prototype.sin = function sin() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sin(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sin = function sin(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sin();\n };\n\n AbstractMatrix.prototype.sinh = function sinh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sinh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sinh = function sinh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sinh();\n };\n\n AbstractMatrix.prototype.sqrt = function sqrt() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sqrt(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sqrt = function sqrt(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sqrt();\n };\n\n AbstractMatrix.prototype.tan = function tan() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.tan(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.tan = function tan(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.tan();\n };\n\n AbstractMatrix.prototype.tanh = function tanh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.tanh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.tanh = function tanh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.tanh();\n };\n\n AbstractMatrix.prototype.trunc = function trunc() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.trunc(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.trunc = function trunc(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.trunc();\n };\n\n AbstractMatrix.pow = function pow(matrix, arg0) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.pow(arg0);\n };\n\n AbstractMatrix.prototype.pow = function pow(value) {\n if (typeof value === 'number') return this.powS(value);\n return this.powM(value);\n };\n\n AbstractMatrix.prototype.powS = function powS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.pow(this.get(i, j), value));\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.powM = function powM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.pow(this.get(i, j), matrix.get(i, j)));\n }\n }\n return this;\n };\n}\n","import { AbstractMatrix } from '../matrix';\n\nexport default class WrapperMatrix2D extends AbstractMatrix {\n constructor(data) {\n super();\n this.data = data;\n this.rows = data.length;\n this.columns = data[0].length;\n }\n\n set(rowIndex, columnIndex, value) {\n this.data[rowIndex][columnIndex] = value;\n return this;\n }\n\n get(rowIndex, columnIndex) {\n return this.data[rowIndex][columnIndex];\n }\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nexport default class LuDecomposition {\n constructor(matrix) {\n matrix = WrapperMatrix2D.checkMatrix(matrix);\n\n let lu = matrix.clone();\n let rows = lu.rows;\n let columns = lu.columns;\n let pivotVector = new Float64Array(rows);\n let pivotSign = 1;\n let i, j, k, p, s, t, v;\n let LUcolj, kmax;\n\n for (i = 0; i < rows; i++) {\n pivotVector[i] = i;\n }\n\n LUcolj = new Float64Array(rows);\n\n for (j = 0; j < columns; j++) {\n for (i = 0; i < rows; i++) {\n LUcolj[i] = lu.get(i, j);\n }\n\n for (i = 0; i < rows; i++) {\n kmax = Math.min(i, j);\n s = 0;\n for (k = 0; k < kmax; k++) {\n s += lu.get(i, k) * LUcolj[k];\n }\n LUcolj[i] -= s;\n lu.set(i, j, LUcolj[i]);\n }\n\n p = j;\n for (i = j + 1; i < rows; i++) {\n if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {\n p = i;\n }\n }\n\n if (p !== j) {\n for (k = 0; k < columns; k++) {\n t = lu.get(p, k);\n lu.set(p, k, lu.get(j, k));\n lu.set(j, k, t);\n }\n\n v = pivotVector[p];\n pivotVector[p] = pivotVector[j];\n pivotVector[j] = v;\n\n pivotSign = -pivotSign;\n }\n\n if (j < rows && lu.get(j, j) !== 0) {\n for (i = j + 1; i < rows; i++) {\n lu.set(i, j, lu.get(i, j) / lu.get(j, j));\n }\n }\n }\n\n this.LU = lu;\n this.pivotVector = pivotVector;\n this.pivotSign = pivotSign;\n }\n\n isSingular() {\n let data = this.LU;\n let col = data.columns;\n for (let j = 0; j < col; j++) {\n if (data.get(j, j) === 0) {\n return true;\n }\n }\n return false;\n }\n\n solve(value) {\n value = Matrix.checkMatrix(value);\n\n let lu = this.LU;\n let rows = lu.rows;\n\n if (rows !== value.rows) {\n throw new Error('Invalid matrix dimensions');\n }\n if (this.isSingular()) {\n throw new Error('LU matrix is singular');\n }\n\n let count = value.columns;\n let X = value.subMatrixRow(this.pivotVector, 0, count - 1);\n let columns = lu.columns;\n let i, j, k;\n\n for (k = 0; k < columns; k++) {\n for (i = k + 1; i < columns; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * lu.get(i, k));\n }\n }\n }\n for (k = columns - 1; k >= 0; k--) {\n for (j = 0; j < count; j++) {\n X.set(k, j, X.get(k, j) / lu.get(k, k));\n }\n for (i = 0; i < k; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * lu.get(i, k));\n }\n }\n }\n return X;\n }\n\n get determinant() {\n let data = this.LU;\n if (!data.isSquare()) {\n throw new Error('Matrix must be square');\n }\n let determinant = this.pivotSign;\n let col = data.columns;\n for (let j = 0; j < col; j++) {\n determinant *= data.get(j, j);\n }\n return determinant;\n }\n\n get lowerTriangularMatrix() {\n let data = this.LU;\n let rows = data.rows;\n let columns = data.columns;\n let X = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n if (i > j) {\n X.set(i, j, data.get(i, j));\n } else if (i === j) {\n X.set(i, j, 1);\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get upperTriangularMatrix() {\n let data = this.LU;\n let rows = data.rows;\n let columns = data.columns;\n let X = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n if (i <= j) {\n X.set(i, j, data.get(i, j));\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get pivotPermutationVector() {\n return Array.from(this.pivotVector);\n }\n}\n","export function hypotenuse(a, b) {\n let r = 0;\n if (Math.abs(a) > Math.abs(b)) {\n r = b / a;\n return Math.abs(a) * Math.sqrt(1 + r * r);\n }\n if (b !== 0) {\n r = a / b;\n return Math.abs(b) * Math.sqrt(1 + r * r);\n }\n return 0;\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nimport { hypotenuse } from './util';\n\nexport default class QrDecomposition {\n constructor(value) {\n value = WrapperMatrix2D.checkMatrix(value);\n\n let qr = value.clone();\n let m = value.rows;\n let n = value.columns;\n let rdiag = new Float64Array(n);\n let i, j, k, s;\n\n for (k = 0; k < n; k++) {\n let nrm = 0;\n for (i = k; i < m; i++) {\n nrm = hypotenuse(nrm, qr.get(i, k));\n }\n if (nrm !== 0) {\n if (qr.get(k, k) < 0) {\n nrm = -nrm;\n }\n for (i = k; i < m; i++) {\n qr.set(i, k, qr.get(i, k) / nrm);\n }\n qr.set(k, k, qr.get(k, k) + 1);\n for (j = k + 1; j < n; j++) {\n s = 0;\n for (i = k; i < m; i++) {\n s += qr.get(i, k) * qr.get(i, j);\n }\n s = -s / qr.get(k, k);\n for (i = k; i < m; i++) {\n qr.set(i, j, qr.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n rdiag[k] = -nrm;\n }\n\n this.QR = qr;\n this.Rdiag = rdiag;\n }\n\n solve(value) {\n value = Matrix.checkMatrix(value);\n\n let qr = this.QR;\n let m = qr.rows;\n\n if (value.rows !== m) {\n throw new Error('Matrix row dimensions must agree');\n }\n if (!this.isFullRank()) {\n throw new Error('Matrix is rank deficient');\n }\n\n let count = value.columns;\n let X = value.clone();\n let n = qr.columns;\n let i, j, k, s;\n\n for (k = 0; k < n; k++) {\n for (j = 0; j < count; j++) {\n s = 0;\n for (i = k; i < m; i++) {\n s += qr.get(i, k) * X.get(i, j);\n }\n s = -s / qr.get(k, k);\n for (i = k; i < m; i++) {\n X.set(i, j, X.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n for (k = n - 1; k >= 0; k--) {\n for (j = 0; j < count; j++) {\n X.set(k, j, X.get(k, j) / this.Rdiag[k]);\n }\n for (i = 0; i < k; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * qr.get(i, k));\n }\n }\n }\n\n return X.subMatrix(0, n - 1, 0, count - 1);\n }\n\n isFullRank() {\n let columns = this.QR.columns;\n for (let i = 0; i < columns; i++) {\n if (this.Rdiag[i] === 0) {\n return false;\n }\n }\n return true;\n }\n\n get upperTriangularMatrix() {\n let qr = this.QR;\n let n = qr.columns;\n let X = new Matrix(n, n);\n let i, j;\n for (i = 0; i < n; i++) {\n for (j = 0; j < n; j++) {\n if (i < j) {\n X.set(i, j, qr.get(i, j));\n } else if (i === j) {\n X.set(i, j, this.Rdiag[i]);\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get orthogonalMatrix() {\n let qr = this.QR;\n let rows = qr.rows;\n let columns = qr.columns;\n let X = new Matrix(rows, columns);\n let i, j, k, s;\n\n for (k = columns - 1; k >= 0; k--) {\n for (i = 0; i < rows; i++) {\n X.set(i, k, 0);\n }\n X.set(k, k, 1);\n for (j = k; j < columns; j++) {\n if (qr.get(k, k) !== 0) {\n s = 0;\n for (i = k; i < rows; i++) {\n s += qr.get(i, k) * X.get(i, j);\n }\n\n s = -s / qr.get(k, k);\n\n for (i = k; i < rows; i++) {\n X.set(i, j, X.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n }\n return X;\n }\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nimport { hypotenuse } from './util';\n\nexport default class SingularValueDecomposition {\n constructor(value, options = {}) {\n value = WrapperMatrix2D.checkMatrix(value);\n\n if (value.isEmpty()) {\n throw new Error('Matrix must be non-empty');\n }\n\n let m = value.rows;\n let n = value.columns;\n\n const {\n computeLeftSingularVectors = true,\n computeRightSingularVectors = true,\n autoTranspose = false,\n } = options;\n\n let wantu = Boolean(computeLeftSingularVectors);\n let wantv = Boolean(computeRightSingularVectors);\n\n let swapped = false;\n let a;\n if (m < n) {\n if (!autoTranspose) {\n a = value.clone();\n // eslint-disable-next-line no-console\n console.warn(\n 'Computing SVD on a matrix with more columns than rows. Consider enabling autoTranspose',\n );\n } else {\n a = value.transpose();\n m = a.rows;\n n = a.columns;\n swapped = true;\n let aux = wantu;\n wantu = wantv;\n wantv = aux;\n }\n } else {\n a = value.clone();\n }\n\n let nu = Math.min(m, n);\n let ni = Math.min(m + 1, n);\n let s = new Float64Array(ni);\n let U = new Matrix(m, nu);\n let V = new Matrix(n, n);\n\n let e = new Float64Array(n);\n let work = new Float64Array(m);\n\n let si = new Float64Array(ni);\n for (let i = 0; i < ni; i++) si[i] = i;\n\n let nct = Math.min(m - 1, n);\n let nrt = Math.max(0, Math.min(n - 2, m));\n let mrc = Math.max(nct, nrt);\n\n for (let k = 0; k < mrc; k++) {\n if (k < nct) {\n s[k] = 0;\n for (let i = k; i < m; i++) {\n s[k] = hypotenuse(s[k], a.get(i, k));\n }\n if (s[k] !== 0) {\n if (a.get(k, k) < 0) {\n s[k] = -s[k];\n }\n for (let i = k; i < m; i++) {\n a.set(i, k, a.get(i, k) / s[k]);\n }\n a.set(k, k, a.get(k, k) + 1);\n }\n s[k] = -s[k];\n }\n\n for (let j = k + 1; j < n; j++) {\n if (k < nct && s[k] !== 0) {\n let t = 0;\n for (let i = k; i < m; i++) {\n t += a.get(i, k) * a.get(i, j);\n }\n t = -t / a.get(k, k);\n for (let i = k; i < m; i++) {\n a.set(i, j, a.get(i, j) + t * a.get(i, k));\n }\n }\n e[j] = a.get(k, j);\n }\n\n if (wantu && k < nct) {\n for (let i = k; i < m; i++) {\n U.set(i, k, a.get(i, k));\n }\n }\n\n if (k < nrt) {\n e[k] = 0;\n for (let i = k + 1; i < n; i++) {\n e[k] = hypotenuse(e[k], e[i]);\n }\n if (e[k] !== 0) {\n if (e[k + 1] < 0) {\n e[k] = 0 - e[k];\n }\n for (let i = k + 1; i < n; i++) {\n e[i] /= e[k];\n }\n e[k + 1] += 1;\n }\n e[k] = -e[k];\n if (k + 1 < m && e[k] !== 0) {\n for (let i = k + 1; i < m; i++) {\n work[i] = 0;\n }\n for (let i = k + 1; i < m; i++) {\n for (let j = k + 1; j < n; j++) {\n work[i] += e[j] * a.get(i, j);\n }\n }\n for (let j = k + 1; j < n; j++) {\n let t = -e[j] / e[k + 1];\n for (let i = k + 1; i < m; i++) {\n a.set(i, j, a.get(i, j) + t * work[i]);\n }\n }\n }\n if (wantv) {\n for (let i = k + 1; i < n; i++) {\n V.set(i, k, e[i]);\n }\n }\n }\n }\n\n let p = Math.min(n, m + 1);\n if (nct < n) {\n s[nct] = a.get(nct, nct);\n }\n if (m < p) {\n s[p - 1] = 0;\n }\n if (nrt + 1 < p) {\n e[nrt] = a.get(nrt, p - 1);\n }\n e[p - 1] = 0;\n\n if (wantu) {\n for (let j = nct; j < nu; j++) {\n for (let i = 0; i < m; i++) {\n U.set(i, j, 0);\n }\n U.set(j, j, 1);\n }\n for (let k = nct - 1; k >= 0; k--) {\n if (s[k] !== 0) {\n for (let j = k + 1; j < nu; j++) {\n let t = 0;\n for (let i = k; i < m; i++) {\n t += U.get(i, k) * U.get(i, j);\n }\n t = -t / U.get(k, k);\n for (let i = k; i < m; i++) {\n U.set(i, j, U.get(i, j) + t * U.get(i, k));\n }\n }\n for (let i = k; i < m; i++) {\n U.set(i, k, -U.get(i, k));\n }\n U.set(k, k, 1 + U.get(k, k));\n for (let i = 0; i < k - 1; i++) {\n U.set(i, k, 0);\n }\n } else {\n for (let i = 0; i < m; i++) {\n U.set(i, k, 0);\n }\n U.set(k, k, 1);\n }\n }\n }\n\n if (wantv) {\n for (let k = n - 1; k >= 0; k--) {\n if (k < nrt && e[k] !== 0) {\n for (let j = k + 1; j < n; j++) {\n let t = 0;\n for (let i = k + 1; i < n; i++) {\n t += V.get(i, k) * V.get(i, j);\n }\n t = -t / V.get(k + 1, k);\n for (let i = k + 1; i < n; i++) {\n V.set(i, j, V.get(i, j) + t * V.get(i, k));\n }\n }\n }\n for (let i = 0; i < n; i++) {\n V.set(i, k, 0);\n }\n V.set(k, k, 1);\n }\n }\n\n let pp = p - 1;\n let iter = 0;\n let eps = Number.EPSILON;\n while (p > 0) {\n let k, kase;\n for (k = p - 2; k >= -1; k--) {\n if (k === -1) {\n break;\n }\n const alpha =\n Number.MIN_VALUE + eps * Math.abs(s[k] + Math.abs(s[k + 1]));\n if (Math.abs(e[k]) <= alpha || Number.isNaN(e[k])) {\n e[k] = 0;\n break;\n }\n }\n if (k === p - 2) {\n kase = 4;\n } else {\n let ks;\n for (ks = p - 1; ks >= k; ks--) {\n if (ks === k) {\n break;\n }\n let t =\n (ks !== p ? Math.abs(e[ks]) : 0) +\n (ks !== k + 1 ? Math.abs(e[ks - 1]) : 0);\n if (Math.abs(s[ks]) <= eps * t) {\n s[ks] = 0;\n break;\n }\n }\n if (ks === k) {\n kase = 3;\n } else if (ks === p - 1) {\n kase = 1;\n } else {\n kase = 2;\n k = ks;\n }\n }\n\n k++;\n\n switch (kase) {\n case 1: {\n let f = e[p - 2];\n e[p - 2] = 0;\n for (let j = p - 2; j >= k; j--) {\n let t = hypotenuse(s[j], f);\n let cs = s[j] / t;\n let sn = f / t;\n s[j] = t;\n if (j !== k) {\n f = -sn * e[j - 1];\n e[j - 1] = cs * e[j - 1];\n }\n if (wantv) {\n for (let i = 0; i < n; i++) {\n t = cs * V.get(i, j) + sn * V.get(i, p - 1);\n V.set(i, p - 1, -sn * V.get(i, j) + cs * V.get(i, p - 1));\n V.set(i, j, t);\n }\n }\n }\n break;\n }\n case 2: {\n let f = e[k - 1];\n e[k - 1] = 0;\n for (let j = k; j < p; j++) {\n let t = hypotenuse(s[j], f);\n let cs = s[j] / t;\n let sn = f / t;\n s[j] = t;\n f = -sn * e[j];\n e[j] = cs * e[j];\n if (wantu) {\n for (let i = 0; i < m; i++) {\n t = cs * U.get(i, j) + sn * U.get(i, k - 1);\n U.set(i, k - 1, -sn * U.get(i, j) + cs * U.get(i, k - 1));\n U.set(i, j, t);\n }\n }\n }\n break;\n }\n case 3: {\n const scale = Math.max(\n Math.abs(s[p - 1]),\n Math.abs(s[p - 2]),\n Math.abs(e[p - 2]),\n Math.abs(s[k]),\n Math.abs(e[k]),\n );\n const sp = s[p - 1] / scale;\n const spm1 = s[p - 2] / scale;\n const epm1 = e[p - 2] / scale;\n const sk = s[k] / scale;\n const ek = e[k] / scale;\n const b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2;\n const c = sp * epm1 * (sp * epm1);\n let shift = 0;\n if (b !== 0 || c !== 0) {\n if (b < 0) {\n shift = 0 - Math.sqrt(b * b + c);\n } else {\n shift = Math.sqrt(b * b + c);\n }\n shift = c / (b + shift);\n }\n let f = (sk + sp) * (sk - sp) + shift;\n let g = sk * ek;\n for (let j = k; j < p - 1; j++) {\n let t = hypotenuse(f, g);\n if (t === 0) t = Number.MIN_VALUE;\n let cs = f / t;\n let sn = g / t;\n if (j !== k) {\n e[j - 1] = t;\n }\n f = cs * s[j] + sn * e[j];\n e[j] = cs * e[j] - sn * s[j];\n g = sn * s[j + 1];\n s[j + 1] = cs * s[j + 1];\n if (wantv) {\n for (let i = 0; i < n; i++) {\n t = cs * V.get(i, j) + sn * V.get(i, j + 1);\n V.set(i, j + 1, -sn * V.get(i, j) + cs * V.get(i, j + 1));\n V.set(i, j, t);\n }\n }\n t = hypotenuse(f, g);\n if (t === 0) t = Number.MIN_VALUE;\n cs = f / t;\n sn = g / t;\n s[j] = t;\n f = cs * e[j] + sn * s[j + 1];\n s[j + 1] = -sn * e[j] + cs * s[j + 1];\n g = sn * e[j + 1];\n e[j + 1] = cs * e[j + 1];\n if (wantu && j < m - 1) {\n for (let i = 0; i < m; i++) {\n t = cs * U.get(i, j) + sn * U.get(i, j + 1);\n U.set(i, j + 1, -sn * U.get(i, j) + cs * U.get(i, j + 1));\n U.set(i, j, t);\n }\n }\n }\n e[p - 2] = f;\n iter = iter + 1;\n break;\n }\n case 4: {\n if (s[k] <= 0) {\n s[k] = s[k] < 0 ? -s[k] : 0;\n if (wantv) {\n for (let i = 0; i <= pp; i++) {\n V.set(i, k, -V.get(i, k));\n }\n }\n }\n while (k < pp) {\n if (s[k] >= s[k + 1]) {\n break;\n }\n let t = s[k];\n s[k] = s[k + 1];\n s[k + 1] = t;\n if (wantv && k < n - 1) {\n for (let i = 0; i < n; i++) {\n t = V.get(i, k + 1);\n V.set(i, k + 1, V.get(i, k));\n V.set(i, k, t);\n }\n }\n if (wantu && k < m - 1) {\n for (let i = 0; i < m; i++) {\n t = U.get(i, k + 1);\n U.set(i, k + 1, U.get(i, k));\n U.set(i, k, t);\n }\n }\n k++;\n }\n iter = 0;\n p--;\n break;\n }\n // no default\n }\n }\n\n if (swapped) {\n let tmp = V;\n V = U;\n U = tmp;\n }\n\n this.m = m;\n this.n = n;\n this.s = s;\n this.U = U;\n this.V = V;\n }\n\n solve(value) {\n let Y = value;\n let e = this.threshold;\n let scols = this.s.length;\n let Ls = Matrix.zeros(scols, scols);\n\n for (let i = 0; i < scols; i++) {\n if (Math.abs(this.s[i]) <= e) {\n Ls.set(i, i, 0);\n } else {\n Ls.set(i, i, 1 / this.s[i]);\n }\n }\n\n let U = this.U;\n let V = this.rightSingularVectors;\n\n let VL = V.mmul(Ls);\n let vrows = V.rows;\n let urows = U.rows;\n let VLU = Matrix.zeros(vrows, urows);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < urows; j++) {\n let sum = 0;\n for (let k = 0; k < scols; k++) {\n sum += VL.get(i, k) * U.get(j, k);\n }\n VLU.set(i, j, sum);\n }\n }\n\n return VLU.mmul(Y);\n }\n\n solveForDiagonal(value) {\n return this.solve(Matrix.diag(value));\n }\n\n inverse() {\n let V = this.V;\n let e = this.threshold;\n let vrows = V.rows;\n let vcols = V.columns;\n let X = new Matrix(vrows, this.s.length);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < vcols; j++) {\n if (Math.abs(this.s[j]) > e) {\n X.set(i, j, V.get(i, j) / this.s[j]);\n }\n }\n }\n\n let U = this.U;\n\n let urows = U.rows;\n let ucols = U.columns;\n let Y = new Matrix(vrows, urows);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < urows; j++) {\n let sum = 0;\n for (let k = 0; k < ucols; k++) {\n sum += X.get(i, k) * U.get(j, k);\n }\n Y.set(i, j, sum);\n }\n }\n\n return Y;\n }\n\n get condition() {\n return this.s[0] / this.s[Math.min(this.m, this.n) - 1];\n }\n\n get norm2() {\n return this.s[0];\n }\n\n get rank() {\n let tol = Math.max(this.m, this.n) * this.s[0] * Number.EPSILON;\n let r = 0;\n let s = this.s;\n for (let i = 0, ii = s.length; i < ii; i++) {\n if (s[i] > tol) {\n r++;\n }\n }\n return r;\n }\n\n get diagonal() {\n return Array.from(this.s);\n }\n\n get threshold() {\n return (Number.EPSILON / 2) * Math.max(this.m, this.n) * this.s[0];\n }\n\n get leftSingularVectors() {\n return this.U;\n }\n\n get rightSingularVectors() {\n return this.V;\n }\n\n get diagonalMatrix() {\n return Matrix.diag(this.s);\n }\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","import LuDecomposition from './dc/lu';\nimport QrDecomposition from './dc/qr';\nimport SingularValueDecomposition from './dc/svd';\nimport Matrix from './matrix';\nimport WrapperMatrix2D from './wrap/WrapperMatrix2D';\n\nexport function inverse(matrix, useSVD = false) {\n matrix = WrapperMatrix2D.checkMatrix(matrix);\n if (useSVD) {\n return new SingularValueDecomposition(matrix).inverse();\n } else {\n return solve(matrix, Matrix.eye(matrix.rows));\n }\n}\n\nexport function solve(leftHandSide, rightHandSide, useSVD = false) {\n leftHandSide = WrapperMatrix2D.checkMatrix(leftHandSide);\n rightHandSide = WrapperMatrix2D.checkMatrix(rightHandSide);\n if (useSVD) {\n return new SingularValueDecomposition(leftHandSide).solve(rightHandSide);\n } else {\n return leftHandSide.isSquare()\n ? new LuDecomposition(leftHandSide).solve(rightHandSide)\n : new QrDecomposition(leftHandSide).solve(rightHandSide);\n }\n}\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 = this.nNeighbors;\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 }\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 }\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 }\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 }\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 }\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 }\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 }\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 let index = Math.floor(localConnectivity);\n let 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 }\n else {\n psum += 1.0;\n }\n }\n if (Math.abs(psum - target) < SMOOTH_K_TOLERANCE) {\n break;\n }\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 }\n else {\n mid = (lo + hi) / 2.0;\n }\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 }\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 }\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 }\n if (knnIndices[i][j] === i) {\n val = 0.0;\n }\n else if (knnDistances[i][j] - rhos[i] <= 0.0) {\n val = 1.0;\n }\n else {\n val = Math.exp(-((knnDistances[i][j] - rhos[i]) / sigmas[i]));\n }\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 }\n const graph = this.graph.map(value => {\n if (value < graphMax / nEpochs) {\n return 0;\n }\n else {\n return value;\n }\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 }\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 }\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 }\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 }\n else {\n return resolve(isFinished);\n }\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 }\n if (!graph) {\n return 200;\n }\n const length = graph.nRows;\n if (length <= 2500) {\n return 500;\n }\n else if (length <= 5000) {\n return 400;\n }\n else if (length <= 7500) {\n return 300;\n }\n else {\n return 200;\n }\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 }\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 }\n else if (normX === 0 || normY === 0) {\n return 1.0;\n }\n else {\n return 1.0 - result / Math.sqrt(normX * normY);\n }\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 }\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 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 }\n else if (target[row] !== target[col]) {\n return value * Math.exp(-farDist);\n }\n else {\n return value;\n }\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW1hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInVtYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxTQUFTLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBYXhDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0FBbUg5Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sT0FBTyxJQUFJO0lBMkNmLElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBQ0QsWUFBWSxTQUF5QixFQUFFO1FBN0MvQixpQkFBWSxHQUFHLEdBQUcsQ0FBQztRQUNuQixzQkFBaUIsR0FBRyxHQUFHLENBQUM7UUFDeEIsWUFBTyxHQUFHLEdBQUcsQ0FBQztRQUNkLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWixlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLHVCQUFrQixHQUFHLENBQUMsQ0FBQztRQUN2QixXQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNyQixzQkFBaUIsR0FBRyxHQUFHLENBQUM7UUFDeEIsa0JBQWEsR0FBRyxHQUFHLENBQUM7UUFDcEIsV0FBTSxHQUFHLEdBQUcsQ0FBQztRQUNiLHVCQUFrQixHQUFH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QUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDNUMsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4QixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNqRDtTQUNGO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgSmF2YVNjcmlwdCByZWltcGxlbWVudGF0aW9uIG9mIFVNQVAgKG9yaWdpbmFsIGxpY2Vuc2UgYmVsb3cpLCBmcm9tXG4gKiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9sbWNpbm5lcy91bWFwLlxuICpcbiAqIEBhdXRob3IgYW5keWNvZW5lbkBnb29nbGUuY29tIChBbmR5IENvZW5lbilcbiAqL1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBCU0QgMy1DbGF1c2UgTGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNywgTGVsYW5kIE1jSW5uZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4gKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcbiAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXG4gKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcbiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuaW1wb3J0ICogYXMgaGVhcCBmcm9tICcuL2hlYXAnO1xuaW1wb3J0ICogYXMgbWF0cml4IGZyb20gJy4vbWF0cml4JztcbmltcG9ydCAqIGFzIG5uRGVzY2VudCBmcm9tICcuL25uX2Rlc2NlbnQnO1xuaW1wb3J0ICogYXMgdHJlZSBmcm9tICcuL3RyZWUnO1xuaW1wb3J0ICogYXMgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgTE0gZnJvbSAnbWwtbGV2ZW5iZXJnLW1hcnF1YXJkdCc7XG5cbmV4cG9ydCB0eXBlIERpc3RhbmNlRm4gPSAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IG51bWJlcjtcbmV4cG9ydCB0eXBlIFJhbmRvbUZuID0gKCkgPT4gbnVtYmVyO1xuZXhwb3J0IHR5cGUgRXBvY2hDYWxsYmFjayA9IChlcG9jaDogbnVtYmVyKSA9PiBib29sZWFuIHwgdm9pZDtcbmV4cG9ydCB0eXBlIFZlY3RvciA9IG51bWJlcltdO1xuZXhwb3J0IHR5cGUgVmVjdG9ycyA9IFZlY3RvcltdO1xuZXhwb3J0IGNvbnN0IGVudW0gVGFyZ2V0TWV0cmljIHtcbiAgY2F0ZWdvcmljYWwgPSAnY2F0ZWdvcmljYWwnLFxuICBsMSA9ICdsMScsXG4gIGwyID0gJ2wyJyxcbn1cblxuY29uc3QgU01PT1RIX0tfVE9MRVJBTkNFID0gMWUtNTtcbmNvbnN0IE1JTl9LX0RJU1RfU0NBTEUgPSAxZS0zO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVNQVBQYXJhbWV0ZXJzIHtcbiAgLyoqXG4gICAqIFRoZSBkaXN0YW5jZSBmdW5jdGlvbiB3aXRoIHdoaWNoIHRvIGFzc2VzcyBuZWFyZXN0IG5laWdoYm9ycywgZGVmYXVsdHNcbiAgICogdG8gZXVjbGlkZWFuIGRpc3RhbmNlLlxuICAgKi9cbiAgZGlzdGFuY2VGbj86IERpc3RhbmNlRm47XG4gIC8qKlxuICAgKiBUaGUgaW5pdGlhbCBsZWFybmluZyByYXRlIGZvciB0aGUgZW1iZWRkaW5nIG9wdGltaXphdGlvbi5cbiAgICovXG4gIGxlYXJuaW5nUmF0ZT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBsb2NhbCBjb25uZWN0aXZpdHkgcmVxdWlyZWQgLS0gaS5lLiB0aGUgbnVtYmVyIG9mIG5lYXJlc3RcbiAgICogbmVpZ2hib3JzIHRoYXQgc2hvdWxkIGJlIGFzc3VtZWQgdG8gYmUgY29ubmVjdGVkIGF0IGEgbG9jYWwgbGV2ZWwuXG4gICAqIFRoZSBoaWdoZXIgdGhpcyB2YWx1ZSB0aGUgbW9yZSBjb25uZWN0ZWQgdGhlIG1hbmlmb2xkIGJlY29tZXNcbiAgICogbG9jYWxseS4gSW4gcHJhY3RpY2UgdGhpcyBzaG91bGQgYmUgbm90IG1vcmUgdGhhbiB0aGUgbG9jYWwgaW50cmluc2ljXG4gICAqIGRpbWVuc2lvbiBvZiB0aGUgbWFuaWZvbGQuXG4gICAqL1xuICBsb2NhbENvbm5lY3Rpdml0eT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBlZmZlY3RpdmUgbWluaW11bSBkaXN0YW5jZSBiZXR3ZWVuIGVtYmVkZGVkIHBvaW50cy4gU21hbGxlciB2YWx1ZXNcbiAgICogd2lsbCByZXN1bHQgaW4gYSBtb3JlIGNsdXN0ZXJlZC9jbHVtcGVkIGVtYmVkZGluZyB3aGVyZSBuZWFyYnkgcG9pbnRzXG4gICAqIG9uIHRoZSBtYW5pZm9sZCBhcmUgZHJhd24gY2xvc2VyIHRvZ2V0aGVyLCB3aGlsZSBsYXJnZXIgdmFsdWVzIHdpbGxcbiAgICogcmVzdWx0IG9uIGEgbW9yZSBldmVuIGRpc3BlcnNhbCBvZiBwb2ludHMuIFRoZSB2YWx1ZSBzaG91bGQgYmUgc2V0XG4gICAqIHJlbGF0aXZlIHRvIHRoZSBgYHNwcmVhZGBgIHZhbHVlLCB3aGljaCBkZXRlcm1pbmVzIHRoZSBzY2FsZSBhdCB3aGljaFxuICAgKiBlbWJlZGRlZCBwb2ludHMgd2lsbCBiZSBzcHJlYWQgb3V0LlxuICAgKi9cbiAgbWluRGlzdD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBkaW1lbnNpb24gb2YgdGhlIHNwYWNlIHRvIGVtYmVkIGludG8uIFRoaXMgZGVmYXVsdHMgdG8gMiB0b1xuICAgKiBwcm92aWRlIGVhc3kgdmlzdWFsaXphdGlvbiwgYnV0IGNhbiByZWFzb25hYmx5IGJlIHNldCB0byBhbnlcbiAgICogaW50ZWdlciB2YWx1ZSBpbiB0aGUgcmFuZ2UgMiB0byAxMDAuXG4gICAqL1xuICBuQ29tcG9uZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgdHJhaW5pbmcgZXBvY2hzIHRvIGJlIHVzZWQgaW4gb3B0aW1pemluZyB0aGVcbiAgICogbG93IGRpbWVuc2lvbmFsIGVtYmVkZGluZy4gTGFyZ2VyIHZhbHVlcyByZXN1bHQgaW4gbW9yZSBhY2N1cmF0ZVxuICAgKiBlbWJlZGRpbmdzLiBJZiBOb25lIGlzIHNwZWNpZmllZCBhIHZhbHVlIHdpbGwgYmUgc2VsZWN0ZWQgYmFzZWQgb25cbiAgICogdGhlIHNpemUgb2YgdGhlIGlucHV0IGRhdGFzZXQgKDIwMCBmb3IgbGFyZ2UgZGF0YXNldHMsIDUwMCBmb3Igc21hbGwpLlxuICAgKi9cbiAgbkVwb2Nocz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBzaXplIG9mIGxvY2FsIG5laWdoYm9yaG9vZCAoaW4gdGVybXMgb2YgbnVtYmVyIG9mIG5laWdoYm9yaW5nXG4gICAqIHNhbXBsZSBwb2ludHMpIHVzZWQgZm9yIG1hbmlmb2xkIGFwcHJveGltYXRpb24uIExhcmdlciB2YWx1ZXNcbiAgICogcmVzdWx0IGluIG1vcmUgZ2xvYmFsIHZpZXdzIG9mIHRoZSBtYW5pZm9sZCwgd2hpbGUgc21hbGxlclxuICAgKiB2YWx1ZXMgcmVzdWx0IGluIG1vcmUgbG9jYWwgZGF0YSBiZWluZyBwcmVzZXJ2ZWQuIEluIGdlbmVyYWxcbiAgICogdmFsdWVzIHNob3VsZCBiZSBpbiB0aGUgcmFuZ2UgMiB0byAxMDAuXG4gICAqL1xuICBuTmVpZ2hib3JzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBuZWdhdGl2ZSBzYW1wbGVzIHRvIHNlbGVjdCBwZXIgcG9zaXRpdmUgc2FtcGxlXG4gICAqIGluIHRoZSBvcHRpbWl6YXRpb24gcHJvY2Vzcy4gSW5jcmVhc2luZyB0aGlzIHZhbHVlIHdpbGwgcmVzdWx0XG4gICAqIGluIGdyZWF0ZXIgcmVwdWxzaXZlIGZvcmNlIGJlaW5nIGFwcGxpZWQsIGdyZWF0ZXIgb3B0aW1pemF0aW9uXG4gICAqIGNvc3QsIGJ1dCBzbGlnaHRseSBtb3JlIGFjY3VyYWN5LlxuICAgKi9cbiAgbmVnYXRpdmVTYW1wbGVSYXRlPzogbnVtYmVyO1xuICAvKipcbiAgICogV2VpZ2h0aW5nIGFwcGxpZWQgdG8gbmVnYXRpdmUgc2FtcGxlcyBpbiBsb3cgZGltZW5zaW9uYWwgZW1iZWRkaW5nXG4gICAqIG9wdGltaXphdGlvbi4gVmFsdWVzIGhpZ2hlciB0aGFuIG9uZSB3aWxsIHJlc3VsdCBpbiBncmVhdGVyIHdlaWdodFxuICAgKiBiZWluZyBnaXZlbiB0byBuZWdhdGl2ZSBzYW1wbGVzLlxuICAgKi9cbiAgcmVwdWxzaW9uU3RyZW5ndGg/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgcHNldWRvLXJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yIHVzZWQgYnkgdGhlIHN0b2NoYXN0aWMgcGFydHMgb2YgdGhlXG4gICAqIGFsZ29yaXRobS5cbiAgICovXG4gIHJhbmRvbT86IFJhbmRvbUZuO1xuICAvKipcbiAgICogSW50ZXJwb2xhdGUgYmV0d2VlbiAoZnV6enkpIHVuaW9uIGFuZCBpbnRlcnNlY3Rpb24gYXMgdGhlIHNldCBvcGVyYXRpb25cbiAgICogdXNlZCB0byBjb21iaW5lIGxvY2FsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cyB0byBvYnRhaW4gYSBnbG9iYWwgZnV6enlcbiAgICogc2ltcGxpY2lhbCBzZXRzLiBCb3RoIGZ1enp5IHNldCBvcGVyYXRpb25zIHVzZSB0aGUgcHJvZHVjdCB0LW5vcm0uXG4gICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHBhcmFtZXRlciBzaG91bGQgYmUgYmV0d2VlbiAwLjAgYW5kIDEuMDsgYSB2YWx1ZSBvZlxuICAgKiAxLjAgd2lsbCB1c2UgYSBwdXJlIGZ1enp5IHVuaW9uLCB3aGlsZSAwLjAgd2lsbCB1c2UgYSBwdXJlIGZ1enp5XG4gICAqIGludGVyc2VjdGlvbi5cbiAgICovXG4gIHNldE9wTWl4UmF0aW8/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZWZmZWN0aXZlIHNjYWxlIG9mIGVtYmVkZGVkIHBvaW50cy4gSW4gY29tYmluYXRpb24gd2l0aCBgYG1pbl9kaXN0YGBcbiAgICogdGhpcyBkZXRlcm1pbmVzIGhvdyBjbHVzdGVyZWQvY2x1bXBlZCB0aGUgZW1iZWRkZWQgcG9pbnRzIGFyZS5cbiAgICovXG4gIHNwcmVhZD86IG51bWJlcjtcbiAgLyoqXG4gICAqIEZvciB0cmFuc2Zvcm0gb3BlcmF0aW9ucyAoZW1iZWRkaW5nIG5ldyBwb2ludHMgdXNpbmcgYSB0cmFpbmVkIG1vZGVsKVxuICAgKiB0aGlzIHdpbGwgY29udHJvbCBob3cgYWdncmVzc2l2ZWx5IHRvIHNlYXJjaCBmb3IgbmVhcmVzdCBuZWlnaGJvcnMuXG4gICAqIExhcmdlciB2YWx1ZXMgd2lsbCByZXN1bHQgaW4gc2xvd2VyIHBlcmZvcm1hbmNlIGJ1dCBtb3JlIGFjY3VyYXRlXG4gICAqIG5lYXJlc3QgbmVpZ2hib3IgZXZhbHVhdGlvbi5cbiAgICovXG4gIHRyYW5zZm9ybVF1ZXVlU2l6ZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVTUFQU3VwZXJ2aXNlZFBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgbWV0cmljIHVzZWQgdG8gbWVhc3VyZSBkaXN0YW5jZSBmb3IgYSB0YXJnZXQgYXJyYXkgaXMgdXNpbmcgc3VwZXJ2aXNlZFxuICAgKiBkaW1lbnNpb24gcmVkdWN0aW9uLiBCeSBkZWZhdWx0IHRoaXMgaXMgJ2NhdGVnb3JpY2FsJyB3aGljaCB3aWxsIG1lYXN1cmVcbiAgICogZGlzdGFuY2UgaW4gdGVybXMgb2Ygd2hldGhlciBjYXRlZ29yaWVzIG1hdGNoIG9yIGFyZSBkaWZmZXJlbnQuIEZ1cnRoZXJtb3JlLFxuICAgKiBpZiBzZW1pLXN1cGVydmlzZWQgaXMgcmVxdWlyZWQgdGFyZ2V0IHZhbHVlcyBvZiAtMSB3aWxsIGJlIHRyZWF0ZWQgYXNcbiAgICogdW5sYWJlbGxlZCB1bmRlciB0aGUgJ2NhdGVnb3JpY2FsJyBtZXRyaWMuIElmIHRoZSB0YXJnZXQgYXJyYXkgdGFrZXNcbiAgICogY29udGludW91cyB2YWx1ZXMgKGUuZy4gZm9yIGEgcmVncmVzc2lvbiBwcm9ibGVtKSB0aGVuIG1ldHJpYyBvZiAnbDEnXG4gICAqIG9yICdsMicgaXMgcHJvYmFibHkgbW9yZSBhcHByb3ByaWF0ZS5cbiAgICovXG4gIHRhcmdldE1ldHJpYz86IFRhcmdldE1ldHJpYztcbiAgLyoqXG4gICAqIFdlaWdodGluZyBmYWN0b3IgYmV0d2VlbiBkYXRhIHRvcG9sb2d5IGFuZCB0YXJnZXQgdG9wb2xvZ3kuIEEgdmFsdWUgb2ZcbiAgICogMC4wIHdlaWdodHMgZW50aXJlbHkgb24gZGF0YSwgYSB2YWx1ZSBvZiAxLjAgd2VpZ2h0cyBlbnRpcmVseSBvbiB0YXJnZXQuXG4gICAqIFRoZSBkZWZhdWx0IG9mIDAuNSBiYWxhbmNlcyB0aGUgd2VpZ2h0aW5nIGVxdWFsbHkgYmV0d2VlbiBkYXRhIGFuZCB0YXJnZXQuXG4gICAqL1xuICB0YXJnZXRXZWlnaHQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIG5lYXJlc3QgbmVpZ2hib3JzIHRvIHVzZSB0byBjb25zdHJ1Y3QgdGhlIHRhcmdldCBzaW1wbGNpYWxcbiAgICogc2V0LiBEZWZhdWx0cyB0byB0aGUgYG5lYXJlc3ROZWlnaGJvcnNgIHBhcmFtZXRlci5cbiAgICovXG4gIHRhcmdldE5OZWlnaGJvcnM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogVU1BUCBwcm9qZWN0aW9uIHN5c3RlbSwgYmFzZWQgb24gdGhlIHB5dGhvbiBpbXBsZW1lbnRhdGlvbiBmcm9tIE1jSW5uZXMsIEwsXG4gKiBIZWFseSwgSiwgVU1BUDogVW5pZm9ybSBNYW5pZm9sZCBBcHByb3hpbWF0aW9uIGFuZCBQcm9qZWN0aW9uIGZvciBEaW1lbnNpb25cbiAqIFJlZHVjdGlvbiAoaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXApLlxuICpcbiAqIFRoaXMgaW1wbGVtZW50YXRpb24gZGlmZmVycyBpbiBhIGZldyByZWdhcmRzOlxuICogYSkgVGhlIGluaXRpYWxpemF0aW9uIG9mIHRoZSBlbWJlZGRpbmcgZm9yIG9wdGltaXphdGlvbiBpcyBub3QgY29tcHV0ZWQgdXNpbmdcbiAqICAgIGEgc3BlY3RyYWwgbWV0aG9kLCByYXRoZXIgaXQgaXMgaW5pdGlhbGl6ZWQgcmFuZG9tbHkuIFRoaXMgYXZvaWRzIHNvbWVcbiAqICAgIGNvbXB1dGF0aW9uYWxseSBpbnRlbnNpdmUgbWF0cml4IGVpZ2VuIGNvbXB1dGF0aW9ucyB0aGF0IGFyZW4ndCBlYXNpbHlcbiAqICAgIHBvcnRlZCB0byBKYXZhU2NyaXB0LlxuICogYikgQSBsb3Qgb2YgXCJleHRyYVwiIGZ1bmN0aW9uYWxpdHkgaGFzIGJlZW4gb21pdHRlZCBmcm9tIHRoaXMgaW1wbGVtZW50YXRpb24sXG4gKiAgICBtb3N0IG5vdGFibHkgYSBncmVhdCBkZWFsIG9mIGFsdGVybmF0ZSBkaXN0YW5jZSBmdW5jdGlvbnMuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBwcm92aWRlcyB0aHJlZSBtZXRob2RzIG9mIHJlZHVjaW5nIGRpbWVuc2lvbmFsaXR5OlxuICogMSkgZml0OiBmaXQgdGhlIGRhdGEgc3luY2hyb25vdXNseVxuICogMikgZml0QXN5bmM6IGZpdCB0aGUgZGF0YSBhc3luY2hyb25vdXNseSwgd2l0aCBhIGNhbGxiYWNrIGZ1bmN0aW9uIHByb3ZpZGVkXG4gKiAgICAgIHRoYXQgaXMgaW52b2tlZCBvbiBlYWNoIG9wdGltaXphdGlvbiBzdGVwLlxuICogMykgaW5pdGlhbGl6ZUZpdCAvIHN0ZXA6IG1hbnVhbGx5IGluaXRpYWxpemUgdGhlIGFsZ29yaXRobSB0aGVuIGV4cGxpY3RseVxuICogICAgICBzdGVwIHRocm91Z2ggZWFjaCBlcG9jaCBvZiB0aGUgU0dEIG9wdGltaXphdGlvblxuICovXG5leHBvcnQgY2xhc3MgVU1BUCB7XG4gIHByaXZhdGUgbGVhcm5pbmdSYXRlID0gMS4wO1xuICBwcml2YXRlIGxvY2FsQ29ubmVjdGl2aXR5ID0gMS4wO1xuICBwcml2YXRlIG1pbkRpc3QgPSAwLjE7XG4gIHByaXZhdGUgbkNvbXBvbmVudHMgPSAyO1xuICBwcml2YXRlIG5FcG9jaHMgPSAwO1xuICBwcml2YXRlIG5OZWlnaGJvcnMgPSAxNTtcbiAgcHJpdmF0ZSBuZWdhdGl2ZVNhbXBsZVJhdGUgPSA1O1xuICBwcml2YXRlIHJhbmRvbSA9IE1hdGgucmFuZG9tO1xuICBwcml2YXRlIHJlcHVsc2lvblN0cmVuZ3RoID0gMS4wO1xuICBwcml2YXRlIHNldE9wTWl4UmF0aW8gPSAxLjA7XG4gIHByaXZhdGUgc3ByZWFkID0gMS4wO1xuICBwcml2YXRlIHRyYW5zZm9ybVF1ZXVlU2l6ZSA9IDQuMDtcblxuICAvLyBTdXBlcnZpc2VkIHByb2plY3Rpb24gcGFyYW1zXG4gIHByaXZhdGUgdGFyZ2V0TWV0cmljID0gVGFyZ2V0TWV0cmljLmNhdGVnb3JpY2FsO1xuICBwcml2YXRlIHRhcmdldFdlaWdodCA9IDAuNTtcbiAgcHJpdmF0ZSB0YXJnZXROTmVpZ2hib3JzID0gdGhpcy5uTmVpZ2hib3JzO1xuXG4gIHByaXZhdGUgZGlzdGFuY2VGbjogRGlzdGFuY2VGbiA9IG51bWVyaWM7XG5cbiAgLy8gS05OIHN0YXRlIChjYW4gYmUgcHJlY29tcHV0ZWQgYW5kIHN1cHBsaWVkIHZpYSBpbml0aWFsaXplRml0KVxuICBwcml2YXRlIGtubkluZGljZXM/OiBudW1iZXJbXVtdO1xuICBwcml2YXRlIGtubkRpc3RhbmNlcz86IG51bWJlcltdW107XG5cbiAgLy8gSW50ZXJuYWwgZ3JhcGggY29ubmVjdGl2aXR5IHJlcHJlc2VudGF0aW9uXG4gIHByaXZhdGUgZ3JhcGghOiBtYXRyaXguU3BhcnNlTWF0cml4O1xuICBwcml2YXRlIFghOiBWZWN0b3I7XG4gIHByaXZhdGUgaXNJbml0aWFsaXplZCA9IGZhbHNlO1xuICBwcml2YXRlIHJwRm9yZXN0OiB0cmVlLkZsYXRUcmVlW10gPSBbXTtcbiAgcHJpdmF0ZSBpbml0RnJvbVJhbmRvbSE6IG5uRGVzY2VudC5Jbml0RnJvbVJhbmRvbUZuO1xuICBwcml2YXRlIGluaXRGcm9tVHJlZSE6IG5uRGVzY2VudC5Jbml0RnJvbVRyZWVGbjtcbiAgcHJpdmF0ZSBzZWFyY2ghOiBubkRlc2NlbnQuU2VhcmNoRm47XG4gIHByaXZhdGUgc2VhcmNoR3JhcGghOiBtYXRyaXguU3BhcnNlTWF0cml4O1xuXG4gIC8vIFN1cGVydmlzZWQgcHJvamVjdGlvbiBsYWJlbHMgLyB0YXJnZXRzXG4gIHByaXZhdGUgWT86IG51bWJlcltdO1xuXG4gIC8vIFByb2plY3RlZCBlbWJlZGRpbmdcbiAgcHJpdmF0ZSBlbWJlZGRpbmc6IG51bWJlcltdW10gPSBbXTtcbiAgcHJpdmF0ZSBvcHRpbWl6YXRpb25TdGF0ZSA9IG5ldyBPcHRpbWl6YXRpb25TdGF0ZSgpO1xuXG5cbiAgZ2V0IG5laWdoYm9ycygpIHtcbiAgICByZXR1cm4gdGhpcy5uTmVpZ2hib3JzO1xuICB9XG4gIGNvbnN0cnVjdG9yKHBhcmFtczogVU1BUFBhcmFtZXRlcnMgPSB7fSkge1xuICAgIGNvbnN0IHNldFBhcmFtID0gKGtleToga2V5b2YgVU1BUFBhcmFtZXRlcnMpID0+IHtcbiAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgaWYgKHBhcmFtc1trZXldICE9PSB1bmRlZmluZWQpIHRoaXNba2V5XSA9IHBhcmFtc1trZXldO1xuICAgIH07XG5cbiAgICBzZXRQYXJhbSgnZGlzdGFuY2VGbicpO1xuICAgIHNldFBhcmFtKCdsZWFybmluZ1JhdGUnKTtcbiAgICBzZXRQYXJhbSgnbG9jYWxDb25uZWN0aXZpdHknKTtcbiAgICBzZXRQYXJhbSgnbWluRGlzdCcpO1xuICAgIHNldFBhcmFtKCduQ29tcG9uZW50cycpO1xuICAgIHNldFBhcmFtKCduRXBvY2hzJyk7XG4gICAgc2V0UGFyYW0oJ25OZWlnaGJvcnMnKTtcbiAgICBzZXRQYXJhbSgnbmVnYXRpdmVTYW1wbGVSYXRlJyk7XG4gICAgc2V0UGFyYW0oJ3JhbmRvbScpO1xuICAgIHNldFBhcmFtKCdyZXB1bHNpb25TdHJlbmd0aCcpO1xuICAgIHNldFBhcmFtKCdzZXRPcE1peFJhdGlvJyk7XG4gICAgc2V0UGFyYW0oJ3NwcmVhZCcpO1xuICAgIHNldFBhcmFtKCd0cmFuc2Zvcm1RdWV1ZVNpemUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIHN5bmNocm9ub3VzbHkuXG4gICAqL1xuICBmaXQoWDogVmVjdG9yKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuICAgIHRoaXMub3B0aW1pemVMYXlvdXQoKTtcblxuICAgIHJldHVybiB0aGlzLmVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIGFzeW5jaHJvbm91c2x5LCB3aXRoIGEgY2FsbGJhY2tcbiAgICogZnVuY3Rpb24gaW52b2tlZCBvbiBldmVyeSBlcG9jaCBvZiBvcHRpbWl6YXRpb24uXG4gICAqL1xuICBhc3luYyBmaXRBc3luYyhcbiAgICBYOiBWZWN0b3IsXG4gICAgY2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuXG4gICAgYXdhaXQgdGhpcy5vcHRpbWl6ZUxheW91dEFzeW5jKGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy5lbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgcGFyYW1ldGVycyBuZWVkZWQgZm9yIHN1cGVydmlzZWQgcHJvamVjdGlvbi5cbiAgICovXG4gIHNldFN1cGVydmlzZWRQcm9qZWN0aW9uKFk6IG51bWJlcltdLCBwYXJhbXM6IFVNQVBTdXBlcnZpc2VkUGFyYW1zID0ge30pIHtcbiAgICB0aGlzLlkgPSBZO1xuICAgIHRoaXMudGFyZ2V0TWV0cmljID0gcGFyYW1zLnRhcmdldE1ldHJpYyB8fCB0aGlzLnRhcmdldE1ldHJpYztcbiAgICB0aGlzLnRhcmdldFdlaWdodCA9IHBhcmFtcy50YXJnZXRXZWlnaHQgfHwgdGhpcy50YXJnZXRXZWlnaHQ7XG4gICAgdGhpcy50YXJnZXROTmVpZ2hib3JzID0gcGFyYW1zLnRhcmdldE5OZWlnaGJvcnMgfHwgdGhpcy50YXJnZXROTmVpZ2hib3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHVtYXAgd2l0aCBwcmVjb21wdXRlZCBLTk4gaW5kaWNlcyBhbmQgZGlzdGFuY2VzLlxuICAgKi9cbiAgc2V0UHJlY29tcHV0ZWRLTk4oa25uSW5kaWNlczogbnVtYmVyW11bXSwga25uRGlzdGFuY2VzOiBudW1iZXJbXVtdKSB7XG4gICAgdGhpcy5rbm5JbmRpY2VzID0ga25uSW5kaWNlcztcbiAgICB0aGlzLmtubkRpc3RhbmNlcyA9IGtubkRpc3RhbmNlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBmaXQgYnkgY29tcHV0aW5nIEtOTiBhbmQgYSBmdXp6eSBzaW1wbGljaWFsIHNldCwgYXMgd2VsbCBhc1xuICAgKiBpbml0aWFsaXppbmcgdGhlIHByb2plY3RlZCBlbWJlZGRpbmdzLiBTZXRzIHRoZSBvcHRpbWl6YXRpb24gc3RhdGUgYWhlYWRcbiAgICogb2Ygb3B0aW1pemF0aW9uIHN0ZXBzLiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZXBvY2hzIHRvIGJlIHVzZWQgZm9yIHRoZVxuICAgKiBTR0Qgb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgaW5pdGlhbGl6ZUZpdChYOiBWZWN0b3IpOiBudW1iZXIge1xuICAgIGlmIChYLmxlbmd0aCA8PSB0aGlzLm5OZWlnaGJvcnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm90IGVub3VnaCBkYXRhIHBvaW50cyAoJHtYLmxlbmd0aH0pIHRvIGNyZWF0ZSBuTmVpZ2hib3JzOiAke3RoaXMubk5laWdoYm9yc30uICBBZGQgbW9yZSBkYXRhIHBvaW50cyBvciBhZGp1c3QgdGhlIGNvbmZpZ3VyYXRpb24uYCk7XG4gICAgfVxuXG4gICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZWluaXRpYWxpemUgaWYgd2UndmUgYWxyZWFkeSBpbml0aWFsaXplZCBmb3IgdGhpcyBkYXRhLlxuICAgIGlmICh0aGlzLlggPT09IFggJiYgdGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRORXBvY2hzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5YID0gWDtcblxuICAgIGlmICghdGhpcy5rbm5JbmRpY2VzICYmICF0aGlzLmtubkRpc3RhbmNlcykge1xuICAgICAgY29uc3Qga25uUmVzdWx0cyA9IHRoaXMubmVhcmVzdE5laWdoYm9ycyhYKTtcbiAgICAgIHRoaXMua25uSW5kaWNlcyA9IGtublJlc3VsdHMua25uSW5kaWNlcztcbiAgICAgIHRoaXMua25uRGlzdGFuY2VzID0ga25uUmVzdWx0cy5rbm5EaXN0YW5jZXM7XG4gICAgfVxuXG4gICAgdGhpcy5ncmFwaCA9IHRoaXMuZnV6enlTaW1wbGljaWFsU2V0KFxuICAgICAgWCxcbiAgICAgIHRoaXMubk5laWdoYm9ycyxcbiAgICAgIHRoaXMuc2V0T3BNaXhSYXRpb1xuICAgICk7XG5cbiAgICAvLyBTZXQgdXAgdGhlIHNlYXJjaCBncmFwaCBmb3Igc3Vic2VxdWVudCB0cmFuc2Zvcm1hdGlvbi5cbiAgICB0aGlzLm1ha2VTZWFyY2hGbnMoKTtcbiAgICB0aGlzLnNlYXJjaEdyYXBoID0gdGhpcy5tYWtlU2VhcmNoR3JhcGgoWCk7XG5cbiAgICAvLyBDaGVjayBpZiBzdXBlcnZpc2VkIHByb2plY3Rpb24sIHRoZW4gYWRqdXN0IHRoZSBncmFwaC5cbiAgICB0aGlzLnByb2Nlc3NHcmFwaEZvclN1cGVydmlzZWRQcm9qZWN0aW9uKCk7XG5cbiAgICBjb25zdCB7XG4gICAgICBoZWFkLFxuICAgICAgdGFpbCxcbiAgICAgIGVwb2Noc1BlclNhbXBsZSxcbiAgICB9ID0gdGhpcy5pbml0aWFsaXplU2ltcGxpY2lhbFNldEVtYmVkZGluZygpO1xuXG4gICAgLy8gU2V0IHRoZSBvcHRpbWl6YXRpb24gcm91dGluZSBzdGF0ZVxuICAgIHRoaXMub3B0aW1pemF0aW9uU3RhdGUuaGVhZCA9IGhlYWQ7XG4gICAgdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS50YWlsID0gdGFpbDtcbiAgICB0aGlzLm9wdGltaXphdGlvblN0YXRlLmVwb2Noc1BlclNhbXBsZSA9IGVwb2Noc1BlclNhbXBsZTtcblxuICAgIC8vIE5vdywgaW5pdGlhbGl6ZSB0aGUgb3B0aW1pemF0aW9uIHN0ZXBzXG4gICAgdGhpcy5pbml0aWFsaXplT3B0aW1pemF0aW9uKCk7XG4gICAgdGhpcy5wcmVwYXJlRm9yT3B0aW1pemF0aW9uTG9vcCgpO1xuICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICByZXR1cm4gdGhpcy5nZXRORXBvY2hzKCk7XG4gIH1cblxuICBwcml2YXRlIG1ha2VTZWFyY2hGbnMoKSB7XG4gICAgY29uc3QgeyBpbml0RnJvbVRyZWUsIGluaXRGcm9tUmFuZG9tIH0gPSBubkRlc2NlbnQubWFrZUluaXRpYWxpemF0aW9ucyhcbiAgICAgIHRoaXMuZGlzdGFuY2VGblxuICAgICk7XG4gICAgdGhpcy5pbml0RnJvbVRyZWUgPSBpbml0RnJvbVRyZWU7XG4gICAgdGhpcy5pbml0RnJvbVJhbmRvbSA9IGluaXRGcm9tUmFuZG9tO1xuICAgIHRoaXMuc2VhcmNoID0gbm5EZXNjZW50Lm1ha2VJbml0aWFsaXplZE5OU2VhcmNoKHRoaXMuZGlzdGFuY2VGbik7XG4gIH1cblxuICBwcml2YXRlIG1ha2VTZWFyY2hHcmFwaChYOiBWZWN0b3IpIHtcbiAgICBjb25zdCBrbm5JbmRpY2VzID0gdGhpcy5rbm5JbmRpY2VzITtcbiAgICBjb25zdCBrbm5EaXN0YW5jZXMgPSB0aGlzLmtubkRpc3RhbmNlcyE7XG4gICAgY29uc3QgZGltcyA9IFtYLmxlbmd0aCwgWC5sZW5ndGhdO1xuICAgIGNvbnN0IHNlYXJjaEdyYXBoID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgoW10sIFtdLCBbXSwgZGltcyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrbm5JbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBrbm4gPSBrbm5JbmRpY2VzW2ldO1xuICAgICAgY29uc3QgZGlzdGFuY2VzID0ga25uRGlzdGFuY2VzW2ldO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBrbm4ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgY29uc3QgbmVpZ2hib3IgPSBrbm5bal07XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gZGlzdGFuY2VzW2pdO1xuICAgICAgICBpZiAoZGlzdGFuY2UgPiAwKSB7XG4gICAgICAgICAgc2VhcmNoR3JhcGguc2V0KGksIG5laWdoYm9yLCBkaXN0YW5jZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc3Bvc2UgPSBtYXRyaXgudHJhbnNwb3NlKHNlYXJjaEdyYXBoKTtcbiAgICByZXR1cm4gbWF0cml4Lm1heGltdW0oc2VhcmNoR3JhcGgsIHRyYW5zcG9zZSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtcyBkYXRhIHRvIHRoZSBleGlzdGluZyBlbWJlZGRpbmcgc3BhY2UuXG4gICAqL1xuICB0cmFuc2Zvcm0odG9UcmFuc2Zvcm06IFZlY3Rvcikge1xuICAgIC8vIFVzZSB0aGUgcHJldmlvdXMgcmF3RGF0YVxuICAgIGNvbnN0IHJhd0RhdGEgPSB0aGlzLlg7XG4gICAgaWYgKHJhd0RhdGEgPT09IHVuZGVmaW5lZCB8fCByYXdEYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBkYXRhIGhhcyBiZWVuIGZpdC4nKTtcbiAgICB9XG5cbiAgICBsZXQgbk5laWdoYm9ycyA9IE1hdGguZmxvb3IodGhpcy5uTmVpZ2hib3JzICogdGhpcy50cmFuc2Zvcm1RdWV1ZVNpemUpO1xuICAgIG5OZWlnaGJvcnMgPSBNYXRoLm1pbihyYXdEYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG4gICAgY29uc3QgaW5pdCA9IG5uRGVzY2VudC5pbml0aWFsaXplU2VhcmNoKFxuICAgICAgdGhpcy5ycEZvcmVzdCxcbiAgICAgIHJhd0RhdGEsXG4gICAgICB0b1RyYW5zZm9ybSxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICB0aGlzLmluaXRGcm9tUmFuZG9tLFxuICAgICAgdGhpcy5pbml0RnJvbVRyZWUsXG4gICAgICB0aGlzLnJhbmRvbVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnNlYXJjaChyYXdEYXRhLCB0aGlzLnNlYXJjaEdyYXBoLCBpbml0LCB0b1RyYW5zZm9ybSk7XG5cbiAgICBsZXQgeyBpbmRpY2VzLCB3ZWlnaHRzOiBkaXN0YW5jZXMgfSA9IGhlYXAuZGVoZWFwU29ydChyZXN1bHQpO1xuXG4gICAgaW5kaWNlcyA9IGluZGljZXMubWFwKHggPT4geC5zbGljZSgwLCB0aGlzLm5OZWlnaGJvcnMpKTtcbiAgICBkaXN0YW5jZXMgPSBkaXN0YW5jZXMubWFwKHggPT4geC5zbGljZSgwLCB0aGlzLm5OZWlnaGJvcnMpKTtcblxuICAgIGNvbnN0IGFkanVzdGVkTG9jYWxDb25uZWN0aXZpdHkgPSBNYXRoLm1heCgwLCB0aGlzLmxvY2FsQ29ubmVjdGl2aXR5IC0gMSk7XG4gICAgY29uc3QgeyBzaWdtYXMsIHJob3MgfSA9IHRoaXMuc21vb3RoS05ORGlzdGFuY2UoXG4gICAgICBkaXN0YW5jZXMsXG4gICAgICB0aGlzLm5OZWlnaGJvcnMsXG4gICAgICBhZGp1c3RlZExvY2FsQ29ubmVjdGl2aXR5XG4gICAgKTtcblxuICAgIGNvbnN0IHsgcm93cywgY29scywgdmFscyB9ID0gdGhpcy5jb21wdXRlTWVtYmVyc2hpcFN0cmVuZ3RocyhcbiAgICAgIGluZGljZXMsXG4gICAgICBkaXN0YW5jZXMsXG4gICAgICBzaWdtYXMsXG4gICAgICByaG9zXG4gICAgKTtcblxuICAgIGNvbnN0IHNpemUgPSBbdG9UcmFuc2Zvcm0ubGVuZ3RoLCByYXdEYXRhLmxlbmd0aF07XG4gICAgbGV0IGdyYXBoID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgocm93cywgY29scywgdmFscywgc2l6ZSk7XG5cbiAgICAvLyBUaGlzIHdhcyBhIHZlcnkgc3BlY2lhbGx5IGNvbnN0cnVjdGVkIGdyYXBoIHdpdGggY29uc3RhbnQgZGVncmVlLlxuICAgIC8vIFRoYXQgbGV0cyB1cyBkbyBmYW5jeSB1bnBhY2tpbmcgYnkgcmVzaGFwaW5nIHRoZSBjc3IgbWF0cml4IGluZGljZXNcbiAgICAvLyBhbmQgZGF0YS4gRG9pbmcgc28gcmVsaWVzIG9uIHRoZSBjb25zdGFudCBkZWdyZWUgYXNzdW1wdGlvbiFcblxuICAgIGNvbnN0IG5vcm1lZCA9IG1hdHJpeC5ub3JtYWxpemUoZ3JhcGgsIG1hdHJpeC5Ob3JtVHlwZS5sMSk7XG5cbiAgICBjb25zdCBjc3JNYXRyaXggPSBtYXRyaXguZ2V0Q1NSKG5vcm1lZCk7XG4gICAgY29uc3QgblBvaW50cyA9IHRvVHJhbnNmb3JtLmxlbmd0aDtcblxuICAgIGNvbnN0IGVJbmRpY2VzID0gdXRpbHMucmVzaGFwZTJkKFxuICAgICAgY3NyTWF0cml4LmluZGljZXMsXG4gICAgICBuUG9pbnRzLFxuICAgICAgdGhpcy5uTmVpZ2hib3JzXG4gICAgKTtcblxuICAgIGNvbnN0IGVXZWlnaHRzID0gdXRpbHMucmVzaGFwZTJkKFxuICAgICAgY3NyTWF0cml4LnZhbHVlcyxcbiAgICAgIG5Qb2ludHMsXG4gICAgICB0aGlzLm5OZWlnaGJvcnNcbiAgICApO1xuXG4gICAgY29uc3QgZW1iZWRkaW5nID0gaW5pdFRyYW5zZm9ybShlSW5kaWNlcywgZVdlaWdodHMsIHRoaXMuZW1iZWRkaW5nKTtcblxuICAgIGNvbnN0IG5FcG9jaHMgPSB0aGlzLm5FcG9jaHNcbiAgICAgID8gdGhpcy5uRXBvY2hzIC8gM1xuICAgICAgOiBncmFwaC5uUm93cyA8PSAxMDAwMFxuICAgICAgPyAxMDBcbiAgICAgIDogMzA7XG5cbiAgICBjb25zdCBncmFwaE1heCA9IGdyYXBoXG4gICAgICAuZ2V0VmFsdWVzKClcbiAgICAgIC5yZWR1Y2UoKG1heCwgdmFsKSA9PiAodmFsID4gbWF4ID8gdmFsIDogbWF4KSwgMCk7XG4gICAgZ3JhcGggPSBncmFwaC5tYXAodmFsdWUgPT4gKHZhbHVlIDwgZ3JhcGhNYXggLyBuRXBvY2hzID8gMCA6IHZhbHVlKSk7XG4gICAgZ3JhcGggPSBtYXRyaXguZWxpbWluYXRlWmVyb3MoZ3JhcGgpO1xuXG4gICAgY29uc3QgZXBvY2hzUGVyU2FtcGxlID0gdGhpcy5tYWtlRXBvY2hzUGVyU2FtcGxlKFxuICAgICAgZ3JhcGguZ2V0VmFsdWVzKCksXG4gICAgICBuRXBvY2hzXG4gICAgKTtcbiAgICBjb25zdCBoZWFkID0gZ3JhcGguZ2V0Um93cygpO1xuICAgIGNvbnN0IHRhaWwgPSBncmFwaC5nZXRDb2xzKCk7XG5cbiAgICAvLyBJbml0aWFsaXplIG9wdGltaXphdGlvbiBzbGlnaHRseSBkaWZmZXJlbnRseSB0aGFuIHRoZSBmaXQgbWV0aG9kLlxuICAgIHRoaXMuYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHtcbiAgICAgIGhlYWRFbWJlZGRpbmc6IGVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmc6IHRoaXMuZW1iZWRkaW5nLFxuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBjdXJyZW50RXBvY2g6IDAsXG4gICAgICBuRXBvY2hzLFxuICAgICAgblZlcnRpY2VzOiBncmFwaC5nZXREaW1zKClbMV0sXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgfSk7XG4gICAgdGhpcy5wcmVwYXJlRm9yT3B0aW1pemF0aW9uTG9vcCgpO1xuXG4gICAgcmV0dXJuIHRoaXMub3B0aW1pemVMYXlvdXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgd2UncmUgdXNpbmcgc3VwZXJ2aXNlZCBwcm9qZWN0aW9uLCB0aGVuIHByb2Nlc3MgdGhlIGdyYXBoXG4gICAqIGFjY29yZGluZ2x5LlxuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzR3JhcGhGb3JTdXBlcnZpc2VkUHJvamVjdGlvbigpIHtcbiAgICBjb25zdCB7IFksIFggfSA9IHRoaXM7XG4gICAgaWYgKFkpIHtcbiAgICAgIGlmIChZLmxlbmd0aCAhPT0gWC5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggb2YgWCBhbmQgeSBtdXN0IGJlIGVxdWFsJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRhcmdldE1ldHJpYyA9PT0gVGFyZ2V0TWV0cmljLmNhdGVnb3JpY2FsKSB7XG4gICAgICAgIGNvbnN0IGx0ID0gdGhpcy50YXJnZXRXZWlnaHQgPCAxLjA7XG4gICAgICAgIGNvbnN0IGZhckRpc3QgPSBsdCA/IDIuNSAqICgxLjAgLyAoMS4wIC0gdGhpcy50YXJnZXRXZWlnaHQpKSA6IDEuMGUxMjtcbiAgICAgICAgdGhpcy5ncmFwaCA9IHRoaXMuY2F0ZWdvcmljYWxTaW1wbGljaWFsU2V0SW50ZXJzZWN0aW9uKFxuICAgICAgICAgIHRoaXMuZ3JhcGgsXG4gICAgICAgICAgWSxcbiAgICAgICAgICBmYXJEaXN0XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyBUT0RPIChhbmR5Y29lbmVuQCk6IGFkZCBub24tY2F0ZWdvcmljYWwgc3VwZXJ2aXNlZCBlbWJlZGRpbmdzLlxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYW51YWxseSBzdGVwIHRocm91Z2ggdGhlIG9wdGltaXphdGlvbiBwcm9jZXNzIG9uZSBlcG9jaCBhdCBhIHRpbWUuXG4gICAqL1xuICBzdGVwKCkge1xuICAgIGNvbnN0IHsgY3VycmVudEVwb2NoIH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuXG4gICAgaWYgKGN1cnJlbnRFcG9jaCA8IHRoaXMuZ2V0TkVwb2NocygpKSB7XG4gICAgICB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5jdXJyZW50RXBvY2g7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29tcHV0ZWQgcHJvamVjdGVkIGVtYmVkZGluZy5cbiAgICovXG4gIGdldEVtYmVkZGluZygpIHtcbiAgICByZXR1cm4gdGhpcy5lbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZSB0aGUgYGBuTmVpZ2hib3JzYGAgbmVhcmVzdCBwb2ludHMgZm9yIGVhY2ggZGF0YSBwb2ludCBpbiBgYFhgYFxuICAgKiBUaGlzIG1heSBiZSBleGFjdCwgYnV0IG1vcmUgbGlrZWx5IGlzIGFwcHJveGltYXRlZCB2aWEgbmVhcmVzdCBuZWlnaGJvclxuICAgKiBkZXNjZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBuZWFyZXN0TmVpZ2hib3JzKFg6IFZlY3Rvcikge1xuICAgIGNvbnN0IHsgZGlzdGFuY2VGbiwgbk5laWdoYm9ycyB9ID0gdGhpcztcbiAgICBjb25zdCBsb2cyID0gKG46IG51bWJlcikgPT4gTWF0aC5sb2cobikgLyBNYXRoLmxvZygyKTtcbiAgICBjb25zdCBtZXRyaWNOTkRlc2NlbnQgPSBubkRlc2NlbnQubWFrZU5ORGVzY2VudChkaXN0YW5jZUZuLCB0aGlzLnJhbmRvbSk7XG5cbiAgICAvLyBIYW5kbGUgcHl0aG9uMyByb3VuZGluZyBkb3duIGZyb20gMC41IGRpc2NycGFuY3lcbiAgICBjb25zdCByb3VuZCA9IChuOiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBuID09PSAwLjUgPyAwIDogTWF0aC5yb3VuZChuKTtcbiAgICB9O1xuXG4gICAgY29uc3QgblRyZWVzID0gNSArIE1hdGguZmxvb3Iocm91bmQoWC5sZW5ndGggKiogMC41IC8gMjAuMCkpO1xuICAgIGNvbnN0IG5JdGVycyA9IE1hdGgubWF4KDUsIE1hdGguZmxvb3IoTWF0aC5yb3VuZChsb2cyKFgubGVuZ3RoKSkpKTtcblxuICAgIHRoaXMucnBGb3Jlc3QgPSB0cmVlLm1ha2VGb3Jlc3QoWCwgbk5laWdoYm9ycywgblRyZWVzLCB0aGlzLnJhbmRvbSk7XG5cbiAgICBjb25zdCBsZWFmQXJyYXkgPSB0cmVlLm1ha2VMZWFmQXJyYXkodGhpcy5ycEZvcmVzdCk7XG4gICAgY29uc3QgeyBpbmRpY2VzLCB3ZWlnaHRzIH0gPSBtZXRyaWNOTkRlc2NlbnQoXG4gICAgICBYLFxuICAgICAgbGVhZkFycmF5LFxuICAgICAgbk5laWdoYm9ycyxcbiAgICAgIG5JdGVyc1xuICAgICk7XG4gICAgcmV0dXJuIHsga25uSW5kaWNlczogaW5kaWNlcywga25uRGlzdGFuY2VzOiB3ZWlnaHRzIH07XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gYSBzZXQgb2YgZGF0YSBYLCBhIG5laWdoYm9yaG9vZCBzaXplLCBhbmQgYSBtZWFzdXJlIG9mIGRpc3RhbmNlXG4gICAqIGNvbXB1dGUgdGhlIGZ1enp5IHNpbXBsaWNpYWwgc2V0IChoZXJlIHJlcHJlc2VudGVkIGFzIGEgZnV6enkgZ3JhcGggaW5cbiAgICogdGhlIGZvcm0gb2YgYSBzcGFyc2UgbWF0cml4KSBhc3NvY2lhdGVkIHRvIHRoZSBkYXRhLiBUaGlzIGlzIGRvbmUgYnlcbiAgICogbG9jYWxseSBhcHByb3hpbWF0aW5nIGdlb2Rlc2ljIGRpc3RhbmNlIGF0IGVhY2ggcG9pbnQsIGNyZWF0aW5nIGEgZnV6enlcbiAgICogc2ltcGxpY2lhbCBzZXQgZm9yIGVhY2ggc3VjaCBwb2ludCwgYW5kIHRoZW4gY29tYmluaW5nIGFsbCB0aGUgbG9jYWxcbiAgICogZnV6enkgc2ltcGxpY2lhbCBzZXRzIGludG8gYSBnbG9iYWwgb25lIHZpYSBhIGZ1enp5IHVuaW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBmdXp6eVNpbXBsaWNpYWxTZXQoXG4gICAgWDogVmVjdG9yLFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBzZXRPcE1peFJhdGlvID0gMS4wXG4gICkge1xuICAgIGNvbnN0IHsga25uSW5kaWNlcyA9IFtdLCBrbm5EaXN0YW5jZXMgPSBbXSwgbG9jYWxDb25uZWN0aXZpdHkgfSA9IHRoaXM7XG5cbiAgICBjb25zdCB7IHNpZ21hcywgcmhvcyB9ID0gdGhpcy5zbW9vdGhLTk5EaXN0YW5jZShcbiAgICAgIGtubkRpc3RhbmNlcyxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICBsb2NhbENvbm5lY3Rpdml0eVxuICAgICk7XG5cbiAgICBjb25zdCB7IHJvd3MsIGNvbHMsIHZhbHMgfSA9IHRoaXMuY29tcHV0ZU1lbWJlcnNoaXBTdHJlbmd0aHMoXG4gICAgICBrbm5JbmRpY2VzLFxuICAgICAga25uRGlzdGFuY2VzLFxuICAgICAgc2lnbWFzLFxuICAgICAgcmhvc1xuICAgICk7XG5cbiAgICBjb25zdCBzaXplID0gW1gubGVuZ3RoLCBYLmxlbmd0aF07XG4gICAgY29uc3Qgc3BhcnNlTWF0cml4ID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgocm93cywgY29scywgdmFscywgc2l6ZSk7XG5cbiAgICBjb25zdCB0cmFuc3Bvc2UgPSBtYXRyaXgudHJhbnNwb3NlKHNwYXJzZU1hdHJpeCk7XG4gICAgY29uc3QgcHJvZE1hdHJpeCA9IG1hdHJpeC5wYWlyd2lzZU11bHRpcGx5KHNwYXJzZU1hdHJpeCwgdHJhbnNwb3NlKTtcblxuICAgIGNvbnN0IGEgPSBtYXRyaXguc3VidHJhY3QobWF0cml4LmFkZChzcGFyc2VNYXRyaXgsIHRyYW5zcG9zZSksIHByb2RNYXRyaXgpO1xuICAgIGNvbnN0IGIgPSBtYXRyaXgubXVsdGlwbHlTY2FsYXIoYSwgc2V0T3BNaXhSYXRpbyk7XG4gICAgY29uc3QgYyA9IG1hdHJpeC5tdWx0aXBseVNjYWxhcihwcm9kTWF0cml4LCAxLjAgLSBzZXRPcE1peFJhdGlvKTtcbiAgICBjb25zdCByZXN1bHQgPSBtYXRyaXguYWRkKGIsIGMpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21iaW5lIGEgZnV6enkgc2ltcGxpY2lhbCBzZXQgd2l0aCBhbm90aGVyIGZ1enp5IHNpbXBsaWNpYWwgc2V0XG4gICAqIGdlbmVyYXRlZCBmcm9tIGNhdGVnb3JpY2FsIGRhdGEgdXNpbmcgY2F0ZWdvcmljYWwgZGlzdGFuY2VzLiBUaGUgdGFyZ2V0XG4gICAqIGRhdGEgaXMgYXNzdW1lZCB0byBiZSBjYXRlZ29yaWNhbCBsYWJlbCBkYXRhIChhIHZlY3RvciBvZiBsYWJlbHMpLFxuICAgKiBhbmQgdGhpcyB3aWxsIHVwZGF0ZSB0aGUgZnV6enkgc2ltcGxpY2lhbCBzZXQgdG8gcmVzcGVjdCB0aGF0IGxhYmVsIGRhdGEuXG4gICAqL1xuICBwcml2YXRlIGNhdGVnb3JpY2FsU2ltcGxpY2lhbFNldEludGVyc2VjdGlvbihcbiAgICBzaW1wbGljaWFsU2V0OiBtYXRyaXguU3BhcnNlTWF0cml4LFxuICAgIHRhcmdldDogbnVtYmVyW10sXG4gICAgZmFyRGlzdDogbnVtYmVyLFxuICAgIHVua25vd25EaXN0ID0gMS4wXG4gICkge1xuICAgIGxldCBpbnRlcnNlY3Rpb24gPSBmYXN0SW50ZXJzZWN0aW9uKFxuICAgICAgc2ltcGxpY2lhbFNldCxcbiAgICAgIHRhcmdldCxcbiAgICAgIHVua25vd25EaXN0LFxuICAgICAgZmFyRGlzdFxuICAgICk7XG4gICAgaW50ZXJzZWN0aW9uID0gbWF0cml4LmVsaW1pbmF0ZVplcm9zKGludGVyc2VjdGlvbik7XG4gICAgcmV0dXJuIHJlc2V0TG9jYWxDb25uZWN0aXZpdHkoaW50ZXJzZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGEgY29udGludW91cyB2ZXJzaW9uIG9mIHRoZSBkaXN0YW5jZSB0byB0aGUga3RoIG5lYXJlc3RcbiAgICogbmVpZ2hib3IuIFRoYXQgaXMsIHRoaXMgaXMgc2ltaWxhciB0byBrbm4tZGlzdGFuY2UgYnV0IGFsbG93cyBjb250aW51b3VzXG4gICAqIGsgdmFsdWVzIHJhdGhlciB0aGFuIHJlcXVpcmluZyBhbiBpbnRlZ3JhbCBrLiBJbiBlc3NjZW5jZSB3ZSBhcmUgc2ltcGx5XG4gICAqIGNvbXB1dGluZyB0aGUgZGlzdGFuY2Ugc3VjaCB0aGF0IHRoZSBjYXJkaW5hbGl0eSBvZiBmdXp6eSBzZXQgd2UgZ2VuZXJhdGVcbiAgICogaXMgay5cbiAgICovXG4gIHByaXZhdGUgc21vb3RoS05ORGlzdGFuY2UoXG4gICAgZGlzdGFuY2VzOiBWZWN0b3JzLFxuICAgIGs6IG51bWJlcixcbiAgICBsb2NhbENvbm5lY3Rpdml0eSA9IDEuMCxcbiAgICBuSXRlciA9IDY0LFxuICAgIGJhbmR3aWR0aCA9IDEuMFxuICApIHtcbiAgICBjb25zdCB0YXJnZXQgPSAoTWF0aC5sb2coaykgLyBNYXRoLmxvZygyKSkgKiBiYW5kd2lkdGg7XG4gICAgY29uc3QgcmhvID0gdXRpbHMuemVyb3MoZGlzdGFuY2VzLmxlbmd0aCk7XG4gICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuemVyb3MoZGlzdGFuY2VzLmxlbmd0aCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpc3RhbmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IGxvID0gMC4wO1xuICAgICAgbGV0IGhpID0gSW5maW5pdHk7XG4gICAgICBsZXQgbWlkID0gMS4wO1xuXG4gICAgICAvLyBUT0RPOiBUaGlzIGlzIHZlcnkgaW5lZmZpY2llbnQsIGJ1dCB3aWxsIGRvIGZvciBub3cuIEZJWE1FXG4gICAgICBjb25zdCBpdGhEaXN0YW5jZXMgPSBkaXN0YW5jZXNbaV07XG4gICAgICBjb25zdCBub25aZXJvRGlzdHMgPSBpdGhEaXN0YW5jZXMuZmlsdGVyKGQgPT4gZCA+IDAuMCk7XG5cbiAgICAgIGlmIChub25aZXJvRGlzdHMubGVuZ3RoID49IGxvY2FsQ29ubmVjdGl2aXR5KSB7XG4gICAgICAgIGxldCBpbmRleCA9IE1hdGguZmxvb3IobG9jYWxDb25uZWN0aXZpdHkpO1xuICAgICAgICBsZXQgaW50ZXJwb2xhdGlvbiA9IGxvY2FsQ29ubmVjdGl2aXR5IC0gaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA+IDApIHtcbiAgICAgICAgICByaG9baV0gPSBub25aZXJvRGlzdHNbaW5kZXggLSAxXTtcbiAgICAgICAgICBpZiAoaW50ZXJwb2xhdGlvbiA+IFNNT09USF9LX1RPTEVSQU5DRSkge1xuICAgICAgICAgICAgcmhvW2ldICs9XG4gICAgICAgICAgICAgIGludGVycG9sYXRpb24gKiAobm9uWmVyb0Rpc3RzW2luZGV4XSAtIG5vblplcm9EaXN0c1tpbmRleCAtIDFdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmhvW2ldID0gaW50ZXJwb2xhdGlvbiAqIG5vblplcm9EaXN0c1swXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub25aZXJvRGlzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICByaG9baV0gPSB1dGlscy5tYXgobm9uWmVyb0Rpc3RzKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgbiA9IDA7IG4gPCBuSXRlcjsgbisrKSB7XG4gICAgICAgIGxldCBwc3VtID0gMC4wO1xuICAgICAgICBmb3IgKGxldCBqID0gMTsgaiA8IGRpc3RhbmNlc1tpXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZXNbaV1bal0gLSByaG9baV07XG4gICAgICAgICAgaWYgKGQgPiAwKSB7XG4gICAgICAgICAgICBwc3VtICs9IE1hdGguZXhwKC0oZCAvIG1pZCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwc3VtICs9IDEuMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoTWF0aC5hYnMocHN1bSAtIHRhcmdldCkgPCBTTU9PVEhfS19UT0xFUkFOQ0UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwc3VtID4gdGFyZ2V0KSB7XG4gICAgICAgICAgaGkgPSBtaWQ7XG4gICAgICAgICAgbWlkID0gKGxvICsgaGkpIC8gMi4wO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvID0gbWlkO1xuICAgICAgICAgIGlmIChoaSA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgIG1pZCAqPSAyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtaWQgPSAobG8gKyBoaSkgLyAyLjA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdFtpXSA9IG1pZDtcblxuICAgICAgLy8gVE9ETzogVGhpcyBpcyB2ZXJ5IGluZWZmaWNpZW50LCBidXQgd2lsbCBkbyBmb3Igbm93LiBGSVhNRVxuICAgICAgaWYgKHJob1tpXSA+IDAuMCkge1xuICAgICAgICBjb25zdCBtZWFuSXRoRGlzdGFuY2VzID0gdXRpbHMubWVhbihpdGhEaXN0YW5jZXMpO1xuICAgICAgICBpZiAocmVzdWx0W2ldIDwgTUlOX0tfRElTVF9TQ0FMRSAqIG1lYW5JdGhEaXN0YW5jZXMpIHtcbiAgICAgICAgICByZXN1bHRbaV0gPSBNSU5fS19ESVNUX1NDQUxFICogbWVhbkl0aERpc3RhbmNlcztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWVhbkRpc3RhbmNlcyA9IHV0aWxzLm1lYW4oZGlzdGFuY2VzLm1hcCh1dGlscy5tZWFuKSk7XG4gICAgICAgIGlmIChyZXN1bHRbaV0gPCBNSU5fS19ESVNUX1NDQUxFICogbWVhbkRpc3RhbmNlcykge1xuICAgICAgICAgIHJlc3VsdFtpXSA9IE1JTl9LX0RJU1RfU0NBTEUgKiBtZWFuRGlzdGFuY2VzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgc2lnbWFzOiByZXN1bHQsIHJob3M6IHJobyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCB0aGUgbWVtYmVyc2hpcCBzdHJlbmd0aCBkYXRhIGZvciB0aGUgMS1za2VsZXRvbiBvZiBlYWNoIGxvY2FsXG4gICAqIGZ1enp5IHNpbXBsaWNpYWwgc2V0IC0tIHRoaXMgaXMgZm9ybWVkIGFzIGEgc3BhcnNlIG1hdHJpeCB3aGVyZSBlYWNoIHJvdyBpc1xuICAgKiBhIGxvY2FsIGZ1enp5IHNpbXBsaWNpYWwgc2V0LCB3aXRoIGEgbWVtYmVyc2hpcCBzdHJlbmd0aCBmb3IgdGhlXG4gICAqIDEtc2ltcGxleCB0byBlYWNoIG90aGVyIGRhdGEgcG9pbnQuXG4gICAqL1xuICBwcml2YXRlIGNvbXB1dGVNZW1iZXJzaGlwU3RyZW5ndGhzKFxuICAgIGtubkluZGljZXM6IFZlY3RvcnMsXG4gICAga25uRGlzdGFuY2VzOiBWZWN0b3JzLFxuICAgIHNpZ21hczogbnVtYmVyW10sXG4gICAgcmhvczogbnVtYmVyW11cbiAgKTogeyByb3dzOiBudW1iZXJbXTsgY29sczogbnVtYmVyW107IHZhbHM6IG51bWJlcltdIH0ge1xuICAgIGNvbnN0IG5TYW1wbGVzID0ga25uSW5kaWNlcy5sZW5ndGg7XG4gICAgY29uc3Qgbk5laWdoYm9ycyA9IGtubkluZGljZXNbMF0ubGVuZ3RoO1xuXG4gICAgY29uc3Qgcm93cyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgY29scyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgdmFscyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICAgIGxldCB2YWwgPSAwO1xuICAgICAgICBpZiAoa25uSW5kaWNlc1tpXVtqXSA9PT0gLTEpIHtcbiAgICAgICAgICBjb250aW51ZTsgLy8gV2UgZGlkbid0IGdldCB0aGUgZnVsbCBrbm4gZm9yIGlcbiAgICAgICAgfVxuICAgICAgICBpZiAoa25uSW5kaWNlc1tpXVtqXSA9PT0gaSkge1xuICAgICAgICAgIHZhbCA9IDAuMDtcbiAgICAgICAgfSBlbHNlIGlmIChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldIDw9IDAuMCkge1xuICAgICAgICAgIHZhbCA9IDEuMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWwgPSBNYXRoLmV4cCgtKChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldKSAvIHNpZ21hc1tpXSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcm93c1tpICogbk5laWdoYm9ycyArIGpdID0gaTtcbiAgICAgICAgY29sc1tpICogbk5laWdoYm9ycyArIGpdID0ga25uSW5kaWNlc1tpXVtqXTtcbiAgICAgICAgdmFsc1tpICogbk5laWdoYm9ycyArIGpdID0gdmFsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IHJvd3MsIGNvbHMsIHZhbHMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGEgZnV6enkgc2ltcGxpY2lhbCBzZXQgZW1iZWRkaW5nLCB1c2luZyBhIHNwZWNpZmllZFxuICAgKiBpbml0aWFsaXNhdGlvbiBtZXRob2QgYW5kIHRoZW4gbWluaW1pemluZyB0aGUgZnV6enkgc2V0IGNyb3NzIGVudHJvcHlcbiAgICogYmV0d2VlbiB0aGUgMS1za2VsZXRvbnMgb2YgdGhlIGhpZ2ggYW5kIGxvdyBkaW1lbnNpb25hbCBmdXp6eSBzaW1wbGljaWFsXG4gICAqIHNldHMuXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVTaW1wbGljaWFsU2V0RW1iZWRkaW5nKCkge1xuICAgIGNvbnN0IG5FcG9jaHMgPSB0aGlzLmdldE5FcG9jaHMoKTtcblxuICAgIGNvbnN0IHsgbkNvbXBvbmVudHMgfSA9IHRoaXM7XG4gICAgY29uc3QgZ3JhcGhWYWx1ZXMgPSB0aGlzLmdyYXBoLmdldFZhbHVlcygpO1xuICAgIGxldCBncmFwaE1heCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdmFsdWUgPSBncmFwaFZhbHVlc1tpXTtcbiAgICAgIGlmIChncmFwaE1heCA8IGdyYXBoVmFsdWVzW2ldKSB7XG4gICAgICAgIGdyYXBoTWF4ID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZ3JhcGggPSB0aGlzLmdyYXBoLm1hcCh2YWx1ZSA9PiB7XG4gICAgICBpZiAodmFsdWUgPCBncmFwaE1heCAvIG5FcG9jaHMpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBXZSdyZSBub3QgY29tcHV0aW5nIHRoZSBzcGVjdHJhbCBpbml0aWFsaXphdGlvbiBpbiB0aGlzIGltcGxlbWVudGF0aW9uXG4gICAgLy8gdW50aWwgd2UgZGV0ZXJtaW5lIGEgYmV0dGVyIGVpZ2VudmFsdWUvZWlnZW52ZWN0b3IgY29tcHV0YXRpb25cbiAgICAvLyBhcHByb2FjaFxuICAgIHRoaXMuZW1iZWRkaW5nID0gdXRpbHMuemVyb3MoZ3JhcGgublJvd3MpLm1hcCgoKSA9PiB7XG4gICAgICByZXR1cm4gdXRpbHMuemVyb3MobkNvbXBvbmVudHMpLm1hcCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB1dGlscy50YXVSYW5kKHRoaXMucmFuZG9tKSAqIDIwICsgLTEwOyAvLyBSYW5kb20gZnJvbSAtMTAgdG8gMTBcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gR2V0IGdyYXBoIGRhdGEgaW4gb3JkZXJlZCB3YXkuLi5cbiAgICBjb25zdCB3ZWlnaHRzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGhlYWQ6IG51bWJlcltdID0gW107XG4gICAgY29uc3QgdGFpbDogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCByb3dDb2xWYWx1ZXMgPSBncmFwaC5nZXRBbGwoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd0NvbFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZW50cnkgPSByb3dDb2xWYWx1ZXNbaV07XG4gICAgICBpZiAoZW50cnkudmFsdWUpIHtcbiAgICAgICAgd2VpZ2h0cy5wdXNoKGVudHJ5LnZhbHVlKTtcbiAgICAgICAgdGFpbC5wdXNoKGVudHJ5LnJvdyk7XG4gICAgICAgIGhlYWQucHVzaChlbnRyeS5jb2wpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBlcG9jaHNQZXJTYW1wbGUgPSB0aGlzLm1ha2VFcG9jaHNQZXJTYW1wbGUod2VpZ2h0cywgbkVwb2Nocyk7XG5cbiAgICByZXR1cm4geyBoZWFkLCB0YWlsLCBlcG9jaHNQZXJTYW1wbGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHNldCBvZiB3ZWlnaHRzIGFuZCBudW1iZXIgb2YgZXBvY2hzIGdlbmVyYXRlIHRoZSBudW1iZXIgb2ZcbiAgICogZXBvY2hzIHBlciBzYW1wbGUgZm9yIGVhY2ggd2VpZ2h0LlxuICAgKi9cbiAgcHJpdmF0ZSBtYWtlRXBvY2hzUGVyU2FtcGxlKHdlaWdodHM6IG51bWJlcltdLCBuRXBvY2hzOiBudW1iZXIpIHtcbiAgICBjb25zdCByZXN1bHQgPSB1dGlscy5maWxsZWQod2VpZ2h0cy5sZW5ndGgsIC0xLjApO1xuICAgIGNvbnN0IG1heCA9IHV0aWxzLm1heCh3ZWlnaHRzKTtcbiAgICBjb25zdCBuU2FtcGxlcyA9IHdlaWdodHMubWFwKHcgPT4gKHcgLyBtYXgpICogbkVwb2Nocyk7XG4gICAgblNhbXBsZXMuZm9yRWFjaCgobiwgaSkgPT4ge1xuICAgICAgaWYgKG4gPiAwKSByZXN1bHRbaV0gPSBuRXBvY2hzIC8gblNhbXBsZXNbaV07XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NpZ25zIG9wdGltaXphdGlvbiBzdGF0ZSBwYXJhbWV0ZXJzIGZyb20gYSBwYXJ0aWFsIG9wdGltaXphdGlvbiBzdGF0ZS5cbiAgICovXG4gIHByaXZhdGUgYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHN0YXRlOiBQYXJ0aWFsPE9wdGltaXphdGlvblN0YXRlPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5vcHRpbWl6YXRpb25TdGF0ZSwgc3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYSBmZXcgb3B0aW1pemF0aW9uIHN0YXRlIHBhcmFtZXRlcnMgdGhhdCBhcmUgbmVjZXNzYXJ5IGJlZm9yZSBlbnRlcmluZ1xuICAgKiB0aGUgb3B0aW1pemF0aW9uIHN0ZXAgbG9vcC5cbiAgICovXG4gIHByaXZhdGUgcHJlcGFyZUZvck9wdGltaXphdGlvbkxvb3AoKSB7XG4gICAgLy8gSHlwZXJwYXJhbWV0ZXJzXG4gICAgY29uc3QgeyByZXB1bHNpb25TdHJlbmd0aCwgbGVhcm5pbmdSYXRlLCBuZWdhdGl2ZVNhbXBsZVJhdGUgfSA9IHRoaXM7XG5cbiAgICBjb25zdCB7XG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBoZWFkRW1iZWRkaW5nLFxuICAgICAgdGFpbEVtYmVkZGluZyxcbiAgICB9ID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZTtcblxuICAgIGNvbnN0IGRpbSA9IGhlYWRFbWJlZGRpbmdbMF0ubGVuZ3RoO1xuICAgIGNvbnN0IG1vdmVPdGhlciA9IGhlYWRFbWJlZGRpbmcubGVuZ3RoID09PSB0YWlsRW1iZWRkaW5nLmxlbmd0aDtcblxuICAgIGNvbnN0IGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlID0gZXBvY2hzUGVyU2FtcGxlLm1hcChcbiAgICAgIGUgPT4gZSAvIG5lZ2F0aXZlU2FtcGxlUmF0ZVxuICAgICk7XG4gICAgY29uc3QgZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZSA9IFsuLi5lcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZV07XG4gICAgY29uc3QgZXBvY2hPZk5leHRTYW1wbGUgPSBbLi4uZXBvY2hzUGVyU2FtcGxlXTtcblxuICAgIHRoaXMuYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHtcbiAgICAgIGVwb2NoT2ZOZXh0U2FtcGxlLFxuICAgICAgZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZSxcbiAgICAgIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlLFxuICAgICAgbW92ZU90aGVyLFxuICAgICAgaW5pdGlhbEFscGhhOiBsZWFybmluZ1JhdGUsXG4gICAgICBhbHBoYTogbGVhcm5pbmdSYXRlLFxuICAgICAgZ2FtbWE6IHJlcHVsc2lvblN0cmVuZ3RoLFxuICAgICAgZGltLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIG9wdGltaXphdGlvbiBzdGF0ZSBmb3Igc3RlcHdpc2Ugb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplT3B0aW1pemF0aW9uKCkge1xuICAgIC8vIEFsZ29yaXRobSBzdGF0ZVxuICAgIGNvbnN0IGhlYWRFbWJlZGRpbmcgPSB0aGlzLmVtYmVkZGluZztcbiAgICBjb25zdCB0YWlsRW1iZWRkaW5nID0gdGhpcy5lbWJlZGRpbmc7XG5cbiAgICAvLyBJbml0aWFsaXplZCBpbiBpbml0aWFsaXplU2ltcGxpY2lhbFNldEVtYmVkZGluZygpXG4gICAgY29uc3QgeyBoZWFkLCB0YWlsLCBlcG9jaHNQZXJTYW1wbGUgfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG5cbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5nZXRORXBvY2hzKCk7XG4gICAgY29uc3QgblZlcnRpY2VzID0gdGhpcy5ncmFwaC5uQ29scztcblxuICAgIGNvbnN0IHsgYSwgYiB9ID0gZmluZEFCUGFyYW1zKHRoaXMuc3ByZWFkLCB0aGlzLm1pbkRpc3QpO1xuXG4gICAgdGhpcy5hc3NpZ25PcHRpbWl6YXRpb25TdGF0ZVBhcmFtZXRlcnMoe1xuICAgICAgaGVhZEVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmcsXG4gICAgICBoZWFkLFxuICAgICAgdGFpbCxcbiAgICAgIGVwb2Noc1BlclNhbXBsZSxcbiAgICAgIGEsXG4gICAgICBiLFxuICAgICAgbkVwb2NocyxcbiAgICAgIG5WZXJ0aWNlcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXByb3ZlIGFuIGVtYmVkZGluZyB1c2luZyBzdG9jaGFzdGljIGdyYWRpZW50IGRlc2NlbnQgdG8gbWluaW1pemUgdGhlXG4gICAqIGZ1enp5IHNldCBjcm9zcyBlbnRyb3B5IGJldHdlZW4gdGhlIDEtc2tlbGV0b25zIG9mIHRoZSBoaWdoIGRpbWVuc2lvbmFsXG4gICAqIGFuZCBsb3cgZGltZW5zaW9uYWwgZnV6enkgc2ltcGxpY2lhbCBzZXRzLiBJbiBwcmFjdGljZSB0aGlzIGlzIGRvbmUgYnlcbiAgICogc2FtcGxpbmcgZWRnZXMgYmFzZWQgb24gdGhlaXIgbWVtYmVyc2hpcCBzdHJlbmd0aCAod2l0aCB0aGUgKDEtcCkgdGVybXNcbiAgICogY29taW5nIGZyb20gbmVnYXRpdmUgc2FtcGxpbmcgc2ltaWxhciB0byB3b3JkMnZlYykuXG4gICAqL1xuICBwcml2YXRlIG9wdGltaXplTGF5b3V0U3RlcChuOiBudW1iZXIpIHtcbiAgICBjb25zdCB7IG9wdGltaXphdGlvblN0YXRlIH0gPSB0aGlzO1xuICAgIGNvbnN0IHtcbiAgICAgIGhlYWQsXG4gICAgICB0YWlsLFxuICAgICAgaGVhZEVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmcsXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBlcG9jaE9mTmV4dFNhbXBsZSxcbiAgICAgIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGUsXG4gICAgICBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZSxcbiAgICAgIG1vdmVPdGhlcixcbiAgICAgIGluaXRpYWxBbHBoYSxcbiAgICAgIGFscGhhLFxuICAgICAgZ2FtbWEsXG4gICAgICBhLFxuICAgICAgYixcbiAgICAgIGRpbSxcbiAgICAgIG5FcG9jaHMsXG4gICAgICBuVmVydGljZXMsXG4gICAgfSA9IG9wdGltaXphdGlvblN0YXRlO1xuXG4gICAgY29uc3QgY2xpcFZhbHVlID0gNC4wO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlcG9jaHNQZXJTYW1wbGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChlcG9jaE9mTmV4dFNhbXBsZVtpXSA+IG4pIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGogPSBoZWFkW2ldO1xuICAgICAgY29uc3QgayA9IHRhaWxbaV07XG5cbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBoZWFkRW1iZWRkaW5nW2pdO1xuICAgICAgY29uc3Qgb3RoZXIgPSB0YWlsRW1iZWRkaW5nW2tdO1xuXG4gICAgICBjb25zdCBkaXN0U3F1YXJlZCA9IHJEaXN0KGN1cnJlbnQsIG90aGVyKTtcblxuICAgICAgbGV0IGdyYWRDb2VmZiA9IDA7XG4gICAgICBpZiAoZGlzdFNxdWFyZWQgPiAwKSB7XG4gICAgICAgIGdyYWRDb2VmZiA9IC0yLjAgKiBhICogYiAqIE1hdGgucG93KGRpc3RTcXVhcmVkLCBiIC0gMS4wKTtcbiAgICAgICAgZ3JhZENvZWZmIC89IGEgKiBNYXRoLnBvdyhkaXN0U3F1YXJlZCwgYikgKyAxLjA7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgZGltOyBkKyspIHtcbiAgICAgICAgY29uc3QgZ3JhZEQgPSBjbGlwKGdyYWRDb2VmZiAqIChjdXJyZW50W2RdIC0gb3RoZXJbZF0pLCBjbGlwVmFsdWUpO1xuICAgICAgICBjdXJyZW50W2RdICs9IGdyYWREICogYWxwaGE7XG4gICAgICAgIGlmIChtb3ZlT3RoZXIpIHtcbiAgICAgICAgICBvdGhlcltkXSArPSAtZ3JhZEQgKiBhbHBoYTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBlcG9jaE9mTmV4dFNhbXBsZVtpXSArPSBlcG9jaHNQZXJTYW1wbGVbaV07XG5cbiAgICAgIGNvbnN0IG5OZWdTYW1wbGVzID0gTWF0aC5mbG9vcihcbiAgICAgICAgKG4gLSBlcG9jaE9mTmV4dE5lZ2F0aXZlU2FtcGxlW2ldKSAvIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlW2ldXG4gICAgICApO1xuXG4gICAgICBmb3IgKGxldCBwID0gMDsgcCA8IG5OZWdTYW1wbGVzOyBwKyspIHtcbiAgICAgICAgY29uc3QgayA9IHV0aWxzLnRhdVJhbmRJbnQoblZlcnRpY2VzLCB0aGlzLnJhbmRvbSk7XG4gICAgICAgIGNvbnN0IG90aGVyID0gdGFpbEVtYmVkZGluZ1trXTtcblxuICAgICAgICBjb25zdCBkaXN0U3F1YXJlZCA9IHJEaXN0KGN1cnJlbnQsIG90aGVyKTtcblxuICAgICAgICBsZXQgZ3JhZENvZWZmID0gMC4wO1xuICAgICAgICBpZiAoZGlzdFNxdWFyZWQgPiAwLjApIHtcbiAgICAgICAgICBncmFkQ29lZmYgPSAyLjAgKiBnYW1tYSAqIGI7XG4gICAgICAgICAgZ3JhZENvZWZmIC89XG4gICAgICAgICAgICAoMC4wMDEgKyBkaXN0U3F1YXJlZCkgKiAoYSAqIE1hdGgucG93KGRpc3RTcXVhcmVkLCBiKSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGogPT09IGspIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgZGltOyBkKyspIHtcbiAgICAgICAgICBsZXQgZ3JhZEQgPSA0LjA7XG4gICAgICAgICAgaWYgKGdyYWRDb2VmZiA+IDAuMCkge1xuICAgICAgICAgICAgZ3JhZEQgPSBjbGlwKGdyYWRDb2VmZiAqIChjdXJyZW50W2RdIC0gb3RoZXJbZF0pLCBjbGlwVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50W2RdICs9IGdyYWREICogYWxwaGE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGVbaV0gKz0gbk5lZ1NhbXBsZXMgKiBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZVtpXTtcbiAgICB9XG4gICAgb3B0aW1pemF0aW9uU3RhdGUuYWxwaGEgPSBpbml0aWFsQWxwaGEgKiAoMS4wIC0gbiAvIG5FcG9jaHMpO1xuXG4gICAgb3B0aW1pemF0aW9uU3RhdGUuY3VycmVudEVwb2NoICs9IDE7XG4gICAgcmV0dXJuIGhlYWRFbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dEFzeW5jKFxuICAgIGVwb2NoQ2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHN0ZXAgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBuRXBvY2hzLCBjdXJyZW50RXBvY2ggfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG4gICAgICAgICAgdGhpcy5lbWJlZGRpbmcgPSB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgICAgICAgIGNvbnN0IGVwb2NoQ29tcGxldGVkID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5jdXJyZW50RXBvY2g7XG4gICAgICAgICAgY29uc3Qgc2hvdWxkU3RvcCA9IGVwb2NoQ2FsbGJhY2soZXBvY2hDb21wbGV0ZWQpID09PSBmYWxzZTtcbiAgICAgICAgICBjb25zdCBpc0ZpbmlzaGVkID0gZXBvY2hDb21wbGV0ZWQgPT09IG5FcG9jaHM7XG4gICAgICAgICAgaWYgKCFzaG91bGRTdG9wICYmICFpc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHN0ZXAoKSwgMCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGlzRmluaXNoZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHN0ZXAoKSwgMCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dChcbiAgICBlcG9jaENhbGxiYWNrOiAoZXBvY2hOdW1iZXI6IG51bWJlcikgPT4gdm9pZCB8IGJvb2xlYW4gPSAoKSA9PiB0cnVlXG4gICk6IFZlY3RvcnMge1xuICAgIGxldCBpc0ZpbmlzaGVkID0gZmFsc2U7XG4gICAgbGV0IGVtYmVkZGluZzogVmVjdG9ycyA9IFtdO1xuICAgIHdoaWxlICghaXNGaW5pc2hlZCkge1xuICAgICAgY29uc3QgeyBuRXBvY2hzLCBjdXJyZW50RXBvY2ggfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG4gICAgICBlbWJlZGRpbmcgPSB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgICAgY29uc3QgZXBvY2hDb21wbGV0ZWQgPSB0aGlzLm9wdGltaXphdGlvblN0YXRlLmN1cnJlbnRFcG9jaDtcbiAgICAgIGNvbnN0IHNob3VsZFN0b3AgPSBlcG9jaENhbGxiYWNrKGVwb2NoQ29tcGxldGVkKSA9PT0gZmFsc2U7XG4gICAgICBpc0ZpbmlzaGVkID0gZXBvY2hDb21wbGV0ZWQgPT09IG5FcG9jaHMgfHwgc2hvdWxkU3RvcDtcbiAgICB9XG4gICAgcmV0dXJuIGVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgZXBvY2hzIGZvciBvcHRpbWl6aW5nIHRoZSBwcm9qZWN0aW9uLlxuICAgKiBOT1RFOiBUaGlzIGhldXJpc3RpYyBkaWZmZXJzIGZyb20gdGhlIHB5dGhvbiB2ZXJzaW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0TkVwb2NocygpIHtcbiAgICBjb25zdCBncmFwaCA9IHRoaXMuZ3JhcGg7XG5cbiAgICBpZiAodGhpcy5uRXBvY2hzID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMubkVwb2NocztcbiAgICB9XG5cbiAgICBpZiAoIWdyYXBoKSB7XG4gICAgICByZXR1cm4gMjAwO1xuICAgIH1cblxuICAgIGNvbnN0IGxlbmd0aCA9IGdyYXBoLm5Sb3dzO1xuICAgIGlmIChsZW5ndGggPD0gMjUwMCkge1xuICAgICAgcmV0dXJuIDUwMDtcbiAgICB9IGVsc2UgaWYgKGxlbmd0aCA8PSA1MDAwKSB7XG4gICAgICByZXR1cm4gNDAwO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoIDw9IDc1MDApIHtcbiAgICAgIHJldHVybiAzMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAyMDA7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldWNsaWRlYW4oeDogVmVjdG9yLCB5OiBWZWN0b3IpIHtcbiAgbGV0IHJlc3VsdCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdCArPSAoeFtpXSAtIHlbaV0pICoqIDI7XG4gIH1cbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbnVtZXJpYyh4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICBjb25zdCByZXN1bHQgPSBNYXRoLmFicyh4IC0geSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmUoeDogVmVjdG9yLCB5OiBWZWN0b3IpIHtcbiAgbGV0IHJlc3VsdCA9IDAuMDtcbiAgbGV0IG5vcm1YID0gMC4wO1xuICBsZXQgbm9ybVkgPSAwLjA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IHhbaV0gKiB5W2ldO1xuICAgIG5vcm1YICs9IHhbaV0gKiogMjtcbiAgICBub3JtWSArPSB5W2ldICoqIDI7XG4gIH1cblxuICBpZiAobm9ybVggPT09IDAgJiYgbm9ybVkgPT09IDApIHtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIGlmIChub3JtWCA9PT0gMCB8fCBub3JtWSA9PT0gMCkge1xuICAgIHJldHVybiAxLjA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDEuMCAtIHJlc3VsdCAvIE1hdGguc3FydChub3JtWCAqIG5vcm1ZKTtcbiAgfVxufVxuXG4vKipcbiAqIEFuIGludGVyZmFjZSByZXByZXNlbnRpbmcgdGhlIG9wdGltaXphdGlvbiBzdGF0ZSB0cmFja2VkIGJldHdlZW4gc3RlcHMgb2ZcbiAqIHRoZSBTR0Qgb3B0aW1pemF0aW9uXG4gKi9cbmNsYXNzIE9wdGltaXphdGlvblN0YXRlIHtcbiAgY3VycmVudEVwb2NoID0gMDtcblxuICAvLyBEYXRhIHRyYWNrZWQgZHVyaW5nIG9wdGltaXphdGlvbiBzdGVwcy5cbiAgaGVhZEVtYmVkZGluZzogbnVtYmVyW11bXSA9IFtdO1xuICB0YWlsRW1iZWRkaW5nOiBudW1iZXJbXVtdID0gW107XG4gIGhlYWQ6IG51bWJlcltdID0gW107XG4gIHRhaWw6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1BlclNhbXBsZTogbnVtYmVyW10gPSBbXTtcbiAgZXBvY2hPZk5leHRTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlOiBudW1iZXJbXSA9IFtdO1xuICBtb3ZlT3RoZXIgPSB0cnVlO1xuICBpbml0aWFsQWxwaGEgPSAxLjA7XG4gIGFscGhhID0gMS4wO1xuICBnYW1tYSA9IDEuMDtcbiAgYSA9IDEuNTc2OTQzNDYwMzExMzA3NztcbiAgYiA9IDAuODk1MDYwODc3OTEwOTczMztcbiAgZGltID0gMjtcbiAgbkVwb2NocyA9IDUwMDtcbiAgblZlcnRpY2VzID0gMDtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBjbGFtcGluZyBvZiBhIHZhbHVlIGludG8gYSBmaXhlZCByYW5nZVxuICovXG5mdW5jdGlvbiBjbGlwKHg6IG51bWJlciwgY2xpcFZhbHVlOiBudW1iZXIpIHtcbiAgaWYgKHggPiBjbGlwVmFsdWUpIHJldHVybiBjbGlwVmFsdWU7XG4gIGVsc2UgaWYgKHggPCAtY2xpcFZhbHVlKSByZXR1cm4gLWNsaXBWYWx1ZTtcbiAgZWxzZSByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBSZWR1Y2VkIEV1Y2xpZGVhbiBkaXN0YW5jZS5cbiAqL1xuZnVuY3Rpb24gckRpc3QoeDogbnVtYmVyW10sIHk6IG51bWJlcltdKSB7XG4gIGxldCByZXN1bHQgPSAwLjA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdCArPSBNYXRoLnBvdyh4W2ldIC0geVtpXSwgMik7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBGaXQgYSwgYiBwYXJhbXMgZm9yIHRoZSBkaWZmZXJlbnRpYWJsZSBjdXJ2ZSB1c2VkIGluIGxvd2VyXG4gKiBkaW1lbnNpb25hbCBmdXp6eSBzaW1wbGljaWFsIGNvbXBsZXggY29uc3RydWN0aW9uLiBXZSB3YW50IHRoZVxuICogc21vb3RoIGN1cnZlIChmcm9tIGEgcHJlLWRlZmluZWQgZmFtaWx5IHdpdGggc2ltcGxlIGdyYWRpZW50KSB0aGF0XG4gKiBiZXN0IG1hdGNoZXMgYW4gb2Zmc2V0IGV4cG9uZW50aWFsIGRlY2F5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEFCUGFyYW1zKHNwcmVhZDogbnVtYmVyLCBtaW5EaXN0OiBudW1iZXIpIHtcbiAgY29uc3QgY3VydmUgPSAoW2EsIGJdOiBudW1iZXJbXSkgPT4gKHg6IG51bWJlcikgPT4ge1xuICAgIHJldHVybiAxLjAgLyAoMS4wICsgYSAqIHggKiogKDIgKiBiKSk7XG4gIH07XG5cbiAgY29uc3QgeHYgPSB1dGlsc1xuICAgIC5saW5lYXIoMCwgc3ByZWFkICogMywgMzAwKVxuICAgIC5tYXAodmFsID0+ICh2YWwgPCBtaW5EaXN0ID8gMS4wIDogdmFsKSk7XG5cbiAgY29uc3QgeXYgPSB1dGlscy56ZXJvcyh4di5sZW5ndGgpLm1hcCgodmFsLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IGd0ZSA9IHh2W2luZGV4XSA+PSBtaW5EaXN0O1xuICAgIHJldHVybiBndGUgPyBNYXRoLmV4cCgtKHh2W2luZGV4XSAtIG1pbkRpc3QpIC8gc3ByZWFkKSA6IHZhbDtcbiAgfSk7XG5cbiAgY29uc3QgaW5pdGlhbFZhbHVlcyA9IFswLjUsIDAuNV07XG4gIGNvbnN0IGRhdGEgPSB7IHg6IHh2LCB5OiB5diB9O1xuXG4gIC8vIERlZmF1bHQgb3B0aW9ucyBmb3IgdGhlIGFsZ29yaXRobSAoZnJvbSBnaXRodWIgZXhhbXBsZSlcbiAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICBkYW1waW5nOiAxLjUsXG4gICAgaW5pdGlhbFZhbHVlcyxcbiAgICBncmFkaWVudERpZmZlcmVuY2U6IDEwZS0yLFxuICAgIG1heEl0ZXJhdGlvbnM6IDEwMCxcbiAgICBlcnJvclRvbGVyYW5jZTogMTBlLTMsXG4gIH07XG5cbiAgY29uc3QgeyBwYXJhbWV0ZXJWYWx1ZXMgfSA9IExNKGRhdGEsIGN1cnZlLCBvcHRpb25zKTtcbiAgY29uc3QgW2EsIGJdID0gcGFyYW1ldGVyVmFsdWVzIGFzIG51bWJlcltdO1xuICByZXR1cm4geyBhLCBiIH07XG59XG5cbi8qKlxuICogVW5kZXIgdGhlIGFzc3VtcHRpb24gb2YgY2F0ZWdvcmljYWwgZGlzdGFuY2UgZm9yIHRoZSBpbnRlcnNlY3RpbmdcbiAqIHNpbXBsaWNpYWwgc2V0IHBlcmZvcm0gYSBmYXN0IGludGVyc2VjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhc3RJbnRlcnNlY3Rpb24oXG4gIGdyYXBoOiBtYXRyaXguU3BhcnNlTWF0cml4LFxuICB0YXJnZXQ6IG51bWJlcltdLFxuICB1bmtub3duRGlzdCA9IDEuMCxcbiAgZmFyRGlzdCA9IDUuMFxuKSB7XG4gIHJldHVybiBncmFwaC5tYXAoKHZhbHVlLCByb3csIGNvbCkgPT4ge1xuICAgIGlmICh0YXJnZXRbcm93XSA9PT0gLTEgfHwgdGFyZ2V0W2NvbF0gPT09IC0xKSB7XG4gICAgICByZXR1cm4gdmFsdWUgKiBNYXRoLmV4cCgtdW5rbm93bkRpc3QpO1xuICAgIH0gZWxzZSBpZiAodGFyZ2V0W3Jvd10gIT09IHRhcmdldFtjb2xdKSB7XG4gICAgICByZXR1cm4gdmFsdWUgKiBNYXRoLmV4cCgtZmFyRGlzdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIFJlc2V0IHRoZSBsb2NhbCBjb25uZWN0aXZpdHkgcmVxdWlyZW1lbnQgLS0gZWFjaCBkYXRhIHNhbXBsZSBzaG91bGRcbiAqIGhhdmUgY29tcGxldGUgY29uZmlkZW5jZSBpbiBhdCBsZWFzdCBvbmUgMS1zaW1wbGV4IGluIHRoZSBzaW1wbGljaWFsIHNldC5cbiAqIFdlIGNhbiBlbmZvcmNlIHRoaXMgYnkgbG9jYWxseSByZXNjYWxpbmcgY29uZmlkZW5jZXMsIGFuZCB0aGVuIHJlbWVyZ2luZyB0aGVcbiAqIGRpZmZlcmVudCBsb2NhbCBzaW1wbGljaWFsIHNldHMgdG9nZXRoZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldExvY2FsQ29ubmVjdGl2aXR5KHNpbXBsaWNpYWxTZXQ6IG1hdHJpeC5TcGFyc2VNYXRyaXgpIHtcbiAgc2ltcGxpY2lhbFNldCA9IG1hdHJpeC5ub3JtYWxpemUoc2ltcGxpY2lhbFNldCwgbWF0cml4Lk5vcm1UeXBlLm1heCk7XG4gIGNvbnN0IHRyYW5zcG9zZSA9IG1hdHJpeC50cmFuc3Bvc2Uoc2ltcGxpY2lhbFNldCk7XG4gIGNvbnN0IHByb2RNYXRyaXggPSBtYXRyaXgucGFpcndpc2VNdWx0aXBseSh0cmFuc3Bvc2UsIHNpbXBsaWNpYWxTZXQpO1xuICBzaW1wbGljaWFsU2V0ID0gbWF0cml4LmFkZChcbiAgICBzaW1wbGljaWFsU2V0LFxuICAgIG1hdHJpeC5zdWJ0cmFjdCh0cmFuc3Bvc2UsIHByb2RNYXRyaXgpXG4gICk7XG4gIHJldHVybiBtYXRyaXguZWxpbWluYXRlWmVyb3Moc2ltcGxpY2lhbFNldCk7XG59XG5cbi8qKlxuICogR2l2ZW4gaW5kaWNlcyBhbmQgd2VpZ2h0cyBhbmQgYW4gb3JpZ2luYWwgZW1iZWRkaW5nc1xuICogaW5pdGlhbGl6ZSB0aGUgcG9zaXRpb25zIG9mIG5ldyBwb2ludHMgcmVsYXRpdmUgdG8gdGhlXG4gKiBpbmRpY2VzIGFuZCB3ZWlnaHRzIChvZiB0aGVpciBuZWlnaGJvcnMgaW4gdGhlIHNvdXJjZSBkYXRhKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRUcmFuc2Zvcm0oXG4gIGluZGljZXM6IG51bWJlcltdW10sXG4gIHdlaWdodHM6IG51bWJlcltdW10sXG4gIGVtYmVkZGluZzogVmVjdG9yc1xuKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHV0aWxzXG4gICAgLnplcm9zKGluZGljZXMubGVuZ3RoKVxuICAgIC5tYXAoeiA9PiB1dGlscy56ZXJvcyhlbWJlZGRpbmdbMF0ubGVuZ3RoKSk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRpY2VzWzBdLmxlbmd0aDsgaisrKSB7XG4gICAgICBmb3IgKGxldCBkID0gMDsgZCA8IGVtYmVkZGluZ1swXS5sZW5ndGg7IGQrKykge1xuICAgICAgICBjb25zdCBhID0gaW5kaWNlc1tpXVtqXTtcbiAgICAgICAgcmVzdWx0W2ldW2RdICs9IHdlaWdodHNbaV1bal0gKiBlbWJlZGRpbmdbYV1bZF07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG4iXX0=","/**\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 }\n for (let j = i + 1; j < leafArray[n].length; j++) {\n if (leafArray[n][j] < 0) {\n break;\n }\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 let p = Math.floor(candidateNeighbors[0][i][j]);\n if (p < 0 || utils.tauRand(random) < rho) {\n continue;\n }\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 }\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 }\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 }\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 }\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 }\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 }\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 (let tree of forest) {\n initFromTree(tree, data, queryPoints, results, random);\n }\n }\n return results;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm5fZGVzY2VudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm5uX2Rlc2NlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBR2pDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxVQUFzQixFQUFFLE1BQWdCO0lBQ3BFLE9BQU8sU0FBUyxTQUFTLENBQ3ZCLElBQVksRUFDWixTQUFrQixFQUNsQixVQUFrQixFQUNsQixNQUFNLEdBQUcsRUFBRSxFQUNYLGFBQWEsR0FBRyxFQUFFLEVBQ2xCLEtBQUssR0FBRyxLQUFLLEVBQ2IsR0FBRyxHQUFHLEdBQUcsRUFDVCxVQUFVLEdBQUcsSUFBSTtRQUVqQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzlCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUU1RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNwQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3RFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxF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QU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgSmF2YVNjcmlwdCByZWltcGxlbWVudGF0aW9uIG9mIFVNQVAgKG9yaWdpbmFsIGxpY2Vuc2UgYmVsb3cpLCBmcm9tXG4gKiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9sbWNpbm5lcy91bWFwLlxuICpcbiAqIEBhdXRob3IgYW5keWNvZW5lbkBnb29nbGUuY29tIChBbmR5IENvZW5lbilcbiAqL1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBCU0QgMy1DbGF1c2UgTGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNywgTGVsYW5kIE1jSW5uZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4gKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcbiAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXG4gKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcbiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuaW1wb3J0ICogYXMgaGVhcCBmcm9tICcuL2hlYXAnO1xuaW1wb3J0ICogYXMgbWF0cml4IGZyb20gJy4vbWF0cml4JztcbmltcG9ydCAqIGFzIHRyZWUgZnJvbSAnLi90cmVlJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgUmFuZG9tRm4sIFZlY3RvcnMsIERpc3RhbmNlRm4sIFZlY3RvciB9IGZyb20gJy4vdW1hcCc7XG5cbi8qKlxuICogQ3JlYXRlIGEgdmVyc2lvbiBvZiBuZWFyZXN0IG5laWdoYm9yIGRlc2NlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTk5EZXNjZW50KGRpc3RhbmNlRm46IERpc3RhbmNlRm4sIHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIG5ORGVzY2VudChcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgbGVhZkFycmF5OiBWZWN0b3JzLFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBuSXRlcnMgPSAxMCxcbiAgICBtYXhDYW5kaWRhdGVzID0gNTAsXG4gICAgZGVsdGEgPSAwLjAwMSxcbiAgICByaG8gPSAwLjUsXG4gICAgcnBUcmVlSW5pdCA9IHRydWVcbiAgKSB7XG4gICAgY29uc3QgblZlcnRpY2VzID0gZGF0YS5sZW5ndGg7XG4gICAgY29uc3QgY3VycmVudEdyYXBoID0gaGVhcC5tYWtlSGVhcChkYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSBoZWFwLnJlamVjdGlvblNhbXBsZShuTmVpZ2hib3JzLCBkYXRhLmxlbmd0aCwgcmFuZG9tKTtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2ldLCBkYXRhW2luZGljZXNbal1dKTtcblxuICAgICAgICBoZWFwLmhlYXBQdXNoKGN1cnJlbnRHcmFwaCwgaSwgZCwgaW5kaWNlc1tqXSwgMSk7XG4gICAgICAgIGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBpbmRpY2VzW2pdLCBkLCBpLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJwVHJlZUluaXQpIHtcbiAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgbGVhZkFycmF5Lmxlbmd0aDsgbisrKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVhZkFycmF5W25dLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGxlYWZBcnJheVtuXVtpXSA8IDApIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBsZWFmQXJyYXlbbl0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChsZWFmQXJyYXlbbl1bal0gPCAwKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtsZWFmQXJyYXlbbl1baV1dLCBkYXRhW2xlYWZBcnJheVtuXVtqXV0pO1xuICAgICAgICAgICAgaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIGxlYWZBcnJheVtuXVtpXSwgZCwgbGVhZkFycmF5W25dW2pdLCAxKTtcbiAgICAgICAgICAgIGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBsZWFmQXJyYXlbbl1bal0sIGQsIGxlYWZBcnJheVtuXVtpXSwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgbiA9IDA7IG4gPCBuSXRlcnM7IG4rKykge1xuICAgICAgY29uc3QgY2FuZGlkYXRlTmVpZ2hib3JzID0gaGVhcC5idWlsZENhbmRpZGF0ZXMoXG4gICAgICAgIGN1cnJlbnRHcmFwaCxcbiAgICAgICAgblZlcnRpY2VzLFxuICAgICAgICBuTmVpZ2hib3JzLFxuICAgICAgICBtYXhDYW5kaWRhdGVzLFxuICAgICAgICByYW5kb21cbiAgICAgICk7XG5cbiAgICAgIGxldCBjID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgblZlcnRpY2VzOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBtYXhDYW5kaWRhdGVzOyBqKyspIHtcbiAgICAgICAgICBsZXQgcCA9IE1hdGguZmxvb3IoY2FuZGlkYXRlTmVpZ2hib3JzWzBdW2ldW2pdKTtcbiAgICAgICAgICBpZiAocCA8IDAgfHwgdXRpbHMudGF1UmFuZChyYW5kb20pIDwgcmhvKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBtYXhDYW5kaWRhdGVzOyBrKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHEgPSBNYXRoLmZsb29yKGNhbmRpZGF0ZU5laWdoYm9yc1swXVtpXVtrXSk7XG4gICAgICAgICAgICBjb25zdCBjaiA9IGNhbmRpZGF0ZU5laWdoYm9yc1syXVtpXVtqXTtcbiAgICAgICAgICAgIGNvbnN0IGNrID0gY2FuZGlkYXRlTmVpZ2hib3JzWzJdW2ldW2tdO1xuICAgICAgICAgICAgaWYgKHEgPCAwIHx8ICghY2ogJiYgIWNrKSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtwXSwgZGF0YVtxXSk7XG4gICAgICAgICAgICBjICs9IGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBwLCBkLCBxLCAxKTtcbiAgICAgICAgICAgIGMgKz0gaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIHEsIGQsIHAsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGMgPD0gZGVsdGEgKiBuTmVpZ2hib3JzICogZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHNvcnRlZCA9IGhlYXAuZGVoZWFwU29ydChjdXJyZW50R3JhcGgpO1xuICAgIHJldHVybiBzb3J0ZWQ7XG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIEluaXRGcm9tUmFuZG9tRm4gPSAoXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgZGF0YTogVmVjdG9yLFxuICBxdWVyeVBvaW50czogVmVjdG9yLFxuICBfaGVhcDogaGVhcC5IZWFwLFxuICByYW5kb206IFJhbmRvbUZuXG4pID0+IHZvaWQ7XG5cbmV4cG9ydCB0eXBlIEluaXRGcm9tVHJlZUZuID0gKFxuICBfdHJlZTogdHJlZS5GbGF0VHJlZSxcbiAgZGF0YTogVmVjdG9yLFxuICBxdWVyeVBvaW50czogVmVjdG9yLFxuICBfaGVhcDogaGVhcC5IZWFwLFxuICByYW5kb206IFJhbmRvbUZuXG4pID0+IHZvaWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlSW5pdGlhbGl6YXRpb25zKGRpc3RhbmNlRm46IERpc3RhbmNlRm4pIHtcbiAgZnVuY3Rpb24gaW5pdEZyb21SYW5kb20oXG4gICAgbk5laWdoYm9yczogbnVtYmVyLFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBxdWVyeVBvaW50czogVmVjdG9yLFxuICAgIF9oZWFwOiBoZWFwLkhlYXAsXG4gICAgcmFuZG9tOiBSYW5kb21GblxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5UG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gdXRpbHMucmVqZWN0aW9uU2FtcGxlKG5OZWlnaGJvcnMsIGRhdGEubGVuZ3RoLCByYW5kb20pO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRpY2VzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChpbmRpY2VzW2pdIDwgMCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZUZuKGRhdGFbaW5kaWNlc1tqXV0sIHF1ZXJ5UG9pbnRzW2ldKTtcbiAgICAgICAgaGVhcC5oZWFwUHVzaChfaGVhcCwgaSwgZCwgaW5kaWNlc1tqXSwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdEZyb21UcmVlKFxuICAgIF90cmVlOiB0cmVlLkZsYXRUcmVlLFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBxdWVyeVBvaW50czogVmVjdG9yLFxuICAgIF9oZWFwOiBoZWFwLkhlYXAsXG4gICAgcmFuZG9tOiBSYW5kb21GblxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5UG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gdHJlZS5zZWFyY2hGbGF0VHJlZShxdWVyeVBvaW50c1tpXSwgX3RyZWUsIHJhbmRvbSk7XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoaW5kaWNlc1tqXSA8IDApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtpbmRpY2VzW2pdXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICBoZWFwLmhlYXBQdXNoKF9oZWFwLCBpLCBkLCBpbmRpY2VzW2pdLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIHsgaW5pdEZyb21SYW5kb20sIGluaXRGcm9tVHJlZSB9O1xufVxuXG5leHBvcnQgdHlwZSBTZWFyY2hGbiA9IChcbiAgZGF0YTogVmVjdG9yLFxuICBncmFwaDogbWF0cml4LlNwYXJzZU1hdHJpeCxcbiAgaW5pdGlhbGl6YXRpb246IGhlYXAuSGVhcCxcbiAgcXVlcnlQb2ludHM6IFZlY3RvclxuKSA9PiBoZWFwLkhlYXA7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlSW5pdGlhbGl6ZWROTlNlYXJjaChkaXN0YW5jZUZuOiBEaXN0YW5jZUZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBublNlYXJjaEZuKFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBncmFwaDogbWF0cml4LlNwYXJzZU1hdHJpeCxcbiAgICBpbml0aWFsaXphdGlvbjogaGVhcC5IZWFwLFxuICAgIHF1ZXJ5UG9pbnRzOiBWZWN0b3JcbiAgKSB7XG4gICAgY29uc3QgeyBpbmRpY2VzLCBpbmRwdHIgfSA9IG1hdHJpeC5nZXRDU1IoZ3JhcGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyeVBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdHJpZWQgPSBuZXcgU2V0KGluaXRpYWxpemF0aW9uWzBdW2ldKTtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIC8vIEZpbmQgc21hbGxlc3QgZmxhZ2dlZCB2ZXJ0ZXhcbiAgICAgICAgY29uc3QgdmVydGV4ID0gaGVhcC5zbWFsbGVzdEZsYWdnZWQoaW5pdGlhbGl6YXRpb24sIGkpO1xuXG4gICAgICAgIGlmICh2ZXJ0ZXggPT09IC0xKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IGluZGljZXMuc2xpY2UoaW5kcHRyW3ZlcnRleF0sIGluZHB0clt2ZXJ0ZXggKyAxXSk7XG4gICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBjYW5kaWRhdGUgPT09IHZlcnRleCB8fFxuICAgICAgICAgICAgY2FuZGlkYXRlID09PSAtMSB8fFxuICAgICAgICAgICAgdHJpZWQuaGFzKGNhbmRpZGF0ZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2NhbmRpZGF0ZV0sIHF1ZXJ5UG9pbnRzW2ldKTtcbiAgICAgICAgICBoZWFwLnVuY2hlY2tlZEhlYXBQdXNoKGluaXRpYWxpemF0aW9uLCBpLCBkLCBjYW5kaWRhdGUsIDEpO1xuICAgICAgICAgIHRyaWVkLmFkZChjYW5kaWRhdGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpbml0aWFsaXphdGlvbjtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVTZWFyY2goXG4gIGZvcmVzdDogdHJlZS5GbGF0VHJlZVtdLFxuICBkYXRhOiBWZWN0b3IsXG4gIHF1ZXJ5UG9pbnRzOiBWZWN0b3IsXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgaW5pdEZyb21SYW5kb206IEluaXRGcm9tUmFuZG9tRm4sXG4gIGluaXRGcm9tVHJlZTogSW5pdEZyb21UcmVlRm4sXG4gIHJhbmRvbTogUmFuZG9tRm5cbikge1xuICBjb25zdCByZXN1bHRzID0gaGVhcC5tYWtlSGVhcChxdWVyeVBvaW50cy5sZW5ndGgsIG5OZWlnaGJvcnMpO1xuICBpbml0RnJvbVJhbmRvbShuTmVpZ2hib3JzLCBkYXRhLCBxdWVyeVBvaW50cywgcmVzdWx0cywgcmFuZG9tKTtcbiAgaWYgKGZvcmVzdCkge1xuICAgIGZvciAobGV0IHRyZWUgb2YgZm9yZXN0KSB7XG4gICAgICBpbml0RnJvbVRyZWUodHJlZSwgZGF0YSwgcXVlcnlQb2ludHMsIHJlc3VsdHMsIHJhbmRvbSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuIl19","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","/* eslint-disable max-len */\nimport { TSNE } from '@keckelt/tsne';\nimport { Vector, } from '@datagrok-libraries/utils/src/type-declarations';\nimport { transposeMatrix, assert, } from '@datagrok-libraries/utils/src/vector-operations';\nimport { SPEBase, PSPEBase, OriginalSPE } from './spe';\nimport { Measure, AvailableMetrics, isBitArrayMetric } from './typed-metrics/typed-metrics';\nimport BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport { UMAP } from './umap';\nimport { DistanceMatrix, DistanceMatrixService, distanceMatrixProxy, dmLinearIndex } from './distance-matrix';\nimport { SparseMatrixService } from './distance-matrix/sparse-matrix-service';\nimport { getKnnGraph } from './umap/knnGraph';\nexport var DimReductionMethods;\n(function (DimReductionMethods) {\n DimReductionMethods[\"UMAP\"] = \"UMAP\";\n DimReductionMethods[\"T_SNE\"] = \"t-SNE\";\n})(DimReductionMethods || (DimReductionMethods = {}));\n/** Umap uses precalculated distance matrix to save time. though for too much data, memory becomes constraint.\n * if we have 100 000 rows, distance matrix will take ~10gb of memory and probably overflow.\n */\nexport const MAX_DISTANCE_MATRIX_ROWS = 20000;\nexport class UMAPOptions {\n constructor() {\n this.learningRate = { uiName: 'Learinig rate', value: 1, tooltip: 'The initial learning rate for the embedding optimization' };\n this.nComponents = { uiName: 'Components', value: 2, tooltip: 'The number of components (dimensions) to project the data to' };\n this.nEpochs = { uiName: 'Epochs', value: 0, tooltip: 'The number of epochs to optimize embeddings via SGD. Computed automatically if set to 0' };\n this.nNeighbors = { uiName: 'Neighbors', value: 15, tooltip: 'The number of nearest neighbors to construct the fuzzy manifold' };\n this.spread = { uiName: 'Spread', value: 1, tooltip: 'The effective scale of embedded points, used with min distance to control the clumped/dispersed nature of the embedding' };\n this.minDist = { uiName: 'Min distance', value: 0.1, tooltip: 'The effective minimum distance between embedded points, used with spread to control the clumped/dispersed nature of the embedding' };\n }\n ;\n}\nexport class TSNEOptions {\n constructor() {\n this.epsilon = { uiName: 'Epsilon', value: 10, tooltip: 'Epsilon is learning rate' };\n this.perplexity = { uiName: 'Perplexity', value: 30, tooltip: 'Roughly how many neighbors each point influences' };\n this.dim = { uiName: 'Dimensionality', value: 2, tooltip: 'Dimensionality of the embedding' };\n }\n ;\n}\n/** Abstract dimensionality reducer */\nclass Reducer {\n constructor(options) {\n this.data = options.data;\n }\n}\n/** t-SNE dimensionality reduction. */\nclass TSNEReducer extends Reducer {\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 this.reducer = new TSNE(options);\n this.iterations = options?.iterations ?? 100;\n this.distanceFname = options.distanceFname;\n this.distanceFn = options.distanceFn;\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(parallelDistanceWorkers) {\n const distance = parallelDistanceWorkers ? await (async () => {\n const matrixService = new DistanceMatrixService(true, false);\n try {\n const dist = await matrixService.calc(this.data, this.distanceFname);\n matrixService.terminate();\n return dist;\n }\n catch (e) {\n matrixService.terminate();\n throw e;\n }\n })() :\n (() => { const ret = DistanceMatrix.calc(this.data, (a, b) => this.distanceFn(a, b)); ret.normalize(); return ret.data; })();\n const matrixProxy = distanceMatrixProxy(distance, this.data.length);\n this.reducer.initDataDist(matrixProxy);\n for (let i = 0; i < this.iterations; ++i)\n this.reducer.step(); // every time you call this, solution gets better\n return { distance: distance, embedding: this.reducer.getSolution() };\n }\n}\n/**\n * Implements UMAP dimensionality reduction.\n *\n * @class UMAPReducer\n * @extends {Reducer}\n */\nclass UMAPReducer extends Reducer {\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 super(options);\n assert('distanceFname' in options);\n assert('distanceFn' in options);\n this.distanceFnArgs = options?.distanceFnArgs;\n this.distanceFn = options.distanceFn;\n this.usingSparseMatrix = !!options.usingSparseMatrix || !!options.sparseMatrix;\n this.sparseMatrixThreshold = options.sparseMatrixThreshold ?? 0.8;\n this.transferedSparseMatrix = options.sparseMatrix;\n this.progressFunc = options.progressFunc;\n this.distanceFname = options.distanceFname;\n this.dmIndexFunc = dmLinearIndex(this.data.length);\n //Umap uses vector indexing, so we need to create an array of vectors as indeces.\n this.vectors = new Array(this.data.length).fill(0).map((_, i) => i);\n this.usingDistanceMatrix = !((!options.preCalculateDistanceMatrix && this.data.length > MAX_DISTANCE_MATRIX_ROWS)\n || this.usingSparseMatrix);\n if (this.usingDistanceMatrix)\n options.distanceFn = this._encodedDistanceMatrix.bind(this);\n else if (this.usingSparseMatrix)\n options.distanceFn = this._encodedSparseMatrix.bind(this);\n else\n options.distanceFn = this._encodedDistance.bind(this);\n if (this.data.length < 15)\n options.nNeighbors = this.data.length - 1;\n this.reducer = new UMAP(options);\n // this.reducer.distanceFn = this._encodedDistance.bind(this);\n }\n /**\n * Custom distance wrapper to have numeric inputs instead of string ones.\n *\n * @protected\n * @param {number[]} a The first item.\n * @param {number[]} b The first item.\n * @return {number} Distance metric.\n * @memberof UMAPReducer\n */\n _encodedDistanceMatrix(a, b) {\n if (a === b)\n return 0;\n if (a > b)\n return this.distanceMatrix[this.dmIndexFunc(b, a)];\n return this.distanceMatrix[this.dmIndexFunc(a, b)];\n }\n _encodedSparseMatrix(a, b) {\n return this.sparseMatrix.get(a)?.get(b) ?? this.sparseMatrix.get(b)?.get(a) ?? 1;\n }\n _encodedDistance(a, b) {\n return this.distanceFn(this.data[a], this.data[b]);\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 if (this.usingDistanceMatrix) {\n this.distanceMatrix = parallelDistanceWorkers ? await (async () => {\n const matrixService = new DistanceMatrixService(true, false);\n try {\n const dist = await matrixService.calc(this.data, this.distanceFname, true, this.distanceFnArgs);\n matrixService.terminate();\n return dist;\n }\n catch (e) {\n matrixService.terminate();\n throw e;\n }\n })() :\n (() => {\n const ret = DistanceMatrix.calc(this.data, (a, b) => {\n const d = this.distanceFn(a, b);\n return d;\n });\n return ret.data;\n })();\n }\n else if (this.usingSparseMatrix) {\n console.time('sparse matrix');\n let res = this.transferedSparseMatrix ??\n await new SparseMatrixService().calc(this.data, this.distanceFname, this.sparseMatrixThreshold, this.distanceFnArgs);\n console.timeEnd('sparse matrix');\n const knnRes = getKnnGraph(res.i, res.j, res.distance, this.reducer.neighbors, this.data.length);\n this.reducer.setPrecomputedKNN(knnRes.knnIndexes, knnRes.knnDistances);\n console.time('sparse matrix to map');\n this.sparseMatrix = new Map();\n for (let i = 0; i < res.i.length; ++i) {\n const first = res.i[i];\n const second = res.j[i];\n const distance = res.distance[i];\n if (!this.sparseMatrix.has(first))\n this.sparseMatrix.set(first, new Map());\n this.sparseMatrix.get(first).set(second, distance);\n }\n console.timeEnd('sparse matrix to map');\n res.distance = null;\n res.i = null;\n res.j = null;\n res = null;\n // needed so that garbage collector can free memory from distance matrix\n await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, 500);\n });\n }\n const embedding = await this.reducer.fitAsync(this.vectors, (epoc) => {\n if (this.progressFunc)\n this.progressFunc(epoc, this.reducer.getNEpochs(), this.reducer.getEmbedding());\n });\n function arrayCast2Coordinates(data) {\n return new Array(data.length).fill(0).map((_, i) => (Vector.from(data[i])));\n }\n return { embedding: arrayCast2Coordinates(embedding), ...(this.distanceMatrix ? { distance: this.distanceMatrix } : {}) };\n }\n}\n/**\n * Implements original SPE dimensionality reduction.\n *\n * @class SPEReducer\n * @extends {Reducer}\n */\nclass SPEReducer extends Reducer {\n /**\n * Creates an instance of SPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof SPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new SPEBase(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the original SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\n/**\n * Implements modified SPE dimensionality reduction.\n *\n * @class PSPEReducer\n * @extends {Reducer}\n */\nclass PSPEReducer extends Reducer {\n /**\n * Creates an instance of PSPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof PSPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new PSPEBase(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the modified SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\n/**\n * Implements original SPE dimensionality reduction.\n *\n * @class OriginalSPEReducer\n * @extends {Reducer}\n */\nclass OriginalSPEReducer extends Reducer {\n /**\n * Creates an instance of OriginalSPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof OriginalSPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new OriginalSPE(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the original SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\nconst AvailableReducers = {\n 'UMAP': UMAPReducer,\n 't-SNE': TSNEReducer,\n 'SPE': SPEReducer,\n 'pSPE': PSPEReducer,\n 'OriginalSPE': OriginalSPEReducer,\n};\n/**\n * Unified class implementing different dimensionality reduction methods.\n *\n * @export\n * @class DimensionalityReducer\n */\nexport class DimensionalityReducer {\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, metric, options) {\n const measure = new Measure(metric).getMeasure(options?.distanceFnArgs);\n let specOptions = {};\n if (isBitArrayMetric(metric)) {\n for (let i = 0; i < data.length; ++i)\n data[i] = new BitArray(data[i]._data, data[i]._length);\n }\n if (method == 'UMAP') {\n specOptions = {\n ...{ data: data },\n ...{ distanceFn: measure },\n ...{ distanceFname: metric },\n ...{ nEpochs: options?.cycles },\n ...options,\n };\n }\n else if (method == 't-SNE') {\n specOptions = {\n ...{ data: data },\n ...{ distanceFn: measure },\n ...{ distanceFname: metric },\n ...{ iterations: options?.cycles ?? undefined },\n ...options,\n };\n }\n else if (method == 'SPE') {\n specOptions = { ...{ data: data }, ...{ distance: measure }, distanceFunctionName: metric, ...options };\n }\n else {\n specOptions = { ...{ data: data }, ...{ distance: measure }, distanceFunctionName: metric, ...options };\n }\n this.reducer = new AvailableReducers[method](specOptions);\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, parallelDistanceWorkers) {\n if (this.reducer === undefined)\n throw new Error('Reducer was not defined.');\n let { embedding, distance } = await this.reducer.transform(parallelDistanceWorkers);\n if (transpose)\n embedding = transposeMatrix(embedding);\n return { distance: distance, embedding: 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlLWRpbWVuc2lvbmFsaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVkdWNlLWRpbWVuc2lvbmFsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRCQUE0QjtBQUM1QixPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ25DLE9BQU8sRUFHTCxNQUFNLEdBR1AsTUFBTSxpREFBaUQsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsZUFBZSxFQUNmLE1BQU0sR0FDUCxNQUFNLGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBQyxNQUFNLE9BQU8sQ0FBQztBQUNyRCxPQUFPLEVBQUMsT0FBTyxFQUFnQixnQkFBZ0IsRUFDN0MsZ0JBQWdCLEVBQXFCLE1BQU0sK0JBQStCLENBQUM7QUFDN0UsT0FBTyxRQUFRLE1BQU0seUNBQXlDLENBQUM7QUFDL0QsT0FBTyxFQUFpQixJQUFJLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFDNUMsT0FBTyxFQUFDLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUM1RyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSx5Q0FBeUMsQ0FBQztBQUM1RSxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFjNUMsTUFBTSxDQUFOLElBQVksbUJBR1g7QUFIRCxXQUFZLG1CQUFtQjtJQUM3QixvQ0FBYSxDQUFBO0lBQ2Isc0NBQWUsQ0FBQTtBQUNqQixDQUFDLEVBSFcsbUJBQW1CLEtBQW5CLG1CQUFtQixRQUc5QjtBQTZCRDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFHLEtBQUssQ0FBQztBQUU5QyxNQUFNLE9BQU8sV0FBVztJQVF0QjtRQVBBLGlCQUFZLEdBQXVCLEVBQUMsTUFBTSxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsQ0FB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ICovXG5pbXBvcnQge1RTTkV9IGZyb20gJ0BrZWNrZWx0L3RzbmUnO1xuaW1wb3J0IHtcbiAgT3B0aW9ucyxcbiAgQ29vcmRpbmF0ZXMsXG4gIFZlY3RvcixcbiAgVmVjdG9ycyxcbiAgTWF0cml4LFxufSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge1xuICB0cmFuc3Bvc2VNYXRyaXgsXG4gIGFzc2VydCxcbn0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdmVjdG9yLW9wZXJhdGlvbnMnO1xuaW1wb3J0IHtTUEVCYXNlLCBQU1BFQmFzZSwgT3JpZ2luYWxTUEV9IGZyb20gJy4vc3BlJztcbmltcG9ydCB7TWVhc3VyZSwgS25vd25NZXRyaWNzLCBBdmFpbGFibGVNZXRyaWNzLFxuICBpc0JpdEFycmF5TWV0cmljLCBBdmFpbGFibGVEYXRhVHlwZXN9IGZyb20gJy4vdHlwZWQtbWV0cmljcy90eXBlZC1tZXRyaWNzJztcbmltcG9ydCBCaXRBcnJheSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy9iaXQtYXJyYXknO1xuaW1wb3J0IHtVTUFQUGFyYW1ldGVycywgVU1BUH0gZnJvbSAnLi91bWFwJztcbmltcG9ydCB7RGlzdGFuY2VNYXRyaXgsIERpc3RhbmNlTWF0cml4U2VydmljZSwgZGlzdGFuY2VNYXRyaXhQcm94eSwgZG1MaW5lYXJJbmRleH0gZnJvbSAnLi9kaXN0YW5jZS1tYXRyaXgnO1xuaW1wb3J0IHtTcGFyc2VNYXRyaXhTZXJ2aWNlfSBmcm9tICcuL2Rpc3RhbmNlLW1hdHJpeC9zcGFyc2UtbWF0cml4LXNlcnZpY2UnO1xuaW1wb3J0IHtnZXRLbm5HcmFwaH0gZnJvbSAnLi91bWFwL2tubkdyYXBoJztcblxuZXhwb3J0IHR5cGUgU3BhcnNlTWF0cml4VHJhbnNmZXJUeXBlID0ge1xuICBpOiBJbnQzMkFycmF5LFxuICBqOiBJbnQzMkFycmF5LFxuICBkaXN0YW5jZTogRmxvYXQzMkFycmF5LFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdCB7XG4gIGRpc3RhbmNlPzogRmxvYXQzMkFycmF5O1xuICBzcGFyc2VNYXRyaXg/OiBNYXA8bnVtYmVyLCBNYXA8bnVtYmVyLCBudW1iZXI+PjtcbiAgZW1iZWRkaW5nOiBNYXRyaXg7XG59XG5cbmV4cG9ydCBlbnVtIERpbVJlZHVjdGlvbk1ldGhvZHN7XG4gIFVNQVAgPSAnVU1BUCcsXG4gIFRfU05FID0gJ3QtU05FJ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElVTUFQT3B0aW9ucyB7XG4gIGxlYXJuaW5nUmF0ZT86IG51bWJlcjtcbiAgbkNvbXBvbmVudHM/OiBudW1iZXI7XG4gIG5FcG9jaHM/OiBudW1iZXI7XG4gIG5OZWlnaGJvcnM/OiBudW1iZXI7XG4gIHNwcmVhZD86IG51bWJlcjtcbiAgbWluRGlzdD86IG51bWJlcjtcbiAgc3BhcnNlTWF0cml4VGhyZXNob2xkPzogbnVtYmVyO1xuICBwcmVDYWxjdWxhdGVEaXN0YW5jZU1hdHJpeD86IGJvb2xlYW47XG4gIHVzaW5nU3BhcnNlTWF0cml4PzogYm9vbGVhbjtcbiAgc3BhcnNlTWF0cml4PzogU3BhcnNlTWF0cml4VHJhbnNmZXJUeXBlO1xuICBwcm9ncmVzc0Z1bmM/OiAoZXBvYzogbnVtYmVyLCBlcG9jaHNMZW5ndGg6IG51bWJlciwgZW1iZWRkaW5nczogbnVtYmVyW11bXSkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVFNORU9wdGlvbnMge1xuICBlcHNpbG9uPzogbnVtYmVyO1xuICBwZXJwbGV4aXR5PzogbnVtYmVyO1xuICBkaW0/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSURpbVJlZHVjdGlvblBhcmFtIHtcbiAgdWlOYW1lOiBzdHJpbmc7XG4gIHZhbHVlOiBudW1iZXIgfCBudWxsO1xuICB0b29sdGlwOiBzdHJpbmc7XG4gIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xufVxuXG4vKiogVW1hcCB1c2VzIHByZWNhbGN1bGF0ZWQgZGlzdGFuY2UgbWF0cml4IHRvIHNhdmUgdGltZS4gdGhvdWdoIGZvciB0b28gbXVjaCBkYXRhLCBtZW1vcnkgYmVjb21lcyBjb25zdHJhaW50LlxuICogaWYgd2UgaGF2ZSAxMDAgMDAwIHJvd3MsIGRpc3RhbmNlIG1hdHJpeCB3aWxsIHRha2UgfjEwZ2Igb2YgbWVtb3J5IGFuZCBwcm9iYWJseSBvdmVyZmxvdy5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9ESVNUQU5DRV9NQVRSSVhfUk9XUyA9IDIwMDAwO1xuXG5leHBvcnQgY2xhc3MgVU1BUE9wdGlvbnMge1xuICBsZWFybmluZ1JhdGU6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdMZWFyaW5pZyByYXRlJywgdmFsdWU6IDEsIHRvb2x0aXA6ICdUaGUgaW5pdGlhbCBsZWFybmluZyByYXRlIGZvciB0aGUgZW1iZWRkaW5nIG9wdGltaXphdGlvbid9O1xuICBuQ29tcG9uZW50czogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ0NvbXBvbmVudHMnLCB2YWx1ZTogMiwgdG9vbHRpcDogJ1RoZSBudW1iZXIgb2YgY29tcG9uZW50cyAoZGltZW5zaW9ucykgdG8gcHJvamVjdCB0aGUgZGF0YSB0byd9O1xuICBuRXBvY2hzOiBJRGltUmVkdWN0aW9uUGFyYW0gPSB7dWlOYW1lOiAnRXBvY2hzJywgdmFsdWU6IDAsIHRvb2x0aXA6ICdUaGUgbnVtYmVyIG9mIGVwb2NocyB0byBvcHRpbWl6ZSBlbWJlZGRpbmdzIHZpYSBTR0QuIENvbXB1dGVkIGF1dG9tYXRpY2FsbHkgaWYgc2V0IHRvIDAnfTtcbiAgbk5laWdoYm9yczogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ05laWdoYm9ycycsIHZhbHVlOiAxNSwgdG9vbHRpcDogJ1RoZSBudW1iZXIgb2YgbmVhcmVzdCBuZWlnaGJvcnMgdG8gY29uc3RydWN0IHRoZSBmdXp6eSBtYW5pZm9sZCd9O1xuICBzcHJlYWQ6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdTcHJlYWQnLCB2YWx1ZTogMSwgdG9vbHRpcDogJ1RoZSBlZmZlY3RpdmUgc2NhbGUgb2YgZW1iZWRkZWQgcG9pbnRzLCB1c2VkIHdpdGggbWluIGRpc3RhbmNlIHRvIGNvbnRyb2wgdGhlIGNsdW1wZWQvZGlzcGVyc2VkIG5hdHVyZSBvZiB0aGUgZW1iZWRkaW5nJ307XG4gIG1pbkRpc3Q6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdNaW4gZGlzdGFuY2UnLCB2YWx1ZTogMC4xLCB0b29sdGlwOiAnVGhlIGVmZmVjdGl2ZSBtaW5pbXVtIGRpc3RhbmNlIGJldHdlZW4gZW1iZWRkZWQgcG9pbnRzLCB1c2VkIHdpdGggc3ByZWFkIHRvIGNvbnRyb2wgdGhlIGNsdW1wZWQvZGlzcGVyc2VkIG5hdHVyZSBvZiB0aGUgZW1iZWRkaW5nJ307XG5cbiAgY29uc3RydWN0b3IoKSB7fTtcbn1cblxuZXhwb3J0IGNsYXNzIFRTTkVPcHRpb25zIHtcbiAgZXBzaWxvbjogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ0Vwc2lsb24nLCB2YWx1ZTogMTAsIHRvb2x0aXA6ICdFcHNpbG9uIGlzIGxlYXJuaW5nIHJhdGUnfTtcbiAgcGVycGxleGl0eTogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ1BlcnBsZXhpdHknLCB2YWx1ZTogMzAsIHRvb2x0aXA6ICdSb3VnaGx5IGhvdyBtYW55IG5laWdoYm9ycyBlYWNoIHBvaW50IGluZmx1ZW5jZXMnfTtcbiAgZGltOiBJRGltUmVkdWN0aW9uUGFyYW0gPSB7dWlOYW1lOiAnRGltZW5zaW9uYWxpdHknLCB2YWx1ZTogMiwgdG9vbHRpcDogJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBlbWJlZGRpbmcnfTtcblxuICBjb25zdHJ1Y3RvcigpIHt9O1xufVxuXG4vKiogQWJzdHJhY3QgZGltZW5zaW9uYWxpdHkgcmVkdWNlciAqL1xuYWJzdHJhY3QgY2xhc3MgUmVkdWNlciB7XG4gIHByb3RlY3RlZCBkYXRhOiBWZWN0b3JzO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICB0aGlzLmRhdGEgPSBvcHRpb25zLmRhdGE7XG4gIH1cblxuICAvKiogRW1iZWRzIHRoZSBkYXRhIGdpdmVuIGludG8gdGhlIHR3by1kaW1lbnNpb25hbCBzcGFjZS5cbiAgICogQHJldHVybiB7YW55fSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBvZiB0aGlzIGVtYmVkZGluZyBhbmQgZGlzdGFuY2UgbWF0cml4IHdoZXJlIGFwcGxpY2FibGUuICovXG4gIGFic3RyYWN0IHRyYW5zZm9ybShwYXJhbGxlbERpc3RhbmNlV29ya2Vycz86IGJvb2xlYW4pOiBQcm9taXNlPElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdD47XG59XG5cbi8qKiB0LVNORSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24uICovXG5jbGFzcyBUU05FUmVkdWNlciBleHRlbmRzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgcmVkdWNlcjogVFNORTtcbiAgcHJvdGVjdGVkIGl0ZXJhdGlvbnM6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGRpc3RhbmNlRm5hbWU6IEtub3duTWV0cmljcztcbiAgcHJvdGVjdGVkIGRpc3RhbmNlRm46IChhOiBhbnksIGI6IGFueSkgPT4gbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFRTTkVSZWR1Y2VyLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQG1lbWJlcm9mIFRTTkVSZWR1Y2VyXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zKSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gICAgdGhpcy5yZWR1Y2VyID0gbmV3IFRTTkUob3B0aW9ucyk7XG4gICAgdGhpcy5pdGVyYXRpb25zID0gb3B0aW9ucz8uaXRlcmF0aW9ucyA/PyAxMDA7XG4gICAgdGhpcy5kaXN0YW5jZUZuYW1lID0gb3B0aW9ucy5kaXN0YW5jZUZuYW1lO1xuICAgIHRoaXMuZGlzdGFuY2VGbiA9IG9wdGlvbnMuZGlzdGFuY2VGbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIHQtU05FIG1ldGhvZC5cXFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtwYXJhbGxlbERpc3RhbmNlV29ya2Vyc10gV2hldGhlciB0byB1c2UgcGFyYWxsZWwgZGlzdGFuY2Ugd29ya2Vycy5cbiAgICogQHJldHVybiB7YW55fSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBvZiB0aGlzIGVtYmVkZGluZyBhbmQgZGlzdGFuY2UgbWF0cml4IHdoZXJlIGFwcGxpY2FibGUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzPzogYm9vbGVhbik6IFByb21pc2U8SVJlZHVjZURpbWVuc2lvbmFsaXR5UmVzdWx0PiB7XG4gICAgY29uc3QgZGlzdGFuY2UgPSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyA/IGF3YWl0IChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtYXRyaXhTZXJ2aWNlID0gbmV3IERpc3RhbmNlTWF0cml4U2VydmljZSh0cnVlLCBmYWxzZSk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkaXN0ID0gYXdhaXQgbWF0cml4U2VydmljZS5jYWxjKHRoaXMuZGF0YSwgdGhpcy5kaXN0YW5jZUZuYW1lKTtcbiAgICAgICAgbWF0cml4U2VydmljZS50ZXJtaW5hdGUoKTtcbiAgICAgICAgcmV0dXJuIGRpc3Q7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIG1hdHJpeFNlcnZpY2UudGVybWluYXRlKCk7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfSkoKSA6XG4gICAgICAoKCkgPT4geyBjb25zdCByZXQgPSBEaXN0YW5jZU1hdHJpeC5jYWxjKHRoaXMuZGF0YSwgKGEsIGIpID0+IHRoaXMuZGlzdGFuY2VGbihhLCBiKSk7IHJldC5ub3JtYWxpemUoKTsgcmV0dXJuIHJldC5kYXRhOyB9KSgpO1xuXG4gICAgY29uc3QgbWF0cml4UHJveHkgPSBkaXN0YW5jZU1hdHJpeFByb3h5KGRpc3RhbmNlLCB0aGlzLmRhdGEubGVuZ3RoKTtcbiAgICB0aGlzLnJlZHVjZXIuaW5pdERhdGFEaXN0KG1hdHJpeFByb3h5KTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5pdGVyYXRpb25zOyArK2kpXG4gICAgICB0aGlzLnJlZHVjZXIuc3RlcCgpOyAvLyBldmVyeSB0aW1lIHlvdSBjYWxsIHRoaXMsIHNvbHV0aW9uIGdldHMgYmV0dGVyXG5cbiAgICByZXR1cm4ge2Rpc3RhbmNlOiBkaXN0YW5jZSwgZW1iZWRkaW5nOiB0aGlzLnJlZHVjZXIuZ2V0U29sdXRpb24oKX07XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgVW1hcE9wdGlvbnMgPSBPcHRpb25zICYgVU1BUFBhcmFtZXRlcnMgJiB7XG4gIHByZUNhbGN1bGF0ZURpc3RhbmNlTWF0cml4PzogYm9vbGVhbixcbiAgdXNpbmdTcGFyc2VNYXRyaXg/OiBib29sZWFuLFxuICBzcGFyc2VNYXRyaXhUaHJlc2hvbGQ/OiBudW1iZXIsXG4gIHNwYXJzZU1hdHJpeD86IFNwYXJzZU1hdHJpeFRyYW5zZmVyVHlwZSxcbiAgcHJvZ3Jlc3NGdW5jPzogKGVwb2M6IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZ3M6IG51bWJlcltdW10pID0+IHZvaWQsXG59O1xuXG4vKipcbiAqIEltcGxlbWVudHMgVU1BUCBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24uXG4gKlxuICogQGNsYXNzIFVNQVBSZWR1Y2VyXG4gKiBAZXh0ZW5kcyB7UmVkdWNlcn1cbiAqL1xuY2xhc3MgVU1BUFJlZHVjZXIgZXh0ZW5kcyBSZWR1Y2VyIHtcbiAgcHJvdGVjdGVkIHJlZHVjZXI6IFVNQVA7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZuYW1lOiBLbm93bk1ldHJpY3M7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZuOiBGdW5jdGlvbjtcbiAgcHJvdGVjdGVkIHZlY3RvcnM6IG51bWJlcltdO1xuICBwcm90ZWN0ZWQgZGlzdGFuY2VNYXRyaXg/OiBGbG9hdDMyQXJyYXk7XG4gIHByb3RlY3RlZCB1c2luZ0Rpc3RhbmNlTWF0cml4OiBib29sZWFuO1xuICBwcm90ZWN0ZWQgc3BhcnNlTWF0cml4PzogTWFwPG51bWJlciwgTWFwPG51bWJlciwgbnVtYmVyPj47XG4gIHByb3RlY3RlZCBkbUluZGV4RnVuYzogKGk6IG51bWJlciwgajogbnVtYmVyKSA9PiBudW1iZXI7XG4gIHByb3RlY3RlZCB1c2luZ1NwYXJzZU1hdHJpeDogYm9vbGVhbjtcbiAgcHJvdGVjdGVkIHNwYXJzZU1hdHJpeFRocmVzaG9sZDogbnVtYmVyO1xuICBwcm90ZWN0ZWQgdHJhbnNmZXJlZFNwYXJzZU1hdHJpeD86IFNwYXJzZU1hdHJpeFRyYW5zZmVyVHlwZTtcbiAgcHJvdGVjdGVkIHByb2dyZXNzRnVuYz86IChlcG9jOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmdzOiBudW1iZXJbXVtdKSA9PiB2b2lkO1xuICBwcm90ZWN0ZWQgZGlzdGFuY2VGbkFyZ3M/OiB7W186IHN0cmluZ106IGFueX07XG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFVNQVBSZWR1Y2VyLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQG1lbWJlcm9mIFVNQVBSZWR1Y2VyXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBVbWFwT3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIGFzc2VydCgnZGlzdGFuY2VGbmFtZScgaW4gb3B0aW9ucyk7XG4gICAgYXNzZXJ0KCdkaXN0YW5jZUZuJyBpbiBvcHRpb25zKTtcbiAgICB0aGlzLmRpc3RhbmNlRm5BcmdzID0gb3B0aW9ucz8uZGlzdGFuY2VGbkFyZ3M7XG4gICAgdGhpcy5kaXN0YW5jZUZuID0gb3B0aW9ucy5kaXN0YW5jZUZuITtcbiAgICB0aGlzLnVzaW5nU3BhcnNlTWF0cml4ID0gISFvcHRpb25zLnVzaW5nU3BhcnNlTWF0cml4IHx8ICEhb3B0aW9ucy5zcGFyc2VNYXRyaXg7XG4gICAgdGhpcy5zcGFyc2VNYXRyaXhUaHJlc2hvbGQgPSBvcHRpb25zLnNwYXJzZU1hdHJpeFRocmVzaG9sZCA/PyAwLjg7XG4gICAgdGhpcy50cmFuc2ZlcmVkU3BhcnNlTWF0cml4ID0gb3B0aW9ucy5zcGFyc2VNYXRyaXg7XG4gICAgdGhpcy5wcm9ncmVzc0Z1bmMgPSBvcHRpb25zLnByb2dyZXNzRnVuYztcblxuICAgIHRoaXMuZGlzdGFuY2VGbmFtZSA9IG9wdGlvbnMuZGlzdGFuY2VGbmFtZSE7XG4gICAgdGhpcy5kbUluZGV4RnVuYyA9IGRtTGluZWFySW5kZXgodGhpcy5kYXRhLmxlbmd0aCk7XG4gICAgLy9VbWFwIHVzZXMgdmVjdG9yIGluZGV4aW5nLCBzbyB3ZSBuZWVkIHRvIGNyZWF0ZSBhbiBhcnJheSBvZiB2ZWN0b3JzIGFzIGluZGVjZXMuXG4gICAgdGhpcy52ZWN0b3JzID0gbmV3IEFycmF5KHRoaXMuZGF0YS5sZW5ndGgpLmZpbGwoMCkubWFwKChfLCBpKSA9PiBpKTtcbiAgICB0aGlzLnVzaW5nRGlzdGFuY2VNYXRyaXggPSAhKCghb3B0aW9ucy5wcmVDYWxjdWxhdGVEaXN0YW5jZU1hdHJpeCAmJiB0aGlzLmRhdGEubGVuZ3RoID4gTUFYX0RJU1RBTkNFX01BVFJJWF9ST1dTKVxuICAgICAgfHwgdGhpcy51c2luZ1NwYXJzZU1hdHJpeCk7XG4gICAgaWYgKHRoaXMudXNpbmdEaXN0YW5jZU1hdHJpeClcbiAgICAgIG9wdGlvbnMuZGlzdGFuY2VGbiA9IHRoaXMuX2VuY29kZWREaXN0YW5jZU1hdHJpeC5iaW5kKHRoaXMpO1xuICAgIGVsc2UgaWYgKHRoaXMudXNpbmdTcGFyc2VNYXRyaXgpXG4gICAgICBvcHRpb25zLmRpc3RhbmNlRm4gPSB0aGlzLl9lbmNvZGVkU3BhcnNlTWF0cml4LmJpbmQodGhpcyk7XG4gICAgZWxzZVxuICAgICAgb3B0aW9ucy5kaXN0YW5jZUZuID0gdGhpcy5fZW5jb2RlZERpc3RhbmNlLmJpbmQodGhpcyk7XG5cbiAgICBpZiAodGhpcy5kYXRhLmxlbmd0aCA8IDE1KVxuICAgICAgb3B0aW9ucy5uTmVpZ2hib3JzID0gdGhpcy5kYXRhLmxlbmd0aCAtIDE7XG4gICAgdGhpcy5yZWR1Y2VyID0gbmV3IFVNQVAob3B0aW9ucyk7XG4gICAgLy8gdGhpcy5yZWR1Y2VyLmRpc3RhbmNlRm4gPSB0aGlzLl9lbmNvZGVkRGlzdGFuY2UuYmluZCh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDdXN0b20gZGlzdGFuY2Ugd3JhcHBlciB0byBoYXZlIG51bWVyaWMgaW5wdXRzIGluc3RlYWQgb2Ygc3RyaW5nIG9uZXMuXG4gICAqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHBhcmFtIHtudW1iZXJbXX0gYSBUaGUgZmlyc3QgaXRlbS5cbiAgICogQHBhcmFtIHtudW1iZXJbXX0gYiBUaGUgZmlyc3QgaXRlbS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBtZXRyaWMuXG4gICAqIEBtZW1iZXJvZiBVTUFQUmVkdWNlclxuICAgKi9cbiAgcHJvdGVjdGVkIF9lbmNvZGVkRGlzdGFuY2VNYXRyaXgoYTogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChhID09PSBiKVxuICAgICAgcmV0dXJuIDA7XG4gICAgaWYgKGEgPiBiKVxuICAgICAgcmV0dXJuIHRoaXMuZGlzdGFuY2VNYXRyaXghW3RoaXMuZG1JbmRleEZ1bmMoYiwgYSldO1xuICAgIHJldHVybiB0aGlzLmRpc3RhbmNlTWF0cml4IVt0aGlzLmRtSW5kZXhGdW5jKGEsIGIpXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZW5jb2RlZFNwYXJzZU1hdHJpeChhOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc3BhcnNlTWF0cml4IS5nZXQoYSk/LmdldChiKSA/PyB0aGlzLnNwYXJzZU1hdHJpeCEuZ2V0KGIpPy5nZXQoYSkgPz8gMTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZW5jb2RlZERpc3RhbmNlKGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5kaXN0YW5jZUZuKHRoaXMuZGF0YVthXSwgdGhpcy5kYXRhW2JdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIFVNQVAgbWV0aG9kLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtwYXJhbGxlbERpc3RhbmNlV29ya2Vyc10gV2hldGhlciB0byB1c2UgcGFyYWxsZWwgZGlzdGFuY2UgbWF0cml4IHdvcmtlcnMuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzPzogYm9vbGVhbik6IFByb21pc2U8SVJlZHVjZURpbWVuc2lvbmFsaXR5UmVzdWx0PiB7XG4gICAgaWYgKHRoaXMudXNpbmdEaXN0YW5jZU1hdHJpeCkge1xuICAgICAgdGhpcy5kaXN0YW5jZU1hdHJpeCA9IHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzID8gYXdhaXQgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgbWF0cml4U2VydmljZSA9IG5ldyBEaXN0YW5jZU1hdHJpeFNlcnZpY2UodHJ1ZSwgZmFsc2UpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGRpc3QgPSBhd2FpdCBtYXRyaXhTZXJ2aWNlLmNhbGModGhpcy5kYXRhLCB0aGlzLmRpc3RhbmNlRm5hbWUsIHRydWUsIHRoaXMuZGlzdGFuY2VGbkFyZ3MpO1xuICAgICAgICAgIG1hdHJpeFNlcnZpY2UudGVybWluYXRlKCk7XG4gICAgICAgICAgcmV0dXJuIGRpc3Q7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBtYXRyaXhTZXJ2aWNlLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH0pKCkgOlxuICAgICAgICAoKCkgPT4geyBcbiAgICAgICAgICBjb25zdCByZXQgPSBEaXN0YW5jZU1hdHJpeC5jYWxjKHRoaXMuZGF0YSwgKGEsIGIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGQgPSB0aGlzLmRpc3RhbmNlRm4oYSwgYik7XG4gICAgICAgICAgICByZXR1cm4gZDt9KTsgXG4gICAgICAgICAgcmV0dXJuIHJldC5kYXRhOyBcbiAgICAgICAgfSkoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudXNpbmdTcGFyc2VNYXRyaXgpIHtcbiAgICAgICAgICBjb25zb2xlLnRpbWUoJ3NwYXJzZSBtYXRyaXgnKTtcbiAgICAgICAgICBsZXQgcmVzOiB7W0sgaW4ga2V5b2YgU3BhcnNlTWF0cml4VHJhbnNmZXJUeXBlXTogU3BhcnNlTWF0cml4VHJhbnNmZXJUeXBlW0tdIHwgbnVsbH0gfCBudWxsXG4gICAgICAgICAgICA9IHRoaXMudHJhbnNmZXJlZFNwYXJzZU1hdHJpeCA/P1xuICAgICAgICAgICAgICBhd2FpdCBuZXcgU3BhcnNlTWF0cml4U2VydmljZSgpLmNhbGModGhpcy5kYXRhLCB0aGlzLmRpc3RhbmNlRm5hbWUsIHRoaXMuc3BhcnNlTWF0cml4VGhyZXNob2xkLCB0aGlzLmRpc3RhbmNlRm5BcmdzKTtcbiAgICAgICAgICBjb25zb2xlLnRpbWVFbmQoJ3NwYXJzZSBtYXRyaXgnKTtcblxuICAgICAgICAgIGNvbnN0IGtublJlcyA9IGdldEtubkdyYXBoKHJlcy5pISwgcmVzLmohLCByZXMuZGlzdGFuY2UhLCB0aGlzLnJlZHVjZXIubmVpZ2hib3JzLCB0aGlzLmRhdGEubGVuZ3RoKTtcblxuICAgICAgICAgIHRoaXMucmVkdWNlci5zZXRQcmVjb21wdXRlZEtOTihrbm5SZXMua25uSW5kZXhlcywga25uUmVzLmtubkRpc3RhbmNlcyk7XG5cbiAgICAgICAgICBjb25zb2xlLnRpbWUoJ3NwYXJzZSBtYXRyaXggdG8gbWFwJylcbiAgICAgICAgICB0aGlzLnNwYXJzZU1hdHJpeCA9IG5ldyBNYXA8bnVtYmVyLCBNYXA8bnVtYmVyLCBudW1iZXI+PigpO1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVzLmkhLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBjb25zdCBmaXJzdCA9IHJlcy5pIVtpXTtcbiAgICAgICAgICAgIGNvbnN0IHNlY29uZCA9IHJlcy5qIVtpXTtcbiAgICAgICAgICAgIGNvbnN0IGRpc3RhbmNlID0gcmVzLmRpc3RhbmNlIVtpXTtcbiAgICAgICAgICAgIGlmICghdGhpcy5zcGFyc2VNYXRyaXguaGFzKGZpcnN0KSlcbiAgICAgICAgICAgICAgdGhpcy5zcGFyc2VNYXRyaXguc2V0KGZpcnN0LCBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpKTtcbiAgICAgICAgICAgIHRoaXMuc3BhcnNlTWF0cml4LmdldChmaXJzdCkhLnNldChzZWNvbmQsIGRpc3RhbmNlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc29sZS50aW1lRW5kKCdzcGFyc2UgbWF0cml4IHRvIG1hcCcpO1xuICAgICAgICAgIHJlcy5kaXN0YW5jZSA9IG51bGw7XG4gICAgICAgICAgcmVzLmkgPSBudWxsO1xuICAgICAgICAgIHJlcy5qID0gbnVsbDtcbiAgICAgICAgICByZXMgPSBudWxsO1xuICAgICAgICAgIC8vIG5lZWRlZCBzbyB0aGF0IGdhcmJhZ2UgY29sbGVjdG9yIGNhbiBmcmVlIG1lbW9yeSBmcm9tIGRpc3RhbmNlIG1hdHJpeFxuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICBcbiAgICBjb25zdCBlbWJlZGRpbmcgPSBhd2FpdCB0aGlzLnJlZHVjZXIuZml0QXN5bmModGhpcy52ZWN0b3JzLCAoZXBvYykgPT4ge1xuICAgICAgaWYgKHRoaXMucHJvZ3Jlc3NGdW5jKVxuICAgICAgICB0aGlzLnByb2dyZXNzRnVuYyhlcG9jLCB0aGlzLnJlZHVjZXIuZ2V0TkVwb2NocygpLCB0aGlzLnJlZHVjZXIuZ2V0RW1iZWRkaW5nKCkpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYXJyYXlDYXN0MkNvb3JkaW5hdGVzKGRhdGE6IG51bWJlcltdW10pOiBDb29yZGluYXRlcyB7XG4gICAgICByZXR1cm4gbmV3IEFycmF5KGRhdGEubGVuZ3RoKS5maWxsKDApLm1hcCgoXywgaSkgPT4gKFZlY3Rvci5mcm9tKGRhdGFbaV0pKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtlbWJlZGRpbmc6IGFycmF5Q2FzdDJDb29yZGluYXRlcyhlbWJlZGRpbmcpLCAuLi4odGhpcy5kaXN0YW5jZU1hdHJpeCA/IHtkaXN0YW5jZTogdGhpcy5kaXN0YW5jZU1hdHJpeH0gOiB7fSl9O1xuICB9XG59XG5cbi8qKlxuICogSW1wbGVtZW50cyBvcmlnaW5hbCBTUEUgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uLlxuICpcbiAqIEBjbGFzcyBTUEVSZWR1Y2VyXG4gKiBAZXh0ZW5kcyB7UmVkdWNlcn1cbiAqL1xuY2xhc3MgU1BFUmVkdWNlciBleHRlbmRzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgcmVkdWNlcjogU1BFQmFzZTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBTUEVSZWR1Y2VyLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQG1lbWJlcm9mIFNQRVJlZHVjZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgICB0aGlzLnJlZHVjZXIgPSBuZXcgU1BFQmFzZShvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIHRoZSBvcmlnaW5hbCBTUEUgbWV0aG9kLlxuICAgKiBAcmV0dXJuIHthbnl9IENhcnRlc2lhbiBjb29yZGluYXRlIG9mIHRoaXMgZW1iZWRkaW5nIGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0oKTogUHJvbWlzZTxJUmVkdWNlRGltZW5zaW9uYWxpdHlSZXN1bHQ+IHtcbiAgICBjb25zdCBlbWIgPSBhd2FpdCB0aGlzLnJlZHVjZXIuZW1iZWQodGhpcy5kYXRhKTtcbiAgICByZXR1cm4ge2Rpc3RhbmNlOiB0aGlzLnJlZHVjZXIuZGlzdGFuY2UsIGVtYmVkZGluZzogZW1ifTtcbiAgfVxufVxuXG4vKipcbiAqIEltcGxlbWVudHMgbW9kaWZpZWQgU1BFIGRpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbi5cbiAqXG4gKiBAY2xhc3MgUFNQRVJlZHVjZXJcbiAqIEBleHRlbmRzIHtSZWR1Y2VyfVxuICovXG5jbGFzcyBQU1BFUmVkdWNlciBleHRlbmRzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgcmVkdWNlcjogUFNQRUJhc2U7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgUFNQRVJlZHVjZXIuXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgKiBAbWVtYmVyb2YgUFNQRVJlZHVjZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgICB0aGlzLnJlZHVjZXIgPSBuZXcgUFNQRUJhc2Uob3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogRW1iZWRzIHRoZSBkYXRhIGdpdmVuIGludG8gdGhlIHR3by1kaW1lbnNpb25hbCBzcGFjZSB1c2luZyB0aGUgbW9kaWZpZWQgU1BFIG1ldGhvZC5cbiAgICogQHJldHVybiB7YW55fSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBvZiB0aGlzIGVtYmVkZGluZyBhbmQgZGlzdGFuY2UgbWF0cml4IHdoZXJlIGFwcGxpY2FibGUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKCk6IFByb21pc2U8SVJlZHVjZURpbWVuc2lvbmFsaXR5UmVzdWx0PiB7XG4gICAgY29uc3QgZW1iID0gYXdhaXQgdGhpcy5yZWR1Y2VyLmVtYmVkKHRoaXMuZGF0YSk7XG4gICAgcmV0dXJuIHtkaXN0YW5jZTogdGhpcy5yZWR1Y2VyLmRpc3RhbmNlLCBlbWJlZGRpbmc6IGVtYn07XG4gIH1cbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRzIG9yaWdpbmFsIFNQRSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24uXG4gKlxuICogQGNsYXNzIE9yaWdpbmFsU1BFUmVkdWNlclxuICogQGV4dGVuZHMge1JlZHVjZXJ9XG4gKi9cbmNsYXNzIE9yaWdpbmFsU1BFUmVkdWNlciBleHRlbmRzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgcmVkdWNlcjogT3JpZ2luYWxTUEU7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgT3JpZ2luYWxTUEVSZWR1Y2VyLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQG1lbWJlcm9mIE9yaWdpbmFsU1BFUmVkdWNlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMucmVkdWNlciA9IG5ldyBPcmlnaW5hbFNQRShvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIHRoZSBvcmlnaW5hbCBTUEUgbWV0aG9kLlxuICAgKiBAcmV0dXJuIHthbnl9IENhcnRlc2lhbiBjb29yZGluYXRlIG9mIHRoaXMgZW1iZWRkaW5nIGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0oKTogUHJvbWlzZTxJUmVkdWNlRGltZW5zaW9uYWxpdHlSZXN1bHQ+IHtcbiAgICBjb25zdCBlbWIgPSBhd2FpdCB0aGlzLnJlZHVjZXIuZW1iZWQodGhpcy5kYXRhKTtcbiAgICByZXR1cm4ge2Rpc3RhbmNlOiB0aGlzLnJlZHVjZXIuZGlzdGFuY2UsIGVtYmVkZGluZzogZW1ifTtcbiAgfVxufVxuXG5jb25zdCBBdmFpbGFibGVSZWR1Y2VycyA9IHtcbiAgJ1VNQVAnOiBVTUFQUmVkdWNlcixcbiAgJ3QtU05FJzogVFNORVJlZHVjZXIsXG4gICdTUEUnOiBTUEVSZWR1Y2VyLFxuICAncFNQRSc6IFBTUEVSZWR1Y2VyLFxuICAnT3JpZ2luYWxTUEUnOiBPcmlnaW5hbFNQRVJlZHVjZXIsXG59O1xuXG5leHBvcnQgdHlwZSBLbm93bk1ldGhvZHMgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlUmVkdWNlcnM7XG5cbi8qKlxuICogVW5pZmllZCBjbGFzcyBpbXBsZW1lbnRpbmcgZGlmZmVyZW50IGRpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbiBtZXRob2RzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAqL1xuZXhwb3J0IGNsYXNzIERpbWVuc2lvbmFsaXR5UmVkdWNlciB7XG4gIHByaXZhdGUgcmVkdWNlcjogUmVkdWNlciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXIuXG4gICAqIEBwYXJhbSB7YW55W119IGRhdGEgVmVjdG9ycyB0byBlbWJlZC5cbiAgICogQHBhcmFtIHtLbm93bk1ldGhvZHN9IG1ldGhvZCBFbWJlZGRpbmcgbWV0aG9kIHRvIGJlIGFwcGxpZWRcbiAgICogQHBhcmFtIHtLbm93bk1ldHJpY3N9IG1ldHJpYyBEaXN0YW5jZSBtZXRyaWMgdG8gYmUgY29tcHV0ZWQgYmV0d2VlbiBlYWNoIG9mIHRoZSB2ZWN0b3JzLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IFtvcHRpb25zXSBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGltcGxlbWVudGluZyBlbWJlZGRlcnMuXG4gICAqIEBtZW1iZXJvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKGRhdGE6IGFueVtdLCBtZXRob2Q6IEtub3duTWV0aG9kcywgbWV0cmljOiBLbm93bk1ldHJpY3MsIG9wdGlvbnM/OiBPcHRpb25zKSB7XG4gICAgY29uc3QgbWVhc3VyZSA9IG5ldyBNZWFzdXJlKG1ldHJpYykuZ2V0TWVhc3VyZShvcHRpb25zPy5kaXN0YW5jZUZuQXJncyk7XG4gICAgbGV0IHNwZWNPcHRpb25zID0ge307XG5cbiAgICBpZiAoaXNCaXRBcnJheU1ldHJpYyhtZXRyaWMpKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgIGRhdGFbaV0gPSBuZXcgQml0QXJyYXkoZGF0YVtpXS5fZGF0YSwgZGF0YVtpXS5fbGVuZ3RoKTtcbiAgICB9XG5cbiAgICBpZiAobWV0aG9kID09ICdVTUFQJykge1xuICAgICAgc3BlY09wdGlvbnMgPSB7XG4gICAgICAgIC4uLntkYXRhOiBkYXRhfSxcbiAgICAgICAgLi4ue2Rpc3RhbmNlRm46IG1lYXN1cmV9LFxuICAgICAgICAuLi57ZGlzdGFuY2VGbmFtZTogbWV0cmljfSxcbiAgICAgICAgLi4ue25FcG9jaHM6IG9wdGlvbnM/LmN5Y2xlc30sXG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAobWV0aG9kID09ICd0LVNORScpIHtcbiAgICAgIHNwZWNPcHRpb25zID0ge1xuICAgICAgICAuLi57ZGF0YTogZGF0YX0sXG4gICAgICAgIC4uLntkaXN0YW5jZUZuOiBtZWFzdXJlfSxcbiAgICAgICAgLi4ue2Rpc3RhbmNlRm5hbWU6IG1ldHJpY30sXG4gICAgICAgIC4uLntpdGVyYXRpb25zOiBvcHRpb25zPy5jeWNsZXMgPz8gdW5kZWZpbmVkfSxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChtZXRob2QgPT0gJ1NQRScpIHtcbiAgICAgIHNwZWNPcHRpb25zID0gey4uLntkYXRhOiBkYXRhfSwgLi4ue2Rpc3RhbmNlOiBtZWFzdXJlfSwgZGlzdGFuY2VGdW5jdGlvbk5hbWU6IG1ldHJpYywgLi4ub3B0aW9uc307XG4gICAgfSBlbHNlIHtcbiAgICAgIHNwZWNPcHRpb25zID0gey4uLntkYXRhOiBkYXRhfSwgLi4ue2Rpc3RhbmNlOiBtZWFzdXJlfSwgZGlzdGFuY2VGdW5jdGlvbk5hbWU6IG1ldHJpYywgLi4ub3B0aW9uc307XG4gICAgfVxuICAgIHRoaXMucmVkdWNlciA9IG5ldyBBdmFpbGFibGVSZWR1Y2Vyc1ttZXRob2RdKHNwZWNPcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIHRoZSBjaG9zZW4gbWV0aG9kLlxuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHRyYW5zcG9zZSBXaGV0aGVyIHRvIHRyYW5zZm9ybSBjb29yZGluYXRlcyB0byBoYXZlIGNvbHVtbnMtZmlyc3Qgb3JpZW50YXRpb24uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnMgV2hldGhlciB0byB1c2UgcGFyYWxsZWwgZGlzdGFuY2UgY29tcHV0YXRpb24uXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgZW1iZWRkaW5nIG1ldGhvZCB3YXMgbm90IGZvdW5kLlxuICAgKiBAcmV0dXJuIHthbnl9IENhcnRlc2lhbiBjb29yZGluYXRlIG9mIHRoaXMgZW1iZWRkaW5nIGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZS5cbiAgICogQG1lbWJlcm9mIERpbWVuc2lvbmFsaXR5UmVkdWNlclxuICAgKi9cbiAgcHVibGljIGFzeW5jIHRyYW5zZm9ybSh0cmFuc3Bvc2U6IGJvb2xlYW4gPSBmYWxzZSwgcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnM/OiBib29sZWFuKTogUHJvbWlzZTxJUmVkdWNlRGltZW5zaW9uYWxpdHlSZXN1bHQ+IHtcbiAgICBpZiAodGhpcy5yZWR1Y2VyID09PSB1bmRlZmluZWQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZHVjZXIgd2FzIG5vdCBkZWZpbmVkLicpO1xuXG4gICAgbGV0IHtlbWJlZGRpbmcsIGRpc3RhbmNlfSA9IGF3YWl0IHRoaXMucmVkdWNlci50cmFuc2Zvcm0ocGFyYWxsZWxEaXN0YW5jZVdvcmtlcnMpO1xuXG4gICAgaWYgKHRyYW5zcG9zZSlcbiAgICAgIGVtYmVkZGluZyA9IHRyYW5zcG9zZU1hdHJpeChlbWJlZGRpbmcpO1xuXG4gICAgcmV0dXJuIHtkaXN0YW5jZTogZGlzdGFuY2UsIGVtYmVkZGluZzogZW1iZWRkaW5nfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG1ldHJpY3MgYXZhaWxhYmxlIGJ5IHR5cGUuXG4gICAqXG4gICAqIEBwYXJhbSB7QXZhaWxhYmxlRGF0YVR5cGVzfSB0eXBlTmFtZSB0eXBlIG5hbWVcbiAgICogQHJldHVybiB7c3RyaW5nW119IE1ldHJpYyBuYW1lcyB3aGljaCBleHBlY3RzIHRoZSBnaXZlbiBkYXRhIHR5cGVcbiAgICogQG1lbWJlcm9mIERpbWVuc2lvbmFsaXR5UmVkdWNlclxuICAgKi9cbiAgc3RhdGljIGF2YWlsYWJsZU1ldHJpY3NCeVR5cGUodHlwZU5hbWU6IEF2YWlsYWJsZURhdGFUeXBlcykge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhBdmFpbGFibGVNZXRyaWNzW3R5cGVOYW1lXSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gbWV0aG9kcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEByZWFkb25seVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICBzdGF0aWMgZ2V0IGF2YWlsYWJsZU1ldGhvZHMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZVJlZHVjZXJzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIG1ldHJpY3MgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAcmVhZG9ubHlcbiAgICogQG1lbWJlcm9mIERpbWVuc2lvbmFsaXR5UmVkdWNlclxuICAgKi9cbiAgc3RhdGljIGdldCBhdmFpbGFibGVNZXRyaWNzKCkge1xuICAgIGxldCBhbnM6IHN0cmluZ1tdID0gW107XG4gICAgT2JqZWN0LnZhbHVlcyhBdmFpbGFibGVNZXRyaWNzKS5mb3JFYWNoKChvYmopID0+IHtcbiAgICAgIGNvbnN0IGFycmF5ID0gT2JqZWN0LnZhbHVlcyhvYmopO1xuICAgICAgYW5zID0gWy4uLmFucywgLi4uYXJyYXldO1xuICAgIH0pO1xuICAgIHJldHVybiBhbnM7XG4gIH1cbn1cbiJdfQ==","import { isNil } from './utils';\n/** Distance matrix class compatible with data structure of scipy.spatial.distance.pdist */\nexport class DistanceMatrix {\n get data() { return this._data; }\n get size() { return this._size; }\n /**\n * @param {Float32Array} data Distance data\n * @param {number} size Number of original observations\n */\n constructor(data, size) {\n if (size == undefined) {\n if (data == undefined)\n throw new Error('Arguments error: data or size is required.');\n this._data = data;\n this._size = (1 + Math.sqrt(1 + 4 * 2 * this._data.length)) / 2;\n if (this._size != Math.floor(this._size))\n throw new Error(`Invalid data length ${this._data.length} leads to non integer size ${this._size}`);\n }\n else {\n this._size = size;\n const dataLength = size * (size - 1) / 2;\n if (data) {\n if (data.length != dataLength)\n throw new Error(`Invalid data length. Observations size ${size} requires data length ${dataLength}.`);\n this._data = data;\n }\n else {\n this._data = new Float32Array(dataLength);\n }\n }\n }\n _linearizeIJ(i, j) {\n if (!(i < j))\n throw new Error('i must be less than j');\n return this._size * i + j - Math.floor(((i + 2) * (i + 1)) / 2);\n }\n get(i, j) {\n if (i == j)\n return 0;\n else if (i < j)\n return this._data[this._linearizeIJ(i, j)];\n else\n return this._data[this._linearizeIJ(j, i)];\n }\n set(i, j, value) {\n this._data[this._linearizeIJ(i, j)] = value;\n }\n static calc(list, method) {\n const size = list.length;\n const res = new DistanceMatrix(undefined, size);\n for (let i = 0; i < size; i++) {\n for (let j = i + 1; j < size; j++) {\n // if any of the values is null, set distance to 1\n res.set(i, j, !isNil(list[i]) && !isNil(list[j]) ? method(list[i], list[j]) : 1);\n }\n }\n return res;\n }\n // squares each value in matrix in place\n square() {\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = this._data[i] ** 2;\n }\n // adds another matrix to this one in place\n add(other) {\n if (this._size !== other._size)\n throw new Error(`Matrices must have the same size. This size: ${this._size}, other size: ${other._size}`);\n for (let i = 0; i < this._data.length; i++)\n this._data[i] += other._data[i];\n }\n // square root each value in matrix in place\n sqrt() {\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = Math.sqrt(this._data[i]);\n }\n //normilze distance matrix in place\n normalize() {\n let min = 0;\n let max = this._data[0];\n for (let i = 0; i < this._data.length; i++) {\n if (this._data[i] < min)\n min = this._data[i];\n if (this._data[i] > max)\n max = this._data[i];\n }\n const range = max - min;\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = range === 0 ? this._data[i] - min : (this._data[i] - min) / (max - min);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWF0cml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdGFuY2UtbWF0cml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFFOUIsMkZBQTJGO0FBQzNGLE1BQU0sT0FBTyxjQUFjO0lBSXpCLElBQUksSUFBSSxLQUFtQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBRS9DLElBQUksSUFBSSxLQUFhLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFekM7OztPQUdHO0lBQ0gsWUFBWSxJQUFtQixFQUFFLElBQWE7UUFDNUMsSUFBSSxJQUFJLElBQUksU0FBUyxFQUFFO1lBQ3JCLElBQUksSUFBSSxJQUFJLFNBQVM7Z0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1lBRXJGLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSyxDQUFDO1lBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hFLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSw4QkFBOEIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDdkc7YUFBTTtZQUNMLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ2xCLE1BQU0sVUFBVSxHQUFXLElBQUksR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7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QjtRQUNELE1BQU0sS0FBSyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDeEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtZQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDNUYsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyB1aSBmcm9tICdkYXRhZ3Jvay1hcGkvdWknO1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCB7aXNOaWx9IGZyb20gJy4vdXRpbHMnO1xuXG4vKiogRGlzdGFuY2UgbWF0cml4IGNsYXNzIGNvbXBhdGlibGUgd2l0aCBkYXRhIHN0cnVjdHVyZSBvZiBzY2lweS5zcGF0aWFsLmRpc3RhbmNlLnBkaXN0ICovXG5leHBvcnQgY2xhc3MgRGlzdGFuY2VNYXRyaXgge1xuICBfZGF0YTogRmxvYXQzMkFycmF5O1xuICBfc2l6ZTogbnVtYmVyO1xuXG4gIGdldCBkYXRhKCk6IEZsb2F0MzJBcnJheSB7IHJldHVybiB0aGlzLl9kYXRhOyB9XG5cbiAgZ2V0IHNpemUoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3NpemU7IH1cblxuICAvKipcbiAgICogQHBhcmFtIHtGbG9hdDMyQXJyYXl9IGRhdGEgRGlzdGFuY2UgZGF0YVxuICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBOdW1iZXIgb2Ygb3JpZ2luYWwgb2JzZXJ2YXRpb25zXG4gICAqL1xuICBjb25zdHJ1Y3RvcihkYXRhPzogRmxvYXQzMkFycmF5LCBzaXplPzogbnVtYmVyKSB7XG4gICAgaWYgKHNpemUgPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoZGF0YSA9PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcignQXJndW1lbnRzIGVycm9yOiBkYXRhIG9yIHNpemUgaXMgcmVxdWlyZWQuJyk7XG5cbiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhITtcbiAgICAgIHRoaXMuX3NpemUgPSAoMSArIE1hdGguc3FydCgxICsgNCAqIDIgKiB0aGlzLl9kYXRhLmxlbmd0aCkpIC8gMjtcbiAgICAgIGlmICh0aGlzLl9zaXplICE9IE1hdGguZmxvb3IodGhpcy5fc2l6ZSkpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkYXRhIGxlbmd0aCAke3RoaXMuX2RhdGEubGVuZ3RofSBsZWFkcyB0byBub24gaW50ZWdlciBzaXplICR7dGhpcy5fc2l6ZX1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fc2l6ZSA9IHNpemU7XG4gICAgICBjb25zdCBkYXRhTGVuZ3RoOiBudW1iZXIgPSBzaXplICogKHNpemUgLSAxKSAvIDI7XG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gZGF0YUxlbmd0aClcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YSBsZW5ndGguIE9ic2VydmF0aW9ucyBzaXplICR7c2l6ZX0gcmVxdWlyZXMgZGF0YSBsZW5ndGggJHtkYXRhTGVuZ3RofS5gKTtcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9kYXRhID0gbmV3IEZsb2F0MzJBcnJheShkYXRhTGVuZ3RoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9saW5lYXJpemVJSihpOiBudW1iZXIsIGo6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCEoaSA8IGopKSB0aHJvdyBuZXcgRXJyb3IoJ2kgbXVzdCBiZSBsZXNzIHRoYW4gaicpO1xuICAgIHJldHVybiB0aGlzLl9zaXplICogaSArIGogLSBNYXRoLmZsb29yKCgoaSArIDIpICogKGkgKyAxKSkgLyAyKTtcbiAgfVxuXG4gIGdldChpOiBudW1iZXIsIGo6IG51bWJlcikge1xuICAgIGlmIChpID09IGopXG4gICAgICByZXR1cm4gMDtcbiAgICBlbHNlIGlmIChpIDwgailcbiAgICAgIHJldHVybiB0aGlzLl9kYXRhW3RoaXMuX2xpbmVhcml6ZUlKKGksIGopXTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5fZGF0YVt0aGlzLl9saW5lYXJpemVJSihqLCBpKV07XG4gIH1cblxuICBzZXQoaTogbnVtYmVyLCBqOiBudW1iZXIsIHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLl9kYXRhW3RoaXMuX2xpbmVhcml6ZUlKKGksIGopXSA9IHZhbHVlO1xuICB9XG5cbiAgc3RhdGljIGNhbGM8VE9iaj4obGlzdDogSW5kZXhhYmxlPFRPYmo+LCBtZXRob2Q6IChhOiBUT2JqLCBiOiBUT2JqKSA9PiBudW1iZXIpOiBEaXN0YW5jZU1hdHJpeCB7XG4gICAgY29uc3Qgc2l6ZTogbnVtYmVyID0gbGlzdC5sZW5ndGg7XG4gICAgY29uc3QgcmVzID0gbmV3IERpc3RhbmNlTWF0cml4KHVuZGVmaW5lZCwgc2l6ZSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHNpemU7IGorKykge1xuICAgICAgICAvLyBpZiBhbnkgb2YgdGhlIHZhbHVlcyBpcyBudWxsLCBzZXQgZGlzdGFuY2UgdG8gMVxuICAgICAgICByZXMuc2V0KGksIGosICFpc05pbChsaXN0W2ldKSAmJiAhaXNOaWwobGlzdFtqXSkgPyBtZXRob2QobGlzdFtpXSwgbGlzdFtqXSkgOiAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8vIHNxdWFyZXMgZWFjaCB2YWx1ZSBpbiBtYXRyaXggaW4gcGxhY2VcbiAgcHVibGljIHNxdWFyZSgpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldID0gdGhpcy5fZGF0YVtpXSAqKiAyO1xuICB9XG5cbiAgLy8gYWRkcyBhbm90aGVyIG1hdHJpeCB0byB0aGlzIG9uZSBpbiBwbGFjZVxuICBwdWJsaWMgYWRkKG90aGVyOiBEaXN0YW5jZU1hdHJpeCkge1xuICAgIGlmICh0aGlzLl9zaXplICE9PSBvdGhlci5fc2l6ZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWF0cmljZXMgbXVzdCBoYXZlIHRoZSBzYW1lIHNpemUuIFRoaXMgc2l6ZTogJHt0aGlzLl9zaXplfSwgb3RoZXIgc2l6ZTogJHtvdGhlci5fc2l6ZX1gKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldICs9IG90aGVyLl9kYXRhW2ldO1xuICB9XG5cbiAgLy8gc3F1YXJlIHJvb3QgZWFjaCB2YWx1ZSBpbiBtYXRyaXggaW4gcGxhY2VcbiAgcHVibGljIHNxcnQoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9kYXRhLmxlbmd0aDsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSA9IE1hdGguc3FydCh0aGlzLl9kYXRhW2ldKTtcbiAgfVxuXG4gIC8vbm9ybWlsemUgZGlzdGFuY2UgbWF0cml4IGluIHBsYWNlXG4gIHB1YmxpYyBub3JtYWxpemUoKSB7XG4gICAgbGV0IG1pbiA9IDA7XG4gICAgbGV0IG1heCA9IHRoaXMuX2RhdGFbMF07XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9kYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5fZGF0YVtpXSA8IG1pbilcbiAgICAgICAgbWluID0gdGhpcy5fZGF0YVtpXTtcbiAgICAgIGlmICh0aGlzLl9kYXRhW2ldID4gbWF4KVxuICAgICAgICBtYXggPSB0aGlzLl9kYXRhW2ldO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IG1heCAtIG1pbjtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldID0gcmFuZ2UgPT09IDAgPyB0aGlzLl9kYXRhW2ldIC0gbWluIDogKHRoaXMuX2RhdGFbaV0gLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmRleGFibGU8VE9iaj4ge1xuICBbaW5kZXg6IG51bWJlcl06IFRPYmo7XG4gIGdldCBsZW5ndGgoKTogbnVtYmVyO1xufVxuIl19","import { getSimilarityFromDistance } from \"../distance-metrics-methods\";\nimport { BitArrayMetricsNames } from \"../typed-metrics\";\nimport { isNil } from \"./utils\";\nexport class SparseMatrixService {\n constructor() {\n this._workerCount = Math.max(navigator.hardwareConcurrency - 2, 1);\n }\n async calc(values, fnName, threshold, opts = {}) {\n //size of full matrix\n const matSize = values.length * (values.length - 1) / 2;\n const chunkSize = Math.floor(matSize / this._workerCount);\n const minThreshold = await this.getMinimalThreshold(values, fnName, opts);\n if (threshold < minThreshold) {\n console.log(`using threshold ${minThreshold}`);\n threshold = minThreshold;\n }\n opts['threshold'] = threshold;\n const promises = new Array(this._workerCount);\n const workers = new Array(this._workerCount).fill(null).map(() => new Worker(new URL('./sparse-matrix-worker', import.meta.url)));\n for (let idx = 0; idx < this._workerCount; idx++) {\n promises[idx] = new Promise((resolveWorker, rejectWorker) => {\n const startIdx = idx * chunkSize;\n const endIdx = idx === this._workerCount - 1 ? matSize : (idx + 1) * chunkSize;\n if (endIdx <= startIdx)\n resolveWorker({ i: new Int32Array(0), j: new Int32Array(0), distance: new Float32Array(0), idx });\n workers[idx].postMessage({ values, startIdx, endIdx, threshold, fnName, opts });\n workers[idx].onmessage = ({ data: { error, i, j, distance } }) => {\n if (error) {\n workers[idx].terminate();\n rejectWorker(error);\n }\n else {\n workers[idx].terminate();\n resolveWorker({ i, j, distance, idx });\n }\n };\n });\n }\n const results = await Promise.all(promises);\n const fullSize = results.reduce((acc, val) => acc + val.i.length, 0);\n const i = new Int32Array(fullSize);\n const j = new Int32Array(fullSize);\n const distance = new Float32Array(fullSize);\n let offset = 0;\n // setting the results\n for (const res of results) {\n i.set(res.i, offset);\n j.set(res.j, offset);\n distance.set(res.distance, offset);\n offset += res.i.length;\n }\n return { i, j, distance };\n }\n async getMinimalThreshold(values, fnName, opts = {}) {\n const thresholdWorkers = new Array(this._workerCount).fill(null)\n .map(() => new Worker(new URL('./sparse-matrix-threshold-worker', import.meta.url)));\n // data may be sorted by clusters, which will hinder the random sampling\n // so we shuffle it first\n const shuffledValues = values.slice();\n for (let i = shuffledValues.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [shuffledValues[i], shuffledValues[j]] = [shuffledValues[j], shuffledValues[i]];\n }\n //We need to calculate the minimal threshold first,\n //in order to get matrix such that it does not exceed the maximum size of 1GB\n //we have 3 return arrays, each 4 bites per element, so if the maximum size of the matrix is 1GB,\n const max_Sparse_matrix_size = 70000000;\n try {\n const matSize = values.length * (values.length - 1) / 2;\n const chunkSize = Math.floor(matSize / this._workerCount);\n const testSetSizePerWorker = Math.floor(Math.min(matSize / 1000, 1000000) / this._workerCount);\n const tPromises = new Array(this._workerCount);\n for (let idx = 0; idx < this._workerCount; idx++) {\n tPromises[idx] = new Promise((resolveWorker, rejectWorker) => {\n const startIdx = idx * chunkSize;\n const endIdx = idx === this._workerCount - 1 ? matSize : (idx + 1) * chunkSize;\n thresholdWorkers[idx].postMessage({ values: shuffledValues, startIdx, endIdx, sampleLength: testSetSizePerWorker, fnName, opts });\n thresholdWorkers[idx].onmessage = ({ data: { error, distance } }) => {\n thresholdWorkers[idx].terminate();\n if (error) {\n rejectWorker(error);\n }\n else {\n resolveWorker({ distance });\n }\n };\n });\n }\n const results = await Promise.all(tPromises);\n const fullSize = results.reduce((acc, val) => acc + val.distance.length, 0);\n const distance = new Float32Array(fullSize);\n let offset = 0;\n for (const res of results) {\n distance.set(res.distance, offset);\n offset += res.distance.length;\n }\n distance.sort();\n const fractionIndex = Math.floor(max_Sparse_matrix_size / matSize * distance.length);\n let threshold = 1 - distance[fractionIndex];\n threshold = Math.min(Math.max(threshold, 0.3), 0.9); //capping\n return threshold;\n }\n catch (e) {\n thresholdWorkers?.forEach((w) => w?.terminate());\n console.error(e);\n return 0.5;\n }\n }\n static calcSync(values, fnName, distanceFn, threshold) {\n const i = [];\n const j = [];\n const distances = [];\n let cnt = 0;\n let mi = 0;\n let mj = 0;\n const fullSize = values.length * (values.length - 1) / 2;\n while (cnt < fullSize) {\n //const value = seq1List[mi] && seq1List[mj] ? hamming(seq1List[mi], seq1List[mj]) : 0;\n const value = !isNil(values[mi]) && !isNil(values[mj]) ?\n distanceFn(values[mi], values[mj]) : 1;\n const similarity = Object.values(BitArrayMetricsNames).some((a) => a === fnName) ? getSimilarityFromDistance(value) : 1 - value;\n if (similarity >= threshold) {\n i.push(mi);\n j.push(mj);\n distances.push(value);\n }\n cnt++;\n mj++;\n if (mj === values.length) {\n mi++;\n mj = mi + 1;\n }\n }\n const iArray = new Int32Array(i);\n const jArray = new Int32Array(j);\n const distanceArray = new Float32Array(distances);\n return { i: iArray, j: jArray, distance: distanceArray };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhcnNlLW1hdHJpeC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3BhcnNlLW1hdHJpeC1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxvQkFBb0IsRUFBeUIsTUFBTSxrQkFBa0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBUWhDLE1BQU0sT0FBTyxtQkFBbUI7SUFFNUI7UUFDRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLG1CQUFtQixHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUksQ0FBSSxNQUFnQixFQUFFLE1BQW9CLEVBQUUsU0FBaUIsRUFBRSxPQUEyQixFQUFFO1FBRzNHLHFCQUFxQjtRQUNyQixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRTFELE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDMUUsSUFBSSxTQUFTLEdBQUcsWUFBWSxFQUFFO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLFlBQVksRUFBRSxDQUFDLENBQUM7WUFDL0MsU0FBUyxHQUFHLFlBQVksQ0FBQztTQUMxQjtRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxTQUFTLENBQUM7UUFDOUIsTUFBTSxRQUFRLEdBQ1osSUFB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Q0FBQyxvQkFBb0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztZQUNoSSxJQUFJLFVBQVUsSUFBSSxTQUFTLEVBQUU7Z0JBQzNCLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ1gsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDWCxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3ZCO1lBQ0QsR0FBRyxFQUFFLENBQUM7WUFDTixFQUFFLEVBQUUsQ0FBQztZQUNMLElBQUksRUFBRSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUU7Z0JBQ3hCLEVBQUUsRUFBRSxDQUFDO2dCQUNMLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2FBQ2I7U0FDRjtRQUVELE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sYUFBYSxHQUFHLElBQUksWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWxELE9BQU8sRUFBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBQyxDQUFDO0lBQ3pELENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UgfSBmcm9tIFwiLi4vZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzXCI7XG5pbXBvcnQgeyBCaXRBcnJheU1ldHJpY3NOYW1lcywgS25vd25NZXRyaWNzLCBNZWFzdXJlIH0gZnJvbSBcIi4uL3R5cGVkLW1ldHJpY3NcIjtcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuZXhwb3J0IHR5cGUgU3BhcnNlTWF0cml4UmVzdWx0ID0ge1xuICBpOiBJbnQzMkFycmF5LFxuICBqOiBJbnQzMkFycmF5LFxuICBkaXN0YW5jZTogRmxvYXQzMkFycmF5LFxuICBpZHg/OiBudW1iZXJcbn07XG5leHBvcnQgY2xhc3MgU3BhcnNlTWF0cml4U2VydmljZSB7XG4gICAgcHJpdmF0ZSBfd29ya2VyQ291bnQ6IG51bWJlcjtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHRoaXMuX3dvcmtlckNvdW50ID0gTWF0aC5tYXgobmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3kgLSAyLCAxKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgY2FsYzxUPih2YWx1ZXM6IEFycmF5PFQ+LCBmbk5hbWU6IEtub3duTWV0cmljcywgdGhyZXNob2xkOiBudW1iZXIsIG9wdHM6IHtbXzogc3RyaW5nXTogYW55fSA9IHt9KSB7XG5cblxuICAgICAgLy9zaXplIG9mIGZ1bGwgbWF0cml4XG4gICAgICBjb25zdCBtYXRTaXplID0gdmFsdWVzLmxlbmd0aCAqICh2YWx1ZXMubGVuZ3RoIC0gMSkgLyAyO1xuICAgICAgY29uc3QgY2h1bmtTaXplID0gTWF0aC5mbG9vcihtYXRTaXplIC8gdGhpcy5fd29ya2VyQ291bnQpO1xuXG4gICAgICBjb25zdCBtaW5UaHJlc2hvbGQgPSBhd2FpdCB0aGlzLmdldE1pbmltYWxUaHJlc2hvbGQodmFsdWVzLCBmbk5hbWUsIG9wdHMpO1xuICAgICAgaWYgKHRocmVzaG9sZCA8IG1pblRocmVzaG9sZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgdXNpbmcgdGhyZXNob2xkICR7bWluVGhyZXNob2xkfWApO1xuICAgICAgICB0aHJlc2hvbGQgPSBtaW5UaHJlc2hvbGQ7XG4gICAgICB9XG4gICAgICBvcHRzWyd0aHJlc2hvbGQnXSA9IHRocmVzaG9sZDtcbiAgICAgIGNvbnN0IHByb21pc2VzID1cbiAgICAgICAgbmV3IEFycmF5PFByb21pc2U8U3BhcnNlTWF0cml4UmVzdWx0Pj4odGhpcy5fd29ya2VyQ291bnQpO1xuXG4gICAgICBjb25zdCB3b3JrZXJzID0gbmV3IEFycmF5KHRoaXMuX3dvcmtlckNvdW50KS5maWxsKG51bGwpLm1hcCgoKSA9PiBuZXcgV29ya2VyKG5ldyBVUkwoJy4vc3BhcnNlLW1hdHJpeC13b3JrZXInLCBpbXBvcnQubWV0YS51cmwpKSk7XG4gICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCB0aGlzLl93b3JrZXJDb3VudDsgaWR4KyspIHtcbiAgICAgICAgcHJvbWlzZXNbaWR4XSA9IG5ldyBQcm9taXNlKChyZXNvbHZlV29ya2VyLCByZWplY3RXb3JrZXIpID0+IHtcbiAgICAgICAgICBjb25zdCBzdGFydElkeCA9IGlkeCAqIGNodW5rU2l6ZTtcbiAgICAgICAgICBjb25zdCBlbmRJZHggPSBpZHggPT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSA/IG1hdFNpemUgOiAoaWR4ICsgMSkgKiBjaHVua1NpemU7XG4gICAgICAgICAgaWYgKGVuZElkeCA8PSBzdGFydElkeCkgXG4gICAgICAgICAgICByZXNvbHZlV29ya2VyKHtpOiBuZXcgSW50MzJBcnJheSgwKSwgajogbmV3IEludDMyQXJyYXkoMCksIGRpc3RhbmNlOiBuZXcgRmxvYXQzMkFycmF5KDApLCBpZHh9KTtcbiAgICAgICAgICB3b3JrZXJzW2lkeF0ucG9zdE1lc3NhZ2Uoe3ZhbHVlcywgc3RhcnRJZHgsIGVuZElkeCwgdGhyZXNob2xkLCBmbk5hbWUsIG9wdHN9KTtcbiAgICAgICAgICB3b3JrZXJzW2lkeF0ub25tZXNzYWdlID0gKHtkYXRhOiB7ZXJyb3IsIGksIGosIGRpc3RhbmNlfX0pOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikgeyBcbiAgICAgICAgICAgICAgd29ya2Vyc1tpZHhdLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgICByZWplY3RXb3JrZXIoZXJyb3IpOyBcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHdvcmtlcnNbaWR4XS50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgICAgcmVzb2x2ZVdvcmtlcih7aSwgaiwgZGlzdGFuY2UsIGlkeH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgY29uc3QgZnVsbFNpemUgPSByZXN1bHRzLnJlZHVjZSgoYWNjLCB2YWwpID0+IGFjYyArIHZhbC5pLmxlbmd0aCwgMCk7XG4gICAgICBjb25zdCBpID0gbmV3IEludDMyQXJyYXkoZnVsbFNpemUpO1xuICAgICAgY29uc3QgaiA9IG5ldyBJbnQzMkFycmF5KGZ1bGxTaXplKTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gbmV3IEZsb2F0MzJBcnJheShmdWxsU2l6ZSk7XG4gICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgIC8vIHNldHRpbmcgdGhlIHJlc3VsdHNcbiAgICAgIGZvciAoY29uc3QgcmVzIG9mIHJlc3VsdHMpIHtcbiAgICAgICAgaS5zZXQocmVzLmksIG9mZnNldCk7XG4gICAgICAgIGouc2V0KHJlcy5qLCBvZmZzZXQpO1xuICAgICAgICBkaXN0YW5jZS5zZXQocmVzLmRpc3RhbmNlLCBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gcmVzLmkubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtpLCBqLCBkaXN0YW5jZX07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRNaW5pbWFsVGhyZXNob2xkPFQ+KHZhbHVlczogQXJyYXk8VD4sIGZuTmFtZTogS25vd25NZXRyaWNzLCBvcHRzOiB7W186IHN0cmluZ106IGFueX0gPSB7fSkge1xuICAgICAgY29uc3QgdGhyZXNob2xkV29ya2VycyA9IG5ldyBBcnJheSh0aGlzLl93b3JrZXJDb3VudCkuZmlsbChudWxsKVxuICAgICAgICAubWFwKCgpID0+IG5ldyBXb3JrZXIobmV3IFVSTCgnLi9zcGFyc2UtbWF0cml4LXRocmVzaG9sZC13b3JrZXInLCBpbXBvcnQubWV0YS51cmwpKSk7XG4gICAgICBcbiAgICAgIC8vIGRhdGEgbWF5IGJlIHNvcnRlZCBieSBjbHVzdGVycywgd2hpY2ggd2lsbCBoaW5kZXIgdGhlIHJhbmRvbSBzYW1wbGluZ1xuICAgICAgLy8gc28gd2Ugc2h1ZmZsZSBpdCBmaXJzdFxuICAgICAgY29uc3Qgc2h1ZmZsZWRWYWx1ZXMgPSB2YWx1ZXMuc2xpY2UoKTtcbiAgICAgIGZvciAobGV0IGkgPSBzaHVmZmxlZFZhbHVlcy5sZW5ndGggLSAxOyBpID4gMDsgaS0tKSB7XG4gICAgICAgIGNvbnN0IGogPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAoaSArIDEpKTtcbiAgICAgICAgW3NodWZmbGVkVmFsdWVzW2ldLCBzaHVmZmxlZFZhbHVlc1tqXV0gPSBbc2h1ZmZsZWRWYWx1ZXNbal0sIHNodWZmbGVkVmFsdWVzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLy9XZSBuZWVkIHRvIGNhbGN1bGF0ZSB0aGUgbWluaW1hbCB0aHJlc2hvbGQgZmlyc3QsXG4gICAgICAvL2luIG9yZGVyIHRvIGdldCBtYXRyaXggc3VjaCB0aGF0IGl0IGRvZXMgbm90IGV4Y2VlZCB0aGUgbWF4aW11bSBzaXplIG9mIDFHQlxuICAgICAgLy93ZSBoYXZlIDMgcmV0dXJuIGFycmF5cywgZWFjaCA0IGJpdGVzIHBlciBlbGVtZW50LCBzbyBpZiB0aGUgbWF4aW11bSBzaXplIG9mIHRoZSBtYXRyaXggaXMgMUdCLFxuICAgICAgY29uc3QgbWF4X1NwYXJzZV9tYXRyaXhfc2l6ZSA9IDcwXzAwMF8wMDA7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtYXRTaXplID0gdmFsdWVzLmxlbmd0aCAqICh2YWx1ZXMubGVuZ3RoIC0gMSkgLyAyO1xuICAgICAgICBjb25zdCBjaHVua1NpemUgPSBNYXRoLmZsb29yKG1hdFNpemUgLyB0aGlzLl93b3JrZXJDb3VudCk7XG4gICAgICAgIGNvbnN0IHRlc3RTZXRTaXplUGVyV29ya2VyID0gTWF0aC5mbG9vcihNYXRoLm1pbihtYXRTaXplIC8gMTAwMCwgMV8wMDBfMDAwKSAvIHRoaXMuX3dvcmtlckNvdW50KTtcbiAgICAgICAgY29uc3QgdFByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8e2Rpc3RhbmNlOiBGbG9hdDMyQXJyYXl9Pj4odGhpcy5fd29ya2VyQ291bnQpO1xuXG4gICAgICAgIGZvciAobGV0IGlkeCA9IDA7IGlkeCA8IHRoaXMuX3dvcmtlckNvdW50OyBpZHgrKykge1xuICAgICAgICAgIHRQcm9taXNlc1tpZHhdID0gbmV3IFByb21pc2UoKHJlc29sdmVXb3JrZXIsIHJlamVjdFdvcmtlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRJZHggPSBpZHggKiBjaHVua1NpemU7XG4gICAgICAgICAgICBjb25zdCBlbmRJZHggPSBpZHggPT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSA/IG1hdFNpemUgOiAoaWR4ICsgMSkgKiBjaHVua1NpemU7XG4gICAgICAgICAgICB0aHJlc2hvbGRXb3JrZXJzW2lkeF0ucG9zdE1lc3NhZ2Uoe3ZhbHVlczogc2h1ZmZsZWRWYWx1ZXMsIHN0YXJ0SWR4LCBlbmRJZHgsIHNhbXBsZUxlbmd0aDogdGVzdFNldFNpemVQZXJXb3JrZXIsIGZuTmFtZSwgb3B0c30pO1xuICAgICAgICAgICAgdGhyZXNob2xkV29ya2Vyc1tpZHhdLm9ubWVzc2FnZSA9ICh7ZGF0YToge2Vycm9yLCBkaXN0YW5jZX19KTogdm9pZCA9PiB7XG4gICAgICAgICAgICAgIHRocmVzaG9sZFdvcmtlcnNbaWR4XS50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgICAgaWYgKGVycm9yKSB7IHJlamVjdFdvcmtlcihlcnJvcik7IH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZVdvcmtlcih7ZGlzdGFuY2V9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbCh0UHJvbWlzZXMpO1xuICAgICAgICBjb25zdCBmdWxsU2l6ZSA9IHJlc3VsdHMucmVkdWNlKChhY2MsIHZhbCkgPT4gYWNjICsgdmFsLmRpc3RhbmNlLmxlbmd0aCwgMCk7XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gbmV3IEZsb2F0MzJBcnJheShmdWxsU2l6ZSk7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IHJlcyBvZiByZXN1bHRzKSB7XG4gICAgICAgICAgZGlzdGFuY2Uuc2V0KHJlcy5kaXN0YW5jZSwgb2Zmc2V0KTtcbiAgICAgICAgICBvZmZzZXQgKz0gcmVzLmRpc3RhbmNlLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBkaXN0YW5jZS5zb3J0KCk7XG5cbiAgICAgICAgY29uc3QgZnJhY3Rpb25JbmRleCA9IE1hdGguZmxvb3IobWF4X1NwYXJzZV9tYXRyaXhfc2l6ZSAvIG1hdFNpemUgKiBkaXN0YW5jZS5sZW5ndGgpO1xuXG4gICAgICAgIGxldCB0aHJlc2hvbGQgPSAxIC0gZGlzdGFuY2VbZnJhY3Rpb25JbmRleF07XG4gICAgICAgIHRocmVzaG9sZCA9IE1hdGgubWluKE1hdGgubWF4KHRocmVzaG9sZCwgMC4zKSwgMC45KTsgLy9jYXBwaW5nXG4gICAgICAgIHJldHVybiB0aHJlc2hvbGQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocmVzaG9sZFdvcmtlcnM/LmZvckVhY2goKHcpID0+IHc/LnRlcm1pbmF0ZSgpKTtcbiAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgcmV0dXJuIDAuNTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgY2FsY1N5bmM8VD4gKHZhbHVlczogQXJyYXk8VD4gfCBBcnJheUxpa2U8VD4sIGZuTmFtZTogS25vd25NZXRyaWNzLCBkaXN0YW5jZUZuOiBGdW5jdGlvbiwgdGhyZXNob2xkOiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IGk6IG51bWJlcltdID0gW107XG4gICAgICBjb25zdCBqOiBudW1iZXJbXSA9IFtdO1xuICAgICAgY29uc3QgZGlzdGFuY2VzOiBudW1iZXJbXSA9IFtdO1xuICAgICAgbGV0IGNudCA9IDA7XG4gICAgICBsZXQgbWkgPSAwO1xuICAgICAgbGV0IG1qID0gMDtcbiAgICAgIGNvbnN0IGZ1bGxTaXplID0gdmFsdWVzLmxlbmd0aCAqICh2YWx1ZXMubGVuZ3RoIC0gMSkgLyAyO1xuICAgICAgd2hpbGUgKGNudCA8IGZ1bGxTaXplKSB7XG4gICAgICAgIC8vY29uc3QgdmFsdWUgPSBzZXExTGlzdFttaV0gJiYgc2VxMUxpc3RbbWpdID8gaGFtbWluZyhzZXExTGlzdFttaV0sIHNlcTFMaXN0W21qXSkgOiAwO1xuICAgICAgICBjb25zdCB2YWx1ZSA9ICFpc05pbCh2YWx1ZXNbbWldKSAmJiAhaXNOaWwodmFsdWVzW21qXSkgP1xuICAgICAgICAgIGRpc3RhbmNlRm4odmFsdWVzW21pXSwgdmFsdWVzW21qXSkgOiAxO1xuICAgICAgICBjb25zdCBzaW1pbGFyaXR5ID0gT2JqZWN0LnZhbHVlcyhCaXRBcnJheU1ldHJpY3NOYW1lcykuc29tZSgoYSkgPT4gYSA9PT0gZm5OYW1lKSA/IGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UodmFsdWUpIDogMSAtIHZhbHVlO1xuICAgICAgICBpZiAoc2ltaWxhcml0eSA+PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgICBpLnB1c2gobWkpO1xuICAgICAgICAgIGoucHVzaChtaik7XG4gICAgICAgICAgZGlzdGFuY2VzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGNudCsrO1xuICAgICAgICBtaisrO1xuICAgICAgICBpZiAobWogPT09IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICBtaSsrO1xuICAgICAgICAgIG1qID0gbWkgKyAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgXG4gICAgICBjb25zdCBpQXJyYXkgPSBuZXcgSW50MzJBcnJheShpKTtcbiAgICAgIGNvbnN0IGpBcnJheSA9IG5ldyBJbnQzMkFycmF5KGopO1xuICAgICAgY29uc3QgZGlzdGFuY2VBcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkoZGlzdGFuY2VzKTtcblxuICAgICAgcmV0dXJuIHtpOiBpQXJyYXksIGo6IGpBcnJheSwgZGlzdGFuY2U6IGRpc3RhbmNlQXJyYXl9O1xuICAgIH1cbn0iXX0=","export function getKnnGraph(i, j, distances, neighbours, dataLength) {\n function insert(distancesAr, indexes, num, index) {\n if (num > distancesAr[distancesAr.length - 1]) {\n return;\n }\n let k = distancesAr.length - 2;\n for (k = distancesAr.length - 2; k >= 0; k--) {\n if (num > distancesAr[k]) {\n break;\n }\n }\n distancesAr.splice(distancesAr.length - 1, 1);\n distancesAr.splice(k + 1, 0, num);\n indexes.splice(indexes.length - 1, 1);\n indexes.splice(k + 1, 0, index);\n }\n console.time('knnGraph');\n const knnIndexes = new Array(dataLength).fill(null).map(() => new Array(neighbours).fill(1));\n const knnDistances = new Array(dataLength).fill(null).map(() => new Array(neighbours).fill(1));\n for (let k = 0; k < i.length; k++) {\n insert(knnDistances[i[k]], knnIndexes[i[k]], distances[k], j[k]);\n insert(knnDistances[j[k]], knnIndexes[j[k]], distances[k], i[k]);\n }\n console.timeEnd('knnGraph');\n return { knnIndexes, knnDistances };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia25uR3JhcGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJrbm5HcmFwaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLFVBQVUsV0FBVyxDQUFDLENBQWEsRUFBRSxDQUFhLEVBQUUsU0FBdUIsRUFDN0UsVUFBa0IsRUFBRSxVQUFrQjtJQUNsQyxTQUFTLE1BQU0sQ0FBQyxXQUFxQixFQUFFLE9BQWlCLEVBQUUsR0FBVyxFQUFFLEtBQWE7UUFDaEYsSUFBSSxHQUFHLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDekMsT0FBTztTQUNWO1FBQ0QsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDL0IsS0FBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN6QyxJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3RCLE1BQU07YUFDVDtTQUNKO1FBQ0QsV0FBVyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdEMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBR0QsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUN4QixNQUFNLFVBQVUsR0FBRyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksS0FBSyxDQUFTLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JHLE1BQU0sWUFBWSxHQUFHLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxLQUFLLENBQVMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFdkcsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDL0IsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNwRTtJQUVELE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDNUIsT0FBTyxFQUFDLFVBQVUsRUFBRSxZQUFZLEVBQUMsQ0FBQztBQUMxQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRLbm5HcmFwaChpOiBJbnQzMkFycmF5LCBqOiBJbnQzMkFycmF5LCBkaXN0YW5jZXM6IEZsb2F0MzJBcnJheSxcbiAgICBuZWlnaGJvdXJzOiBudW1iZXIsIGRhdGFMZW5ndGg6IG51bWJlcikge1xuICAgICAgICBmdW5jdGlvbiBpbnNlcnQoZGlzdGFuY2VzQXI6IG51bWJlcltdLCBpbmRleGVzOiBudW1iZXJbXSwgbnVtOiBudW1iZXIsIGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgICAgIGlmIChudW0gPiBkaXN0YW5jZXNBcltkaXN0YW5jZXNBci5sZW5ndGgtMV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgayA9IGRpc3RhbmNlc0FyLmxlbmd0aCAtIDI7XG4gICAgICAgICAgICBmb3IoayA9IGRpc3RhbmNlc0FyLmxlbmd0aCAtIDI7IGsgPj0gMDsgay0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKG51bSA+IGRpc3RhbmNlc0FyW2tdKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpc3RhbmNlc0FyLnNwbGljZShkaXN0YW5jZXNBci5sZW5ndGggLSAxLCAxKTtcbiAgICAgICAgICAgIGRpc3RhbmNlc0FyLnNwbGljZShrKzEsIDAsIG51bSk7XG4gICAgICAgICAgICBpbmRleGVzLnNwbGljZShpbmRleGVzLmxlbmd0aCAtIDEsIDEpO1xuICAgICAgICAgICAgaW5kZXhlcy5zcGxpY2UoaysxLCAwLCBpbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgICAgIFxuXG4gICAgICAgIGNvbnNvbGUudGltZSgna25uR3JhcGgnKVxuICAgICAgICBjb25zdCBrbm5JbmRleGVzID0gbmV3IEFycmF5KGRhdGFMZW5ndGgpLmZpbGwobnVsbCkubWFwKCgpID0+IG5ldyBBcnJheTxudW1iZXI+KG5laWdoYm91cnMpLmZpbGwoMSkpO1xuICAgICAgICBjb25zdCBrbm5EaXN0YW5jZXMgPSBuZXcgQXJyYXkoZGF0YUxlbmd0aCkuZmlsbChudWxsKS5tYXAoKCkgPT4gbmV3IEFycmF5PG51bWJlcj4obmVpZ2hib3VycykuZmlsbCgxKSk7XG5cbiAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBpLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICBpbnNlcnQoa25uRGlzdGFuY2VzW2lba11dLCBrbm5JbmRleGVzW2lba11dLCBkaXN0YW5jZXNba10sIGpba10pO1xuICAgICAgICAgICAgaW5zZXJ0KGtubkRpc3RhbmNlc1tqW2tdXSwga25uSW5kZXhlc1tqW2tdXSwgZGlzdGFuY2VzW2tdLCBpW2tdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUudGltZUVuZCgna25uR3JhcGgnKTtcbiAgICAgICAgcmV0dXJuIHtrbm5JbmRleGVzLCBrbm5EaXN0YW5jZXN9O1xufSJdfQ==","import { DimensionalityReducer } from '../reduce-dimensionality';\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(columnData, method, measure, options, parallelDistanceWorkers) {\n const reducer = new DimensionalityReducer(columnData, method, measure, { ...options, progressFunc });\n return await reducer.transform(true, parallelDistanceWorkers);\n}\nasync function progressFunc(epochNum, epochsLength, embedding) {\n if (epochNum % 5 === 0)\n self.postMessage({ epochNum, epochsLength, embedding });\n}\nself.onmessage = async ({ data: { columnData, method, measure, options, parallelDistanceWorkers } }) => {\n let data;\n try {\n data = await onMessage(columnData, method, measure, options, parallelDistanceWorkers);\n }\n catch (e) {\n data = { error: e };\n }\n self.postMessage({\n error: data.error,\n distance: data.distance,\n embedding: data.embedding,\n });\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGltZW5zaW9uYWxpdHktcmVkdWNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImRpbWVuc2lvbmFsaXR5LXJlZHVjZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLHFCQUFxQixFQUFlLE1BQU0sMEJBQTBCLENBQUM7QUFHN0U7Ozs7Ozs7OztHQVNHO0FBQ0gsS0FBSyxVQUFVLFNBQVMsQ0FBQyxVQUFpQixFQUFFLE1BQW9CLEVBQUUsT0FBcUIsRUFDckYsT0FBYSxFQUFFLHVCQUFpQztJQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLHFCQUFxQixDQUN2QyxVQUFVLEVBQ1YsTUFBTSxFQUNOLE9BQU8sRUFDUCxFQUFDLEdBQUcsT0FBTyxFQUFFLFlBQVksRUFBQyxDQUMzQixDQUFDO0lBQ0YsT0FBTyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLHVCQUF1QixDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVELEtBQUssVUFBVSxZQUFZLENBQUUsUUFBZ0IsRUFBRSxZQUFvQixFQUFFLFNBQXFCO0lBQ3hGLElBQUksUUFBUSxHQUFHLENBQUMsS0FBSyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBQyxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxFQUFFLEVBQUMsSUFBSSxFQUFFLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFDLEVBQUMsRUFBRSxFQUFFO0lBQ2pHLElBQUksSUFBb0QsQ0FBQztJQUN6RCxJQUFJO1FBQ0YsSUFBSSxHQUFHLE1BQU0sU0FBUyxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0tBQ3ZGO0lBQUMsT0FBTyxDQUFNLEVBQUU7UUFDZixJQUFJLEdBQUcsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUM7S0FDbkI7SUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ2YsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1FBQ2pCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtRQUN2QixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7S0FDMUIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtEaW1lbnNpb25hbGl0eVJlZHVjZXIsIEtub3duTWV0aG9kc30gZnJvbSAnLi4vcmVkdWNlLWRpbWVuc2lvbmFsaXR5JztcbmltcG9ydCB7S25vd25NZXRyaWNzfSBmcm9tICcuLi90eXBlZC1tZXRyaWNzL3R5cGVkLW1ldHJpY3MnO1xuXG4vKipcbiAqIFdvcmtlciB0aHJlYWQgcmVjZWl2aW5nIGRhdGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHthbnlbXX0gY29sdW1uRGF0YSBTYW1wbGVzIHRvIHByb2Nlc3MuXG4gKiBAcGFyYW0ge0tub3duTWV0aG9kc30gbWV0aG9kIEVtYmVkZGluZyBtZXRob2QuXG4gKiBAcGFyYW0ge0tub3duTWV0cmljc30gbWVhc3VyZSBEaXN0YW5jZSBtZXRyaWMuXG4gKiBAcGFyYW0ge2FueX0gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gYWxnb3JpdGhtLlxuICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSB3b3JrZXJzLlxuICogQHJldHVybiB7YW55fSBFbWJlZGRpbmcgKGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZSkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG9uTWVzc2FnZShjb2x1bW5EYXRhOiBhbnlbXSwgbWV0aG9kOiBLbm93bk1ldGhvZHMsIG1lYXN1cmU6IEtub3duTWV0cmljcyxcbiAgb3B0aW9ucz86IGFueSwgcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnM/OiBib29sZWFuKTogUHJvbWlzZTx7ZGlzdGFuY2U/OiBhbnksIGVtYmVkZGluZz86IGFueX0+IHtcbiAgY29uc3QgcmVkdWNlciA9IG5ldyBEaW1lbnNpb25hbGl0eVJlZHVjZXIoXG4gICAgY29sdW1uRGF0YSxcbiAgICBtZXRob2QsXG4gICAgbWVhc3VyZSxcbiAgICB7Li4ub3B0aW9ucywgcHJvZ3Jlc3NGdW5jfSxcbiAgKTtcbiAgcmV0dXJuIGF3YWl0IHJlZHVjZXIudHJhbnNmb3JtKHRydWUsIHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcHJvZ3Jlc3NGdW5jIChlcG9jaE51bTogbnVtYmVyLCBlcG9jaHNMZW5ndGg6IG51bWJlciwgZW1iZWRkaW5nOiBudW1iZXJbXVtdKSB7XG4gIGlmIChlcG9jaE51bSAlIDUgPT09IDApXG4gICAgc2VsZi5wb3N0TWVzc2FnZSh7ZXBvY2hOdW0sIGVwb2Noc0xlbmd0aCwgZW1iZWRkaW5nfSk7XG59XG5cbnNlbGYub25tZXNzYWdlID0gYXN5bmMgKHtkYXRhOiB7Y29sdW1uRGF0YSwgbWV0aG9kLCBtZWFzdXJlLCBvcHRpb25zLCBwYXJhbGxlbERpc3RhbmNlV29ya2Vyc319KSA9PiB7XG4gIGxldCBkYXRhOiB7ZXJyb3I/OiBhbnksIGRpc3RhbmNlPzogYW55LCBlbWJlZGRpbmc/OiBhbnl9O1xuICB0cnkge1xuICAgIGRhdGEgPSBhd2FpdCBvbk1lc3NhZ2UoY29sdW1uRGF0YSwgbWV0aG9kLCBtZWFzdXJlLCBvcHRpb25zLCBwYXJhbGxlbERpc3RhbmNlV29ya2Vycyk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGRhdGEgPSB7ZXJyb3I6IGV9O1xuICB9XG4gIHNlbGYucG9zdE1lc3NhZ2Uoe1xuICAgIGVycm9yOiBkYXRhLmVycm9yLFxuICAgIGRpc3RhbmNlOiBkYXRhLmRpc3RhbmNlLFxuICAgIGVtYmVkZGluZzogZGF0YS5lbWJlZGRpbmcsXG4gIH0pO1xufTtcbiJdfQ==","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TSNE = void 0;\nvar tsne_1 = require(\"./tsne\");\nObject.defineProperty(exports, \"TSNE\", { enumerable: true, get: function () { return tsne_1.TSNE; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TSNE = void 0;\nclass TSNE {\n constructor(opt) {\n // return 0 mean unit standard deviation random number\n this.returnV = false;\n this.vValue = 0.0;\n this.iter = 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 }\n assert(condition, message) {\n if (!condition) {\n throw message || 'Assertion failed';\n }\n }\n // syntax sugar\n getopt(opt, field, defaultval) {\n if (opt.hasOwnProperty(field)) {\n return opt[field];\n }\n else {\n return defaultval;\n }\n }\n gaussRandom() {\n if (this.returnV) {\n this.returnV = false;\n return this.vValue;\n }\n const u = 2 * Math.random() - 1;\n const v = 2 * Math.random() - 1;\n const r = u * u + v * v;\n if (r === 0 || r > 1) {\n return this.gaussRandom();\n }\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) { return mu + this.gaussRandom() * std; }\n // utilitity that creates contiguous vector of zeros of size n\n zeros(n) {\n if (typeof (n) === 'undefined' || isNaN(n)) {\n return [];\n }\n if (typeof ArrayBuffer === 'undefined') {\n // lacking browser support\n const arr = new Array(n);\n for (let i = 0; i < n; i++) {\n arr[i] = 0;\n }\n return arr;\n }\n else {\n return new Float64Array(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 = [];\n for (let i = 0; i < n; i++) {\n const xhere = [];\n for (let j = 0; j < d; j++) {\n if (uses) {\n xhere.push(s);\n }\n else {\n xhere.push(this.randn(0.0, 1e-4));\n }\n }\n x.push(xhere);\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 // compute (p_{i|j} + p_{j|i})/(2n)\n d2p(D, perplexity, tol) {\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 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 = 50;\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 let pj = Math.exp(-D[i * n + j] * beta);\n if (i === j) {\n pj = 0;\n } // we dont care about diagonals\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 }\n else {\n pj = prow[j] / psum;\n }\n prow[j] = pj;\n if (pj > 1e-7) {\n nHere -= pj * Math.log(pj);\n }\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 }\n else {\n beta = (beta + betamax) / 2;\n }\n }\n else {\n // converse case. make distrubtion less peaky\n betamax = beta;\n if (betamin === -Infinity) {\n beta = beta / 2;\n }\n else {\n beta = (beta + betamin) / 2;\n }\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 }\n if (num >= maxtries) {\n done = true;\n }\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 }\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 }\n return pOut;\n }\n // helper function\n sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }\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); // 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) {\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 const dists = 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 = D[i][j];\n dists[i * N + j] = d;\n dists[j * N + i] = d;\n }\n }\n this.P = this.d2p(dists, this.perplexity, 1e-4);\n this.N = N;\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;\n } // 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 }\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 const 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 let dsum = 0.0;\n for (let d = 0; d < dim; d++) {\n const dhere = Y[i][d] - Y[j][d];\n dsum += dhere * dhere;\n }\n const qu = 1.0 / (1.0 + dsum); // Student t-distribution\n quArr[i * N + j] = qu;\n 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 for (let q = 0; q < NN; q++) {\n Q[q] = Math.max(quArr[q] / qsum, 1e-100);\n }\n let cost = 0.0;\n const grad = [];\n for (let i = 0; i < N; i++) {\n const gsum = new Array(dim); // init grad for point i\n for (let d = 0; d < dim; d++) {\n gsum[d] = 0.0;\n }\n for (let j = 0; j < N; j++) {\n cost += -P[i * N + j] * Math.log(Q[i * N + j]); // accumulate cost (the non-constant portion at least...)\n const premult = 4 * (pmul * P[i * N + j] - Q[i * N + j]) * quArr[i * N + j];\n for (let d = 0; d < dim; d++) {\n gsum[d] += premult * (Y[i][d] - Y[j][d]);\n }\n }\n grad.push(gsum);\n }\n return { cost, grad };\n }\n}\nexports.TSNE = TSNE;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n// the startup function\n__webpack_require__.x = () => {\n\t// Load entry module and return exports\n\t// This entry module depends on other loaded chunks and execution need to be delayed\n\tvar __webpack_exports__ = __webpack_require__.O(undefined, [1,172], () => (__webpack_require__(3196)))\n\t__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n\treturn __webpack_exports__;\n};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks and sibling chunks for the entrypoint\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && !scriptUrl) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","__webpack_require__.b = self.location + \"\";\n\n// object to store loaded chunks\n// \"1\" means \"already loaded\"\nvar installedChunks = {\n\t196: 1\n};\n\n// importScripts chunk loading\nvar installChunk = (data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\tfor(var moduleId in moreModules) {\n\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t}\n\t}\n\tif(runtime) runtime(__webpack_require__);\n\twhile(chunkIds.length)\n\t\tinstalledChunks[chunkIds.pop()] = 1;\n\tparentChunkLoadingFunction(data);\n};\n__webpack_require__.f.i = (chunkId, promises) => {\n\t// \"1\" is the signal for \"already loaded\"\n\tif(!installedChunks[chunkId]) {\n\t\tif(true) { // all chunks have JS\n\t\t\timportScripts(__webpack_require__.p + __webpack_require__.u(chunkId));\n\t\t}\n\t}\n};\n\nvar chunkLoadingGlobal = self[\"webpackChunkbio\"] = self[\"webpackChunkbio\"] || [];\nvar parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);\nchunkLoadingGlobal.push = installChunk;\n\n// no HMR\n\n// no HMR manifest","// run startup\nvar __webpack_exports__ = __webpack_require__.x();\n"],"names":["deferred","next","randomFloat","range","Math","random","floor","assert","condition","message","Error","vectorAdd","p","q","multiplier","nItems","length","total","i","fillRandomMatrix","dimension1","dimension2","scale","matrix","fill","Array","map","initCoordinates","j","calculateEuclideanDistance","sqdiffSumm","v","itemsSum","vectorSquare","sqrt","dmLinearIndex","size","DistanceMatrixService","constructor","useConcurrentWorkers","terminateOnComplete","threadCount","navigator","hardwareConcurrency","this","_workerCount","max","_workers","Worker","URL","_terminateOnComplete","async","values","fnName","normalize","opts","Promise","resolve","reject","len","promises","totalLength","min","chunkSize","distanceMatrix","Float32Array","endRow","endCol","lmin","lmax","Number","MIN_VALUE","start","end","startRow","startCol","postMessage","chunckSize","resolveWorker","rejectWorker","onmessage","data","error","distanceMatrixData","terminate","set","all","forEach","value","index","e","worker","SPEBase","options","steps","cycles","cutoff","lambda","dlambda","lambda2","dlambda2","epsilon","distanceFunction","distance","distanceFunctionName","vectors","dmIndexFunct","matrixService","calc","calcDistance","index1","index2","coordinates","dimension","initDistance","cycle","step","rowi","rowj","r","d","diffIJ","PSPEBase","OriginalSPE","super","radiusPercent","maxDistance","maxDistanceSteps","n","radius","StringMetricsNames","VectorMetricsNames","BitArrayMetricsNames","IntArrayMetricsNames","DistanceMetricsSubjects","NumberMetricsNames","tanimotoSimilarity","x","y","trueCount","common","andWithCountBits","getDistanceFromSimilarity","similarity","Tanimoto","Dice","Asymmetric","BraunBlanquet","Cosine","Kulczynski","McConnaughey","RogotGoldberg","Russel","Sokal","Hamming","Euclidean","HAMMING","LEVENSHTEIN","MONOMER_CHEMICAL_DISTANCE","vectorDistanceMetricsMethods","stringDistanceMetricsMethods","Levenshtein","JaroWinkler","Manhattan","s1","s2","dist","bitArrayDistanceMetricsMethods","diceSimilarity","asymmetricSimilarity","braunBlanquetSimilarity","cosineSimilarity","totalProd","kulczynskiSimilarity","mcConnaugheySimilarity","countBits","diff","rogotGoldbergSimilarity","russelSimilarity","sokalSimilarity","intArrayDistanceMetricsMethods","TanimotoIntArray","numberDistanceMetricsMethods","NumericDistance","abs","AvailableMetrics","Vector","String","BitArray","MacroMolecule","NEEDLEMANN_WUNSCH","IntArray","MetricToDataType","Object","keys","reduce","ret","key","val","Measure","method","dataType","getMeasure","dict","hasOwnProperty","name","toString","static","availableMeasures","tauRandInt","tauRand","empty","output","push","undefined","_","filled","zeros","mean","input","sum","rejectionSample","nSamples","poolSize","result","rejectSample","broken","k","reshape2d","a","b","rows","count","col","makeHeap","nPoints","makeArrays","fillValue","heap","Infinity","heapPush","row","weight","flag","indices","weights","uncheckedHeapPush","isNew","iSwap","ic1","ic2","heapShape2","buildCandidates","currentGraph","nVertices","nNeighbors","maxCandidates","candidateNeighbors","idx","isn","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","getCols","getValues","fn","vals","toArray","oldRows","oldCols","oldVals","matlen","Int32Array","pairwiseMultiply","elementWise","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","splice","oldNodeNum","res","selectSide","point","searchFlatTree","node","prototype","isAnyArray","object","call","endsWith","errorCalculation","parameters","parameterizedFunction","func","rescale","arguments","TypeError","currentMin","_options$fromIndex","fromIndex","_options$toIndex","toIndex","isInteger","minValue","currentMax","maxValue","RangeError","_options$min","autoMinMax","_options$max","factor","indent","repeat","indentData","inspectMatrixWithOptions","maxRows","maxColumns","maxNumSize","padMinus","columns","maxI","maxJ","loop","line","formatNumber","join","inspectData","num","formatNumber2","padEnd","str","fix","toFixed","startsWith","exp","toExponential","slice","checkRowIndex","outer","checkColumnIndex","checkRowVector","vector","to1DArray","checkColumnVector","checkRange","startColumn","endColumn","checkNumber","newArray","array","checkNonEmpty","isEmpty","AbstractMatrix","newRows","newColumns","newData","newMatrix","Matrix","column","interval","round","l","matrix1","matrix2","checkMatrix","isMatrix","klass","apply","callback","to2DArray","copy","toJSON","isRowVector","isColumnVector","isVector","isSquare","isSymmetric","isEchelonForm","previousColumn","checked","isReducedEchelonForm","echelonForm","clone","h","iMax","swapRows","tmp","reducedEchelonForm","maxRow","pivot","setSubMatrix","neg","mulS","getRow","getRowVector","rowVector","setRow","row1","row2","temp","getColumn","getColumnVector","columnVector","setColumn","swapColumns","column1","column2","addRowVector","subRowVector","mulRowVector","divRowVector","addColumnVector","subColumnVector","mulColumnVector","divColumnVector","mulRow","mulColumn","by","NaN","NEGATIVE_INFINITY","maxIndex","POSITIVE_INFINITY","minIndex","maxRowIndex","minRow","minRowIndex","maxColumn","maxColumnIndex","minColumn","minColumnIndex","diag","type","cumulativeSum","dot","vector2","vector1","mmul","other","Bcolj","Float64Array","s","strassen2x2","a11","b11","a12","b12","a21","b21","a22","b22","m1","m2","m3","m4","m5","c00","c01","c10","c11","strassen3x3","a00","a01","a02","a10","a20","b00","b01","b02","b10","b20","m6","m7","m8","m9","m12","m13","m14","m15","m16","m17","m18","c02","c12","c20","c21","c22","mmulStrassen","r1","c1","r2","c2","embed","mat","c","resultat","console","warn","blockMult","halfRows","parseInt","halfCols","subMatrix","sub","scaleRows","isFinite","scaleColumns","flipRows","middle","ceil","first","last","flipColumns","kroneckerProduct","kroneckerSum","AxI","eye","IxB","transpose","sortRows","compareFunction","compareNumbers","sortColumns","subMatrixRow","subMatrixColumn","selection","rowIndices","columnIndices","checkRowIndices","checkColumnIndices","rowIndex","columnIndex","trace","sumByRow","sumByColumn","sumAll","product","productByRow","productByColumn","productAll","variance","unbiased","sum1","sum2","varianceByRow","varianceByColumn","varianceAll","standardDeviation","center","centerByRow","centerByColumn","centerAll","pow","getScaleByRow","scaleByRow","getScaleByColumn","scaleByColumn","divider","getScaleAll","scaleAll","Symbol","for","rand","randomInt","randInt","diagonal","identity","negate","tensorProduct","nColumns","arrayData","every","element","removeRow","addRow","removeColumn","newRow","addColumn","addS","addM","subS","subM","subtractS","subtractM","mul","mulM","multiply","multiplyS","multiplyM","div","divS","divM","divide","divideS","divideM","mod","modS","modM","modulus","modulusS","modulusM","and","andS","andM","or","orS","orM","xor","xorS","xorM","leftShift","leftShiftS","leftShiftM","signPropagatingRightShift","signPropagatingRightShiftS","signPropagatingRightShiftM","rightShift","rightShiftS","rightShiftM","zeroFillRightShift","zeroFillRightShiftS","zeroFillRightShiftM","not","acos","acosh","asin","asinh","atan","atanh","cbrt","clz32","cos","cosh","expm1","fround","log","log1p","log10","log2","sign","sin","sinh","tan","tanh","trunc","arg0","powS","powM","installMathOperations","WrapperMatrix2D","LuDecomposition","t","LUcolj","kmax","lu","pivotVector","pivotSign","LU","isSingular","solve","X","determinant","lowerTriangularMatrix","upperTriangularMatrix","pivotPermutationVector","hypotenuse","QrDecomposition","qr","rdiag","nrm","QR","Rdiag","isFullRank","orthogonalMatrix","SingularValueDecomposition","computeLeftSingularVectors","computeRightSingularVectors","autoTranspose","wantu","Boolean","wantv","swapped","aux","nu","ni","U","V","work","si","nct","nrt","mrc","pp","iter","eps","EPSILON","kase","alpha","isNaN","ks","f","cs","sn","sp","spm1","epm1","sk","ek","shift","g","Y","threshold","scols","Ls","rightSingularVectors","VL","vrows","urows","VLU","solveForDiagonal","inverse","vcols","ucols","norm2","rank","tol","ii","leftSingularVectors","diagonalMatrix","params","damping","gradientDifference","evaluatedData","gradientFunc","paramFunction","ans","param","auxParams","funcParam","gradientFunction","matrixFunc","matrixFunction","inverseMatrix","useSVD","leftHandSide","rightHandSide","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","initializeFit","optimizeLayout","optimizeLayoutAsync","setSupervisedProjection","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","transform","toTransform","rawData","init","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","sparseMatrix","prodMatrix","simplicialSet","target","unknownDist","intersection","fastIntersection","resetLocalConnectivity","nIter","bandwidth","lo","hi","mid","ithDistances","nonZeroDists","interpolation","psum","meanIthDistances","meanDistances","graphValues","entry","w","state","assign","dim","moveOther","epochsPerNegativeSample","epochOfNextNegativeSample","epochOfNextSample","initialAlpha","gamma","xv","yv","parameterValues","maxIterations","errorTolerance","minValues","maxValues","initialValues","parLen","MAX_SAFE_INTEGER","MIN_SAFE_INTEGER","iteration","converged","parameterError","iterations","findABParams","current","distSquared","rDist","gradCoeff","gradD","clip","nNegSamples","epochCallback","epochCompleted","shouldStop","isFinished","setTimeout","err","clipValue","DimReductionMethods","DistanceMatrix","_data","_size","dataLength","_linearizeIJ","list","square","SparseMatrixService","matSize","minThreshold","getMinimalThreshold","workers","startIdx","endIdx","fullSize","acc","thresholdWorkers","shuffledValues","testSetSizePerWorker","tPromises","sampleLength","cnt","mi","mj","some","Reducer","AvailableReducers","distanceFnArgs","usingSparseMatrix","sparseMatrixThreshold","transferedSparseMatrix","progressFunc","distanceFname","dmIndexFunc","usingDistanceMatrix","preCalculateDistanceMatrix","_encodedDistanceMatrix","bind","_encodedSparseMatrix","_encodedDistance","reducer","parallelDistanceWorkers","time","timeEnd","knnRes","neighbours","insert","distancesAr","indexes","knnIndexes","getKnnGraph","second","fitAsync","epoc","matrixProxy","condensedArray","linearFunc","linearIndex","iNum","jNum","idx1Handler","idx1","_receiver","Proxy","idx2","idx2Handler","distanceMatrixProxy","initDataDist","getSolution","emb","DimensionalityReducer","metric","measure","specOptions","_length","typeName","availableMethods","availableMetrics","obj","epochNum","epochsLength","self","columnData","onMessage","exports","tsne_1","defineProperty","enumerable","TSNE","opt","returnV","vValue","perplexity","getopt","field","defaultval","gaussRandom","u","randn","mu","std","ArrayBuffer","arr","randn2d","uses","xhere","L2","x1","x2","D","x1i","x2i","xtod","N","d2p","nf","hTarget","P","prow","betamin","betamax","beta","done","maxtries","pj","nHere","pOut","N2","initDataRaw","dists","initSolution","gains","ystep","cg","costGrad","cost","grad","ymean","gid","sid","gainid","newgain","newsid","debugGrad","yold","cg0","cg1","analytic","numerical","pmul","quArr","qsum","dsum","dhere","qu","NN","Q","gsum","premult","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","module","__webpack_modules__","__webpack_exports__","O","chunkIds","priority","notFulfilled","fulfilled","definition","o","chunkId","globalThis","Function","window","prop","scriptUrl","importScripts","location","document","currentScript","src","scripts","getElementsByTagName","replace","installedChunks","chunkLoadingGlobal","parentChunkLoadingFunction","moreModules","runtime","pop","then"],"sourceRoot":""}
1
+ {"version":3,"file":"196.js","mappings":"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","sources":["webpack://bio/webpack/runtime/chunk loaded","webpack://bio/webpack/runtime/startup chunk dependencies","webpack://bio/./node_modules/@datagrok-libraries/utils/src/random.js","webpack://bio/./node_modules/@datagrok-libraries/utils/src/vector-operations.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/proxy.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/distance-matrix-service.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/spe.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/typed-metrics/consts.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-metrics-methods.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/typed-metrics/typed-metrics.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/utils.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/heap.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/matrix.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/tree.js","webpack://bio/./node_modules/is-any-array/src/index.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/errorCalculation.js","webpack://bio/./node_modules/ml-matrix/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-rescale/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-max/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-min/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-rescale/lib-es6/index.js","webpack://bio/./node_modules/ml-array-min/lib-es6/index.js","webpack://bio/./node_modules/ml-array-max/lib-es6/index.js","webpack://bio/./node_modules/ml-matrix/src/inspect.js","webpack://bio/./node_modules/ml-matrix/src/util.js","webpack://bio/./node_modules/ml-matrix/src/matrix.js","webpack://bio/./node_modules/ml-matrix/src/stat.js","webpack://bio/./node_modules/ml-matrix/src/mathOperations.js","webpack://bio/./node_modules/ml-matrix/src/wrap/WrapperMatrix2D.js","webpack://bio/./node_modules/ml-matrix/src/dc/lu.js","webpack://bio/./node_modules/ml-matrix/src/dc/util.js","webpack://bio/./node_modules/ml-matrix/src/dc/qr.js","webpack://bio/./node_modules/ml-matrix/src/dc/svd.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/step.js","webpack://bio/./node_modules/ml-matrix/src/decompositions.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/umap.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/nn_descent.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/index.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/reduce-dimensionality.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/distance-matrix.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/sparse-matrix-service.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/knnGraph.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/workers/dimensionality-reducer.js","webpack://bio/./node_modules/@keckelt/tsne/lib/index.js","webpack://bio/./node_modules/@keckelt/tsne/lib/tsne.js","webpack://bio/webpack/bootstrap","webpack://bio/webpack/runtime/define property getters","webpack://bio/webpack/runtime/ensure chunk","webpack://bio/webpack/runtime/get javascript chunk filename","webpack://bio/webpack/runtime/global","webpack://bio/webpack/runtime/hasOwnProperty shorthand","webpack://bio/webpack/runtime/publicPath","webpack://bio/webpack/runtime/importScripts chunk loading","webpack://bio/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var next = __webpack_require__.x;\n__webpack_require__.x = () => {\n\treturn Promise.all([\n\t\t__webpack_require__.e(1),\n\t\t__webpack_require__.e(172)\n\t]).then(next);\n};","/**\n * Generates single random float from 0 to range.\n *\n * @export\n * @param {number} range Max generating value.\n * @return {number} A random float generated.\n */\nexport function randomFloat(range) {\n return Math.random() * range;\n}\n/**\n * Generates single random integer from 0 to range.\n *\n * @export\n * @param {number} range Max generating value.\n * @return {number} A random integer generated.\n */\nexport function randomInt(range) {\n return Math.floor(randomFloat(range));\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZG9tLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmFuZG9tLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBYTtJQUN2QyxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFDL0IsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsS0FBYTtJQUNyQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDeEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVzIHNpbmdsZSByYW5kb20gZmxvYXQgZnJvbSAwIHRvIHJhbmdlLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSByYW5nZSBNYXggZ2VuZXJhdGluZyB2YWx1ZS5cbiAqIEByZXR1cm4ge251bWJlcn0gQSByYW5kb20gZmxvYXQgZ2VuZXJhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tRmxvYXQocmFuZ2U6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLnJhbmRvbSgpICogcmFuZ2U7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHNpbmdsZSByYW5kb20gaW50ZWdlciBmcm9tIDAgdG8gcmFuZ2UuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHJhbmdlIE1heCBnZW5lcmF0aW5nIHZhbHVlLlxuICogQHJldHVybiB7bnVtYmVyfSBBIHJhbmRvbSBpbnRlZ2VyIGdlbmVyYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbUludChyYW5nZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IocmFuZG9tRmxvYXQocmFuZ2UpKTtcbn1cbiJdfQ==","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 */\nfunction 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 const diff = vectorAdd(p, q, -1);\n const sqdiff = vectorSquare(diff);\n const sqdiffSumm = itemsSum(sqdiff);\n return Math.sqrt(sqdiffSumm);\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 * @param {Vector} data numerical array\n */\nexport function normalize(data) {\n let mean = 0;\n let std = 0;\n for (let i = 0; i < data.length; ++i)\n mean += data[i];\n mean /= data.length;\n for (let i = 0; i < data.length; ++i)\n std += (data[i] - mean) * (data[i] - mean);\n std = Math.sqrt(std / data.length);\n for (let i = 0; i < data.length; ++i)\n data[i] = (data[i] - mean) / std;\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yLW9wZXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ2ZWN0b3Itb3BlcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVMsTUFBTSxFQUF1QyxNQUFNLHFCQUFxQixDQUFDO0FBQ3pGLE9BQU8sRUFBQyxXQUFXLEVBQUUsU0FBUyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBRWhEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLFlBQXFCLEtBQUssRUFBRSxVQUFrQixrQkFBa0I7SUFDckYsSUFBSSxDQUFDLFNBQVM7UUFDWixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsZUFBZSxDQUFDLFVBQWtCLEVBQUUsVUFBa0IsRUFBRSxPQUFlLENBQUM7SUFDL0UsT0FBTyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6RixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsTUFBYztJQUM1QyxPQUFPLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1NBQ3ZDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1B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QUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0FBQ3JFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge01hdHJpeCwgVmVjdG9yLCBDb29yZGluYXRlcywgVmVjdG9ycywgRGlzdGFuY2VNZXRyaWN9IGZyb20gJy4vdHlwZS1kZWNsYXJhdGlvbnMnO1xuaW1wb3J0IHtyYW5kb21GbG9hdCwgcmFuZG9tSW50fSBmcm9tICcuL3JhbmRvbSc7XG5cbi8qKlxuICogQXNzZXJ0cyBhIGNvbmRpdGlvbiBieSB0aHJvd2luZyBhbiBFcnJvci5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtjb25kaXRpb249ZmFsc2VdIENvbmRpdGlvbiB0byBhc3NlcnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2U9J0Fzc2VydGlvbiBlcnJvci4nXSBNZXNzYWdlIHRvIG91dHB1dC5cbiAqIEB0aHJvd3Mge0Vycm9yfVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0KGNvbmRpdGlvbjogYm9vbGVhbiA9IGZhbHNlLCBtZXNzYWdlOiBzdHJpbmcgPSAnQXNzZXJ0aW9uIGVycm9yLicpIHtcbiAgaWYgKCFjb25kaXRpb24pXG4gICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgbmV3IHR3by1kaW1lbnNpb25hbCBhcnJheSBhbmQgZmlsbHMgaXQgd2l0aCB0aGUgdmFsdWUgZ2l2ZW4uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGRpbWVuc2lvbjEgVGhlIGZpcnN0IGRpbWVuc2lvbiBvZiB0aGUgY29vcmRpbmF0ZXMgKG51bWJlciBvZiByb3dzKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkaW1lbnNpb24yIFRoZSBzZWNvbmQgZGltZW5zaW9uIG9mIHRoZSBjb29yZGluYXRlcyAobnVtYmVyIG9mIGNvbHVtbnMpLlxuICogQHBhcmFtIHtudW1iZXJ9IFtmaWxsPTBdIEEgdmFsdWUgdG8gZmlsbCB0aGUgY29vcmRpbmF0ZXMgd2l0aC5cbiAqIEByZXR1cm4ge0Nvb3JkaW5hdGVzfSBBIHR3by1kaW1lbnNpb25hbCBmaWxsZWQgd2l0aCB0aGUgdmFsdWUgZ2l2ZW4uXG4gKiBAdG9kbyBNaWdodCBiZSBzbG93IHNpbmNlIHVzZWQgQXJyYXkubWFwLiBQcm9iYWJseSBuZWVkcyBwZXJmb3JtYW5jZSByZXZpc2lvbi5cbiAqL1xuZnVuY3Rpb24gaW5pdENvb3JkaW5hdGVzKGRpbWVuc2lvbjE6IG51bWJlciwgZGltZW5zaW9uMjogbnVtYmVyLCBmaWxsOiBudW1iZXIgPSAwKTogQ29vcmRpbmF0ZXMge1xuICByZXR1cm4gbmV3IEFycmF5KGRpbWVuc2lvbjEpLmZpbGwoZmlsbCkubWFwKCgpID0+IChuZXcgVmVjdG9yKGRpbWVuc2lvbjIpLmZpbGwoZmlsbCkpKTtcbn1cblxuLyoqXG4gKiBUcmFuc3Bvc2UgbWF0cml4LlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7TWF0cml4fSBtYXRyaXggVGhlIG1hdHJpeCB0byBiZSB0cmFuc3Bvc2VkLlxuICogQHJldHVybiB7TWF0cml4fSBUcmFuc3Bvc2VkIG1hdHJpeC5cbiAqIEB0b2RvIE1pZ2h0IGJlIHNsb3cgc2luY2UgdXNlZCBBcnJheS5tYXAuIFByb2JhYmx5IG5lZWRzIHBlcmZvcm1hbmNlIHJldmlzaW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNwb3NlTWF0cml4KG1hdHJpeDogTWF0cml4KTogTWF0cml4IHtcbiAgcmV0dXJuIG5ldyBBcnJheShtYXRyaXhbMF0ubGVuZ3RoKS5maWxsKDApXG4gICAgLm1hcCgoXywgaSkgPT4gKG5ldyBWZWN0b3IobWF0cml4Lmxlbmd0aCkuZmlsbCgwKS5tYXAoKF8sIGopID0+IChtYXRyaXhbal1baV0pKSkpO1xufVxuXG4vKipcbiAqIEFkZHMgdHdvIHZlY3RvcnMgd2l0aCB0aGUgc2Vjb25kIG9uZSB0byBiZSBtdWx0aXBsaWVkIGJ5IHRoZSBnaXZlbiByYXRpby5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3Rvcn0gcCBUaGUgZmlyc3QgdmVjdG9yIHRvIGFkZC5cbiAqIEBwYXJhbSB7VmVjdG9yfSBxIFRoZSBzZWNvbmQgdmVjdG9yIHRvIGFkZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbXVsdGlwbGllcj0xXSBBIG11bHRpcGxpZXIgdG8gYmUgdXNlZCBiZWZvcmUgdGhlIHNlY29uZCB2ZWN0b3IgaXMgYWRkZWQuXG4gKiBAcmV0dXJuIHtWZWN0b3J9IE5ldyB2ZWN0b3IgY29udGFpbmVkIHRoZSByZXN1bHQgb2Ygb3BlcmF0aW9uIHArbXVsdGlwbGllcipxLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVjdG9yQWRkKHA6IFZlY3RvciwgcTogVmVjdG9yLCBtdWx0aXBsaWVyOiBudW1iZXIgPSAxKTogVmVjdG9yIHtcbiAgY29uc3Qgbkl0ZW1zID0gcC5sZW5ndGg7XG5cbiAgYXNzZXJ0KG5JdGVtcyA9PSBxLmxlbmd0aCwgJ1ZlY3RvciBsZW5ndGhzIGRvIG5vdCBtYXRjaC4nKTtcblxuICBjb25zdCB0b3RhbCA9IG5ldyBWZWN0b3Iobkl0ZW1zKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHAubGVuZ3RoOyArK2kpXG4gICAgdG90YWxbaV0gPSBwW2ldICsgbXVsdGlwbGllciAqIHFbaV07XG5cbiAgcmV0dXJuIHRvdGFsO1xufVxuXG4vKipcbiAqIFN1bXMgdGhlIHZlY3RvcidzIGl0ZW1zLlxuICpcbiAqIEBwYXJhbSB7VmVjdG9yfSB2IFRoZSB2ZWN0b3IgdG8gYmUgc3VtbWVkLlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgdmVjdG9yJ3MgaXRlbXMgc3VtLlxuICovXG5mdW5jdGlvbiBpdGVtc1N1bSh2OiBWZWN0b3IpOiBudW1iZXIge1xuICBsZXQgdG90YWwgPSAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdi5sZW5ndGg7ICsraSlcbiAgICB0b3RhbCArPSB2W2ldO1xuXG4gIHJldHVybiB0b3RhbDtcbn1cblxuLyoqXG4gKiBTdXFhcmVzIHRoZSB2ZWN0b3IncyBpdGVtcy5cbiAqXG4gKiBAcGFyYW0ge1ZlY3Rvcn0gdiBUaGUgdmVjdG9yIHRvIHNxdWFyZS5cbiAqIEByZXR1cm4ge1ZlY3Rvcn0gQSBuZXcgdmVjdG9yIGNvbnRhaW5pbmcgdGhlIG9yaWdpbmFsJ3MgaXRlbXMgc3F1YXJlZC5cbiAqL1xuZnVuY3Rpb24gdmVjdG9yU3F1YXJlKHY6IFZlY3Rvcik6IFZlY3RvciB7XG4gIGNvbnN0IG5JdGVtcyA9IHYubGVuZ3RoO1xuICBjb25zdCB0b3RhbCA9IG5ldyBWZWN0b3Iobkl0ZW1zKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHYubGVuZ3RoOyArK2kpXG4gICAgdG90YWxbaV0gPSB2W2ldICogdltpXTtcblxuICByZXR1cm4gdG90YWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2ZWN0b3JMZW5ndGgodjogVmVjdG9yKTogbnVtYmVyIHtcbiAgbGV0IHNxclN1bTogbnVtYmVyID0gMDtcbiAgZm9yIChsZXQgaTogbnVtYmVyID0gMDsgaSA8IHYubGVuZ3RoOyBpKyspXG4gICAgc3FyU3VtICs9IHZbaV0gKiB2W2ldO1xuICByZXR1cm4gTWF0aC5zcXJ0KHNxclN1bSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2ZWN0b3JEb3RQcm9kdWN0KHYxOiBWZWN0b3IsIHYyOiBWZWN0b3IpOiBudW1iZXIge1xuICBpZiAodjEubGVuZ3RoICE9IHYyLmxlbmd0aClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBkaW1lbnNpb25hbGl0eSBvZiB0aGUgdmVjdG9ycyBtdXN0IG1hdGNoJyk7XG4gIGxldCBwcm9kOiBudW1iZXIgPSAwO1xuICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgdjEubGVuZ3RoOyBpKyspXG4gICAgcHJvZCArPSB2MVtpXSAqIHYyW2ldO1xuICByZXR1cm4gcHJvZDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZpbGxlZCB3aXRoIHJhbmRvbSBmbG9hdGluZyBwb2ludCB2YWx1ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IGRpbWVuc2lvbjEgVGhlIGZpcnN0IGRpbWVuc2lvbiBvZiB0aGUgbWF0cml4LlxuICogQHBhcmFtIHtudW1iZXJ9IGRpbWVuc2lvbjIgVGhlIHNlY29uZCBkaW1lbnNpb24gb2YgdGhlIG1hdHJpeC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2NhbGU9MS5dIE1heCB2YWx1ZSBnaXZlbiBieSByYW5kb20gZ2VuZXJhdG9yLlxuICogQHJldHVybiB7TWF0cml4fSBBIG5ldyBtYXRyaXggZmlsbGVkIHdpdGggcmFuZG9tIGZsb2F0aW5nIHBvaW50ICB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWxsUmFuZG9tTWF0cml4KGRpbWVuc2lvbjE6IG51bWJlciwgZGltZW5zaW9uMjogbnVtYmVyLCBzY2FsZTogbnVtYmVyID0gMS4pOiBNYXRyaXgge1xuICBjb25zdCBtYXRyaXggPSBpbml0Q29vcmRpbmF0ZXMoZGltZW5zaW9uMSwgZGltZW5zaW9uMik7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1lbnNpb24xOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGRpbWVuc2lvbjI7ICsrailcbiAgICAgIG1hdHJpeFtpXVtqXSA9IHJhbmRvbUZsb2F0KHNjYWxlKTtcbiAgfVxuICByZXR1cm4gbWF0cml4O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgRXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3J9IHAgVGhlIGZpcnN0IHZlY3Rvci5cbiAqIEBwYXJhbSB7VmVjdG9yfSBxIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBFdWNsaWRlYW4gZGlzdGFuY2UgYmV0d2VlbiB0aGUgZ2l2ZW4gdmVjdG9ycy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlKHA6IFZlY3RvciwgcTogVmVjdG9yKTogbnVtYmVyIHtcbiAgY29uc3QgZGlmZiA9IHZlY3RvckFkZChwLCBxLCAtMSk7XG4gIGNvbnN0IHNxZGlmZiA9IHZlY3RvclNxdWFyZShkaWZmKTtcbiAgY29uc3Qgc3FkaWZmU3VtbSA9IGl0ZW1zU3VtKHNxZGlmZik7XG4gIHJldHVybiBNYXRoLnNxcnQoc3FkaWZmU3VtbSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRpc3RhbmNlIG1hdHJpeCB1c2luZyBhIGN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3RvcnN9IGRhdGEgSW5wdXQgdmVjdG9ycyB0byBjYWxjdWxhdGUgZGlzdGFuY2VzLlxuICogQHBhcmFtIHtEaXN0YW5jZU1ldHJpY30gZGlzdGFuY2UgQ3VzdG9tIGRpc3RhbmNlIGZ1bmN0aW9uLlxuICogQHJldHVybiB7TWF0cml4fSBDYWxjdWxhdGVkIGN1c3RvbSBkaXN0YW5jZSBtYXRyaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjRGlzdGFuY2VNYXRyaXgoZGF0YTogVmVjdG9ycywgZGlzdGFuY2U6IERpc3RhbmNlTWV0cmljKTogTWF0cml4IHtcbiAgY29uc3Qgbkl0ZW1zID0gZGF0YS5sZW5ndGg7XG4gIGNvbnN0IG1hdHJpeCA9IGluaXRDb29yZGluYXRlcyhuSXRlbXMsIG5JdGVtcywgMCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuSXRlbXM7ICsraSkge1xuICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IG5JdGVtczsgKytqKSB7XG4gICAgICBjb25zdCBkOiBudW1iZXIgPSAoZGF0YVtpXSA9PSBudWxsKSB8fCAoZGF0YVtqXSA9PSBudWxsKSA/IDAgOiBkaXN0YW5jZShkYXRhW2ldLCBkYXRhW2pdKTtcbiAgICAgIG1hdHJpeFtpXVtqXSA9IG1hdHJpeFtqXVtpXSA9IGQ7XG4gICAgfVxuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRpc3RhbmNlIG1hdHJpeCB1c2luZyBhIGN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3RvcnN9IGRhdGEgSW5wdXQgdmVjdG9ycyB0byBjYWxjdWxhdGUgZGlzdGFuY2VzLlxuICogQHBhcmFtIHtEaXN0YW5jZU1ldHJpY30gZGlzdGFuY2UgQ3VzdG9tIGRpc3RhbmNlIGZ1bmN0aW9uLlxuICogQHJldHVybiB7TWF0cml4fSBDYWxjdWxhdGVkIGN1c3RvbSBkaXN0YW5jZSBtYXRyaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjTm9ybWFsaXplZERpc3RhbmNlTWF0cml4KGRhdGE6IFZlY3RvcnMsIGRpc3RhbmNlOiBEaXN0YW5jZU1ldHJpYyk6IE1hdHJpeCB7XG4gIGNvbnN0IG5JdGVtcyA9IGRhdGEubGVuZ3RoO1xuICBjb25zdCBtYXRyaXggPSBpbml0Q29vcmRpbmF0ZXMobkl0ZW1zLCBuSXRlbXMsIDApO1xuICBsZXQgbWF4ID0gTnVtYmVyLk1JTl9WQUxVRTtcbiAgbGV0IG1pbiA9IE51bWJlci5NQVhfVkFMVUU7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gaTsgaiA8IG5JdGVtczsgKytqKSB7XG4gICAgICBjb25zdCBkOiBudW1iZXIgPSAoZGF0YVtpXSA9PSBudWxsKSB8fCAoZGF0YVtqXSA9PSBudWxsIHx8IGkgPT09IGopID8gMCA6IGRpc3RhbmNlKGRhdGFbaV0sIGRhdGFbal0pO1xuICAgICAgbWF0cml4W2ldW2pdID0gbWF0cml4W2pdW2ldID0gZDtcbiAgICAgIGlmIChkID4gbWF4KSBtYXggPSBkO1xuICAgICAgaWYgKGQgPCBtaW4pIG1pbiA9IGQ7XG4gICAgfVxuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBuSXRlbXM7ICsrailcbiAgICAgIG1hdHJpeFtpXVtqXSA9IG1hdHJpeFtqXVtpXSA9IChtYXRyaXhbaV1bal0gLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gIH1cbiAgcmV0dXJuIG1hdHJpeDtcbn1cblxuLyoqIEdlbmVyYXRlcyBhcnJheSBmcm9tIGEgcmFuZ2UgW2JlZ2luOyBlbmRdIG9yIFtiZWdpbjsgZW5kKSBpZiBlbmRFeGNsdXNpdmUuICoqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlblJhbmdlKGJlZ2luOiBudW1iZXIsIGVuZDogbnVtYmVyLCBlbmRFeGNsdXNpdmUgPSBmYWxzZSk6IEludDMyQXJyYXkge1xuICBjb25zdCBuSXRlbXMgPSBlbmQgLSBiZWdpbiArIChlbmRFeGNsdXNpdmUgPyAwIDogMSk7XG4gIGNvbnN0IHNlcmllcyA9IG5ldyBJbnQzMkFycmF5KG5JdGVtcyk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuSXRlbXM7ICsraSlcbiAgICBzZXJpZXNbaV0gPSBiZWdpbiArIGk7XG5cbiAgcmV0dXJuIHNlcmllcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIG9yZGVyIG9mIHZhbHVlcyBhcyBpZiB0aGV5IGFyZSBzb3J0ZWQuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHthbnlbXX0gdmFsdWVzIElucHV0IGFycmF5LlxuICogQHBhcmFtIHtib29sZWFufSBbcmV2ZXJzZT1mYWxzZV0gV2hldGhlciB0byByZXR1cm4gcmV2ZXJzZWQgb3JkZXIuXG4gKiBAcmV0dXJuIHtudW1iZXJbXX0gVGhlIG9yZGVyIGNvbXB1dGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXJnU29ydCh2YWx1ZXM6IGFueVtdLCByZXZlcnNlID0gZmFsc2UpOiBudW1iZXJbXSB7XG4gIGNvbnN0IHNvcnRmbiA9IHJldmVyc2UgPyAoYTogYW55W10sIGI6IGFueVtdKSA9PiAoYlswXSAtIGFbMF0pIDogKGE6IGFueVtdLCBiOiBhbnlbXSkgPT4gKGFbMF0gLSBiWzBdKTtcbiAgY29uc3QgZGVjb3IgPSAodjogYW55LCBpOiBudW1iZXIpID0+IFt2LCBpXTsgLy8gc2V0IGluZGV4IHRvIHZhbHVlXG4gIGNvbnN0IHVuZGVjb3IgPSAoYTogYW55W10pID0+IGFbMV07IC8vIGxlYXZlIG9ubHkgaW5kZXhcbiAgY29uc3QgX2FyZ3NvcnQgPSAoYXJyOiBhbnlbXSkgPT4gYXJyLm1hcChkZWNvcikuc29ydChzb3J0Zm4pLm1hcCh1bmRlY29yKTtcbiAgcmV0dXJuIF9hcmdzb3J0KHZhbHVlcyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgaW5kZXhlcyBvZiB0aGUgbW9zdCBkaXZlcnNlIG9iamVjdHMgYWNjb3JkaW5nIHRvIHRoZSBkaXN0IGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIHRvdGFsIG51bWJlciBvZiBvYmplY3RzXG4gKiBAcGFyYW0ge251bWJlcn0gbiBudW1iZXIgb2YgZGl2ZXJzZSBlbGVtZW50cyB0byBmaW5kXG4gKiBAcGFyYW0geyhpMTogbnVtYmVyLCBpMjogbnVtYmVyKSA9PiBudW1iZXJ9IGRpc3QgYSBmdW5jdGlvbiB3aGljaCBjYWxjdWxhdGVzIGRpc3RhbmNlIGJldHdlZW5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0d28gb2JqZWN0cyB1c2luZyB0aGVpciBpbmRleGVzXG4gKiBAcmV0dXJucyB7bnVtYmVyW119IFRoZSBpbmRleGVzIG9mIHRoZSBtb3N0IGRpdmVyc2Ugb2JqZWN0c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGl2ZXJzZVN1YnNldChsZW5ndGg6IG51bWJlciwgbjogbnVtYmVyLCBkaXN0OiAoaTE6IG51bWJlciwgaTI6IG51bWJlcikgPT4gbnVtYmVyKTogbnVtYmVyW10ge1xuICBmdW5jdGlvbiBtYXhCeSh2YWx1ZXM6IEl0ZXJhYmxlSXRlcmF0b3I8bnVtYmVyPiwgb3JkZXJCeTogKGk6IG51bWJlcikgPT4gbnVtYmVyKSB7XG4gICAgbGV0IG1heFZhbHVlID0gbnVsbDtcbiAgICBsZXQgbWF4T3JkZXJCeSA9IG51bGw7XG5cbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgdmFsdWVzKSB7XG4gICAgICBjb25zdCBlbGVtZW50T3JkZXJCeSA9IG9yZGVyQnkoZWxlbWVudCk7XG4gICAgICBpZiAobWF4T3JkZXJCeSA9PSBudWxsIHx8IGVsZW1lbnRPcmRlckJ5ID4gbWF4T3JkZXJCeSkge1xuICAgICAgICBtYXhWYWx1ZSA9IGVsZW1lbnQ7XG4gICAgICAgIG1heE9yZGVyQnkgPSBlbGVtZW50T3JkZXJCeTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1heFZhbHVlO1xuICB9XG5cbiAgY29uc3Qgc3Vic2V0ID0gW3JhbmRvbUludChsZW5ndGggLSAxKV07XG4gIGNvbnN0IGNvbXBsZW1lbnQgPSBuZXcgU2V0KCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICghc3Vic2V0LmluY2x1ZGVzKGkpKVxuICAgICAgY29tcGxlbWVudC5hZGQoaSk7XG4gIH1cblxuICB3aGlsZSAoc3Vic2V0Lmxlbmd0aCA8IG4pIHtcbiAgICBjb25zdCBpZHggPSBtYXhCeShcbiAgICAgIGNvbXBsZW1lbnQudmFsdWVzKCkgYXMgSXRlcmFibGVJdGVyYXRvcjxudW1iZXI+LFxuICAgICAgKGkpID0+IE1hdGgubWluLmFwcGx5KE1hdGgsIHN1YnNldC5tYXAoZnVuY3Rpb24odmFsLCBpbmRleCkge1xuICAgICAgICByZXR1cm4gZGlzdChpLCB2YWwpO1xuICAgICAgfSkpKTtcbiAgICBpZiAoaWR4KSB7XG4gICAgICBzdWJzZXQucHVzaChpZHgpO1xuICAgICAgY29tcGxlbWVudC5kZWxldGUoaWR4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN1YnNldDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIG5vcm1hbGl6ZWQgdmVjdG9yXG4gKiBAcGFyYW0ge1ZlY3Rvcn0gZGF0YSBudW1lcmljYWwgYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShkYXRhOiBWZWN0b3IpOiBWZWN0b3Ige1xuICBsZXQgbWVhbiA9IDA7XG4gIGxldCBzdGQgPSAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSlcbiAgICBtZWFuICs9IGRhdGFbaV07XG5cbiAgbWVhbiAvPSBkYXRhLmxlbmd0aDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpXG4gICAgc3RkICs9IChkYXRhW2ldIC0gbWVhbikgKiAoZGF0YVtpXSAtIG1lYW4pO1xuXG4gIHN0ZCA9IE1hdGguc3FydChzdGQgLyBkYXRhLmxlbmd0aCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgKytpKVxuICAgIGRhdGFbaV0gPSAoZGF0YVtpXSAtIG1lYW4pIC8gc3RkO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG4vKipcbiAqIEZpbmRzIHNldCBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIGxpc3RzLlxuICogQHBhcmFtIHthbnlbXX0gYSBUaGUgZmlyc3QgbGlzdC5cbiAqIEBwYXJhbSB7YW55W119IGIgVGhlIHNlY29uZCBsaXN0LlxuICogQHJldHVybiB7YW55W119XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXREaWZmZXJlbmNlKGE6IGFueVtdLCBiOiBhbnlbXSk6IGFueVtdIHtcbiAgY29uc3QgYlNldCA9IG5ldyBTZXQoYik7XG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoYS5maWx0ZXIoKHgpID0+ICFiU2V0Lmhhcyh4KSkpLnZhbHVlcygpKTtcbn1cbiJdfQ==","/** 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=","export 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 new Promise(async (resolve, reject) => {\n try {\n const len = values.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, fnName, startRow, startCol, chunckSize: end - start, opts });\n promises[i] = new Promise((resolveWorker, rejectWorker) => {\n this._workers[i].onmessage = ({ data: { error, distanceMatrixData, min, max } }) => {\n this._terminateOnComplete && 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWF0cml4LXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkaXN0YW5jZS1tYXRyaXgtc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLE9BQU8scUJBQXFCO0lBSTlCLFlBQW1CLG9CQUFvQixHQUFHLElBQUksRUFBRSxtQkFBbUIsR0FBRyxJQUFJO1FBQ3hFLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQztRQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ3BELEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQywwQkFBMEIsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsbUJBQW1CLENBQUM7SUFDbEQsQ0FBQztJQUFBLENBQUM7SUFFSyxLQUFLLENBQUMsSUFBSSxDQUFJLE1BQStCLEVBQUUsTUFBb0IsRUFDeEUsU0FBUyxHQUFHLElBQUksRUFBRSxJQUF5QjtRQUMzQyxPQUFPLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDM0MsSUFBSTtnQkFDRixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO2dCQUMxQixNQUFNLFFBQVEsR0FBRyxJQUFJLEtBQUssQ0FBZ0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUM3RCxNQUFNLFdBQVcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsa0NBQWtDO2dCQUMzRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDN0QsTUFBTSxTQUFTLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7Z0JBQ2xELE1BQU0sY0FBYyxHQUFHLElBQUksWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUNyRCxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBQ2YsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO2dCQUNmLDJCQUEyQjtnQkFDM0IsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO2dCQUNiLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7Z0JBQzVCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUMxQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQztvQkFDeEMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDO29CQUMxRixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUM7b0JBQ3hCLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQztvQkFDeEIsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLEVBQUU7d0JBQy9CLDZFQUE2RTt3QkFDN0UsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQzt3QkFDdkYsTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7cUJBQzNFO29CQUNELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEVBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxHQUFHLEdBQUcsS0FBSyxFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7b0JBQ2xHLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxDQUFDLGFBQWEsRUFBRSxZQUFZLEVBQUUsRUFBRTt3QkFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxFQUFDLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFDLEVBQUMsRUFBUSxFQUFFOzRCQUNuRixJQUFJLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQzs0QkFDMUQsSUFBSSxLQUFLLEVBQUU7Z0NBQ1QsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDOzZCQUNyQjtpQ0FBTTtnQ0FDTCxjQUFjLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxDQUFDO2dDQUM5QyxJQUFJLEdBQUcsR0FBRyxJQUFJO29DQUNaLElBQUksR0FBRyxHQUFHLENBQUM7Z0NBQ2IsSUFBSSxHQUFHLEdBQUcsSUFBSTtvQ0FDWixJQUFJLEdBQUcsR0FBRyxDQUFDO2dDQUNiLGFBQWEsRUFBRSxDQUFDOzZCQUNqQjt3QkFDSCxDQUFDLENBQUM7b0JBQ0osQ0FBQyxDQUFDLENBQUM7aUJBQ0o7Z0JBQ0QsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM1QixJQUFJLFNBQVM7b0JBQ1gsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4RyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7YUFDekI7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDWDtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFNBQVM7UUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtLbm93bk1ldHJpY3N9IGZyb20gJy4uL3R5cGVkLW1ldHJpY3MnO1xuXG5leHBvcnQgY2xhc3MgRGlzdGFuY2VNYXRyaXhTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF93b3JrZXJzOiBXb3JrZXJbXTtcbiAgICBwcml2YXRlIF93b3JrZXJDb3VudDogbnVtYmVyO1xuICAgIHByaXZhdGUgX3Rlcm1pbmF0ZU9uQ29tcGxldGU6IGJvb2xlYW47XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHVzZUNvbmN1cnJlbnRXb3JrZXJzID0gdHJ1ZSwgdGVybWluYXRlT25Db21wbGV0ZSA9IHRydWUpIHtcbiAgICAgIGNvbnN0IHRocmVhZENvdW50ID0gbmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3k7XG4gICAgICB0aGlzLl93b3JrZXJDb3VudCA9IHVzZUNvbmN1cnJlbnRXb3JrZXJzID8gTWF0aC5tYXgodGhyZWFkQ291bnQgLSAyLCAxKSA6IDE7XG4gICAgICB0aGlzLl93b3JrZXJzID0gbmV3IEFycmF5KHRoaXMuX3dvcmtlckNvdW50KS5maWxsKG51bGwpXG4gICAgICAgIC5tYXAoKCkgPT4gbmV3IFdvcmtlcihuZXcgVVJMKCcuL2Rpc3RhbmNlLW1hdHJpeC13b3JrZXInLCBpbXBvcnQubWV0YS51cmwpKSk7XG4gICAgICB0aGlzLl90ZXJtaW5hdGVPbkNvbXBsZXRlID0gdGVybWluYXRlT25Db21wbGV0ZTtcbiAgICB9O1xuXG4gICAgcHVibGljIGFzeW5jIGNhbGM8VD4odmFsdWVzOiBBcnJheTxUPiB8IEFycmF5TGlrZTxUPiwgZm5OYW1lOiBLbm93bk1ldHJpY3MsXG4gICAgICBub3JtYWxpemUgPSB0cnVlLCBvcHRzPzoge1tfOiBzdHJpbmddOiBhbnl9KTogUHJvbWlzZTxGbG9hdDMyQXJyYXk+IHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgbGVuID0gdmFsdWVzLmxlbmd0aDtcbiAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHZvaWQ+Pih0aGlzLl93b3JrZXJDb3VudCk7XG4gICAgICAgICAgY29uc3QgdG90YWxMZW5ndGggPSBsZW4gKiAobGVuIC0gMSkgLyAyOyAvLyBzaXplIG9mIHJlZHVjZWQgZGlzdGFuY2UgbWF0cml4XG4gICAgICAgICAgdGhpcy5fd29ya2VyQ291bnQgPSBNYXRoLm1pbih0aGlzLl93b3JrZXJDb3VudCwgdG90YWxMZW5ndGgpO1xuICAgICAgICAgIGNvbnN0IGNodW5rU2l6ZSA9IHRvdGFsTGVuZ3RoIC8gdGhpcy5fd29ya2VyQ291bnQ7XG4gICAgICAgICAgY29uc3QgZGlzdGFuY2VNYXRyaXggPSBuZXcgRmxvYXQzMkFycmF5KHRvdGFsTGVuZ3RoKTtcbiAgICAgICAgICBsZXQgZW5kUm93ID0gMDtcbiAgICAgICAgICBsZXQgZW5kQ29sID0gMTtcbiAgICAgICAgICAvLyBtaW5tYXggZm9yIG5vcm1hbGl6YXRpb25cbiAgICAgICAgICBsZXQgbG1pbiA9IDA7XG4gICAgICAgICAgbGV0IGxtYXggPSBOdW1iZXIuTUlOX1ZBTFVFO1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fd29ya2VyQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSBNYXRoLmZsb29yKGkgKiBjaHVua1NpemUpO1xuICAgICAgICAgICAgY29uc3QgZW5kID0gKGkgPT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSkgPyB0b3RhbExlbmd0aCA6IE1hdGguZmxvb3IoKGkgKyAxKSAqIGNodW5rU2l6ZSk7XG4gICAgICAgICAgICBjb25zdCBzdGFydFJvdyA9IGVuZFJvdztcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0Q29sID0gZW5kQ29sO1xuICAgICAgICAgICAgaWYgKGkgIT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSkge1xuICAgICAgICAgICAgICAvLyBUaGVzZSBmb3JtdWxhcyBtYXAgdGhlIGxpbmVhciBpbmRleCB0byB0aGUgdXBwZXIgdHJpYW5ndWxhciBtYXRyaXggaW5kaWNlc1xuICAgICAgICAgICAgICBlbmRSb3cgPSBsZW4gLSAyIC0gTWF0aC5mbG9vcihNYXRoLnNxcnQoLTggKiBlbmQgKyA0ICogbGVuICogKGxlbiAtIDEpIC0gNykgLyAyIC0gMC41KTtcbiAgICAgICAgICAgICAgZW5kQ29sID0gZW5kIC0gbGVuICogZW5kUm93ICsgTWF0aC5mbG9vcigoZW5kUm93ICsgMSkgKiAoZW5kUm93ICsgMikgLyAyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3dvcmtlcnNbaV0ucG9zdE1lc3NhZ2Uoe3ZhbHVlcywgZm5OYW1lLCBzdGFydFJvdywgc3RhcnRDb2wsIGNodW5ja1NpemU6IGVuZCAtIHN0YXJ0LCBvcHRzfSk7XG4gICAgICAgICAgICBwcm9taXNlc1tpXSA9IG5ldyBQcm9taXNlKChyZXNvbHZlV29ya2VyLCByZWplY3RXb3JrZXIpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5fd29ya2Vyc1tpXS5vbm1lc3NhZ2UgPSAoe2RhdGE6IHtlcnJvciwgZGlzdGFuY2VNYXRyaXhEYXRhLCBtaW4sIG1heH19KTogdm9pZCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGVybWluYXRlT25Db21wbGV0ZSAmJiB0aGlzLl93b3JrZXJzW2ldLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgcmVqZWN0V29ya2VyKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgZGlzdGFuY2VNYXRyaXguc2V0KGRpc3RhbmNlTWF0cml4RGF0YSwgc3RhcnQpO1xuICAgICAgICAgICAgICAgICAgaWYgKG1pbiA8IGxtaW4pXG4gICAgICAgICAgICAgICAgICAgIGxtaW4gPSBtaW47XG4gICAgICAgICAgICAgICAgICBpZiAobWF4ID4gbG1heClcbiAgICAgICAgICAgICAgICAgICAgbG1heCA9IG1heDtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmVXb3JrZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgICAgIGlmIChub3JtYWxpemUpXG4gICAgICAgICAgICBkaXN0YW5jZU1hdHJpeC5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHsgZGlzdGFuY2VNYXRyaXhbaW5kZXhdID0gKHZhbHVlIC0gbG1pbikgLyAobG1heCAtIGxtaW4pOyB9KTtcbiAgICAgICAgICByZXNvbHZlKGRpc3RhbmNlTWF0cml4KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHRlcm1pbmF0ZSgpOiB2b2lkIHtcbiAgICAgIHRoaXMuX3dvcmtlcnMuZm9yRWFjaCgod29ya2VyKSA9PiB3b3JrZXIudGVybWluYXRlKCkpO1xuICAgIH1cbn1cbiJdfQ==","import { calculateEuclideanDistance, fillRandomMatrix, vectorAdd, } from '@datagrok-libraries/utils/src/vector-operations';\nimport { randomInt } from '@datagrok-libraries/utils/src/random';\nimport { DistanceMatrixService, dmLinearIndex } from './distance-matrix';\n/**\n * Implements stochastic proximity embedding.\n *\n * @export\n * @class SPEBase\n * @link doi:10.1016/S1093-3263(03)00155-4\n */\nclass SPEBase {\n /**\n * Creates an instance of SPEBase.\n * @param {Options} [options] Options to pass to the constructor.\n * @memberof SPEBase\n */\n constructor(options) {\n this.steps = options?.steps ?? 0;\n this.cycles = options?.cycles ?? 1e6;\n // Select a cutoff distance {cutoff} and ...\n this.cutoff = options?.cutoff ?? 0;\n // ... an initial learning rate {lambda} > 0\n this.lambda = options?.lambda ?? 2.0;\n this.dlambda = options?.dlambda ?? 0.01;\n this.lambda2 = this.lambda / 2.;\n this.dlambda2 = this.dlambda / 2.;\n this.epsilon = options?.epsilon ?? 1e-10;\n // eslint-disable-next-line brace-style\n this.distanceFunction = options?.distance ?? calculateEuclideanDistance;\n this.distance = new Float32Array();\n this.distanceFunctionName = options?.distanceFunctionName;\n }\n /**\n * Initializes distance matrix.\n *\n * @param {Vectors} vectors Input vectors to calculate distance between.\n * @memberof SPEBase\n */\n async initDistance(vectors) {\n this.dmIndexFunct = dmLinearIndex(vectors.length);\n const matrixService = new DistanceMatrixService(true, false);\n this.distance = await matrixService.calc(vectors, this.distanceFunctionName);\n matrixService.terminate();\n }\n /**\n * Calculates distance between the two vectors given.\n *\n * @param {Vectors} vectors Set of vectors to calculate distances between.\n * @param {number} index1 Index of the first vector of the pair.\n * @param {number} index2 Index of the second vector of the pair.\n * @return {number} Distance between these two vectors.\n */\n calcDistance(vectors, index1, index2) {\n return this.distance[this.dmIndexFunct(index1, index2)];\n }\n /**\n * Embeds the vectors given into a two-dimensional space.\n *\n * @param {Vectors} vectors D-dimensional coordinates.\n * @return {Coordinates} SPE coordinates in D space.\n */\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, SPEBase.dimension, areaWidth);\n let lambda2 = this.lambda2;\n if (this.steps === 0)\n this.steps = vectors.length - 1;\n await this.initDistance(vectors);\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n for (let step = 0; step < this.steps; ++step) {\n // Select two points, i and j, at random, ...\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const rowi = coordinates[i];\n const rowj = coordinates[j];\n // ... retrieve (or evaluate) their proximity in the input space, rij and ...\n const r = this.calcDistance(vectors, i, j);\n // ... compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n // If rij <= rc, or if rij > rc and dij < rij ...\n if ((this.cutoff == 0) || (r <= this.cutoff) || (d < r)) {\n const multiplier = lambda2 * (r - d) / (d + this.epsilon);\n // ... update the coordinates xi and xj.\n const diffIJ = vectorAdd(rowi, rowj, -1);\n coordinates[i] = vectorAdd(rowi, diffIJ, multiplier);\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n // Decrease the learning rate {lambda} by a prescribed {dlambda}.\n lambda2 -= this.dlambda2;\n if (lambda2 <= 0.)\n break;\n }\n return coordinates;\n }\n}\nSPEBase.dimension = 2;\nexport { SPEBase };\n/**\n * Implements modified stochastic proximity embedding.\n *\n * @export\n * @class PSPEBase\n * @link doi:10.1016/S1093-3263(03)00155-4\n */\nexport class PSPEBase extends SPEBase {\n /**\n * Embeds the vectors given into a two-dimensional space using a modified update rule.\n *\n * @param {Vectors} vectors D-dimensional coordinates.\n * @return {Coordinates} SPE coordinates in D space.\n */\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, PSPEBase.dimension, areaWidth);\n let lambda = this.lambda;\n await this.initDistance(vectors);\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n // Select a point, i, at random (pivot).\n const i = randomInt(nItems);\n const rowi = coordinates[i];\n // For every point j != i ...\n for (let j = 0; j < nItems; ++j) {\n if (i == j)\n continue;\n const rowj = coordinates[j];\n // ... retrieve (or evaluate) its proximity to i in the input space, rij ...\n const r = this.calcDistance(vectors, i, j);\n // ... and compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n // If rij <= rc, or if rij > rc and dij < rij ...\n if ((this.cutoff == 0) || (r <= this.cutoff) || (d < r)) {\n const multiplier = lambda * (r - d) / (d + this.epsilon);\n const diffIJ = vectorAdd(rowi, rowj, -1);\n // ... update the coordinates xj.\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n // Decrease the learning rate {lambda} by a prescribed {dlambda}.\n lambda -= this.dlambda;\n if (lambda <= 0.)\n break;\n }\n return coordinates;\n }\n}\n/**\n * Implements modified stochastic proximity embedding.\n *\n * @export\n * @class OriginalSPE\n * @link doi:10.1002/jcc.10234\n */\nexport class OriginalSPE extends SPEBase {\n constructor(options) {\n super(options);\n this.cycles = options?.cycles ?? 1e3;\n this.steps = options?.steps ?? 100000;\n this.radiusPercent = options?.radiusPercent ?? 1.0;\n this.maxDistance = options?.maxDistance ?? null;\n this.maxDistanceSteps = options?.maxDistanceSteps ?? null;\n }\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, OriginalSPE.dimension, areaWidth);\n await this.initDistance(vectors);\n if (this.maxDistanceSteps === null)\n this.maxDistanceSteps = nItems * Math.floor((nItems - 1) / 2);\n if (this.maxDistance === null) {\n this.maxDistance = -1e37;\n for (let n = 0; n < this.maxDistanceSteps; n++) {\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const d = this.calcDistance(vectors, i, j);\n if (d > this.maxDistance)\n this.maxDistance = d;\n }\n }\n let lambda = this.lambda;\n const radius = (this.radiusPercent == 0.0) ? this.maxDistance : this.maxDistance * this.radiusPercent;\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n for (let step = 0; step < this.steps; ++step) {\n // Select two points, i and j, at random, ...\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const rowi = coordinates[i];\n const rowj = coordinates[j];\n // retrieve (or evaluate) their proximity in the input space, rij and ...\n const r = this.calcDistance(vectors, i, j);\n // compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n if ((r <= radius) || (d < r)) {\n const multiplier = lambda * 0.5 * (r - d) / (d + this.epsilon);\n // ... update the coordinates xi and xj.\n const diffIJ = vectorAdd(rowi, rowj, -1);\n coordinates[i] = vectorAdd(rowi, diffIJ, multiplier);\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n lambda -= ((this.lambda - this.dlambda) / (this.cycles - 1.0));\n ;\n if (lambda < this.dlambda)\n break;\n }\n return coordinates;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3BlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsZ0JBQWdCLEVBQ2hCLFNBQVMsR0FDVixNQUFNLGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUUvRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsYUFBYSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFFdkU7Ozs7OztHQU1HO0FBQ0gsTUFBYSxPQUFPO0lBZWxCOzs7O09BSUc7SUFDSCxZQUFZLE9BQWlCO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLEdBQUcsQ0FBQztRQUNyQyw0Q0FBNEM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUNuQyw0Q0FBNEM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLEdBQUcsQ0FBQztRQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksSUFBSSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksS0FBSyxDQUFDO1FBQ3pDLHVDQUF1QztRQUN2QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSwwQkFBMEIsQ0FBQztRQUN4RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksWUFBWSxF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IFZlY3RvcnMsIERpc3RhbmNlTWV0cmljfSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZSxcbiAgZmlsbFJhbmRvbU1hdHJpeCxcbiAgdmVjdG9yQWRkLFxufSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy92ZWN0b3Itb3BlcmF0aW9ucyc7XG5pbXBvcnQge3JhbmRvbUludH0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvcmFuZG9tJztcbmltcG9ydCB7S25vd25NZXRyaWNzfSBmcm9tICcuL3R5cGVkLW1ldHJpY3MnO1xuaW1wb3J0IHtEaXN0YW5jZU1hdHJpeFNlcnZpY2UsIGRtTGluZWFySW5kZXh9IGZyb20gJy4vZGlzdGFuY2UtbWF0cml4JztcblxuLyoqXG4gKiBJbXBsZW1lbnRzIHN0b2NoYXN0aWMgcHJveGltaXR5IGVtYmVkZGluZy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgU1BFQmFzZVxuICogQGxpbmsgZG9pOjEwLjEwMTYvUzEwOTMtMzI2MygwMykwMDE1NS00XG4gKi9cbmV4cG9ydCBjbGFzcyBTUEVCYXNlIHtcbiAgcHJvdGVjdGVkIHN0YXRpYyBkaW1lbnNpb24gPSAyO1xuICBwcm90ZWN0ZWQgc3RlcHM6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGN5Y2xlczogbnVtYmVyO1xuICBwcm90ZWN0ZWQgY3V0b2ZmOiBudW1iZXI7XG4gIHByb3RlY3RlZCBsYW1iZGE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGRsYW1iZGE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGxhbWJkYTI6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGRsYW1iZGEyOiBudW1iZXI7XG4gIHByb3RlY3RlZCBlcHNpbG9uOiBudW1iZXI7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZ1bmN0aW9uOiBEaXN0YW5jZU1ldHJpYztcbiAgcHJvdGVjdGVkIGRpc3RhbmNlRnVuY3Rpb25OYW1lOiBLbm93bk1ldHJpY3M7XG4gIGRpc3RhbmNlOiBGbG9hdDMyQXJyYXk7XG4gIHByb3RlY3RlZCBkbUluZGV4RnVuY3Q/OiAoaTogbnVtYmVyLCBqOiBudW1iZXIpID0+IG51bWJlcjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBTUEVCYXNlLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IFtvcHRpb25zXSBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgKiBAbWVtYmVyb2YgU1BFQmFzZVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE9wdGlvbnMpIHtcbiAgICB0aGlzLnN0ZXBzID0gb3B0aW9ucz8uc3RlcHMgPz8gMDtcbiAgICB0aGlzLmN5Y2xlcyA9IG9wdGlvbnM/LmN5Y2xlcyA/PyAxZTY7XG4gICAgLy8gU2VsZWN0IGEgY3V0b2ZmIGRpc3RhbmNlIHtjdXRvZmZ9IGFuZCAuLi5cbiAgICB0aGlzLmN1dG9mZiA9IG9wdGlvbnM/LmN1dG9mZiA/PyAwO1xuICAgIC8vIC4uLiBhbiBpbml0aWFsIGxlYXJuaW5nIHJhdGUge2xhbWJkYX0gPiAwXG4gICAgdGhpcy5sYW1iZGEgPSBvcHRpb25zPy5sYW1iZGEgPz8gMi4wO1xuICAgIHRoaXMuZGxhbWJkYSA9IG9wdGlvbnM/LmRsYW1iZGEgPz8gMC4wMTtcbiAgICB0aGlzLmxhbWJkYTIgPSB0aGlzLmxhbWJkYSAvIDIuO1xuICAgIHRoaXMuZGxhbWJkYTIgPSB0aGlzLmRsYW1iZGEgLyAyLjtcbiAgICB0aGlzLmVwc2lsb24gPSBvcHRpb25zPy5lcHNpbG9uID8/IDFlLTEwO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBicmFjZS1zdHlsZVxuICAgIHRoaXMuZGlzdGFuY2VGdW5jdGlvbiA9IG9wdGlvbnM/LmRpc3RhbmNlID8/IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlO1xuICAgIHRoaXMuZGlzdGFuY2UgPSBuZXcgRmxvYXQzMkFycmF5KCk7XG4gICAgdGhpcy5kaXN0YW5jZUZ1bmN0aW9uTmFtZSA9IG9wdGlvbnM/LmRpc3RhbmNlRnVuY3Rpb25OYW1lITtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBkaXN0YW5jZSBtYXRyaXguXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBJbnB1dCB2ZWN0b3JzIHRvIGNhbGN1bGF0ZSBkaXN0YW5jZSBiZXR3ZWVuLlxuICAgKiBAbWVtYmVyb2YgU1BFQmFzZVxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGluaXREaXN0YW5jZSh2ZWN0b3JzOiBWZWN0b3JzKSB7XG4gICAgdGhpcy5kbUluZGV4RnVuY3QgPSBkbUxpbmVhckluZGV4KHZlY3RvcnMubGVuZ3RoKTtcbiAgICBjb25zdCBtYXRyaXhTZXJ2aWNlID0gbmV3IERpc3RhbmNlTWF0cml4U2VydmljZSh0cnVlLCBmYWxzZSk7XG4gICAgdGhpcy5kaXN0YW5jZSA9IGF3YWl0IG1hdHJpeFNlcnZpY2UuY2FsYyh2ZWN0b3JzLCB0aGlzLmRpc3RhbmNlRnVuY3Rpb25OYW1lKTtcbiAgICBtYXRyaXhTZXJ2aWNlLnRlcm1pbmF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgZGlzdGFuY2UgYmV0d2VlbiB0aGUgdHdvIHZlY3RvcnMgZ2l2ZW4uXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBTZXQgb2YgdmVjdG9ycyB0byBjYWxjdWxhdGUgZGlzdGFuY2VzIGJldHdlZW4uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleDEgSW5kZXggb2YgdGhlIGZpcnN0IHZlY3RvciBvZiB0aGUgcGFpci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4MiBJbmRleCBvZiB0aGUgc2Vjb25kIHZlY3RvciBvZiB0aGUgcGFpci5cbiAgICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNhbGNEaXN0YW5jZSh2ZWN0b3JzOiBWZWN0b3JzLCBpbmRleDE6IG51bWJlciwgaW5kZXgyOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmRpc3RhbmNlW3RoaXMuZG1JbmRleEZ1bmN0IShpbmRleDEsIGluZGV4MildO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgdmVjdG9ycyBnaXZlbiBpbnRvIGEgdHdvLWRpbWVuc2lvbmFsIHNwYWNlLlxuICAgKlxuICAgKiBAcGFyYW0ge1ZlY3RvcnN9IHZlY3RvcnMgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcy5cbiAgICogQHJldHVybiB7Q29vcmRpbmF0ZXN9IFNQRSBjb29yZGluYXRlcyBpbiBEIHNwYWNlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGVtYmVkKHZlY3RvcnM6IFZlY3RvcnMpOiBQcm9taXNlPENvb3JkaW5hdGVzPiB7XG4gICAgY29uc3Qgbkl0ZW1zID0gdmVjdG9ycy5sZW5ndGg7XG4gICAgY29uc3QgYXJlYVdpZHRoID0gNDA7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcyBvZiB0aGUgTiBwb2ludHMuXG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSBmaWxsUmFuZG9tTWF0cml4KG5JdGVtcywgU1BFQmFzZS5kaW1lbnNpb24sIGFyZWFXaWR0aCk7XG5cbiAgICBsZXQgbGFtYmRhMiA9IHRoaXMubGFtYmRhMjtcblxuICAgIGlmICh0aGlzLnN0ZXBzID09PSAwKVxuICAgICAgdGhpcy5zdGVwcyA9IHZlY3RvcnMubGVuZ3RoIC0gMTtcblxuXG4gICAgYXdhaXQgdGhpcy5pbml0RGlzdGFuY2UodmVjdG9ycyk7XG5cbiAgICBmb3IgKGxldCBjeWNsZSA9IDA7IGN5Y2xlIDwgdGhpcy5jeWNsZXM7ICsrY3ljbGUpIHtcbiAgICAgIGZvciAobGV0IHN0ZXAgPSAwOyBzdGVwIDwgdGhpcy5zdGVwczsgKytzdGVwKSB7XG4gICAgICAgIC8vIFNlbGVjdCB0d28gcG9pbnRzLCBpIGFuZCBqLCBhdCByYW5kb20sIC4uLlxuICAgICAgICBjb25zdCBpID0gcmFuZG9tSW50KG5JdGVtcyk7XG4gICAgICAgIGxldCBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG4gICAgICAgIHdoaWxlIChpID09IGopIGogPSByYW5kb21JbnQobkl0ZW1zKTtcblxuICAgICAgICBjb25zdCByb3dpID0gY29vcmRpbmF0ZXNbaV07XG4gICAgICAgIGNvbnN0IHJvd2ogPSBjb29yZGluYXRlc1tqXTtcblxuICAgICAgICAvLyAuLi4gcmV0cmlldmUgKG9yIGV2YWx1YXRlKSB0aGVpciBwcm94aW1pdHkgaW4gdGhlIGlucHV0IHNwYWNlLCByaWogYW5kIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIC4uLiBjb21wdXRlIHRoZWlyIEV1Y2xpZGVhbiBkaXN0YW5jZSBvbiB0aGUgRC1kaW1lbnNpb25hbCBtYXAsIGRpai5cbiAgICAgICAgY29uc3QgZCA9IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlKHJvd2ksIHJvd2opO1xuXG4gICAgICAgIC8vIElmIHJpaiA8PSByYywgb3IgaWYgcmlqID4gcmMgYW5kIGRpaiA8IHJpaiAuLi5cbiAgICAgICAgaWYgKCh0aGlzLmN1dG9mZiA9PSAwKSB8fCAociA8PSB0aGlzLmN1dG9mZikgfHwgKGQgPCByKSkge1xuICAgICAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSBsYW1iZGEyICogKHIgLSBkKSAvIChkICsgdGhpcy5lcHNpbG9uKTtcbiAgICAgICAgICAvLyAuLi4gdXBkYXRlIHRoZSBjb29yZGluYXRlcyB4aSBhbmQgeGouXG4gICAgICAgICAgY29uc3QgZGlmZklKID0gdmVjdG9yQWRkKHJvd2ksIHJvd2osIC0xKTtcbiAgICAgICAgICBjb29yZGluYXRlc1tpXSA9IHZlY3RvckFkZChyb3dpLCBkaWZmSUosIG11bHRpcGxpZXIpO1xuICAgICAgICAgIGNvb3JkaW5hdGVzW2pdID0gdmVjdG9yQWRkKHJvd2osIGRpZmZJSiwgLW11bHRpcGxpZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBEZWNyZWFzZSB0aGUgbGVhcm5pbmcgcmF0ZSB7bGFtYmRhfSBieSBhIHByZXNjcmliZWQge2RsYW1iZGF9LlxuICAgICAgbGFtYmRhMiAtPSB0aGlzLmRsYW1iZGEyO1xuICAgICAgaWYgKGxhbWJkYTIgPD0gMC4pXG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gY29vcmRpbmF0ZXM7XG4gIH1cbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRzIG1vZGlmaWVkIHN0b2NoYXN0aWMgcHJveGltaXR5IGVtYmVkZGluZy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgUFNQRUJhc2VcbiAqIEBsaW5rIGRvaToxMC4xMDE2L1MxMDkzLTMyNjMoMDMpMDAxNTUtNFxuICovXG5leHBvcnQgY2xhc3MgUFNQRUJhc2UgZXh0ZW5kcyBTUEVCYXNlIHtcbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgdmVjdG9ycyBnaXZlbiBpbnRvIGEgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIGEgbW9kaWZpZWQgdXBkYXRlIHJ1bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBELWRpbWVuc2lvbmFsIGNvb3JkaW5hdGVzLlxuICAgKiBAcmV0dXJuIHtDb29yZGluYXRlc30gU1BFIGNvb3JkaW5hdGVzIGluIEQgc3BhY2UuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZW1iZWQodmVjdG9yczogVmVjdG9ycyk6IFByb21pc2U8Q29vcmRpbmF0ZXM+IHtcbiAgICBjb25zdCBuSXRlbXMgPSB2ZWN0b3JzLmxlbmd0aDtcbiAgICBjb25zdCBhcmVhV2lkdGggPSA0MDtcbiAgICAvLyAgSW5pdGlhbGl6ZSB0aGUgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcyBvZiB0aGUgTiBwb2ludHMuXG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSBmaWxsUmFuZG9tTWF0cml4KG5JdGVtcywgUFNQRUJhc2UuZGltZW5zaW9uLCBhcmVhV2lkdGgpO1xuICAgIGxldCBsYW1iZGEgPSB0aGlzLmxhbWJkYTtcblxuICAgIGF3YWl0IHRoaXMuaW5pdERpc3RhbmNlKHZlY3RvcnMpO1xuXG4gICAgZm9yIChsZXQgY3ljbGUgPSAwOyBjeWNsZSA8IHRoaXMuY3ljbGVzOyArK2N5Y2xlKSB7XG4gICAgICAvLyBTZWxlY3QgYSBwb2ludCwgaSwgYXQgcmFuZG9tIChwaXZvdCkuXG4gICAgICBjb25zdCBpOiBudW1iZXIgPSByYW5kb21JbnQobkl0ZW1zKTtcbiAgICAgIGNvbnN0IHJvd2kgPSBjb29yZGluYXRlc1tpXTtcblxuICAgICAgLy8gRm9yIGV2ZXJ5IHBvaW50IGogIT0gaSAuLi5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbkl0ZW1zOyArK2opIHtcbiAgICAgICAgaWYgKGkgPT0gaikgY29udGludWU7XG4gICAgICAgIGNvbnN0IHJvd2ogPSBjb29yZGluYXRlc1tqXTtcbiAgICAgICAgLy8gLi4uIHJldHJpZXZlIChvciBldmFsdWF0ZSkgaXRzIHByb3hpbWl0eSB0byBpIGluIHRoZSBpbnB1dCBzcGFjZSwgcmlqIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIC4uLiBhbmQgY29tcHV0ZSB0aGVpciBFdWNsaWRlYW4gZGlzdGFuY2Ugb24gdGhlIEQtZGltZW5zaW9uYWwgbWFwLCBkaWouXG4gICAgICAgIGNvbnN0IGQgPSBjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZShyb3dpLCByb3dqKTtcbiAgICAgICAgLy8gSWYgcmlqIDw9IHJjLCBvciBpZiByaWogPiByYyBhbmQgZGlqIDwgcmlqIC4uLlxuICAgICAgICBpZiAoKHRoaXMuY3V0b2ZmID09IDApIHx8IChyIDw9IHRoaXMuY3V0b2ZmKSB8fCAoZCA8IHIpKSB7XG4gICAgICAgICAgY29uc3QgbXVsdGlwbGllciA9IGxhbWJkYSAqIChyIC0gZCkgLyAoZCArIHRoaXMuZXBzaWxvbik7XG4gICAgICAgICAgY29uc3QgZGlmZklKID0gdmVjdG9yQWRkKHJvd2ksIHJvd2osIC0xKTtcbiAgICAgICAgICAvLyAuLi4gdXBkYXRlIHRoZSBjb29yZGluYXRlcyB4ai5cbiAgICAgICAgICBjb29yZGluYXRlc1tqXSA9IHZlY3RvckFkZChyb3dqLCBkaWZmSUosIC1tdWx0aXBsaWVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGVjcmVhc2UgdGhlIGxlYXJuaW5nIHJhdGUge2xhbWJkYX0gYnkgYSBwcmVzY3JpYmVkIHtkbGFtYmRhfS5cbiAgICAgIGxhbWJkYSAtPSB0aGlzLmRsYW1iZGE7XG4gICAgICBpZiAobGFtYmRhIDw9IDAuKVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvb3JkaW5hdGVzO1xuICB9XG59XG5cbi8qKlxuICogSW1wbGVtZW50cyBtb2RpZmllZCBzdG9jaGFzdGljIHByb3hpbWl0eSBlbWJlZGRpbmcuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE9yaWdpbmFsU1BFXG4gKiBAbGluayBkb2k6MTAuMTAwMi9qY2MuMTAyMzRcbiAqL1xuZXhwb3J0IGNsYXNzIE9yaWdpbmFsU1BFIGV4dGVuZHMgU1BFQmFzZSB7XG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIHZlY3RvcnMgZ2l2ZW4gaW50byBhIHR3by1kaW1lbnNpb25hbCBzcGFjZSB1c2luZyBhIG1vZGlmaWVkIHVwZGF0ZSBydWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge1ZlY3RvcnN9IHZlY3RvcnMgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcy5cbiAgICogQHJldHVybiB7Q29vcmRpbmF0ZXN9IFNQRSBjb29yZGluYXRlcyBpbiBEIHNwYWNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJhZGl1c1BlcmNlbnQ6IG51bWJlcjtcbiAgcHJvdGVjdGVkIG1heERpc3RhbmNlOiBudW1iZXI7XG4gIHByb3RlY3RlZCBtYXhEaXN0YW5jZVN0ZXBzOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgICB0aGlzLmN5Y2xlcyA9IG9wdGlvbnM/LmN5Y2xlcyA/PyAxZTM7XG4gICAgdGhpcy5zdGVwcyA9IG9wdGlvbnM/LnN0ZXBzID8/IDEwMDAwMDtcbiAgICB0aGlzLnJhZGl1c1BlcmNlbnQgPSBvcHRpb25zPy5yYWRpdXNQZXJjZW50ID8/IDEuMDtcbiAgICB0aGlzLm1heERpc3RhbmNlID0gb3B0aW9ucz8ubWF4RGlzdGFuY2UgPz8gbnVsbDtcbiAgICB0aGlzLm1heERpc3RhbmNlU3RlcHMgPSBvcHRpb25zPy5tYXhEaXN0YW5jZVN0ZXBzID8/IG51bGw7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZW1iZWQodmVjdG9yczogVmVjdG9ycyk6IFByb21pc2U8Q29vcmRpbmF0ZXM+IHtcbiAgICBjb25zdCBuSXRlbXMgPSB2ZWN0b3JzLmxlbmd0aDtcbiAgICBjb25zdCBhcmVhV2lkdGggPSA0MDtcbiAgICAvLyBJbml0aWFsaXplIHRoZSBELWRpbWVuc2lvbmFsIGNvb3JkaW5hdGVzIG9mIHRoZSBOIHBvaW50cy5cbiAgICBjb25zdCBjb29yZGluYXRlcyA9IGZpbGxSYW5kb21NYXRyaXgobkl0ZW1zLCBPcmlnaW5hbFNQRS5kaW1lbnNpb24sIGFyZWFXaWR0aCk7XG5cbiAgICBhd2FpdCB0aGlzLmluaXREaXN0YW5jZSh2ZWN0b3JzKTtcblxuICAgIGlmICh0aGlzLm1heERpc3RhbmNlU3RlcHMgPT09IG51bGwpXG4gICAgICB0aGlzLm1heERpc3RhbmNlU3RlcHMgPSBuSXRlbXMgKiBNYXRoLmZsb29yKChuSXRlbXMgLSAxKSAvIDIpO1xuXG4gICAgaWYgKHRoaXMubWF4RGlzdGFuY2UgPT09IG51bGwpIHtcbiAgICAgIHRoaXMubWF4RGlzdGFuY2UgPSAtMWUzNztcbiAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgdGhpcy5tYXhEaXN0YW5jZVN0ZXBzOyBuKyspIHtcbiAgICAgICAgY29uc3QgaSA9IHJhbmRvbUludChuSXRlbXMpOyBsZXQgaiA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICB3aGlsZSAoaSA9PSBqKSBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG5cbiAgICAgICAgY29uc3QgZCA9IHRoaXMuY2FsY0Rpc3RhbmNlKHZlY3RvcnMsIGksIGopO1xuICAgICAgICBpZiAoZCA+IHRoaXMubWF4RGlzdGFuY2UpXG4gICAgICAgICAgdGhpcy5tYXhEaXN0YW5jZSA9IGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGxhbWJkYSA9IHRoaXMubGFtYmRhO1xuICAgIGNvbnN0IHJhZGl1cyA9ICh0aGlzLnJhZGl1c1BlcmNlbnQgPT0gMC4wKSA/IHRoaXMubWF4RGlzdGFuY2UgOiB0aGlzLm1heERpc3RhbmNlICogdGhpcy5yYWRpdXNQZXJjZW50O1xuXG4gICAgZm9yIChsZXQgY3ljbGUgPSAwOyBjeWNsZSA8IHRoaXMuY3ljbGVzOyArK2N5Y2xlKSB7XG4gICAgICBmb3IgKGxldCBzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7ICsrc3RlcCkge1xuICAgICAgICAvLyBTZWxlY3QgdHdvIHBvaW50cywgaSBhbmQgaiwgYXQgcmFuZG9tLCAuLi5cbiAgICAgICAgY29uc3QgaSA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICBsZXQgaiA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICB3aGlsZSAoaSA9PSBqKSBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG5cbiAgICAgICAgY29uc3Qgcm93aSA9IGNvb3JkaW5hdGVzW2ldO1xuICAgICAgICBjb25zdCByb3dqID0gY29vcmRpbmF0ZXNbal07XG5cbiAgICAgICAgLy8gcmV0cmlldmUgKG9yIGV2YWx1YXRlKSB0aGVpciBwcm94aW1pdHkgaW4gdGhlIGlucHV0IHNwYWNlLCByaWogYW5kIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIGNvbXB1dGUgdGhlaXIgRXVjbGlkZWFuIGRpc3RhbmNlIG9uIHRoZSBELWRpbWVuc2lvbmFsIG1hcCwgZGlqLlxuICAgICAgICBjb25zdCBkID0gY2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2Uocm93aSwgcm93aik7XG5cbiAgICAgICAgaWYgKChyIDw9IHJhZGl1cykgfHwgKGQgPCByKSkge1xuICAgICAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSBsYW1iZGEgKiAwLjUgKiAociAtIGQpIC8gKGQgKyB0aGlzLmVwc2lsb24pO1xuICAgICAgICAgIC8vIC4uLiB1cGRhdGUgdGhlIGNvb3JkaW5hdGVzIHhpIGFuZCB4ai5cbiAgICAgICAgICBjb25zdCBkaWZmSUogPSB2ZWN0b3JBZGQocm93aSwgcm93aiwgLTEpO1xuICAgICAgICAgIGNvb3JkaW5hdGVzW2ldID0gdmVjdG9yQWRkKHJvd2ksIGRpZmZJSiwgbXVsdGlwbGllcik7XG4gICAgICAgICAgY29vcmRpbmF0ZXNbal0gPSB2ZWN0b3JBZGQocm93aiwgZGlmZklKLCAtbXVsdGlwbGllcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxhbWJkYSAtPSAoKHRoaXMubGFtYmRhIC0gdGhpcy5kbGFtYmRhKSAvICh0aGlzLmN5Y2xlcyAtIDEuMCkpOyA7XG4gICAgICBpZiAobGFtYmRhIDwgdGhpcy5kbGFtYmRhKVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvb3JkaW5hdGVzO1xuICB9XG59XG4iXX0=","export var StringMetricsNames;\n(function (StringMetricsNames) {\n StringMetricsNames[\"Levenshtein\"] = \"Levenshtein\";\n StringMetricsNames[\"JaroWinkler\"] = \"Jaro-Winkler\";\n StringMetricsNames[\"Manhattan\"] = \"Manhattan\";\n})(StringMetricsNames || (StringMetricsNames = {}));\nexport var VectorMetricsNames;\n(function (VectorMetricsNames) {\n VectorMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(VectorMetricsNames || (VectorMetricsNames = {}));\nexport var BitArrayMetricsNames;\n(function (BitArrayMetricsNames) {\n BitArrayMetricsNames[\"Tanimoto\"] = \"Tanimoto\";\n BitArrayMetricsNames[\"Dice\"] = \"Dice\";\n BitArrayMetricsNames[\"Asymmetric\"] = \"Asymmetric\";\n BitArrayMetricsNames[\"BraunBlanquet\"] = \"Braun-Blanquet\";\n BitArrayMetricsNames[\"Cosine\"] = \"Cosine\";\n BitArrayMetricsNames[\"Kulczynski\"] = \"Kulczynski\";\n BitArrayMetricsNames[\"McConnaughey\"] = \"Mc-Connaughey\";\n BitArrayMetricsNames[\"RogotGoldberg\"] = \"Rogot-Goldberg\";\n BitArrayMetricsNames[\"Russel\"] = \"Russel\";\n BitArrayMetricsNames[\"Sokal\"] = \"Sokal\";\n BitArrayMetricsNames[\"Hamming\"] = \"Hamming\";\n BitArrayMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(BitArrayMetricsNames || (BitArrayMetricsNames = {}));\nexport var IntArrayMetricsNames;\n(function (IntArrayMetricsNames) {\n IntArrayMetricsNames[\"TanimotoIntArray\"] = \"TanimotoIntArray\";\n})(IntArrayMetricsNames || (IntArrayMetricsNames = {}));\nexport var DistanceMetricsSubjects;\n(function (DistanceMetricsSubjects) {\n DistanceMetricsSubjects[\"Vector\"] = \"Vector\";\n DistanceMetricsSubjects[\"String\"] = \"String\";\n DistanceMetricsSubjects[\"BitArray\"] = \"BitArray\";\n DistanceMetricsSubjects[\"MacroMolecule\"] = \"MacroMolecule\";\n DistanceMetricsSubjects[\"Number\"] = \"Number\";\n DistanceMetricsSubjects[\"IntArray\"] = \"IntArray\";\n})(DistanceMetricsSubjects || (DistanceMetricsSubjects = {}));\nexport var NumberMetricsNames;\n(function (NumberMetricsNames) {\n NumberMetricsNames[\"NumericDistance\"] = \"NumericDistance\";\n})(NumberMetricsNames || (NumberMetricsNames = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBTixJQUFZLGtCQUlUO0FBSkgsV0FBWSxrQkFBa0I7SUFDMUIsaURBQTJCLENBQUE7SUFDM0Isa0RBQTRCLENBQUE7SUFDNUIsNkNBQXVCLENBQUE7QUFDekIsQ0FBQyxFQUpTLGtCQUFrQixLQUFsQixrQkFBa0IsUUFJM0I7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFVDtBQUZILFdBQVksa0JBQWtCO0lBQzFCLDZDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFGUyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTNCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBYVQ7QUFiSCxXQUFZLG9CQUFvQjtJQUM1Qiw2Q0FBcUIsQ0FBQTtJQUNyQixxQ0FBYSxDQUFBO0lBQ2IsaURBQXlCLENBQUE7SUFDekIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsaURBQXlCLENBQUE7SUFDekIsc0RBQThCLENBQUE7SUFDOUIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsdUNBQWUsQ0FBQTtJQUNmLDJDQUFtQixDQUFBO0lBQ25CLCtDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFiUyxvQkFBb0IsS0FBcEIsb0JBQW9CLFFBYTdCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBRVg7QUFGRCxXQUFZLG9CQUFvQjtJQUM5Qiw2REFBcUMsQ0FBQTtBQUN2QyxDQUFDLEVBRlcsb0JBQW9CLEtBQXBCLG9CQUFvQixRQUUvQjtBQUVELE1BQU0sQ0FBTixJQUFZLHVCQU9UO0FBUEgsV0FBWSx1QkFBdUI7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7SUFDckIsMERBQStCLENBQUE7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQVBTLHVCQUF1QixLQUF2Qix1QkFBdUIsUUFPaEM7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFWDtBQUZELFdBQVksa0JBQWtCO0lBQzVCLHlEQUFtQyxDQUFBO0FBQ3JDLENBQUMsRUFGVyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGVudW0gU3RyaW5nTWV0cmljc05hbWVzIHtcbiAgICBMZXZlbnNodGVpbiA9ICdMZXZlbnNodGVpbicsXG4gICAgSmFyb1dpbmtsZXIgPSAnSmFyby1XaW5rbGVyJyxcbiAgICBNYW5oYXR0YW4gPSAnTWFuaGF0dGFuJyxcbiAgfVxuXG5leHBvcnQgZW51bSBWZWN0b3JNZXRyaWNzTmFtZXMge1xuICAgIEV1Y2xpZGVhbiA9ICdFdWNsaWRlYW4nLFxuICB9XG5cbmV4cG9ydCBlbnVtIEJpdEFycmF5TWV0cmljc05hbWVzIHtcbiAgICBUYW5pbW90byA9ICdUYW5pbW90bycsXG4gICAgRGljZSA9ICdEaWNlJyxcbiAgICBBc3ltbWV0cmljID0gJ0FzeW1tZXRyaWMnLFxuICAgIEJyYXVuQmxhbnF1ZXQgPSAnQnJhdW4tQmxhbnF1ZXQnLFxuICAgIENvc2luZSA9ICdDb3NpbmUnLFxuICAgIEt1bGN6eW5za2kgPSAnS3VsY3p5bnNraScsXG4gICAgTWNDb25uYXVnaGV5ID0gJ01jLUNvbm5hdWdoZXknLFxuICAgIFJvZ290R29sZGJlcmcgPSAnUm9nb3QtR29sZGJlcmcnLFxuICAgIFJ1c3NlbCA9ICdSdXNzZWwnLFxuICAgIFNva2FsID0gJ1Nva2FsJyxcbiAgICBIYW1taW5nID0gJ0hhbW1pbmcnLFxuICAgIEV1Y2xpZGVhbiA9ICdFdWNsaWRlYW4nLFxuICB9XG5cbmV4cG9ydCBlbnVtIEludEFycmF5TWV0cmljc05hbWVzIHtcbiAgVGFuaW1vdG9JbnRBcnJheSA9ICdUYW5pbW90b0ludEFycmF5Jyxcbn1cblxuZXhwb3J0IGVudW0gRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMge1xuICAgIFZlY3RvciA9ICdWZWN0b3InLFxuICAgIFN0cmluZyA9ICdTdHJpbmcnLFxuICAgIEJpdEFycmF5ID0gJ0JpdEFycmF5JyxcbiAgICBNYWNyb01vbGVjdWxlID0gJ01hY3JvTW9sZWN1bGUnLFxuICAgIE51bWJlciA9ICdOdW1iZXInLFxuICAgIEludEFycmF5ID0gJ0ludEFycmF5JyxcbiAgfVxuXG5leHBvcnQgZW51bSBOdW1iZXJNZXRyaWNzTmFtZXMge1xuICBOdW1lcmljRGlzdGFuY2UgPSAnTnVtZXJpY0Rpc3RhbmNlJyxcbn1cblxuIl19","import BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport { BitArrayMetricsNames } from './typed-metrics/consts';\nimport { MmDistanceFunctionsNames } from './macromolecule-distance-functions';\nexport const similarityMetric = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoSimilarity,\n [BitArrayMetricsNames.Dice]: diceSimilarity,\n [BitArrayMetricsNames.Asymmetric]: asymmetricSimilarity,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetSimilarity,\n [BitArrayMetricsNames.Cosine]: cosineSimilarity,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiSimilarity,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheySimilarity,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergSimilarity,\n [BitArrayMetricsNames.Russel]: russelSimilarity,\n [BitArrayMetricsNames.Sokal]: sokalSimilarity,\n [BitArrayMetricsNames.Hamming]: hammingSimilarity,\n [BitArrayMetricsNames.Euclidean]: euclideanSimilarity,\n};\nexport const distanceMetrics = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoDistance,\n [BitArrayMetricsNames.Dice]: diceDistance,\n [BitArrayMetricsNames.Asymmetric]: asymmetricDistance,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetDistance,\n [BitArrayMetricsNames.Cosine]: cosineDistance,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiDistance,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheyDistance,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergDistance,\n [BitArrayMetricsNames.Russel]: russelDistance,\n [BitArrayMetricsNames.Sokal]: sokalDistance,\n [BitArrayMetricsNames.Hamming]: hammingDistance,\n [BitArrayMetricsNames.Euclidean]: euclideanDistance,\n};\nexport const CHEM_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Dice,\n BitArrayMetricsNames.Cosine\n];\nexport const SEQ_SPACE_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Asymmetric,\n BitArrayMetricsNames.Cosine,\n BitArrayMetricsNames.Sokal\n];\nexport const MACROMOLECULE_SIMILARITY_METRICS = [\n MmDistanceFunctionsNames.HAMMING,\n MmDistanceFunctionsNames.LEVENSHTEIN,\n MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE\n];\nexport function tanimotoSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 1.0;\n const common = x.andWithCountBits(y, true);\n return common / (total - common);\n}\nexport function tanimotoDistance(x, y) {\n return getDistanceFromSimilarity(tanimotoSimilarity(x, y));\n}\nexport function tanimotoDistanceIntArray(x, y) {\n const xb = new BitArray(x, x.length * 32);\n const yb = new BitArray(y, y.length * 32);\n return getDistanceFromSimilarity(tanimotoSimilarity(xb, yb));\n}\nexport function diceSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return 2 * common / total;\n}\nexport function diceDistance(x, y) {\n return getDistanceFromSimilarity(diceSimilarity(x, y));\n}\nexport function cosineSimilarity(x, y) {\n const total = x.trueCount() * y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / Math.sqrt(total);\n}\nexport function cosineDistance(x, y) {\n return getDistanceFromSimilarity(cosineSimilarity(x, y));\n}\nexport function euclideanSimilarity(x, y) {\n return getSimilarityFromDistance(euclideanDistance(x, y));\n}\nexport function euclideanDistance(x, y) {\n return Math.sqrt(x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true));\n}\nexport function hammingSimilarity(x, y) {\n return getSimilarityFromDistance(hammingDistance(x, y));\n}\nexport function hammingDistance(x, y) {\n return x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true);\n}\nexport function sokalSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const common = x.andWithCountBits(y, true);\n return common / (2 * total - 3 * common);\n}\nexport function sokalDistance(x, y) {\n return getDistanceFromSimilarity(sokalSimilarity(x, y));\n}\nexport function kulczynskiSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total) / (2 * totalProd);\n}\nexport function kulczynskiDistance(x, y) {\n return getDistanceFromSimilarity(kulczynskiSimilarity(x, y));\n}\nexport function mcConnaugheySimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total - totalProd) / totalProd;\n}\nexport function mcConnaugheyDistance(x, y) {\n return getDistanceFromSimilarity(mcConnaugheySimilarity(x, y));\n}\nexport function asymmetricSimilarity(x, y) {\n const min = Math.min(x.trueCount(), y.trueCount());\n if (min == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / min;\n}\nexport function asymmetricDistance(x, y) {\n return getDistanceFromSimilarity(asymmetricSimilarity(x, y));\n}\nexport function braunBlanquetSimilarity(x, y) {\n const max = Math.max(x.trueCount(), y.trueCount());\n if (max == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / max;\n}\nexport function braunBlanquetDistance(x, y) {\n return getDistanceFromSimilarity(braunBlanquetSimilarity(x, y));\n}\nexport function russelSimilarity(x, y) {\n if (x.length == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / x.length;\n}\nexport function russelDistance(x, y) {\n return getDistanceFromSimilarity(russelSimilarity(x, y));\n}\nexport function rogotGoldbergSimilarity(x, y) {\n const common = x.andWithCountBits(y, true);\n const total = x.countBits(true) + y.countBits(true);\n const len = x.length;\n const diff = len - total + common;\n if ((common == len) || (diff == len))\n return 1.0;\n else\n return common / total + diff / (2 * len - total);\n}\nexport function rogotGoldbergDistance(x, y) {\n return getDistanceFromSimilarity(rogotGoldbergSimilarity(x, y));\n}\nexport function getSimilarityFromDistance(distance) {\n return 1 / (1 + distance);\n}\nexport function getDistanceFromSimilarity(similarity) {\n return similarity === 0 ? 3.402823E+38 : (1 / similarity) - 1;\n}\nexport function numericDistance(x, y) {\n return Math.abs(x - y);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sUUFBUSxNQUFNLHlDQUF5QyxDQUFDO0FBQy9ELE9BQU8sRUFBQyxvQkFBb0IsRUFBdUIsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUU5RSxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBNkQ7SUFDeEYsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSxrQkFBa0I7SUFDbkQsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFjO0lBQzNDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsb0JBQW9CO0lBQ3ZELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUsdUJBQXVCO0lBQzdELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsZ0JBQWdCO0lBQy9DLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsb0JBQW9CO0lBQ3ZELENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLEVBQUUsc0JBQXNCO0lBQzNELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUsdUJBQXVCO0lBQzdELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsZ0JBQWdCO0lBQy9DLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLEVBQUUsZUFBZTtJQUM3QyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxFQUFFLGlCQUFpQjtJQUNqRCxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxFQUFFLG1CQUFtQjtDQUN0RCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUE2RDtJQUN2RixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxF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QUFDO0FBRUQsTUFBTSxVQUFVLGVBQWUsQ0FBQyxDQUFTLEVBQUUsQ0FBUztJQUNsRCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQml0QXJyYXkgZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvYml0LWFycmF5JztcbmltcG9ydCB7Qml0QXJyYXlNZXRyaWNzTmFtZXMsIEludEFycmF5TWV0cmljc05hbWVzfSBmcm9tICcuL3R5cGVkLW1ldHJpY3MvY29uc3RzJztcbmltcG9ydCB7IE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB9IGZyb20gJy4vbWFjcm9tb2xlY3VsZS1kaXN0YW5jZS1mdW5jdGlvbnMnO1xuXG5leHBvcnQgY29uc3Qgc2ltaWxhcml0eU1ldHJpYzogeyBbbmFtZTogc3RyaW5nXTogKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSkgPT4gbnVtYmVyIH0gPSB7XG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b106IHRhbmltb3RvU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkRpY2VdOiBkaWNlU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkFzeW1tZXRyaWNdOiBhc3ltbWV0cmljU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkJyYXVuQmxhbnF1ZXRdOiBicmF1bkJsYW5xdWV0U2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV06IGNvc2luZVNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5LdWxjenluc2tpXToga3VsY3p5bnNraVNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldOiBtY0Nvbm5hdWdoZXlTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUm9nb3RHb2xkYmVyZ106IHJvZ290R29sZGJlcmdTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXTogcnVzc2VsU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXTogc29rYWxTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuSGFtbWluZ106IGhhbW1pbmdTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogZXVjbGlkZWFuU2ltaWxhcml0eSxcbn07XG5cbmV4cG9ydCBjb25zdCBkaXN0YW5jZU1ldHJpY3M6IHsgW25hbWU6IHN0cmluZ106ICh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9dOiB0YW5pbW90b0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV06IGRpY2VEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkFzeW1tZXRyaWNdOiBhc3ltbWV0cmljRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XTogYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTogY29zaW5lRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5LdWxjenluc2tpXToga3VsY3p5bnNraURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuTWNDb25uYXVnaGV5XTogbWNDb25uYXVnaGV5RGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXTogcm9nb3RHb2xkYmVyZ0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXTogcnVzc2VsRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF06IHNva2FsRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5IYW1taW5nXTogaGFtbWluZ0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogZXVjbGlkZWFuRGlzdGFuY2UsXG59O1xuXG5leHBvcnQgY29uc3QgQ0hFTV9TSU1JTEFSSVRZX01FVFJJQ1MgPSBbXG4gIEJpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdO1xuZXhwb3J0IGNvbnN0IFNFUV9TUEFDRV9TSU1JTEFSSVRZX01FVFJJQ1MgPSBbXG4gIEJpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmUsXG4gIEJpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXTtcbmV4cG9ydCBjb25zdCBNQUNST01PTEVDVUxFX1NJTUlMQVJJVFlfTUVUUklDUyA9IFtcbiAgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkcsXG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5MRVZFTlNIVEVJTixcbiAgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk1PTk9NRVJfQ0hFTUlDQUxfRElTVEFOQ0VdO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiB0YW5pbW90b1NpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgdG90YWwgPSB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKTtcbiAgaWYgKHRvdGFsID09IDApIHJldHVybiAxLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvICh0b3RhbCAtIGNvbW1vbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0YW5pbW90b0Rpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KHRhbmltb3RvU2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0YW5pbW90b0Rpc3RhbmNlSW50QXJyYXkoeDogVWludDMyQXJyYXksIHk6IFVpbnQzMkFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgeGIgPSBuZXcgQml0QXJyYXkoeCwgeC5sZW5ndGggKiAzMik7XG4gIGNvbnN0IHliID0gbmV3IEJpdEFycmF5KHksIHkubGVuZ3RoICogMzIpO1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eSh0YW5pbW90b1NpbWlsYXJpdHkoeGIsIHliKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWNlU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWwgPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gMiAqIGNvbW1vbiAvIHRvdGFsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGljZURpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KGRpY2VTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvc2luZVNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgdG90YWwgPSB4LnRydWVDb3VudCgpICogeS50cnVlQ291bnQoKTtcbiAgaWYgKHRvdGFsID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvIE1hdGguc3FydCh0b3RhbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmVEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShjb3NpbmVTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV1Y2xpZGVhblNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UoZXVjbGlkZWFuRGlzdGFuY2UoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXVjbGlkZWFuRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguc3FydCh4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKSAtIDIgKiB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFtbWluZ1NpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UoaGFtbWluZ0Rpc3RhbmNlKHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhbW1pbmdEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCkgLSAyICogeC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc29rYWxTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCk7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvICgyICogdG90YWwgLSAzICogY29tbW9uKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNva2FsRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoc29rYWxTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGt1bGN6eW5za2lTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCk7XG4gIGNvbnN0IHRvdGFsUHJvZCA9IHgudHJ1ZUNvdW50KCkgKiB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWxQcm9kID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIChjb21tb24gKiB0b3RhbCkgLyAoMiAqIHRvdGFsUHJvZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBrdWxjenluc2tpRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoa3VsY3p5bnNraVNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWNDb25uYXVnaGV5U2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBjb25zdCB0b3RhbFByb2QgPSB4LnRydWVDb3VudCgpICogeS50cnVlQ291bnQoKTtcbiAgaWYgKHRvdGFsUHJvZCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiAoY29tbW9uICogdG90YWwgLSB0b3RhbFByb2QpIC8gdG90YWxQcm9kO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWNDb25uYXVnaGV5RGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkobWNDb25uYXVnaGV5U2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3ltbWV0cmljU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCBtaW4gPSBNYXRoLm1pbih4LnRydWVDb3VudCgpLCB5LnRydWVDb3VudCgpKTtcbiAgaWYgKG1pbiA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyBtaW47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3ltbWV0cmljRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoYXN5bW1ldHJpY1NpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnJhdW5CbGFucXVldFNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgbWF4ID0gTWF0aC5tYXgoeC50cnVlQ291bnQoKSwgeS50cnVlQ291bnQoKSk7XG4gIGlmIChtYXggPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gbWF4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnJhdW5CbGFucXVldERpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KGJyYXVuQmxhbnF1ZXRTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1c3NlbFNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgaWYgKHgubGVuZ3RoID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvIHgubGVuZ3RoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcnVzc2VsRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkocnVzc2VsU2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByb2dvdEdvbGRiZXJnU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIGNvbnN0IHRvdGFsID0geC5jb3VudEJpdHModHJ1ZSkgKyB5LmNvdW50Qml0cyh0cnVlKTtcbiAgY29uc3QgbGVuID0geC5sZW5ndGg7XG4gIGNvbnN0IGRpZmYgPSBsZW4gLSB0b3RhbCArIGNvbW1vbjtcbiAgaWYgKChjb21tb24gPT0gbGVuKSB8fCAoZGlmZiA9PSBsZW4pKSByZXR1cm4gMS4wO1xuICBlbHNlIHJldHVybiBjb21tb24gLyB0b3RhbCArIGRpZmYgLyAoMiAqIGxlbiAtIHRvdGFsKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJvZ290R29sZGJlcmdEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShyb2dvdEdvbGRiZXJnU2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTaW1pbGFyaXR5RnJvbURpc3RhbmNlKGRpc3RhbmNlOiBudW1iZXIpIHtcbiAgcmV0dXJuIDEgLyAoMSArIGRpc3RhbmNlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoc2ltaWxhcml0eTogbnVtYmVyKSB7IC8vaW4gY2FzZSBzaW1pbGFyaXR5IGlzIDAsIHVzZSBtYXggbnVtYmVyIGZvciBmbG9hdDMyXG4gIHJldHVybiBzaW1pbGFyaXR5ID09PSAwID8gMy40MDI4MjNFKzM4IDogKDEgLyBzaW1pbGFyaXR5KSAtIDE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBudW1lcmljRGlzdGFuY2UoeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgcmV0dXJuIE1hdGguYWJzKHggLSB5KTtcbn1cbiJdfQ==","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, } 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 } 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};\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.NumericDistance]: numericDistance,\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 },\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.NumericDistance]: numberDistanceMetricsMethods[NumberMetricsNames.NumericDistance],\n },\n [DistanceMetricsSubjects.IntArray]: {\n [IntArrayMetricsNames.TanimotoIntArray]: intArrayDistanceMetricsMethods[IntArrayMetricsNames.TanimotoIntArray],\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}\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}\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 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 isMacroMoleculeMetric(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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWQtbWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInR5cGVkLW1ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxQyxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFcEQsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixxQkFBcUIsRUFDckIsY0FBYyxFQUNkLFlBQVksRUFDWixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZix3QkFBd0IsR0FDekIsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQUMsMEJBQTBCLEVBQUMsTUFBTSxpREFBaUQsQ0FBQztBQUczRixPQUFPLEVBQUMsbUJBQW1CLEVBQUUsd0JBQXdCLEVBQUMsTUFBTSxxQ0FBcUMsQ0FBQztBQUNsRyxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQ25ELGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLG9CQUFvQixFQUFDLE1BQU0sVUFBVSxDQUFDO0FBR3BHLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUF5RDtJQUNoRyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLDBCQUEwQjtDQUMzRCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQXlEO0lBQ2hHLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVE7SUFDN0MsQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxXQUFXO0lBQzdDLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsaUJBQWlCO0NBQ2xELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBNkQ7SUFDdEcsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSxnQkFBZ0I7SUFDakQsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxZQUFZO0lBQ3pDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsa0JBQWtCO0lBQ3JELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUscUJBQXFCO0lBQzNELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsY0FBYztJQUM3QyxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLGtCQUFrQjtJQUNyRCxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxFQUFFLG9CQUFvQjtJQUN6RCxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLHFCQUFxQjtJQUMzRCxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLGNBQWM7SUFDN0MsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhO0lBQzNDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLEVBQUUsZUFBZTtJQUMvQyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxFQUFFLGlCQUFpQjtDQUNwRCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQW1FO0lBQzVHLENBQUMsb0JBQW9CLENBQUMsZ0JBQWdCLENBQUMsRUFBRSx3QkFBd0I7Q0FDbEUsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUF5RDtJQUNoRyxDQUFDLGtCQUFrQixDQUFDLGVBQWUsQ0FBQyxFQUFFLGVBQWU7Q0FDdEQsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHO0lBQzlCLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDaEMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFBRSw0QkFBNEIsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUM7S0FDM0Y7SUFDRCxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQ2hDLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDO1FBQzlGLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDO1FBQzlGLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDO0tBQzNGO0lBQ0QsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUNsQyxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQztRQUM5RixDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQztRQUN0RixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQztRQUNsRyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQztRQUN4RyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQztRQUMxRixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQztRQUNsRyxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQztRQUN0RyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQztRQUN4RyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFD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dCB7amFyb1dpbmtsZXJ9IGZyb20gJ2phcm8td2lua2xlci10eXBlc2NyaXB0JztcbmltcG9ydCB7RGlzdGFuY2VNZXRyaWN9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7XG4gIGFzeW1tZXRyaWNEaXN0YW5jZSxcbiAgYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBjb3NpbmVEaXN0YW5jZSxcbiAgZGljZURpc3RhbmNlLFxuICBldWNsaWRlYW5EaXN0YW5jZSxcbiAgaGFtbWluZ0Rpc3RhbmNlLFxuICBrdWxjenluc2tpRGlzdGFuY2UsXG4gIG1jQ29ubmF1Z2hleURpc3RhbmNlLFxuICByb2dvdEdvbGRiZXJnRGlzdGFuY2UsXG4gIHJ1c3NlbERpc3RhbmNlLFxuICBzb2thbERpc3RhbmNlLFxuICB0YW5pbW90b0Rpc3RhbmNlLFxuICBudW1lcmljRGlzdGFuY2UsXG4gIHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSxcbn0gZnJvbSAnLi4vZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzJztcblxuaW1wb3J0IHtjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZX0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdmVjdG9yLW9wZXJhdGlvbnMnO1xuaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQge1ZlY3RvciwgU3RyaW5nRGljdGlvbmFyeX0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdHlwZS1kZWNsYXJhdGlvbnMnO1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25zLCBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXN9IGZyb20gJy4uL21hY3JvbW9sZWN1bGUtZGlzdGFuY2UtZnVuY3Rpb25zJztcbmltcG9ydCB7RGlzdGFuY2VNZXRyaWNzU3ViamVjdHMsIEJpdEFycmF5TWV0cmljc05hbWVzLFxuICBTdHJpbmdNZXRyaWNzTmFtZXMsIFZlY3Rvck1ldHJpY3NOYW1lcywgTnVtYmVyTWV0cmljc05hbWVzLCBJbnRBcnJheU1ldHJpY3NOYW1lc30gZnJvbSAnLi9jb25zdHMnO1xuXG5cbmV4cG9ydCBjb25zdCB2ZWN0b3JEaXN0YW5jZU1ldHJpY3NNZXRob2RzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogVmVjdG9yLCB5OiBWZWN0b3IpID0+IG51bWJlciB9ID0ge1xuICBbVmVjdG9yTWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IHN0cmluZ0Rpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBzdHJpbmcsIHk6IHN0cmluZykgPT4gbnVtYmVyIH0gPSB7XG4gIFtTdHJpbmdNZXRyaWNzTmFtZXMuTGV2ZW5zaHRlaW5dOiBmbC5kaXN0YW5jZSxcbiAgW1N0cmluZ01ldHJpY3NOYW1lcy5KYXJvV2lua2xlcl06IGphcm9XaW5rbGVyLFxuICBbU3RyaW5nTWV0cmljc05hbWVzLk1hbmhhdHRhbl06IG1hbmhhdHRhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kczogeyBbbmFtZTogc3RyaW5nXTogKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSkgPT4gbnVtYmVyIH0gPSB7XG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b106IHRhbmltb3RvRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXTogZGljZURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpY106IGFzeW1tZXRyaWNEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkJyYXVuQmxhbnF1ZXRdOiBicmF1bkJsYW5xdWV0RGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdOiBjb3NpbmVEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkt1bGN6eW5za2ldOiBrdWxjenluc2tpRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldOiBtY0Nvbm5hdWdoZXlEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddOiByb2dvdEdvbGRiZXJnRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5SdXNzZWxdOiBydXNzZWxEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXTogc29rYWxEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkhhbW1pbmddOiBoYW1taW5nRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5FdWNsaWRlYW5dOiBldWNsaWRlYW5EaXN0YW5jZSxcbn07XG5cbmV4cG9ydCBjb25zdCBpbnRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBVaW50MzJBcnJheSwgeTogVWludDMyQXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbSW50QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9JbnRBcnJheV06IHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSxcbn07XG5cbmV4cG9ydCBjb25zdCBudW1iZXJEaXN0YW5jZU1ldHJpY3NNZXRob2RzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IG51bWJlciB9ID0ge1xuICBbTnVtYmVyTWV0cmljc05hbWVzLk51bWVyaWNEaXN0YW5jZV06IG51bWVyaWNEaXN0YW5jZSxcbn07XG5cbmV4cG9ydCBjb25zdCBBdmFpbGFibGVNZXRyaWNzID0ge1xuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuVmVjdG9yXToge1xuICAgIFtWZWN0b3JNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXTogdmVjdG9yRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tWZWN0b3JNZXRyaWNzTmFtZXMuRXVjbGlkZWFuXSxcbiAgfSxcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLlN0cmluZ106IHtcbiAgICBbU3RyaW5nTWV0cmljc05hbWVzLkxldmVuc2h0ZWluXTogc3RyaW5nRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tTdHJpbmdNZXRyaWNzTmFtZXMuTGV2ZW5zaHRlaW5dLFxuICAgIFtTdHJpbmdNZXRyaWNzTmFtZXMuSmFyb1dpbmtsZXJdOiBzdHJpbmdEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1N0cmluZ01ldHJpY3NOYW1lcy5KYXJvV2lua2xlcl0sXG4gICAgW1N0cmluZ01ldHJpY3NOYW1lcy5NYW5oYXR0YW5dOiBzdHJpbmdEaXN0YW5jZU1ldHJpY3NNZXRob2RzW1N0cmluZ01ldHJpY3NOYW1lcy5NYW5oYXR0YW5dLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuQml0QXJyYXldOiB7XG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpY106IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQnJhdW5CbGFucXVldF06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLkt1bGN6eW5za2ldOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLk1jQ29ubmF1Z2hleV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5SdXNzZWxdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdLFxuICB9LFxuICBbRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMuTWFjcm9Nb2xlY3VsZV06IHsgLy8gb3B0aW9uYWwgYXJncyBuZWVkZWQgZm9yIG1hY3JvbW9sZWN1bGUgZnVuY3Rpb25zIHdoaWNoIGluaXRpYWxpemUgdGhlbVxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuSEFNTUlOR106IG1tRGlzdGFuY2VGdW5jdGlvbnNbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkddLFxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU5dOiBtbURpc3RhbmNlRnVuY3Rpb25zW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5MRVZFTlNIVEVJTl0sXG4gICAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5ORUVETEVNQU5OX1dVTlNDSF06IG1tRGlzdGFuY2VGdW5jdGlvbnNbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk5FRURMRU1BTk5fV1VOU0NIXSxcbiAgICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk1PTk9NRVJfQ0hFTUlDQUxfRElTVEFOQ0VdOiBtbURpc3RhbmNlRnVuY3Rpb25zW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5NT05PTUVSX0NIRU1JQ0FMX0RJU1RBTkNFXSxcbiAgfSxcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLk51bWJlcl06IHtcbiAgICBbTnVtYmVyTWV0cmljc05hbWVzLk51bWVyaWNEaXN0YW5jZV06IG51bWJlckRpc3RhbmNlTWV0cmljc01ldGhvZHNbTnVtYmVyTWV0cmljc05hbWVzLk51bWVyaWNEaXN0YW5jZV0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5JbnRBcnJheV06IHtcbiAgICBbSW50QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9JbnRBcnJheV06IGludEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tJbnRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b0ludEFycmF5XSxcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IE1ldHJpY1RvRGF0YVR5cGU6IFN0cmluZ0RpY3Rpb25hcnkgPSBPYmplY3Qua2V5cyhBdmFpbGFibGVNZXRyaWNzKVxuICAucmVkdWNlKChyZXQ6IFN0cmluZ0RpY3Rpb25hcnksIGtleSkgPT4ge1xuICAgIGZvciAoY29uc3QgdmFsIG9mIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3Nba2V5IGFzIEF2YWlsYWJsZURhdGFUeXBlc10pKVxuICAgICAgcmV0W3ZhbCBhcyBBdmFpbGFibGVEYXRhVHlwZXNdID0ga2V5O1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfSwge30pO1xuXG5leHBvcnQgdHlwZSBBdmFpbGFibGVEYXRhVHlwZXMgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljcztcbmV4cG9ydCB0eXBlIFZlY3Rvck1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5WZWN0b3JdO1xuZXhwb3J0IHR5cGUgU3RyaW5nTWV0cmljcyA9IGtleW9mIHR5cGVvZiBBdmFpbGFibGVNZXRyaWNzW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLlN0cmluZ107XG5leHBvcnQgdHlwZSBCaXRBcnJheU1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5CaXRBcnJheV07XG5leHBvcnQgdHlwZSBLbm93bk1ldHJpY3MgPSBTdHJpbmdNZXRyaWNzIHwgQml0QXJyYXlNZXRyaWNzIHwgVmVjdG9yTWV0cmljcyB8XG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB8IE51bWJlck1ldHJpY3NOYW1lcyB8IEludEFycmF5TWV0cmljc05hbWVzO1xuXG5leHBvcnQgdHlwZSBWYWxpZFR5cGVzID1cbiAgeyBkYXRhOiBzdHJpbmdbXSwgbWV0cmljOiBTdHJpbmdNZXRyaWNzIHwgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzIH0gfFxuICB7IGRhdGE6IFZlY3RvcltdLCBtZXRyaWM6IFZlY3Rvck1ldHJpY3MgfSB8XG4gIHsgZGF0YTogQml0QXJyYXlbXSwgbWV0cmljOiBCaXRBcnJheU1ldHJpY3MgfSB8XG4gIHsgZGF0YTogbnVtYmVyW10sIG1ldHJpYzogTnVtYmVyTWV0cmljc05hbWVzIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZ01ldHJpYyhuYW1lOiBLbm93bk1ldHJpY3MpIHtcbiAgcmV0dXJuIE1ldHJpY1RvRGF0YVR5cGVbbmFtZV0gPT0gJ1N0cmluZyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0JpdEFycmF5TWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSAnQml0QXJyYXknO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZWN0b3JNZXRyaWMobmFtZTogS25vd25NZXRyaWNzKSB7XG4gIHJldHVybiBNZXRyaWNUb0RhdGFUeXBlW25hbWVdID09ICdWZWN0b3InO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNYWNyb01vbGVjdWxlTWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSBEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5NYWNyb01vbGVjdWxlLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBNYW5oYXR0YW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gc2VxdWVuY2VzIChtYXRjaCAtIDAsIG1pc21hdGNoIC0gMSkgbm9ybWFsaXplZCBmb3IgbGVuZ3RoLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hbmhhdHRhbkRpc3RhbmNlKHMxOiBzdHJpbmcsIHMyOiBzdHJpbmcpOiBudW1iZXIge1xuICBpZiAoczEubGVuZ3RoICE9PSBzMi5sZW5ndGgpIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgZGlzdDogbnVtYmVyID0gMDtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHMxLmxlbmd0aDsgaSsrKVxuICAgICAgZGlzdCArPSBzMVtpXSA9PSBzMltpXSA/IDAgOiAxO1xuICAgIHJldHVybiBkaXN0IC8gczEubGVuZ3RoO1xuICB9XG59XG5cbi8qKiBVbmlmaWVkIGNsYXNzIGltcGxlbWVudGluZyBkaWZmZXJlbnQgc3RyaW5nIG1lYXN1cmVzLiAqL1xuZXhwb3J0IGNsYXNzIE1lYXN1cmUge1xuICBwcm90ZWN0ZWQgbWV0aG9kOiBLbm93bk1ldHJpY3M7XG4gIHByb3RlY3RlZCBkYXRhVHlwZTogQXZhaWxhYmxlRGF0YVR5cGVzO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIE1lYXN1cmUgd2l0aCAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QgTWV0aG9kIHRvIGNhbGN1bGF0ZSBkaXN0YW5jZSBiZXR3ZWVuIHN0cmluZ3MuXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgY29uc3RydWN0b3IobWV0aG9kOiBLbm93bk1ldHJpY3MpIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgICB0aGlzLmRhdGFUeXBlID0gTWV0cmljVG9EYXRhVHlwZVttZXRob2RdIGFzIEF2YWlsYWJsZURhdGFUeXBlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGN1c3RvbSBzdHJpbmcgZGlzdGFuY2UgZnVuY3Rpb24gc3BlY2lmaWVkLlxuICAgKiBAcGFyYW0ge29wdHN9IG9wdHMgT3B0aW9ucyBmb3IgdGhlIG1lYXN1cmUuIHVzZWQgZm9yIG1hY3JvbW9sZWN1bGUgZGlzdGFuY2VzXG4gICAqIEByZXR1cm4ge0Rpc3RhbmNlTWV0cmljfSBDYWxsYmFjayBvZiB0aGUgbWVhc3VyZSBjaG9zZW4uXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgcHVibGljIGdldE1lYXN1cmUob3B0cz86IGFueSk6IERpc3RhbmNlTWV0cmljIHtcbiAgICBjb25zdCBkaWN0OiB7IFtrZXk6IHN0cmluZ106XG4gICAgICB7W2tleTI6IHN0cmluZ106IERpc3RhbmNlTWV0cmljIHwgKChvcHRzOiBhbnkpID0+IERpc3RhbmNlTWV0cmljKX1cbiAgICB9ID0gQXZhaWxhYmxlTWV0cmljcztcbiAgICBpZiAoIWRpY3QuaGFzT3duUHJvcGVydHkodGhpcy5kYXRhVHlwZSkgfHwgIWRpY3RbdGhpcy5kYXRhVHlwZV0uaGFzT3duUHJvcGVydHkodGhpcy5tZXRob2QpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIG1lYXN1cmUgJHt0aGlzLm1ldGhvZH0gZm9yIGRhdGEgdHlwZSAke3RoaXMuZGF0YVR5cGV9YCk7XG4gICAgcmV0dXJuIGlzTWFjcm9Nb2xlY3VsZU1ldHJpYyh0aGlzLm1ldGhvZCkgP1xuICAgICAgKGRpY3RbdGhpcy5kYXRhVHlwZV1bdGhpcy5tZXRob2RdIGFzICgob3B0czogYW55KSA9PiBEaXN0YW5jZU1ldHJpYykpKG9wdHMpIDpcbiAgICAgIGRpY3RbdGhpcy5kYXRhVHlwZV1bdGhpcy5tZXRob2RdIGFzIERpc3RhbmNlTWV0cmljO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgY3VzdG9tIHN0cmluZyBkaXN0YW5jZSBieSB0aGUgZ2l2ZW4gZGF0YSB0eXBlLlxuICAgKiBAcGFyYW0ge0F2YWlsYWJsZURhdGFUeXBlc30gZGF0YVR5cGUgTWV0cmljJ3MgZGF0YSB0eXBlXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBNZXRyaWMgbmFtZXMgd2hpY2ggZXhwZWN0cyB0aGUgZ2l2ZW4gZGF0YSB0eXBlXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBnZXRNZXRyaWNCeURhdGFUeXBlKGRhdGFUeXBlOiBBdmFpbGFibGVEYXRhVHlwZXMpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3NbZGF0YVR5cGVdKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIG1ldHJpYyBuYW1lcyBhdmFpbGFibGUuXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgc3RhdGljIGdldCBhdmFpbGFibGVNZWFzdXJlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3MpO1xuICB9XG59XG4iXX0=","/**\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 (let item of vec) {\n result += item ** 2;\n }\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 }\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 }\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 }\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 }\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 }\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFJSDs7R0FFRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsQ0FBUyxFQUFFLE1BQWdCO0lBQ3BELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLE1BQWdCO0lBQ3RDLE9BQU8sTUFBTSxFQUFFLENBQUM7QUFDbEIsQ0FBQztBQUNEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FBQyxHQUFhO0lBQ2hDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNmLEtBQUssSUFBSSxJQUFJLElBQUksR0FBRyxFQUFFO1FBQ3BCLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDO0tBQ3JCO0lBQ0QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzNCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxLQUFLLENBQUMsQ0FBUztJQUM3QixNQUFNLE1BQU0sR0FBZ0IsRUFBRSxDQUFDO0lBQy9CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDMUIsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUN4QjtJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxLQUFLLENBQUMsQ0FBUztJQUM3QixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FB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QUMsQ0FBQztTQUNaO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNmLEtBQUssSUFBSSxDQUFDLENBQUM7S0FDWjtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCB7IFJhbmRvbUZuIH0gZnJvbSAnLi91bWFwJztcblxuLyoqXG4gKiBTaW1wbGUgcmFuZG9tIGludGVnZXIgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRhdVJhbmRJbnQobjogbnVtYmVyLCByYW5kb206IFJhbmRvbUZuKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKHJhbmRvbSgpICogbik7XG59XG5cbi8qKlxuICogU2ltcGxlIHJhbmRvbSBmbG9hdCBmdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdGF1UmFuZChyYW5kb206IFJhbmRvbUZuKSB7XG4gIHJldHVybiByYW5kb20oKTtcbn1cbi8qKlxuICogQ29tcHV0ZSB0aGUgKHN0YW5kYXJkIGwyKSBub3JtIG9mIGEgdmVjdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybSh2ZWM6IG51bWJlcltdKSB7XG4gIGxldCByZXN1bHQgPSAwO1xuICBmb3IgKGxldCBpdGVtIG9mIHZlYykge1xuICAgIHJlc3VsdCArPSBpdGVtICoqIDI7XG4gIH1cbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4gZW1wdHkgYXJyYXkgKGZpbGxlZCB3aXRoIHVuZGVmaW5lZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtcHR5KG46IG51bWJlcik6IHVuZGVmaW5lZFtdIHtcbiAgY29uc3Qgb3V0cHV0OiB1bmRlZmluZWRbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgIG91dHB1dC5wdXNoKHVuZGVmaW5lZCk7XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGluZGV4IHZhbHVlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2UobjogbnVtYmVyKTogbnVtYmVyW10ge1xuICByZXR1cm4gZW1wdHkobikubWFwKChfLCBpKSA9PiBpKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGEgc3BlY2lmaWMgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGxlZChuOiBudW1iZXIsIHY6IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGVtcHR5KG4pLm1hcCgoKSA9PiB2KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIHplcm9zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvcyhuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBmaWxsZWQobiwgMCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBmaWxsZWQgd2l0aCBvbmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVzKG46IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGZpbGxlZChuLCAxKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZyb20gYSB0byBiLCBvZiBsZW5ndGggbGVuLCBpbmNsdXNpdmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhcihhOiBudW1iZXIsIGI6IG51bWJlciwgbGVuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBlbXB0eShsZW4pLm1hcCgoXywgaSkgPT4ge1xuICAgIHJldHVybiBhICsgaSAqICgoYiAtIGEpIC8gKGxlbiAtIDEpKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3VtIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdW0oaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgcmV0dXJuIGlucHV0LnJlZHVjZSgoc3VtLCB2YWwpID0+IHN1bSArIHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWVhbiBvZiBhbiBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVhbihpbnB1dDogbnVtYmVyW10pOiBudW1iZXIge1xuICByZXR1cm4gc3VtKGlucHV0KSAvIGlucHV0Lmxlbmd0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgoaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgbGV0IG1heCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICBtYXggPSBpbnB1dFtpXSA+IG1heCA/IGlucHV0W2ldIDogbWF4O1xuICB9XG4gIHJldHVybiBtYXg7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZSBvZiBhIDJkIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgyZChpbnB1dDogbnVtYmVyW11bXSk6IG51bWJlciB7XG4gIGxldCBtYXggPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dFtpXS5sZW5ndGg7IGorKykge1xuICAgICAgbWF4ID0gaW5wdXRbaV1bal0gPiBtYXggPyBpbnB1dFtpXVtqXSA6IG1heDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1heDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBuU2FtcGxlcyBtYW55IGludGVnZXJzIGZyb20gMCB0byBwb29sU2l6ZSBzdWNoIHRoYXQgbm9cbiAqIGludGVnZXIgaXMgc2VsZWN0ZWQgdHdpY2UuIFRoZSBkdXBsaWNhdGlvbiBjb25zdHJhaW50IGlzIGFjaGlldmVkIHZpYVxuICogcmVqZWN0aW9uIHNhbXBsaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVqZWN0aW9uU2FtcGxlKFxuICBuU2FtcGxlczogbnVtYmVyLFxuICBwb29sU2l6ZTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBudW1iZXJbXSB7XG4gIGNvbnN0IHJlc3VsdCA9IHplcm9zKG5TYW1wbGVzKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuU2FtcGxlczsgaSsrKSB7XG4gICAgbGV0IHJlamVjdFNhbXBsZSA9IHRydWU7XG4gICAgd2hpbGUgKHJlamVjdFNhbXBsZSkge1xuICAgICAgY29uc3QgaiA9IHRhdVJhbmRJbnQocG9vbFNpemUsIHJhbmRvbSk7XG4gICAgICBsZXQgYnJva2VuID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykge1xuICAgICAgICBpZiAoaiA9PT0gcmVzdWx0W2tdKSB7XG4gICAgICAgICAgYnJva2VuID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFicm9rZW4pIHtcbiAgICAgICAgcmVqZWN0U2FtcGxlID0gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXN1bHRbaV0gPSBqO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJlc2hhcGVzIGEgMWQgYXJyYXkgaW50byBhIDJEIG9mIGdpdmVuIGRpbWVuc2lvbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNoYXBlMmQ8VD4oeDogVFtdLCBhOiBudW1iZXIsIGI6IG51bWJlcik6IFRbXVtdIHtcbiAgY29uc3Qgcm93czogVFtdW10gPSBbXTtcbiAgbGV0IGNvdW50ID0gMDtcbiAgbGV0IGluZGV4ID0gMDtcblxuICBpZiAoeC5sZW5ndGggIT09IGEgKiBiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBkaW1lbnNpb25zIG11c3QgbWF0Y2ggaW5wdXQgbGVuZ3RoLicpO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhOyBpKyspIHtcbiAgICBjb25zdCBjb2w6IFRbXSA9IFtdO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgYjsgaisrKSB7XG4gICAgICBjb2wucHVzaCh4W2luZGV4XSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cbiAgICByb3dzLnB1c2goY29sKTtcbiAgICBjb3VudCArPSAxO1xuICB9XG4gIHJldHVybiByb3dzO1xufVxuIl19","/**\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 }\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 }\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 }\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 }\n else {\n break;\n }\n }\n else if (weights[ic1] >= weights[ic2]) {\n if (weight < weights[ic1]) {\n iSwap = ic1;\n }\n else {\n break;\n }\n }\n else {\n if (weight < weights[ic2]) {\n iSwap = ic2;\n }\n else {\n break;\n }\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 }\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 }\n if (rightChild < ceiling && heap1[swap] < heap1[rightChild]) {\n swap = rightChild;\n }\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhlYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBMkNILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsT0FBZSxFQUFFLElBQVk7SUFDcEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxTQUFpQixFQUFFLEVBQUU7UUFDdkMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDbkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztJQUVGLE1BQU0sSUFBSSxHQUFTLEVBQUUsQ0FBQztJQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUM3QixRQUFnQixFQUNoQixRQUFnQixFQUNoQixNQUFnQjtJQUVoQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDakMsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMs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SSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUxQixJQUFJLE9BQU8sR0FBRyxRQUFRLENBQUM7SUFDdkIsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDbkMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUU7WUFDdEMsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsQixXQUFXLEdBQUcsQ0FBQyxDQUFDO1NBQ2pCO0tBQ0Y7SUFFRCxJQUFJLFdBQVcsSUFBSSxDQUFDLEVBQUU7UUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN0QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7S0FDckM7U0FBTTtRQUNMLE9BQU8sQ0FBQyxDQUFDLENBQUM7S0FDWDtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgeyBSYW5kb21GbiB9IGZyb20gJy4vdW1hcCc7XG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IHR5cGUgSGVhcCA9IG51bWJlcltdW11bXTtcblxuLyoqXG4gKiAgQ29uc3RydWN0b3IgZm9yIHRoZSBoZWFwIG9iamVjdHMuIFRoZSBoZWFwcyBhcmUgdXNlZFxuICogZm9yIGFwcHJveGltYXRlIG5lYXJlc3QgbmVpZ2hib3Igc2VhcmNoLCBtYWludGFpbmluZyBhIGxpc3Qgb2YgcG90ZW50aWFsXG4gKiBuZWlnaGJvcnMgc29ydGVkIGJ5IHRoZWlyIGRpc3RhbmNlLiBXZSBhbHNvIGZsYWcgaWYgcG90ZW50aWFsIG5laWdoYm9yc1xuICogYXJlIG5ld2x5IGFkZGVkIHRvIHRoZSBsaXN0IG9yIG5vdC4gSW50ZXJuYWxseSB0aGlzIGlzIHN0b3JlZCBhc1xuICogYSBzaW5nbGUgYXJyYXk7IHRoZSBmaXJzdCBheGlzIGRldGVybWluZXMgd2hldGhlciB3ZSBhcmUgbG9va2luZyBhdCB0aGVcbiAqIGFycmF5IG9mIGNhbmRpZGF0ZSBpbmRpY2VzLCB0aGUgYXJyYXkgb2YgZGlzdGFuY2VzLCBvciB0aGUgZmxhZyBhcnJheSBmb3JcbiAqIHdoZXRoZXIgZWxlbWVudHMgYXJlIG5ldyBvciBub3QuIEVhY2ggb2YgdGhlc2UgYXJyYXlzIGFyZSBvZiBzaGFwZVxuICogKGBgblBvaW50c2BgLCBgYHNpemVgYClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VIZWFwKG5Qb2ludHM6IG51bWJlciwgc2l6ZTogbnVtYmVyKTogSGVhcCB7XG4gIGNvbnN0IG1ha2VBcnJheXMgPSAoZmlsbFZhbHVlOiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gdXRpbHMuZW1wdHkoblBvaW50cykubWFwKCgpID0+IHtcbiAgICAgIHJldHVybiB1dGlscy5maWxsZWQoc2l6ZSwgZmlsbFZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBoZWFwOiBIZWFwID0gW107XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKC0xKSk7XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKEluZmluaXR5KSk7XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKDApKTtcbiAgcmV0dXJuIGhlYXA7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgbl9zYW1wbGVzIG1hbnkgaW50ZWdlcnMgZnJvbSAwIHRvIHBvb2xfc2l6ZSBzdWNoIHRoYXQgbm9cbiAqIGludGVnZXIgaXMgc2VsZWN0ZWQgdHdpY2UuIFRoZSBkdXBsaWNhdGlvbiBjb25zdHJhaW50IGlzIGFjaGlldmVkIHZpYVxuICogcmVqZWN0aW9uIHNhbXBsaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVqZWN0aW9uU2FtcGxlKFxuICBuU2FtcGxlczogbnVtYmVyLFxuICBwb29sU2l6ZTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgY29uc3QgcmVzdWx0ID0gdXRpbHMuemVyb3MoblNhbXBsZXMpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHtcbiAgICBsZXQgcmVqZWN0U2FtcGxlID0gdHJ1ZTtcbiAgICBsZXQgaiA9IDA7XG4gICAgd2hpbGUgKHJlamVjdFNhbXBsZSkge1xuICAgICAgaiA9IHV0aWxzLnRhdVJhbmRJbnQocG9vbFNpemUsIHJhbmRvbSk7XG4gICAgICBsZXQgYnJva2VuID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykge1xuICAgICAgICBpZiAoaiA9PT0gcmVzdWx0W2tdKSB7XG4gICAgICAgICAgYnJva2VuID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFicm9rZW4pIHJlamVjdFNhbXBsZSA9IGZhbHNlO1xuICAgIH1cbiAgICByZXN1bHRbaV0gPSBqO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUHVzaCBhIG5ldyBlbGVtZW50IG9udG8gdGhlIGhlYXAuIFRoZSBoZWFwIHN0b3JlcyBwb3RlbnRpYWwgbmVpZ2hib3JzXG4gKiBmb3IgZWFjaCBkYXRhIHBvaW50LiBUaGUgYGByb3dgYCBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB3aGljaCBkYXRhIHBvaW50IHdlXG4gKiBhcmUgYWRkcmVzc2luZywgdGhlIGBgd2VpZ2h0YGAgZGV0ZXJtaW5lcyB0aGUgZGlzdGFuY2UgKGZvciBoZWFwIHNvcnRpbmcpLFxuICogdGhlIGBgaW5kZXhgYCBpcyB0aGUgZWxlbWVudCB0byBhZGQsIGFuZCB0aGUgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhpc1xuICogaXMgdG8gYmUgY29uc2lkZXJlZCBhIG5ldyBhZGRpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhlYXBQdXNoKFxuICBoZWFwOiBIZWFwLFxuICByb3c6IG51bWJlcixcbiAgd2VpZ2h0OiBudW1iZXIsXG4gIGluZGV4OiBudW1iZXIsXG4gIGZsYWc6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgcm93ID0gTWF0aC5mbG9vcihyb3cpO1xuICBjb25zdCBpbmRpY2VzID0gaGVhcFswXVtyb3ddO1xuICBjb25zdCB3ZWlnaHRzID0gaGVhcFsxXVtyb3ddO1xuICBjb25zdCBpc05ldyA9IGhlYXBbMl1bcm93XTtcblxuICBpZiAod2VpZ2h0ID49IHdlaWdodHNbMF0pIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8vIEJyZWFrIGlmIHdlIGFscmVhZHkgaGF2ZSB0aGlzIGVsZW1lbnQuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpbmRleCA9PT0gaW5kaWNlc1tpXSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuY2hlY2tlZEhlYXBQdXNoKGhlYXAsIHJvdywgd2VpZ2h0LCBpbmRleCwgZmxhZyk7XG59XG5cbi8qKlxuICogUHVzaCBhIG5ldyBlbGVtZW50IG9udG8gdGhlIGhlYXAuIFRoZSBoZWFwIHN0b3JlcyBwb3RlbnRpYWwgbmVpZ2hib3JzXG4gKiBmb3IgZWFjaCBkYXRhIHBvaW50LiBUaGUgYGByb3dgYCBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB3aGljaCBkYXRhIHBvaW50IHdlXG4gKiBhcmUgYWRkcmVzc2luZywgdGhlIGBgd2VpZ2h0YGAgZGV0ZXJtaW5lcyB0aGUgZGlzdGFuY2UgKGZvciBoZWFwIHNvcnRpbmcpLFxuICogdGhlIGBgaW5kZXhgYCBpcyB0aGUgZWxlbWVudCB0byBhZGQsIGFuZCB0aGUgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhpc1xuICogaXMgdG8gYmUgY29uc2lkZXJlZCBhIG5ldyBhZGRpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuY2hlY2tlZEhlYXBQdXNoKFxuICBoZWFwOiBIZWFwLFxuICByb3c6IG51bWJlcixcbiAgd2VpZ2h0OiBudW1iZXIsXG4gIGluZGV4OiBudW1iZXIsXG4gIGZsYWc6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgY29uc3QgaW5kaWNlcyA9IGhlYXBbMF1bcm93XTtcbiAgY29uc3Qgd2VpZ2h0cyA9IGhlYXBbMV1bcm93XTtcbiAgY29uc3QgaXNOZXcgPSBoZWFwWzJdW3Jvd107XG5cbiAgaWYgKHdlaWdodCA+PSB3ZWlnaHRzWzBdKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvLyBJbnNlcnQgdmFsIGF0IHBvc2l0aW9uIHplcm9cbiAgd2VpZ2h0c1swXSA9IHdlaWdodDtcbiAgaW5kaWNlc1swXSA9IGluZGV4O1xuICBpc05ld1swXSA9IGZsYWc7XG5cbiAgLy8gRGVzY2VuZCB0aGUgaGVhcCwgc3dhcHBpbmcgdmFsdWVzIHVudGlsIHRoZSBtYXggaGVhcCBjcml0ZXJpb24gaXMgbWV0XG4gIGxldCBpID0gMDtcbiAgbGV0IGlTd2FwID0gMDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCBpYzEgPSAyICogaSArIDE7XG4gICAgY29uc3QgaWMyID0gaWMxICsgMTtcblxuICAgIGNvbnN0IGhlYXBTaGFwZTIgPSBoZWFwWzBdWzBdLmxlbmd0aDtcbiAgICBpZiAoaWMxID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoaWMyID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGlmICh3ZWlnaHRzW2ljMV0gPiB3ZWlnaHQpIHtcbiAgICAgICAgaVN3YXAgPSBpYzE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHdlaWdodHNbaWMxXSA+PSB3ZWlnaHRzW2ljMl0pIHtcbiAgICAgIGlmICh3ZWlnaHQgPCB3ZWlnaHRzW2ljMV0pIHtcbiAgICAgICAgaVN3YXAgPSBpYzE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHdlaWdodCA8IHdlaWdodHNbaWMyXSkge1xuICAgICAgICBpU3dhcCA9IGljMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdlaWdodHNbaV0gPSB3ZWlnaHRzW2lTd2FwXTtcbiAgICBpbmRpY2VzW2ldID0gaW5kaWNlc1tpU3dhcF07XG4gICAgaXNOZXdbaV0gPSBpc05ld1tpU3dhcF07XG5cbiAgICBpID0gaVN3YXA7XG4gIH1cblxuICB3ZWlnaHRzW2ldID0gd2VpZ2h0O1xuICBpbmRpY2VzW2ldID0gaW5kZXg7XG4gIGlzTmV3W2ldID0gZmxhZztcbiAgcmV0dXJuIDE7XG59XG5cbi8qKlxuICogQnVpbGQgYSBoZWFwIG9mIGNhbmRpZGF0ZSBuZWlnaGJvcnMgZm9yIG5lYXJlc3QgbmVpZ2hib3IgZGVzY2VudC4gRm9yXG4gKiBlYWNoIHZlcnRleCB0aGUgY2FuZGlkYXRlIG5laWdoYm9ycyBhcmUgYW55IGN1cnJlbnQgbmVpZ2hib3JzLCBhbmQgYW55XG4gKiB2ZXJ0aWNlcyB0aGF0IGhhdmUgdGhlIHZlcnRleCBhcyBvbmUgb2YgdGhlaXIgbmVhcmVzdCBuZWlnaGJvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENhbmRpZGF0ZXMoXG4gIGN1cnJlbnRHcmFwaDogSGVhcCxcbiAgblZlcnRpY2VzOiBudW1iZXIsXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgbWF4Q2FuZGlkYXRlczogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgY29uc3QgY2FuZGlkYXRlTmVpZ2hib3JzID0gbWFrZUhlYXAoblZlcnRpY2VzLCBtYXhDYW5kaWRhdGVzKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuVmVydGljZXM7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICBpZiAoY3VycmVudEdyYXBoWzBdW2ldW2pdIDwgMCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGlkeCA9IGN1cnJlbnRHcmFwaFswXVtpXVtqXTtcbiAgICAgIGNvbnN0IGlzbiA9IGN1cnJlbnRHcmFwaFsyXVtpXVtqXTtcbiAgICAgIGNvbnN0IGQgPSB1dGlscy50YXVSYW5kKHJhbmRvbSk7XG4gICAgICBoZWFwUHVzaChjYW5kaWRhdGVOZWlnaGJvcnMsIGksIGQsIGlkeCwgaXNuKTtcbiAgICAgIGhlYXBQdXNoKGNhbmRpZGF0ZU5laWdoYm9ycywgaWR4LCBkLCBpLCBpc24pO1xuICAgICAgY3VycmVudEdyYXBoWzJdW2ldW2pdID0gMDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNhbmRpZGF0ZU5laWdoYm9ycztcbn1cblxuLyoqXG4gKiBHaXZlbiBhbiBhcnJheSBvZiBoZWFwcyAob2YgaW5kaWNlcyBhbmQgd2VpZ2h0cyksIHVucGFjayB0aGUgaGVhcFxuICogb3V0IHRvIGdpdmUgYW5kIGFycmF5IG9mIHNvcnRlZCBsaXN0cyBvZiBpbmRpY2VzIGFuZCB3ZWlnaHRzIGJ5IGluY3JlYXNpbmdcbiAqIHdlaWdodC4gVGhpcyBpcyBlZmZlY3RpdmVseSBqdXN0IHRoZSBzZWNvbmQgaGFsZiBvZiBoZWFwIHNvcnQgKHRoZSBmaXJzdFxuICogaGFsZiBub3QgYmVpbmcgcmVxdWlyZWQgc2luY2Ugd2UgYWxyZWFkeSBoYXZlIHRoZSBkYXRhIGluIGEgaGVhcCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWhlYXBTb3J0KGhlYXA6IEhlYXApIHtcbiAgY29uc3QgaW5kaWNlcyA9IGhlYXBbMF07XG4gIGNvbnN0IHdlaWdodHMgPSBoZWFwWzFdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGluZEhlYXAgPSBpbmRpY2VzW2ldO1xuICAgIGNvbnN0IGRpc3RIZWFwID0gd2VpZ2h0c1tpXTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kSGVhcC5sZW5ndGggLSAxOyBqKyspIHtcbiAgICAgIGNvbnN0IGluZEhlYXBJbmRleCA9IGluZEhlYXAubGVuZ3RoIC0gaiAtIDE7XG4gICAgICBjb25zdCBkaXN0SGVhcEluZGV4ID0gZGlzdEhlYXAubGVuZ3RoIC0gaiAtIDE7XG5cbiAgICAgIGNvbnN0IHRlbXAxID0gaW5kSGVhcFswXTtcbiAgICAgIGluZEhlYXBbMF0gPSBpbmRIZWFwW2luZEhlYXBJbmRleF07XG4gICAgICBpbmRIZWFwW2luZEhlYXBJbmRleF0gPSB0ZW1wMTtcblxuICAgICAgY29uc3QgdGVtcDIgPSBkaXN0SGVhcFswXTtcbiAgICAgIGRpc3RIZWFwWzBdID0gZGlzdEhlYXBbZGlzdEhlYXBJbmRleF07XG4gICAgICBkaXN0SGVhcFtkaXN0SGVhcEluZGV4XSA9IHRlbXAyO1xuXG4gICAgICBzaWZ0RG93bihkaXN0SGVhcCwgaW5kSGVhcCwgZGlzdEhlYXBJbmRleCwgMCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IGluZGljZXMsIHdlaWdodHMgfTtcbn1cblxuLyoqXG4gKiBSZXN0b3JlIHRoZSBoZWFwIHByb3BlcnR5IGZvciBhIGhlYXAgd2l0aCBhbiBvdXQgb2YgcGxhY2UgZWxlbWVudFxuICogYXQgcG9zaXRpb24gYGBlbHRgYC4gVGhpcyB3b3JrcyB3aXRoIGEgaGVhcCBwYWlyIHdoZXJlIGhlYXAxIGNhcnJpZXNcbiAqIHRoZSB3ZWlnaHRzIGFuZCBoZWFwMiBob2xkcyB0aGUgY29ycmVzcG9uZGluZyBlbGVtZW50cy5cbiAqL1xuZnVuY3Rpb24gc2lmdERvd24oXG4gIGhlYXAxOiBudW1iZXJbXSxcbiAgaGVhcDI6IG51bWJlcltdLFxuICBjZWlsaW5nOiBudW1iZXIsXG4gIGVsdDogbnVtYmVyXG4pIHtcbiAgd2hpbGUgKGVsdCAqIDIgKyAxIDwgY2VpbGluZykge1xuICAgIGNvbnN0IGxlZnRDaGlsZCA9IGVsdCAqIDIgKyAxO1xuICAgIGNvbnN0IHJpZ2h0Q2hpbGQgPSBsZWZ0Q2hpbGQgKyAxO1xuICAgIGxldCBzd2FwID0gZWx0O1xuXG4gICAgaWYgKGhlYXAxW3N3YXBdIDwgaGVhcDFbbGVmdENoaWxkXSkge1xuICAgICAgc3dhcCA9IGxlZnRDaGlsZDtcbiAgICB9XG4gICAgaWYgKHJpZ2h0Q2hpbGQgPCBjZWlsaW5nICYmIGhlYXAxW3N3YXBdIDwgaGVhcDFbcmlnaHRDaGlsZF0pIHtcbiAgICAgIHN3YXAgPSByaWdodENoaWxkO1xuICAgIH1cblxuICAgIGlmIChzd2FwID09PSBlbHQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0ZW1wMSA9IGhlYXAxW2VsdF07XG4gICAgICBoZWFwMVtlbHRdID0gaGVhcDFbc3dhcF07XG4gICAgICBoZWFwMVtzd2FwXSA9IHRlbXAxO1xuXG4gICAgICBjb25zdCB0ZW1wMiA9IGhlYXAyW2VsdF07XG4gICAgICBoZWFwMltlbHRdID0gaGVhcDJbc3dhcF07XG4gICAgICBoZWFwMltzd2FwXSA9IHRlbXAyO1xuICAgICAgZWx0ID0gc3dhcDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBTZWFyY2ggdGhlIGhlYXAgZm9yIHRoZSBzbWFsbGVzdCBlbGVtZW50IHRoYXQgaXMgc3RpbGwgZmxhZ2dlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNtYWxsZXN0RmxhZ2dlZChoZWFwOiBIZWFwLCByb3c6IG51bWJlcikge1xuICBjb25zdCBpbmQgPSBoZWFwWzBdW3Jvd107XG4gIGNvbnN0IGRpc3QgPSBoZWFwWzFdW3Jvd107XG4gIGNvbnN0IGZsYWcgPSBoZWFwWzJdW3Jvd107XG5cbiAgbGV0IG1pbkRpc3QgPSBJbmZpbml0eTtcbiAgbGV0IHJlc3VsdEluZGV4ID0gLTE7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPiBpbmQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZmxhZ1tpXSA9PT0gMSAmJiBkaXN0W2ldIDwgbWluRGlzdCkge1xuICAgICAgbWluRGlzdCA9IGRpc3RbaV07XG4gICAgICByZXN1bHRJbmRleCA9IGk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3VsdEluZGV4ID49IDApIHtcbiAgICBmbGFnW3Jlc3VsdEluZGV4XSA9IDA7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoaW5kW3Jlc3VsdEluZGV4XSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG59XG4iXX0=","/**\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 }\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 }\n else {\n this.entries.get(key).value = value;\n }\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 }\n else {\n return defaultValue;\n }\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 }\n else {\n return a.row - b.row;\n }\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 }\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 }\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 (let 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 }\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 }\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 }\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 }\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 }\n else {\n return a.row - b.row;\n }\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0cml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibWF0cml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFNdkIsWUFDRSxJQUEyQixFQUMzQixJQUEyQixFQUMzQixNQUErQixFQUMvQixJQUFjO1FBVFIsWUFBTyxHQUFHLElBQUksR0FBRyxFQUFpQixDQUFDO1FBRWxDLFVBQUssR0FBVyxDQUFDLENBQUM7UUFDbEIsVUFBSyxHQUFXLENBQUMsQ0FBQztRQVF6QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDaEUsTUFBTSxJQUFJLEtBQUssQ0FDYiw0REFBNEQsQ0FDN0QsQ0FBQztTQUNIO1FBRUQsb0NBQW9DO1FBQ3BDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3RDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxH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LElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdELDJDQUEyQztJQUM1QyxDQUFDO0lBRUQsT0FBTztRQUNOLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3RCwyQ0FBMkM7SUFDNUMsQ0FBQztJQUVELFNBQVM7UUFDVCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0QsNENBQTRDO0lBQzVDLENBQUM7SUFFRCxPQUFPLENBQUMsRUFBcUQ7UUFDM0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxHQUFHLENBQUMsRUFBdUQ7UUFDekQsTUFBTSxJQUFJLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDVCxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUMzQixJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztRQUNI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QUVILE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUM3QixNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFDNUIsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO0lBRTVCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3BCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3ZDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxJQUFJLEdBQUcsS0FBSyxVQUFVLEVBQUU7WUFDdEIsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2hCO1FBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3BCO0lBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDckMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG50eXBlIEVudHJ5ID0geyB2YWx1ZTogbnVtYmVyOyByb3c6IG51bWJlcjsgY29sOiBudW1iZXIgfTtcblxuLyoqXG4gKiBJbnRlcm5hbCAyLWRpbWVuc2lvbmFsIHNwYXJzZSBtYXRyaXggY2xhc3NcbiAqL1xuZXhwb3J0IGNsYXNzIFNwYXJzZU1hdHJpeCB7XG4gIHByaXZhdGUgZW50cmllcyA9IG5ldyBNYXA8c3RyaW5nLCBFbnRyeT4oKTtcblxuICByZWFkb25seSBuUm93czogbnVtYmVyID0gMDtcbiAgcmVhZG9ubHkgbkNvbHM6IG51bWJlciA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcm93czogbnVtYmVyW10gfCBJbnQzMkFycmF5LFxuICAgIGNvbHM6IG51bWJlcltdIHwgSW50MzJBcnJheSxcbiAgICB2YWx1ZXM6IG51bWJlcltdIHwgRmxvYXQzMkFycmF5LFxuICAgIGRpbXM6IG51bWJlcltdXG4gICkge1xuICAgIGlmIChyb3dzLmxlbmd0aCAhPT0gY29scy5sZW5ndGggfHwgcm93cy5sZW5ndGggIT09IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ3Jvd3MsIGNvbHMgYW5kIHZhbHVlcyBhcnJheXMgbXVzdCBhbGwgaGF2ZSB0aGUgc2FtZSBsZW5ndGgnXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFRPRE86IEFzc2VydCB0aGF0IGRpbXMgYXJlIGxlZ2l0LlxuICAgIHRoaXMublJvd3MgPSBkaW1zWzBdO1xuICAgIHRoaXMubkNvbHMgPSBkaW1zWzFdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByb3cgPSByb3dzW2ldO1xuICAgICAgY29uc3QgY29sID0gY29sc1tpXTtcbiAgICAgIHRoaXMuY2hlY2tEaW1zKHJvdywgY29sKTtcbiAgICAgIGNvbnN0IGtleSA9IHRoaXMubWFrZUtleShyb3csIGNvbCk7XG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwgeyB2YWx1ZTogdmFsdWVzW2ldLCByb3csIGNvbCB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1ha2VLZXkocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7cm93fToke2NvbH1gO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0RpbXMocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKSB7XG4gICAgY29uc3Qgd2l0aGluQm91bmRzID0gcm93IDwgdGhpcy5uUm93cyAmJiBjb2wgPCB0aGlzLm5Db2xzO1xuICAgIGlmICghd2l0aGluQm91bmRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3JvdyBhbmQvb3IgY29sIHNwZWNpZmllZCBvdXRzaWRlIG9mIG1hdHJpeCBkaW1lbnNpb25zJyk7XG4gICAgfVxuICB9XG5cbiAgc2V0KHJvdzogbnVtYmVyLCBjb2w6IG51bWJlciwgdmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuY2hlY2tEaW1zKHJvdywgY29sKTtcbiAgICBjb25zdCBrZXkgPSB0aGlzLm1ha2VLZXkocm93LCBjb2wpO1xuICAgIGlmICghdGhpcy5lbnRyaWVzLmhhcyhrZXkpKSB7XG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwgeyB2YWx1ZSwgcm93LCBjb2wgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW50cmllcy5nZXQoa2V5KSEudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICBnZXQocm93OiBudW1iZXIsIGNvbDogbnVtYmVyLCBkZWZhdWx0VmFsdWUgPSAwKSB7XG4gICAgLy90aGlzLmNoZWNrRGltcyhyb3csIGNvbCk7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5tYWtlS2V5KHJvdywgY29sKTtcbiAgICBpZiAodGhpcy5lbnRyaWVzLmhhcyhrZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbnRyaWVzLmdldChrZXkpIS52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG4gIH1cblxuICBnZXRBbGwob3JkZXJlZCA9IHRydWUpOiB7IHZhbHVlOiBudW1iZXI7IHJvdzogbnVtYmVyOyBjb2w6IG51bWJlciB9W10ge1xuICAgIGNvbnN0IHJvd0NvbFZhbHVlczogRW50cnlbXSA9IG5ldyBBcnJheSh0aGlzLmVudHJpZXMuc2l6ZSkuZmlsbChudWxsKTtcbiAgICBsZXQgaSA9IDA7XG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgcm93Q29sVmFsdWVzW2krK10gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICBpZiAob3JkZXJlZCkge1xuICAgICAgLy8gT3JkZXJpbmcgdGhlIHJlc3VsdCBpc24ndCByZXF1aXJlZCBmb3IgcHJvY2Vzc2luZyBidXQgaXQgZG9lcyBtYWtlIGl0IGVhc2llciB0byB3cml0ZSB0ZXN0c1xuICAgICAgcm93Q29sVmFsdWVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgaWYgKGEucm93ID09PSBiLnJvdykge1xuICAgICAgICAgIHJldHVybiBhLmNvbCAtIGIuY29sO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBhLnJvdyAtIGIucm93O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJvd0NvbFZhbHVlcztcbiAgfVxuXG4gIGdldERpbXMoKTogbnVtYmVyW10ge1xuICAgIHJldHVybiBbdGhpcy5uUm93cywgdGhpcy5uQ29sc107XG4gIH1cblxuICBnZXRSb3dzKCk6IG51bWJlcltdIHtcbiAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuZW50cmllcywgKFtrZXksIHZhbHVlXSkgPT4gdmFsdWUucm93KTtcbiAgIC8vIHJldHVybiB0aGlzLnJvd3MgYXMgdW5rbm93biBhcyBudW1iZXJbXTtcbiAgfVxuXG4gIGdldENvbHMoKTogbnVtYmVyW117XG4gICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMsIChba2V5LCB2YWx1ZV0pID0+IHZhbHVlLmNvbCk7XG4gICAvLyByZXR1cm4gdGhpcy5jb2xzIGFzIHVua25vd24gYXMgbnVtYmVyW107XG4gIH1cblxuICBnZXRWYWx1ZXMoKTogbnVtYmVyW10ge1xuICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMsIChba2V5LCB2YWx1ZV0pID0+IHZhbHVlLnZhbHVlKTtcbiAgLy9yZXR1cm4gdGhpcy52YWx1ZXMgYXMgdW5rbm93biBhcyBudW1iZXJbXTtcbiAgfVxuXG4gIGZvckVhY2goZm46ICh2YWx1ZTogbnVtYmVyLCByb3c6IG51bWJlciwgY29sOiBudW1iZXIpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCh2YWx1ZSA9PiBmbih2YWx1ZS52YWx1ZSwgdmFsdWUucm93LCB2YWx1ZS5jb2wpKTtcbiAgfVxuXG4gIG1hcChmbjogKHZhbHVlOiBudW1iZXIsIHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcikgPT4gbnVtYmVyKTogU3BhcnNlTWF0cml4IHtcbiAgICBjb25zdCB2YWxzID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmVudHJpZXMuc2l6ZSk7XG4gICAgbGV0IGkgPSAwXG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgdmFsc1tpKytdID0gZm4odmFsdWUudmFsdWUsIHZhbHVlLnJvdywgdmFsdWUuY29sKTtcbiAgICB9KTtcbiAgICBjb25zdCBkaW1zID0gW3RoaXMublJvd3MsIHRoaXMubkNvbHNdO1xuICAgIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHRoaXMuZ2V0Um93cygpLCB0aGlzLmdldENvbHMoKSwgdmFscyBhcyB1bmtub3duIGFzIG51bWJlcltdLCBkaW1zKTtcbiAgfVxuXG4gIHRvQXJyYXkoKSB7XG4gICAgY29uc3Qgcm93czogdW5kZWZpbmVkW10gPSB1dGlscy5lbXB0eSh0aGlzLm5Sb3dzKTtcbiAgICBjb25zdCBvdXRwdXQgPSByb3dzLm1hcCgoKSA9PiB7XG4gICAgICByZXR1cm4gdXRpbHMuemVyb3ModGhpcy5uQ29scyk7XG4gICAgfSk7XG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgb3V0cHV0W3ZhbHVlLnJvd11bdmFsdWUuY29sXSA9IHZhbHVlLnZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn1cblxuLyoqXG4gKiBUcmFuc3Bvc2UgYSBzcGFyc2UgbWF0cml4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2UobWF0cml4OiBTcGFyc2VNYXRyaXgpOiBTcGFyc2VNYXRyaXgge1xuICBjb25zdCBvbGRSb3dzID0gbWF0cml4LmdldFJvd3MoKTtcbiAgY29uc3Qgb2xkQ29scyA9IG1hdHJpeC5nZXRDb2xzKCk7XG4gIGNvbnN0IG9sZFZhbHMgPSBtYXRyaXguZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IG1hdGxlbiA9IG9sZENvbHMubGVuZ3RoO1xuICBjb25zdCBjb2xzID0gbmV3IEludDMyQXJyYXkobWF0bGVuKTtcbiAgY29uc3Qgcm93cyA9IG5ldyBJbnQzMkFycmF5KG1hdGxlbik7XG4gIGNvbnN0IHZhbHMgPSBuZXcgRmxvYXQzMkFycmF5KG1hdGxlbik7XG5cbiAgY29scy5zZXQob2xkUm93cyk7XG4gIHJvd3Muc2V0KG9sZENvbHMpO1xuICB2YWxzLnNldChvbGRWYWxzKTtcbiAgY29uc3QgZGltcyA9IFttYXRyaXgubkNvbHMsIG1hdHJpeC5uUm93c107XG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIGRpbXMpO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHNwYXJzZSBpZGVudGl0eSBtYXRyaXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KHNpemU6IG51bWJlcltdKTogU3BhcnNlTWF0cml4IHtcbiAgY29uc3QgW3Jvd3NdID0gc2l6ZTtcbiAgY29uc3QgbWF0cml4ID0gbmV3IFNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBzaXplKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHtcbiAgICBtYXRyaXguc2V0KGksIGksIDEpO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKlxuICogRWxlbWVudC13aXNlIG11bHRpcGxpY2F0aW9uIG9mIHR3byBtYXRyaWNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFpcndpc2VNdWx0aXBseShcbiAgYTogU3BhcnNlTWF0cml4LFxuICBiOiBTcGFyc2VNYXRyaXhcbik6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4geCAqIHkpO1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBhZGRpdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZChhOiBTcGFyc2VNYXRyaXgsIGI6IFNwYXJzZU1hdHJpeCk6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4geCArIHkpO1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBzdWJ0cmFjdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1YnRyYWN0KGE6IFNwYXJzZU1hdHJpeCwgYjogU3BhcnNlTWF0cml4KTogU3BhcnNlTWF0cml4IHtcbiAgcmV0dXJuIGVsZW1lbnRXaXNlKGEsIGIsICh4LCB5KSA9PiB4IC0geSk7XG59XG5cbi8qKlxuICogRWxlbWVudC13aXNlIG1heGltdW0gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXhpbXVtKGE6IFNwYXJzZU1hdHJpeCwgYjogU3BhcnNlTWF0cml4KTogU3BhcnNlTWF0cml4IHtcbiAgcmV0dXJuIGVsZW1lbnRXaXNlKGEsIGIsICh4LCB5KSA9PiAoeCA+IHkgPyB4IDogeSkpO1xufVxuXG4vKipcbiAqIFNjYWxhciBtdWx0aXBsaWNhdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5U2NhbGFyKGE6IFNwYXJzZU1hdHJpeCwgc2NhbGFyOiBudW1iZXIpOiBTcGFyc2VNYXRyaXgge1xuICByZXR1cm4gYS5tYXAoKHZhbHVlOiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gdmFsdWUgKiBzY2FsYXI7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgbWF0cml4IHdpdGggemVybyBlbnRyaWVzIHJlbW92ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbGltaW5hdGVaZXJvcyhtOiBTcGFyc2VNYXRyaXgpIHtcbiAgY29uc3QgemVyb0luZGljZXMgPSBuZXcgU2V0KCk7XG4gIGNvbnN0IHZhbHVlcyA9IG0uZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3MgPSBtLmdldFJvd3MoKTtcbiAgY29uc3QgY29scyA9IG0uZ2V0Q29scygpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh2YWx1ZXNbaV0gPT09IDApIHtcbiAgICAgIHplcm9JbmRpY2VzLmFkZChpKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgcmVtb3ZlQnlaZXJvSW5kZXggPSAoXzogYW55LCBpbmRleDogbnVtYmVyKSA9PiAhemVyb0luZGljZXMuaGFzKGluZGV4KTtcbiAgY29uc3QgbmV4dFZhbHVlcyA9IHZhbHVlcy5maWx0ZXIocmVtb3ZlQnlaZXJvSW5kZXgpO1xuICBjb25zdCBuZXh0Um93cyA9IHJvd3MuZmlsdGVyKHJlbW92ZUJ5WmVyb0luZGV4KTtcbiAgY29uc3QgbmV4dENvbHMgPSBjb2xzLmZpbHRlcihyZW1vdmVCeVplcm9JbmRleCk7XG5cbiAgcmV0dXJuIG5ldyBTcGFyc2VNYXRyaXgobmV4dFJvd3MsIG5leHRDb2xzLCBuZXh0VmFsdWVzLCBtLmdldERpbXMoKSk7XG59XG5cbi8qKlxuICogTm9ybWFsaXphdGlvbiBvZiBhIHNwYXJzZSBtYXRyaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUobTogU3BhcnNlTWF0cml4LCBub3JtVHlwZSA9IE5vcm1UeXBlLmwyKSB7XG4gIGNvbnN0IG5vcm1GbiA9IG5vcm1GbnNbbm9ybVR5cGVdO1xuXG4gIGNvbnN0IGNvbHNCeVJvdyA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXJbXT4oKTtcbiAgbS5mb3JFYWNoKChfLCByb3csIGNvbCkgPT4ge1xuICAgIGNvbnN0IGNvbHMgPSBjb2xzQnlSb3cuZ2V0KHJvdykgfHwgW107XG4gICAgY29scy5wdXNoKGNvbCk7XG4gICAgY29sc0J5Um93LnNldChyb3csIGNvbHMpO1xuICB9KTtcblxuICBjb25zdCBuZXh0TWF0cml4ID0gbmV3IFNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBtLmdldERpbXMoKSk7XG5cbiAgZm9yIChsZXQgcm93IG9mIGNvbHNCeVJvdy5rZXlzKCkpIHtcbiAgICBjb25zdCBjb2xzID0gY29sc0J5Um93LmdldChyb3cpIS5zb3J0KCk7XG5cbiAgICBjb25zdCB2YWxzID0gY29scy5tYXAoY29sID0+IG0uZ2V0KHJvdywgY29sKSk7XG4gICAgY29uc3Qgbm9ybSA9IG5vcm1Gbih2YWxzKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vcm0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIG5leHRNYXRyaXguc2V0KHJvdywgY29sc1tpXSwgbm9ybVtpXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHRNYXRyaXg7XG59XG5cbi8qKlxuICogVmVjdG9yIG5vcm1hbGl6YXRpb24gZnVuY3Rpb25zXG4gKi9cbnR5cGUgTm9ybUZucyA9IHsgW2tleSBpbiBOb3JtVHlwZV06ICh2OiBudW1iZXJbXSkgPT4gbnVtYmVyW10gfTtcbmNvbnN0IG5vcm1GbnM6IE5vcm1GbnMgPSB7XG4gIFtOb3JtVHlwZS5tYXhdOiAoeHM6IG51bWJlcltdKSA9PiB7XG4gICAgbGV0IG1heCA9IC1JbmZpbml0eTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBtYXggPSB4c1tpXSA+IG1heCA/IHhzW2ldIDogbWF4O1xuICAgIH1cbiAgICByZXR1cm4geHMubWFwKHggPT4geCAvIG1heCk7XG4gIH0sXG4gIFtOb3JtVHlwZS5sMV06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBzdW0gKz0geHNbaV07XG4gICAgfVxuICAgIHJldHVybiB4cy5tYXAoeCA9PiB4IC8gc3VtKTtcbiAgfSxcbiAgW05vcm1UeXBlLmwyXTogKHhzOiBudW1iZXJbXSkgPT4ge1xuICAgIGxldCBzdW0gPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHN1bSArPSB4c1tpXSAqKiAyO1xuICAgIH1cbiAgICByZXR1cm4geHMubWFwKHggPT4gTWF0aC5zcXJ0KHggKiogMiAvIHN1bSkpO1xuICB9LFxufTtcblxuZXhwb3J0IGNvbnN0IGVudW0gTm9ybVR5cGUge1xuICBtYXggPSAnbWF4JyxcbiAgbDEgPSAnbDEnLFxuICBsMiA9ICdsMicsXG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIGZvciBlbGVtZW50LXdpc2Ugb3BlcmF0aW9ucy5cbiAqL1xuZnVuY3Rpb24gZWxlbWVudFdpc2UoXG4gIGE6IFNwYXJzZU1hdHJpeCxcbiAgYjogU3BhcnNlTWF0cml4LFxuICBvcDogKHg6IG51bWJlciwgeTogbnVtYmVyKSA9PiBudW1iZXJcbik6IFNwYXJzZU1hdHJpeCB7XG4gIGNvbnN0IHZpc2l0ZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3Qgcm93czogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgY29sczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgdmFsczogbnVtYmVyW10gPSBbXTtcblxuICBjb25zdCBvcGVyYXRlID0gKHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcikgPT4ge1xuICAgIHJvd3MucHVzaChyb3cpO1xuICAgIGNvbHMucHVzaChjb2wpO1xuICAgIGNvbnN0IG5leHRWYWx1ZSA9IG9wKGEuZ2V0KHJvdywgY29sKSwgYi5nZXQocm93LCBjb2wpKTtcbiAgICB2YWxzLnB1c2gobmV4dFZhbHVlKTtcbiAgfTtcbiAgY29uc3QgdmFsdWVzQSA9IGEuZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3NBID0gYS5nZXRSb3dzKCk7XG4gIGNvbnN0IGNvbHNBID0gYS5nZXRDb2xzKCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzQS5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHJvdyA9IHJvd3NBW2ldO1xuICAgIGNvbnN0IGNvbCA9IGNvbHNBW2ldO1xuICAgIGNvbnN0IGtleSA9IGAke3Jvd306JHtjb2x9YDtcbiAgICB2aXNpdGVkLmFkZChrZXkpO1xuICAgIG9wZXJhdGUocm93LCBjb2wpO1xuICB9XG5cbiAgY29uc3QgdmFsdWVzQiA9IGIuZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3NCID0gYi5nZXRSb3dzKCk7XG4gIGNvbnN0IGNvbHNCID0gYi5nZXRDb2xzKCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzQi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHJvdyA9IHJvd3NCW2ldO1xuICAgIGNvbnN0IGNvbCA9IGNvbHNCW2ldO1xuICAgIGNvbnN0IGtleSA9IGAke3Jvd306JHtjb2x9YDtcbiAgICBpZiAodmlzaXRlZC5oYXMoa2V5KSkgY29udGludWU7XG4gICAgb3BlcmF0ZShyb3csIGNvbCk7XG4gIH1cblxuICBjb25zdCBkaW1zID0gW2EublJvd3MsIGEubkNvbHNdO1xuICByZXR1cm4gbmV3IFNwYXJzZU1hdHJpeChyb3dzLCBjb2xzLCB2YWxzLCBkaW1zKTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGdldHRpbmcgZGF0YSwgaW5kaWNlcywgYW5kIGlucHRyIGFycmF5cyBmcm9tIGEgc3BhcnNlXG4gKiBtYXRyaXggdG8gZm9sbG93IGNzciBtYXRyaXggY29udmVudGlvbnMuIFN1cGVyIGluZWZmaWNpZW50IChhbmQga2luZCBvZlxuICogZGVmZWF0cyB0aGUgcHVycG9zZSBvZiB0aGlzIGNvbnZlbnRpb24pIGJ1dCBhIGxvdCBvZiB0aGUgcG9ydGVkIHB5dGhvbiB0cmVlXG4gKiBzZWFyY2ggbG9naWMgZGVwZW5kcyBvbiB0aGlzIGRhdGEgZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q1NSKHg6IFNwYXJzZU1hdHJpeCkge1xuICBjb25zdCBlbnRyaWVzOiBFbnRyeVtdID0gW107XG5cbiAgeC5mb3JFYWNoKCh2YWx1ZSwgcm93LCBjb2wpID0+IHtcbiAgICBlbnRyaWVzLnB1c2goeyB2YWx1ZSwgcm93LCBjb2wgfSk7XG4gIH0pO1xuXG4gIGVudHJpZXMuc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhLnJvdyA9PT0gYi5yb3cpIHtcbiAgICAgIHJldHVybiBhLmNvbCAtIGIuY29sO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYS5yb3cgLSBiLnJvdztcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gW107XG4gIGNvbnN0IHZhbHVlczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaW5kcHRyOiBudW1iZXJbXSA9IFtdO1xuXG4gIGxldCBjdXJyZW50Um93ID0gLTE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHsgcm93LCBjb2wsIHZhbHVlIH0gPSBlbnRyaWVzW2ldO1xuICAgIGlmIChyb3cgIT09IGN1cnJlbnRSb3cpIHtcbiAgICAgIGN1cnJlbnRSb3cgPSByb3c7XG4gICAgICBpbmRwdHIucHVzaChpKTtcbiAgICB9XG4gICAgaW5kaWNlcy5wdXNoKGNvbCk7XG4gICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHsgaW5kaWNlcywgdmFsdWVzLCBpbmRwdHIgfTtcbn1cbiJdfQ==","/**\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 let 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 }\n else {\n nRight += 1;\n }\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 }\n else {\n return 1 + numNodes(tree.leftChild) + numNodes(tree.rightChild);\n }\n}\nfunction numLeaves(tree) {\n if (tree.isLeaf) {\n return 1;\n }\n else {\n return numLeaves(tree.leftChild) + numLeaves(tree.rightChild);\n }\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 (let tree of rpForest) {\n output.push(...tree.indices);\n }\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 }\n else {\n node = tree.children[node][1];\n }\n }\n const index = -1 * tree.children[node][0];\n return tree.indices[index];\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBZWpDLE1BQU0sT0FBTyxRQUFRO0lBQ25CLFlBQ1MsV0FBcUIsRUFDckIsT0FBaUIsRUFDakIsUUFBb0IsRUFDcEIsT0FBbUI7UUFIbkIsZ0JBQVcsR0FBWCxXQUFXLENBQVU7UUFDckIsWUFBTyxHQUFQLE9BQU8sQ0FBVTtRQUNqQixhQUFRLEdBQVIsUUFBUSxDQUFZO1FBQ3BCLFlBQU8sR0FBUCxPQUFPLENBQVk7SUFDekIsQ0FBQztDQUNMO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUN4QixJQUFZLEVBQ1osVUFBa0IsRUFDbEIsTUFBYyxFQUNkLE1BQWdCO0lBRWhCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRTFDLE1BQU0sS0FBSyxHQUFHLEtBQUs7U0FDaEIsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUNiLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFFOUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsUUFBUSxDQUNmLElBQVksRUFDWixRQUFRLEdBQUcsRUFBRSxFQUNi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QUMvQjthQUFNO1lBQ0wsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDL0I7S0FDRjtJQUVELE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IFJhbmRvbUZuLCBWZWN0b3IsIFZlY3RvcnMgfSBmcm9tICcuL3VtYXAnO1xuXG4vKipcbiAqIFRyZWUgZnVuY3Rpb25hbGl0eSBmb3IgYXBwcm94aW1hdGluZyBuZWFyZXN0IG5laWdoYm9yc1xuICovXG5pbnRlcmZhY2UgUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlIHtcbiAgaXNMZWFmOiBib29sZWFuO1xuICBpbmRpY2VzPzogbnVtYmVyW107XG4gIGxlZnRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgcmlnaHRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgaHlwZXJwbGFuZT86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgRmxhdFRyZWUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgaHlwZXJwbGFuZXM6IG51bWJlcltdLFxuICAgIHB1YmxpYyBvZmZzZXRzOiBudW1iZXJbXSxcbiAgICBwdWJsaWMgY2hpbGRyZW46IG51bWJlcltdW10sXG4gICAgcHVibGljIGluZGljZXM6IG51bWJlcltdW11cbiAgKSB7fVxufVxuXG4vKipcbiAqIEJ1aWxkIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IHdpdGggYGBuVHJlZXNgYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VGb3Jlc3QoXG4gIGRhdGE6IFZlY3RvcixcbiAgbk5laWdoYm9yczogbnVtYmVyLFxuICBuVHJlZXM6IG51bWJlcixcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IGxlYWZTaXplID0gTWF0aC5tYXgoMTAsIG5OZWlnaGJvcnMpO1xuXG4gIGNvbnN0IHRyZWVzID0gdXRpbHNcbiAgICAucmFuZ2UoblRyZWVzKVxuICAgIC5tYXAoKF8sIGkpID0+IG1ha2VUcmVlKGRhdGEsIGxlYWZTaXplLCBpLCByYW5kb20pKTtcbiAgY29uc3QgZm9yZXN0ID0gdHJlZXMubWFwKHRyZWUgPT4gZmxhdHRlblRyZWUodHJlZSwgbGVhZlNpemUpKTtcblxuICByZXR1cm4gZm9yZXN0O1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHJhbmRvbSBwcm9qZWN0aW9uIHRyZWUgYmFzZWQgb24gYGBkYXRhYGAgd2l0aCBsZWF2ZXNcbiAqIG9mIHNpemUgYXQgbW9zdCBgYGxlYWZTaXplYGBcbiAqL1xuZnVuY3Rpb24gbWFrZVRyZWUoXG4gIGRhdGE6IFZlY3RvcixcbiAgbGVhZlNpemUgPSAzMCxcbiAgbjogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUge1xuICBjb25zdCBpbmRpY2VzID0gdXRpbHMucmFuZ2UoZGF0YS5sZW5ndGgpO1xuICBjb25zdCB0cmVlID0gbWFrZUV1Y2xpZGVhblRyZWUoZGF0YSwgaW5kaWNlcywgbGVhZlNpemUsIG4sIHJhbmRvbSk7XG4gIHJldHVybiB0cmVlO1xufVxuXG5mdW5jdGlvbiBtYWtlRXVjbGlkZWFuVHJlZShcbiAgZGF0YTogVmVjdG9yLFxuICBpbmRpY2VzOiBudW1iZXJbXSxcbiAgbGVhZlNpemUgPSAzMCxcbiAgcTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUge1xuICBpZiAoaW5kaWNlcy5sZW5ndGggPiBsZWFmU2l6ZSkge1xuICAgIGNvbnN0IHNwbGl0UmVzdWx0cyA9IGV1Y2xpZGVhblJhbmRvbVByb2plY3Rpb25TcGxpdChkYXRhLCBpbmRpY2VzLCByYW5kb20pO1xuICAgIGNvbnN0IHsgaW5kaWNlc0xlZnQsIGluZGljZXNSaWdodCwgaHlwZXJwbGFuZSwgb2Zmc2V0IH0gPSBzcGxpdFJlc3VsdHM7XG5cbiAgICBjb25zdCBsZWZ0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzTGVmdCxcbiAgICAgIGxlYWZTaXplLFxuICAgICAgcSArIDEsXG4gICAgICByYW5kb21cbiAgICApO1xuICAgIGNvbnN0IHJpZ2h0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzUmlnaHQsXG4gICAgICBsZWFmU2l6ZSxcbiAgICAgIHEgKyAxLFxuICAgICAgcmFuZG9tXG4gICAgKTtcblxuICAgIGNvbnN0IG5vZGUgPSB7IGxlZnRDaGlsZCwgcmlnaHRDaGlsZCwgaXNMZWFmOiBmYWxzZSwgaHlwZXJwbGFuZSwgb2Zmc2V0IH07XG4gICAgcmV0dXJuIG5vZGU7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgbm9kZSA9IHsgaW5kaWNlcywgaXNMZWFmOiB0cnVlIH07XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cbn1cblxuLyoqXG4gKiBHaXZlbiBhIHNldCBvZiBgYGluZGljZXNgYCBmb3IgZGF0YSBwb2ludHMgZnJvbSBgYGRhdGFgYCwgY3JlYXRlXG4gKiBhIHJhbmRvbSBoeXBlcnBsYW5lIHRvIHNwbGl0IHRoZSBkYXRhLCByZXR1cm5pbmcgdHdvIGFycmF5cyBpbmRpY2VzXG4gKiB0aGF0IGZhbGwgb24gZWl0aGVyIHNpZGUgb2YgdGhlIGh5cGVycGxhbmUuIFRoaXMgaXMgdGhlIGJhc2lzIGZvciBhXG4gKiByYW5kb20gcHJvamVjdGlvbiB0cmVlLCB3aGljaCBzaW1wbHkgdXNlcyB0aGlzIHNwbGl0dGluZyByZWN1cnNpdmVseS5cbiAqIFRoaXMgcGFydGljdWxhciBzcGxpdCB1c2VzIGV1Y2xpZGVhbiBkaXN0YW5jZSB0byBkZXRlcm1pbmUgdGhlIGh5cGVycGxhbmVcbiAqIGFuZCB3aGljaCBzaWRlIGVhY2ggZGF0YSBzYW1wbGUgZmFsbHMgb24uXG4gKi9cbmZ1bmN0aW9uIGV1Y2xpZGVhblJhbmRvbVByb2plY3Rpb25TcGxpdChcbiAgZGF0YTogVmVjdG9yLFxuICBpbmRpY2VzOiBudW1iZXJbXSxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IGRpbSA9IDE7XG5cbiAgLy8gU2VsZWN0IHR3byByYW5kb20gcG9pbnRzLCBzZXQgdGhlIGh5cGVycGxhbmUgYmV0d2VlbiB0aGVtXG4gIGxldCBsZWZ0SW5kZXggPSB1dGlscy50YXVSYW5kSW50KGluZGljZXMubGVuZ3RoLCByYW5kb20pO1xuICBsZXQgcmlnaHRJbmRleCA9IHV0aWxzLnRhdVJhbmRJbnQoaW5kaWNlcy5sZW5ndGgsIHJhbmRvbSk7XG4gIHJpZ2h0SW5kZXggKz0gbGVmdEluZGV4ID09PSByaWdodEluZGV4ID8gMSA6IDA7XG4gIHJpZ2h0SW5kZXggPSByaWdodEluZGV4ICUgaW5kaWNlcy5sZW5ndGg7XG4gIGNvbnN0IGxlZnQgPSBpbmRpY2VzW2xlZnRJbmRleF07XG4gIGNvbnN0IHJpZ2h0ID0gaW5kaWNlc1tyaWdodEluZGV4XTtcblxuICAvLyBDb21wdXRlIHRoZSBub3JtYWwgdmVjdG9yIHRvIHRoZSBoeXBlcnBsYW5lICh0aGUgdmVjdG9yIGJldHdlZW4gdGhlIHR3b1xuICAvLyBwb2ludHMpIGFuZCB0aGUgb2Zmc2V0IGZyb20gdGhlIG9yaWdpblxuICBsZXQgaHlwZXJwbGFuZU9mZnNldCA9IDA7XG4gIGxldCBoeXBlcnBsYW5lVmVjdG9yID0gMDtcblxuICBcbiAgaHlwZXJwbGFuZVZlY3RvciA9IGRhdGFbbGVmdF0gLSBkYXRhW3JpZ2h0XTtcbiAgaHlwZXJwbGFuZU9mZnNldCAtPVxuICAgIChoeXBlcnBsYW5lVmVjdG9yICogKGRhdGFbbGVmdF0gKyBkYXRhW3JpZ2h0XSkpIC8gMi4wO1xuICBcblxuICAvLyBGb3IgZWFjaCBwb2ludCBjb21wdXRlIHRoZSBtYXJnaW4gKHByb2plY3QgaW50byBub3JtYWwgdmVjdG9yKVxuICAvLyBJZiB3ZSBhcmUgb24gbG93ZXIgc2lkZSBvZiB0aGUgaHlwZXJwbGFuZSBwdXQgaW4gb25lIHBpbGUsIG90aGVyd2lzZVxuICAvLyBwdXQgaXQgaW4gdGhlIG90aGVyIHBpbGUgKGlmIHdlIGhpdCBoeXBlcnBsYW5lIG9uIHRoZSBub3NlLCBmbGlwIGEgY29pbilcbiAgbGV0IG5MZWZ0ID0gMDtcbiAgbGV0IG5SaWdodCA9IDA7XG4gIGNvbnN0IHNpZGUgPSB1dGlscy56ZXJvcyhpbmRpY2VzLmxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBtYXJnaW4gPSBoeXBlcnBsYW5lT2Zmc2V0O1xuICAgIFxuICAgICAgbWFyZ2luICs9IGh5cGVycGxhbmVWZWN0b3IgKiBkYXRhW2luZGljZXNbaV1dO1xuICAgIFxuICAgIGlmIChtYXJnaW4gPT09IDApIHtcbiAgICAgIHNpZGVbaV0gPSB1dGlscy50YXVSYW5kSW50KDIsIHJhbmRvbSk7XG4gICAgICBpZiAoc2lkZVtpXSA9PT0gMCkge1xuICAgICAgICBuTGVmdCArPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgblJpZ2h0ICs9IDE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChtYXJnaW4gPiAwKSB7XG4gICAgICBzaWRlW2ldID0gMDtcbiAgICAgIG5MZWZ0ICs9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNpZGVbaV0gPSAxO1xuICAgICAgblJpZ2h0ICs9IDE7XG4gICAgfVxuICB9XG5cbiAgLy8gTm93IHRoYXQgd2UgaGF2ZSB0aGUgY291bnRzLCBhbGxvY2F0ZSBhcnJheXNcbiAgY29uc3QgaW5kaWNlc0xlZnQgPSB1dGlscy56ZXJvcyhuTGVmdCk7XG4gIGNvbnN0IGluZGljZXNSaWdodCA9IHV0aWxzLnplcm9zKG5SaWdodCk7XG5cbiAgLy8gUG9wdWxhdGUgdGhlIGFycmF5cyB3aXRoIGluZGljZXMgYWNjb3JkaW5nIHRvIHdoaWNoIHNpZGUgdGhleSBmZWxsIG9uXG4gIG5MZWZ0ID0gMDtcbiAgblJpZ2h0ID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaWRlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHNpZGVbaV0gPT09IDApIHtcbiAgICAgIGluZGljZXNMZWZ0W25MZWZ0XSA9IGluZGljZXNbaV07XG4gICAgICBuTGVmdCArPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbmRpY2VzUmlnaHRbblJpZ2h0XSA9IGluZGljZXNbaV07XG4gICAgICBuUmlnaHQgKz0gMTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGluZGljZXNMZWZ0LFxuICAgIGluZGljZXNSaWdodCxcbiAgICBoeXBlcnBsYW5lOiBoeXBlcnBsYW5lVmVjdG9yLFxuICAgIG9mZnNldDogaHlwZXJwbGFuZU9mZnNldCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmxhdHRlblRyZWUodHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlLCBsZWFmU2l6ZTogbnVtYmVyKSB7XG4gIGNvbnN0IG5Ob2RlcyA9IG51bU5vZGVzKHRyZWUpO1xuICBjb25zdCBuTGVhdmVzID0gbnVtTGVhdmVzKHRyZWUpO1xuXG4gIC8vIFRPRE86IFZlcmlmeSB0aGF0IHNwYXJzZSBjb2RlIGlzIG5vdCByZWxldmFudC4uLlxuICBjb25zdCBoeXBlcnBsYW5lcyA9IHV0aWxzXG4gICAgLnJhbmdlKG5Ob2RlcylcbiAgICAubWFwKCgpID0+IHRyZWUuaHlwZXJwbGFuZSA/IDEgOiAwKTtcblxuICBjb25zdCBvZmZzZXRzID0gdXRpbHMuemVyb3Mobk5vZGVzKTtcbiAgY29uc3QgY2hpbGRyZW4gPSB1dGlscy5yYW5nZShuTm9kZXMpLm1hcCgoKSA9PiBbLTEsIC0xXSk7XG4gIGNvbnN0IGluZGljZXMgPSB1dGlsc1xuICAgIC5yYW5nZShuTGVhdmVzKVxuICAgIC5tYXAoKCkgPT4gdXRpbHMucmFuZ2UobGVhZlNpemUpLm1hcCgoKSA9PiAtMSkpO1xuICByZWN1cnNpdmVGbGF0dGVuKHRyZWUsIGh5cGVycGxhbmVzLCBvZmZzZXRzLCBjaGlsZHJlbiwgaW5kaWNlcywgMCwgMCk7XG4gIHJldHVybiBuZXcgRmxhdFRyZWUoaHlwZXJwbGFuZXMsIG9mZnNldHMsIGNoaWxkcmVuLCBpbmRpY2VzKTtcbn1cblxuZnVuY3Rpb24gcmVjdXJzaXZlRmxhdHRlbihcbiAgdHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlLFxuICBoeXBlcnBsYW5lczogbnVtYmVyW10sXG4gIG9mZnNldHM6IG51bWJlcltdLFxuICBjaGlsZHJlbjogbnVtYmVyW11bXSxcbiAgaW5kaWNlczogbnVtYmVyW11bXSxcbiAgbm9kZU51bTogbnVtYmVyLFxuICBsZWFmTnVtOiBudW1iZXJcbik6IHsgbm9kZU51bTogbnVtYmVyOyBsZWFmTnVtOiBudW1iZXIgfSB7XG4gIGlmICh0cmVlLmlzTGVhZikge1xuICAgIGNoaWxkcmVuW25vZGVOdW1dWzBdID0gLWxlYWZOdW07XG5cbiAgICAvLyBUT0RPOiBUcmlwbGUgY2hlY2sgdGhpcyBvcGVyYXRpb24gY29ycmVzcG9uZHMgdG9cbiAgICAvLyBpbmRpY2VzW2xlYWZOdW0gOiB0cmVlLmluZGljZXMuc2hhcGVbMF1dID0gdHJlZS5pbmRpY2VzXG4gICAgaW5kaWNlc1tsZWFmTnVtXS5zcGxpY2UoMCwgdHJlZS5pbmRpY2VzIS5sZW5ndGgsIC4uLnRyZWUuaW5kaWNlcyEpO1xuICAgIGxlYWZOdW0gKz0gMTtcbiAgICByZXR1cm4geyBub2RlTnVtLCBsZWFmTnVtIH07XG4gIH0gZWxzZSB7XG4gICAgaHlwZXJwbGFuZXNbbm9kZU51bV0gPSB0cmVlLmh5cGVycGxhbmUhO1xuICAgIG9mZnNldHNbbm9kZU51bV0gPSB0cmVlLm9mZnNldCE7XG4gICAgY2hpbGRyZW5bbm9kZU51bV1bMF0gPSBub2RlTnVtICsgMTtcbiAgICBjb25zdCBvbGROb2RlTnVtID0gbm9kZU51bTtcblxuICAgIGxldCByZXMgPSByZWN1cnNpdmVGbGF0dGVuKFxuICAgICAgdHJlZS5sZWZ0Q2hpbGQhLFxuICAgICAgaHlwZXJwbGFuZXMsXG4gICAgICBvZmZzZXRzLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBpbmRpY2VzLFxuICAgICAgbm9kZU51bSArIDEsXG4gICAgICBsZWFmTnVtXG4gICAgKTtcbiAgICBub2RlTnVtID0gcmVzLm5vZGVOdW07XG4gICAgbGVhZk51bSA9IHJlcy5sZWFmTnVtO1xuXG4gICAgY2hpbGRyZW5bb2xkTm9kZU51bV1bMV0gPSBub2RlTnVtICsgMTtcblxuICAgIHJlcyA9IHJlY3Vyc2l2ZUZsYXR0ZW4oXG4gICAgICB0cmVlLnJpZ2h0Q2hpbGQhLFxuICAgICAgaHlwZXJwbGFuZXMsXG4gICAgICBvZmZzZXRzLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBpbmRpY2VzLFxuICAgICAgbm9kZU51bSArIDEsXG4gICAgICBsZWFmTnVtXG4gICAgKTtcbiAgICByZXR1cm4geyBub2RlTnVtOiByZXMubm9kZU51bSwgbGVhZk51bTogcmVzLmxlYWZOdW0gfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1Ob2Rlcyh0cmVlOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUpOiBudW1iZXIge1xuICBpZiAodHJlZS5pc0xlYWYpIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMSArIG51bU5vZGVzKHRyZWUubGVmdENoaWxkISkgKyBudW1Ob2Rlcyh0cmVlLnJpZ2h0Q2hpbGQhKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1MZWF2ZXModHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlKTogbnVtYmVyIHtcbiAgaWYgKHRyZWUuaXNMZWFmKSB7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bUxlYXZlcyh0cmVlLmxlZnRDaGlsZCEpICsgbnVtTGVhdmVzKHRyZWUucmlnaHRDaGlsZCEpO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYW4gYXJyYXkgb2Ygc2V0cyBvZiBjYW5kaWRhdGUgbmVhcmVzdCBuZWlnaGJvcnMgYnlcbiAqIGNvbnN0cnVjdGluZyBhIHJhbmRvbSBwcm9qZWN0aW9uIGZvcmVzdCBhbmQgdGFraW5nIHRoZSBsZWF2ZXMgb2YgYWxsIHRoZVxuICogdHJlZXMuIEFueSBnaXZlbiB0cmVlIGhhcyBsZWF2ZXMgdGhhdCBhcmUgYSBzZXQgb2YgcG90ZW50aWFsIG5lYXJlc3RcbiAqIG5laWdoYm9ycy4gR2l2ZW4gZW5vdWdoIHRyZWVzIHRoZSBzZXQgb2YgYWxsIHN1Y2ggbGVhdmVzIGdpdmVzIGEgZ29vZFxuICogbGlrZWxpaG9vZCBvZiBnZXR0aW5nIGEgZ29vZCBzZXQgb2YgbmVhcmVzdCBuZWlnaGJvcnMgaW4gY29tcG9zaXRlLiBTaW5jZVxuICogc3VjaCBhIHJhbmRvbSBwcm9qZWN0aW9uIGZvcmVzdCBpcyBpbmV4cGVuc2l2ZSB0byBjb21wdXRlLCB0aGlzIGNhbiBiZSBhXG4gKiB1c2VmdWwgbWVhbnMgb2Ygc2VlZGluZyBvdGhlciBuZWFyZXN0IG5laWdoYm9yIGFsZ29yaXRobXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTGVhZkFycmF5KHJwRm9yZXN0OiBGbGF0VHJlZVtdKTogbnVtYmVyW11bXSB7XG4gIGlmIChycEZvcmVzdC5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qgb3V0cHV0OiBudW1iZXJbXVtdID0gW107XG4gICAgZm9yIChsZXQgdHJlZSBvZiBycEZvcmVzdCkge1xuICAgICAgb3V0cHV0LnB1c2goLi4udHJlZS5pbmRpY2VzISk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtbLTFdXTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbGVjdHMgdGhlIHNpZGUgb2YgdGhlIHRyZWUgdG8gc2VhcmNoIGR1cmluZyBmbGF0IHRyZWUgc2VhcmNoLlxuICovXG5mdW5jdGlvbiBzZWxlY3RTaWRlKFxuICBoeXBlcnBsYW5lOiBudW1iZXIsXG4gIG9mZnNldDogbnVtYmVyLFxuICBwb2ludDogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgbGV0IG1hcmdpbiA9IG9mZnNldDtcblxuICAgIG1hcmdpbiArPSBoeXBlcnBsYW5lICogcG9pbnQ7XG4gIFxuXG4gIGlmIChtYXJnaW4gPT09IDApIHtcbiAgICBjb25zdCBzaWRlID0gdXRpbHMudGF1UmFuZEludCgyLCByYW5kb20pO1xuICAgIHJldHVybiBzaWRlO1xuICB9IGVsc2UgaWYgKG1hcmdpbiA+IDApIHtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMTtcbiAgfVxufVxuXG4vKipcbiAqIFNlYXJjaGVzIGEgZmxhdHRlbmVkIHJwLXRyZWUgZm9yIGEgcG9pbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWFyY2hGbGF0VHJlZShcbiAgcG9pbnQ6IG51bWJlcixcbiAgdHJlZTogRmxhdFRyZWUsXG4gIHJhbmRvbTogUmFuZG9tRm5cbikge1xuICBsZXQgbm9kZSA9IDA7XG4gIHdoaWxlICh0cmVlLmNoaWxkcmVuW25vZGVdWzBdID4gMCkge1xuICAgIGNvbnN0IHNpZGUgPSBzZWxlY3RTaWRlKFxuICAgICAgdHJlZS5oeXBlcnBsYW5lc1tub2RlXSxcbiAgICAgIHRyZWUub2Zmc2V0c1tub2RlXSxcbiAgICAgIHBvaW50LFxuICAgICAgcmFuZG9tXG4gICAgKTtcbiAgICBpZiAoc2lkZSA9PT0gMCkge1xuICAgICAgbm9kZSA9IHRyZWUuY2hpbGRyZW5bbm9kZV1bMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGUgPSB0cmVlLmNoaWxkcmVuW25vZGVdWzFdO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGluZGV4ID0gLTEgKiB0cmVlLmNoaWxkcmVuW25vZGVdWzBdO1xuICByZXR1cm4gdHJlZS5pbmRpY2VzW2luZGV4XTtcbn1cbiJdfQ==","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","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","import { isAnyArray } from 'is-any-array';\nimport max from 'ml-array-max';\nimport min from 'ml-array-min';\n\nfunction rescale(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n } else if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var output;\n\n if (options.output !== undefined) {\n if (!isAnyArray(options.output)) {\n throw new TypeError('output option must be an array if specified');\n }\n\n output = options.output;\n } else {\n output = new Array(input.length);\n }\n\n var currentMin = min(input);\n var currentMax = max(input);\n\n if (currentMin === currentMax) {\n throw new RangeError('minimum and maximum input values are equal. Cannot rescale a constant array');\n }\n\n var _options$min = options.min,\n minValue = _options$min === void 0 ? options.autoMinMax ? currentMin : 0 : _options$min,\n _options$max = options.max,\n maxValue = _options$max === void 0 ? options.autoMinMax ? currentMax : 1 : _options$max;\n\n if (minValue >= maxValue) {\n throw new RangeError('min option must be smaller than max option');\n }\n\n var factor = (maxValue - minValue) / (currentMax - currentMin);\n\n for (var i = 0; i < input.length; i++) {\n output[i] = (input[i] - currentMin) * factor + minValue;\n }\n\n return output;\n}\n\nexport { rescale as default };\n","import { isAnyArray } from 'is-any-array';\n\nfunction min(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n }\n\n if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var _options$fromIndex = options.fromIndex,\n fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex,\n _options$toIndex = options.toIndex,\n toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex;\n\n if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) {\n throw new Error('fromIndex must be a positive integer smaller than length');\n }\n\n if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) {\n throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length');\n }\n\n var minValue = input[fromIndex];\n\n for (var i = fromIndex + 1; i < toIndex; i++) {\n if (input[i] < minValue) minValue = input[i];\n }\n\n return minValue;\n}\n\nexport { min as default };\n","import { isAnyArray } from 'is-any-array';\n\nfunction max(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n }\n\n if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var _options$fromIndex = options.fromIndex,\n fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex,\n _options$toIndex = options.toIndex,\n toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex;\n\n if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) {\n throw new Error('fromIndex must be a positive integer smaller than length');\n }\n\n if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) {\n throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length');\n }\n\n var maxValue = input[fromIndex];\n\n for (var i = fromIndex + 1; i < toIndex; i++) {\n if (input[i] > maxValue) maxValue = input[i];\n }\n\n return maxValue;\n}\n\nexport { max as default };\n","const indent = ' '.repeat(2);\nconst indentData = ' '.repeat(4);\n\nexport function inspectMatrix() {\n return inspectMatrixWithOptions(this);\n}\n\nexport function inspectMatrixWithOptions(matrix, options = {}) {\n const {\n maxRows = 15,\n maxColumns = 10,\n maxNumSize = 8,\n padMinus = 'auto',\n } = options;\n return `${matrix.constructor.name} {\n${indent}[\n${indentData}${inspectData(matrix, maxRows, maxColumns, maxNumSize, padMinus)}\n${indent}]\n${indent}rows: ${matrix.rows}\n${indent}columns: ${matrix.columns}\n}`;\n}\n\nfunction inspectData(matrix, maxRows, maxColumns, maxNumSize, padMinus) {\n const { rows, columns } = matrix;\n const maxI = Math.min(rows, maxRows);\n const maxJ = Math.min(columns, maxColumns);\n const result = [];\n\n if (padMinus === 'auto') {\n padMinus = false;\n loop: for (let i = 0; i < maxI; i++) {\n for (let j = 0; j < maxJ; j++) {\n if (matrix.get(i, j) < 0) {\n padMinus = true;\n break loop;\n }\n }\n }\n }\n\n for (let i = 0; i < maxI; i++) {\n let line = [];\n for (let j = 0; j < maxJ; j++) {\n line.push(formatNumber(matrix.get(i, j), maxNumSize, padMinus));\n }\n result.push(`${line.join(' ')}`);\n }\n if (maxJ !== columns) {\n result[result.length - 1] += ` ... ${columns - maxColumns} more columns`;\n }\n if (maxI !== rows) {\n result.push(`... ${rows - maxRows} more rows`);\n }\n return result.join(`\\n${indentData}`);\n}\n\nfunction formatNumber(num, maxNumSize, padMinus) {\n return (\n num >= 0 && padMinus\n ? ` ${formatNumber2(num, maxNumSize - 1)}`\n : formatNumber2(num, maxNumSize)\n ).padEnd(maxNumSize);\n}\n\nfunction formatNumber2(num, len) {\n // small.length numbers should be as is\n let str = num.toString();\n if (str.length <= len) return str;\n\n // (7)'0.00123' is better then (7)'1.23e-2'\n // (8)'0.000123' is worse then (7)'1.23e-3',\n let fix = num.toFixed(len);\n if (fix.length > len) {\n fix = num.toFixed(Math.max(0, len - (fix.length - len)));\n }\n if (\n fix.length <= len &&\n !fix.startsWith('0.000') &&\n !fix.startsWith('-0.000')\n ) {\n return fix;\n }\n\n // well, if it's still too long the user should've used longer numbers\n let exp = num.toExponential(len);\n if (exp.length > len) {\n exp = num.toExponential(Math.max(0, len - (exp.length - len)));\n }\n return exp.slice(0);\n}\n","import { isAnyArray } from 'is-any-array';\n\n/**\n * @private\n * Check that a row index is not out of bounds\n * @param {Matrix} matrix\n * @param {number} index\n * @param {boolean} [outer]\n */\nexport function checkRowIndex(matrix, index, outer) {\n let max = outer ? matrix.rows : matrix.rows - 1;\n if (index < 0 || index > max) {\n throw new RangeError('Row index out of range');\n }\n}\n\n/**\n * @private\n * Check that a column index is not out of bounds\n * @param {Matrix} matrix\n * @param {number} index\n * @param {boolean} [outer]\n */\nexport function checkColumnIndex(matrix, index, outer) {\n let max = outer ? matrix.columns : matrix.columns - 1;\n if (index < 0 || index > max) {\n throw new RangeError('Column index out of range');\n }\n}\n\n/**\n * @private\n * Check that the provided vector is an array with the right length\n * @param {Matrix} matrix\n * @param {Array|Matrix} vector\n * @return {Array}\n * @throws {RangeError}\n */\nexport function checkRowVector(matrix, vector) {\n if (vector.to1DArray) {\n vector = vector.to1DArray();\n }\n if (vector.length !== matrix.columns) {\n throw new RangeError(\n 'vector size must be the same as the number of columns',\n );\n }\n return vector;\n}\n\n/**\n * @private\n * Check that the provided vector is an array with the right length\n * @param {Matrix} matrix\n * @param {Array|Matrix} vector\n * @return {Array}\n * @throws {RangeError}\n */\nexport function checkColumnVector(matrix, vector) {\n if (vector.to1DArray) {\n vector = vector.to1DArray();\n }\n if (vector.length !== matrix.rows) {\n throw new RangeError('vector size must be the same as the number of rows');\n }\n return vector;\n}\n\nexport function checkRowIndices(matrix, rowIndices) {\n if (!isAnyArray(rowIndices)) {\n throw new TypeError('row indices must be an array');\n }\n\n for (let i = 0; i < rowIndices.length; i++) {\n if (rowIndices[i] < 0 || rowIndices[i] >= matrix.rows) {\n throw new RangeError('row indices are out of range');\n }\n }\n}\n\nexport function checkColumnIndices(matrix, columnIndices) {\n if (!isAnyArray(columnIndices)) {\n throw new TypeError('column indices must be an array');\n }\n\n for (let i = 0; i < columnIndices.length; i++) {\n if (columnIndices[i] < 0 || columnIndices[i] >= matrix.columns) {\n throw new RangeError('column indices are out of range');\n }\n }\n}\n\nexport function checkRange(matrix, startRow, endRow, startColumn, endColumn) {\n if (arguments.length !== 5) {\n throw new RangeError('expected 4 arguments');\n }\n checkNumber('startRow', startRow);\n checkNumber('endRow', endRow);\n checkNumber('startColumn', startColumn);\n checkNumber('endColumn', endColumn);\n if (\n startRow > endRow ||\n startColumn > endColumn ||\n startRow < 0 ||\n startRow >= matrix.rows ||\n endRow < 0 ||\n endRow >= matrix.rows ||\n startColumn < 0 ||\n startColumn >= matrix.columns ||\n endColumn < 0 ||\n endColumn >= matrix.columns\n ) {\n throw new RangeError('Submatrix indices are out of range');\n }\n}\n\nexport function newArray(length, value = 0) {\n let array = [];\n for (let i = 0; i < length; i++) {\n array.push(value);\n }\n return array;\n}\n\nfunction checkNumber(name, value) {\n if (typeof value !== 'number') {\n throw new TypeError(`${name} must be a number`);\n }\n}\n\nexport function checkNonEmpty(matrix) {\n if (matrix.isEmpty()) {\n throw new Error('Empty matrix has no elements to index');\n }\n}\n","import { isAnyArray } from 'is-any-array';\nimport rescale from 'ml-array-rescale';\n\nimport { inspectMatrix, inspectMatrixWithOptions } from './inspect';\nimport { installMathOperations } from './mathOperations';\nimport {\n sumByRow,\n sumByColumn,\n sumAll,\n productByRow,\n productByColumn,\n productAll,\n varianceByRow,\n varianceByColumn,\n varianceAll,\n centerByRow,\n centerByColumn,\n centerAll,\n scaleByRow,\n scaleByColumn,\n scaleAll,\n getScaleByRow,\n getScaleByColumn,\n getScaleAll,\n} from './stat';\nimport {\n checkRowVector,\n checkRowIndex,\n checkColumnIndex,\n checkColumnVector,\n checkRange,\n checkNonEmpty,\n checkRowIndices,\n checkColumnIndices,\n} from './util';\n\nexport class AbstractMatrix {\n static from1DArray(newRows, newColumns, newData) {\n let length = newRows * newColumns;\n if (length !== newData.length) {\n throw new RangeError('data length does not match given dimensions');\n }\n let newMatrix = new Matrix(newRows, newColumns);\n for (let row = 0; row < newRows; row++) {\n for (let column = 0; column < newColumns; column++) {\n newMatrix.set(row, column, newData[row * newColumns + column]);\n }\n }\n return newMatrix;\n }\n\n static rowVector(newData) {\n let vector = new Matrix(1, newData.length);\n for (let i = 0; i < newData.length; i++) {\n vector.set(0, i, newData[i]);\n }\n return vector;\n }\n\n static columnVector(newData) {\n let vector = new Matrix(newData.length, 1);\n for (let i = 0; i < newData.length; i++) {\n vector.set(i, 0, newData[i]);\n }\n return vector;\n }\n\n static zeros(rows, columns) {\n return new Matrix(rows, columns);\n }\n\n static ones(rows, columns) {\n return new Matrix(rows, columns).fill(1);\n }\n\n static rand(rows, columns, options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { random = Math.random } = options;\n let matrix = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n matrix.set(i, j, random());\n }\n }\n return matrix;\n }\n\n static randInt(rows, columns, options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1000, random = Math.random } = options;\n if (!Number.isInteger(min)) throw new TypeError('min must be an integer');\n if (!Number.isInteger(max)) throw new TypeError('max must be an integer');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let interval = max - min;\n let matrix = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n let value = min + Math.round(random() * interval);\n matrix.set(i, j, value);\n }\n }\n return matrix;\n }\n\n static eye(rows, columns, value) {\n if (columns === undefined) columns = rows;\n if (value === undefined) value = 1;\n let min = Math.min(rows, columns);\n let matrix = this.zeros(rows, columns);\n for (let i = 0; i < min; i++) {\n matrix.set(i, i, value);\n }\n return matrix;\n }\n\n static diag(data, rows, columns) {\n let l = data.length;\n if (rows === undefined) rows = l;\n if (columns === undefined) columns = rows;\n let min = Math.min(l, rows, columns);\n let matrix = this.zeros(rows, columns);\n for (let i = 0; i < min; i++) {\n matrix.set(i, i, data[i]);\n }\n return matrix;\n }\n\n static min(matrix1, matrix2) {\n matrix1 = this.checkMatrix(matrix1);\n matrix2 = this.checkMatrix(matrix2);\n let rows = matrix1.rows;\n let columns = matrix1.columns;\n let result = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n result.set(i, j, Math.min(matrix1.get(i, j), matrix2.get(i, j)));\n }\n }\n return result;\n }\n\n static max(matrix1, matrix2) {\n matrix1 = this.checkMatrix(matrix1);\n matrix2 = this.checkMatrix(matrix2);\n let rows = matrix1.rows;\n let columns = matrix1.columns;\n let result = new this(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n result.set(i, j, Math.max(matrix1.get(i, j), matrix2.get(i, j)));\n }\n }\n return result;\n }\n\n static checkMatrix(value) {\n return AbstractMatrix.isMatrix(value) ? value : new Matrix(value);\n }\n\n static isMatrix(value) {\n return value != null && value.klass === 'Matrix';\n }\n\n get size() {\n return this.rows * this.columns;\n }\n\n apply(callback) {\n if (typeof callback !== 'function') {\n throw new TypeError('callback must be a function');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n callback.call(this, i, j);\n }\n }\n return this;\n }\n\n to1DArray() {\n let array = [];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n array.push(this.get(i, j));\n }\n }\n return array;\n }\n\n to2DArray() {\n let copy = [];\n for (let i = 0; i < this.rows; i++) {\n copy.push([]);\n for (let j = 0; j < this.columns; j++) {\n copy[i].push(this.get(i, j));\n }\n }\n return copy;\n }\n\n toJSON() {\n return this.to2DArray();\n }\n\n isRowVector() {\n return this.rows === 1;\n }\n\n isColumnVector() {\n return this.columns === 1;\n }\n\n isVector() {\n return this.rows === 1 || this.columns === 1;\n }\n\n isSquare() {\n return this.rows === this.columns;\n }\n\n isEmpty() {\n return this.rows === 0 || this.columns === 0;\n }\n\n isSymmetric() {\n if (this.isSquare()) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j <= i; j++) {\n if (this.get(i, j) !== this.get(j, i)) {\n return false;\n }\n }\n }\n return true;\n }\n return false;\n }\n\n isEchelonForm() {\n let i = 0;\n let j = 0;\n let previousColumn = -1;\n let isEchelonForm = true;\n let checked = false;\n while (i < this.rows && isEchelonForm) {\n j = 0;\n checked = false;\n while (j < this.columns && checked === false) {\n if (this.get(i, j) === 0) {\n j++;\n } else if (this.get(i, j) === 1 && j > previousColumn) {\n checked = true;\n previousColumn = j;\n } else {\n isEchelonForm = false;\n checked = true;\n }\n }\n i++;\n }\n return isEchelonForm;\n }\n\n isReducedEchelonForm() {\n let i = 0;\n let j = 0;\n let previousColumn = -1;\n let isReducedEchelonForm = true;\n let checked = false;\n while (i < this.rows && isReducedEchelonForm) {\n j = 0;\n checked = false;\n while (j < this.columns && checked === false) {\n if (this.get(i, j) === 0) {\n j++;\n } else if (this.get(i, j) === 1 && j > previousColumn) {\n checked = true;\n previousColumn = j;\n } else {\n isReducedEchelonForm = false;\n checked = true;\n }\n }\n for (let k = j + 1; k < this.rows; k++) {\n if (this.get(i, k) !== 0) {\n isReducedEchelonForm = false;\n }\n }\n i++;\n }\n return isReducedEchelonForm;\n }\n\n echelonForm() {\n let result = this.clone();\n let h = 0;\n let k = 0;\n while (h < result.rows && k < result.columns) {\n let iMax = h;\n for (let i = h; i < result.rows; i++) {\n if (result.get(i, k) > result.get(iMax, k)) {\n iMax = i;\n }\n }\n if (result.get(iMax, k) === 0) {\n k++;\n } else {\n result.swapRows(h, iMax);\n let tmp = result.get(h, k);\n for (let j = k; j < result.columns; j++) {\n result.set(h, j, result.get(h, j) / tmp);\n }\n for (let i = h + 1; i < result.rows; i++) {\n let factor = result.get(i, k) / result.get(h, k);\n result.set(i, k, 0);\n for (let j = k + 1; j < result.columns; j++) {\n result.set(i, j, result.get(i, j) - result.get(h, j) * factor);\n }\n }\n h++;\n k++;\n }\n }\n return result;\n }\n\n reducedEchelonForm() {\n let result = this.echelonForm();\n let m = result.columns;\n let n = result.rows;\n let h = n - 1;\n while (h >= 0) {\n if (result.maxRow(h) === 0) {\n h--;\n } else {\n let p = 0;\n let pivot = false;\n while (p < n && pivot === false) {\n if (result.get(h, p) === 1) {\n pivot = true;\n } else {\n p++;\n }\n }\n for (let i = 0; i < h; i++) {\n let factor = result.get(i, p);\n for (let j = p; j < m; j++) {\n let tmp = result.get(i, j) - factor * result.get(h, j);\n result.set(i, j, tmp);\n }\n }\n h--;\n }\n }\n return result;\n }\n\n set() {\n throw new Error('set method is unimplemented');\n }\n\n get() {\n throw new Error('get method is unimplemented');\n }\n\n repeat(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { rows = 1, columns = 1 } = options;\n if (!Number.isInteger(rows) || rows <= 0) {\n throw new TypeError('rows must be a positive integer');\n }\n if (!Number.isInteger(columns) || columns <= 0) {\n throw new TypeError('columns must be a positive integer');\n }\n let matrix = new Matrix(this.rows * rows, this.columns * columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n matrix.setSubMatrix(this, this.rows * i, this.columns * j);\n }\n }\n return matrix;\n }\n\n fill(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, value);\n }\n }\n return this;\n }\n\n neg() {\n return this.mulS(-1);\n }\n\n getRow(index) {\n checkRowIndex(this, index);\n let row = [];\n for (let i = 0; i < this.columns; i++) {\n row.push(this.get(index, i));\n }\n return row;\n }\n\n getRowVector(index) {\n return Matrix.rowVector(this.getRow(index));\n }\n\n setRow(index, array) {\n checkRowIndex(this, index);\n array = checkRowVector(this, array);\n for (let i = 0; i < this.columns; i++) {\n this.set(index, i, array[i]);\n }\n return this;\n }\n\n swapRows(row1, row2) {\n checkRowIndex(this, row1);\n checkRowIndex(this, row2);\n for (let i = 0; i < this.columns; i++) {\n let temp = this.get(row1, i);\n this.set(row1, i, this.get(row2, i));\n this.set(row2, i, temp);\n }\n return this;\n }\n\n getColumn(index) {\n checkColumnIndex(this, index);\n let column = [];\n for (let i = 0; i < this.rows; i++) {\n column.push(this.get(i, index));\n }\n return column;\n }\n\n getColumnVector(index) {\n return Matrix.columnVector(this.getColumn(index));\n }\n\n setColumn(index, array) {\n checkColumnIndex(this, index);\n array = checkColumnVector(this, array);\n for (let i = 0; i < this.rows; i++) {\n this.set(i, index, array[i]);\n }\n return this;\n }\n\n swapColumns(column1, column2) {\n checkColumnIndex(this, column1);\n checkColumnIndex(this, column2);\n for (let i = 0; i < this.rows; i++) {\n let temp = this.get(i, column1);\n this.set(i, column1, this.get(i, column2));\n this.set(i, column2, temp);\n }\n return this;\n }\n\n addRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + vector[j]);\n }\n }\n return this;\n }\n\n subRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - vector[j]);\n }\n }\n return this;\n }\n\n mulRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * vector[j]);\n }\n }\n return this;\n }\n\n divRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / vector[j]);\n }\n }\n return this;\n }\n\n addColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + vector[i]);\n }\n }\n return this;\n }\n\n subColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - vector[i]);\n }\n }\n return this;\n }\n\n mulColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * vector[i]);\n }\n }\n return this;\n }\n\n divColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / vector[i]);\n }\n }\n return this;\n }\n\n mulRow(index, value) {\n checkRowIndex(this, index);\n for (let i = 0; i < this.columns; i++) {\n this.set(index, i, this.get(index, i) * value);\n }\n return this;\n }\n\n mulColumn(index, value) {\n checkColumnIndex(this, index);\n for (let i = 0; i < this.rows; i++) {\n this.set(i, index, this.get(i, index) * value);\n }\n return this;\n }\n\n max(by) {\n if (this.isEmpty()) {\n return NaN;\n }\n switch (by) {\n case 'row': {\n const max = new Array(this.rows).fill(Number.NEGATIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max[row]) {\n max[row] = this.get(row, column);\n }\n }\n }\n return max;\n }\n case 'column': {\n const max = new Array(this.columns).fill(Number.NEGATIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max[column]) {\n max[column] = this.get(row, column);\n }\n }\n }\n return max;\n }\n case undefined: {\n let max = this.get(0, 0);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max) {\n max = this.get(row, column);\n }\n }\n }\n return max;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n maxIndex() {\n checkNonEmpty(this);\n let v = this.get(0, 0);\n let idx = [0, 0];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n if (this.get(i, j) > v) {\n v = this.get(i, j);\n idx[0] = i;\n idx[1] = j;\n }\n }\n }\n return idx;\n }\n\n min(by) {\n if (this.isEmpty()) {\n return NaN;\n }\n\n switch (by) {\n case 'row': {\n const min = new Array(this.rows).fill(Number.POSITIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min[row]) {\n min[row] = this.get(row, column);\n }\n }\n }\n return min;\n }\n case 'column': {\n const min = new Array(this.columns).fill(Number.POSITIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min[column]) {\n min[column] = this.get(row, column);\n }\n }\n }\n return min;\n }\n case undefined: {\n let min = this.get(0, 0);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min) {\n min = this.get(row, column);\n }\n }\n }\n return min;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n minIndex() {\n checkNonEmpty(this);\n let v = this.get(0, 0);\n let idx = [0, 0];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n if (this.get(i, j) < v) {\n v = this.get(i, j);\n idx[0] = i;\n idx[1] = j;\n }\n }\n }\n return idx;\n }\n\n maxRow(row) {\n checkRowIndex(this, row);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(row, 0);\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) > v) {\n v = this.get(row, i);\n }\n }\n return v;\n }\n\n maxRowIndex(row) {\n checkRowIndex(this, row);\n checkNonEmpty(this);\n let v = this.get(row, 0);\n let idx = [row, 0];\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) > v) {\n v = this.get(row, i);\n idx[1] = i;\n }\n }\n return idx;\n }\n\n minRow(row) {\n checkRowIndex(this, row);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(row, 0);\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) < v) {\n v = this.get(row, i);\n }\n }\n return v;\n }\n\n minRowIndex(row) {\n checkRowIndex(this, row);\n checkNonEmpty(this);\n let v = this.get(row, 0);\n let idx = [row, 0];\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) < v) {\n v = this.get(row, i);\n idx[1] = i;\n }\n }\n return idx;\n }\n\n maxColumn(column) {\n checkColumnIndex(this, column);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(0, column);\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) > v) {\n v = this.get(i, column);\n }\n }\n return v;\n }\n\n maxColumnIndex(column) {\n checkColumnIndex(this, column);\n checkNonEmpty(this);\n let v = this.get(0, column);\n let idx = [0, column];\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) > v) {\n v = this.get(i, column);\n idx[0] = i;\n }\n }\n return idx;\n }\n\n minColumn(column) {\n checkColumnIndex(this, column);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(0, column);\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) < v) {\n v = this.get(i, column);\n }\n }\n return v;\n }\n\n minColumnIndex(column) {\n checkColumnIndex(this, column);\n checkNonEmpty(this);\n let v = this.get(0, column);\n let idx = [0, column];\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) < v) {\n v = this.get(i, column);\n idx[0] = i;\n }\n }\n return idx;\n }\n\n diag() {\n let min = Math.min(this.rows, this.columns);\n let diag = [];\n for (let i = 0; i < min; i++) {\n diag.push(this.get(i, i));\n }\n return diag;\n }\n\n norm(type = 'frobenius') {\n let result = 0;\n if (type === 'max') {\n return this.max();\n } else if (type === 'frobenius') {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n result = result + this.get(i, j) * this.get(i, j);\n }\n }\n return Math.sqrt(result);\n } else {\n throw new RangeError(`unknown norm type: ${type}`);\n }\n }\n\n cumulativeSum() {\n let sum = 0;\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n sum += this.get(i, j);\n this.set(i, j, sum);\n }\n }\n return this;\n }\n\n dot(vector2) {\n if (AbstractMatrix.isMatrix(vector2)) vector2 = vector2.to1DArray();\n let vector1 = this.to1DArray();\n if (vector1.length !== vector2.length) {\n throw new RangeError('vectors do not have the same size');\n }\n let dot = 0;\n for (let i = 0; i < vector1.length; i++) {\n dot += vector1[i] * vector2[i];\n }\n return dot;\n }\n\n mmul(other) {\n other = Matrix.checkMatrix(other);\n\n let m = this.rows;\n let n = this.columns;\n let p = other.columns;\n\n let result = new Matrix(m, p);\n\n let Bcolj = new Float64Array(n);\n for (let j = 0; j < p; j++) {\n for (let k = 0; k < n; k++) {\n Bcolj[k] = other.get(k, j);\n }\n\n for (let i = 0; i < m; i++) {\n let s = 0;\n for (let k = 0; k < n; k++) {\n s += this.get(i, k) * Bcolj[k];\n }\n\n result.set(i, j, s);\n }\n }\n return result;\n }\n\n strassen2x2(other) {\n other = Matrix.checkMatrix(other);\n let result = new Matrix(2, 2);\n const a11 = this.get(0, 0);\n const b11 = other.get(0, 0);\n const a12 = this.get(0, 1);\n const b12 = other.get(0, 1);\n const a21 = this.get(1, 0);\n const b21 = other.get(1, 0);\n const a22 = this.get(1, 1);\n const b22 = other.get(1, 1);\n\n // Compute intermediate values.\n const m1 = (a11 + a22) * (b11 + b22);\n const m2 = (a21 + a22) * b11;\n const m3 = a11 * (b12 - b22);\n const m4 = a22 * (b21 - b11);\n const m5 = (a11 + a12) * b22;\n const m6 = (a21 - a11) * (b11 + b12);\n const m7 = (a12 - a22) * (b21 + b22);\n\n // Combine intermediate values into the output.\n const c00 = m1 + m4 - m5 + m7;\n const c01 = m3 + m5;\n const c10 = m2 + m4;\n const c11 = m1 - m2 + m3 + m6;\n\n result.set(0, 0, c00);\n result.set(0, 1, c01);\n result.set(1, 0, c10);\n result.set(1, 1, c11);\n return result;\n }\n\n strassen3x3(other) {\n other = Matrix.checkMatrix(other);\n let result = new Matrix(3, 3);\n\n const a00 = this.get(0, 0);\n const a01 = this.get(0, 1);\n const a02 = this.get(0, 2);\n const a10 = this.get(1, 0);\n const a11 = this.get(1, 1);\n const a12 = this.get(1, 2);\n const a20 = this.get(2, 0);\n const a21 = this.get(2, 1);\n const a22 = this.get(2, 2);\n\n const b00 = other.get(0, 0);\n const b01 = other.get(0, 1);\n const b02 = other.get(0, 2);\n const b10 = other.get(1, 0);\n const b11 = other.get(1, 1);\n const b12 = other.get(1, 2);\n const b20 = other.get(2, 0);\n const b21 = other.get(2, 1);\n const b22 = other.get(2, 2);\n\n const m1 = (a00 + a01 + a02 - a10 - a11 - a21 - a22) * b11;\n const m2 = (a00 - a10) * (-b01 + b11);\n const m3 = a11 * (-b00 + b01 + b10 - b11 - b12 - b20 + b22);\n const m4 = (-a00 + a10 + a11) * (b00 - b01 + b11);\n const m5 = (a10 + a11) * (-b00 + b01);\n const m6 = a00 * b00;\n const m7 = (-a00 + a20 + a21) * (b00 - b02 + b12);\n const m8 = (-a00 + a20) * (b02 - b12);\n const m9 = (a20 + a21) * (-b00 + b02);\n const m10 = (a00 + a01 + a02 - a11 - a12 - a20 - a21) * b12;\n const m11 = a21 * (-b00 + b02 + b10 - b11 - b12 - b20 + b21);\n const m12 = (-a02 + a21 + a22) * (b11 + b20 - b21);\n const m13 = (a02 - a22) * (b11 - b21);\n const m14 = a02 * b20;\n const m15 = (a21 + a22) * (-b20 + b21);\n const m16 = (-a02 + a11 + a12) * (b12 + b20 - b22);\n const m17 = (a02 - a12) * (b12 - b22);\n const m18 = (a11 + a12) * (-b20 + b22);\n const m19 = a01 * b10;\n const m20 = a12 * b21;\n const m21 = a10 * b02;\n const m22 = a20 * b01;\n const m23 = a22 * b22;\n\n const c00 = m6 + m14 + m19;\n const c01 = m1 + m4 + m5 + m6 + m12 + m14 + m15;\n const c02 = m6 + m7 + m9 + m10 + m14 + m16 + m18;\n const c10 = m2 + m3 + m4 + m6 + m14 + m16 + m17;\n const c11 = m2 + m4 + m5 + m6 + m20;\n const c12 = m14 + m16 + m17 + m18 + m21;\n const c20 = m6 + m7 + m8 + m11 + m12 + m13 + m14;\n const c21 = m12 + m13 + m14 + m15 + m22;\n const c22 = m6 + m7 + m8 + m9 + m23;\n\n result.set(0, 0, c00);\n result.set(0, 1, c01);\n result.set(0, 2, c02);\n result.set(1, 0, c10);\n result.set(1, 1, c11);\n result.set(1, 2, c12);\n result.set(2, 0, c20);\n result.set(2, 1, c21);\n result.set(2, 2, c22);\n return result;\n }\n\n mmulStrassen(y) {\n y = Matrix.checkMatrix(y);\n let x = this.clone();\n let r1 = x.rows;\n let c1 = x.columns;\n let r2 = y.rows;\n let c2 = y.columns;\n if (c1 !== r2) {\n // eslint-disable-next-line no-console\n console.warn(\n `Multiplying ${r1} x ${c1} and ${r2} x ${c2} matrix: dimensions do not match.`,\n );\n }\n\n // Put a matrix into the top left of a matrix of zeros.\n // `rows` and `cols` are the dimensions of the output matrix.\n function embed(mat, rows, cols) {\n let r = mat.rows;\n let c = mat.columns;\n if (r === rows && c === cols) {\n return mat;\n } else {\n let resultat = AbstractMatrix.zeros(rows, cols);\n resultat = resultat.setSubMatrix(mat, 0, 0);\n return resultat;\n }\n }\n\n // Make sure both matrices are the same size.\n // This is exclusively for simplicity:\n // this algorithm can be implemented with matrices of different sizes.\n\n let r = Math.max(r1, r2);\n let c = Math.max(c1, c2);\n x = embed(x, r, c);\n y = embed(y, r, c);\n\n // Our recursive multiplication function.\n function blockMult(a, b, rows, cols) {\n // For small matrices, resort to naive multiplication.\n if (rows <= 512 || cols <= 512) {\n return a.mmul(b); // a is equivalent to this\n }\n\n // Apply dynamic padding.\n if (rows % 2 === 1 && cols % 2 === 1) {\n a = embed(a, rows + 1, cols + 1);\n b = embed(b, rows + 1, cols + 1);\n } else if (rows % 2 === 1) {\n a = embed(a, rows + 1, cols);\n b = embed(b, rows + 1, cols);\n } else if (cols % 2 === 1) {\n a = embed(a, rows, cols + 1);\n b = embed(b, rows, cols + 1);\n }\n\n let halfRows = parseInt(a.rows / 2, 10);\n let halfCols = parseInt(a.columns / 2, 10);\n // Subdivide input matrices.\n let a11 = a.subMatrix(0, halfRows - 1, 0, halfCols - 1);\n let b11 = b.subMatrix(0, halfRows - 1, 0, halfCols - 1);\n\n let a12 = a.subMatrix(0, halfRows - 1, halfCols, a.columns - 1);\n let b12 = b.subMatrix(0, halfRows - 1, halfCols, b.columns - 1);\n\n let a21 = a.subMatrix(halfRows, a.rows - 1, 0, halfCols - 1);\n let b21 = b.subMatrix(halfRows, b.rows - 1, 0, halfCols - 1);\n\n let a22 = a.subMatrix(halfRows, a.rows - 1, halfCols, a.columns - 1);\n let b22 = b.subMatrix(halfRows, b.rows - 1, halfCols, b.columns - 1);\n\n // Compute intermediate values.\n let m1 = blockMult(\n AbstractMatrix.add(a11, a22),\n AbstractMatrix.add(b11, b22),\n halfRows,\n halfCols,\n );\n let m2 = blockMult(AbstractMatrix.add(a21, a22), b11, halfRows, halfCols);\n let m3 = blockMult(a11, AbstractMatrix.sub(b12, b22), halfRows, halfCols);\n let m4 = blockMult(a22, AbstractMatrix.sub(b21, b11), halfRows, halfCols);\n let m5 = blockMult(AbstractMatrix.add(a11, a12), b22, halfRows, halfCols);\n let m6 = blockMult(\n AbstractMatrix.sub(a21, a11),\n AbstractMatrix.add(b11, b12),\n halfRows,\n halfCols,\n );\n let m7 = blockMult(\n AbstractMatrix.sub(a12, a22),\n AbstractMatrix.add(b21, b22),\n halfRows,\n halfCols,\n );\n\n // Combine intermediate values into the output.\n let c11 = AbstractMatrix.add(m1, m4);\n c11.sub(m5);\n c11.add(m7);\n let c12 = AbstractMatrix.add(m3, m5);\n let c21 = AbstractMatrix.add(m2, m4);\n let c22 = AbstractMatrix.sub(m1, m2);\n c22.add(m3);\n c22.add(m6);\n\n // Crop output to the desired size (undo dynamic padding).\n let resultat = AbstractMatrix.zeros(2 * c11.rows, 2 * c11.columns);\n resultat = resultat.setSubMatrix(c11, 0, 0);\n resultat = resultat.setSubMatrix(c12, c11.rows, 0);\n resultat = resultat.setSubMatrix(c21, 0, c11.columns);\n resultat = resultat.setSubMatrix(c22, c11.rows, c11.columns);\n return resultat.subMatrix(0, rows - 1, 0, cols - 1);\n }\n\n return blockMult(x, y, r, c);\n }\n\n scaleRows(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1 } = options;\n if (!Number.isFinite(min)) throw new TypeError('min must be a number');\n if (!Number.isFinite(max)) throw new TypeError('max must be a number');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let i = 0; i < this.rows; i++) {\n const row = this.getRow(i);\n if (row.length > 0) {\n rescale(row, { min, max, output: row });\n }\n newMatrix.setRow(i, row);\n }\n return newMatrix;\n }\n\n scaleColumns(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1 } = options;\n if (!Number.isFinite(min)) throw new TypeError('min must be a number');\n if (!Number.isFinite(max)) throw new TypeError('max must be a number');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let i = 0; i < this.columns; i++) {\n const column = this.getColumn(i);\n if (column.length) {\n rescale(column, {\n min: min,\n max: max,\n output: column,\n });\n }\n newMatrix.setColumn(i, column);\n }\n return newMatrix;\n }\n\n flipRows() {\n const middle = Math.ceil(this.columns / 2);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < middle; j++) {\n let first = this.get(i, j);\n let last = this.get(i, this.columns - 1 - j);\n this.set(i, j, last);\n this.set(i, this.columns - 1 - j, first);\n }\n }\n return this;\n }\n\n flipColumns() {\n const middle = Math.ceil(this.rows / 2);\n for (let j = 0; j < this.columns; j++) {\n for (let i = 0; i < middle; i++) {\n let first = this.get(i, j);\n let last = this.get(this.rows - 1 - i, j);\n this.set(i, j, last);\n this.set(this.rows - 1 - i, j, first);\n }\n }\n return this;\n }\n\n kroneckerProduct(other) {\n other = Matrix.checkMatrix(other);\n\n let m = this.rows;\n let n = this.columns;\n let p = other.rows;\n let q = other.columns;\n\n let result = new Matrix(m * p, n * q);\n for (let i = 0; i < m; i++) {\n for (let j = 0; j < n; j++) {\n for (let k = 0; k < p; k++) {\n for (let l = 0; l < q; l++) {\n result.set(p * i + k, q * j + l, this.get(i, j) * other.get(k, l));\n }\n }\n }\n }\n return result;\n }\n\n kroneckerSum(other) {\n other = Matrix.checkMatrix(other);\n if (!this.isSquare() || !other.isSquare()) {\n throw new Error('Kronecker Sum needs two Square Matrices');\n }\n let m = this.rows;\n let n = other.rows;\n let AxI = this.kroneckerProduct(Matrix.eye(n, n));\n let IxB = Matrix.eye(m, m).kroneckerProduct(other);\n return AxI.add(IxB);\n }\n\n transpose() {\n let result = new Matrix(this.columns, this.rows);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n result.set(j, i, this.get(i, j));\n }\n }\n return result;\n }\n\n sortRows(compareFunction = compareNumbers) {\n for (let i = 0; i < this.rows; i++) {\n this.setRow(i, this.getRow(i).sort(compareFunction));\n }\n return this;\n }\n\n sortColumns(compareFunction = compareNumbers) {\n for (let i = 0; i < this.columns; i++) {\n this.setColumn(i, this.getColumn(i).sort(compareFunction));\n }\n return this;\n }\n\n subMatrix(startRow, endRow, startColumn, endColumn) {\n checkRange(this, startRow, endRow, startColumn, endColumn);\n let newMatrix = new Matrix(\n endRow - startRow + 1,\n endColumn - startColumn + 1,\n );\n for (let i = startRow; i <= endRow; i++) {\n for (let j = startColumn; j <= endColumn; j++) {\n newMatrix.set(i - startRow, j - startColumn, this.get(i, j));\n }\n }\n return newMatrix;\n }\n\n subMatrixRow(indices, startColumn, endColumn) {\n if (startColumn === undefined) startColumn = 0;\n if (endColumn === undefined) endColumn = this.columns - 1;\n if (\n startColumn > endColumn ||\n startColumn < 0 ||\n startColumn >= this.columns ||\n endColumn < 0 ||\n endColumn >= this.columns\n ) {\n throw new RangeError('Argument out of range');\n }\n\n let newMatrix = new Matrix(indices.length, endColumn - startColumn + 1);\n for (let i = 0; i < indices.length; i++) {\n for (let j = startColumn; j <= endColumn; j++) {\n if (indices[i] < 0 || indices[i] >= this.rows) {\n throw new RangeError(`Row index out of range: ${indices[i]}`);\n }\n newMatrix.set(i, j - startColumn, this.get(indices[i], j));\n }\n }\n return newMatrix;\n }\n\n subMatrixColumn(indices, startRow, endRow) {\n if (startRow === undefined) startRow = 0;\n if (endRow === undefined) endRow = this.rows - 1;\n if (\n startRow > endRow ||\n startRow < 0 ||\n startRow >= this.rows ||\n endRow < 0 ||\n endRow >= this.rows\n ) {\n throw new RangeError('Argument out of range');\n }\n\n let newMatrix = new Matrix(endRow - startRow + 1, indices.length);\n for (let i = 0; i < indices.length; i++) {\n for (let j = startRow; j <= endRow; j++) {\n if (indices[i] < 0 || indices[i] >= this.columns) {\n throw new RangeError(`Column index out of range: ${indices[i]}`);\n }\n newMatrix.set(j - startRow, i, this.get(j, indices[i]));\n }\n }\n return newMatrix;\n }\n\n setSubMatrix(matrix, startRow, startColumn) {\n matrix = Matrix.checkMatrix(matrix);\n if (matrix.isEmpty()) {\n return this;\n }\n let endRow = startRow + matrix.rows - 1;\n let endColumn = startColumn + matrix.columns - 1;\n checkRange(this, startRow, endRow, startColumn, endColumn);\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n this.set(startRow + i, startColumn + j, matrix.get(i, j));\n }\n }\n return this;\n }\n\n selection(rowIndices, columnIndices) {\n checkRowIndices(this, rowIndices);\n checkColumnIndices(this, columnIndices);\n let newMatrix = new Matrix(rowIndices.length, columnIndices.length);\n for (let i = 0; i < rowIndices.length; i++) {\n let rowIndex = rowIndices[i];\n for (let j = 0; j < columnIndices.length; j++) {\n let columnIndex = columnIndices[j];\n newMatrix.set(i, j, this.get(rowIndex, columnIndex));\n }\n }\n return newMatrix;\n }\n\n trace() {\n let min = Math.min(this.rows, this.columns);\n let trace = 0;\n for (let i = 0; i < min; i++) {\n trace += this.get(i, i);\n }\n return trace;\n }\n\n clone() {\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n newMatrix.set(row, column, this.get(row, column));\n }\n }\n return newMatrix;\n }\n\n sum(by) {\n switch (by) {\n case 'row':\n return sumByRow(this);\n case 'column':\n return sumByColumn(this);\n case undefined:\n return sumAll(this);\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n product(by) {\n switch (by) {\n case 'row':\n return productByRow(this);\n case 'column':\n return productByColumn(this);\n case undefined:\n return productAll(this);\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n mean(by) {\n const sum = this.sum(by);\n switch (by) {\n case 'row': {\n for (let i = 0; i < this.rows; i++) {\n sum[i] /= this.columns;\n }\n return sum;\n }\n case 'column': {\n for (let i = 0; i < this.columns; i++) {\n sum[i] /= this.rows;\n }\n return sum;\n }\n case undefined:\n return sum / this.size;\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n variance(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { unbiased = true, mean = this.mean(by) } = options;\n if (typeof unbiased !== 'boolean') {\n throw new TypeError('unbiased must be a boolean');\n }\n switch (by) {\n case 'row': {\n if (!isAnyArray(mean)) {\n throw new TypeError('mean must be an array');\n }\n return varianceByRow(this, unbiased, mean);\n }\n case 'column': {\n if (!isAnyArray(mean)) {\n throw new TypeError('mean must be an array');\n }\n return varianceByColumn(this, unbiased, mean);\n }\n case undefined: {\n if (typeof mean !== 'number') {\n throw new TypeError('mean must be a number');\n }\n return varianceAll(this, unbiased, mean);\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n standardDeviation(by, options) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n const variance = this.variance(by, options);\n if (by === undefined) {\n return Math.sqrt(variance);\n } else {\n for (let i = 0; i < variance.length; i++) {\n variance[i] = Math.sqrt(variance[i]);\n }\n return variance;\n }\n }\n\n center(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { center = this.mean(by) } = options;\n switch (by) {\n case 'row': {\n if (!isAnyArray(center)) {\n throw new TypeError('center must be an array');\n }\n centerByRow(this, center);\n return this;\n }\n case 'column': {\n if (!isAnyArray(center)) {\n throw new TypeError('center must be an array');\n }\n centerByColumn(this, center);\n return this;\n }\n case undefined: {\n if (typeof center !== 'number') {\n throw new TypeError('center must be a number');\n }\n centerAll(this, center);\n return this;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n scale(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n let scale = options.scale;\n switch (by) {\n case 'row': {\n if (scale === undefined) {\n scale = getScaleByRow(this);\n } else if (!isAnyArray(scale)) {\n throw new TypeError('scale must be an array');\n }\n scaleByRow(this, scale);\n return this;\n }\n case 'column': {\n if (scale === undefined) {\n scale = getScaleByColumn(this);\n } else if (!isAnyArray(scale)) {\n throw new TypeError('scale must be an array');\n }\n scaleByColumn(this, scale);\n return this;\n }\n case undefined: {\n if (scale === undefined) {\n scale = getScaleAll(this);\n } else if (typeof scale !== 'number') {\n throw new TypeError('scale must be a number');\n }\n scaleAll(this, scale);\n return this;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n toString(options) {\n return inspectMatrixWithOptions(this, options);\n }\n}\n\nAbstractMatrix.prototype.klass = 'Matrix';\nif (typeof Symbol !== 'undefined') {\n AbstractMatrix.prototype[Symbol.for('nodejs.util.inspect.custom')] =\n inspectMatrix;\n}\n\nfunction compareNumbers(a, b) {\n return a - b;\n}\n\nfunction isArrayOfNumbers(array) {\n return array.every((element) => {\n return typeof element === 'number';\n });\n}\n\n// Synonyms\nAbstractMatrix.random = AbstractMatrix.rand;\nAbstractMatrix.randomInt = AbstractMatrix.randInt;\nAbstractMatrix.diagonal = AbstractMatrix.diag;\nAbstractMatrix.prototype.diagonal = AbstractMatrix.prototype.diag;\nAbstractMatrix.identity = AbstractMatrix.eye;\nAbstractMatrix.prototype.negate = AbstractMatrix.prototype.neg;\nAbstractMatrix.prototype.tensorProduct =\n AbstractMatrix.prototype.kroneckerProduct;\n\nexport default class Matrix extends AbstractMatrix {\n constructor(nRows, nColumns) {\n super();\n if (Matrix.isMatrix(nRows)) {\n // eslint-disable-next-line no-constructor-return\n return nRows.clone();\n } else if (Number.isInteger(nRows) && nRows >= 0) {\n // Create an empty matrix\n this.data = [];\n if (Number.isInteger(nColumns) && nColumns >= 0) {\n for (let i = 0; i < nRows; i++) {\n this.data.push(new Float64Array(nColumns));\n }\n } else {\n throw new TypeError('nColumns must be a positive integer');\n }\n } else if (isAnyArray(nRows)) {\n // Copy the values from the 2D array\n const arrayData = nRows;\n nRows = arrayData.length;\n nColumns = nRows ? arrayData[0].length : 0;\n if (typeof nColumns !== 'number') {\n throw new TypeError(\n 'Data must be a 2D array with at least one element',\n );\n }\n this.data = [];\n for (let i = 0; i < nRows; i++) {\n if (arrayData[i].length !== nColumns) {\n throw new RangeError('Inconsistent array dimensions');\n }\n if (!isArrayOfNumbers(arrayData[i])) {\n throw new TypeError('Input data contains non-numeric values');\n }\n this.data.push(Float64Array.from(arrayData[i]));\n }\n } else {\n throw new TypeError(\n 'First argument must be a positive number or an array',\n );\n }\n this.rows = nRows;\n this.columns = nColumns;\n }\n\n set(rowIndex, columnIndex, value) {\n this.data[rowIndex][columnIndex] = value;\n return this;\n }\n\n get(rowIndex, columnIndex) {\n return this.data[rowIndex][columnIndex];\n }\n\n removeRow(index) {\n checkRowIndex(this, index);\n this.data.splice(index, 1);\n this.rows -= 1;\n return this;\n }\n\n addRow(index, array) {\n if (array === undefined) {\n array = index;\n index = this.rows;\n }\n checkRowIndex(this, index, true);\n array = Float64Array.from(checkRowVector(this, array));\n this.data.splice(index, 0, array);\n this.rows += 1;\n return this;\n }\n\n removeColumn(index) {\n checkColumnIndex(this, index);\n for (let i = 0; i < this.rows; i++) {\n const newRow = new Float64Array(this.columns - 1);\n for (let j = 0; j < index; j++) {\n newRow[j] = this.data[i][j];\n }\n for (let j = index + 1; j < this.columns; j++) {\n newRow[j - 1] = this.data[i][j];\n }\n this.data[i] = newRow;\n }\n this.columns -= 1;\n return this;\n }\n\n addColumn(index, array) {\n if (typeof array === 'undefined') {\n array = index;\n index = this.columns;\n }\n checkColumnIndex(this, index, true);\n array = checkColumnVector(this, array);\n for (let i = 0; i < this.rows; i++) {\n const newRow = new Float64Array(this.columns + 1);\n let j = 0;\n for (; j < index; j++) {\n newRow[j] = this.data[i][j];\n }\n newRow[j++] = array[i];\n for (; j < this.columns + 1; j++) {\n newRow[j] = this.data[i][j - 1];\n }\n this.data[i] = newRow;\n }\n this.columns += 1;\n return this;\n }\n}\n\ninstallMathOperations(AbstractMatrix, Matrix);\n","import { newArray } from './util';\n\nexport function sumByRow(matrix) {\n let sum = newArray(matrix.rows);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[i] += matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function sumByColumn(matrix) {\n let sum = newArray(matrix.columns);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[j] += matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function sumAll(matrix) {\n let v = 0;\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n v += matrix.get(i, j);\n }\n }\n return v;\n}\n\nexport function productByRow(matrix) {\n let sum = newArray(matrix.rows, 1);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[i] *= matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function productByColumn(matrix) {\n let sum = newArray(matrix.columns, 1);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[j] *= matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function productAll(matrix) {\n let v = 1;\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n v *= matrix.get(i, j);\n }\n }\n return v;\n}\n\nexport function varianceByRow(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const variance = [];\n\n for (let i = 0; i < rows; i++) {\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let j = 0; j < cols; j++) {\n x = matrix.get(i, j) - mean[i];\n sum1 += x;\n sum2 += x * x;\n }\n if (unbiased) {\n variance.push((sum2 - (sum1 * sum1) / cols) / (cols - 1));\n } else {\n variance.push((sum2 - (sum1 * sum1) / cols) / cols);\n }\n }\n return variance;\n}\n\nexport function varianceByColumn(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const variance = [];\n\n for (let j = 0; j < cols; j++) {\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let i = 0; i < rows; i++) {\n x = matrix.get(i, j) - mean[j];\n sum1 += x;\n sum2 += x * x;\n }\n if (unbiased) {\n variance.push((sum2 - (sum1 * sum1) / rows) / (rows - 1));\n } else {\n variance.push((sum2 - (sum1 * sum1) / rows) / rows);\n }\n }\n return variance;\n}\n\nexport function varianceAll(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const size = rows * cols;\n\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n x = matrix.get(i, j) - mean;\n sum1 += x;\n sum2 += x * x;\n }\n }\n if (unbiased) {\n return (sum2 - (sum1 * sum1) / size) / (size - 1);\n } else {\n return (sum2 - (sum1 * sum1) / size) / size;\n }\n}\n\nexport function centerByRow(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean[i]);\n }\n }\n}\n\nexport function centerByColumn(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean[j]);\n }\n }\n}\n\nexport function centerAll(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean);\n }\n }\n}\n\nexport function getScaleByRow(matrix) {\n const scale = [];\n for (let i = 0; i < matrix.rows; i++) {\n let sum = 0;\n for (let j = 0; j < matrix.columns; j++) {\n sum += Math.pow(matrix.get(i, j), 2) / (matrix.columns - 1);\n }\n scale.push(Math.sqrt(sum));\n }\n return scale;\n}\n\nexport function scaleByRow(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale[i]);\n }\n }\n}\n\nexport function getScaleByColumn(matrix) {\n const scale = [];\n for (let j = 0; j < matrix.columns; j++) {\n let sum = 0;\n for (let i = 0; i < matrix.rows; i++) {\n sum += Math.pow(matrix.get(i, j), 2) / (matrix.rows - 1);\n }\n scale.push(Math.sqrt(sum));\n }\n return scale;\n}\n\nexport function scaleByColumn(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale[j]);\n }\n }\n}\n\nexport function getScaleAll(matrix) {\n const divider = matrix.size - 1;\n let sum = 0;\n for (let j = 0; j < matrix.columns; j++) {\n for (let i = 0; i < matrix.rows; i++) {\n sum += Math.pow(matrix.get(i, j), 2) / divider;\n }\n }\n return Math.sqrt(sum);\n}\n\nexport function scaleAll(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale);\n }\n }\n}\n","export function installMathOperations(AbstractMatrix, Matrix) {\n AbstractMatrix.prototype.add = function add(value) {\n if (typeof value === 'number') return this.addS(value);\n return this.addM(value);\n };\n\n AbstractMatrix.prototype.addS = function addS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.addM = function addM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.add = function add(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.add(value);\n };\n\n AbstractMatrix.prototype.sub = function sub(value) {\n if (typeof value === 'number') return this.subS(value);\n return this.subM(value);\n };\n\n AbstractMatrix.prototype.subS = function subS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.subM = function subM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.sub = function sub(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sub(value);\n };\n AbstractMatrix.prototype.subtract = AbstractMatrix.prototype.sub;\n AbstractMatrix.prototype.subtractS = AbstractMatrix.prototype.subS;\n AbstractMatrix.prototype.subtractM = AbstractMatrix.prototype.subM;\n AbstractMatrix.subtract = AbstractMatrix.sub;\n\n AbstractMatrix.prototype.mul = function mul(value) {\n if (typeof value === 'number') return this.mulS(value);\n return this.mulM(value);\n };\n\n AbstractMatrix.prototype.mulS = function mulS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.mulM = function mulM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.mul = function mul(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.mul(value);\n };\n AbstractMatrix.prototype.multiply = AbstractMatrix.prototype.mul;\n AbstractMatrix.prototype.multiplyS = AbstractMatrix.prototype.mulS;\n AbstractMatrix.prototype.multiplyM = AbstractMatrix.prototype.mulM;\n AbstractMatrix.multiply = AbstractMatrix.mul;\n\n AbstractMatrix.prototype.div = function div(value) {\n if (typeof value === 'number') return this.divS(value);\n return this.divM(value);\n };\n\n AbstractMatrix.prototype.divS = function divS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.divM = function divM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.div = function div(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.div(value);\n };\n AbstractMatrix.prototype.divide = AbstractMatrix.prototype.div;\n AbstractMatrix.prototype.divideS = AbstractMatrix.prototype.divS;\n AbstractMatrix.prototype.divideM = AbstractMatrix.prototype.divM;\n AbstractMatrix.divide = AbstractMatrix.div;\n\n AbstractMatrix.prototype.mod = function mod(value) {\n if (typeof value === 'number') return this.modS(value);\n return this.modM(value);\n };\n\n AbstractMatrix.prototype.modS = function modS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) % value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.modM = function modM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) % matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.mod = function mod(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.mod(value);\n };\n AbstractMatrix.prototype.modulus = AbstractMatrix.prototype.mod;\n AbstractMatrix.prototype.modulusS = AbstractMatrix.prototype.modS;\n AbstractMatrix.prototype.modulusM = AbstractMatrix.prototype.modM;\n AbstractMatrix.modulus = AbstractMatrix.mod;\n\n AbstractMatrix.prototype.and = function and(value) {\n if (typeof value === 'number') return this.andS(value);\n return this.andM(value);\n };\n\n AbstractMatrix.prototype.andS = function andS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) & value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.andM = function andM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) & matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.and = function and(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.and(value);\n };\n\n AbstractMatrix.prototype.or = function or(value) {\n if (typeof value === 'number') return this.orS(value);\n return this.orM(value);\n };\n\n AbstractMatrix.prototype.orS = function orS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) | value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.orM = function orM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) | matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.or = function or(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.or(value);\n };\n\n AbstractMatrix.prototype.xor = function xor(value) {\n if (typeof value === 'number') return this.xorS(value);\n return this.xorM(value);\n };\n\n AbstractMatrix.prototype.xorS = function xorS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) ^ value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.xorM = function xorM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) ^ matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.xor = function xor(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.xor(value);\n };\n\n AbstractMatrix.prototype.leftShift = function leftShift(value) {\n if (typeof value === 'number') return this.leftShiftS(value);\n return this.leftShiftM(value);\n };\n\n AbstractMatrix.prototype.leftShiftS = function leftShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) << value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.leftShiftM = function leftShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) << matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.leftShift = function leftShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.leftShift(value);\n };\n\n AbstractMatrix.prototype.signPropagatingRightShift = function signPropagatingRightShift(value) {\n if (typeof value === 'number') return this.signPropagatingRightShiftS(value);\n return this.signPropagatingRightShiftM(value);\n };\n\n AbstractMatrix.prototype.signPropagatingRightShiftS = function signPropagatingRightShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >> value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.signPropagatingRightShiftM = function signPropagatingRightShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >> matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.signPropagatingRightShift = function signPropagatingRightShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.signPropagatingRightShift(value);\n };\n\n AbstractMatrix.prototype.rightShift = function rightShift(value) {\n if (typeof value === 'number') return this.rightShiftS(value);\n return this.rightShiftM(value);\n };\n\n AbstractMatrix.prototype.rightShiftS = function rightShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >>> value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.rightShiftM = function rightShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >>> matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.rightShift = function rightShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.rightShift(value);\n };\n AbstractMatrix.prototype.zeroFillRightShift = AbstractMatrix.prototype.rightShift;\n AbstractMatrix.prototype.zeroFillRightShiftS = AbstractMatrix.prototype.rightShiftS;\n AbstractMatrix.prototype.zeroFillRightShiftM = AbstractMatrix.prototype.rightShiftM;\n AbstractMatrix.zeroFillRightShift = AbstractMatrix.rightShift;\n\n AbstractMatrix.prototype.not = function not() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, ~(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.not = function not(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.not();\n };\n\n AbstractMatrix.prototype.abs = function abs() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.abs(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.abs = function abs(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.abs();\n };\n\n AbstractMatrix.prototype.acos = function acos() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.acos(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.acos = function acos(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.acos();\n };\n\n AbstractMatrix.prototype.acosh = function acosh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.acosh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.acosh = function acosh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.acosh();\n };\n\n AbstractMatrix.prototype.asin = function asin() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.asin(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.asin = function asin(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.asin();\n };\n\n AbstractMatrix.prototype.asinh = function asinh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.asinh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.asinh = function asinh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.asinh();\n };\n\n AbstractMatrix.prototype.atan = function atan() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.atan(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.atan = function atan(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.atan();\n };\n\n AbstractMatrix.prototype.atanh = function atanh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.atanh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.atanh = function atanh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.atanh();\n };\n\n AbstractMatrix.prototype.cbrt = function cbrt() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cbrt(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cbrt = function cbrt(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cbrt();\n };\n\n AbstractMatrix.prototype.ceil = function ceil() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.ceil(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.ceil = function ceil(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.ceil();\n };\n\n AbstractMatrix.prototype.clz32 = function clz32() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.clz32(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.clz32 = function clz32(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.clz32();\n };\n\n AbstractMatrix.prototype.cos = function cos() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cos(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cos = function cos(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cos();\n };\n\n AbstractMatrix.prototype.cosh = function cosh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cosh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cosh = function cosh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cosh();\n };\n\n AbstractMatrix.prototype.exp = function exp() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.exp(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.exp = function exp(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.exp();\n };\n\n AbstractMatrix.prototype.expm1 = function expm1() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.expm1(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.expm1 = function expm1(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.expm1();\n };\n\n AbstractMatrix.prototype.floor = function floor() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.floor(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.floor = function floor(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.floor();\n };\n\n AbstractMatrix.prototype.fround = function fround() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.fround(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.fround = function fround(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.fround();\n };\n\n AbstractMatrix.prototype.log = function log() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log = function log(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log();\n };\n\n AbstractMatrix.prototype.log1p = function log1p() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log1p(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log1p = function log1p(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log1p();\n };\n\n AbstractMatrix.prototype.log10 = function log10() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log10(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log10 = function log10(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log10();\n };\n\n AbstractMatrix.prototype.log2 = function log2() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log2(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log2 = function log2(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log2();\n };\n\n AbstractMatrix.prototype.round = function round() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.round(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.round = function round(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.round();\n };\n\n AbstractMatrix.prototype.sign = function sign() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sign(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sign = function sign(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sign();\n };\n\n AbstractMatrix.prototype.sin = function sin() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sin(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sin = function sin(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sin();\n };\n\n AbstractMatrix.prototype.sinh = function sinh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sinh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sinh = function sinh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sinh();\n };\n\n AbstractMatrix.prototype.sqrt = function sqrt() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sqrt(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sqrt = function sqrt(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sqrt();\n };\n\n AbstractMatrix.prototype.tan = function tan() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.tan(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.tan = function tan(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.tan();\n };\n\n AbstractMatrix.prototype.tanh = function tanh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.tanh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.tanh = function tanh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.tanh();\n };\n\n AbstractMatrix.prototype.trunc = function trunc() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.trunc(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.trunc = function trunc(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.trunc();\n };\n\n AbstractMatrix.pow = function pow(matrix, arg0) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.pow(arg0);\n };\n\n AbstractMatrix.prototype.pow = function pow(value) {\n if (typeof value === 'number') return this.powS(value);\n return this.powM(value);\n };\n\n AbstractMatrix.prototype.powS = function powS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.pow(this.get(i, j), value));\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.powM = function powM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.pow(this.get(i, j), matrix.get(i, j)));\n }\n }\n return this;\n };\n}\n","import { AbstractMatrix } from '../matrix';\n\nexport default class WrapperMatrix2D extends AbstractMatrix {\n constructor(data) {\n super();\n this.data = data;\n this.rows = data.length;\n this.columns = data[0].length;\n }\n\n set(rowIndex, columnIndex, value) {\n this.data[rowIndex][columnIndex] = value;\n return this;\n }\n\n get(rowIndex, columnIndex) {\n return this.data[rowIndex][columnIndex];\n }\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nexport default class LuDecomposition {\n constructor(matrix) {\n matrix = WrapperMatrix2D.checkMatrix(matrix);\n\n let lu = matrix.clone();\n let rows = lu.rows;\n let columns = lu.columns;\n let pivotVector = new Float64Array(rows);\n let pivotSign = 1;\n let i, j, k, p, s, t, v;\n let LUcolj, kmax;\n\n for (i = 0; i < rows; i++) {\n pivotVector[i] = i;\n }\n\n LUcolj = new Float64Array(rows);\n\n for (j = 0; j < columns; j++) {\n for (i = 0; i < rows; i++) {\n LUcolj[i] = lu.get(i, j);\n }\n\n for (i = 0; i < rows; i++) {\n kmax = Math.min(i, j);\n s = 0;\n for (k = 0; k < kmax; k++) {\n s += lu.get(i, k) * LUcolj[k];\n }\n LUcolj[i] -= s;\n lu.set(i, j, LUcolj[i]);\n }\n\n p = j;\n for (i = j + 1; i < rows; i++) {\n if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {\n p = i;\n }\n }\n\n if (p !== j) {\n for (k = 0; k < columns; k++) {\n t = lu.get(p, k);\n lu.set(p, k, lu.get(j, k));\n lu.set(j, k, t);\n }\n\n v = pivotVector[p];\n pivotVector[p] = pivotVector[j];\n pivotVector[j] = v;\n\n pivotSign = -pivotSign;\n }\n\n if (j < rows && lu.get(j, j) !== 0) {\n for (i = j + 1; i < rows; i++) {\n lu.set(i, j, lu.get(i, j) / lu.get(j, j));\n }\n }\n }\n\n this.LU = lu;\n this.pivotVector = pivotVector;\n this.pivotSign = pivotSign;\n }\n\n isSingular() {\n let data = this.LU;\n let col = data.columns;\n for (let j = 0; j < col; j++) {\n if (data.get(j, j) === 0) {\n return true;\n }\n }\n return false;\n }\n\n solve(value) {\n value = Matrix.checkMatrix(value);\n\n let lu = this.LU;\n let rows = lu.rows;\n\n if (rows !== value.rows) {\n throw new Error('Invalid matrix dimensions');\n }\n if (this.isSingular()) {\n throw new Error('LU matrix is singular');\n }\n\n let count = value.columns;\n let X = value.subMatrixRow(this.pivotVector, 0, count - 1);\n let columns = lu.columns;\n let i, j, k;\n\n for (k = 0; k < columns; k++) {\n for (i = k + 1; i < columns; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * lu.get(i, k));\n }\n }\n }\n for (k = columns - 1; k >= 0; k--) {\n for (j = 0; j < count; j++) {\n X.set(k, j, X.get(k, j) / lu.get(k, k));\n }\n for (i = 0; i < k; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * lu.get(i, k));\n }\n }\n }\n return X;\n }\n\n get determinant() {\n let data = this.LU;\n if (!data.isSquare()) {\n throw new Error('Matrix must be square');\n }\n let determinant = this.pivotSign;\n let col = data.columns;\n for (let j = 0; j < col; j++) {\n determinant *= data.get(j, j);\n }\n return determinant;\n }\n\n get lowerTriangularMatrix() {\n let data = this.LU;\n let rows = data.rows;\n let columns = data.columns;\n let X = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n if (i > j) {\n X.set(i, j, data.get(i, j));\n } else if (i === j) {\n X.set(i, j, 1);\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get upperTriangularMatrix() {\n let data = this.LU;\n let rows = data.rows;\n let columns = data.columns;\n let X = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n if (i <= j) {\n X.set(i, j, data.get(i, j));\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get pivotPermutationVector() {\n return Array.from(this.pivotVector);\n }\n}\n","export function hypotenuse(a, b) {\n let r = 0;\n if (Math.abs(a) > Math.abs(b)) {\n r = b / a;\n return Math.abs(a) * Math.sqrt(1 + r * r);\n }\n if (b !== 0) {\n r = a / b;\n return Math.abs(b) * Math.sqrt(1 + r * r);\n }\n return 0;\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nimport { hypotenuse } from './util';\n\nexport default class QrDecomposition {\n constructor(value) {\n value = WrapperMatrix2D.checkMatrix(value);\n\n let qr = value.clone();\n let m = value.rows;\n let n = value.columns;\n let rdiag = new Float64Array(n);\n let i, j, k, s;\n\n for (k = 0; k < n; k++) {\n let nrm = 0;\n for (i = k; i < m; i++) {\n nrm = hypotenuse(nrm, qr.get(i, k));\n }\n if (nrm !== 0) {\n if (qr.get(k, k) < 0) {\n nrm = -nrm;\n }\n for (i = k; i < m; i++) {\n qr.set(i, k, qr.get(i, k) / nrm);\n }\n qr.set(k, k, qr.get(k, k) + 1);\n for (j = k + 1; j < n; j++) {\n s = 0;\n for (i = k; i < m; i++) {\n s += qr.get(i, k) * qr.get(i, j);\n }\n s = -s / qr.get(k, k);\n for (i = k; i < m; i++) {\n qr.set(i, j, qr.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n rdiag[k] = -nrm;\n }\n\n this.QR = qr;\n this.Rdiag = rdiag;\n }\n\n solve(value) {\n value = Matrix.checkMatrix(value);\n\n let qr = this.QR;\n let m = qr.rows;\n\n if (value.rows !== m) {\n throw new Error('Matrix row dimensions must agree');\n }\n if (!this.isFullRank()) {\n throw new Error('Matrix is rank deficient');\n }\n\n let count = value.columns;\n let X = value.clone();\n let n = qr.columns;\n let i, j, k, s;\n\n for (k = 0; k < n; k++) {\n for (j = 0; j < count; j++) {\n s = 0;\n for (i = k; i < m; i++) {\n s += qr.get(i, k) * X.get(i, j);\n }\n s = -s / qr.get(k, k);\n for (i = k; i < m; i++) {\n X.set(i, j, X.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n for (k = n - 1; k >= 0; k--) {\n for (j = 0; j < count; j++) {\n X.set(k, j, X.get(k, j) / this.Rdiag[k]);\n }\n for (i = 0; i < k; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * qr.get(i, k));\n }\n }\n }\n\n return X.subMatrix(0, n - 1, 0, count - 1);\n }\n\n isFullRank() {\n let columns = this.QR.columns;\n for (let i = 0; i < columns; i++) {\n if (this.Rdiag[i] === 0) {\n return false;\n }\n }\n return true;\n }\n\n get upperTriangularMatrix() {\n let qr = this.QR;\n let n = qr.columns;\n let X = new Matrix(n, n);\n let i, j;\n for (i = 0; i < n; i++) {\n for (j = 0; j < n; j++) {\n if (i < j) {\n X.set(i, j, qr.get(i, j));\n } else if (i === j) {\n X.set(i, j, this.Rdiag[i]);\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get orthogonalMatrix() {\n let qr = this.QR;\n let rows = qr.rows;\n let columns = qr.columns;\n let X = new Matrix(rows, columns);\n let i, j, k, s;\n\n for (k = columns - 1; k >= 0; k--) {\n for (i = 0; i < rows; i++) {\n X.set(i, k, 0);\n }\n X.set(k, k, 1);\n for (j = k; j < columns; j++) {\n if (qr.get(k, k) !== 0) {\n s = 0;\n for (i = k; i < rows; i++) {\n s += qr.get(i, k) * X.get(i, j);\n }\n\n s = -s / qr.get(k, k);\n\n for (i = k; i < rows; i++) {\n X.set(i, j, X.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n }\n return X;\n }\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nimport { hypotenuse } from './util';\n\nexport default class SingularValueDecomposition {\n constructor(value, options = {}) {\n value = WrapperMatrix2D.checkMatrix(value);\n\n if (value.isEmpty()) {\n throw new Error('Matrix must be non-empty');\n }\n\n let m = value.rows;\n let n = value.columns;\n\n const {\n computeLeftSingularVectors = true,\n computeRightSingularVectors = true,\n autoTranspose = false,\n } = options;\n\n let wantu = Boolean(computeLeftSingularVectors);\n let wantv = Boolean(computeRightSingularVectors);\n\n let swapped = false;\n let a;\n if (m < n) {\n if (!autoTranspose) {\n a = value.clone();\n // eslint-disable-next-line no-console\n console.warn(\n 'Computing SVD on a matrix with more columns than rows. Consider enabling autoTranspose',\n );\n } else {\n a = value.transpose();\n m = a.rows;\n n = a.columns;\n swapped = true;\n let aux = wantu;\n wantu = wantv;\n wantv = aux;\n }\n } else {\n a = value.clone();\n }\n\n let nu = Math.min(m, n);\n let ni = Math.min(m + 1, n);\n let s = new Float64Array(ni);\n let U = new Matrix(m, nu);\n let V = new Matrix(n, n);\n\n let e = new Float64Array(n);\n let work = new Float64Array(m);\n\n let si = new Float64Array(ni);\n for (let i = 0; i < ni; i++) si[i] = i;\n\n let nct = Math.min(m - 1, n);\n let nrt = Math.max(0, Math.min(n - 2, m));\n let mrc = Math.max(nct, nrt);\n\n for (let k = 0; k < mrc; k++) {\n if (k < nct) {\n s[k] = 0;\n for (let i = k; i < m; i++) {\n s[k] = hypotenuse(s[k], a.get(i, k));\n }\n if (s[k] !== 0) {\n if (a.get(k, k) < 0) {\n s[k] = -s[k];\n }\n for (let i = k; i < m; i++) {\n a.set(i, k, a.get(i, k) / s[k]);\n }\n a.set(k, k, a.get(k, k) + 1);\n }\n s[k] = -s[k];\n }\n\n for (let j = k + 1; j < n; j++) {\n if (k < nct && s[k] !== 0) {\n let t = 0;\n for (let i = k; i < m; i++) {\n t += a.get(i, k) * a.get(i, j);\n }\n t = -t / a.get(k, k);\n for (let i = k; i < m; i++) {\n a.set(i, j, a.get(i, j) + t * a.get(i, k));\n }\n }\n e[j] = a.get(k, j);\n }\n\n if (wantu && k < nct) {\n for (let i = k; i < m; i++) {\n U.set(i, k, a.get(i, k));\n }\n }\n\n if (k < nrt) {\n e[k] = 0;\n for (let i = k + 1; i < n; i++) {\n e[k] = hypotenuse(e[k], e[i]);\n }\n if (e[k] !== 0) {\n if (e[k + 1] < 0) {\n e[k] = 0 - e[k];\n }\n for (let i = k + 1; i < n; i++) {\n e[i] /= e[k];\n }\n e[k + 1] += 1;\n }\n e[k] = -e[k];\n if (k + 1 < m && e[k] !== 0) {\n for (let i = k + 1; i < m; i++) {\n work[i] = 0;\n }\n for (let i = k + 1; i < m; i++) {\n for (let j = k + 1; j < n; j++) {\n work[i] += e[j] * a.get(i, j);\n }\n }\n for (let j = k + 1; j < n; j++) {\n let t = -e[j] / e[k + 1];\n for (let i = k + 1; i < m; i++) {\n a.set(i, j, a.get(i, j) + t * work[i]);\n }\n }\n }\n if (wantv) {\n for (let i = k + 1; i < n; i++) {\n V.set(i, k, e[i]);\n }\n }\n }\n }\n\n let p = Math.min(n, m + 1);\n if (nct < n) {\n s[nct] = a.get(nct, nct);\n }\n if (m < p) {\n s[p - 1] = 0;\n }\n if (nrt + 1 < p) {\n e[nrt] = a.get(nrt, p - 1);\n }\n e[p - 1] = 0;\n\n if (wantu) {\n for (let j = nct; j < nu; j++) {\n for (let i = 0; i < m; i++) {\n U.set(i, j, 0);\n }\n U.set(j, j, 1);\n }\n for (let k = nct - 1; k >= 0; k--) {\n if (s[k] !== 0) {\n for (let j = k + 1; j < nu; j++) {\n let t = 0;\n for (let i = k; i < m; i++) {\n t += U.get(i, k) * U.get(i, j);\n }\n t = -t / U.get(k, k);\n for (let i = k; i < m; i++) {\n U.set(i, j, U.get(i, j) + t * U.get(i, k));\n }\n }\n for (let i = k; i < m; i++) {\n U.set(i, k, -U.get(i, k));\n }\n U.set(k, k, 1 + U.get(k, k));\n for (let i = 0; i < k - 1; i++) {\n U.set(i, k, 0);\n }\n } else {\n for (let i = 0; i < m; i++) {\n U.set(i, k, 0);\n }\n U.set(k, k, 1);\n }\n }\n }\n\n if (wantv) {\n for (let k = n - 1; k >= 0; k--) {\n if (k < nrt && e[k] !== 0) {\n for (let j = k + 1; j < n; j++) {\n let t = 0;\n for (let i = k + 1; i < n; i++) {\n t += V.get(i, k) * V.get(i, j);\n }\n t = -t / V.get(k + 1, k);\n for (let i = k + 1; i < n; i++) {\n V.set(i, j, V.get(i, j) + t * V.get(i, k));\n }\n }\n }\n for (let i = 0; i < n; i++) {\n V.set(i, k, 0);\n }\n V.set(k, k, 1);\n }\n }\n\n let pp = p - 1;\n let iter = 0;\n let eps = Number.EPSILON;\n while (p > 0) {\n let k, kase;\n for (k = p - 2; k >= -1; k--) {\n if (k === -1) {\n break;\n }\n const alpha =\n Number.MIN_VALUE + eps * Math.abs(s[k] + Math.abs(s[k + 1]));\n if (Math.abs(e[k]) <= alpha || Number.isNaN(e[k])) {\n e[k] = 0;\n break;\n }\n }\n if (k === p - 2) {\n kase = 4;\n } else {\n let ks;\n for (ks = p - 1; ks >= k; ks--) {\n if (ks === k) {\n break;\n }\n let t =\n (ks !== p ? Math.abs(e[ks]) : 0) +\n (ks !== k + 1 ? Math.abs(e[ks - 1]) : 0);\n if (Math.abs(s[ks]) <= eps * t) {\n s[ks] = 0;\n break;\n }\n }\n if (ks === k) {\n kase = 3;\n } else if (ks === p - 1) {\n kase = 1;\n } else {\n kase = 2;\n k = ks;\n }\n }\n\n k++;\n\n switch (kase) {\n case 1: {\n let f = e[p - 2];\n e[p - 2] = 0;\n for (let j = p - 2; j >= k; j--) {\n let t = hypotenuse(s[j], f);\n let cs = s[j] / t;\n let sn = f / t;\n s[j] = t;\n if (j !== k) {\n f = -sn * e[j - 1];\n e[j - 1] = cs * e[j - 1];\n }\n if (wantv) {\n for (let i = 0; i < n; i++) {\n t = cs * V.get(i, j) + sn * V.get(i, p - 1);\n V.set(i, p - 1, -sn * V.get(i, j) + cs * V.get(i, p - 1));\n V.set(i, j, t);\n }\n }\n }\n break;\n }\n case 2: {\n let f = e[k - 1];\n e[k - 1] = 0;\n for (let j = k; j < p; j++) {\n let t = hypotenuse(s[j], f);\n let cs = s[j] / t;\n let sn = f / t;\n s[j] = t;\n f = -sn * e[j];\n e[j] = cs * e[j];\n if (wantu) {\n for (let i = 0; i < m; i++) {\n t = cs * U.get(i, j) + sn * U.get(i, k - 1);\n U.set(i, k - 1, -sn * U.get(i, j) + cs * U.get(i, k - 1));\n U.set(i, j, t);\n }\n }\n }\n break;\n }\n case 3: {\n const scale = Math.max(\n Math.abs(s[p - 1]),\n Math.abs(s[p - 2]),\n Math.abs(e[p - 2]),\n Math.abs(s[k]),\n Math.abs(e[k]),\n );\n const sp = s[p - 1] / scale;\n const spm1 = s[p - 2] / scale;\n const epm1 = e[p - 2] / scale;\n const sk = s[k] / scale;\n const ek = e[k] / scale;\n const b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2;\n const c = sp * epm1 * (sp * epm1);\n let shift = 0;\n if (b !== 0 || c !== 0) {\n if (b < 0) {\n shift = 0 - Math.sqrt(b * b + c);\n } else {\n shift = Math.sqrt(b * b + c);\n }\n shift = c / (b + shift);\n }\n let f = (sk + sp) * (sk - sp) + shift;\n let g = sk * ek;\n for (let j = k; j < p - 1; j++) {\n let t = hypotenuse(f, g);\n if (t === 0) t = Number.MIN_VALUE;\n let cs = f / t;\n let sn = g / t;\n if (j !== k) {\n e[j - 1] = t;\n }\n f = cs * s[j] + sn * e[j];\n e[j] = cs * e[j] - sn * s[j];\n g = sn * s[j + 1];\n s[j + 1] = cs * s[j + 1];\n if (wantv) {\n for (let i = 0; i < n; i++) {\n t = cs * V.get(i, j) + sn * V.get(i, j + 1);\n V.set(i, j + 1, -sn * V.get(i, j) + cs * V.get(i, j + 1));\n V.set(i, j, t);\n }\n }\n t = hypotenuse(f, g);\n if (t === 0) t = Number.MIN_VALUE;\n cs = f / t;\n sn = g / t;\n s[j] = t;\n f = cs * e[j] + sn * s[j + 1];\n s[j + 1] = -sn * e[j] + cs * s[j + 1];\n g = sn * e[j + 1];\n e[j + 1] = cs * e[j + 1];\n if (wantu && j < m - 1) {\n for (let i = 0; i < m; i++) {\n t = cs * U.get(i, j) + sn * U.get(i, j + 1);\n U.set(i, j + 1, -sn * U.get(i, j) + cs * U.get(i, j + 1));\n U.set(i, j, t);\n }\n }\n }\n e[p - 2] = f;\n iter = iter + 1;\n break;\n }\n case 4: {\n if (s[k] <= 0) {\n s[k] = s[k] < 0 ? -s[k] : 0;\n if (wantv) {\n for (let i = 0; i <= pp; i++) {\n V.set(i, k, -V.get(i, k));\n }\n }\n }\n while (k < pp) {\n if (s[k] >= s[k + 1]) {\n break;\n }\n let t = s[k];\n s[k] = s[k + 1];\n s[k + 1] = t;\n if (wantv && k < n - 1) {\n for (let i = 0; i < n; i++) {\n t = V.get(i, k + 1);\n V.set(i, k + 1, V.get(i, k));\n V.set(i, k, t);\n }\n }\n if (wantu && k < m - 1) {\n for (let i = 0; i < m; i++) {\n t = U.get(i, k + 1);\n U.set(i, k + 1, U.get(i, k));\n U.set(i, k, t);\n }\n }\n k++;\n }\n iter = 0;\n p--;\n break;\n }\n // no default\n }\n }\n\n if (swapped) {\n let tmp = V;\n V = U;\n U = tmp;\n }\n\n this.m = m;\n this.n = n;\n this.s = s;\n this.U = U;\n this.V = V;\n }\n\n solve(value) {\n let Y = value;\n let e = this.threshold;\n let scols = this.s.length;\n let Ls = Matrix.zeros(scols, scols);\n\n for (let i = 0; i < scols; i++) {\n if (Math.abs(this.s[i]) <= e) {\n Ls.set(i, i, 0);\n } else {\n Ls.set(i, i, 1 / this.s[i]);\n }\n }\n\n let U = this.U;\n let V = this.rightSingularVectors;\n\n let VL = V.mmul(Ls);\n let vrows = V.rows;\n let urows = U.rows;\n let VLU = Matrix.zeros(vrows, urows);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < urows; j++) {\n let sum = 0;\n for (let k = 0; k < scols; k++) {\n sum += VL.get(i, k) * U.get(j, k);\n }\n VLU.set(i, j, sum);\n }\n }\n\n return VLU.mmul(Y);\n }\n\n solveForDiagonal(value) {\n return this.solve(Matrix.diag(value));\n }\n\n inverse() {\n let V = this.V;\n let e = this.threshold;\n let vrows = V.rows;\n let vcols = V.columns;\n let X = new Matrix(vrows, this.s.length);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < vcols; j++) {\n if (Math.abs(this.s[j]) > e) {\n X.set(i, j, V.get(i, j) / this.s[j]);\n }\n }\n }\n\n let U = this.U;\n\n let urows = U.rows;\n let ucols = U.columns;\n let Y = new Matrix(vrows, urows);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < urows; j++) {\n let sum = 0;\n for (let k = 0; k < ucols; k++) {\n sum += X.get(i, k) * U.get(j, k);\n }\n Y.set(i, j, sum);\n }\n }\n\n return Y;\n }\n\n get condition() {\n return this.s[0] / this.s[Math.min(this.m, this.n) - 1];\n }\n\n get norm2() {\n return this.s[0];\n }\n\n get rank() {\n let tol = Math.max(this.m, this.n) * this.s[0] * Number.EPSILON;\n let r = 0;\n let s = this.s;\n for (let i = 0, ii = s.length; i < ii; i++) {\n if (s[i] > tol) {\n r++;\n }\n }\n return r;\n }\n\n get diagonal() {\n return Array.from(this.s);\n }\n\n get threshold() {\n return (Number.EPSILON / 2) * Math.max(this.m, this.n) * this.s[0];\n }\n\n get leftSingularVectors() {\n return this.U;\n }\n\n get rightSingularVectors() {\n return this.V;\n }\n\n get diagonalMatrix() {\n return Matrix.diag(this.s);\n }\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","import LuDecomposition from './dc/lu';\nimport QrDecomposition from './dc/qr';\nimport SingularValueDecomposition from './dc/svd';\nimport Matrix from './matrix';\nimport WrapperMatrix2D from './wrap/WrapperMatrix2D';\n\nexport function inverse(matrix, useSVD = false) {\n matrix = WrapperMatrix2D.checkMatrix(matrix);\n if (useSVD) {\n return new SingularValueDecomposition(matrix).inverse();\n } else {\n return solve(matrix, Matrix.eye(matrix.rows));\n }\n}\n\nexport function solve(leftHandSide, rightHandSide, useSVD = false) {\n leftHandSide = WrapperMatrix2D.checkMatrix(leftHandSide);\n rightHandSide = WrapperMatrix2D.checkMatrix(rightHandSide);\n if (useSVD) {\n return new SingularValueDecomposition(leftHandSide).solve(rightHandSide);\n } else {\n return leftHandSide.isSquare()\n ? new LuDecomposition(leftHandSide).solve(rightHandSide)\n : new QrDecomposition(leftHandSide).solve(rightHandSide);\n }\n}\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 = this.nNeighbors;\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 }\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 }\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 }\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 }\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 }\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 }\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 }\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 let index = Math.floor(localConnectivity);\n let 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 }\n else {\n psum += 1.0;\n }\n }\n if (Math.abs(psum - target) < SMOOTH_K_TOLERANCE) {\n break;\n }\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 }\n else {\n mid = (lo + hi) / 2.0;\n }\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 }\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 }\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 }\n if (knnIndices[i][j] === i) {\n val = 0.0;\n }\n else if (knnDistances[i][j] - rhos[i] <= 0.0) {\n val = 1.0;\n }\n else {\n val = Math.exp(-((knnDistances[i][j] - rhos[i]) / sigmas[i]));\n }\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 }\n const graph = this.graph.map(value => {\n if (value < graphMax / nEpochs) {\n return 0;\n }\n else {\n return value;\n }\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 }\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 }\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 }\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 }\n else {\n return resolve(isFinished);\n }\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 }\n if (!graph) {\n return 200;\n }\n const length = graph.nRows;\n if (length <= 2500) {\n return 500;\n }\n else if (length <= 5000) {\n return 400;\n }\n else if (length <= 7500) {\n return 300;\n }\n else {\n return 200;\n }\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 }\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 }\n else if (normX === 0 || normY === 0) {\n return 1.0;\n }\n else {\n return 1.0 - result / Math.sqrt(normX * normY);\n }\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 }\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 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 }\n else if (target[row] !== target[col]) {\n return value * Math.exp(-farDist);\n }\n else {\n return value;\n }\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW1hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInVtYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxTQUFTLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBYXhDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0FBbUg5Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sT0FBTyxJQUFJO0lBMkNmLElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBQ0QsWUFBWSxTQUF5QixFQUFFO1FBN0MvQixpQkFBWSxHQUFHLEdBQUcsQ0FBQztRQUNuQixzQkFBaUIsR0FBRyxHQUFHLENBQUM7UUFDeEIsWUFBTyxHQUFHLEdBQUcsQ0FBQztRQUNkLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWixlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLHVCQUFrQixHQUFHLENBQUMsQ0FBQztRQUN2QixXQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNyQixzQkFBaUIsR0FBRyxHQUFHLENBQUM7UUFDeEIsa0JBQWEsR0FBRyxHQUFHLENBQUM7UUFDcEIsV0FBTSxHQUFHLEdBQUcsQ0FBQztRQUNiLHVCQUFrQixHQUFH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QUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDNUMsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4QixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNqRDtTQUNGO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgSmF2YVNjcmlwdCByZWltcGxlbWVudGF0aW9uIG9mIFVNQVAgKG9yaWdpbmFsIGxpY2Vuc2UgYmVsb3cpLCBmcm9tXG4gKiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9sbWNpbm5lcy91bWFwLlxuICpcbiAqIEBhdXRob3IgYW5keWNvZW5lbkBnb29nbGUuY29tIChBbmR5IENvZW5lbilcbiAqL1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBCU0QgMy1DbGF1c2UgTGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNywgTGVsYW5kIE1jSW5uZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4gKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcbiAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXG4gKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcbiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuaW1wb3J0ICogYXMgaGVhcCBmcm9tICcuL2hlYXAnO1xuaW1wb3J0ICogYXMgbWF0cml4IGZyb20gJy4vbWF0cml4JztcbmltcG9ydCAqIGFzIG5uRGVzY2VudCBmcm9tICcuL25uX2Rlc2NlbnQnO1xuaW1wb3J0ICogYXMgdHJlZSBmcm9tICcuL3RyZWUnO1xuaW1wb3J0ICogYXMgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgTE0gZnJvbSAnbWwtbGV2ZW5iZXJnLW1hcnF1YXJkdCc7XG5cbmV4cG9ydCB0eXBlIERpc3RhbmNlRm4gPSAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IG51bWJlcjtcbmV4cG9ydCB0eXBlIFJhbmRvbUZuID0gKCkgPT4gbnVtYmVyO1xuZXhwb3J0IHR5cGUgRXBvY2hDYWxsYmFjayA9IChlcG9jaDogbnVtYmVyKSA9PiBib29sZWFuIHwgdm9pZDtcbmV4cG9ydCB0eXBlIFZlY3RvciA9IG51bWJlcltdO1xuZXhwb3J0IHR5cGUgVmVjdG9ycyA9IFZlY3RvcltdO1xuZXhwb3J0IGNvbnN0IGVudW0gVGFyZ2V0TWV0cmljIHtcbiAgY2F0ZWdvcmljYWwgPSAnY2F0ZWdvcmljYWwnLFxuICBsMSA9ICdsMScsXG4gIGwyID0gJ2wyJyxcbn1cblxuY29uc3QgU01PT1RIX0tfVE9MRVJBTkNFID0gMWUtNTtcbmNvbnN0IE1JTl9LX0RJU1RfU0NBTEUgPSAxZS0zO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVNQVBQYXJhbWV0ZXJzIHtcbiAgLyoqXG4gICAqIFRoZSBkaXN0YW5jZSBmdW5jdGlvbiB3aXRoIHdoaWNoIHRvIGFzc2VzcyBuZWFyZXN0IG5laWdoYm9ycywgZGVmYXVsdHNcbiAgICogdG8gZXVjbGlkZWFuIGRpc3RhbmNlLlxuICAgKi9cbiAgZGlzdGFuY2VGbj86IERpc3RhbmNlRm47XG4gIC8qKlxuICAgKiBUaGUgaW5pdGlhbCBsZWFybmluZyByYXRlIGZvciB0aGUgZW1iZWRkaW5nIG9wdGltaXphdGlvbi5cbiAgICovXG4gIGxlYXJuaW5nUmF0ZT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBsb2NhbCBjb25uZWN0aXZpdHkgcmVxdWlyZWQgLS0gaS5lLiB0aGUgbnVtYmVyIG9mIG5lYXJlc3RcbiAgICogbmVpZ2hib3JzIHRoYXQgc2hvdWxkIGJlIGFzc3VtZWQgdG8gYmUgY29ubmVjdGVkIGF0IGEgbG9jYWwgbGV2ZWwuXG4gICAqIFRoZSBoaWdoZXIgdGhpcyB2YWx1ZSB0aGUgbW9yZSBjb25uZWN0ZWQgdGhlIG1hbmlmb2xkIGJlY29tZXNcbiAgICogbG9jYWxseS4gSW4gcHJhY3RpY2UgdGhpcyBzaG91bGQgYmUgbm90IG1vcmUgdGhhbiB0aGUgbG9jYWwgaW50cmluc2ljXG4gICAqIGRpbWVuc2lvbiBvZiB0aGUgbWFuaWZvbGQuXG4gICAqL1xuICBsb2NhbENvbm5lY3Rpdml0eT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBlZmZlY3RpdmUgbWluaW11bSBkaXN0YW5jZSBiZXR3ZWVuIGVtYmVkZGVkIHBvaW50cy4gU21hbGxlciB2YWx1ZXNcbiAgICogd2lsbCByZXN1bHQgaW4gYSBtb3JlIGNsdXN0ZXJlZC9jbHVtcGVkIGVtYmVkZGluZyB3aGVyZSBuZWFyYnkgcG9pbnRzXG4gICAqIG9uIHRoZSBtYW5pZm9sZCBhcmUgZHJhd24gY2xvc2VyIHRvZ2V0aGVyLCB3aGlsZSBsYXJnZXIgdmFsdWVzIHdpbGxcbiAgICogcmVzdWx0IG9uIGEgbW9yZSBldmVuIGRpc3BlcnNhbCBvZiBwb2ludHMuIFRoZSB2YWx1ZSBzaG91bGQgYmUgc2V0XG4gICAqIHJlbGF0aXZlIHRvIHRoZSBgYHNwcmVhZGBgIHZhbHVlLCB3aGljaCBkZXRlcm1pbmVzIHRoZSBzY2FsZSBhdCB3aGljaFxuICAgKiBlbWJlZGRlZCBwb2ludHMgd2lsbCBiZSBzcHJlYWQgb3V0LlxuICAgKi9cbiAgbWluRGlzdD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBkaW1lbnNpb24gb2YgdGhlIHNwYWNlIHRvIGVtYmVkIGludG8uIFRoaXMgZGVmYXVsdHMgdG8gMiB0b1xuICAgKiBwcm92aWRlIGVhc3kgdmlzdWFsaXphdGlvbiwgYnV0IGNhbiByZWFzb25hYmx5IGJlIHNldCB0byBhbnlcbiAgICogaW50ZWdlciB2YWx1ZSBpbiB0aGUgcmFuZ2UgMiB0byAxMDAuXG4gICAqL1xuICBuQ29tcG9uZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgdHJhaW5pbmcgZXBvY2hzIHRvIGJlIHVzZWQgaW4gb3B0aW1pemluZyB0aGVcbiAgICogbG93IGRpbWVuc2lvbmFsIGVtYmVkZGluZy4gTGFyZ2VyIHZhbHVlcyByZXN1bHQgaW4gbW9yZSBhY2N1cmF0ZVxuICAgKiBlbWJlZGRpbmdzLiBJZiBOb25lIGlzIHNwZWNpZmllZCBhIHZhbHVlIHdpbGwgYmUgc2VsZWN0ZWQgYmFzZWQgb25cbiAgICogdGhlIHNpemUgb2YgdGhlIGlucHV0IGRhdGFzZXQgKDIwMCBmb3IgbGFyZ2UgZGF0YXNldHMsIDUwMCBmb3Igc21hbGwpLlxuICAgKi9cbiAgbkVwb2Nocz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBzaXplIG9mIGxvY2FsIG5laWdoYm9yaG9vZCAoaW4gdGVybXMgb2YgbnVtYmVyIG9mIG5laWdoYm9yaW5nXG4gICAqIHNhbXBsZSBwb2ludHMpIHVzZWQgZm9yIG1hbmlmb2xkIGFwcHJveGltYXRpb24uIExhcmdlciB2YWx1ZXNcbiAgICogcmVzdWx0IGluIG1vcmUgZ2xvYmFsIHZpZXdzIG9mIHRoZSBtYW5pZm9sZCwgd2hpbGUgc21hbGxlclxuICAgKiB2YWx1ZXMgcmVzdWx0IGluIG1vcmUgbG9jYWwgZGF0YSBiZWluZyBwcmVzZXJ2ZWQuIEluIGdlbmVyYWxcbiAgICogdmFsdWVzIHNob3VsZCBiZSBpbiB0aGUgcmFuZ2UgMiB0byAxMDAuXG4gICAqL1xuICBuTmVpZ2hib3JzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBuZWdhdGl2ZSBzYW1wbGVzIHRvIHNlbGVjdCBwZXIgcG9zaXRpdmUgc2FtcGxlXG4gICAqIGluIHRoZSBvcHRpbWl6YXRpb24gcHJvY2Vzcy4gSW5jcmVhc2luZyB0aGlzIHZhbHVlIHdpbGwgcmVzdWx0XG4gICAqIGluIGdyZWF0ZXIgcmVwdWxzaXZlIGZvcmNlIGJlaW5nIGFwcGxpZWQsIGdyZWF0ZXIgb3B0aW1pemF0aW9uXG4gICAqIGNvc3QsIGJ1dCBzbGlnaHRseSBtb3JlIGFjY3VyYWN5LlxuICAgKi9cbiAgbmVnYXRpdmVTYW1wbGVSYXRlPzogbnVtYmVyO1xuICAvKipcbiAgICogV2VpZ2h0aW5nIGFwcGxpZWQgdG8gbmVnYXRpdmUgc2FtcGxlcyBpbiBsb3cgZGltZW5zaW9uYWwgZW1iZWRkaW5nXG4gICAqIG9wdGltaXphdGlvbi4gVmFsdWVzIGhpZ2hlciB0aGFuIG9uZSB3aWxsIHJlc3VsdCBpbiBncmVhdGVyIHdlaWdodFxuICAgKiBiZWluZyBnaXZlbiB0byBuZWdhdGl2ZSBzYW1wbGVzLlxuICAgKi9cbiAgcmVwdWxzaW9uU3RyZW5ndGg/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgcHNldWRvLXJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yIHVzZWQgYnkgdGhlIHN0b2NoYXN0aWMgcGFydHMgb2YgdGhlXG4gICAqIGFsZ29yaXRobS5cbiAgICovXG4gIHJhbmRvbT86IFJhbmRvbUZuO1xuICAvKipcbiAgICogSW50ZXJwb2xhdGUgYmV0d2VlbiAoZnV6enkpIHVuaW9uIGFuZCBpbnRlcnNlY3Rpb24gYXMgdGhlIHNldCBvcGVyYXRpb25cbiAgICogdXNlZCB0byBjb21iaW5lIGxvY2FsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cyB0byBvYnRhaW4gYSBnbG9iYWwgZnV6enlcbiAgICogc2ltcGxpY2lhbCBzZXRzLiBCb3RoIGZ1enp5IHNldCBvcGVyYXRpb25zIHVzZSB0aGUgcHJvZHVjdCB0LW5vcm0uXG4gICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHBhcmFtZXRlciBzaG91bGQgYmUgYmV0d2VlbiAwLjAgYW5kIDEuMDsgYSB2YWx1ZSBvZlxuICAgKiAxLjAgd2lsbCB1c2UgYSBwdXJlIGZ1enp5IHVuaW9uLCB3aGlsZSAwLjAgd2lsbCB1c2UgYSBwdXJlIGZ1enp5XG4gICAqIGludGVyc2VjdGlvbi5cbiAgICovXG4gIHNldE9wTWl4UmF0aW8/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZWZmZWN0aXZlIHNjYWxlIG9mIGVtYmVkZGVkIHBvaW50cy4gSW4gY29tYmluYXRpb24gd2l0aCBgYG1pbl9kaXN0YGBcbiAgICogdGhpcyBkZXRlcm1pbmVzIGhvdyBjbHVzdGVyZWQvY2x1bXBlZCB0aGUgZW1iZWRkZWQgcG9pbnRzIGFyZS5cbiAgICovXG4gIHNwcmVhZD86IG51bWJlcjtcbiAgLyoqXG4gICAqIEZvciB0cmFuc2Zvcm0gb3BlcmF0aW9ucyAoZW1iZWRkaW5nIG5ldyBwb2ludHMgdXNpbmcgYSB0cmFpbmVkIG1vZGVsKVxuICAgKiB0aGlzIHdpbGwgY29udHJvbCBob3cgYWdncmVzc2l2ZWx5IHRvIHNlYXJjaCBmb3IgbmVhcmVzdCBuZWlnaGJvcnMuXG4gICAqIExhcmdlciB2YWx1ZXMgd2lsbCByZXN1bHQgaW4gc2xvd2VyIHBlcmZvcm1hbmNlIGJ1dCBtb3JlIGFjY3VyYXRlXG4gICAqIG5lYXJlc3QgbmVpZ2hib3IgZXZhbHVhdGlvbi5cbiAgICovXG4gIHRyYW5zZm9ybVF1ZXVlU2l6ZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVTUFQU3VwZXJ2aXNlZFBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgbWV0cmljIHVzZWQgdG8gbWVhc3VyZSBkaXN0YW5jZSBmb3IgYSB0YXJnZXQgYXJyYXkgaXMgdXNpbmcgc3VwZXJ2aXNlZFxuICAgKiBkaW1lbnNpb24gcmVkdWN0aW9uLiBCeSBkZWZhdWx0IHRoaXMgaXMgJ2NhdGVnb3JpY2FsJyB3aGljaCB3aWxsIG1lYXN1cmVcbiAgICogZGlzdGFuY2UgaW4gdGVybXMgb2Ygd2hldGhlciBjYXRlZ29yaWVzIG1hdGNoIG9yIGFyZSBkaWZmZXJlbnQuIEZ1cnRoZXJtb3JlLFxuICAgKiBpZiBzZW1pLXN1cGVydmlzZWQgaXMgcmVxdWlyZWQgdGFyZ2V0IHZhbHVlcyBvZiAtMSB3aWxsIGJlIHRyZWF0ZWQgYXNcbiAgICogdW5sYWJlbGxlZCB1bmRlciB0aGUgJ2NhdGVnb3JpY2FsJyBtZXRyaWMuIElmIHRoZSB0YXJnZXQgYXJyYXkgdGFrZXNcbiAgICogY29udGludW91cyB2YWx1ZXMgKGUuZy4gZm9yIGEgcmVncmVzc2lvbiBwcm9ibGVtKSB0aGVuIG1ldHJpYyBvZiAnbDEnXG4gICAqIG9yICdsMicgaXMgcHJvYmFibHkgbW9yZSBhcHByb3ByaWF0ZS5cbiAgICovXG4gIHRhcmdldE1ldHJpYz86IFRhcmdldE1ldHJpYztcbiAgLyoqXG4gICAqIFdlaWdodGluZyBmYWN0b3IgYmV0d2VlbiBkYXRhIHRvcG9sb2d5IGFuZCB0YXJnZXQgdG9wb2xvZ3kuIEEgdmFsdWUgb2ZcbiAgICogMC4wIHdlaWdodHMgZW50aXJlbHkgb24gZGF0YSwgYSB2YWx1ZSBvZiAxLjAgd2VpZ2h0cyBlbnRpcmVseSBvbiB0YXJnZXQuXG4gICAqIFRoZSBkZWZhdWx0IG9mIDAuNSBiYWxhbmNlcyB0aGUgd2VpZ2h0aW5nIGVxdWFsbHkgYmV0d2VlbiBkYXRhIGFuZCB0YXJnZXQuXG4gICAqL1xuICB0YXJnZXRXZWlnaHQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIG5lYXJlc3QgbmVpZ2hib3JzIHRvIHVzZSB0byBjb25zdHJ1Y3QgdGhlIHRhcmdldCBzaW1wbGNpYWxcbiAgICogc2V0LiBEZWZhdWx0cyB0byB0aGUgYG5lYXJlc3ROZWlnaGJvcnNgIHBhcmFtZXRlci5cbiAgICovXG4gIHRhcmdldE5OZWlnaGJvcnM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogVU1BUCBwcm9qZWN0aW9uIHN5c3RlbSwgYmFzZWQgb24gdGhlIHB5dGhvbiBpbXBsZW1lbnRhdGlvbiBmcm9tIE1jSW5uZXMsIEwsXG4gKiBIZWFseSwgSiwgVU1BUDogVW5pZm9ybSBNYW5pZm9sZCBBcHByb3hpbWF0aW9uIGFuZCBQcm9qZWN0aW9uIGZvciBEaW1lbnNpb25cbiAqIFJlZHVjdGlvbiAoaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXApLlxuICpcbiAqIFRoaXMgaW1wbGVtZW50YXRpb24gZGlmZmVycyBpbiBhIGZldyByZWdhcmRzOlxuICogYSkgVGhlIGluaXRpYWxpemF0aW9uIG9mIHRoZSBlbWJlZGRpbmcgZm9yIG9wdGltaXphdGlvbiBpcyBub3QgY29tcHV0ZWQgdXNpbmdcbiAqICAgIGEgc3BlY3RyYWwgbWV0aG9kLCByYXRoZXIgaXQgaXMgaW5pdGlhbGl6ZWQgcmFuZG9tbHkuIFRoaXMgYXZvaWRzIHNvbWVcbiAqICAgIGNvbXB1dGF0aW9uYWxseSBpbnRlbnNpdmUgbWF0cml4IGVpZ2VuIGNvbXB1dGF0aW9ucyB0aGF0IGFyZW4ndCBlYXNpbHlcbiAqICAgIHBvcnRlZCB0byBKYXZhU2NyaXB0LlxuICogYikgQSBsb3Qgb2YgXCJleHRyYVwiIGZ1bmN0aW9uYWxpdHkgaGFzIGJlZW4gb21pdHRlZCBmcm9tIHRoaXMgaW1wbGVtZW50YXRpb24sXG4gKiAgICBtb3N0IG5vdGFibHkgYSBncmVhdCBkZWFsIG9mIGFsdGVybmF0ZSBkaXN0YW5jZSBmdW5jdGlvbnMuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBwcm92aWRlcyB0aHJlZSBtZXRob2RzIG9mIHJlZHVjaW5nIGRpbWVuc2lvbmFsaXR5OlxuICogMSkgZml0OiBmaXQgdGhlIGRhdGEgc3luY2hyb25vdXNseVxuICogMikgZml0QXN5bmM6IGZpdCB0aGUgZGF0YSBhc3luY2hyb25vdXNseSwgd2l0aCBhIGNhbGxiYWNrIGZ1bmN0aW9uIHByb3ZpZGVkXG4gKiAgICAgIHRoYXQgaXMgaW52b2tlZCBvbiBlYWNoIG9wdGltaXphdGlvbiBzdGVwLlxuICogMykgaW5pdGlhbGl6ZUZpdCAvIHN0ZXA6IG1hbnVhbGx5IGluaXRpYWxpemUgdGhlIGFsZ29yaXRobSB0aGVuIGV4cGxpY3RseVxuICogICAgICBzdGVwIHRocm91Z2ggZWFjaCBlcG9jaCBvZiB0aGUgU0dEIG9wdGltaXphdGlvblxuICovXG5leHBvcnQgY2xhc3MgVU1BUCB7XG4gIHByaXZhdGUgbGVhcm5pbmdSYXRlID0gMS4wO1xuICBwcml2YXRlIGxvY2FsQ29ubmVjdGl2aXR5ID0gMS4wO1xuICBwcml2YXRlIG1pbkRpc3QgPSAwLjE7XG4gIHByaXZhdGUgbkNvbXBvbmVudHMgPSAyO1xuICBwcml2YXRlIG5FcG9jaHMgPSAwO1xuICBwcml2YXRlIG5OZWlnaGJvcnMgPSAxNTtcbiAgcHJpdmF0ZSBuZWdhdGl2ZVNhbXBsZVJhdGUgPSA1O1xuICBwcml2YXRlIHJhbmRvbSA9IE1hdGgucmFuZG9tO1xuICBwcml2YXRlIHJlcHVsc2lvblN0cmVuZ3RoID0gMS4wO1xuICBwcml2YXRlIHNldE9wTWl4UmF0aW8gPSAxLjA7XG4gIHByaXZhdGUgc3ByZWFkID0gMS4wO1xuICBwcml2YXRlIHRyYW5zZm9ybVF1ZXVlU2l6ZSA9IDQuMDtcblxuICAvLyBTdXBlcnZpc2VkIHByb2plY3Rpb24gcGFyYW1zXG4gIHByaXZhdGUgdGFyZ2V0TWV0cmljID0gVGFyZ2V0TWV0cmljLmNhdGVnb3JpY2FsO1xuICBwcml2YXRlIHRhcmdldFdlaWdodCA9IDAuNTtcbiAgcHJpdmF0ZSB0YXJnZXROTmVpZ2hib3JzID0gdGhpcy5uTmVpZ2hib3JzO1xuXG4gIHByaXZhdGUgZGlzdGFuY2VGbjogRGlzdGFuY2VGbiA9IG51bWVyaWM7XG5cbiAgLy8gS05OIHN0YXRlIChjYW4gYmUgcHJlY29tcHV0ZWQgYW5kIHN1cHBsaWVkIHZpYSBpbml0aWFsaXplRml0KVxuICBwcml2YXRlIGtubkluZGljZXM/OiBudW1iZXJbXVtdO1xuICBwcml2YXRlIGtubkRpc3RhbmNlcz86IG51bWJlcltdW107XG5cbiAgLy8gSW50ZXJuYWwgZ3JhcGggY29ubmVjdGl2aXR5IHJlcHJlc2VudGF0aW9uXG4gIHByaXZhdGUgZ3JhcGghOiBtYXRyaXguU3BhcnNlTWF0cml4O1xuICBwcml2YXRlIFghOiBWZWN0b3I7XG4gIHByaXZhdGUgaXNJbml0aWFsaXplZCA9IGZhbHNlO1xuICBwcml2YXRlIHJwRm9yZXN0OiB0cmVlLkZsYXRUcmVlW10gPSBbXTtcbiAgcHJpdmF0ZSBpbml0RnJvbVJhbmRvbSE6IG5uRGVzY2VudC5Jbml0RnJvbVJhbmRvbUZuO1xuICBwcml2YXRlIGluaXRGcm9tVHJlZSE6IG5uRGVzY2VudC5Jbml0RnJvbVRyZWVGbjtcbiAgcHJpdmF0ZSBzZWFyY2ghOiBubkRlc2NlbnQuU2VhcmNoRm47XG4gIHByaXZhdGUgc2VhcmNoR3JhcGghOiBtYXRyaXguU3BhcnNlTWF0cml4O1xuXG4gIC8vIFN1cGVydmlzZWQgcHJvamVjdGlvbiBsYWJlbHMgLyB0YXJnZXRzXG4gIHByaXZhdGUgWT86IG51bWJlcltdO1xuXG4gIC8vIFByb2plY3RlZCBlbWJlZGRpbmdcbiAgcHJpdmF0ZSBlbWJlZGRpbmc6IG51bWJlcltdW10gPSBbXTtcbiAgcHJpdmF0ZSBvcHRpbWl6YXRpb25TdGF0ZSA9IG5ldyBPcHRpbWl6YXRpb25TdGF0ZSgpO1xuXG5cbiAgZ2V0IG5laWdoYm9ycygpIHtcbiAgICByZXR1cm4gdGhpcy5uTmVpZ2hib3JzO1xuICB9XG4gIGNvbnN0cnVjdG9yKHBhcmFtczogVU1BUFBhcmFtZXRlcnMgPSB7fSkge1xuICAgIGNvbnN0IHNldFBhcmFtID0gKGtleToga2V5b2YgVU1BUFBhcmFtZXRlcnMpID0+IHtcbiAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgaWYgKHBhcmFtc1trZXldICE9PSB1bmRlZmluZWQpIHRoaXNba2V5XSA9IHBhcmFtc1trZXldO1xuICAgIH07XG5cbiAgICBzZXRQYXJhbSgnZGlzdGFuY2VGbicpO1xuICAgIHNldFBhcmFtKCdsZWFybmluZ1JhdGUnKTtcbiAgICBzZXRQYXJhbSgnbG9jYWxDb25uZWN0aXZpdHknKTtcbiAgICBzZXRQYXJhbSgnbWluRGlzdCcpO1xuICAgIHNldFBhcmFtKCduQ29tcG9uZW50cycpO1xuICAgIHNldFBhcmFtKCduRXBvY2hzJyk7XG4gICAgc2V0UGFyYW0oJ25OZWlnaGJvcnMnKTtcbiAgICBzZXRQYXJhbSgnbmVnYXRpdmVTYW1wbGVSYXRlJyk7XG4gICAgc2V0UGFyYW0oJ3JhbmRvbScpO1xuICAgIHNldFBhcmFtKCdyZXB1bHNpb25TdHJlbmd0aCcpO1xuICAgIHNldFBhcmFtKCdzZXRPcE1peFJhdGlvJyk7XG4gICAgc2V0UGFyYW0oJ3NwcmVhZCcpO1xuICAgIHNldFBhcmFtKCd0cmFuc2Zvcm1RdWV1ZVNpemUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIHN5bmNocm9ub3VzbHkuXG4gICAqL1xuICBmaXQoWDogVmVjdG9yKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuICAgIHRoaXMub3B0aW1pemVMYXlvdXQoKTtcblxuICAgIHJldHVybiB0aGlzLmVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIGFzeW5jaHJvbm91c2x5LCB3aXRoIGEgY2FsbGJhY2tcbiAgICogZnVuY3Rpb24gaW52b2tlZCBvbiBldmVyeSBlcG9jaCBvZiBvcHRpbWl6YXRpb24uXG4gICAqL1xuICBhc3luYyBmaXRBc3luYyhcbiAgICBYOiBWZWN0b3IsXG4gICAgY2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuXG4gICAgYXdhaXQgdGhpcy5vcHRpbWl6ZUxheW91dEFzeW5jKGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy5lbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgcGFyYW1ldGVycyBuZWVkZWQgZm9yIHN1cGVydmlzZWQgcHJvamVjdGlvbi5cbiAgICovXG4gIHNldFN1cGVydmlzZWRQcm9qZWN0aW9uKFk6IG51bWJlcltdLCBwYXJhbXM6IFVNQVBTdXBlcnZpc2VkUGFyYW1zID0ge30pIHtcbiAgICB0aGlzLlkgPSBZO1xuICAgIHRoaXMudGFyZ2V0TWV0cmljID0gcGFyYW1zLnRhcmdldE1ldHJpYyB8fCB0aGlzLnRhcmdldE1ldHJpYztcbiAgICB0aGlzLnRhcmdldFdlaWdodCA9IHBhcmFtcy50YXJnZXRXZWlnaHQgfHwgdGhpcy50YXJnZXRXZWlnaHQ7XG4gICAgdGhpcy50YXJnZXROTmVpZ2hib3JzID0gcGFyYW1zLnRhcmdldE5OZWlnaGJvcnMgfHwgdGhpcy50YXJnZXROTmVpZ2hib3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHVtYXAgd2l0aCBwcmVjb21wdXRlZCBLTk4gaW5kaWNlcyBhbmQgZGlzdGFuY2VzLlxuICAgKi9cbiAgc2V0UHJlY29tcHV0ZWRLTk4oa25uSW5kaWNlczogbnVtYmVyW11bXSwga25uRGlzdGFuY2VzOiBudW1iZXJbXVtdKSB7XG4gICAgdGhpcy5rbm5JbmRpY2VzID0ga25uSW5kaWNlcztcbiAgICB0aGlzLmtubkRpc3RhbmNlcyA9IGtubkRpc3RhbmNlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBmaXQgYnkgY29tcHV0aW5nIEtOTiBhbmQgYSBmdXp6eSBzaW1wbGljaWFsIHNldCwgYXMgd2VsbCBhc1xuICAgKiBpbml0aWFsaXppbmcgdGhlIHByb2plY3RlZCBlbWJlZGRpbmdzLiBTZXRzIHRoZSBvcHRpbWl6YXRpb24gc3RhdGUgYWhlYWRcbiAgICogb2Ygb3B0aW1pemF0aW9uIHN0ZXBzLiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZXBvY2hzIHRvIGJlIHVzZWQgZm9yIHRoZVxuICAgKiBTR0Qgb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgaW5pdGlhbGl6ZUZpdChYOiBWZWN0b3IpOiBudW1iZXIge1xuICAgIGlmIChYLmxlbmd0aCA8PSB0aGlzLm5OZWlnaGJvcnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm90IGVub3VnaCBkYXRhIHBvaW50cyAoJHtYLmxlbmd0aH0pIHRvIGNyZWF0ZSBuTmVpZ2hib3JzOiAke3RoaXMubk5laWdoYm9yc30uICBBZGQgbW9yZSBkYXRhIHBvaW50cyBvciBhZGp1c3QgdGhlIGNvbmZpZ3VyYXRpb24uYCk7XG4gICAgfVxuXG4gICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZWluaXRpYWxpemUgaWYgd2UndmUgYWxyZWFkeSBpbml0aWFsaXplZCBmb3IgdGhpcyBkYXRhLlxuICAgIGlmICh0aGlzLlggPT09IFggJiYgdGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRORXBvY2hzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5YID0gWDtcblxuICAgIGlmICghdGhpcy5rbm5JbmRpY2VzICYmICF0aGlzLmtubkRpc3RhbmNlcykge1xuICAgICAgY29uc3Qga25uUmVzdWx0cyA9IHRoaXMubmVhcmVzdE5laWdoYm9ycyhYKTtcbiAgICAgIHRoaXMua25uSW5kaWNlcyA9IGtublJlc3VsdHMua25uSW5kaWNlcztcbiAgICAgIHRoaXMua25uRGlzdGFuY2VzID0ga25uUmVzdWx0cy5rbm5EaXN0YW5jZXM7XG4gICAgfVxuXG4gICAgdGhpcy5ncmFwaCA9IHRoaXMuZnV6enlTaW1wbGljaWFsU2V0KFxuICAgICAgWCxcbiAgICAgIHRoaXMubk5laWdoYm9ycyxcbiAgICAgIHRoaXMuc2V0T3BNaXhSYXRpb1xuICAgICk7XG5cbiAgICAvLyBTZXQgdXAgdGhlIHNlYXJjaCBncmFwaCBmb3Igc3Vic2VxdWVudCB0cmFuc2Zvcm1hdGlvbi5cbiAgICB0aGlzLm1ha2VTZWFyY2hGbnMoKTtcbiAgICB0aGlzLnNlYXJjaEdyYXBoID0gdGhpcy5tYWtlU2VhcmNoR3JhcGgoWCk7XG5cbiAgICAvLyBDaGVjayBpZiBzdXBlcnZpc2VkIHByb2plY3Rpb24sIHRoZW4gYWRqdXN0IHRoZSBncmFwaC5cbiAgICB0aGlzLnByb2Nlc3NHcmFwaEZvclN1cGVydmlzZWRQcm9qZWN0aW9uKCk7XG5cbiAgICBjb25zdCB7XG4gICAgICBoZWFkLFxuICAgICAgdGFpbCxcbiAgICAgIGVwb2Noc1BlclNhbXBsZSxcbiAgICB9ID0gdGhpcy5pbml0aWFsaXplU2ltcGxpY2lhbFNldEVtYmVkZGluZygpO1xuXG4gICAgLy8gU2V0IHRoZSBvcHRpbWl6YXRpb24gcm91dGluZSBzdGF0ZVxuICAgIHRoaXMub3B0aW1pemF0aW9uU3RhdGUuaGVhZCA9IGhlYWQ7XG4gICAgdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS50YWlsID0gdGFpbDtcbiAgICB0aGlzLm9wdGltaXphdGlvblN0YXRlLmVwb2Noc1BlclNhbXBsZSA9IGVwb2Noc1BlclNhbXBsZTtcblxuICAgIC8vIE5vdywgaW5pdGlhbGl6ZSB0aGUgb3B0aW1pemF0aW9uIHN0ZXBzXG4gICAgdGhpcy5pbml0aWFsaXplT3B0aW1pemF0aW9uKCk7XG4gICAgdGhpcy5wcmVwYXJlRm9yT3B0aW1pemF0aW9uTG9vcCgpO1xuICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICByZXR1cm4gdGhpcy5nZXRORXBvY2hzKCk7XG4gIH1cblxuICBwcml2YXRlIG1ha2VTZWFyY2hGbnMoKSB7XG4gICAgY29uc3QgeyBpbml0RnJvbVRyZWUsIGluaXRGcm9tUmFuZG9tIH0gPSBubkRlc2NlbnQubWFrZUluaXRpYWxpemF0aW9ucyhcbiAgICAgIHRoaXMuZGlzdGFuY2VGblxuICAgICk7XG4gICAgdGhpcy5pbml0RnJvbVRyZWUgPSBpbml0RnJvbVRyZWU7XG4gICAgdGhpcy5pbml0RnJvbVJhbmRvbSA9IGluaXRGcm9tUmFuZG9tO1xuICAgIHRoaXMuc2VhcmNoID0gbm5EZXNjZW50Lm1ha2VJbml0aWFsaXplZE5OU2VhcmNoKHRoaXMuZGlzdGFuY2VGbik7XG4gIH1cblxuICBwcml2YXRlIG1ha2VTZWFyY2hHcmFwaChYOiBWZWN0b3IpIHtcbiAgICBjb25zdCBrbm5JbmRpY2VzID0gdGhpcy5rbm5JbmRpY2VzITtcbiAgICBjb25zdCBrbm5EaXN0YW5jZXMgPSB0aGlzLmtubkRpc3RhbmNlcyE7XG4gICAgY29uc3QgZGltcyA9IFtYLmxlbmd0aCwgWC5sZW5ndGhdO1xuICAgIGNvbnN0IHNlYXJjaEdyYXBoID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgoW10sIFtdLCBbXSwgZGltcyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrbm5JbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBrbm4gPSBrbm5JbmRpY2VzW2ldO1xuICAgICAgY29uc3QgZGlzdGFuY2VzID0ga25uRGlzdGFuY2VzW2ldO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBrbm4ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgY29uc3QgbmVpZ2hib3IgPSBrbm5bal07XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gZGlzdGFuY2VzW2pdO1xuICAgICAgICBpZiAoZGlzdGFuY2UgPiAwKSB7XG4gICAgICAgICAgc2VhcmNoR3JhcGguc2V0KGksIG5laWdoYm9yLCBkaXN0YW5jZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc3Bvc2UgPSBtYXRyaXgudHJhbnNwb3NlKHNlYXJjaEdyYXBoKTtcbiAgICByZXR1cm4gbWF0cml4Lm1heGltdW0oc2VhcmNoR3JhcGgsIHRyYW5zcG9zZSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtcyBkYXRhIHRvIHRoZSBleGlzdGluZyBlbWJlZGRpbmcgc3BhY2UuXG4gICAqL1xuICB0cmFuc2Zvcm0odG9UcmFuc2Zvcm06IFZlY3Rvcikge1xuICAgIC8vIFVzZSB0aGUgcHJldmlvdXMgcmF3RGF0YVxuICAgIGNvbnN0IHJhd0RhdGEgPSB0aGlzLlg7XG4gICAgaWYgKHJhd0RhdGEgPT09IHVuZGVmaW5lZCB8fCByYXdEYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBkYXRhIGhhcyBiZWVuIGZpdC4nKTtcbiAgICB9XG5cbiAgICBsZXQgbk5laWdoYm9ycyA9IE1hdGguZmxvb3IodGhpcy5uTmVpZ2hib3JzICogdGhpcy50cmFuc2Zvcm1RdWV1ZVNpemUpO1xuICAgIG5OZWlnaGJvcnMgPSBNYXRoLm1pbihyYXdEYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG4gICAgY29uc3QgaW5pdCA9IG5uRGVzY2VudC5pbml0aWFsaXplU2VhcmNoKFxuICAgICAgdGhpcy5ycEZvcmVzdCxcbiAgICAgIHJhd0RhdGEsXG4gICAgICB0b1RyYW5zZm9ybSxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICB0aGlzLmluaXRGcm9tUmFuZG9tLFxuICAgICAgdGhpcy5pbml0RnJvbVRyZWUsXG4gICAgICB0aGlzLnJhbmRvbVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnNlYXJjaChyYXdEYXRhLCB0aGlzLnNlYXJjaEdyYXBoLCBpbml0LCB0b1RyYW5zZm9ybSk7XG5cbiAgICBsZXQgeyBpbmRpY2VzLCB3ZWlnaHRzOiBkaXN0YW5jZXMgfSA9IGhlYXAuZGVoZWFwU29ydChyZXN1bHQpO1xuXG4gICAgaW5kaWNlcyA9IGluZGljZXMubWFwKHggPT4geC5zbGljZSgwLCB0aGlzLm5OZWlnaGJvcnMpKTtcbiAgICBkaXN0YW5jZXMgPSBkaXN0YW5jZXMubWFwKHggPT4geC5zbGljZSgwLCB0aGlzLm5OZWlnaGJvcnMpKTtcblxuICAgIGNvbnN0IGFkanVzdGVkTG9jYWxDb25uZWN0aXZpdHkgPSBNYXRoLm1heCgwLCB0aGlzLmxvY2FsQ29ubmVjdGl2aXR5IC0gMSk7XG4gICAgY29uc3QgeyBzaWdtYXMsIHJob3MgfSA9IHRoaXMuc21vb3RoS05ORGlzdGFuY2UoXG4gICAgICBkaXN0YW5jZXMsXG4gICAgICB0aGlzLm5OZWlnaGJvcnMsXG4gICAgICBhZGp1c3RlZExvY2FsQ29ubmVjdGl2aXR5XG4gICAgKTtcblxuICAgIGNvbnN0IHsgcm93cywgY29scywgdmFscyB9ID0gdGhpcy5jb21wdXRlTWVtYmVyc2hpcFN0cmVuZ3RocyhcbiAgICAgIGluZGljZXMsXG4gICAgICBkaXN0YW5jZXMsXG4gICAgICBzaWdtYXMsXG4gICAgICByaG9zXG4gICAgKTtcblxuICAgIGNvbnN0IHNpemUgPSBbdG9UcmFuc2Zvcm0ubGVuZ3RoLCByYXdEYXRhLmxlbmd0aF07XG4gICAgbGV0IGdyYXBoID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgocm93cywgY29scywgdmFscywgc2l6ZSk7XG5cbiAgICAvLyBUaGlzIHdhcyBhIHZlcnkgc3BlY2lhbGx5IGNvbnN0cnVjdGVkIGdyYXBoIHdpdGggY29uc3RhbnQgZGVncmVlLlxuICAgIC8vIFRoYXQgbGV0cyB1cyBkbyBmYW5jeSB1bnBhY2tpbmcgYnkgcmVzaGFwaW5nIHRoZSBjc3IgbWF0cml4IGluZGljZXNcbiAgICAvLyBhbmQgZGF0YS4gRG9pbmcgc28gcmVsaWVzIG9uIHRoZSBjb25zdGFudCBkZWdyZWUgYXNzdW1wdGlvbiFcblxuICAgIGNvbnN0IG5vcm1lZCA9IG1hdHJpeC5ub3JtYWxpemUoZ3JhcGgsIG1hdHJpeC5Ob3JtVHlwZS5sMSk7XG5cbiAgICBjb25zdCBjc3JNYXRyaXggPSBtYXRyaXguZ2V0Q1NSKG5vcm1lZCk7XG4gICAgY29uc3QgblBvaW50cyA9IHRvVHJhbnNmb3JtLmxlbmd0aDtcblxuICAgIGNvbnN0IGVJbmRpY2VzID0gdXRpbHMucmVzaGFwZTJkKFxuICAgICAgY3NyTWF0cml4LmluZGljZXMsXG4gICAgICBuUG9pbnRzLFxuICAgICAgdGhpcy5uTmVpZ2hib3JzXG4gICAgKTtcblxuICAgIGNvbnN0IGVXZWlnaHRzID0gdXRpbHMucmVzaGFwZTJkKFxuICAgICAgY3NyTWF0cml4LnZhbHVlcyxcbiAgICAgIG5Qb2ludHMsXG4gICAgICB0aGlzLm5OZWlnaGJvcnNcbiAgICApO1xuXG4gICAgY29uc3QgZW1iZWRkaW5nID0gaW5pdFRyYW5zZm9ybShlSW5kaWNlcywgZVdlaWdodHMsIHRoaXMuZW1iZWRkaW5nKTtcblxuICAgIGNvbnN0IG5FcG9jaHMgPSB0aGlzLm5FcG9jaHNcbiAgICAgID8gdGhpcy5uRXBvY2hzIC8gM1xuICAgICAgOiBncmFwaC5uUm93cyA8PSAxMDAwMFxuICAgICAgPyAxMDBcbiAgICAgIDogMzA7XG5cbiAgICBjb25zdCBncmFwaE1heCA9IGdyYXBoXG4gICAgICAuZ2V0VmFsdWVzKClcbiAgICAgIC5yZWR1Y2UoKG1heCwgdmFsKSA9PiAodmFsID4gbWF4ID8gdmFsIDogbWF4KSwgMCk7XG4gICAgZ3JhcGggPSBncmFwaC5tYXAodmFsdWUgPT4gKHZhbHVlIDwgZ3JhcGhNYXggLyBuRXBvY2hzID8gMCA6IHZhbHVlKSk7XG4gICAgZ3JhcGggPSBtYXRyaXguZWxpbWluYXRlWmVyb3MoZ3JhcGgpO1xuXG4gICAgY29uc3QgZXBvY2hzUGVyU2FtcGxlID0gdGhpcy5tYWtlRXBvY2hzUGVyU2FtcGxlKFxuICAgICAgZ3JhcGguZ2V0VmFsdWVzKCksXG4gICAgICBuRXBvY2hzXG4gICAgKTtcbiAgICBjb25zdCBoZWFkID0gZ3JhcGguZ2V0Um93cygpO1xuICAgIGNvbnN0IHRhaWwgPSBncmFwaC5nZXRDb2xzKCk7XG5cbiAgICAvLyBJbml0aWFsaXplIG9wdGltaXphdGlvbiBzbGlnaHRseSBkaWZmZXJlbnRseSB0aGFuIHRoZSBmaXQgbWV0aG9kLlxuICAgIHRoaXMuYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHtcbiAgICAgIGhlYWRFbWJlZGRpbmc6IGVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmc6IHRoaXMuZW1iZWRkaW5nLFxuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBjdXJyZW50RXBvY2g6IDAsXG4gICAgICBuRXBvY2hzLFxuICAgICAgblZlcnRpY2VzOiBncmFwaC5nZXREaW1zKClbMV0sXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgfSk7XG4gICAgdGhpcy5wcmVwYXJlRm9yT3B0aW1pemF0aW9uTG9vcCgpO1xuXG4gICAgcmV0dXJuIHRoaXMub3B0aW1pemVMYXlvdXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgd2UncmUgdXNpbmcgc3VwZXJ2aXNlZCBwcm9qZWN0aW9uLCB0aGVuIHByb2Nlc3MgdGhlIGdyYXBoXG4gICAqIGFjY29yZGluZ2x5LlxuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzR3JhcGhGb3JTdXBlcnZpc2VkUHJvamVjdGlvbigpIHtcbiAgICBjb25zdCB7IFksIFggfSA9IHRoaXM7XG4gICAgaWYgKFkpIHtcbiAgICAgIGlmIChZLmxlbmd0aCAhPT0gWC5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggb2YgWCBhbmQgeSBtdXN0IGJlIGVxdWFsJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRhcmdldE1ldHJpYyA9PT0gVGFyZ2V0TWV0cmljLmNhdGVnb3JpY2FsKSB7XG4gICAgICAgIGNvbnN0IGx0ID0gdGhpcy50YXJnZXRXZWlnaHQgPCAxLjA7XG4gICAgICAgIGNvbnN0IGZhckRpc3QgPSBsdCA/IDIuNSAqICgxLjAgLyAoMS4wIC0gdGhpcy50YXJnZXRXZWlnaHQpKSA6IDEuMGUxMjtcbiAgICAgICAgdGhpcy5ncmFwaCA9IHRoaXMuY2F0ZWdvcmljYWxTaW1wbGljaWFsU2V0SW50ZXJzZWN0aW9uKFxuICAgICAgICAgIHRoaXMuZ3JhcGgsXG4gICAgICAgICAgWSxcbiAgICAgICAgICBmYXJEaXN0XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyBUT0RPIChhbmR5Y29lbmVuQCk6IGFkZCBub24tY2F0ZWdvcmljYWwgc3VwZXJ2aXNlZCBlbWJlZGRpbmdzLlxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYW51YWxseSBzdGVwIHRocm91Z2ggdGhlIG9wdGltaXphdGlvbiBwcm9jZXNzIG9uZSBlcG9jaCBhdCBhIHRpbWUuXG4gICAqL1xuICBzdGVwKCkge1xuICAgIGNvbnN0IHsgY3VycmVudEVwb2NoIH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuXG4gICAgaWYgKGN1cnJlbnRFcG9jaCA8IHRoaXMuZ2V0TkVwb2NocygpKSB7XG4gICAgICB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5jdXJyZW50RXBvY2g7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29tcHV0ZWQgcHJvamVjdGVkIGVtYmVkZGluZy5cbiAgICovXG4gIGdldEVtYmVkZGluZygpIHtcbiAgICByZXR1cm4gdGhpcy5lbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZSB0aGUgYGBuTmVpZ2hib3JzYGAgbmVhcmVzdCBwb2ludHMgZm9yIGVhY2ggZGF0YSBwb2ludCBpbiBgYFhgYFxuICAgKiBUaGlzIG1heSBiZSBleGFjdCwgYnV0IG1vcmUgbGlrZWx5IGlzIGFwcHJveGltYXRlZCB2aWEgbmVhcmVzdCBuZWlnaGJvclxuICAgKiBkZXNjZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBuZWFyZXN0TmVpZ2hib3JzKFg6IFZlY3Rvcikge1xuICAgIGNvbnN0IHsgZGlzdGFuY2VGbiwgbk5laWdoYm9ycyB9ID0gdGhpcztcbiAgICBjb25zdCBsb2cyID0gKG46IG51bWJlcikgPT4gTWF0aC5sb2cobikgLyBNYXRoLmxvZygyKTtcbiAgICBjb25zdCBtZXRyaWNOTkRlc2NlbnQgPSBubkRlc2NlbnQubWFrZU5ORGVzY2VudChkaXN0YW5jZUZuLCB0aGlzLnJhbmRvbSk7XG5cbiAgICAvLyBIYW5kbGUgcHl0aG9uMyByb3VuZGluZyBkb3duIGZyb20gMC41IGRpc2NycGFuY3lcbiAgICBjb25zdCByb3VuZCA9IChuOiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBuID09PSAwLjUgPyAwIDogTWF0aC5yb3VuZChuKTtcbiAgICB9O1xuXG4gICAgY29uc3QgblRyZWVzID0gNSArIE1hdGguZmxvb3Iocm91bmQoWC5sZW5ndGggKiogMC41IC8gMjAuMCkpO1xuICAgIGNvbnN0IG5JdGVycyA9IE1hdGgubWF4KDUsIE1hdGguZmxvb3IoTWF0aC5yb3VuZChsb2cyKFgubGVuZ3RoKSkpKTtcblxuICAgIHRoaXMucnBGb3Jlc3QgPSB0cmVlLm1ha2VGb3Jlc3QoWCwgbk5laWdoYm9ycywgblRyZWVzLCB0aGlzLnJhbmRvbSk7XG5cbiAgICBjb25zdCBsZWFmQXJyYXkgPSB0cmVlLm1ha2VMZWFmQXJyYXkodGhpcy5ycEZvcmVzdCk7XG4gICAgY29uc3QgeyBpbmRpY2VzLCB3ZWlnaHRzIH0gPSBtZXRyaWNOTkRlc2NlbnQoXG4gICAgICBYLFxuICAgICAgbGVhZkFycmF5LFxuICAgICAgbk5laWdoYm9ycyxcbiAgICAgIG5JdGVyc1xuICAgICk7XG4gICAgcmV0dXJuIHsga25uSW5kaWNlczogaW5kaWNlcywga25uRGlzdGFuY2VzOiB3ZWlnaHRzIH07XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gYSBzZXQgb2YgZGF0YSBYLCBhIG5laWdoYm9yaG9vZCBzaXplLCBhbmQgYSBtZWFzdXJlIG9mIGRpc3RhbmNlXG4gICAqIGNvbXB1dGUgdGhlIGZ1enp5IHNpbXBsaWNpYWwgc2V0IChoZXJlIHJlcHJlc2VudGVkIGFzIGEgZnV6enkgZ3JhcGggaW5cbiAgICogdGhlIGZvcm0gb2YgYSBzcGFyc2UgbWF0cml4KSBhc3NvY2lhdGVkIHRvIHRoZSBkYXRhLiBUaGlzIGlzIGRvbmUgYnlcbiAgICogbG9jYWxseSBhcHByb3hpbWF0aW5nIGdlb2Rlc2ljIGRpc3RhbmNlIGF0IGVhY2ggcG9pbnQsIGNyZWF0aW5nIGEgZnV6enlcbiAgICogc2ltcGxpY2lhbCBzZXQgZm9yIGVhY2ggc3VjaCBwb2ludCwgYW5kIHRoZW4gY29tYmluaW5nIGFsbCB0aGUgbG9jYWxcbiAgICogZnV6enkgc2ltcGxpY2lhbCBzZXRzIGludG8gYSBnbG9iYWwgb25lIHZpYSBhIGZ1enp5IHVuaW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBmdXp6eVNpbXBsaWNpYWxTZXQoXG4gICAgWDogVmVjdG9yLFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBzZXRPcE1peFJhdGlvID0gMS4wXG4gICkge1xuICAgIGNvbnN0IHsga25uSW5kaWNlcyA9IFtdLCBrbm5EaXN0YW5jZXMgPSBbXSwgbG9jYWxDb25uZWN0aXZpdHkgfSA9IHRoaXM7XG5cbiAgICBjb25zdCB7IHNpZ21hcywgcmhvcyB9ID0gdGhpcy5zbW9vdGhLTk5EaXN0YW5jZShcbiAgICAgIGtubkRpc3RhbmNlcyxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICBsb2NhbENvbm5lY3Rpdml0eVxuICAgICk7XG5cbiAgICBjb25zdCB7IHJvd3MsIGNvbHMsIHZhbHMgfSA9IHRoaXMuY29tcHV0ZU1lbWJlcnNoaXBTdHJlbmd0aHMoXG4gICAgICBrbm5JbmRpY2VzLFxuICAgICAga25uRGlzdGFuY2VzLFxuICAgICAgc2lnbWFzLFxuICAgICAgcmhvc1xuICAgICk7XG5cbiAgICBjb25zdCBzaXplID0gW1gubGVuZ3RoLCBYLmxlbmd0aF07XG4gICAgY29uc3Qgc3BhcnNlTWF0cml4ID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgocm93cywgY29scywgdmFscywgc2l6ZSk7XG5cbiAgICBjb25zdCB0cmFuc3Bvc2UgPSBtYXRyaXgudHJhbnNwb3NlKHNwYXJzZU1hdHJpeCk7XG4gICAgY29uc3QgcHJvZE1hdHJpeCA9IG1hdHJpeC5wYWlyd2lzZU11bHRpcGx5KHNwYXJzZU1hdHJpeCwgdHJhbnNwb3NlKTtcblxuICAgIGNvbnN0IGEgPSBtYXRyaXguc3VidHJhY3QobWF0cml4LmFkZChzcGFyc2VNYXRyaXgsIHRyYW5zcG9zZSksIHByb2RNYXRyaXgpO1xuICAgIGNvbnN0IGIgPSBtYXRyaXgubXVsdGlwbHlTY2FsYXIoYSwgc2V0T3BNaXhSYXRpbyk7XG4gICAgY29uc3QgYyA9IG1hdHJpeC5tdWx0aXBseVNjYWxhcihwcm9kTWF0cml4LCAxLjAgLSBzZXRPcE1peFJhdGlvKTtcbiAgICBjb25zdCByZXN1bHQgPSBtYXRyaXguYWRkKGIsIGMpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21iaW5lIGEgZnV6enkgc2ltcGxpY2lhbCBzZXQgd2l0aCBhbm90aGVyIGZ1enp5IHNpbXBsaWNpYWwgc2V0XG4gICAqIGdlbmVyYXRlZCBmcm9tIGNhdGVnb3JpY2FsIGRhdGEgdXNpbmcgY2F0ZWdvcmljYWwgZGlzdGFuY2VzLiBUaGUgdGFyZ2V0XG4gICAqIGRhdGEgaXMgYXNzdW1lZCB0byBiZSBjYXRlZ29yaWNhbCBsYWJlbCBkYXRhIChhIHZlY3RvciBvZiBsYWJlbHMpLFxuICAgKiBhbmQgdGhpcyB3aWxsIHVwZGF0ZSB0aGUgZnV6enkgc2ltcGxpY2lhbCBzZXQgdG8gcmVzcGVjdCB0aGF0IGxhYmVsIGRhdGEuXG4gICAqL1xuICBwcml2YXRlIGNhdGVnb3JpY2FsU2ltcGxpY2lhbFNldEludGVyc2VjdGlvbihcbiAgICBzaW1wbGljaWFsU2V0OiBtYXRyaXguU3BhcnNlTWF0cml4LFxuICAgIHRhcmdldDogbnVtYmVyW10sXG4gICAgZmFyRGlzdDogbnVtYmVyLFxuICAgIHVua25vd25EaXN0ID0gMS4wXG4gICkge1xuICAgIGxldCBpbnRlcnNlY3Rpb24gPSBmYXN0SW50ZXJzZWN0aW9uKFxuICAgICAgc2ltcGxpY2lhbFNldCxcbiAgICAgIHRhcmdldCxcbiAgICAgIHVua25vd25EaXN0LFxuICAgICAgZmFyRGlzdFxuICAgICk7XG4gICAgaW50ZXJzZWN0aW9uID0gbWF0cml4LmVsaW1pbmF0ZVplcm9zKGludGVyc2VjdGlvbik7XG4gICAgcmV0dXJuIHJlc2V0TG9jYWxDb25uZWN0aXZpdHkoaW50ZXJzZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGEgY29udGludW91cyB2ZXJzaW9uIG9mIHRoZSBkaXN0YW5jZSB0byB0aGUga3RoIG5lYXJlc3RcbiAgICogbmVpZ2hib3IuIFRoYXQgaXMsIHRoaXMgaXMgc2ltaWxhciB0byBrbm4tZGlzdGFuY2UgYnV0IGFsbG93cyBjb250aW51b3VzXG4gICAqIGsgdmFsdWVzIHJhdGhlciB0aGFuIHJlcXVpcmluZyBhbiBpbnRlZ3JhbCBrLiBJbiBlc3NjZW5jZSB3ZSBhcmUgc2ltcGx5XG4gICAqIGNvbXB1dGluZyB0aGUgZGlzdGFuY2Ugc3VjaCB0aGF0IHRoZSBjYXJkaW5hbGl0eSBvZiBmdXp6eSBzZXQgd2UgZ2VuZXJhdGVcbiAgICogaXMgay5cbiAgICovXG4gIHByaXZhdGUgc21vb3RoS05ORGlzdGFuY2UoXG4gICAgZGlzdGFuY2VzOiBWZWN0b3JzLFxuICAgIGs6IG51bWJlcixcbiAgICBsb2NhbENvbm5lY3Rpdml0eSA9IDEuMCxcbiAgICBuSXRlciA9IDY0LFxuICAgIGJhbmR3aWR0aCA9IDEuMFxuICApIHtcbiAgICBjb25zdCB0YXJnZXQgPSAoTWF0aC5sb2coaykgLyBNYXRoLmxvZygyKSkgKiBiYW5kd2lkdGg7XG4gICAgY29uc3QgcmhvID0gdXRpbHMuemVyb3MoZGlzdGFuY2VzLmxlbmd0aCk7XG4gICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuemVyb3MoZGlzdGFuY2VzLmxlbmd0aCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpc3RhbmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IGxvID0gMC4wO1xuICAgICAgbGV0IGhpID0gSW5maW5pdHk7XG4gICAgICBsZXQgbWlkID0gMS4wO1xuXG4gICAgICAvLyBUT0RPOiBUaGlzIGlzIHZlcnkgaW5lZmZpY2llbnQsIGJ1dCB3aWxsIGRvIGZvciBub3cuIEZJWE1FXG4gICAgICBjb25zdCBpdGhEaXN0YW5jZXMgPSBkaXN0YW5jZXNbaV07XG4gICAgICBjb25zdCBub25aZXJvRGlzdHMgPSBpdGhEaXN0YW5jZXMuZmlsdGVyKGQgPT4gZCA+IDAuMCk7XG5cbiAgICAgIGlmIChub25aZXJvRGlzdHMubGVuZ3RoID49IGxvY2FsQ29ubmVjdGl2aXR5KSB7XG4gICAgICAgIGxldCBpbmRleCA9IE1hdGguZmxvb3IobG9jYWxDb25uZWN0aXZpdHkpO1xuICAgICAgICBsZXQgaW50ZXJwb2xhdGlvbiA9IGxvY2FsQ29ubmVjdGl2aXR5IC0gaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA+IDApIHtcbiAgICAgICAgICByaG9baV0gPSBub25aZXJvRGlzdHNbaW5kZXggLSAxXTtcbiAgICAgICAgICBpZiAoaW50ZXJwb2xhdGlvbiA+IFNNT09USF9LX1RPTEVSQU5DRSkge1xuICAgICAgICAgICAgcmhvW2ldICs9XG4gICAgICAgICAgICAgIGludGVycG9sYXRpb24gKiAobm9uWmVyb0Rpc3RzW2luZGV4XSAtIG5vblplcm9EaXN0c1tpbmRleCAtIDFdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmhvW2ldID0gaW50ZXJwb2xhdGlvbiAqIG5vblplcm9EaXN0c1swXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub25aZXJvRGlzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICByaG9baV0gPSB1dGlscy5tYXgobm9uWmVyb0Rpc3RzKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgbiA9IDA7IG4gPCBuSXRlcjsgbisrKSB7XG4gICAgICAgIGxldCBwc3VtID0gMC4wO1xuICAgICAgICBmb3IgKGxldCBqID0gMTsgaiA8IGRpc3RhbmNlc1tpXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZXNbaV1bal0gLSByaG9baV07XG4gICAgICAgICAgaWYgKGQgPiAwKSB7XG4gICAgICAgICAgICBwc3VtICs9IE1hdGguZXhwKC0oZCAvIG1pZCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwc3VtICs9IDEuMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoTWF0aC5hYnMocHN1bSAtIHRhcmdldCkgPCBTTU9PVEhfS19UT0xFUkFOQ0UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwc3VtID4gdGFyZ2V0KSB7XG4gICAgICAgICAgaGkgPSBtaWQ7XG4gICAgICAgICAgbWlkID0gKGxvICsgaGkpIC8gMi4wO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvID0gbWlkO1xuICAgICAgICAgIGlmIChoaSA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgIG1pZCAqPSAyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtaWQgPSAobG8gKyBoaSkgLyAyLjA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdFtpXSA9IG1pZDtcblxuICAgICAgLy8gVE9ETzogVGhpcyBpcyB2ZXJ5IGluZWZmaWNpZW50LCBidXQgd2lsbCBkbyBmb3Igbm93LiBGSVhNRVxuICAgICAgaWYgKHJob1tpXSA+IDAuMCkge1xuICAgICAgICBjb25zdCBtZWFuSXRoRGlzdGFuY2VzID0gdXRpbHMubWVhbihpdGhEaXN0YW5jZXMpO1xuICAgICAgICBpZiAocmVzdWx0W2ldIDwgTUlOX0tfRElTVF9TQ0FMRSAqIG1lYW5JdGhEaXN0YW5jZXMpIHtcbiAgICAgICAgICByZXN1bHRbaV0gPSBNSU5fS19ESVNUX1NDQUxFICogbWVhbkl0aERpc3RhbmNlcztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWVhbkRpc3RhbmNlcyA9IHV0aWxzLm1lYW4oZGlzdGFuY2VzLm1hcCh1dGlscy5tZWFuKSk7XG4gICAgICAgIGlmIChyZXN1bHRbaV0gPCBNSU5fS19ESVNUX1NDQUxFICogbWVhbkRpc3RhbmNlcykge1xuICAgICAgICAgIHJlc3VsdFtpXSA9IE1JTl9LX0RJU1RfU0NBTEUgKiBtZWFuRGlzdGFuY2VzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgc2lnbWFzOiByZXN1bHQsIHJob3M6IHJobyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCB0aGUgbWVtYmVyc2hpcCBzdHJlbmd0aCBkYXRhIGZvciB0aGUgMS1za2VsZXRvbiBvZiBlYWNoIGxvY2FsXG4gICAqIGZ1enp5IHNpbXBsaWNpYWwgc2V0IC0tIHRoaXMgaXMgZm9ybWVkIGFzIGEgc3BhcnNlIG1hdHJpeCB3aGVyZSBlYWNoIHJvdyBpc1xuICAgKiBhIGxvY2FsIGZ1enp5IHNpbXBsaWNpYWwgc2V0LCB3aXRoIGEgbWVtYmVyc2hpcCBzdHJlbmd0aCBmb3IgdGhlXG4gICAqIDEtc2ltcGxleCB0byBlYWNoIG90aGVyIGRhdGEgcG9pbnQuXG4gICAqL1xuICBwcml2YXRlIGNvbXB1dGVNZW1iZXJzaGlwU3RyZW5ndGhzKFxuICAgIGtubkluZGljZXM6IFZlY3RvcnMsXG4gICAga25uRGlzdGFuY2VzOiBWZWN0b3JzLFxuICAgIHNpZ21hczogbnVtYmVyW10sXG4gICAgcmhvczogbnVtYmVyW11cbiAgKTogeyByb3dzOiBudW1iZXJbXTsgY29sczogbnVtYmVyW107IHZhbHM6IG51bWJlcltdIH0ge1xuICAgIGNvbnN0IG5TYW1wbGVzID0ga25uSW5kaWNlcy5sZW5ndGg7XG4gICAgY29uc3Qgbk5laWdoYm9ycyA9IGtubkluZGljZXNbMF0ubGVuZ3RoO1xuXG4gICAgY29uc3Qgcm93cyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgY29scyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgdmFscyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICAgIGxldCB2YWwgPSAwO1xuICAgICAgICBpZiAoa25uSW5kaWNlc1tpXVtqXSA9PT0gLTEpIHtcbiAgICAgICAgICBjb250aW51ZTsgLy8gV2UgZGlkbid0IGdldCB0aGUgZnVsbCBrbm4gZm9yIGlcbiAgICAgICAgfVxuICAgICAgICBpZiAoa25uSW5kaWNlc1tpXVtqXSA9PT0gaSkge1xuICAgICAgICAgIHZhbCA9IDAuMDtcbiAgICAgICAgfSBlbHNlIGlmIChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldIDw9IDAuMCkge1xuICAgICAgICAgIHZhbCA9IDEuMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWwgPSBNYXRoLmV4cCgtKChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldKSAvIHNpZ21hc1tpXSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcm93c1tpICogbk5laWdoYm9ycyArIGpdID0gaTtcbiAgICAgICAgY29sc1tpICogbk5laWdoYm9ycyArIGpdID0ga25uSW5kaWNlc1tpXVtqXTtcbiAgICAgICAgdmFsc1tpICogbk5laWdoYm9ycyArIGpdID0gdmFsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IHJvd3MsIGNvbHMsIHZhbHMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGEgZnV6enkgc2ltcGxpY2lhbCBzZXQgZW1iZWRkaW5nLCB1c2luZyBhIHNwZWNpZmllZFxuICAgKiBpbml0aWFsaXNhdGlvbiBtZXRob2QgYW5kIHRoZW4gbWluaW1pemluZyB0aGUgZnV6enkgc2V0IGNyb3NzIGVudHJvcHlcbiAgICogYmV0d2VlbiB0aGUgMS1za2VsZXRvbnMgb2YgdGhlIGhpZ2ggYW5kIGxvdyBkaW1lbnNpb25hbCBmdXp6eSBzaW1wbGljaWFsXG4gICAqIHNldHMuXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVTaW1wbGljaWFsU2V0RW1iZWRkaW5nKCkge1xuICAgIGNvbnN0IG5FcG9jaHMgPSB0aGlzLmdldE5FcG9jaHMoKTtcblxuICAgIGNvbnN0IHsgbkNvbXBvbmVudHMgfSA9IHRoaXM7XG4gICAgY29uc3QgZ3JhcGhWYWx1ZXMgPSB0aGlzLmdyYXBoLmdldFZhbHVlcygpO1xuICAgIGxldCBncmFwaE1heCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdmFsdWUgPSBncmFwaFZhbHVlc1tpXTtcbiAgICAgIGlmIChncmFwaE1heCA8IGdyYXBoVmFsdWVzW2ldKSB7XG4gICAgICAgIGdyYXBoTWF4ID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZ3JhcGggPSB0aGlzLmdyYXBoLm1hcCh2YWx1ZSA9PiB7XG4gICAgICBpZiAodmFsdWUgPCBncmFwaE1heCAvIG5FcG9jaHMpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBXZSdyZSBub3QgY29tcHV0aW5nIHRoZSBzcGVjdHJhbCBpbml0aWFsaXphdGlvbiBpbiB0aGlzIGltcGxlbWVudGF0aW9uXG4gICAgLy8gdW50aWwgd2UgZGV0ZXJtaW5lIGEgYmV0dGVyIGVpZ2VudmFsdWUvZWlnZW52ZWN0b3IgY29tcHV0YXRpb25cbiAgICAvLyBhcHByb2FjaFxuICAgIHRoaXMuZW1iZWRkaW5nID0gdXRpbHMuemVyb3MoZ3JhcGgublJvd3MpLm1hcCgoKSA9PiB7XG4gICAgICByZXR1cm4gdXRpbHMuemVyb3MobkNvbXBvbmVudHMpLm1hcCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB1dGlscy50YXVSYW5kKHRoaXMucmFuZG9tKSAqIDIwICsgLTEwOyAvLyBSYW5kb20gZnJvbSAtMTAgdG8gMTBcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gR2V0IGdyYXBoIGRhdGEgaW4gb3JkZXJlZCB3YXkuLi5cbiAgICBjb25zdCB3ZWlnaHRzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGhlYWQ6IG51bWJlcltdID0gW107XG4gICAgY29uc3QgdGFpbDogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCByb3dDb2xWYWx1ZXMgPSBncmFwaC5nZXRBbGwoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd0NvbFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZW50cnkgPSByb3dDb2xWYWx1ZXNbaV07XG4gICAgICBpZiAoZW50cnkudmFsdWUpIHtcbiAgICAgICAgd2VpZ2h0cy5wdXNoKGVudHJ5LnZhbHVlKTtcbiAgICAgICAgdGFpbC5wdXNoKGVudHJ5LnJvdyk7XG4gICAgICAgIGhlYWQucHVzaChlbnRyeS5jb2wpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBlcG9jaHNQZXJTYW1wbGUgPSB0aGlzLm1ha2VFcG9jaHNQZXJTYW1wbGUod2VpZ2h0cywgbkVwb2Nocyk7XG5cbiAgICByZXR1cm4geyBoZWFkLCB0YWlsLCBlcG9jaHNQZXJTYW1wbGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHNldCBvZiB3ZWlnaHRzIGFuZCBudW1iZXIgb2YgZXBvY2hzIGdlbmVyYXRlIHRoZSBudW1iZXIgb2ZcbiAgICogZXBvY2hzIHBlciBzYW1wbGUgZm9yIGVhY2ggd2VpZ2h0LlxuICAgKi9cbiAgcHJpdmF0ZSBtYWtlRXBvY2hzUGVyU2FtcGxlKHdlaWdodHM6IG51bWJlcltdLCBuRXBvY2hzOiBudW1iZXIpIHtcbiAgICBjb25zdCByZXN1bHQgPSB1dGlscy5maWxsZWQod2VpZ2h0cy5sZW5ndGgsIC0xLjApO1xuICAgIGNvbnN0IG1heCA9IHV0aWxzLm1heCh3ZWlnaHRzKTtcbiAgICBjb25zdCBuU2FtcGxlcyA9IHdlaWdodHMubWFwKHcgPT4gKHcgLyBtYXgpICogbkVwb2Nocyk7XG4gICAgblNhbXBsZXMuZm9yRWFjaCgobiwgaSkgPT4ge1xuICAgICAgaWYgKG4gPiAwKSByZXN1bHRbaV0gPSBuRXBvY2hzIC8gblNhbXBsZXNbaV07XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NpZ25zIG9wdGltaXphdGlvbiBzdGF0ZSBwYXJhbWV0ZXJzIGZyb20gYSBwYXJ0aWFsIG9wdGltaXphdGlvbiBzdGF0ZS5cbiAgICovXG4gIHByaXZhdGUgYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHN0YXRlOiBQYXJ0aWFsPE9wdGltaXphdGlvblN0YXRlPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5vcHRpbWl6YXRpb25TdGF0ZSwgc3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYSBmZXcgb3B0aW1pemF0aW9uIHN0YXRlIHBhcmFtZXRlcnMgdGhhdCBhcmUgbmVjZXNzYXJ5IGJlZm9yZSBlbnRlcmluZ1xuICAgKiB0aGUgb3B0aW1pemF0aW9uIHN0ZXAgbG9vcC5cbiAgICovXG4gIHByaXZhdGUgcHJlcGFyZUZvck9wdGltaXphdGlvbkxvb3AoKSB7XG4gICAgLy8gSHlwZXJwYXJhbWV0ZXJzXG4gICAgY29uc3QgeyByZXB1bHNpb25TdHJlbmd0aCwgbGVhcm5pbmdSYXRlLCBuZWdhdGl2ZVNhbXBsZVJhdGUgfSA9IHRoaXM7XG5cbiAgICBjb25zdCB7XG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBoZWFkRW1iZWRkaW5nLFxuICAgICAgdGFpbEVtYmVkZGluZyxcbiAgICB9ID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZTtcblxuICAgIGNvbnN0IGRpbSA9IGhlYWRFbWJlZGRpbmdbMF0ubGVuZ3RoO1xuICAgIGNvbnN0IG1vdmVPdGhlciA9IGhlYWRFbWJlZGRpbmcubGVuZ3RoID09PSB0YWlsRW1iZWRkaW5nLmxlbmd0aDtcblxuICAgIGNvbnN0IGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlID0gZXBvY2hzUGVyU2FtcGxlLm1hcChcbiAgICAgIGUgPT4gZSAvIG5lZ2F0aXZlU2FtcGxlUmF0ZVxuICAgICk7XG4gICAgY29uc3QgZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZSA9IFsuLi5lcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZV07XG4gICAgY29uc3QgZXBvY2hPZk5leHRTYW1wbGUgPSBbLi4uZXBvY2hzUGVyU2FtcGxlXTtcblxuICAgIHRoaXMuYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHtcbiAgICAgIGVwb2NoT2ZOZXh0U2FtcGxlLFxuICAgICAgZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZSxcbiAgICAgIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlLFxuICAgICAgbW92ZU90aGVyLFxuICAgICAgaW5pdGlhbEFscGhhOiBsZWFybmluZ1JhdGUsXG4gICAgICBhbHBoYTogbGVhcm5pbmdSYXRlLFxuICAgICAgZ2FtbWE6IHJlcHVsc2lvblN0cmVuZ3RoLFxuICAgICAgZGltLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIG9wdGltaXphdGlvbiBzdGF0ZSBmb3Igc3RlcHdpc2Ugb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplT3B0aW1pemF0aW9uKCkge1xuICAgIC8vIEFsZ29yaXRobSBzdGF0ZVxuICAgIGNvbnN0IGhlYWRFbWJlZGRpbmcgPSB0aGlzLmVtYmVkZGluZztcbiAgICBjb25zdCB0YWlsRW1iZWRkaW5nID0gdGhpcy5lbWJlZGRpbmc7XG5cbiAgICAvLyBJbml0aWFsaXplZCBpbiBpbml0aWFsaXplU2ltcGxpY2lhbFNldEVtYmVkZGluZygpXG4gICAgY29uc3QgeyBoZWFkLCB0YWlsLCBlcG9jaHNQZXJTYW1wbGUgfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG5cbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5nZXRORXBvY2hzKCk7XG4gICAgY29uc3QgblZlcnRpY2VzID0gdGhpcy5ncmFwaC5uQ29scztcblxuICAgIGNvbnN0IHsgYSwgYiB9ID0gZmluZEFCUGFyYW1zKHRoaXMuc3ByZWFkLCB0aGlzLm1pbkRpc3QpO1xuXG4gICAgdGhpcy5hc3NpZ25PcHRpbWl6YXRpb25TdGF0ZVBhcmFtZXRlcnMoe1xuICAgICAgaGVhZEVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmcsXG4gICAgICBoZWFkLFxuICAgICAgdGFpbCxcbiAgICAgIGVwb2Noc1BlclNhbXBsZSxcbiAgICAgIGEsXG4gICAgICBiLFxuICAgICAgbkVwb2NocyxcbiAgICAgIG5WZXJ0aWNlcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXByb3ZlIGFuIGVtYmVkZGluZyB1c2luZyBzdG9jaGFzdGljIGdyYWRpZW50IGRlc2NlbnQgdG8gbWluaW1pemUgdGhlXG4gICAqIGZ1enp5IHNldCBjcm9zcyBlbnRyb3B5IGJldHdlZW4gdGhlIDEtc2tlbGV0b25zIG9mIHRoZSBoaWdoIGRpbWVuc2lvbmFsXG4gICAqIGFuZCBsb3cgZGltZW5zaW9uYWwgZnV6enkgc2ltcGxpY2lhbCBzZXRzLiBJbiBwcmFjdGljZSB0aGlzIGlzIGRvbmUgYnlcbiAgICogc2FtcGxpbmcgZWRnZXMgYmFzZWQgb24gdGhlaXIgbWVtYmVyc2hpcCBzdHJlbmd0aCAod2l0aCB0aGUgKDEtcCkgdGVybXNcbiAgICogY29taW5nIGZyb20gbmVnYXRpdmUgc2FtcGxpbmcgc2ltaWxhciB0byB3b3JkMnZlYykuXG4gICAqL1xuICBwcml2YXRlIG9wdGltaXplTGF5b3V0U3RlcChuOiBudW1iZXIpIHtcbiAgICBjb25zdCB7IG9wdGltaXphdGlvblN0YXRlIH0gPSB0aGlzO1xuICAgIGNvbnN0IHtcbiAgICAgIGhlYWQsXG4gICAgICB0YWlsLFxuICAgICAgaGVhZEVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmcsXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBlcG9jaE9mTmV4dFNhbXBsZSxcbiAgICAgIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGUsXG4gICAgICBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZSxcbiAgICAgIG1vdmVPdGhlcixcbiAgICAgIGluaXRpYWxBbHBoYSxcbiAgICAgIGFscGhhLFxuICAgICAgZ2FtbWEsXG4gICAgICBhLFxuICAgICAgYixcbiAgICAgIGRpbSxcbiAgICAgIG5FcG9jaHMsXG4gICAgICBuVmVydGljZXMsXG4gICAgfSA9IG9wdGltaXphdGlvblN0YXRlO1xuXG4gICAgY29uc3QgY2xpcFZhbHVlID0gNC4wO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlcG9jaHNQZXJTYW1wbGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChlcG9jaE9mTmV4dFNhbXBsZVtpXSA+IG4pIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGogPSBoZWFkW2ldO1xuICAgICAgY29uc3QgayA9IHRhaWxbaV07XG5cbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBoZWFkRW1iZWRkaW5nW2pdO1xuICAgICAgY29uc3Qgb3RoZXIgPSB0YWlsRW1iZWRkaW5nW2tdO1xuXG4gICAgICBjb25zdCBkaXN0U3F1YXJlZCA9IHJEaXN0KGN1cnJlbnQsIG90aGVyKTtcblxuICAgICAgbGV0IGdyYWRDb2VmZiA9IDA7XG4gICAgICBpZiAoZGlzdFNxdWFyZWQgPiAwKSB7XG4gICAgICAgIGdyYWRDb2VmZiA9IC0yLjAgKiBhICogYiAqIE1hdGgucG93KGRpc3RTcXVhcmVkLCBiIC0gMS4wKTtcbiAgICAgICAgZ3JhZENvZWZmIC89IGEgKiBNYXRoLnBvdyhkaXN0U3F1YXJlZCwgYikgKyAxLjA7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgZGltOyBkKyspIHtcbiAgICAgICAgY29uc3QgZ3JhZEQgPSBjbGlwKGdyYWRDb2VmZiAqIChjdXJyZW50W2RdIC0gb3RoZXJbZF0pLCBjbGlwVmFsdWUpO1xuICAgICAgICBjdXJyZW50W2RdICs9IGdyYWREICogYWxwaGE7XG4gICAgICAgIGlmIChtb3ZlT3RoZXIpIHtcbiAgICAgICAgICBvdGhlcltkXSArPSAtZ3JhZEQgKiBhbHBoYTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBlcG9jaE9mTmV4dFNhbXBsZVtpXSArPSBlcG9jaHNQZXJTYW1wbGVbaV07XG5cbiAgICAgIGNvbnN0IG5OZWdTYW1wbGVzID0gTWF0aC5mbG9vcihcbiAgICAgICAgKG4gLSBlcG9jaE9mTmV4dE5lZ2F0aXZlU2FtcGxlW2ldKSAvIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlW2ldXG4gICAgICApO1xuXG4gICAgICBmb3IgKGxldCBwID0gMDsgcCA8IG5OZWdTYW1wbGVzOyBwKyspIHtcbiAgICAgICAgY29uc3QgayA9IHV0aWxzLnRhdVJhbmRJbnQoblZlcnRpY2VzLCB0aGlzLnJhbmRvbSk7XG4gICAgICAgIGNvbnN0IG90aGVyID0gdGFpbEVtYmVkZGluZ1trXTtcblxuICAgICAgICBjb25zdCBkaXN0U3F1YXJlZCA9IHJEaXN0KGN1cnJlbnQsIG90aGVyKTtcblxuICAgICAgICBsZXQgZ3JhZENvZWZmID0gMC4wO1xuICAgICAgICBpZiAoZGlzdFNxdWFyZWQgPiAwLjApIHtcbiAgICAgICAgICBncmFkQ29lZmYgPSAyLjAgKiBnYW1tYSAqIGI7XG4gICAgICAgICAgZ3JhZENvZWZmIC89XG4gICAgICAgICAgICAoMC4wMDEgKyBkaXN0U3F1YXJlZCkgKiAoYSAqIE1hdGgucG93KGRpc3RTcXVhcmVkLCBiKSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGogPT09IGspIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgZGltOyBkKyspIHtcbiAgICAgICAgICBsZXQgZ3JhZEQgPSA0LjA7XG4gICAgICAgICAgaWYgKGdyYWRDb2VmZiA+IDAuMCkge1xuICAgICAgICAgICAgZ3JhZEQgPSBjbGlwKGdyYWRDb2VmZiAqIChjdXJyZW50W2RdIC0gb3RoZXJbZF0pLCBjbGlwVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50W2RdICs9IGdyYWREICogYWxwaGE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGVbaV0gKz0gbk5lZ1NhbXBsZXMgKiBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZVtpXTtcbiAgICB9XG4gICAgb3B0aW1pemF0aW9uU3RhdGUuYWxwaGEgPSBpbml0aWFsQWxwaGEgKiAoMS4wIC0gbiAvIG5FcG9jaHMpO1xuXG4gICAgb3B0aW1pemF0aW9uU3RhdGUuY3VycmVudEVwb2NoICs9IDE7XG4gICAgcmV0dXJuIGhlYWRFbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dEFzeW5jKFxuICAgIGVwb2NoQ2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHN0ZXAgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBuRXBvY2hzLCBjdXJyZW50RXBvY2ggfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG4gICAgICAgICAgdGhpcy5lbWJlZGRpbmcgPSB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgICAgICAgIGNvbnN0IGVwb2NoQ29tcGxldGVkID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5jdXJyZW50RXBvY2g7XG4gICAgICAgICAgY29uc3Qgc2hvdWxkU3RvcCA9IGVwb2NoQ2FsbGJhY2soZXBvY2hDb21wbGV0ZWQpID09PSBmYWxzZTtcbiAgICAgICAgICBjb25zdCBpc0ZpbmlzaGVkID0gZXBvY2hDb21wbGV0ZWQgPT09IG5FcG9jaHM7XG4gICAgICAgICAgaWYgKCFzaG91bGRTdG9wICYmICFpc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHN0ZXAoKSwgMCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGlzRmluaXNoZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHN0ZXAoKSwgMCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dChcbiAgICBlcG9jaENhbGxiYWNrOiAoZXBvY2hOdW1iZXI6IG51bWJlcikgPT4gdm9pZCB8IGJvb2xlYW4gPSAoKSA9PiB0cnVlXG4gICk6IFZlY3RvcnMge1xuICAgIGxldCBpc0ZpbmlzaGVkID0gZmFsc2U7XG4gICAgbGV0IGVtYmVkZGluZzogVmVjdG9ycyA9IFtdO1xuICAgIHdoaWxlICghaXNGaW5pc2hlZCkge1xuICAgICAgY29uc3QgeyBuRXBvY2hzLCBjdXJyZW50RXBvY2ggfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG4gICAgICBlbWJlZGRpbmcgPSB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgICAgY29uc3QgZXBvY2hDb21wbGV0ZWQgPSB0aGlzLm9wdGltaXphdGlvblN0YXRlLmN1cnJlbnRFcG9jaDtcbiAgICAgIGNvbnN0IHNob3VsZFN0b3AgPSBlcG9jaENhbGxiYWNrKGVwb2NoQ29tcGxldGVkKSA9PT0gZmFsc2U7XG4gICAgICBpc0ZpbmlzaGVkID0gZXBvY2hDb21wbGV0ZWQgPT09IG5FcG9jaHMgfHwgc2hvdWxkU3RvcDtcbiAgICB9XG4gICAgcmV0dXJuIGVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgZXBvY2hzIGZvciBvcHRpbWl6aW5nIHRoZSBwcm9qZWN0aW9uLlxuICAgKiBOT1RFOiBUaGlzIGhldXJpc3RpYyBkaWZmZXJzIGZyb20gdGhlIHB5dGhvbiB2ZXJzaW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0TkVwb2NocygpIHtcbiAgICBjb25zdCBncmFwaCA9IHRoaXMuZ3JhcGg7XG5cbiAgICBpZiAodGhpcy5uRXBvY2hzID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMubkVwb2NocztcbiAgICB9XG5cbiAgICBpZiAoIWdyYXBoKSB7XG4gICAgICByZXR1cm4gMjAwO1xuICAgIH1cblxuICAgIGNvbnN0IGxlbmd0aCA9IGdyYXBoLm5Sb3dzO1xuICAgIGlmIChsZW5ndGggPD0gMjUwMCkge1xuICAgICAgcmV0dXJuIDUwMDtcbiAgICB9IGVsc2UgaWYgKGxlbmd0aCA8PSA1MDAwKSB7XG4gICAgICByZXR1cm4gNDAwO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoIDw9IDc1MDApIHtcbiAgICAgIHJldHVybiAzMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAyMDA7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldWNsaWRlYW4oeDogVmVjdG9yLCB5OiBWZWN0b3IpIHtcbiAgbGV0IHJlc3VsdCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdCArPSAoeFtpXSAtIHlbaV0pICoqIDI7XG4gIH1cbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbnVtZXJpYyh4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICBjb25zdCByZXN1bHQgPSBNYXRoLmFicyh4IC0geSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmUoeDogVmVjdG9yLCB5OiBWZWN0b3IpIHtcbiAgbGV0IHJlc3VsdCA9IDAuMDtcbiAgbGV0IG5vcm1YID0gMC4wO1xuICBsZXQgbm9ybVkgPSAwLjA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IHhbaV0gKiB5W2ldO1xuICAgIG5vcm1YICs9IHhbaV0gKiogMjtcbiAgICBub3JtWSArPSB5W2ldICoqIDI7XG4gIH1cblxuICBpZiAobm9ybVggPT09IDAgJiYgbm9ybVkgPT09IDApIHtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIGlmIChub3JtWCA9PT0gMCB8fCBub3JtWSA9PT0gMCkge1xuICAgIHJldHVybiAxLjA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDEuMCAtIHJlc3VsdCAvIE1hdGguc3FydChub3JtWCAqIG5vcm1ZKTtcbiAgfVxufVxuXG4vKipcbiAqIEFuIGludGVyZmFjZSByZXByZXNlbnRpbmcgdGhlIG9wdGltaXphdGlvbiBzdGF0ZSB0cmFja2VkIGJldHdlZW4gc3RlcHMgb2ZcbiAqIHRoZSBTR0Qgb3B0aW1pemF0aW9uXG4gKi9cbmNsYXNzIE9wdGltaXphdGlvblN0YXRlIHtcbiAgY3VycmVudEVwb2NoID0gMDtcblxuICAvLyBEYXRhIHRyYWNrZWQgZHVyaW5nIG9wdGltaXphdGlvbiBzdGVwcy5cbiAgaGVhZEVtYmVkZGluZzogbnVtYmVyW11bXSA9IFtdO1xuICB0YWlsRW1iZWRkaW5nOiBudW1iZXJbXVtdID0gW107XG4gIGhlYWQ6IG51bWJlcltdID0gW107XG4gIHRhaWw6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1BlclNhbXBsZTogbnVtYmVyW10gPSBbXTtcbiAgZXBvY2hPZk5leHRTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlOiBudW1iZXJbXSA9IFtdO1xuICBtb3ZlT3RoZXIgPSB0cnVlO1xuICBpbml0aWFsQWxwaGEgPSAxLjA7XG4gIGFscGhhID0gMS4wO1xuICBnYW1tYSA9IDEuMDtcbiAgYSA9IDEuNTc2OTQzNDYwMzExMzA3NztcbiAgYiA9IDAuODk1MDYwODc3OTEwOTczMztcbiAgZGltID0gMjtcbiAgbkVwb2NocyA9IDUwMDtcbiAgblZlcnRpY2VzID0gMDtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBjbGFtcGluZyBvZiBhIHZhbHVlIGludG8gYSBmaXhlZCByYW5nZVxuICovXG5mdW5jdGlvbiBjbGlwKHg6IG51bWJlciwgY2xpcFZhbHVlOiBudW1iZXIpIHtcbiAgaWYgKHggPiBjbGlwVmFsdWUpIHJldHVybiBjbGlwVmFsdWU7XG4gIGVsc2UgaWYgKHggPCAtY2xpcFZhbHVlKSByZXR1cm4gLWNsaXBWYWx1ZTtcbiAgZWxzZSByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBSZWR1Y2VkIEV1Y2xpZGVhbiBkaXN0YW5jZS5cbiAqL1xuZnVuY3Rpb24gckRpc3QoeDogbnVtYmVyW10sIHk6IG51bWJlcltdKSB7XG4gIGxldCByZXN1bHQgPSAwLjA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdCArPSBNYXRoLnBvdyh4W2ldIC0geVtpXSwgMik7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBGaXQgYSwgYiBwYXJhbXMgZm9yIHRoZSBkaWZmZXJlbnRpYWJsZSBjdXJ2ZSB1c2VkIGluIGxvd2VyXG4gKiBkaW1lbnNpb25hbCBmdXp6eSBzaW1wbGljaWFsIGNvbXBsZXggY29uc3RydWN0aW9uLiBXZSB3YW50IHRoZVxuICogc21vb3RoIGN1cnZlIChmcm9tIGEgcHJlLWRlZmluZWQgZmFtaWx5IHdpdGggc2ltcGxlIGdyYWRpZW50KSB0aGF0XG4gKiBiZXN0IG1hdGNoZXMgYW4gb2Zmc2V0IGV4cG9uZW50aWFsIGRlY2F5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEFCUGFyYW1zKHNwcmVhZDogbnVtYmVyLCBtaW5EaXN0OiBudW1iZXIpIHtcbiAgY29uc3QgY3VydmUgPSAoW2EsIGJdOiBudW1iZXJbXSkgPT4gKHg6IG51bWJlcikgPT4ge1xuICAgIHJldHVybiAxLjAgLyAoMS4wICsgYSAqIHggKiogKDIgKiBiKSk7XG4gIH07XG5cbiAgY29uc3QgeHYgPSB1dGlsc1xuICAgIC5saW5lYXIoMCwgc3ByZWFkICogMywgMzAwKVxuICAgIC5tYXAodmFsID0+ICh2YWwgPCBtaW5EaXN0ID8gMS4wIDogdmFsKSk7XG5cbiAgY29uc3QgeXYgPSB1dGlscy56ZXJvcyh4di5sZW5ndGgpLm1hcCgodmFsLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IGd0ZSA9IHh2W2luZGV4XSA+PSBtaW5EaXN0O1xuICAgIHJldHVybiBndGUgPyBNYXRoLmV4cCgtKHh2W2luZGV4XSAtIG1pbkRpc3QpIC8gc3ByZWFkKSA6IHZhbDtcbiAgfSk7XG5cbiAgY29uc3QgaW5pdGlhbFZhbHVlcyA9IFswLjUsIDAuNV07XG4gIGNvbnN0IGRhdGEgPSB7IHg6IHh2LCB5OiB5diB9O1xuXG4gIC8vIERlZmF1bHQgb3B0aW9ucyBmb3IgdGhlIGFsZ29yaXRobSAoZnJvbSBnaXRodWIgZXhhbXBsZSlcbiAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICBkYW1waW5nOiAxLjUsXG4gICAgaW5pdGlhbFZhbHVlcyxcbiAgICBncmFkaWVudERpZmZlcmVuY2U6IDEwZS0yLFxuICAgIG1heEl0ZXJhdGlvbnM6IDEwMCxcbiAgICBlcnJvclRvbGVyYW5jZTogMTBlLTMsXG4gIH07XG5cbiAgY29uc3QgeyBwYXJhbWV0ZXJWYWx1ZXMgfSA9IExNKGRhdGEsIGN1cnZlLCBvcHRpb25zKTtcbiAgY29uc3QgW2EsIGJdID0gcGFyYW1ldGVyVmFsdWVzIGFzIG51bWJlcltdO1xuICByZXR1cm4geyBhLCBiIH07XG59XG5cbi8qKlxuICogVW5kZXIgdGhlIGFzc3VtcHRpb24gb2YgY2F0ZWdvcmljYWwgZGlzdGFuY2UgZm9yIHRoZSBpbnRlcnNlY3RpbmdcbiAqIHNpbXBsaWNpYWwgc2V0IHBlcmZvcm0gYSBmYXN0IGludGVyc2VjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhc3RJbnRlcnNlY3Rpb24oXG4gIGdyYXBoOiBtYXRyaXguU3BhcnNlTWF0cml4LFxuICB0YXJnZXQ6IG51bWJlcltdLFxuICB1bmtub3duRGlzdCA9IDEuMCxcbiAgZmFyRGlzdCA9IDUuMFxuKSB7XG4gIHJldHVybiBncmFwaC5tYXAoKHZhbHVlLCByb3csIGNvbCkgPT4ge1xuICAgIGlmICh0YXJnZXRbcm93XSA9PT0gLTEgfHwgdGFyZ2V0W2NvbF0gPT09IC0xKSB7XG4gICAgICByZXR1cm4gdmFsdWUgKiBNYXRoLmV4cCgtdW5rbm93bkRpc3QpO1xuICAgIH0gZWxzZSBpZiAodGFyZ2V0W3Jvd10gIT09IHRhcmdldFtjb2xdKSB7XG4gICAgICByZXR1cm4gdmFsdWUgKiBNYXRoLmV4cCgtZmFyRGlzdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIFJlc2V0IHRoZSBsb2NhbCBjb25uZWN0aXZpdHkgcmVxdWlyZW1lbnQgLS0gZWFjaCBkYXRhIHNhbXBsZSBzaG91bGRcbiAqIGhhdmUgY29tcGxldGUgY29uZmlkZW5jZSBpbiBhdCBsZWFzdCBvbmUgMS1zaW1wbGV4IGluIHRoZSBzaW1wbGljaWFsIHNldC5cbiAqIFdlIGNhbiBlbmZvcmNlIHRoaXMgYnkgbG9jYWxseSByZXNjYWxpbmcgY29uZmlkZW5jZXMsIGFuZCB0aGVuIHJlbWVyZ2luZyB0aGVcbiAqIGRpZmZlcmVudCBsb2NhbCBzaW1wbGljaWFsIHNldHMgdG9nZXRoZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldExvY2FsQ29ubmVjdGl2aXR5KHNpbXBsaWNpYWxTZXQ6IG1hdHJpeC5TcGFyc2VNYXRyaXgpIHtcbiAgc2ltcGxpY2lhbFNldCA9IG1hdHJpeC5ub3JtYWxpemUoc2ltcGxpY2lhbFNldCwgbWF0cml4Lk5vcm1UeXBlLm1heCk7XG4gIGNvbnN0IHRyYW5zcG9zZSA9IG1hdHJpeC50cmFuc3Bvc2Uoc2ltcGxpY2lhbFNldCk7XG4gIGNvbnN0IHByb2RNYXRyaXggPSBtYXRyaXgucGFpcndpc2VNdWx0aXBseSh0cmFuc3Bvc2UsIHNpbXBsaWNpYWxTZXQpO1xuICBzaW1wbGljaWFsU2V0ID0gbWF0cml4LmFkZChcbiAgICBzaW1wbGljaWFsU2V0LFxuICAgIG1hdHJpeC5zdWJ0cmFjdCh0cmFuc3Bvc2UsIHByb2RNYXRyaXgpXG4gICk7XG4gIHJldHVybiBtYXRyaXguZWxpbWluYXRlWmVyb3Moc2ltcGxpY2lhbFNldCk7XG59XG5cbi8qKlxuICogR2l2ZW4gaW5kaWNlcyBhbmQgd2VpZ2h0cyBhbmQgYW4gb3JpZ2luYWwgZW1iZWRkaW5nc1xuICogaW5pdGlhbGl6ZSB0aGUgcG9zaXRpb25zIG9mIG5ldyBwb2ludHMgcmVsYXRpdmUgdG8gdGhlXG4gKiBpbmRpY2VzIGFuZCB3ZWlnaHRzIChvZiB0aGVpciBuZWlnaGJvcnMgaW4gdGhlIHNvdXJjZSBkYXRhKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRUcmFuc2Zvcm0oXG4gIGluZGljZXM6IG51bWJlcltdW10sXG4gIHdlaWdodHM6IG51bWJlcltdW10sXG4gIGVtYmVkZGluZzogVmVjdG9yc1xuKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHV0aWxzXG4gICAgLnplcm9zKGluZGljZXMubGVuZ3RoKVxuICAgIC5tYXAoeiA9PiB1dGlscy56ZXJvcyhlbWJlZGRpbmdbMF0ubGVuZ3RoKSk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRpY2VzWzBdLmxlbmd0aDsgaisrKSB7XG4gICAgICBmb3IgKGxldCBkID0gMDsgZCA8IGVtYmVkZGluZ1swXS5sZW5ndGg7IGQrKykge1xuICAgICAgICBjb25zdCBhID0gaW5kaWNlc1tpXVtqXTtcbiAgICAgICAgcmVzdWx0W2ldW2RdICs9IHdlaWdodHNbaV1bal0gKiBlbWJlZGRpbmdbYV1bZF07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG4iXX0=","/**\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 }\n for (let j = i + 1; j < leafArray[n].length; j++) {\n if (leafArray[n][j] < 0) {\n break;\n }\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 let p = Math.floor(candidateNeighbors[0][i][j]);\n if (p < 0 || utils.tauRand(random) < rho) {\n continue;\n }\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 }\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 }\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 }\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 }\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 }\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 }\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 (let tree of forest) {\n initFromTree(tree, data, queryPoints, results, random);\n }\n }\n return results;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm5fZGVzY2VudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm5uX2Rlc2NlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBR2pDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxVQUFzQixFQUFFLE1BQWdCO0lBQ3BFLE9BQU8sU0FBUyxTQUFTLENBQ3ZCLElBQVksRUFDWixTQUFrQixFQUNsQixVQUFrQixFQUNsQixNQUFNLEdBQUcsRUFBRSxFQUNYLGFBQWEsR0FBRyxFQUFFLEVBQ2xCLEtBQUssR0FBRyxLQUFLLEVBQ2IsR0FBRyxHQUFHLEdBQUcsRUFDVCxVQUFVLEdBQUcsSUFBSTtRQUVqQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzlCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUU1RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNwQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3RFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxF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QU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgSmF2YVNjcmlwdCByZWltcGxlbWVudGF0aW9uIG9mIFVNQVAgKG9yaWdpbmFsIGxpY2Vuc2UgYmVsb3cpLCBmcm9tXG4gKiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9sbWNpbm5lcy91bWFwLlxuICpcbiAqIEBhdXRob3IgYW5keWNvZW5lbkBnb29nbGUuY29tIChBbmR5IENvZW5lbilcbiAqL1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBCU0QgMy1DbGF1c2UgTGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNywgTGVsYW5kIE1jSW5uZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4gKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcbiAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXG4gKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcbiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuaW1wb3J0ICogYXMgaGVhcCBmcm9tICcuL2hlYXAnO1xuaW1wb3J0ICogYXMgbWF0cml4IGZyb20gJy4vbWF0cml4JztcbmltcG9ydCAqIGFzIHRyZWUgZnJvbSAnLi90cmVlJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgUmFuZG9tRm4sIFZlY3RvcnMsIERpc3RhbmNlRm4sIFZlY3RvciB9IGZyb20gJy4vdW1hcCc7XG5cbi8qKlxuICogQ3JlYXRlIGEgdmVyc2lvbiBvZiBuZWFyZXN0IG5laWdoYm9yIGRlc2NlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTk5EZXNjZW50KGRpc3RhbmNlRm46IERpc3RhbmNlRm4sIHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIG5ORGVzY2VudChcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgbGVhZkFycmF5OiBWZWN0b3JzLFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBuSXRlcnMgPSAxMCxcbiAgICBtYXhDYW5kaWRhdGVzID0gNTAsXG4gICAgZGVsdGEgPSAwLjAwMSxcbiAgICByaG8gPSAwLjUsXG4gICAgcnBUcmVlSW5pdCA9IHRydWVcbiAgKSB7XG4gICAgY29uc3QgblZlcnRpY2VzID0gZGF0YS5sZW5ndGg7XG4gICAgY29uc3QgY3VycmVudEdyYXBoID0gaGVhcC5tYWtlSGVhcChkYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSBoZWFwLnJlamVjdGlvblNhbXBsZShuTmVpZ2hib3JzLCBkYXRhLmxlbmd0aCwgcmFuZG9tKTtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2ldLCBkYXRhW2luZGljZXNbal1dKTtcblxuICAgICAgICBoZWFwLmhlYXBQdXNoKGN1cnJlbnRHcmFwaCwgaSwgZCwgaW5kaWNlc1tqXSwgMSk7XG4gICAgICAgIGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBpbmRpY2VzW2pdLCBkLCBpLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJwVHJlZUluaXQpIHtcbiAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgbGVhZkFycmF5Lmxlbmd0aDsgbisrKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVhZkFycmF5W25dLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGxlYWZBcnJheVtuXVtpXSA8IDApIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBsZWFmQXJyYXlbbl0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChsZWFmQXJyYXlbbl1bal0gPCAwKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtsZWFmQXJyYXlbbl1baV1dLCBkYXRhW2xlYWZBcnJheVtuXVtqXV0pO1xuICAgICAgICAgICAgaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIGxlYWZBcnJheVtuXVtpXSwgZCwgbGVhZkFycmF5W25dW2pdLCAxKTtcbiAgICAgICAgICAgIGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBsZWFmQXJyYXlbbl1bal0sIGQsIGxlYWZBcnJheVtuXVtpXSwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgbiA9IDA7IG4gPCBuSXRlcnM7IG4rKykge1xuICAgICAgY29uc3QgY2FuZGlkYXRlTmVpZ2hib3JzID0gaGVhcC5idWlsZENhbmRpZGF0ZXMoXG4gICAgICAgIGN1cnJlbnRHcmFwaCxcbiAgICAgICAgblZlcnRpY2VzLFxuICAgICAgICBuTmVpZ2hib3JzLFxuICAgICAgICBtYXhDYW5kaWRhdGVzLFxuICAgICAgICByYW5kb21cbiAgICAgICk7XG5cbiAgICAgIGxldCBjID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgblZlcnRpY2VzOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBtYXhDYW5kaWRhdGVzOyBqKyspIHtcbiAgICAgICAgICBsZXQgcCA9IE1hdGguZmxvb3IoY2FuZGlkYXRlTmVpZ2hib3JzWzBdW2ldW2pdKTtcbiAgICAgICAgICBpZiAocCA8IDAgfHwgdXRpbHMudGF1UmFuZChyYW5kb20pIDwgcmhvKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBtYXhDYW5kaWRhdGVzOyBrKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHEgPSBNYXRoLmZsb29yKGNhbmRpZGF0ZU5laWdoYm9yc1swXVtpXVtrXSk7XG4gICAgICAgICAgICBjb25zdCBjaiA9IGNhbmRpZGF0ZU5laWdoYm9yc1syXVtpXVtqXTtcbiAgICAgICAgICAgIGNvbnN0IGNrID0gY2FuZGlkYXRlTmVpZ2hib3JzWzJdW2ldW2tdO1xuICAgICAgICAgICAgaWYgKHEgPCAwIHx8ICghY2ogJiYgIWNrKSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtwXSwgZGF0YVtxXSk7XG4gICAgICAgICAgICBjICs9IGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBwLCBkLCBxLCAxKTtcbiAgICAgICAgICAgIGMgKz0gaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIHEsIGQsIHAsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGMgPD0gZGVsdGEgKiBuTmVpZ2hib3JzICogZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHNvcnRlZCA9IGhlYXAuZGVoZWFwU29ydChjdXJyZW50R3JhcGgpO1xuICAgIHJldHVybiBzb3J0ZWQ7XG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIEluaXRGcm9tUmFuZG9tRm4gPSAoXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgZGF0YTogVmVjdG9yLFxuICBxdWVyeVBvaW50czogVmVjdG9yLFxuICBfaGVhcDogaGVhcC5IZWFwLFxuICByYW5kb206IFJhbmRvbUZuXG4pID0+IHZvaWQ7XG5cbmV4cG9ydCB0eXBlIEluaXRGcm9tVHJlZUZuID0gKFxuICBfdHJlZTogdHJlZS5GbGF0VHJlZSxcbiAgZGF0YTogVmVjdG9yLFxuICBxdWVyeVBvaW50czogVmVjdG9yLFxuICBfaGVhcDogaGVhcC5IZWFwLFxuICByYW5kb206IFJhbmRvbUZuXG4pID0+IHZvaWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlSW5pdGlhbGl6YXRpb25zKGRpc3RhbmNlRm46IERpc3RhbmNlRm4pIHtcbiAgZnVuY3Rpb24gaW5pdEZyb21SYW5kb20oXG4gICAgbk5laWdoYm9yczogbnVtYmVyLFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBxdWVyeVBvaW50czogVmVjdG9yLFxuICAgIF9oZWFwOiBoZWFwLkhlYXAsXG4gICAgcmFuZG9tOiBSYW5kb21GblxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5UG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gdXRpbHMucmVqZWN0aW9uU2FtcGxlKG5OZWlnaGJvcnMsIGRhdGEubGVuZ3RoLCByYW5kb20pO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRpY2VzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChpbmRpY2VzW2pdIDwgMCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZUZuKGRhdGFbaW5kaWNlc1tqXV0sIHF1ZXJ5UG9pbnRzW2ldKTtcbiAgICAgICAgaGVhcC5oZWFwUHVzaChfaGVhcCwgaSwgZCwgaW5kaWNlc1tqXSwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdEZyb21UcmVlKFxuICAgIF90cmVlOiB0cmVlLkZsYXRUcmVlLFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBxdWVyeVBvaW50czogVmVjdG9yLFxuICAgIF9oZWFwOiBoZWFwLkhlYXAsXG4gICAgcmFuZG9tOiBSYW5kb21GblxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5UG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gdHJlZS5zZWFyY2hGbGF0VHJlZShxdWVyeVBvaW50c1tpXSwgX3RyZWUsIHJhbmRvbSk7XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoaW5kaWNlc1tqXSA8IDApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtpbmRpY2VzW2pdXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICBoZWFwLmhlYXBQdXNoKF9oZWFwLCBpLCBkLCBpbmRpY2VzW2pdLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIHsgaW5pdEZyb21SYW5kb20sIGluaXRGcm9tVHJlZSB9O1xufVxuXG5leHBvcnQgdHlwZSBTZWFyY2hGbiA9IChcbiAgZGF0YTogVmVjdG9yLFxuICBncmFwaDogbWF0cml4LlNwYXJzZU1hdHJpeCxcbiAgaW5pdGlhbGl6YXRpb246IGhlYXAuSGVhcCxcbiAgcXVlcnlQb2ludHM6IFZlY3RvclxuKSA9PiBoZWFwLkhlYXA7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlSW5pdGlhbGl6ZWROTlNlYXJjaChkaXN0YW5jZUZuOiBEaXN0YW5jZUZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBublNlYXJjaEZuKFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBncmFwaDogbWF0cml4LlNwYXJzZU1hdHJpeCxcbiAgICBpbml0aWFsaXphdGlvbjogaGVhcC5IZWFwLFxuICAgIHF1ZXJ5UG9pbnRzOiBWZWN0b3JcbiAgKSB7XG4gICAgY29uc3QgeyBpbmRpY2VzLCBpbmRwdHIgfSA9IG1hdHJpeC5nZXRDU1IoZ3JhcGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyeVBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdHJpZWQgPSBuZXcgU2V0KGluaXRpYWxpemF0aW9uWzBdW2ldKTtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIC8vIEZpbmQgc21hbGxlc3QgZmxhZ2dlZCB2ZXJ0ZXhcbiAgICAgICAgY29uc3QgdmVydGV4ID0gaGVhcC5zbWFsbGVzdEZsYWdnZWQoaW5pdGlhbGl6YXRpb24sIGkpO1xuXG4gICAgICAgIGlmICh2ZXJ0ZXggPT09IC0xKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IGluZGljZXMuc2xpY2UoaW5kcHRyW3ZlcnRleF0sIGluZHB0clt2ZXJ0ZXggKyAxXSk7XG4gICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBjYW5kaWRhdGUgPT09IHZlcnRleCB8fFxuICAgICAgICAgICAgY2FuZGlkYXRlID09PSAtMSB8fFxuICAgICAgICAgICAgdHJpZWQuaGFzKGNhbmRpZGF0ZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2NhbmRpZGF0ZV0sIHF1ZXJ5UG9pbnRzW2ldKTtcbiAgICAgICAgICBoZWFwLnVuY2hlY2tlZEhlYXBQdXNoKGluaXRpYWxpemF0aW9uLCBpLCBkLCBjYW5kaWRhdGUsIDEpO1xuICAgICAgICAgIHRyaWVkLmFkZChjYW5kaWRhdGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpbml0aWFsaXphdGlvbjtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVTZWFyY2goXG4gIGZvcmVzdDogdHJlZS5GbGF0VHJlZVtdLFxuICBkYXRhOiBWZWN0b3IsXG4gIHF1ZXJ5UG9pbnRzOiBWZWN0b3IsXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgaW5pdEZyb21SYW5kb206IEluaXRGcm9tUmFuZG9tRm4sXG4gIGluaXRGcm9tVHJlZTogSW5pdEZyb21UcmVlRm4sXG4gIHJhbmRvbTogUmFuZG9tRm5cbikge1xuICBjb25zdCByZXN1bHRzID0gaGVhcC5tYWtlSGVhcChxdWVyeVBvaW50cy5sZW5ndGgsIG5OZWlnaGJvcnMpO1xuICBpbml0RnJvbVJhbmRvbShuTmVpZ2hib3JzLCBkYXRhLCBxdWVyeVBvaW50cywgcmVzdWx0cywgcmFuZG9tKTtcbiAgaWYgKGZvcmVzdCkge1xuICAgIGZvciAobGV0IHRyZWUgb2YgZm9yZXN0KSB7XG4gICAgICBpbml0RnJvbVRyZWUodHJlZSwgZGF0YSwgcXVlcnlQb2ludHMsIHJlc3VsdHMsIHJhbmRvbSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuIl19","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","/* eslint-disable max-len */\nimport { TSNE } from '@keckelt/tsne';\nimport { Vector, } from '@datagrok-libraries/utils/src/type-declarations';\nimport { transposeMatrix, assert, } from '@datagrok-libraries/utils/src/vector-operations';\nimport { SPEBase, PSPEBase, OriginalSPE } from './spe';\nimport { Measure, AvailableMetrics, isBitArrayMetric } from './typed-metrics/typed-metrics';\nimport BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport { UMAP } from './umap';\nimport { DistanceMatrix, DistanceMatrixService, distanceMatrixProxy, dmLinearIndex } from './distance-matrix';\nimport { SparseMatrixService } from './distance-matrix/sparse-matrix-service';\nimport { getKnnGraph, getKnnGraphFromDM } from './umap/knnGraph';\nexport var DimReductionMethods;\n(function (DimReductionMethods) {\n DimReductionMethods[\"UMAP\"] = \"UMAP\";\n DimReductionMethods[\"T_SNE\"] = \"t-SNE\";\n})(DimReductionMethods || (DimReductionMethods = {}));\n/** Umap uses precalculated distance matrix to save time. though for too much data, memory becomes constraint.\n * if we have 100 000 rows, distance matrix will take ~10gb of memory and probably overflow.\n */\nexport const MAX_DISTANCE_MATRIX_ROWS = 20000;\nexport class UMAPOptions {\n constructor() {\n this.learningRate = { uiName: 'Learinig rate', value: 1, tooltip: 'The initial learning rate for the embedding optimization' };\n this.nComponents = { uiName: 'Components', value: 2, tooltip: 'The number of components (dimensions) to project the data to' };\n this.nEpochs = { uiName: 'Epochs', value: 0, tooltip: 'The number of epochs to optimize embeddings via SGD. Computed automatically if set to 0' };\n this.nNeighbors = { uiName: 'Neighbors', value: 15, tooltip: 'The number of nearest neighbors to construct the fuzzy manifold' };\n this.spread = { uiName: 'Spread', value: 1, tooltip: 'The effective scale of embedded points, used with min distance to control the clumped/dispersed nature of the embedding' };\n this.minDist = { uiName: 'Min distance', value: 0.1, tooltip: 'The effective minimum distance between embedded points, used with spread to control the clumped/dispersed nature of the embedding' };\n }\n ;\n}\nexport class TSNEOptions {\n constructor() {\n this.epsilon = { uiName: 'Epsilon', value: 10, tooltip: 'Epsilon is learning rate' };\n this.perplexity = { uiName: 'Perplexity', value: 30, tooltip: 'Roughly how many neighbors each point influences' };\n this.dim = { uiName: 'Dimensionality', value: 2, tooltip: 'Dimensionality of the embedding' };\n }\n ;\n}\n/** Abstract dimensionality reducer */\nclass Reducer {\n constructor(options) {\n this.data = options.data;\n }\n}\n/** t-SNE dimensionality reduction. */\nclass TSNEReducer extends Reducer {\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 this.reducer = new TSNE(options);\n this.iterations = options?.iterations ?? 100;\n this.distanceFname = options.distanceFname;\n this.distanceFn = options.distanceFn;\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(parallelDistanceWorkers) {\n const distance = parallelDistanceWorkers ? await (async () => {\n const matrixService = new DistanceMatrixService(true, false);\n try {\n const dist = await matrixService.calc(this.data, this.distanceFname);\n matrixService.terminate();\n return dist;\n }\n catch (e) {\n matrixService.terminate();\n throw e;\n }\n })() :\n (() => { const ret = DistanceMatrix.calc(this.data, (a, b) => this.distanceFn(a, b)); ret.normalize(); return ret.data; })();\n const matrixProxy = distanceMatrixProxy(distance, this.data.length);\n this.reducer.initDataDist(matrixProxy);\n for (let i = 0; i < this.iterations; ++i)\n this.reducer.step(); // every time you call this, solution gets better\n return { distance: distance, embedding: this.reducer.getSolution() };\n }\n}\n/**\n * Implements UMAP dimensionality reduction.\n *\n * @class UMAPReducer\n * @extends {Reducer}\n */\nclass UMAPReducer extends Reducer {\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 super(options);\n assert('distanceFname' in options);\n assert('distanceFn' in options);\n this.distanceFnArgs = options?.distanceFnArgs;\n this.distanceFn = options.distanceFn;\n this.usingSparseMatrix = !!options.usingSparseMatrix || !!options.sparseMatrix;\n this.sparseMatrixThreshold = options.sparseMatrixThreshold ?? 0.8;\n this.transferedSparseMatrix = options.sparseMatrix;\n this.progressFunc = options.progressFunc;\n this.distanceFname = options.distanceFname;\n this.dmIndexFunc = dmLinearIndex(this.data.length);\n //Umap uses vector indexing, so we need to create an array of vectors as indeces.\n this.vectors = new Array(this.data.length).fill(0).map((_, i) => i);\n this.usingDistanceMatrix = !((!options.preCalculateDistanceMatrix && this.data.length > MAX_DISTANCE_MATRIX_ROWS)\n || this.usingSparseMatrix);\n if (this.usingDistanceMatrix)\n options.distanceFn = this._encodedDistanceMatrix.bind(this);\n else if (this.usingSparseMatrix)\n options.distanceFn = this._encodedSparseMatrix.bind(this);\n else\n options.distanceFn = this._encodedDistance.bind(this);\n if (this.data.length < 15)\n options.nNeighbors = this.data.length - 1;\n this.reducer = new UMAP(options);\n // this.reducer.distanceFn = this._encodedDistance.bind(this);\n }\n /**\n * Custom distance wrapper to have numeric inputs instead of string ones.\n *\n * @protected\n * @param {number[]} a The first item.\n * @param {number[]} b The first item.\n * @return {number} Distance metric.\n * @memberof UMAPReducer\n */\n _encodedDistanceMatrix(a, b) {\n if (a === b)\n return 0;\n if (a > b)\n return this.distanceMatrix[this.dmIndexFunc(b, a)];\n return this.distanceMatrix[this.dmIndexFunc(a, b)];\n }\n _encodedSparseMatrix(a, b) {\n return this.sparseMatrix.get(a)?.get(b) ?? this.sparseMatrix.get(b)?.get(a) ?? 1;\n }\n _encodedDistance(a, b) {\n return this.distanceFn(this.data[a], this.data[b]);\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 if (this.usingDistanceMatrix) {\n this.distanceMatrix = parallelDistanceWorkers ? await (async () => {\n const matrixService = new DistanceMatrixService(true, false);\n try {\n const dist = await matrixService.calc(this.data, this.distanceFname, false, this.distanceFnArgs);\n matrixService.terminate();\n return dist;\n }\n catch (e) {\n matrixService.terminate();\n throw e;\n }\n })() :\n (() => {\n const ret = DistanceMatrix.calc(this.data, (a, b) => {\n const d = this.distanceFn(a, b);\n return d;\n });\n return ret.data;\n })();\n if (this.distanceMatrix && !isBitArrayMetric(this.distanceFname)) {\n const knnRes = getKnnGraphFromDM(this.distanceMatrix, this.reducer.neighbors, this.data.length);\n this.reducer.setPrecomputedKNN(knnRes.knnIndexes, knnRes.knnDistances);\n }\n }\n else if (this.usingSparseMatrix) {\n console.time('sparse matrix');\n let res = this.transferedSparseMatrix ??\n await new SparseMatrixService().calc(this.data, this.distanceFname, this.sparseMatrixThreshold, this.distanceFnArgs);\n console.timeEnd('sparse matrix');\n if (!isBitArrayMetric(this.distanceFname)) {\n const knnRes = getKnnGraph(res.i, res.j, res.distance, this.reducer.neighbors, this.data.length);\n this.reducer.setPrecomputedKNN(knnRes.knnIndexes, knnRes.knnDistances);\n }\n console.time('sparse matrix to map');\n this.sparseMatrix = new Map();\n for (let i = 0; i < res.i.length; ++i) {\n const first = res.i[i];\n const second = res.j[i];\n const distance = res.distance[i];\n if (!this.sparseMatrix.has(first))\n this.sparseMatrix.set(first, new Map());\n this.sparseMatrix.get(first).set(second, distance);\n }\n console.timeEnd('sparse matrix to map');\n res.distance = null;\n res.i = null;\n res.j = null;\n res = null;\n // needed so that garbage collector can free memory from distance matrix\n await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, 500);\n });\n }\n const embedding = await this.reducer.fitAsync(this.vectors, (epoc) => {\n if (this.progressFunc)\n this.progressFunc(epoc, this.reducer.getNEpochs(), this.reducer.getEmbedding());\n });\n function arrayCast2Coordinates(data) {\n return new Array(data.length).fill(0).map((_, i) => (Vector.from(data[i])));\n }\n return { embedding: arrayCast2Coordinates(embedding), ...(this.distanceMatrix ? { distance: this.distanceMatrix } : {}) };\n }\n}\n/**\n * Implements original SPE dimensionality reduction.\n *\n * @class SPEReducer\n * @extends {Reducer}\n */\nclass SPEReducer extends Reducer {\n /**\n * Creates an instance of SPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof SPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new SPEBase(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the original SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\n/**\n * Implements modified SPE dimensionality reduction.\n *\n * @class PSPEReducer\n * @extends {Reducer}\n */\nclass PSPEReducer extends Reducer {\n /**\n * Creates an instance of PSPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof PSPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new PSPEBase(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the modified SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\n/**\n * Implements original SPE dimensionality reduction.\n *\n * @class OriginalSPEReducer\n * @extends {Reducer}\n */\nclass OriginalSPEReducer extends Reducer {\n /**\n * Creates an instance of OriginalSPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof OriginalSPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new OriginalSPE(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the original SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\nconst AvailableReducers = {\n 'UMAP': UMAPReducer,\n 't-SNE': TSNEReducer,\n 'SPE': SPEReducer,\n 'pSPE': PSPEReducer,\n 'OriginalSPE': OriginalSPEReducer,\n};\n/**\n * Unified class implementing different dimensionality reduction methods.\n *\n * @export\n * @class DimensionalityReducer\n */\nexport class DimensionalityReducer {\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, metric, options) {\n const measure = new Measure(metric).getMeasure(options?.distanceFnArgs);\n let specOptions = {};\n if (isBitArrayMetric(metric)) {\n for (let i = 0; i < data.length; ++i)\n data[i] = new BitArray(data[i]._data, data[i]._length);\n }\n if (method == 'UMAP') {\n specOptions = {\n ...{ data: data },\n ...{ distanceFn: measure },\n ...{ distanceFname: metric },\n ...{ nEpochs: options?.cycles },\n ...options,\n };\n }\n else if (method == 't-SNE') {\n specOptions = {\n ...{ data: data },\n ...{ distanceFn: measure },\n ...{ distanceFname: metric },\n ...{ iterations: options?.cycles ?? undefined },\n ...options,\n };\n }\n else if (method == 'SPE') {\n specOptions = { ...{ data: data }, ...{ distance: measure }, distanceFunctionName: metric, ...options };\n }\n else {\n specOptions = { ...{ data: data }, ...{ distance: measure }, distanceFunctionName: metric, ...options };\n }\n this.reducer = new AvailableReducers[method](specOptions);\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, parallelDistanceWorkers) {\n if (this.reducer === undefined)\n throw new Error('Reducer was not defined.');\n let { embedding, distance } = await this.reducer.transform(parallelDistanceWorkers);\n if (transpose)\n embedding = transposeMatrix(embedding);\n return { distance: distance, embedding: 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlLWRpbWVuc2lvbmFsaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVkdWNlLWRpbWVuc2lvbmFsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRCQUE0QjtBQUM1QixPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ25DLE9BQU8sRUFHTCxNQUFNLEdBR1AsTUFBTSxpREFBaUQsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsZUFBZSxFQUNmLE1BQU0sR0FDUCxNQUFNLGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBQyxNQUFNLE9BQU8sQ0FBQztBQUNyRCxPQUFPLEVBQUMsT0FBTyxFQUFnQixnQkFBZ0IsRUFDN0MsZ0JBQWdCLEVBQXFCLE1BQU0sK0JBQStCLENBQUM7QUFDN0UsT0FBTyxRQUFRLE1BQU0seUNBQXlDLENBQUM7QUFDL0QsT0FBTyxFQUFpQixJQUFJLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFDNUMsT0FBTyxFQUFDLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUM1RyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSx5Q0FBeUMsQ0FBQztBQUM1RSxPQUFPLEVBQUMsV0FBVyxFQUFFLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFjL0QsTUFBTSxDQUFOLElBQVksbUJBR1g7QUFIRCxXQUFZLG1CQUFtQjtJQUM3QixvQ0FBYSxDQUFBO0lBQ2Isc0NBQWUsQ0FBQTtBQUNqQixDQUFDLEVBSFcsbUJBQW1CLEtBQW5CLG1CQUFtQixRQUc5QjtBQTZCRDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFHLEtBQUssQ0FBQztBQUU5QyxNQUFNLE9BQU8sV0FBVztJQVF0QjtRQVBBLGlCQUFZLEdBQXVCLEVBQUMsTUFBTSxFQUFFLGVBQWUsRUFBRSxL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SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sS0FBSyxnQkFBZ0I7UUFDekIsSUFBSSxHQUFHLEdBQWEsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUM5QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pDLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cbmltcG9ydCB7VFNORX0gZnJvbSAnQGtlY2tlbHQvdHNuZSc7XG5pbXBvcnQge1xuICBPcHRpb25zLFxuICBDb29yZGluYXRlcyxcbiAgVmVjdG9yLFxuICBWZWN0b3JzLFxuICBNYXRyaXgsXG59IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7XG4gIHRyYW5zcG9zZU1hdHJpeCxcbiAgYXNzZXJ0LFxufSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy92ZWN0b3Itb3BlcmF0aW9ucyc7XG5pbXBvcnQge1NQRUJhc2UsIFBTUEVCYXNlLCBPcmlnaW5hbFNQRX0gZnJvbSAnLi9zcGUnO1xuaW1wb3J0IHtNZWFzdXJlLCBLbm93bk1ldHJpY3MsIEF2YWlsYWJsZU1ldHJpY3MsXG4gIGlzQml0QXJyYXlNZXRyaWMsIEF2YWlsYWJsZURhdGFUeXBlc30gZnJvbSAnLi90eXBlZC1tZXRyaWNzL3R5cGVkLW1ldHJpY3MnO1xuaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQge1VNQVBQYXJhbWV0ZXJzLCBVTUFQfSBmcm9tICcuL3VtYXAnO1xuaW1wb3J0IHtEaXN0YW5jZU1hdHJpeCwgRGlzdGFuY2VNYXRyaXhTZXJ2aWNlLCBkaXN0YW5jZU1hdHJpeFByb3h5LCBkbUxpbmVhckluZGV4fSBmcm9tICcuL2Rpc3RhbmNlLW1hdHJpeCc7XG5pbXBvcnQge1NwYXJzZU1hdHJpeFNlcnZpY2V9IGZyb20gJy4vZGlzdGFuY2UtbWF0cml4L3NwYXJzZS1tYXRyaXgtc2VydmljZSc7XG5pbXBvcnQge2dldEtubkdyYXBoLCBnZXRLbm5HcmFwaEZyb21ETX0gZnJvbSAnLi91bWFwL2tubkdyYXBoJztcblxuZXhwb3J0IHR5cGUgU3BhcnNlTWF0cml4VHJhbnNmZXJUeXBlID0ge1xuICBpOiBJbnQzMkFycmF5LFxuICBqOiBJbnQzMkFycmF5LFxuICBkaXN0YW5jZTogRmxvYXQzMkFycmF5LFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdCB7XG4gIGRpc3RhbmNlPzogRmxvYXQzMkFycmF5O1xuICBzcGFyc2VNYXRyaXg/OiBNYXA8bnVtYmVyLCBNYXA8bnVtYmVyLCBudW1iZXI+PjtcbiAgZW1iZWRkaW5nOiBNYXRyaXg7XG59XG5cbmV4cG9ydCBlbnVtIERpbVJlZHVjdGlvbk1ldGhvZHN7XG4gIFVNQVAgPSAnVU1BUCcsXG4gIFRfU05FID0gJ3QtU05FJ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElVTUFQT3B0aW9ucyB7XG4gIGxlYXJuaW5nUmF0ZT86IG51bWJlcjtcbiAgbkNvbXBvbmVudHM/OiBudW1iZXI7XG4gIG5FcG9jaHM/OiBudW1iZXI7XG4gIG5OZWlnaGJvcnM/OiBudW1iZXI7XG4gIHNwcmVhZD86IG51bWJlcjtcbiAgbWluRGlzdD86IG51bWJlcjtcbiAgc3BhcnNlTWF0cml4VGhyZXNob2xkPzogbnVtYmVyO1xuICBwcmVDYWxjdWxhdGVEaXN0YW5jZU1hdHJpeD86IGJvb2xlYW47XG4gIHVzaW5nU3BhcnNlTWF0cml4PzogYm9vbGVhbjtcbiAgc3BhcnNlTWF0cml4PzogU3BhcnNlTWF0cml4VHJhbnNmZXJUeXBlO1xuICBwcm9ncmVzc0Z1bmM/OiAoZXBvYzogbnVtYmVyLCBlcG9jaHNMZW5ndGg6IG51bWJlciwgZW1iZWRkaW5nczogbnVtYmVyW11bXSkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVFNORU9wdGlvbnMge1xuICBlcHNpbG9uPzogbnVtYmVyO1xuICBwZXJwbGV4aXR5PzogbnVtYmVyO1xuICBkaW0/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSURpbVJlZHVjdGlvblBhcmFtIHtcbiAgdWlOYW1lOiBzdHJpbmc7XG4gIHZhbHVlOiBudW1iZXIgfCBudWxsO1xuICB0b29sdGlwOiBzdHJpbmc7XG4gIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xufVxuXG4vKiogVW1hcCB1c2VzIHByZWNhbGN1bGF0ZWQgZGlzdGFuY2UgbWF0cml4IHRvIHNhdmUgdGltZS4gdGhvdWdoIGZvciB0b28gbXVjaCBkYXRhLCBtZW1vcnkgYmVjb21lcyBjb25zdHJhaW50LlxuICogaWYgd2UgaGF2ZSAxMDAgMDAwIHJvd3MsIGRpc3RhbmNlIG1hdHJpeCB3aWxsIHRha2UgfjEwZ2Igb2YgbWVtb3J5IGFuZCBwcm9iYWJseSBvdmVyZmxvdy5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9ESVNUQU5DRV9NQVRSSVhfUk9XUyA9IDIwMDAwO1xuXG5leHBvcnQgY2xhc3MgVU1BUE9wdGlvbnMge1xuICBsZWFybmluZ1JhdGU6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdMZWFyaW5pZyByYXRlJywgdmFsdWU6IDEsIHRvb2x0aXA6ICdUaGUgaW5pdGlhbCBsZWFybmluZyByYXRlIGZvciB0aGUgZW1iZWRkaW5nIG9wdGltaXphdGlvbid9O1xuICBuQ29tcG9uZW50czogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ0NvbXBvbmVudHMnLCB2YWx1ZTogMiwgdG9vbHRpcDogJ1RoZSBudW1iZXIgb2YgY29tcG9uZW50cyAoZGltZW5zaW9ucykgdG8gcHJvamVjdCB0aGUgZGF0YSB0byd9O1xuICBuRXBvY2hzOiBJRGltUmVkdWN0aW9uUGFyYW0gPSB7dWlOYW1lOiAnRXBvY2hzJywgdmFsdWU6IDAsIHRvb2x0aXA6ICdUaGUgbnVtYmVyIG9mIGVwb2NocyB0byBvcHRpbWl6ZSBlbWJlZGRpbmdzIHZpYSBTR0QuIENvbXB1dGVkIGF1dG9tYXRpY2FsbHkgaWYgc2V0IHRvIDAnfTtcbiAgbk5laWdoYm9yczogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ05laWdoYm9ycycsIHZhbHVlOiAxNSwgdG9vbHRpcDogJ1RoZSBudW1iZXIgb2YgbmVhcmVzdCBuZWlnaGJvcnMgdG8gY29uc3RydWN0IHRoZSBmdXp6eSBtYW5pZm9sZCd9O1xuICBzcHJlYWQ6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdTcHJlYWQnLCB2YWx1ZTogMSwgdG9vbHRpcDogJ1RoZSBlZmZlY3RpdmUgc2NhbGUgb2YgZW1iZWRkZWQgcG9pbnRzLCB1c2VkIHdpdGggbWluIGRpc3RhbmNlIHRvIGNvbnRyb2wgdGhlIGNsdW1wZWQvZGlzcGVyc2VkIG5hdHVyZSBvZiB0aGUgZW1iZWRkaW5nJ307XG4gIG1pbkRpc3Q6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdNaW4gZGlzdGFuY2UnLCB2YWx1ZTogMC4xLCB0b29sdGlwOiAnVGhlIGVmZmVjdGl2ZSBtaW5pbXVtIGRpc3RhbmNlIGJldHdlZW4gZW1iZWRkZWQgcG9pbnRzLCB1c2VkIHdpdGggc3ByZWFkIHRvIGNvbnRyb2wgdGhlIGNsdW1wZWQvZGlzcGVyc2VkIG5hdHVyZSBvZiB0aGUgZW1iZWRkaW5nJ307XG5cbiAgY29uc3RydWN0b3IoKSB7fTtcbn1cblxuZXhwb3J0IGNsYXNzIFRTTkVPcHRpb25zIHtcbiAgZXBzaWxvbjogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ0Vwc2lsb24nLCB2YWx1ZTogMTAsIHRvb2x0aXA6ICdFcHNpbG9uIGlzIGxlYXJuaW5nIHJhdGUnfTtcbiAgcGVycGxleGl0eTogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ1BlcnBsZXhpdHknLCB2YWx1ZTogMzAsIHRvb2x0aXA6ICdSb3VnaGx5IGhvdyBtYW55IG5laWdoYm9ycyBlYWNoIHBvaW50IGluZmx1ZW5jZXMnfTtcbiAgZGltOiBJRGltUmVkdWN0aW9uUGFyYW0gPSB7dWlOYW1lOiAnRGltZW5zaW9uYWxpdHknLCB2YWx1ZTogMiwgdG9vbHRpcDogJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBlbWJlZGRpbmcnfTtcblxuICBjb25zdHJ1Y3RvcigpIHt9O1xufVxuXG4vKiogQWJzdHJhY3QgZGltZW5zaW9uYWxpdHkgcmVkdWNlciAqL1xuYWJzdHJhY3QgY2xhc3MgUmVkdWNlciB7XG4gIHByb3RlY3RlZCBkYXRhOiBWZWN0b3JzO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICB0aGlzLmRhdGEgPSBvcHRpb25zLmRhdGE7XG4gIH1cblxuICAvKiogRW1iZWRzIHRoZSBkYXRhIGdpdmVuIGludG8gdGhlIHR3by1kaW1lbnNpb25hbCBzcGFjZS5cbiAgICogQHJldHVybiB7YW55fSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBvZiB0aGlzIGVtYmVkZGluZyBhbmQgZGlzdGFuY2UgbWF0cml4IHdoZXJlIGFwcGxpY2FibGUuICovXG4gIGFic3RyYWN0IHRyYW5zZm9ybShwYXJhbGxlbERpc3RhbmNlV29ya2Vycz86IGJvb2xlYW4pOiBQcm9taXNlPElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdD47XG59XG5cbi8qKiB0LVNORSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24uICovXG5jbGFzcyBUU05FUmVkdWNlciBleHRlbmRzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgcmVkdWNlcjogVFNORTtcbiAgcHJvdGVjdGVkIGl0ZXJhdGlvbnM6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGRpc3RhbmNlRm5hbWU6IEtub3duTWV0cmljcztcbiAgcHJvdGVjdGVkIGRpc3RhbmNlRm46IChhOiBhbnksIGI6IGFueSkgPT4gbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFRTTkVSZWR1Y2VyLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQG1lbWJlcm9mIFRTTkVSZWR1Y2VyXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zKSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gICAgdGhpcy5yZWR1Y2VyID0gbmV3IFRTTkUob3B0aW9ucyk7XG4gICAgdGhpcy5pdGVyYXRpb25zID0gb3B0aW9ucz8uaXRlcmF0aW9ucyA/PyAxMDA7XG4gICAgdGhpcy5kaXN0YW5jZUZuYW1lID0gb3B0aW9ucy5kaXN0YW5jZUZuYW1lO1xuICAgIHRoaXMuZGlzdGFuY2VGbiA9IG9wdGlvbnMuZGlzdGFuY2VGbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIHQtU05FIG1ldGhvZC5cXFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtwYXJhbGxlbERpc3RhbmNlV29ya2Vyc10gV2hldGhlciB0byB1c2UgcGFyYWxsZWwgZGlzdGFuY2Ugd29ya2Vycy5cbiAgICogQHJldHVybiB7YW55fSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBvZiB0aGlzIGVtYmVkZGluZyBhbmQgZGlzdGFuY2UgbWF0cml4IHdoZXJlIGFwcGxpY2FibGUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzPzogYm9vbGVhbik6IFByb21pc2U8SVJlZHVjZURpbWVuc2lvbmFsaXR5UmVzdWx0PiB7XG4gICAgY29uc3QgZGlzdGFuY2UgPSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyA/IGF3YWl0IChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtYXRyaXhTZXJ2aWNlID0gbmV3IERpc3RhbmNlTWF0cml4U2VydmljZSh0cnVlLCBmYWxzZSk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkaXN0ID0gYXdhaXQgbWF0cml4U2VydmljZS5jYWxjKHRoaXMuZGF0YSwgdGhpcy5kaXN0YW5jZUZuYW1lKTtcbiAgICAgICAgbWF0cml4U2VydmljZS50ZXJtaW5hdGUoKTtcbiAgICAgICAgcmV0dXJuIGRpc3Q7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIG1hdHJpeFNlcnZpY2UudGVybWluYXRlKCk7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfSkoKSA6XG4gICAgICAoKCkgPT4geyBjb25zdCByZXQgPSBEaXN0YW5jZU1hdHJpeC5jYWxjKHRoaXMuZGF0YSwgKGEsIGIpID0+IHRoaXMuZGlzdGFuY2VGbihhLCBiKSk7IHJldC5ub3JtYWxpemUoKTsgcmV0dXJuIHJldC5kYXRhOyB9KSgpO1xuXG4gICAgY29uc3QgbWF0cml4UHJveHkgPSBkaXN0YW5jZU1hdHJpeFByb3h5KGRpc3RhbmNlLCB0aGlzLmRhdGEubGVuZ3RoKTtcbiAgICB0aGlzLnJlZHVjZXIuaW5pdERhdGFEaXN0KG1hdHJpeFByb3h5KTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5pdGVyYXRpb25zOyArK2kpXG4gICAgICB0aGlzLnJlZHVjZXIuc3RlcCgpOyAvLyBldmVyeSB0aW1lIHlvdSBjYWxsIHRoaXMsIHNvbHV0aW9uIGdldHMgYmV0dGVyXG5cbiAgICByZXR1cm4ge2Rpc3RhbmNlOiBkaXN0YW5jZSwgZW1iZWRkaW5nOiB0aGlzLnJlZHVjZXIuZ2V0U29sdXRpb24oKX07XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgVW1hcE9wdGlvbnMgPSBPcHRpb25zICYgVU1BUFBhcmFtZXRlcnMgJiB7XG4gIHByZUNhbGN1bGF0ZURpc3RhbmNlTWF0cml4PzogYm9vbGVhbixcbiAgdXNpbmdTcGFyc2VNYXRyaXg/OiBib29sZWFuLFxuICBzcGFyc2VNYXRyaXhUaHJlc2hvbGQ/OiBudW1iZXIsXG4gIHNwYXJzZU1hdHJpeD86IFNwYXJzZU1hdHJpeFRyYW5zZmVyVHlwZSxcbiAgcHJvZ3Jlc3NGdW5jPzogKGVwb2M6IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZ3M6IG51bWJlcltdW10pID0+IHZvaWQsXG59O1xuXG4vKipcbiAqIEltcGxlbWVudHMgVU1BUCBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24uXG4gKlxuICogQGNsYXNzIFVNQVBSZWR1Y2VyXG4gKiBAZXh0ZW5kcyB7UmVkdWNlcn1cbiAqL1xuY2xhc3MgVU1BUFJlZHVjZXIgZXh0ZW5kcyBSZWR1Y2VyIHtcbiAgcHJvdGVjdGVkIHJlZHVjZXI6IFVNQVA7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZuYW1lOiBLbm93bk1ldHJpY3M7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZuOiBGdW5jdGlvbjtcbiAgcHJvdGVjdGVkIHZlY3RvcnM6IG51bWJlcltdO1xuICBwcm90ZWN0ZWQgZGlzdGFuY2VNYXRyaXg/OiBGbG9hdDMyQXJyYXk7XG4gIHByb3RlY3RlZCB1c2luZ0Rpc3RhbmNlTWF0cml4OiBib29sZWFuO1xuICBwcm90ZWN0ZWQgc3BhcnNlTWF0cml4PzogTWFwPG51bWJlciwgTWFwPG51bWJlciwgbnVtYmVyPj47XG4gIHByb3RlY3RlZCBkbUluZGV4RnVuYzogKGk6IG51bWJlciwgajogbnVtYmVyKSA9PiBudW1iZXI7XG4gIHByb3RlY3RlZCB1c2luZ1NwYXJzZU1hdHJpeDogYm9vbGVhbjtcbiAgcHJvdGVjdGVkIHNwYXJzZU1hdHJpeFRocmVzaG9sZDogbnVtYmVyO1xuICBwcm90ZWN0ZWQgdHJhbnNmZXJlZFNwYXJzZU1hdHJpeD86IFNwYXJzZU1hdHJpeFRyYW5zZmVyVHlwZTtcbiAgcHJvdGVjdGVkIHByb2dyZXNzRnVuYz86IChlcG9jOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmdzOiBudW1iZXJbXVtdKSA9PiB2b2lkO1xuICBwcm90ZWN0ZWQgZGlzdGFuY2VGbkFyZ3M/OiB7W186IHN0cmluZ106IGFueX07XG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFVNQVBSZWR1Y2VyLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQG1lbWJlcm9mIFVNQVBSZWR1Y2VyXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBVbWFwT3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIGFzc2VydCgnZGlzdGFuY2VGbmFtZScgaW4gb3B0aW9ucyk7XG4gICAgYXNzZXJ0KCdkaXN0YW5jZUZuJyBpbiBvcHRpb25zKTtcbiAgICB0aGlzLmRpc3RhbmNlRm5BcmdzID0gb3B0aW9ucz8uZGlzdGFuY2VGbkFyZ3M7XG4gICAgdGhpcy5kaXN0YW5jZUZuID0gb3B0aW9ucy5kaXN0YW5jZUZuITtcbiAgICB0aGlzLnVzaW5nU3BhcnNlTWF0cml4ID0gISFvcHRpb25zLnVzaW5nU3BhcnNlTWF0cml4IHx8ICEhb3B0aW9ucy5zcGFyc2VNYXRyaXg7XG4gICAgdGhpcy5zcGFyc2VNYXRyaXhUaHJlc2hvbGQgPSBvcHRpb25zLnNwYXJzZU1hdHJpeFRocmVzaG9sZCA/PyAwLjg7XG4gICAgdGhpcy50cmFuc2ZlcmVkU3BhcnNlTWF0cml4ID0gb3B0aW9ucy5zcGFyc2VNYXRyaXg7XG4gICAgdGhpcy5wcm9ncmVzc0Z1bmMgPSBvcHRpb25zLnByb2dyZXNzRnVuYztcblxuICAgIHRoaXMuZGlzdGFuY2VGbmFtZSA9IG9wdGlvbnMuZGlzdGFuY2VGbmFtZSE7XG4gICAgdGhpcy5kbUluZGV4RnVuYyA9IGRtTGluZWFySW5kZXgodGhpcy5kYXRhLmxlbmd0aCk7XG4gICAgLy9VbWFwIHVzZXMgdmVjdG9yIGluZGV4aW5nLCBzbyB3ZSBuZWVkIHRvIGNyZWF0ZSBhbiBhcnJheSBvZiB2ZWN0b3JzIGFzIGluZGVjZXMuXG4gICAgdGhpcy52ZWN0b3JzID0gbmV3IEFycmF5KHRoaXMuZGF0YS5sZW5ndGgpLmZpbGwoMCkubWFwKChfLCBpKSA9PiBpKTtcbiAgICB0aGlzLnVzaW5nRGlzdGFuY2VNYXRyaXggPSAhKCghb3B0aW9ucy5wcmVDYWxjdWxhdGVEaXN0YW5jZU1hdHJpeCAmJiB0aGlzLmRhdGEubGVuZ3RoID4gTUFYX0RJU1RBTkNFX01BVFJJWF9ST1dTKVxuICAgICAgfHwgdGhpcy51c2luZ1NwYXJzZU1hdHJpeCk7XG4gICAgaWYgKHRoaXMudXNpbmdEaXN0YW5jZU1hdHJpeClcbiAgICAgIG9wdGlvbnMuZGlzdGFuY2VGbiA9IHRoaXMuX2VuY29kZWREaXN0YW5jZU1hdHJpeC5iaW5kKHRoaXMpO1xuICAgIGVsc2UgaWYgKHRoaXMudXNpbmdTcGFyc2VNYXRyaXgpXG4gICAgICBvcHRpb25zLmRpc3RhbmNlRm4gPSB0aGlzLl9lbmNvZGVkU3BhcnNlTWF0cml4LmJpbmQodGhpcyk7XG4gICAgZWxzZVxuICAgICAgb3B0aW9ucy5kaXN0YW5jZUZuID0gdGhpcy5fZW5jb2RlZERpc3RhbmNlLmJpbmQodGhpcyk7XG5cbiAgICBpZiAodGhpcy5kYXRhLmxlbmd0aCA8IDE1KVxuICAgICAgb3B0aW9ucy5uTmVpZ2hib3JzID0gdGhpcy5kYXRhLmxlbmd0aCAtIDE7XG4gICAgdGhpcy5yZWR1Y2VyID0gbmV3IFVNQVAob3B0aW9ucyk7XG4gICAgLy8gdGhpcy5yZWR1Y2VyLmRpc3RhbmNlRm4gPSB0aGlzLl9lbmNvZGVkRGlzdGFuY2UuYmluZCh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDdXN0b20gZGlzdGFuY2Ugd3JhcHBlciB0byBoYXZlIG51bWVyaWMgaW5wdXRzIGluc3RlYWQgb2Ygc3RyaW5nIG9uZXMuXG4gICAqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHBhcmFtIHtudW1iZXJbXX0gYSBUaGUgZmlyc3QgaXRlbS5cbiAgICogQHBhcmFtIHtudW1iZXJbXX0gYiBUaGUgZmlyc3QgaXRlbS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBtZXRyaWMuXG4gICAqIEBtZW1iZXJvZiBVTUFQUmVkdWNlclxuICAgKi9cbiAgcHJvdGVjdGVkIF9lbmNvZGVkRGlzdGFuY2VNYXRyaXgoYTogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChhID09PSBiKVxuICAgICAgcmV0dXJuIDA7XG4gICAgaWYgKGEgPiBiKVxuICAgICAgcmV0dXJuIHRoaXMuZGlzdGFuY2VNYXRyaXghW3RoaXMuZG1JbmRleEZ1bmMoYiwgYSldO1xuICAgIHJldHVybiB0aGlzLmRpc3RhbmNlTWF0cml4IVt0aGlzLmRtSW5kZXhGdW5jKGEsIGIpXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZW5jb2RlZFNwYXJzZU1hdHJpeChhOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc3BhcnNlTWF0cml4IS5nZXQoYSk/LmdldChiKSA/PyB0aGlzLnNwYXJzZU1hdHJpeCEuZ2V0KGIpPy5nZXQoYSkgPz8gMTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfZW5jb2RlZERpc3RhbmNlKGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5kaXN0YW5jZUZuKHRoaXMuZGF0YVthXSwgdGhpcy5kYXRhW2JdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIFVNQVAgbWV0aG9kLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtwYXJhbGxlbERpc3RhbmNlV29ya2Vyc10gV2hldGhlciB0byB1c2UgcGFyYWxsZWwgZGlzdGFuY2UgbWF0cml4IHdvcmtlcnMuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzPzogYm9vbGVhbik6IFByb21pc2U8SVJlZHVjZURpbWVuc2lvbmFsaXR5UmVzdWx0PiB7XG4gICAgaWYgKHRoaXMudXNpbmdEaXN0YW5jZU1hdHJpeCkge1xuICAgICAgdGhpcy5kaXN0YW5jZU1hdHJpeCA9IHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzID8gYXdhaXQgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgbWF0cml4U2VydmljZSA9IG5ldyBEaXN0YW5jZU1hdHJpeFNlcnZpY2UodHJ1ZSwgZmFsc2UpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGRpc3QgPSBhd2FpdCBtYXRyaXhTZXJ2aWNlLmNhbGModGhpcy5kYXRhLCB0aGlzLmRpc3RhbmNlRm5hbWUsIGZhbHNlLCB0aGlzLmRpc3RhbmNlRm5BcmdzKTtcbiAgICAgICAgICBtYXRyaXhTZXJ2aWNlLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgIHJldHVybiBkaXN0O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgbWF0cml4U2VydmljZS50ZXJtaW5hdGUoKTtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9KSgpIDpcbiAgICAgICAgKCgpID0+IHsgXG4gICAgICAgICAgY29uc3QgcmV0ID0gRGlzdGFuY2VNYXRyaXguY2FsYyh0aGlzLmRhdGEsIChhLCBiKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkID0gdGhpcy5kaXN0YW5jZUZuKGEsIGIpO1xuICAgICAgICAgICAgcmV0dXJuIGQ7fSk7IFxuICAgICAgICAgIHJldHVybiByZXQuZGF0YTsgXG4gICAgICAgIH0pKCk7XG4gICAgICAgIGlmICh0aGlzLmRpc3RhbmNlTWF0cml4ICYmICFpc0JpdEFycmF5TWV0cmljKHRoaXMuZGlzdGFuY2VGbmFtZSkpIHtcbiAgICAgICAgICBjb25zdCBrbm5SZXMgPSBnZXRLbm5HcmFwaEZyb21ETSh0aGlzLmRpc3RhbmNlTWF0cml4LCB0aGlzLnJlZHVjZXIubmVpZ2hib3JzLCB0aGlzLmRhdGEubGVuZ3RoKTtcbiAgICAgICAgICB0aGlzLnJlZHVjZXIuc2V0UHJlY29tcHV0ZWRLTk4oa25uUmVzLmtubkluZGV4ZXMsIGtublJlcy5rbm5EaXN0YW5jZXMpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgIH0gZWxzZSBpZiAodGhpcy51c2luZ1NwYXJzZU1hdHJpeCkge1xuICAgICAgICAgIGNvbnNvbGUudGltZSgnc3BhcnNlIG1hdHJpeCcpO1xuICAgICAgICAgIGxldCByZXM6IHtbSyBpbiBrZXlvZiBTcGFyc2VNYXRyaXhUcmFuc2ZlclR5cGVdOiBTcGFyc2VNYXRyaXhUcmFuc2ZlclR5cGVbS10gfCBudWxsfSB8IG51bGxcbiAgICAgICAgICAgID0gdGhpcy50cmFuc2ZlcmVkU3BhcnNlTWF0cml4ID8/XG4gICAgICAgICAgICAgIGF3YWl0IG5ldyBTcGFyc2VNYXRyaXhTZXJ2aWNlKCkuY2FsYyh0aGlzLmRhdGEsIHRoaXMuZGlzdGFuY2VGbmFtZSwgdGhpcy5zcGFyc2VNYXRyaXhUaHJlc2hvbGQsIHRoaXMuZGlzdGFuY2VGbkFyZ3MpO1xuICAgICAgICAgIGNvbnNvbGUudGltZUVuZCgnc3BhcnNlIG1hdHJpeCcpO1xuICAgICAgICAgIGlmICghaXNCaXRBcnJheU1ldHJpYyh0aGlzLmRpc3RhbmNlRm5hbWUpKSB7XG4gICAgICAgICAgICBjb25zdCBrbm5SZXMgPSBnZXRLbm5HcmFwaChyZXMuaSEsIHJlcy5qISwgcmVzLmRpc3RhbmNlISwgdGhpcy5yZWR1Y2VyLm5laWdoYm9ycywgdGhpcy5kYXRhLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIHRoaXMucmVkdWNlci5zZXRQcmVjb21wdXRlZEtOTihrbm5SZXMua25uSW5kZXhlcywga25uUmVzLmtubkRpc3RhbmNlcyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnNvbGUudGltZSgnc3BhcnNlIG1hdHJpeCB0byBtYXAnKVxuICAgICAgICAgIHRoaXMuc3BhcnNlTWF0cml4ID0gbmV3IE1hcDxudW1iZXIsIE1hcDxudW1iZXIsIG51bWJlcj4+KCk7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXMuaSEubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0ID0gcmVzLmkhW2ldO1xuICAgICAgICAgICAgY29uc3Qgc2Vjb25kID0gcmVzLmohW2ldO1xuICAgICAgICAgICAgY29uc3QgZGlzdGFuY2UgPSByZXMuZGlzdGFuY2UhW2ldO1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNwYXJzZU1hdHJpeC5oYXMoZmlyc3QpKVxuICAgICAgICAgICAgICB0aGlzLnNwYXJzZU1hdHJpeC5zZXQoZmlyc3QsIG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCkpO1xuICAgICAgICAgICAgdGhpcy5zcGFyc2VNYXRyaXguZ2V0KGZpcnN0KSEuc2V0KHNlY29uZCwgZGlzdGFuY2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zb2xlLnRpbWVFbmQoJ3NwYXJzZSBtYXRyaXggdG8gbWFwJyk7XG4gICAgICAgICAgcmVzLmRpc3RhbmNlID0gbnVsbDtcbiAgICAgICAgICByZXMuaSA9IG51bGw7XG4gICAgICAgICAgcmVzLmogPSBudWxsO1xuICAgICAgICAgIHJlcyA9IG51bGw7XG4gICAgICAgICAgLy8gbmVlZGVkIHNvIHRoYXQgZ2FyYmFnZSBjb2xsZWN0b3IgY2FuIGZyZWUgbWVtb3J5IGZyb20gZGlzdGFuY2UgbWF0cml4XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9LCA1MDApO1xuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgIFxuICAgIGNvbnN0IGVtYmVkZGluZyA9IGF3YWl0IHRoaXMucmVkdWNlci5maXRBc3luYyh0aGlzLnZlY3RvcnMsIChlcG9jKSA9PiB7XG4gICAgICBpZiAodGhpcy5wcm9ncmVzc0Z1bmMpXG4gICAgICAgIHRoaXMucHJvZ3Jlc3NGdW5jKGVwb2MsIHRoaXMucmVkdWNlci5nZXRORXBvY2hzKCksIHRoaXMucmVkdWNlci5nZXRFbWJlZGRpbmcoKSk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBhcnJheUNhc3QyQ29vcmRpbmF0ZXMoZGF0YTogbnVtYmVyW11bXSk6IENvb3JkaW5hdGVzIHtcbiAgICAgIHJldHVybiBuZXcgQXJyYXkoZGF0YS5sZW5ndGgpLmZpbGwoMCkubWFwKChfLCBpKSA9PiAoVmVjdG9yLmZyb20oZGF0YVtpXSkpKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge2VtYmVkZGluZzogYXJyYXlDYXN0MkNvb3JkaW5hdGVzKGVtYmVkZGluZyksIC4uLih0aGlzLmRpc3RhbmNlTWF0cml4ID8ge2Rpc3RhbmNlOiB0aGlzLmRpc3RhbmNlTWF0cml4fSA6IHt9KX07XG4gIH1cbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRzIG9yaWdpbmFsIFNQRSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24uXG4gKlxuICogQGNsYXNzIFNQRVJlZHVjZXJcbiAqIEBleHRlbmRzIHtSZWR1Y2VyfVxuICovXG5jbGFzcyBTUEVSZWR1Y2VyIGV4dGVuZHMgUmVkdWNlciB7XG4gIHByb3RlY3RlZCByZWR1Y2VyOiBTUEVCYXNlO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFNQRVJlZHVjZXIuXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgKiBAbWVtYmVyb2YgU1BFUmVkdWNlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMucmVkdWNlciA9IG5ldyBTUEVCYXNlKG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgdGhlIG9yaWdpbmFsIFNQRSBtZXRob2QuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHRyYW5zZm9ybSgpOiBQcm9taXNlPElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdD4ge1xuICAgIGNvbnN0IGVtYiA9IGF3YWl0IHRoaXMucmVkdWNlci5lbWJlZCh0aGlzLmRhdGEpO1xuICAgIHJldHVybiB7ZGlzdGFuY2U6IHRoaXMucmVkdWNlci5kaXN0YW5jZSwgZW1iZWRkaW5nOiBlbWJ9O1xuICB9XG59XG5cbi8qKlxuICogSW1wbGVtZW50cyBtb2RpZmllZCBTUEUgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uLlxuICpcbiAqIEBjbGFzcyBQU1BFUmVkdWNlclxuICogQGV4dGVuZHMge1JlZHVjZXJ9XG4gKi9cbmNsYXNzIFBTUEVSZWR1Y2VyIGV4dGVuZHMgUmVkdWNlciB7XG4gIHByb3RlY3RlZCByZWR1Y2VyOiBQU1BFQmFzZTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBQU1BFUmVkdWNlci5cbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgY29uc3RydWN0b3IuXG4gICAqIEBtZW1iZXJvZiBQU1BFUmVkdWNlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMucmVkdWNlciA9IG5ldyBQU1BFQmFzZShvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIHRoZSBtb2RpZmllZCBTUEUgbWV0aG9kLlxuICAgKiBAcmV0dXJuIHthbnl9IENhcnRlc2lhbiBjb29yZGluYXRlIG9mIHRoaXMgZW1iZWRkaW5nIGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0oKTogUHJvbWlzZTxJUmVkdWNlRGltZW5zaW9uYWxpdHlSZXN1bHQ+IHtcbiAgICBjb25zdCBlbWIgPSBhd2FpdCB0aGlzLnJlZHVjZXIuZW1iZWQodGhpcy5kYXRhKTtcbiAgICByZXR1cm4ge2Rpc3RhbmNlOiB0aGlzLnJlZHVjZXIuZGlzdGFuY2UsIGVtYmVkZGluZzogZW1ifTtcbiAgfVxufVxuXG4vKipcbiAqIEltcGxlbWVudHMgb3JpZ2luYWwgU1BFIGRpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbi5cbiAqXG4gKiBAY2xhc3MgT3JpZ2luYWxTUEVSZWR1Y2VyXG4gKiBAZXh0ZW5kcyB7UmVkdWNlcn1cbiAqL1xuY2xhc3MgT3JpZ2luYWxTUEVSZWR1Y2VyIGV4dGVuZHMgUmVkdWNlciB7XG4gIHByb3RlY3RlZCByZWR1Y2VyOiBPcmlnaW5hbFNQRTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBPcmlnaW5hbFNQRVJlZHVjZXIuXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgKiBAbWVtYmVyb2YgT3JpZ2luYWxTUEVSZWR1Y2VyXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zKSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gICAgdGhpcy5yZWR1Y2VyID0gbmV3IE9yaWdpbmFsU1BFKG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgdGhlIG9yaWdpbmFsIFNQRSBtZXRob2QuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHRyYW5zZm9ybSgpOiBQcm9taXNlPElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdD4ge1xuICAgIGNvbnN0IGVtYiA9IGF3YWl0IHRoaXMucmVkdWNlci5lbWJlZCh0aGlzLmRhdGEpO1xuICAgIHJldHVybiB7ZGlzdGFuY2U6IHRoaXMucmVkdWNlci5kaXN0YW5jZSwgZW1iZWRkaW5nOiBlbWJ9O1xuICB9XG59XG5cbmNvbnN0IEF2YWlsYWJsZVJlZHVjZXJzID0ge1xuICAnVU1BUCc6IFVNQVBSZWR1Y2VyLFxuICAndC1TTkUnOiBUU05FUmVkdWNlcixcbiAgJ1NQRSc6IFNQRVJlZHVjZXIsXG4gICdwU1BFJzogUFNQRVJlZHVjZXIsXG4gICdPcmlnaW5hbFNQRSc6IE9yaWdpbmFsU1BFUmVkdWNlcixcbn07XG5cbmV4cG9ydCB0eXBlIEtub3duTWV0aG9kcyA9IGtleW9mIHR5cGVvZiBBdmFpbGFibGVSZWR1Y2VycztcblxuLyoqXG4gKiBVbmlmaWVkIGNsYXNzIGltcGxlbWVudGluZyBkaWZmZXJlbnQgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uIG1ldGhvZHMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIERpbWVuc2lvbmFsaXR5UmVkdWNlclxuICovXG5leHBvcnQgY2xhc3MgRGltZW5zaW9uYWxpdHlSZWR1Y2VyIHtcbiAgcHJpdmF0ZSByZWR1Y2VyOiBSZWR1Y2VyIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIERpbWVuc2lvbmFsaXR5UmVkdWNlci5cbiAgICogQHBhcmFtIHthbnlbXX0gZGF0YSBWZWN0b3JzIHRvIGVtYmVkLlxuICAgKiBAcGFyYW0ge0tub3duTWV0aG9kc30gbWV0aG9kIEVtYmVkZGluZyBtZXRob2QgdG8gYmUgYXBwbGllZFxuICAgKiBAcGFyYW0ge0tub3duTWV0cmljc30gbWV0cmljIERpc3RhbmNlIG1ldHJpYyB0byBiZSBjb21wdXRlZCBiZXR3ZWVuIGVhY2ggb2YgdGhlIHZlY3RvcnMuXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gW29wdGlvbnNdIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgaW1wbGVtZW50aW5nIGVtYmVkZGVycy5cbiAgICogQG1lbWJlcm9mIERpbWVuc2lvbmFsaXR5UmVkdWNlclxuICAgKi9cbiAgY29uc3RydWN0b3IoZGF0YTogYW55W10sIG1ldGhvZDogS25vd25NZXRob2RzLCBtZXRyaWM6IEtub3duTWV0cmljcywgb3B0aW9ucz86IE9wdGlvbnMpIHtcbiAgICBjb25zdCBtZWFzdXJlID0gbmV3IE1lYXN1cmUobWV0cmljKS5nZXRNZWFzdXJlKG9wdGlvbnM/LmRpc3RhbmNlRm5BcmdzKTtcbiAgICBsZXQgc3BlY09wdGlvbnMgPSB7fTtcblxuICAgIGlmIChpc0JpdEFycmF5TWV0cmljKG1ldHJpYykpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgZGF0YVtpXSA9IG5ldyBCaXRBcnJheShkYXRhW2ldLl9kYXRhLCBkYXRhW2ldLl9sZW5ndGgpO1xuICAgIH1cblxuICAgIGlmIChtZXRob2QgPT0gJ1VNQVAnKSB7XG4gICAgICBzcGVjT3B0aW9ucyA9IHtcbiAgICAgICAgLi4ue2RhdGE6IGRhdGF9LFxuICAgICAgICAuLi57ZGlzdGFuY2VGbjogbWVhc3VyZX0sXG4gICAgICAgIC4uLntkaXN0YW5jZUZuYW1lOiBtZXRyaWN9LFxuICAgICAgICAuLi57bkVwb2Noczogb3B0aW9ucz8uY3ljbGVzfSxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChtZXRob2QgPT0gJ3QtU05FJykge1xuICAgICAgc3BlY09wdGlvbnMgPSB7XG4gICAgICAgIC4uLntkYXRhOiBkYXRhfSxcbiAgICAgICAgLi4ue2Rpc3RhbmNlRm46IG1lYXN1cmV9LFxuICAgICAgICAuLi57ZGlzdGFuY2VGbmFtZTogbWV0cmljfSxcbiAgICAgICAgLi4ue2l0ZXJhdGlvbnM6IG9wdGlvbnM/LmN5Y2xlcyA/PyB1bmRlZmluZWR9LFxuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PSAnU1BFJykge1xuICAgICAgc3BlY09wdGlvbnMgPSB7Li4ue2RhdGE6IGRhdGF9LCAuLi57ZGlzdGFuY2U6IG1lYXN1cmV9LCBkaXN0YW5jZUZ1bmN0aW9uTmFtZTogbWV0cmljLCAuLi5vcHRpb25zfTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3BlY09wdGlvbnMgPSB7Li4ue2RhdGE6IGRhdGF9LCAuLi57ZGlzdGFuY2U6IG1lYXN1cmV9LCBkaXN0YW5jZUZ1bmN0aW9uTmFtZTogbWV0cmljLCAuLi5vcHRpb25zfTtcbiAgICB9XG4gICAgdGhpcy5yZWR1Y2VyID0gbmV3IEF2YWlsYWJsZVJlZHVjZXJzW21ldGhvZF0oc3BlY09wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgdGhlIGNob3NlbiBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdHJhbnNwb3NlIFdoZXRoZXIgdG8gdHJhbnNmb3JtIGNvb3JkaW5hdGVzIHRvIGhhdmUgY29sdW1ucy1maXJzdCBvcmllbnRhdGlvbi5cbiAgICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSBjb21wdXRhdGlvbi5cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBlbWJlZGRpbmcgbWV0aG9kIHdhcyBub3QgZm91bmQuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLlxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKHRyYW5zcG9zZTogYm9vbGVhbiA9IGZhbHNlLCBwYXJhbGxlbERpc3RhbmNlV29ya2Vycz86IGJvb2xlYW4pOiBQcm9taXNlPElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdD4ge1xuICAgIGlmICh0aGlzLnJlZHVjZXIgPT09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBFcnJvcignUmVkdWNlciB3YXMgbm90IGRlZmluZWQuJyk7XG5cbiAgICBsZXQge2VtYmVkZGluZywgZGlzdGFuY2V9ID0gYXdhaXQgdGhpcy5yZWR1Y2VyLnRyYW5zZm9ybShwYXJhbGxlbERpc3RhbmNlV29ya2Vycyk7XG5cbiAgICBpZiAodHJhbnNwb3NlKVxuICAgICAgZW1iZWRkaW5nID0gdHJhbnNwb3NlTWF0cml4KGVtYmVkZGluZyk7XG5cbiAgICByZXR1cm4ge2Rpc3RhbmNlOiBkaXN0YW5jZSwgZW1iZWRkaW5nOiBlbWJlZGRpbmd9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgbWV0cmljcyBhdmFpbGFibGUgYnkgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtIHtBdmFpbGFibGVEYXRhVHlwZXN9IHR5cGVOYW1lIHR5cGUgbmFtZVxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gTWV0cmljIG5hbWVzIHdoaWNoIGV4cGVjdHMgdGhlIGdpdmVuIGRhdGEgdHlwZVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICBzdGF0aWMgYXZhaWxhYmxlTWV0cmljc0J5VHlwZSh0eXBlTmFtZTogQXZhaWxhYmxlRGF0YVR5cGVzKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3NbdHlwZU5hbWVdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGRpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbiBtZXRob2RzIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHJlYWRvbmx5XG4gICAqIEBtZW1iZXJvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAgICovXG4gIHN0YXRpYyBnZXQgYXZhaWxhYmxlTWV0aG9kcygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoQXZhaWxhYmxlUmVkdWNlcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgbWV0cmljcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEByZWFkb25seVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICBzdGF0aWMgZ2V0IGF2YWlsYWJsZU1ldHJpY3MoKSB7XG4gICAgbGV0IGFuczogc3RyaW5nW10gPSBbXTtcbiAgICBPYmplY3QudmFsdWVzKEF2YWlsYWJsZU1ldHJpY3MpLmZvckVhY2goKG9iaikgPT4ge1xuICAgICAgY29uc3QgYXJyYXkgPSBPYmplY3QudmFsdWVzKG9iaik7XG4gICAgICBhbnMgPSBbLi4uYW5zLCAuLi5hcnJheV07XG4gICAgfSk7XG4gICAgcmV0dXJuIGFucztcbiAgfVxufVxuIl19","import { isNil } from './utils';\n/** Distance matrix class compatible with data structure of scipy.spatial.distance.pdist */\nexport class DistanceMatrix {\n get data() { return this._data; }\n get size() { return this._size; }\n /**\n * @param {Float32Array} data Distance data\n * @param {number} size Number of original observations\n */\n constructor(data, size) {\n if (size == undefined) {\n if (data == undefined)\n throw new Error('Arguments error: data or size is required.');\n this._data = data;\n this._size = (1 + Math.sqrt(1 + 4 * 2 * this._data.length)) / 2;\n if (this._size != Math.floor(this._size))\n throw new Error(`Invalid data length ${this._data.length} leads to non integer size ${this._size}`);\n }\n else {\n this._size = size;\n const dataLength = size * (size - 1) / 2;\n if (data) {\n if (data.length != dataLength)\n throw new Error(`Invalid data length. Observations size ${size} requires data length ${dataLength}.`);\n this._data = data;\n }\n else {\n this._data = new Float32Array(dataLength);\n }\n }\n }\n _linearizeIJ(i, j) {\n if (!(i < j))\n throw new Error('i must be less than j');\n return this._size * i + j - Math.floor(((i + 2) * (i + 1)) / 2);\n }\n get(i, j) {\n if (i == j)\n return 0;\n else if (i < j)\n return this._data[this._linearizeIJ(i, j)];\n else\n return this._data[this._linearizeIJ(j, i)];\n }\n set(i, j, value) {\n this._data[this._linearizeIJ(i, j)] = value;\n }\n static calc(list, method) {\n const size = list.length;\n const res = new DistanceMatrix(undefined, size);\n for (let i = 0; i < size; i++) {\n for (let j = i + 1; j < size; j++) {\n // if any of the values is null, set distance to 1\n res.set(i, j, !isNil(list[i]) && !isNil(list[j]) ? method(list[i], list[j]) : 1);\n }\n }\n return res;\n }\n // squares each value in matrix in place\n square() {\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = this._data[i] ** 2;\n }\n // adds another matrix to this one in place\n add(other) {\n if (this._size !== other._size)\n throw new Error(`Matrices must have the same size. This size: ${this._size}, other size: ${other._size}`);\n for (let i = 0; i < this._data.length; i++)\n this._data[i] += other._data[i];\n }\n // square root each value in matrix in place\n sqrt() {\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = Math.sqrt(this._data[i]);\n }\n //normilze distance matrix in place\n normalize() {\n let min = 0;\n let max = this._data[0];\n for (let i = 0; i < this._data.length; i++) {\n if (this._data[i] < min)\n min = this._data[i];\n if (this._data[i] > max)\n max = this._data[i];\n }\n const range = max - min;\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = range === 0 ? this._data[i] - min : (this._data[i] - min) / (max - min);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWF0cml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdGFuY2UtbWF0cml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFFOUIsMkZBQTJGO0FBQzNGLE1BQU0sT0FBTyxjQUFjO0lBSXpCLElBQUksSUFBSSxLQUFtQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBRS9DLElBQUksSUFBSSxLQUFhLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFekM7OztPQUdHO0lBQ0gsWUFBWSxJQUFtQixFQUFFLElBQWE7UUFDNUMsSUFBSSxJQUFJLElBQUksU0FBUyxFQUFFO1lBQ3JCLElBQUksSUFBSSxJQUFJLFNBQVM7Z0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1lBRXJGLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSyxDQUFDO1lBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hFLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSw4QkFBOEIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDdkc7YUFBTTtZQUNMLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ2xCLE1BQU0sVUFBVSxHQUFXLElBQUksR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7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QjtRQUNELE1BQU0sS0FBSyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDeEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtZQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDNUYsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyB1aSBmcm9tICdkYXRhZ3Jvay1hcGkvdWknO1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCB7aXNOaWx9IGZyb20gJy4vdXRpbHMnO1xuXG4vKiogRGlzdGFuY2UgbWF0cml4IGNsYXNzIGNvbXBhdGlibGUgd2l0aCBkYXRhIHN0cnVjdHVyZSBvZiBzY2lweS5zcGF0aWFsLmRpc3RhbmNlLnBkaXN0ICovXG5leHBvcnQgY2xhc3MgRGlzdGFuY2VNYXRyaXgge1xuICBfZGF0YTogRmxvYXQzMkFycmF5O1xuICBfc2l6ZTogbnVtYmVyO1xuXG4gIGdldCBkYXRhKCk6IEZsb2F0MzJBcnJheSB7IHJldHVybiB0aGlzLl9kYXRhOyB9XG5cbiAgZ2V0IHNpemUoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3NpemU7IH1cblxuICAvKipcbiAgICogQHBhcmFtIHtGbG9hdDMyQXJyYXl9IGRhdGEgRGlzdGFuY2UgZGF0YVxuICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBOdW1iZXIgb2Ygb3JpZ2luYWwgb2JzZXJ2YXRpb25zXG4gICAqL1xuICBjb25zdHJ1Y3RvcihkYXRhPzogRmxvYXQzMkFycmF5LCBzaXplPzogbnVtYmVyKSB7XG4gICAgaWYgKHNpemUgPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoZGF0YSA9PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcignQXJndW1lbnRzIGVycm9yOiBkYXRhIG9yIHNpemUgaXMgcmVxdWlyZWQuJyk7XG5cbiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhITtcbiAgICAgIHRoaXMuX3NpemUgPSAoMSArIE1hdGguc3FydCgxICsgNCAqIDIgKiB0aGlzLl9kYXRhLmxlbmd0aCkpIC8gMjtcbiAgICAgIGlmICh0aGlzLl9zaXplICE9IE1hdGguZmxvb3IodGhpcy5fc2l6ZSkpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkYXRhIGxlbmd0aCAke3RoaXMuX2RhdGEubGVuZ3RofSBsZWFkcyB0byBub24gaW50ZWdlciBzaXplICR7dGhpcy5fc2l6ZX1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fc2l6ZSA9IHNpemU7XG4gICAgICBjb25zdCBkYXRhTGVuZ3RoOiBudW1iZXIgPSBzaXplICogKHNpemUgLSAxKSAvIDI7XG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gZGF0YUxlbmd0aClcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YSBsZW5ndGguIE9ic2VydmF0aW9ucyBzaXplICR7c2l6ZX0gcmVxdWlyZXMgZGF0YSBsZW5ndGggJHtkYXRhTGVuZ3RofS5gKTtcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9kYXRhID0gbmV3IEZsb2F0MzJBcnJheShkYXRhTGVuZ3RoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9saW5lYXJpemVJSihpOiBudW1iZXIsIGo6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCEoaSA8IGopKSB0aHJvdyBuZXcgRXJyb3IoJ2kgbXVzdCBiZSBsZXNzIHRoYW4gaicpO1xuICAgIHJldHVybiB0aGlzLl9zaXplICogaSArIGogLSBNYXRoLmZsb29yKCgoaSArIDIpICogKGkgKyAxKSkgLyAyKTtcbiAgfVxuXG4gIGdldChpOiBudW1iZXIsIGo6IG51bWJlcikge1xuICAgIGlmIChpID09IGopXG4gICAgICByZXR1cm4gMDtcbiAgICBlbHNlIGlmIChpIDwgailcbiAgICAgIHJldHVybiB0aGlzLl9kYXRhW3RoaXMuX2xpbmVhcml6ZUlKKGksIGopXTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5fZGF0YVt0aGlzLl9saW5lYXJpemVJSihqLCBpKV07XG4gIH1cblxuICBzZXQoaTogbnVtYmVyLCBqOiBudW1iZXIsIHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLl9kYXRhW3RoaXMuX2xpbmVhcml6ZUlKKGksIGopXSA9IHZhbHVlO1xuICB9XG5cbiAgc3RhdGljIGNhbGM8VE9iaj4obGlzdDogSW5kZXhhYmxlPFRPYmo+LCBtZXRob2Q6IChhOiBUT2JqLCBiOiBUT2JqKSA9PiBudW1iZXIpOiBEaXN0YW5jZU1hdHJpeCB7XG4gICAgY29uc3Qgc2l6ZTogbnVtYmVyID0gbGlzdC5sZW5ndGg7XG4gICAgY29uc3QgcmVzID0gbmV3IERpc3RhbmNlTWF0cml4KHVuZGVmaW5lZCwgc2l6ZSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHNpemU7IGorKykge1xuICAgICAgICAvLyBpZiBhbnkgb2YgdGhlIHZhbHVlcyBpcyBudWxsLCBzZXQgZGlzdGFuY2UgdG8gMVxuICAgICAgICByZXMuc2V0KGksIGosICFpc05pbChsaXN0W2ldKSAmJiAhaXNOaWwobGlzdFtqXSkgPyBtZXRob2QobGlzdFtpXSwgbGlzdFtqXSkgOiAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8vIHNxdWFyZXMgZWFjaCB2YWx1ZSBpbiBtYXRyaXggaW4gcGxhY2VcbiAgcHVibGljIHNxdWFyZSgpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldID0gdGhpcy5fZGF0YVtpXSAqKiAyO1xuICB9XG5cbiAgLy8gYWRkcyBhbm90aGVyIG1hdHJpeCB0byB0aGlzIG9uZSBpbiBwbGFjZVxuICBwdWJsaWMgYWRkKG90aGVyOiBEaXN0YW5jZU1hdHJpeCkge1xuICAgIGlmICh0aGlzLl9zaXplICE9PSBvdGhlci5fc2l6ZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWF0cmljZXMgbXVzdCBoYXZlIHRoZSBzYW1lIHNpemUuIFRoaXMgc2l6ZTogJHt0aGlzLl9zaXplfSwgb3RoZXIgc2l6ZTogJHtvdGhlci5fc2l6ZX1gKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldICs9IG90aGVyLl9kYXRhW2ldO1xuICB9XG5cbiAgLy8gc3F1YXJlIHJvb3QgZWFjaCB2YWx1ZSBpbiBtYXRyaXggaW4gcGxhY2VcbiAgcHVibGljIHNxcnQoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9kYXRhLmxlbmd0aDsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSA9IE1hdGguc3FydCh0aGlzLl9kYXRhW2ldKTtcbiAgfVxuXG4gIC8vbm9ybWlsemUgZGlzdGFuY2UgbWF0cml4IGluIHBsYWNlXG4gIHB1YmxpYyBub3JtYWxpemUoKSB7XG4gICAgbGV0IG1pbiA9IDA7XG4gICAgbGV0IG1heCA9IHRoaXMuX2RhdGFbMF07XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9kYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5fZGF0YVtpXSA8IG1pbilcbiAgICAgICAgbWluID0gdGhpcy5fZGF0YVtpXTtcbiAgICAgIGlmICh0aGlzLl9kYXRhW2ldID4gbWF4KVxuICAgICAgICBtYXggPSB0aGlzLl9kYXRhW2ldO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IG1heCAtIG1pbjtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldID0gcmFuZ2UgPT09IDAgPyB0aGlzLl9kYXRhW2ldIC0gbWluIDogKHRoaXMuX2RhdGFbaV0gLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmRleGFibGU8VE9iaj4ge1xuICBbaW5kZXg6IG51bWJlcl06IFRPYmo7XG4gIGdldCBsZW5ndGgoKTogbnVtYmVyO1xufVxuIl19","import { getSimilarityFromDistance } from \"../distance-metrics-methods\";\nimport { BitArrayMetricsNames } from \"../typed-metrics\";\nimport { isNil } from \"./utils\";\nexport class SparseMatrixService {\n constructor() {\n this._workerCount = Math.max(navigator.hardwareConcurrency - 2, 1);\n }\n async calc(values, fnName, threshold, opts = {}) {\n //size of full matrix\n const matSize = values.length * (values.length - 1) / 2;\n const chunkSize = Math.floor(matSize / this._workerCount);\n const minThreshold = await this.getMinimalThreshold(values, fnName, opts);\n if (threshold < minThreshold) {\n console.log(`using threshold ${minThreshold}`);\n threshold = minThreshold;\n }\n opts['threshold'] = threshold;\n const promises = new Array(this._workerCount);\n const workers = new Array(this._workerCount).fill(null).map(() => new Worker(new URL('./sparse-matrix-worker', import.meta.url)));\n for (let idx = 0; idx < this._workerCount; idx++) {\n promises[idx] = new Promise((resolveWorker, rejectWorker) => {\n const startIdx = idx * chunkSize;\n const endIdx = idx === this._workerCount - 1 ? matSize : (idx + 1) * chunkSize;\n if (endIdx <= startIdx)\n resolveWorker({ i: new Int32Array(0), j: new Int32Array(0), distance: new Float32Array(0), idx });\n workers[idx].postMessage({ values, startIdx, endIdx, threshold, fnName, opts });\n workers[idx].onmessage = ({ data: { error, i, j, distance } }) => {\n if (error) {\n workers[idx].terminate();\n rejectWorker(error);\n }\n else {\n workers[idx].terminate();\n resolveWorker({ i, j, distance, idx });\n }\n };\n });\n }\n const results = await Promise.all(promises);\n const fullSize = results.reduce((acc, val) => acc + val.i.length, 0);\n const i = new Int32Array(fullSize);\n const j = new Int32Array(fullSize);\n const distance = new Float32Array(fullSize);\n let offset = 0;\n // setting the results\n for (const res of results) {\n i.set(res.i, offset);\n j.set(res.j, offset);\n distance.set(res.distance, offset);\n offset += res.i.length;\n }\n return { i, j, distance };\n }\n async getMinimalThreshold(values, fnName, opts = {}) {\n const thresholdWorkers = new Array(this._workerCount).fill(null)\n .map(() => new Worker(new URL('./sparse-matrix-threshold-worker', import.meta.url)));\n // data may be sorted by clusters, which will hinder the random sampling\n // so we shuffle it first\n const shuffledValues = values.slice();\n for (let i = shuffledValues.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [shuffledValues[i], shuffledValues[j]] = [shuffledValues[j], shuffledValues[i]];\n }\n //We need to calculate the minimal threshold first,\n //in order to get matrix such that it does not exceed the maximum size of 1GB\n //we have 3 return arrays, each 4 bites per element, so if the maximum size of the matrix is 1GB,\n const max_Sparse_matrix_size = 70000000;\n try {\n const matSize = values.length * (values.length - 1) / 2;\n const chunkSize = Math.floor(matSize / this._workerCount);\n const testSetSizePerWorker = Math.floor(Math.min(matSize / 1000, 1000000) / this._workerCount);\n const tPromises = new Array(this._workerCount);\n for (let idx = 0; idx < this._workerCount; idx++) {\n tPromises[idx] = new Promise((resolveWorker, rejectWorker) => {\n const startIdx = idx * chunkSize;\n const endIdx = idx === this._workerCount - 1 ? matSize : (idx + 1) * chunkSize;\n thresholdWorkers[idx].postMessage({ values: shuffledValues, startIdx, endIdx, sampleLength: testSetSizePerWorker, fnName, opts });\n thresholdWorkers[idx].onmessage = ({ data: { error, distance } }) => {\n thresholdWorkers[idx].terminate();\n if (error) {\n rejectWorker(error);\n }\n else {\n resolveWorker({ distance });\n }\n };\n });\n }\n const results = await Promise.all(tPromises);\n const fullSize = results.reduce((acc, val) => acc + val.distance.length, 0);\n const distance = new Float32Array(fullSize);\n let offset = 0;\n for (const res of results) {\n distance.set(res.distance, offset);\n offset += res.distance.length;\n }\n distance.sort();\n const fractionIndex = Math.floor(max_Sparse_matrix_size / matSize * distance.length);\n let threshold = 1 - distance[fractionIndex];\n threshold = Math.min(Math.max(threshold, 0.3), 0.9); //capping\n return threshold;\n }\n catch (e) {\n thresholdWorkers?.forEach((w) => w?.terminate());\n console.error(e);\n return 0.5;\n }\n }\n static calcSync(values, fnName, distanceFn, threshold) {\n const i = [];\n const j = [];\n const distances = [];\n let cnt = 0;\n let mi = 0;\n let mj = 0;\n const fullSize = values.length * (values.length - 1) / 2;\n while (cnt < fullSize) {\n //const value = seq1List[mi] && seq1List[mj] ? hamming(seq1List[mi], seq1List[mj]) : 0;\n const value = !isNil(values[mi]) && !isNil(values[mj]) ?\n distanceFn(values[mi], values[mj]) : 1;\n const similarity = Object.values(BitArrayMetricsNames).some((a) => a === fnName) ? getSimilarityFromDistance(value) : 1 - value;\n if (similarity >= threshold) {\n i.push(mi);\n j.push(mj);\n distances.push(value);\n }\n cnt++;\n mj++;\n if (mj === values.length) {\n mi++;\n mj = mi + 1;\n }\n }\n const iArray = new Int32Array(i);\n const jArray = new Int32Array(j);\n const distanceArray = new Float32Array(distances);\n return { i: iArray, j: jArray, distance: distanceArray };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhcnNlLW1hdHJpeC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3BhcnNlLW1hdHJpeC1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxvQkFBb0IsRUFBeUIsTUFBTSxrQkFBa0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBUWhDLE1BQU0sT0FBTyxtQkFBbUI7SUFFNUI7UUFDRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLG1CQUFtQixHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUksQ0FBSSxNQUFnQixFQUFFLE1BQW9CLEVBQUUsU0FBaUIsRUFBRSxPQUEyQixFQUFFO1FBRzNHLHFCQUFxQjtRQUNyQixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRTFELE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDMUUsSUFBSSxTQUFTLEdBQUcsWUFBWSxFQUFFO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLFlBQVksRUFBRSxDQUFDLENBQUM7WUFDL0MsU0FBUyxHQUFHLFlBQVksQ0FBQztTQUMxQjtRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxTQUFTLENBQUM7UUFDOUIsTUFBTSxRQUFRLEdBQ1osSUFB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Q0FBQyxvQkFBb0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztZQUNoSSxJQUFJLFVBQVUsSUFBSSxTQUFTLEVBQUU7Z0JBQzNCLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ1gsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDWCxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3ZCO1lBQ0QsR0FBRyxFQUFFLENBQUM7WUFDTixFQUFFLEVBQUUsQ0FBQztZQUNMLElBQUksRUFBRSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUU7Z0JBQ3hCLEVBQUUsRUFBRSxDQUFDO2dCQUNMLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2FBQ2I7U0FDRjtRQUVELE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sYUFBYSxHQUFHLElBQUksWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWxELE9BQU8sRUFBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBQyxDQUFDO0lBQ3pELENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UgfSBmcm9tIFwiLi4vZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzXCI7XG5pbXBvcnQgeyBCaXRBcnJheU1ldHJpY3NOYW1lcywgS25vd25NZXRyaWNzLCBNZWFzdXJlIH0gZnJvbSBcIi4uL3R5cGVkLW1ldHJpY3NcIjtcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuZXhwb3J0IHR5cGUgU3BhcnNlTWF0cml4UmVzdWx0ID0ge1xuICBpOiBJbnQzMkFycmF5LFxuICBqOiBJbnQzMkFycmF5LFxuICBkaXN0YW5jZTogRmxvYXQzMkFycmF5LFxuICBpZHg/OiBudW1iZXJcbn07XG5leHBvcnQgY2xhc3MgU3BhcnNlTWF0cml4U2VydmljZSB7XG4gICAgcHJpdmF0ZSBfd29ya2VyQ291bnQ6IG51bWJlcjtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHRoaXMuX3dvcmtlckNvdW50ID0gTWF0aC5tYXgobmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3kgLSAyLCAxKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgY2FsYzxUPih2YWx1ZXM6IEFycmF5PFQ+LCBmbk5hbWU6IEtub3duTWV0cmljcywgdGhyZXNob2xkOiBudW1iZXIsIG9wdHM6IHtbXzogc3RyaW5nXTogYW55fSA9IHt9KSB7XG5cblxuICAgICAgLy9zaXplIG9mIGZ1bGwgbWF0cml4XG4gICAgICBjb25zdCBtYXRTaXplID0gdmFsdWVzLmxlbmd0aCAqICh2YWx1ZXMubGVuZ3RoIC0gMSkgLyAyO1xuICAgICAgY29uc3QgY2h1bmtTaXplID0gTWF0aC5mbG9vcihtYXRTaXplIC8gdGhpcy5fd29ya2VyQ291bnQpO1xuXG4gICAgICBjb25zdCBtaW5UaHJlc2hvbGQgPSBhd2FpdCB0aGlzLmdldE1pbmltYWxUaHJlc2hvbGQodmFsdWVzLCBmbk5hbWUsIG9wdHMpO1xuICAgICAgaWYgKHRocmVzaG9sZCA8IG1pblRocmVzaG9sZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgdXNpbmcgdGhyZXNob2xkICR7bWluVGhyZXNob2xkfWApO1xuICAgICAgICB0aHJlc2hvbGQgPSBtaW5UaHJlc2hvbGQ7XG4gICAgICB9XG4gICAgICBvcHRzWyd0aHJlc2hvbGQnXSA9IHRocmVzaG9sZDtcbiAgICAgIGNvbnN0IHByb21pc2VzID1cbiAgICAgICAgbmV3IEFycmF5PFByb21pc2U8U3BhcnNlTWF0cml4UmVzdWx0Pj4odGhpcy5fd29ya2VyQ291bnQpO1xuXG4gICAgICBjb25zdCB3b3JrZXJzID0gbmV3IEFycmF5KHRoaXMuX3dvcmtlckNvdW50KS5maWxsKG51bGwpLm1hcCgoKSA9PiBuZXcgV29ya2VyKG5ldyBVUkwoJy4vc3BhcnNlLW1hdHJpeC13b3JrZXInLCBpbXBvcnQubWV0YS51cmwpKSk7XG4gICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCB0aGlzLl93b3JrZXJDb3VudDsgaWR4KyspIHtcbiAgICAgICAgcHJvbWlzZXNbaWR4XSA9IG5ldyBQcm9taXNlKChyZXNvbHZlV29ya2VyLCByZWplY3RXb3JrZXIpID0+IHtcbiAgICAgICAgICBjb25zdCBzdGFydElkeCA9IGlkeCAqIGNodW5rU2l6ZTtcbiAgICAgICAgICBjb25zdCBlbmRJZHggPSBpZHggPT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSA/IG1hdFNpemUgOiAoaWR4ICsgMSkgKiBjaHVua1NpemU7XG4gICAgICAgICAgaWYgKGVuZElkeCA8PSBzdGFydElkeCkgXG4gICAgICAgICAgICByZXNvbHZlV29ya2VyKHtpOiBuZXcgSW50MzJBcnJheSgwKSwgajogbmV3IEludDMyQXJyYXkoMCksIGRpc3RhbmNlOiBuZXcgRmxvYXQzMkFycmF5KDApLCBpZHh9KTtcbiAgICAgICAgICB3b3JrZXJzW2lkeF0ucG9zdE1lc3NhZ2Uoe3ZhbHVlcywgc3RhcnRJZHgsIGVuZElkeCwgdGhyZXNob2xkLCBmbk5hbWUsIG9wdHN9KTtcbiAgICAgICAgICB3b3JrZXJzW2lkeF0ub25tZXNzYWdlID0gKHtkYXRhOiB7ZXJyb3IsIGksIGosIGRpc3RhbmNlfX0pOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikgeyBcbiAgICAgICAgICAgICAgd29ya2Vyc1tpZHhdLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgICByZWplY3RXb3JrZXIoZXJyb3IpOyBcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHdvcmtlcnNbaWR4XS50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgICAgcmVzb2x2ZVdvcmtlcih7aSwgaiwgZGlzdGFuY2UsIGlkeH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgY29uc3QgZnVsbFNpemUgPSByZXN1bHRzLnJlZHVjZSgoYWNjLCB2YWwpID0+IGFjYyArIHZhbC5pLmxlbmd0aCwgMCk7XG4gICAgICBjb25zdCBpID0gbmV3IEludDMyQXJyYXkoZnVsbFNpemUpO1xuICAgICAgY29uc3QgaiA9IG5ldyBJbnQzMkFycmF5KGZ1bGxTaXplKTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gbmV3IEZsb2F0MzJBcnJheShmdWxsU2l6ZSk7XG4gICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgIC8vIHNldHRpbmcgdGhlIHJlc3VsdHNcbiAgICAgIGZvciAoY29uc3QgcmVzIG9mIHJlc3VsdHMpIHtcbiAgICAgICAgaS5zZXQocmVzLmksIG9mZnNldCk7XG4gICAgICAgIGouc2V0KHJlcy5qLCBvZmZzZXQpO1xuICAgICAgICBkaXN0YW5jZS5zZXQocmVzLmRpc3RhbmNlLCBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gcmVzLmkubGVuZ3RoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtpLCBqLCBkaXN0YW5jZX07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRNaW5pbWFsVGhyZXNob2xkPFQ+KHZhbHVlczogQXJyYXk8VD4sIGZuTmFtZTogS25vd25NZXRyaWNzLCBvcHRzOiB7W186IHN0cmluZ106IGFueX0gPSB7fSkge1xuICAgICAgY29uc3QgdGhyZXNob2xkV29ya2VycyA9IG5ldyBBcnJheSh0aGlzLl93b3JrZXJDb3VudCkuZmlsbChudWxsKVxuICAgICAgICAubWFwKCgpID0+IG5ldyBXb3JrZXIobmV3IFVSTCgnLi9zcGFyc2UtbWF0cml4LXRocmVzaG9sZC13b3JrZXInLCBpbXBvcnQubWV0YS51cmwpKSk7XG4gICAgICBcbiAgICAgIC8vIGRhdGEgbWF5IGJlIHNvcnRlZCBieSBjbHVzdGVycywgd2hpY2ggd2lsbCBoaW5kZXIgdGhlIHJhbmRvbSBzYW1wbGluZ1xuICAgICAgLy8gc28gd2Ugc2h1ZmZsZSBpdCBmaXJzdFxuICAgICAgY29uc3Qgc2h1ZmZsZWRWYWx1ZXMgPSB2YWx1ZXMuc2xpY2UoKTtcbiAgICAgIGZvciAobGV0IGkgPSBzaHVmZmxlZFZhbHVlcy5sZW5ndGggLSAxOyBpID4gMDsgaS0tKSB7XG4gICAgICAgIGNvbnN0IGogPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAoaSArIDEpKTtcbiAgICAgICAgW3NodWZmbGVkVmFsdWVzW2ldLCBzaHVmZmxlZFZhbHVlc1tqXV0gPSBbc2h1ZmZsZWRWYWx1ZXNbal0sIHNodWZmbGVkVmFsdWVzW2ldXTtcbiAgICAgIH1cblxuICAgICAgLy9XZSBuZWVkIHRvIGNhbGN1bGF0ZSB0aGUgbWluaW1hbCB0aHJlc2hvbGQgZmlyc3QsXG4gICAgICAvL2luIG9yZGVyIHRvIGdldCBtYXRyaXggc3VjaCB0aGF0IGl0IGRvZXMgbm90IGV4Y2VlZCB0aGUgbWF4aW11bSBzaXplIG9mIDFHQlxuICAgICAgLy93ZSBoYXZlIDMgcmV0dXJuIGFycmF5cywgZWFjaCA0IGJpdGVzIHBlciBlbGVtZW50LCBzbyBpZiB0aGUgbWF4aW11bSBzaXplIG9mIHRoZSBtYXRyaXggaXMgMUdCLFxuICAgICAgY29uc3QgbWF4X1NwYXJzZV9tYXRyaXhfc2l6ZSA9IDcwXzAwMF8wMDA7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtYXRTaXplID0gdmFsdWVzLmxlbmd0aCAqICh2YWx1ZXMubGVuZ3RoIC0gMSkgLyAyO1xuICAgICAgICBjb25zdCBjaHVua1NpemUgPSBNYXRoLmZsb29yKG1hdFNpemUgLyB0aGlzLl93b3JrZXJDb3VudCk7XG4gICAgICAgIGNvbnN0IHRlc3RTZXRTaXplUGVyV29ya2VyID0gTWF0aC5mbG9vcihNYXRoLm1pbihtYXRTaXplIC8gMTAwMCwgMV8wMDBfMDAwKSAvIHRoaXMuX3dvcmtlckNvdW50KTtcbiAgICAgICAgY29uc3QgdFByb21pc2VzID0gbmV3IEFycmF5PFByb21pc2U8e2Rpc3RhbmNlOiBGbG9hdDMyQXJyYXl9Pj4odGhpcy5fd29ya2VyQ291bnQpO1xuXG4gICAgICAgIGZvciAobGV0IGlkeCA9IDA7IGlkeCA8IHRoaXMuX3dvcmtlckNvdW50OyBpZHgrKykge1xuICAgICAgICAgIHRQcm9taXNlc1tpZHhdID0gbmV3IFByb21pc2UoKHJlc29sdmVXb3JrZXIsIHJlamVjdFdvcmtlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRJZHggPSBpZHggKiBjaHVua1NpemU7XG4gICAgICAgICAgICBjb25zdCBlbmRJZHggPSBpZHggPT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSA/IG1hdFNpemUgOiAoaWR4ICsgMSkgKiBjaHVua1NpemU7XG4gICAgICAgICAgICB0aHJlc2hvbGRXb3JrZXJzW2lkeF0ucG9zdE1lc3NhZ2Uoe3ZhbHVlczogc2h1ZmZsZWRWYWx1ZXMsIHN0YXJ0SWR4LCBlbmRJZHgsIHNhbXBsZUxlbmd0aDogdGVzdFNldFNpemVQZXJXb3JrZXIsIGZuTmFtZSwgb3B0c30pO1xuICAgICAgICAgICAgdGhyZXNob2xkV29ya2Vyc1tpZHhdLm9ubWVzc2FnZSA9ICh7ZGF0YToge2Vycm9yLCBkaXN0YW5jZX19KTogdm9pZCA9PiB7XG4gICAgICAgICAgICAgIHRocmVzaG9sZFdvcmtlcnNbaWR4XS50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgICAgaWYgKGVycm9yKSB7IHJlamVjdFdvcmtlcihlcnJvcik7IH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZVdvcmtlcih7ZGlzdGFuY2V9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbCh0UHJvbWlzZXMpO1xuICAgICAgICBjb25zdCBmdWxsU2l6ZSA9IHJlc3VsdHMucmVkdWNlKChhY2MsIHZhbCkgPT4gYWNjICsgdmFsLmRpc3RhbmNlLmxlbmd0aCwgMCk7XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gbmV3IEZsb2F0MzJBcnJheShmdWxsU2l6ZSk7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IHJlcyBvZiByZXN1bHRzKSB7XG4gICAgICAgICAgZGlzdGFuY2Uuc2V0KHJlcy5kaXN0YW5jZSwgb2Zmc2V0KTtcbiAgICAgICAgICBvZmZzZXQgKz0gcmVzLmRpc3RhbmNlLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBkaXN0YW5jZS5zb3J0KCk7XG5cbiAgICAgICAgY29uc3QgZnJhY3Rpb25JbmRleCA9IE1hdGguZmxvb3IobWF4X1NwYXJzZV9tYXRyaXhfc2l6ZSAvIG1hdFNpemUgKiBkaXN0YW5jZS5sZW5ndGgpO1xuXG4gICAgICAgIGxldCB0aHJlc2hvbGQgPSAxIC0gZGlzdGFuY2VbZnJhY3Rpb25JbmRleF07XG4gICAgICAgIHRocmVzaG9sZCA9IE1hdGgubWluKE1hdGgubWF4KHRocmVzaG9sZCwgMC4zKSwgMC45KTsgLy9jYXBwaW5nXG4gICAgICAgIHJldHVybiB0aHJlc2hvbGQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocmVzaG9sZFdvcmtlcnM/LmZvckVhY2goKHcpID0+IHc/LnRlcm1pbmF0ZSgpKTtcbiAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgcmV0dXJuIDAuNTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgY2FsY1N5bmM8VD4gKHZhbHVlczogQXJyYXk8VD4gfCBBcnJheUxpa2U8VD4sIGZuTmFtZTogS25vd25NZXRyaWNzLCBkaXN0YW5jZUZuOiBGdW5jdGlvbiwgdGhyZXNob2xkOiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IGk6IG51bWJlcltdID0gW107XG4gICAgICBjb25zdCBqOiBudW1iZXJbXSA9IFtdO1xuICAgICAgY29uc3QgZGlzdGFuY2VzOiBudW1iZXJbXSA9IFtdO1xuICAgICAgbGV0IGNudCA9IDA7XG4gICAgICBsZXQgbWkgPSAwO1xuICAgICAgbGV0IG1qID0gMDtcbiAgICAgIGNvbnN0IGZ1bGxTaXplID0gdmFsdWVzLmxlbmd0aCAqICh2YWx1ZXMubGVuZ3RoIC0gMSkgLyAyO1xuICAgICAgd2hpbGUgKGNudCA8IGZ1bGxTaXplKSB7XG4gICAgICAgIC8vY29uc3QgdmFsdWUgPSBzZXExTGlzdFttaV0gJiYgc2VxMUxpc3RbbWpdID8gaGFtbWluZyhzZXExTGlzdFttaV0sIHNlcTFMaXN0W21qXSkgOiAwO1xuICAgICAgICBjb25zdCB2YWx1ZSA9ICFpc05pbCh2YWx1ZXNbbWldKSAmJiAhaXNOaWwodmFsdWVzW21qXSkgP1xuICAgICAgICAgIGRpc3RhbmNlRm4odmFsdWVzW21pXSwgdmFsdWVzW21qXSkgOiAxO1xuICAgICAgICBjb25zdCBzaW1pbGFyaXR5ID0gT2JqZWN0LnZhbHVlcyhCaXRBcnJheU1ldHJpY3NOYW1lcykuc29tZSgoYSkgPT4gYSA9PT0gZm5OYW1lKSA/IGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UodmFsdWUpIDogMSAtIHZhbHVlO1xuICAgICAgICBpZiAoc2ltaWxhcml0eSA+PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgICBpLnB1c2gobWkpO1xuICAgICAgICAgIGoucHVzaChtaik7XG4gICAgICAgICAgZGlzdGFuY2VzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGNudCsrO1xuICAgICAgICBtaisrO1xuICAgICAgICBpZiAobWogPT09IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICBtaSsrO1xuICAgICAgICAgIG1qID0gbWkgKyAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgXG4gICAgICBjb25zdCBpQXJyYXkgPSBuZXcgSW50MzJBcnJheShpKTtcbiAgICAgIGNvbnN0IGpBcnJheSA9IG5ldyBJbnQzMkFycmF5KGopO1xuICAgICAgY29uc3QgZGlzdGFuY2VBcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkoZGlzdGFuY2VzKTtcblxuICAgICAgcmV0dXJuIHtpOiBpQXJyYXksIGo6IGpBcnJheSwgZGlzdGFuY2U6IGRpc3RhbmNlQXJyYXl9O1xuICAgIH1cbn0iXX0=","export function getKnnGraph(i, j, distances, neighbours, dataLength) {\n function insert(distancesAr, indexes, num, index) {\n if (num > distancesAr[distancesAr.length - 1]) {\n return;\n }\n let k = distancesAr.length - 2;\n for (k = distancesAr.length - 2; k >= 0; k--) {\n if (num > distancesAr[k]) {\n break;\n }\n }\n distancesAr.splice(distancesAr.length - 1, 1);\n distancesAr.splice(k + 1, 0, num);\n indexes.splice(indexes.length - 1, 1);\n indexes.splice(k + 1, 0, index);\n }\n console.time('knnGraph');\n const knnIndexes = new Array(dataLength).fill(null).map(() => new Array(neighbours).fill(1));\n const knnDistances = new Array(dataLength).fill(null).map(() => new Array(neighbours).fill(1));\n for (let k = 0; k < i.length; k++) {\n insert(knnDistances[i[k]], knnIndexes[i[k]], distances[k], j[k]);\n insert(knnDistances[j[k]], knnIndexes[j[k]], distances[k], i[k]);\n }\n console.timeEnd('knnGraph');\n return { knnIndexes, knnDistances };\n}\nexport function getKnnGraphFromDM(dm, neighbors, dataLength) {\n function insert(distancesAr, indexes, num, index) {\n if (num > distancesAr[distancesAr.length - 1]) {\n return;\n }\n let k = distancesAr.length - 2;\n for (k = distancesAr.length - 2; k >= 0; k--) {\n if (num > distancesAr[k]) {\n break;\n }\n }\n distancesAr.splice(distancesAr.length - 1, 1);\n distancesAr.splice(k + 1, 0, num);\n indexes.splice(indexes.length - 1, 1);\n indexes.splice(k + 1, 0, index);\n }\n console.time('knnGraph');\n const knnIndexes = new Array(dataLength).fill(null).map(() => new Array(neighbors).fill(1));\n const knnDistances = new Array(dataLength).fill(null).map(() => new Array(neighbors).fill(1));\n let row = 0;\n let col = 1;\n for (let i = 0; i < dm.length; i++) {\n insert(knnDistances[row], knnIndexes[row], dm[i], col);\n insert(knnDistances[col], knnIndexes[col], dm[i], row);\n col++;\n if (col >= dataLength) {\n row++;\n col = row + 1;\n }\n }\n console.timeEnd('knnGraph');\n return { knnIndexes, knnDistances };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia25uR3JhcGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJrbm5HcmFwaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLFVBQVUsV0FBVyxDQUFDLENBQWEsRUFBRSxDQUFhLEVBQUUsU0FBdUIsRUFDN0UsVUFBa0IsRUFBRSxVQUFrQjtJQUNsQyxTQUFTLE1BQU0sQ0FBQyxXQUFxQixFQUFFLE9BQWlCLEVBQUUsR0FBVyxFQUFFLEtBQWE7UUFDaEYsSUFBSSxHQUFHLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDekMsT0FBTztTQUNWO1FBQ0QsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDL0IsS0FBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN6QyxJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3RCLE1BQU07YUFDVDtTQUNKO1FBQ0QsV0FBVyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdEMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBR0QsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUN4QixNQUFNLFVBQVUsR0FBRyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FB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QUFDLENBQUM7SUFFdEcsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ1osSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ1osS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFFaEMsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN2RCxHQUFHLEVBQUUsQ0FBQztRQUNOLElBQUksR0FBRyxJQUFJLFVBQVUsRUFBRTtZQUNuQixHQUFHLEVBQUUsQ0FBQztZQUNOLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1NBQ2pCO0tBQ0o7SUFFRCxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzVCLE9BQU8sRUFBQyxVQUFVLEVBQUUsWUFBWSxFQUFDLENBQUM7QUFDdEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIlxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0S25uR3JhcGgoaTogSW50MzJBcnJheSwgajogSW50MzJBcnJheSwgZGlzdGFuY2VzOiBGbG9hdDMyQXJyYXksXG4gICAgbmVpZ2hib3VyczogbnVtYmVyLCBkYXRhTGVuZ3RoOiBudW1iZXIpIHtcbiAgICAgICAgZnVuY3Rpb24gaW5zZXJ0KGRpc3RhbmNlc0FyOiBudW1iZXJbXSwgaW5kZXhlczogbnVtYmVyW10sIG51bTogbnVtYmVyLCBpbmRleDogbnVtYmVyKSB7XG4gICAgICAgICAgICBpZiAobnVtID4gZGlzdGFuY2VzQXJbZGlzdGFuY2VzQXIubGVuZ3RoLTFdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGsgPSBkaXN0YW5jZXNBci5sZW5ndGggLSAyO1xuICAgICAgICAgICAgZm9yKGsgPSBkaXN0YW5jZXNBci5sZW5ndGggLSAyOyBrID49IDA7IGstLSkge1xuICAgICAgICAgICAgICAgIGlmIChudW0gPiBkaXN0YW5jZXNBcltrXSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaXN0YW5jZXNBci5zcGxpY2UoZGlzdGFuY2VzQXIubGVuZ3RoIC0gMSwgMSk7XG4gICAgICAgICAgICBkaXN0YW5jZXNBci5zcGxpY2UoaysxLCAwLCBudW0pO1xuICAgICAgICAgICAgaW5kZXhlcy5zcGxpY2UoaW5kZXhlcy5sZW5ndGggLSAxLCAxKTtcbiAgICAgICAgICAgIGluZGV4ZXMuc3BsaWNlKGsrMSwgMCwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgICAgICBcblxuICAgICAgICBjb25zb2xlLnRpbWUoJ2tubkdyYXBoJylcbiAgICAgICAgY29uc3Qga25uSW5kZXhlcyA9IG5ldyBBcnJheShkYXRhTGVuZ3RoKS5maWxsKG51bGwpLm1hcCgoKSA9PiBuZXcgQXJyYXk8bnVtYmVyPihuZWlnaGJvdXJzKS5maWxsKDEpKTtcbiAgICAgICAgY29uc3Qga25uRGlzdGFuY2VzID0gbmV3IEFycmF5KGRhdGFMZW5ndGgpLmZpbGwobnVsbCkubWFwKCgpID0+IG5ldyBBcnJheTxudW1iZXI+KG5laWdoYm91cnMpLmZpbGwoMSkpO1xuXG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaS5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgaW5zZXJ0KGtubkRpc3RhbmNlc1tpW2tdXSwga25uSW5kZXhlc1tpW2tdXSwgZGlzdGFuY2VzW2tdLCBqW2tdKTtcbiAgICAgICAgICAgIGluc2VydChrbm5EaXN0YW5jZXNbaltrXV0sIGtubkluZGV4ZXNbaltrXV0sIGRpc3RhbmNlc1trXSwgaVtrXSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLnRpbWVFbmQoJ2tubkdyYXBoJyk7XG4gICAgICAgIHJldHVybiB7a25uSW5kZXhlcywga25uRGlzdGFuY2VzfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEtubkdyYXBoRnJvbURNKGRtOiBGbG9hdDMyQXJyYXksIG5laWdoYm9yczogbnVtYmVyLCBkYXRhTGVuZ3RoOiBudW1iZXIpIHtcbiAgICBmdW5jdGlvbiBpbnNlcnQoZGlzdGFuY2VzQXI6IG51bWJlcltdLCBpbmRleGVzOiBudW1iZXJbXSwgbnVtOiBudW1iZXIsIGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKG51bSA+IGRpc3RhbmNlc0FyW2Rpc3RhbmNlc0FyLmxlbmd0aC0xXSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBrID0gZGlzdGFuY2VzQXIubGVuZ3RoIC0gMjtcbiAgICAgICAgZm9yKGsgPSBkaXN0YW5jZXNBci5sZW5ndGggLSAyOyBrID49IDA7IGstLSkge1xuICAgICAgICAgICAgaWYgKG51bSA+IGRpc3RhbmNlc0FyW2tdKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGlzdGFuY2VzQXIuc3BsaWNlKGRpc3RhbmNlc0FyLmxlbmd0aCAtIDEsIDEpO1xuICAgICAgICBkaXN0YW5jZXNBci5zcGxpY2UoaysxLCAwLCBudW0pO1xuICAgICAgICBpbmRleGVzLnNwbGljZShpbmRleGVzLmxlbmd0aCAtIDEsIDEpO1xuICAgICAgICBpbmRleGVzLnNwbGljZShrKzEsIDAsIGluZGV4KTtcbiAgICB9XG4gICAgICAgIFxuXG4gICAgY29uc29sZS50aW1lKCdrbm5HcmFwaCcpXG4gICAgY29uc3Qga25uSW5kZXhlcyA9IG5ldyBBcnJheShkYXRhTGVuZ3RoKS5maWxsKG51bGwpLm1hcCgoKSA9PiBuZXcgQXJyYXk8bnVtYmVyPihuZWlnaGJvcnMpLmZpbGwoMSkpO1xuICAgIGNvbnN0IGtubkRpc3RhbmNlcyA9IG5ldyBBcnJheShkYXRhTGVuZ3RoKS5maWxsKG51bGwpLm1hcCgoKSA9PiBuZXcgQXJyYXk8bnVtYmVyPihuZWlnaGJvcnMpLmZpbGwoMSkpO1xuXG4gICAgbGV0IHJvdyA9IDA7XG4gICAgbGV0IGNvbCA9IDE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkbS5sZW5ndGg7IGkrKykge1xuICAgICAgICBcbiAgICAgICAgaW5zZXJ0KGtubkRpc3RhbmNlc1tyb3ddLCBrbm5JbmRleGVzW3Jvd10sIGRtW2ldLCBjb2wpO1xuICAgICAgICBpbnNlcnQoa25uRGlzdGFuY2VzW2NvbF0sIGtubkluZGV4ZXNbY29sXSwgZG1baV0sIHJvdyk7XG4gICAgICAgIGNvbCsrO1xuICAgICAgICBpZiAoY29sID49IGRhdGFMZW5ndGgpIHtcbiAgICAgICAgICAgIHJvdysrO1xuICAgICAgICAgICAgY29sID0gcm93ICsgMTtcbiAgICAgICAgfSAgICBcbiAgICB9XG5cbiAgICBjb25zb2xlLnRpbWVFbmQoJ2tubkdyYXBoJyk7XG4gICAgcmV0dXJuIHtrbm5JbmRleGVzLCBrbm5EaXN0YW5jZXN9O1xufSJdfQ==","import { DimensionalityReducer } from '../reduce-dimensionality';\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(columnData, method, measure, options, parallelDistanceWorkers) {\n const reducer = new DimensionalityReducer(columnData, method, measure, { ...options, progressFunc });\n return await reducer.transform(true, parallelDistanceWorkers);\n}\nasync function progressFunc(epochNum, epochsLength, embedding) {\n if (epochNum % 5 === 0)\n self.postMessage({ epochNum, epochsLength, embedding });\n}\nself.onmessage = async ({ data: { columnData, method, measure, options, parallelDistanceWorkers } }) => {\n let data;\n try {\n data = await onMessage(columnData, method, measure, options, parallelDistanceWorkers);\n }\n catch (e) {\n data = { error: e };\n }\n self.postMessage({\n error: data.error,\n distance: data.distance,\n embedding: data.embedding,\n });\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGltZW5zaW9uYWxpdHktcmVkdWNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImRpbWVuc2lvbmFsaXR5LXJlZHVjZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLHFCQUFxQixFQUFlLE1BQU0sMEJBQTBCLENBQUM7QUFHN0U7Ozs7Ozs7OztHQVNHO0FBQ0gsS0FBSyxVQUFVLFNBQVMsQ0FBQyxVQUFpQixFQUFFLE1BQW9CLEVBQUUsT0FBcUIsRUFDckYsT0FBYSxFQUFFLHVCQUFpQztJQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLHFCQUFxQixDQUN2QyxVQUFVLEVBQ1YsTUFBTSxFQUNOLE9BQU8sRUFDUCxFQUFDLEdBQUcsT0FBTyxFQUFFLFlBQVksRUFBQyxDQUMzQixDQUFDO0lBQ0YsT0FBTyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLHVCQUF1QixDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVELEtBQUssVUFBVSxZQUFZLENBQUUsUUFBZ0IsRUFBRSxZQUFvQixFQUFFLFNBQXFCO0lBQ3hGLElBQUksUUFBUSxHQUFHLENBQUMsS0FBSyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBQyxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxFQUFFLEVBQUMsSUFBSSxFQUFFLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFDLEVBQUMsRUFBRSxFQUFFO0lBQ2pHLElBQUksSUFBb0QsQ0FBQztJQUN6RCxJQUFJO1FBQ0YsSUFBSSxHQUFHLE1BQU0sU0FBUyxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0tBQ3ZGO0lBQUMsT0FBTyxDQUFNLEVBQUU7UUFDZixJQUFJLEdBQUcsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUM7S0FDbkI7SUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ2YsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1FBQ2pCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtRQUN2QixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7S0FDMUIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtEaW1lbnNpb25hbGl0eVJlZHVjZXIsIEtub3duTWV0aG9kc30gZnJvbSAnLi4vcmVkdWNlLWRpbWVuc2lvbmFsaXR5JztcbmltcG9ydCB7S25vd25NZXRyaWNzfSBmcm9tICcuLi90eXBlZC1tZXRyaWNzL3R5cGVkLW1ldHJpY3MnO1xuXG4vKipcbiAqIFdvcmtlciB0aHJlYWQgcmVjZWl2aW5nIGRhdGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHthbnlbXX0gY29sdW1uRGF0YSBTYW1wbGVzIHRvIHByb2Nlc3MuXG4gKiBAcGFyYW0ge0tub3duTWV0aG9kc30gbWV0aG9kIEVtYmVkZGluZyBtZXRob2QuXG4gKiBAcGFyYW0ge0tub3duTWV0cmljc30gbWVhc3VyZSBEaXN0YW5jZSBtZXRyaWMuXG4gKiBAcGFyYW0ge2FueX0gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gYWxnb3JpdGhtLlxuICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSB3b3JrZXJzLlxuICogQHJldHVybiB7YW55fSBFbWJlZGRpbmcgKGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZSkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG9uTWVzc2FnZShjb2x1bW5EYXRhOiBhbnlbXSwgbWV0aG9kOiBLbm93bk1ldGhvZHMsIG1lYXN1cmU6IEtub3duTWV0cmljcyxcbiAgb3B0aW9ucz86IGFueSwgcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnM/OiBib29sZWFuKTogUHJvbWlzZTx7ZGlzdGFuY2U/OiBhbnksIGVtYmVkZGluZz86IGFueX0+IHtcbiAgY29uc3QgcmVkdWNlciA9IG5ldyBEaW1lbnNpb25hbGl0eVJlZHVjZXIoXG4gICAgY29sdW1uRGF0YSxcbiAgICBtZXRob2QsXG4gICAgbWVhc3VyZSxcbiAgICB7Li4ub3B0aW9ucywgcHJvZ3Jlc3NGdW5jfSxcbiAgKTtcbiAgcmV0dXJuIGF3YWl0IHJlZHVjZXIudHJhbnNmb3JtKHRydWUsIHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcHJvZ3Jlc3NGdW5jIChlcG9jaE51bTogbnVtYmVyLCBlcG9jaHNMZW5ndGg6IG51bWJlciwgZW1iZWRkaW5nOiBudW1iZXJbXVtdKSB7XG4gIGlmIChlcG9jaE51bSAlIDUgPT09IDApXG4gICAgc2VsZi5wb3N0TWVzc2FnZSh7ZXBvY2hOdW0sIGVwb2Noc0xlbmd0aCwgZW1iZWRkaW5nfSk7XG59XG5cbnNlbGYub25tZXNzYWdlID0gYXN5bmMgKHtkYXRhOiB7Y29sdW1uRGF0YSwgbWV0aG9kLCBtZWFzdXJlLCBvcHRpb25zLCBwYXJhbGxlbERpc3RhbmNlV29ya2Vyc319KSA9PiB7XG4gIGxldCBkYXRhOiB7ZXJyb3I/OiBhbnksIGRpc3RhbmNlPzogYW55LCBlbWJlZGRpbmc/OiBhbnl9O1xuICB0cnkge1xuICAgIGRhdGEgPSBhd2FpdCBvbk1lc3NhZ2UoY29sdW1uRGF0YSwgbWV0aG9kLCBtZWFzdXJlLCBvcHRpb25zLCBwYXJhbGxlbERpc3RhbmNlV29ya2Vycyk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGRhdGEgPSB7ZXJyb3I6IGV9O1xuICB9XG4gIHNlbGYucG9zdE1lc3NhZ2Uoe1xuICAgIGVycm9yOiBkYXRhLmVycm9yLFxuICAgIGRpc3RhbmNlOiBkYXRhLmRpc3RhbmNlLFxuICAgIGVtYmVkZGluZzogZGF0YS5lbWJlZGRpbmcsXG4gIH0pO1xufTtcbiJdfQ==","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TSNE = void 0;\nvar tsne_1 = require(\"./tsne\");\nObject.defineProperty(exports, \"TSNE\", { enumerable: true, get: function () { return tsne_1.TSNE; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TSNE = void 0;\nclass TSNE {\n constructor(opt) {\n // return 0 mean unit standard deviation random number\n this.returnV = false;\n this.vValue = 0.0;\n this.iter = 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 }\n assert(condition, message) {\n if (!condition) {\n throw message || 'Assertion failed';\n }\n }\n // syntax sugar\n getopt(opt, field, defaultval) {\n if (opt.hasOwnProperty(field)) {\n return opt[field];\n }\n else {\n return defaultval;\n }\n }\n gaussRandom() {\n if (this.returnV) {\n this.returnV = false;\n return this.vValue;\n }\n const u = 2 * Math.random() - 1;\n const v = 2 * Math.random() - 1;\n const r = u * u + v * v;\n if (r === 0 || r > 1) {\n return this.gaussRandom();\n }\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) { return mu + this.gaussRandom() * std; }\n // utilitity that creates contiguous vector of zeros of size n\n zeros(n) {\n if (typeof (n) === 'undefined' || isNaN(n)) {\n return [];\n }\n if (typeof ArrayBuffer === 'undefined') {\n // lacking browser support\n const arr = new Array(n);\n for (let i = 0; i < n; i++) {\n arr[i] = 0;\n }\n return arr;\n }\n else {\n return new Float64Array(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 = [];\n for (let i = 0; i < n; i++) {\n const xhere = [];\n for (let j = 0; j < d; j++) {\n if (uses) {\n xhere.push(s);\n }\n else {\n xhere.push(this.randn(0.0, 1e-4));\n }\n }\n x.push(xhere);\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 // compute (p_{i|j} + p_{j|i})/(2n)\n d2p(D, perplexity, tol) {\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 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 = 50;\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 let pj = Math.exp(-D[i * n + j] * beta);\n if (i === j) {\n pj = 0;\n } // we dont care about diagonals\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 }\n else {\n pj = prow[j] / psum;\n }\n prow[j] = pj;\n if (pj > 1e-7) {\n nHere -= pj * Math.log(pj);\n }\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 }\n else {\n beta = (beta + betamax) / 2;\n }\n }\n else {\n // converse case. make distrubtion less peaky\n betamax = beta;\n if (betamin === -Infinity) {\n beta = beta / 2;\n }\n else {\n beta = (beta + betamin) / 2;\n }\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 }\n if (num >= maxtries) {\n done = true;\n }\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 }\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 }\n return pOut;\n }\n // helper function\n sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }\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); // 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) {\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 const dists = 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 = D[i][j];\n dists[i * N + j] = d;\n dists[j * N + i] = d;\n }\n }\n this.P = this.d2p(dists, this.perplexity, 1e-4);\n this.N = N;\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;\n } // 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 }\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 const 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 let dsum = 0.0;\n for (let d = 0; d < dim; d++) {\n const dhere = Y[i][d] - Y[j][d];\n dsum += dhere * dhere;\n }\n const qu = 1.0 / (1.0 + dsum); // Student t-distribution\n quArr[i * N + j] = qu;\n 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 for (let q = 0; q < NN; q++) {\n Q[q] = Math.max(quArr[q] / qsum, 1e-100);\n }\n let cost = 0.0;\n const grad = [];\n for (let i = 0; i < N; i++) {\n const gsum = new Array(dim); // init grad for point i\n for (let d = 0; d < dim; d++) {\n gsum[d] = 0.0;\n }\n for (let j = 0; j < N; j++) {\n cost += -P[i * N + j] * Math.log(Q[i * N + j]); // accumulate cost (the non-constant portion at least...)\n const premult = 4 * (pmul * P[i * N + j] - Q[i * N + j]) * quArr[i * N + j];\n for (let d = 0; d < dim; d++) {\n gsum[d] += premult * (Y[i][d] - Y[j][d]);\n }\n }\n grad.push(gsum);\n }\n return { cost, grad };\n }\n}\nexports.TSNE = TSNE;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n// the startup function\n__webpack_require__.x = () => {\n\t// Load entry module and return exports\n\t// This entry module depends on other loaded chunks and execution need to be delayed\n\tvar __webpack_exports__ = __webpack_require__.O(undefined, [1,172], () => (__webpack_require__(3196)))\n\t__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n\treturn __webpack_exports__;\n};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks and sibling chunks for the entrypoint\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && !scriptUrl) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","__webpack_require__.b = self.location + \"\";\n\n// object to store loaded chunks\n// \"1\" means \"already loaded\"\nvar installedChunks = {\n\t196: 1\n};\n\n// importScripts chunk loading\nvar installChunk = (data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\tfor(var moduleId in moreModules) {\n\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t}\n\t}\n\tif(runtime) runtime(__webpack_require__);\n\twhile(chunkIds.length)\n\t\tinstalledChunks[chunkIds.pop()] = 1;\n\tparentChunkLoadingFunction(data);\n};\n__webpack_require__.f.i = (chunkId, promises) => {\n\t// \"1\" is the signal for \"already loaded\"\n\tif(!installedChunks[chunkId]) {\n\t\tif(true) { // all chunks have JS\n\t\t\timportScripts(__webpack_require__.p + __webpack_require__.u(chunkId));\n\t\t}\n\t}\n};\n\nvar chunkLoadingGlobal = self[\"webpackChunkbio\"] = self[\"webpackChunkbio\"] || [];\nvar parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);\nchunkLoadingGlobal.push = installChunk;\n\n// no HMR\n\n// no HMR manifest","// run startup\nvar __webpack_exports__ = __webpack_require__.x();\n"],"names":["deferred","next","randomFloat","range","Math","random","floor","assert","condition","message","Error","vectorAdd","p","q","multiplier","nItems","length","total","i","fillRandomMatrix","dimension1","dimension2","scale","matrix","fill","Array","map","initCoordinates","j","calculateEuclideanDistance","sqdiffSumm","v","itemsSum","vectorSquare","sqrt","dmLinearIndex","size","DistanceMatrixService","constructor","useConcurrentWorkers","terminateOnComplete","threadCount","navigator","hardwareConcurrency","this","_workerCount","max","_workers","Worker","URL","_terminateOnComplete","async","values","fnName","normalize","opts","Promise","resolve","reject","len","promises","totalLength","min","chunkSize","distanceMatrix","Float32Array","endRow","endCol","lmin","lmax","Number","MIN_VALUE","start","end","startRow","startCol","postMessage","chunckSize","resolveWorker","rejectWorker","onmessage","data","error","distanceMatrixData","terminate","set","all","forEach","value","index","e","worker","SPEBase","options","steps","cycles","cutoff","lambda","dlambda","lambda2","dlambda2","epsilon","distanceFunction","distance","distanceFunctionName","vectors","dmIndexFunct","matrixService","calc","calcDistance","index1","index2","coordinates","dimension","initDistance","cycle","step","rowi","rowj","r","d","diffIJ","PSPEBase","OriginalSPE","super","radiusPercent","maxDistance","maxDistanceSteps","n","radius","StringMetricsNames","VectorMetricsNames","BitArrayMetricsNames","IntArrayMetricsNames","DistanceMetricsSubjects","NumberMetricsNames","tanimotoSimilarity","x","y","trueCount","common","andWithCountBits","getDistanceFromSimilarity","similarity","Tanimoto","Dice","Asymmetric","BraunBlanquet","Cosine","Kulczynski","McConnaughey","RogotGoldberg","Russel","Sokal","Hamming","Euclidean","HAMMING","LEVENSHTEIN","MONOMER_CHEMICAL_DISTANCE","vectorDistanceMetricsMethods","stringDistanceMetricsMethods","Levenshtein","JaroWinkler","Manhattan","s1","s2","dist","bitArrayDistanceMetricsMethods","diceSimilarity","asymmetricSimilarity","braunBlanquetSimilarity","cosineSimilarity","totalProd","kulczynskiSimilarity","mcConnaugheySimilarity","countBits","diff","rogotGoldbergSimilarity","russelSimilarity","sokalSimilarity","intArrayDistanceMetricsMethods","TanimotoIntArray","numberDistanceMetricsMethods","NumericDistance","abs","AvailableMetrics","Vector","String","BitArray","MacroMolecule","NEEDLEMANN_WUNSCH","IntArray","MetricToDataType","Object","keys","reduce","ret","key","val","isBitArrayMetric","name","Measure","method","dataType","getMeasure","dict","hasOwnProperty","toString","static","availableMeasures","tauRandInt","tauRand","empty","output","push","undefined","_","filled","zeros","mean","input","sum","rejectionSample","nSamples","poolSize","result","rejectSample","broken","k","reshape2d","a","b","rows","count","col","makeHeap","nPoints","makeArrays","fillValue","heap","Infinity","heapPush","row","weight","flag","indices","weights","uncheckedHeapPush","isNew","iSwap","ic1","ic2","heapShape2","buildCandidates","currentGraph","nVertices","nNeighbors","maxCandidates","candidateNeighbors","idx","isn","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","getCols","getValues","fn","vals","toArray","oldRows","oldCols","oldVals","matlen","Int32Array","pairwiseMultiply","elementWise","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","splice","oldNodeNum","res","selectSide","point","searchFlatTree","node","prototype","isAnyArray","object","call","endsWith","errorCalculation","parameters","parameterizedFunction","func","rescale","arguments","TypeError","currentMin","_options$fromIndex","fromIndex","_options$toIndex","toIndex","isInteger","minValue","currentMax","maxValue","RangeError","_options$min","autoMinMax","_options$max","factor","indent","repeat","indentData","inspectMatrixWithOptions","maxRows","maxColumns","maxNumSize","padMinus","columns","maxI","maxJ","loop","line","formatNumber","join","inspectData","num","formatNumber2","padEnd","str","fix","toFixed","startsWith","exp","toExponential","slice","checkRowIndex","outer","checkColumnIndex","checkRowVector","vector","to1DArray","checkColumnVector","checkRange","startColumn","endColumn","checkNumber","newArray","array","checkNonEmpty","isEmpty","AbstractMatrix","newRows","newColumns","newData","newMatrix","Matrix","column","interval","round","l","matrix1","matrix2","checkMatrix","isMatrix","klass","apply","callback","to2DArray","copy","toJSON","isRowVector","isColumnVector","isVector","isSquare","isSymmetric","isEchelonForm","previousColumn","checked","isReducedEchelonForm","echelonForm","clone","h","iMax","swapRows","tmp","reducedEchelonForm","maxRow","pivot","setSubMatrix","neg","mulS","getRow","getRowVector","rowVector","setRow","row1","row2","temp","getColumn","getColumnVector","columnVector","setColumn","swapColumns","column1","column2","addRowVector","subRowVector","mulRowVector","divRowVector","addColumnVector","subColumnVector","mulColumnVector","divColumnVector","mulRow","mulColumn","by","NaN","NEGATIVE_INFINITY","maxIndex","POSITIVE_INFINITY","minIndex","maxRowIndex","minRow","minRowIndex","maxColumn","maxColumnIndex","minColumn","minColumnIndex","diag","type","cumulativeSum","dot","vector2","vector1","mmul","other","Bcolj","Float64Array","s","strassen2x2","a11","b11","a12","b12","a21","b21","a22","b22","m1","m2","m3","m4","m5","c00","c01","c10","c11","strassen3x3","a00","a01","a02","a10","a20","b00","b01","b02","b10","b20","m6","m7","m8","m9","m12","m13","m14","m15","m16","m17","m18","c02","c12","c20","c21","c22","mmulStrassen","r1","c1","r2","c2","embed","mat","c","resultat","console","warn","blockMult","halfRows","parseInt","halfCols","subMatrix","sub","scaleRows","isFinite","scaleColumns","flipRows","middle","ceil","first","last","flipColumns","kroneckerProduct","kroneckerSum","AxI","eye","IxB","transpose","sortRows","compareFunction","compareNumbers","sortColumns","subMatrixRow","subMatrixColumn","selection","rowIndices","columnIndices","checkRowIndices","checkColumnIndices","rowIndex","columnIndex","trace","sumByRow","sumByColumn","sumAll","product","productByRow","productByColumn","productAll","variance","unbiased","sum1","sum2","varianceByRow","varianceByColumn","varianceAll","standardDeviation","center","centerByRow","centerByColumn","centerAll","pow","getScaleByRow","scaleByRow","getScaleByColumn","scaleByColumn","divider","getScaleAll","scaleAll","Symbol","for","rand","randomInt","randInt","diagonal","identity","negate","tensorProduct","nColumns","arrayData","every","element","removeRow","addRow","removeColumn","newRow","addColumn","addS","addM","subS","subM","subtractS","subtractM","mul","mulM","multiply","multiplyS","multiplyM","div","divS","divM","divide","divideS","divideM","mod","modS","modM","modulus","modulusS","modulusM","and","andS","andM","or","orS","orM","xor","xorS","xorM","leftShift","leftShiftS","leftShiftM","signPropagatingRightShift","signPropagatingRightShiftS","signPropagatingRightShiftM","rightShift","rightShiftS","rightShiftM","zeroFillRightShift","zeroFillRightShiftS","zeroFillRightShiftM","not","acos","acosh","asin","asinh","atan","atanh","cbrt","clz32","cos","cosh","expm1","fround","log","log1p","log10","log2","sign","sin","sinh","tan","tanh","trunc","arg0","powS","powM","installMathOperations","WrapperMatrix2D","LuDecomposition","t","LUcolj","kmax","lu","pivotVector","pivotSign","LU","isSingular","solve","X","determinant","lowerTriangularMatrix","upperTriangularMatrix","pivotPermutationVector","hypotenuse","QrDecomposition","qr","rdiag","nrm","QR","Rdiag","isFullRank","orthogonalMatrix","SingularValueDecomposition","computeLeftSingularVectors","computeRightSingularVectors","autoTranspose","wantu","Boolean","wantv","swapped","aux","nu","ni","U","V","work","si","nct","nrt","mrc","pp","iter","eps","EPSILON","kase","alpha","isNaN","ks","f","cs","sn","sp","spm1","epm1","sk","ek","shift","g","Y","threshold","scols","Ls","rightSingularVectors","VL","vrows","urows","VLU","solveForDiagonal","inverse","vcols","ucols","norm2","rank","tol","ii","leftSingularVectors","diagonalMatrix","params","damping","gradientDifference","evaluatedData","gradientFunc","paramFunction","ans","param","auxParams","funcParam","gradientFunction","matrixFunc","matrixFunction","inverseMatrix","useSVD","leftHandSide","rightHandSide","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","initializeFit","optimizeLayout","optimizeLayoutAsync","setSupervisedProjection","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","transform","toTransform","rawData","init","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","sparseMatrix","prodMatrix","simplicialSet","target","unknownDist","intersection","fastIntersection","resetLocalConnectivity","nIter","bandwidth","lo","hi","mid","ithDistances","nonZeroDists","interpolation","psum","meanIthDistances","meanDistances","graphValues","entry","w","state","assign","dim","moveOther","epochsPerNegativeSample","epochOfNextNegativeSample","epochOfNextSample","initialAlpha","gamma","xv","yv","parameterValues","maxIterations","errorTolerance","minValues","maxValues","initialValues","parLen","MAX_SAFE_INTEGER","MIN_SAFE_INTEGER","iteration","converged","parameterError","iterations","findABParams","current","distSquared","rDist","gradCoeff","gradD","clip","nNegSamples","epochCallback","epochCompleted","shouldStop","isFinished","setTimeout","err","clipValue","DimReductionMethods","DistanceMatrix","_data","_size","dataLength","_linearizeIJ","list","square","SparseMatrixService","matSize","minThreshold","getMinimalThreshold","workers","startIdx","endIdx","fullSize","acc","thresholdWorkers","shuffledValues","testSetSizePerWorker","tPromises","sampleLength","cnt","mi","mj","some","Reducer","AvailableReducers","distanceFnArgs","usingSparseMatrix","sparseMatrixThreshold","transferedSparseMatrix","progressFunc","distanceFname","dmIndexFunc","usingDistanceMatrix","preCalculateDistanceMatrix","_encodedDistanceMatrix","bind","_encodedSparseMatrix","_encodedDistance","reducer","parallelDistanceWorkers","knnRes","dm","insert","distancesAr","indexes","time","knnIndexes","timeEnd","getKnnGraphFromDM","neighbours","getKnnGraph","second","fitAsync","epoc","matrixProxy","condensedArray","linearFunc","linearIndex","iNum","jNum","idx1Handler","idx1","_receiver","Proxy","idx2","idx2Handler","distanceMatrixProxy","initDataDist","getSolution","emb","DimensionalityReducer","metric","measure","specOptions","_length","typeName","availableMethods","availableMetrics","obj","epochNum","epochsLength","self","columnData","onMessage","exports","tsne_1","defineProperty","enumerable","TSNE","opt","returnV","vValue","perplexity","getopt","field","defaultval","gaussRandom","u","randn","mu","std","ArrayBuffer","arr","randn2d","uses","xhere","L2","x1","x2","D","x1i","x2i","xtod","N","d2p","nf","hTarget","P","prow","betamin","betamax","beta","done","maxtries","pj","nHere","pOut","N2","initDataRaw","dists","initSolution","gains","ystep","cg","costGrad","cost","grad","ymean","gid","sid","gainid","newgain","newsid","debugGrad","yold","cg0","cg1","analytic","numerical","pmul","quArr","qsum","dsum","dhere","qu","NN","Q","gsum","premult","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","module","__webpack_modules__","__webpack_exports__","O","chunkIds","priority","notFulfilled","fulfilled","definition","o","chunkId","globalThis","Function","window","prop","scriptUrl","importScripts","location","document","currentScript","src","scripts","getElementsByTagName","replace","installedChunks","chunkLoadingGlobal","parentChunkLoadingFunction","moreModules","runtime","pop","then"],"sourceRoot":""}