tfcconnection/.shadow-cljs/builds/app/dev/goog-js/goog.array.array.js

1 line
176 KiB
JavaScript

["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/array/array.js"],"~:js","goog.loadModule(function(exports) {\n \"use strict\";\n goog.module(\"goog.array\");\n goog.module.declareLegacyNamespace();\n const asserts = goog.require(\"goog.asserts\");\n goog.NATIVE_ARRAY_PROTOTYPES = goog.define(\"goog.NATIVE_ARRAY_PROTOTYPES\", goog.TRUSTED_SITE);\n const ASSUME_NATIVE_FUNCTIONS = goog.define(\"goog.array.ASSUME_NATIVE_FUNCTIONS\", goog.FEATURESET_YEAR > 2012);\n exports.ASSUME_NATIVE_FUNCTIONS = ASSUME_NATIVE_FUNCTIONS;\n function peek(array) {\n return array[array.length - 1];\n }\n exports.peek = peek;\n exports.last = peek;\n const indexOf = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ? function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\n } : function(arr, obj, opt_fromIndex) {\n const fromIndex = opt_fromIndex == null ? 0 : opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex;\n if (typeof arr === \"string\") {\n if (typeof obj !== \"string\" || obj.length != 1) {\n return -1;\n }\n return arr.indexOf(obj, fromIndex);\n }\n for (let i = fromIndex; i < arr.length; i++) {\n if (i in arr && arr[i] === obj) {\n return i;\n }\n }\n return -1;\n };\n exports.indexOf = indexOf;\n const lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ? function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n const fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\n } : function(arr, obj, opt_fromIndex) {\n let fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n if (fromIndex < 0) {\n fromIndex = Math.max(0, arr.length + fromIndex);\n }\n if (typeof arr === \"string\") {\n if (typeof obj !== \"string\" || obj.length != 1) {\n return -1;\n }\n return arr.lastIndexOf(obj, fromIndex);\n }\n for (let i = fromIndex; i >= 0; i--) {\n if (i in arr && arr[i] === obj) {\n return i;\n }\n }\n return -1;\n };\n exports.lastIndexOf = lastIndexOf;\n const forEach = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n Array.prototype.forEach.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n f.call(opt_obj, arr2[i], i, arr);\n }\n }\n };\n exports.forEach = forEach;\n function forEachRight(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = l - 1; i >= 0; --i) {\n if (i in arr2) {\n f.call(opt_obj, arr2[i], i, arr);\n }\n }\n }\n exports.forEachRight = forEachRight;\n const filter = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n return Array.prototype.filter.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const res = [];\n let resLength = 0;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n const val = arr2[i];\n if (f.call(opt_obj, val, i, arr)) {\n res[resLength++] = val;\n }\n }\n }\n return res;\n };\n exports.filter = filter;\n const map = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n return Array.prototype.map.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const res = new Array(l);\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n res[i] = f.call(opt_obj, arr2[i], i, arr);\n }\n }\n return res;\n };\n exports.map = map;\n const reduce = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ? function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduce.call(arr, f, val);\n } : function(arr, f, val, opt_obj) {\n let rval = val;\n forEach(arr, function(val, index) {\n rval = f.call(opt_obj, rval, val, index, arr);\n });\n return rval;\n };\n exports.reduce = reduce;\n const reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ? function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n asserts.assert(f != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduceRight.call(arr, f, val);\n } : function(arr, f, val, opt_obj) {\n let rval = val;\n forEachRight(arr, function(val, index) {\n rval = f.call(opt_obj, rval, val, index, arr);\n });\n return rval;\n };\n exports.reduceRight = reduceRight;\n const some = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n return Array.prototype.some.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {\n return true;\n }\n }\n return false;\n };\n exports.some = some;\n const every = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n return Array.prototype.every.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) {\n return false;\n }\n }\n return true;\n };\n exports.every = every;\n function count(arr, f, opt_obj) {\n let count = 0;\n forEach(arr, function(element, index, arr) {\n if (f.call(opt_obj, element, index, arr)) {\n ++count;\n }\n }, opt_obj);\n return count;\n }\n exports.count = count;\n function find(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === \"string\" ? arr.charAt(i) : arr[i];\n }\n exports.find = find;\n function findIndex(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n }\n exports.findIndex = findIndex;\n function findRight(arr, f, opt_obj) {\n const i = findIndexRight(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === \"string\" ? arr.charAt(i) : arr[i];\n }\n exports.findRight = findRight;\n function findIndexRight(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = l - 1; i >= 0; i--) {\n if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n }\n exports.findIndexRight = findIndexRight;\n function contains(arr, obj) {\n return indexOf(arr, obj) >= 0;\n }\n exports.contains = contains;\n function isEmpty(arr) {\n return arr.length == 0;\n }\n exports.isEmpty = isEmpty;\n function clear(arr) {\n if (!Array.isArray(arr)) {\n for (let i = arr.length - 1; i >= 0; i--) {\n delete arr[i];\n }\n }\n arr.length = 0;\n }\n exports.clear = clear;\n function insert(arr, obj) {\n if (!contains(arr, obj)) {\n arr.push(obj);\n }\n }\n exports.insert = insert;\n function insertAt(arr, obj, opt_i) {\n splice(arr, opt_i, 0, obj);\n }\n exports.insertAt = insertAt;\n function insertArrayAt(arr, elementsToAdd, opt_i) {\n goog.partial(splice, arr, opt_i, 0).apply(null, elementsToAdd);\n }\n exports.insertArrayAt = insertArrayAt;\n function insertBefore(arr, obj, opt_obj2) {\n let i;\n if (arguments.length == 2 || (i = indexOf(arr, opt_obj2)) < 0) {\n arr.push(obj);\n } else {\n insertAt(arr, obj, i);\n }\n }\n exports.insertBefore = insertBefore;\n function remove(arr, obj) {\n const i = indexOf(arr, obj);\n let rv;\n if (rv = i >= 0) {\n removeAt(arr, i);\n }\n return rv;\n }\n exports.remove = remove;\n function removeLast(arr, obj) {\n const i = lastIndexOf(arr, obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n }\n exports.removeLast = removeLast;\n function removeAt(arr, i) {\n asserts.assert(arr.length != null);\n return Array.prototype.splice.call(arr, i, 1).length == 1;\n }\n exports.removeAt = removeAt;\n function removeIf(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n }\n exports.removeIf = removeIf;\n function removeAllIf(arr, f, opt_obj) {\n let removedCount = 0;\n forEachRight(arr, function(val, index) {\n if (f.call(opt_obj, val, index, arr)) {\n if (removeAt(arr, index)) {\n removedCount++;\n }\n }\n });\n return removedCount;\n }\n exports.removeAllIf = removeAllIf;\n function concat(var_args) {\n return Array.prototype.concat.apply([], arguments);\n }\n exports.concat = concat;\n function join(var_args) {\n return Array.prototype.concat.apply([], arguments);\n }\n exports.join = join;\n function toArray(object) {\n const length = object.length;\n if (length > 0) {\n const rv = new Array(length);\n for (let i = 0; i < length; i++) {\n rv[i] = object[i];\n }\n return rv;\n }\n return [];\n }\n exports.toArray = toArray;\n const clone = toArray;\n exports.clone = clone;\n function extend(arr1, var_args) {\n for (let i = 1; i < arguments.length; i++) {\n const arr2 = arguments[i];\n if (goog.isArrayLike(arr2)) {\n const len1 = arr1.length || 0;\n const len2 = arr2.length || 0;\n arr1.length = len1 + len2;\n for (let j = 0; j < len2; j++) {\n arr1[len1 + j] = arr2[j];\n }\n } else {\n arr1.push(arr2);\n }\n }\n }\n exports.extend = extend;\n function splice(arr, index, howMany, var_args) {\n asserts.assert(arr.length != null);\n return Array.prototype.splice.apply(arr, slice(arguments, 1));\n }\n exports.splice = splice;\n function slice(arr, start, opt_end) {\n asserts.assert(arr.length != null);\n if (arguments.length <= 2) {\n return Array.prototype.slice.call(arr, start);\n } else {\n return Array.prototype.slice.call(arr, start, opt_end);\n }\n }\n exports.slice = slice;\n function removeDuplicates(arr, opt_rv, opt_hashFn) {\n const returnArray = opt_rv || arr;\n const defaultHashFn = function(item) {\n return goog.isObject(item) ? \"o\" + goog.getUid(item) : (typeof item).charAt(0) + item;\n };\n const hashFn = opt_hashFn || defaultHashFn;\n let cursorInsert = 0;\n let cursorRead = 0;\n const seen = {};\n while (cursorRead < arr.length) {\n const current = arr[cursorRead++];\n const key = hashFn(current);\n if (!Object.prototype.hasOwnProperty.call(seen, key)) {\n seen[key] = true;\n returnArray[cursorInsert++] = current;\n }\n }\n returnArray.length = cursorInsert;\n }\n exports.removeDuplicates = removeDuplicates;\n function binarySearch(arr, target, opt_compareFn) {\n return binarySearch_(arr, opt_compareFn || defaultCompare, false, target);\n }\n exports.binarySearch = binarySearch;\n function binarySelect(arr, evaluator, opt_obj) {\n return binarySearch_(arr, evaluator, true, undefined, opt_obj);\n }\n exports.binarySelect = binarySelect;\n function binarySearch_(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\n let left = 0;\n let right = arr.length;\n let found;\n while (left < right) {\n const middle = left + (right - left >>> 1);\n let compareResult;\n if (isEvaluator) {\n compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\n } else {\n compareResult = compareFn(opt_target, arr[middle]);\n }\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : -left - 1;\n }\n function sort(arr, opt_compareFn) {\n arr.sort(opt_compareFn || defaultCompare);\n }\n exports.sort = sort;\n function stableSort(arr, opt_compareFn) {\n const compArr = new Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n compArr[i] = {index:i, value:arr[i]};\n }\n const valueCompareFn = opt_compareFn || defaultCompare;\n function stableCompareFn(obj1, obj2) {\n return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\n }\n sort(compArr, stableCompareFn);\n for (let i = 0; i < arr.length; i++) {\n arr[i] = compArr[i].value;\n }\n }\n exports.stableSort = stableSort;\n function sortByKey(arr, keyFn, opt_compareFn) {\n const keyCompareFn = opt_compareFn || defaultCompare;\n sort(arr, function(a, b) {\n return keyCompareFn(keyFn(a), keyFn(b));\n });\n }\n exports.sortByKey = sortByKey;\n function sortObjectsByKey(arr, key, opt_compareFn) {\n sortByKey(arr, function(obj) {\n return obj[key];\n }, opt_compareFn);\n }\n exports.sortObjectsByKey = sortObjectsByKey;\n function isSorted(arr, opt_compareFn, opt_strict) {\n const compare = opt_compareFn || defaultCompare;\n for (let i = 1; i < arr.length; i++) {\n const compareResult = compare(arr[i - 1], arr[i]);\n if (compareResult > 0 || compareResult == 0 && opt_strict) {\n return false;\n }\n }\n return true;\n }\n exports.isSorted = isSorted;\n function equals(arr1, arr2, opt_equalsFn) {\n if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length != arr2.length) {\n return false;\n }\n const l = arr1.length;\n const equalsFn = opt_equalsFn || defaultCompareEquality;\n for (let i = 0; i < l; i++) {\n if (!equalsFn(arr1[i], arr2[i])) {\n return false;\n }\n }\n return true;\n }\n exports.equals = equals;\n function compare3(arr1, arr2, opt_compareFn) {\n const compare = opt_compareFn || defaultCompare;\n const l = Math.min(arr1.length, arr2.length);\n for (let i = 0; i < l; i++) {\n const result = compare(arr1[i], arr2[i]);\n if (result != 0) {\n return result;\n }\n }\n return defaultCompare(arr1.length, arr2.length);\n }\n exports.compare3 = compare3;\n function defaultCompare(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n }\n exports.defaultCompare = defaultCompare;\n function inverseDefaultCompare(a, b) {\n return -defaultCompare(a, b);\n }\n exports.inverseDefaultCompare = inverseDefaultCompare;\n function defaultCompareEquality(a, b) {\n return a === b;\n }\n exports.defaultCompareEquality = defaultCompareEquality;\n function binaryInsert(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n if (index < 0) {\n insertAt(array, value, -(index + 1));\n return true;\n }\n return false;\n }\n exports.binaryInsert = binaryInsert;\n function binaryRemove(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n return index >= 0 ? removeAt(array, index) : false;\n }\n exports.binaryRemove = binaryRemove;\n function bucket(array, sorter, opt_obj) {\n const buckets = {};\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter.call(opt_obj, value, i, array);\n if (key !== undefined) {\n const bucket = buckets[key] || (buckets[key] = []);\n bucket.push(value);\n }\n }\n return buckets;\n }\n exports.bucket = bucket;\n function bucketToMap(array, sorter) {\n const buckets = new Map();\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter(value, i, array);\n if (key !== undefined) {\n let bucket = buckets.get(key);\n if (!bucket) {\n bucket = [];\n buckets.set(key, bucket);\n }\n bucket.push(value);\n }\n }\n return buckets;\n }\n exports.bucketToMap = bucketToMap;\n function toObject(arr, keyFunc, opt_obj) {\n const ret = {};\n forEach(arr, function(element, index) {\n ret[keyFunc.call(opt_obj, element, index, arr)] = element;\n });\n return ret;\n }\n exports.toObject = toObject;\n function toMap(arr, keyFunc) {\n const map = new Map();\n for (let i = 0; i < arr.length; i++) {\n const element = arr[i];\n map.set(keyFunc(element, i, arr), element);\n }\n return map;\n }\n exports.toMap = toMap;\n function range(startOrEnd, opt_end, opt_step) {\n const array = [];\n let start = 0;\n let end = startOrEnd;\n const step = opt_step || 1;\n if (opt_end !== undefined) {\n start = startOrEnd;\n end = opt_end;\n }\n if (step * (end - start) < 0) {\n return [];\n }\n if (step > 0) {\n for (let i = start; i < end; i += step) {\n array.push(i);\n }\n } else {\n for (let i = start; i > end; i += step) {\n array.push(i);\n }\n }\n return array;\n }\n exports.range = range;\n function repeat(value, n) {\n const array = [];\n for (let i = 0; i < n; i++) {\n array[i] = value;\n }\n return array;\n }\n exports.repeat = repeat;\n function flatten(var_args) {\n const CHUNK_SIZE = 8192;\n const result = [];\n for (let i = 0; i < arguments.length; i++) {\n const element = arguments[i];\n if (Array.isArray(element)) {\n for (let c = 0; c < element.length; c += CHUNK_SIZE) {\n const chunk = slice(element, c, c + CHUNK_SIZE);\n const recurseResult = flatten.apply(null, chunk);\n for (let r = 0; r < recurseResult.length; r++) {\n result.push(recurseResult[r]);\n }\n }\n } else {\n result.push(element);\n }\n }\n return result;\n }\n exports.flatten = flatten;\n function rotate(array, n) {\n asserts.assert(array.length != null);\n if (array.length) {\n n %= array.length;\n if (n > 0) {\n Array.prototype.unshift.apply(array, array.splice(-n, n));\n } else if (n < 0) {\n Array.prototype.push.apply(array, array.splice(0, -n));\n }\n }\n return array;\n }\n exports.rotate = rotate;\n function moveItem(arr, fromIndex, toIndex) {\n asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\n asserts.assert(toIndex >= 0 && toIndex < arr.length);\n const removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\n Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\n }\n exports.moveItem = moveItem;\n function zip(var_args) {\n if (!arguments.length) {\n return [];\n }\n const result = [];\n let minLen = arguments[0].length;\n for (let i = 1; i < arguments.length; i++) {\n if (arguments[i].length < minLen) {\n minLen = arguments[i].length;\n }\n }\n for (let i = 0; i < minLen; i++) {\n const value = [];\n for (let j = 0; j < arguments.length; j++) {\n value.push(arguments[j][i]);\n }\n result.push(value);\n }\n return result;\n }\n exports.zip = zip;\n function shuffle(arr, opt_randFn) {\n const randFn = opt_randFn || Math.random;\n for (let i = arr.length - 1; i > 0; i--) {\n const j = Math.floor(randFn() * (i + 1));\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n }\n }\n exports.shuffle = shuffle;\n function copyByIndex(arr, index_arr) {\n const result = [];\n forEach(index_arr, function(index) {\n result.push(arr[index]);\n });\n return result;\n }\n exports.copyByIndex = copyByIndex;\n function concatMap(arr, f, opt_obj) {\n return concat.apply([], map(arr, f, opt_obj));\n }\n exports.concatMap = concatMap;\n return exports;\n});\n","~:source","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for manipulating arrays.\n */\n\n\ngoog.module('goog.array');\ngoog.module.declareLegacyNamespace();\n\nconst asserts = goog.require('goog.asserts');\n\n\n/**\n * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should\n * rely on Array.prototype functions, if available.\n *\n * The Array.prototype functions can be defined by external libraries like\n * Prototype and setting this flag to false forces closure to use its own\n * goog.array implementation.\n *\n * If your javascript can be loaded by a third party site and you are wary about\n * relying on the prototype functions, specify\n * \"--define goog.NATIVE_ARRAY_PROTOTYPES=false\" to the JSCompiler.\n *\n * Setting goog.TRUSTED_SITE to false will automatically set\n * NATIVE_ARRAY_PROTOTYPES to false.\n */\ngoog.NATIVE_ARRAY_PROTOTYPES =\n goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);\n\n\n/**\n * @define {boolean} If true, JSCompiler will use the native implementation of\n * array functions where appropriate (e.g., `Array#filter`) and remove the\n * unused pure JS implementation.\n */\nconst ASSUME_NATIVE_FUNCTIONS = goog.define(\n 'goog.array.ASSUME_NATIVE_FUNCTIONS', goog.FEATURESET_YEAR > 2012);\nexports.ASSUME_NATIVE_FUNCTIONS = ASSUME_NATIVE_FUNCTIONS;\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as {@link goog.array.last}.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\nfunction peek(array) {\n return array[array.length - 1];\n}\nexports.peek = peek;\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as {@link goog.array.peek}.\n * @param {IArrayLike<T>|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\nexports.last = peek;\n\n// NOTE(arv): Since most of the array functions are generic it allows you to\n// pass an array-like object. Strings have a length and are considered array-\n// like. However, the 'in' operator does not work on strings so we cannot just\n// use the array path even if the browser supports indexing into strings. We\n// therefore end up splitting the string.\n\n\n/**\n * Returns the index of the first element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}\n *\n * @param {IArrayLike<T>|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {number=} opt_fromIndex The index at which to start the search. If\n * omitted the search starts at index 0.\n * @return {number} The index of the first matching array element.\n * @template T\n */\nconst indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ?\n function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\n } :\n function(arr, obj, opt_fromIndex) {\n const fromIndex = opt_fromIndex == null ?\n 0 :\n (opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) :\n opt_fromIndex);\n\n if (typeof arr === 'string') {\n // Array.prototype.indexOf uses === so only strings should be found.\n if (typeof obj !== 'string' || obj.length != 1) {\n return -1;\n }\n return arr.indexOf(obj, fromIndex);\n }\n\n for (let i = fromIndex; i < arr.length; i++) {\n if (i in arr && arr[i] === obj) return i;\n }\n return -1;\n };\nexports.indexOf = indexOf;\n\n\n/**\n * Returns the index of the last element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}\n *\n * @param {!IArrayLike<T>|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {?number=} opt_fromIndex The index at which to start the search. If\n * omitted the search starts at the end of the array.\n * @return {number} The index of the last matching array element.\n * @template T\n */\nconst lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ?\n function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n\n // Firefox treats undefined and null as 0 in the fromIndex argument which\n // leads it to always return -1\n const fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\n } :\n function(arr, obj, opt_fromIndex) {\n let fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n\n if (fromIndex < 0) {\n fromIndex = Math.max(0, arr.length + fromIndex);\n }\n\n if (typeof arr === 'string') {\n // Array.prototype.lastIndexOf uses === so only strings should be found.\n if (typeof obj !== 'string' || obj.length != 1) {\n return -1;\n }\n return arr.lastIndexOf(obj, fromIndex);\n }\n\n for (let i = fromIndex; i >= 0; i--) {\n if (i in arr && arr[i] === obj) return i;\n }\n return -1;\n };\nexports.lastIndexOf = lastIndexOf;\n\n\n/**\n * Calls a function for each element in an array. Skips holes in the array.\n * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}\n *\n * @param {IArrayLike<T>|string} arr Array or array like object over\n * which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n * element. This function takes 3 arguments (the element, the index and the\n * array). The return value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @template T,S\n */\nconst forEach = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n Array.prototype.forEach.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n };\nexports.forEach = forEach;\n\n\n/**\n * Calls a function for each element in an array, starting from the last\n * element rather than the first.\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n * element. This function\n * takes 3 arguments (the element, the index and the array). The return\n * value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @template T,S\n */\nfunction forEachRight(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = l - 1; i >= 0; --i) {\n if (i in arr2) {\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n}\nexports.forEachRight = forEachRight;\n\n\n/**\n * Calls a function for each element in an array, and if the function returns\n * true adds the element to a new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?):boolean} f The function to call for\n * every element. This function\n * takes 3 arguments (the element, the index and the array) and must\n * return a Boolean. If the return value is true the element is added to the\n * result array. If it is false the element is not included.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {!Array<T>} a new array in which only elements that passed the test\n * are present.\n * @template T,S\n */\nconst filter = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.filter.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const res = [];\n let resLength = 0;\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n const val = arr2[i]; // in case f mutates arr2\n if (f.call(/** @type {?} */ (opt_obj), val, i, arr)) {\n res[resLength++] = val;\n }\n }\n }\n return res;\n };\nexports.filter = filter;\n\n\n/**\n * Calls a function for each element in an array and inserts the result into a\n * new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-map}\n *\n * @param {IArrayLike<VALUE>|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call\n * for every element. This function takes 3 arguments (the element,\n * the index and the array) and should return something. The result will be\n * inserted into a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array<RESULT>} a new array with the results from f.\n * @template THIS, VALUE, RESULT\n */\nconst map = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.map.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const res = new Array(l);\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n res[i] = f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n return res;\n };\nexports.map = map;\n\n\n/**\n * Passes every element of an array into a function and accumulates the result.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}\n * Note that this implementation differs from the native Array.prototype.reduce\n * in that the initial value is assumed to be defined (the MDN docs linked above\n * recommend not omitting this parameter, although it is technically optional).\n *\n * For example:\n * var a = [1, 2, 3, 4];\n * reduce(a, function(r, v, i, arr) {return r + v;}, 0);\n * returns 10\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {function(this:S, R, T, number, ?) : R} f The function to call for\n * every element. This function\n * takes 4 arguments (the function's previous result or the initial value,\n * the value of the current array element, the current array index, and the\n * array itself)\n * function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {R} Result of evaluating f repeatedly across the values of the array.\n * @template T,S,R\n */\nconst reduce = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ?\n function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduce.call(arr, f, val);\n } :\n function(arr, f, val, opt_obj) {\n let rval = val;\n forEach(arr, function(val, index) {\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n });\n return rval;\n };\nexports.reduce = reduce;\n\n\n/**\n * Passes every element of an array into a function and accumulates the result,\n * starting from the last element and working towards the first.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}\n *\n * For example:\n * var a = ['a', 'b', 'c'];\n * reduceRight(a, function(r, v, i, arr) {return r + v;}, '');\n * returns 'cba'\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, R, T, number, ?) : R} f The function to call for\n * every element. This function\n * takes 4 arguments (the function's previous result or the initial value,\n * the value of the current array element, the current array index, and the\n * array itself)\n * function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {R} Object returned as a result of evaluating f repeatedly across the\n * values of the array.\n * @template T,S,R\n */\nconst reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ?\n function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n asserts.assert(f != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduceRight.call(arr, f, val);\n } :\n function(arr, f, val, opt_obj) {\n let rval = val;\n forEachRight(arr, function(val, index) {\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n });\n return rval;\n };\nexports.reduceRight = reduceRight;\n\n\n/**\n * Calls f for each element of an array. If any call returns true, some()\n * returns true (without checking the remaining elements). If all calls\n * return false, some() returns false.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-some}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {boolean} true if any element passes the test.\n * @template T,S\n */\nconst some = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.some.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return true;\n }\n }\n return false;\n };\nexports.some = some;\n\n\n/**\n * Call f for each element of an array. If all calls return true, every()\n * returns true. If any call returns false, every() returns false and\n * does not continue to check the remaining elements.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-every}\n *\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {boolean} false if any element fails the test.\n * @template T,S\n */\nconst every = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.every.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && !f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return false;\n }\n }\n return true;\n };\nexports.every = every;\n\n\n/**\n * Counts the array elements that fulfill the predicate, i.e. for which the\n * callback function returns true. Skips holes in the array.\n *\n * @param {!IArrayLike<T>|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this: S, T, number, ?): boolean} f The function to call for\n * every element. Takes 3 arguments (the element, the index and the array).\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @return {number} The number of the matching elements.\n * @template T,S\n */\nfunction count(arr, f, opt_obj) {\n let count = 0;\n forEach(arr, function(element, index, arr) {\n if (f.call(/** @type {?} */ (opt_obj), element, index, arr)) {\n ++count;\n }\n }, opt_obj);\n return count;\n}\nexports.count = count;\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return that element.\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The first array element that passes the test, or null if no\n * element is found.\n * @template T,S\n */\nfunction find(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n}\nexports.find = find;\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return its index.\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the first array element that passes the test,\n * or -1 if no element is found.\n * @template T,S\n */\nfunction findIndex(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n}\nexports.findIndex = findIndex;\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return that element.\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The last array element that passes the test, or null if no\n * element is found.\n * @template T,S\n */\nfunction findRight(arr, f, opt_obj) {\n const i = findIndexRight(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n}\nexports.findRight = findRight;\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return its index.\n * @param {IArrayLike<T>|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the last array element that passes the test,\n * or -1 if no element is found.\n * @template T,S\n */\nfunction findIndexRight(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = l - 1; i >= 0; i--) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n}\nexports.findIndexRight = findIndexRight;\n\n\n/**\n * Whether the array contains the given object.\n * @param {IArrayLike<?>|string} arr The array to test for the presence of the\n * element.\n * @param {*} obj The object for which to test.\n * @return {boolean} true if obj is present.\n */\nfunction contains(arr, obj) {\n return indexOf(arr, obj) >= 0;\n}\nexports.contains = contains;\n\n\n/**\n * Whether the array is empty.\n * @param {IArrayLike<?>|string} arr The array to test.\n * @return {boolean} true if empty.\n */\nfunction isEmpty(arr) {\n return arr.length == 0;\n}\nexports.isEmpty = isEmpty;\n\n\n/**\n * Clears the array.\n * @param {IArrayLike<?>} arr Array or array like object to clear.\n */\nfunction clear(arr) {\n // For non real arrays we don't have the magic length so we delete the\n // indices.\n if (!Array.isArray(arr)) {\n for (let i = arr.length - 1; i >= 0; i--) {\n delete arr[i];\n }\n }\n arr.length = 0;\n}\nexports.clear = clear;\n\n\n/**\n * Pushes an item into an array, if it's not already in the array.\n * @param {Array<T>} arr Array into which to insert the item.\n * @param {T} obj Value to add.\n * @template T\n */\nfunction insert(arr, obj) {\n if (!contains(arr, obj)) {\n arr.push(obj);\n }\n}\nexports.insert = insert;\n\n\n/**\n * Inserts an object at the given index of the array.\n * @param {IArrayLike<?>} arr The array to modify.\n * @param {*} obj The object to insert.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n * treated as 0. A negative index is counted from the end of the array.\n */\nfunction insertAt(arr, obj, opt_i) {\n splice(arr, opt_i, 0, obj);\n}\nexports.insertAt = insertAt;\n\n\n/**\n * Inserts at the given index of the array, all elements of another array.\n * @param {IArrayLike<?>} arr The array to modify.\n * @param {IArrayLike<?>} elementsToAdd The array of elements to add.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n * treated as 0. A negative index is counted from the end of the array.\n */\nfunction insertArrayAt(arr, elementsToAdd, opt_i) {\n goog.partial(splice, arr, opt_i, 0).apply(null, elementsToAdd);\n}\nexports.insertArrayAt = insertArrayAt;\n\n\n/**\n * Inserts an object into an array before a specified object.\n * @param {Array<T>} arr The array to modify.\n * @param {T} obj The object to insert.\n * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2\n * is omitted or not found, obj is inserted at the end of the array.\n * @template T\n */\nfunction insertBefore(arr, obj, opt_obj2) {\n let i;\n if (arguments.length == 2 || (i = indexOf(arr, opt_obj2)) < 0) {\n arr.push(obj);\n } else {\n insertAt(arr, obj, i);\n }\n}\nexports.insertBefore = insertBefore;\n\n\n/**\n * Removes the first occurrence of a particular value from an array.\n * @param {IArrayLike<T>} arr Array from which to remove\n * value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\nfunction remove(arr, obj) {\n const i = indexOf(arr, obj);\n let rv;\n if ((rv = i >= 0)) {\n removeAt(arr, i);\n }\n return rv;\n}\nexports.remove = remove;\n\n\n/**\n * Removes the last occurrence of a particular value from an array.\n * @param {!IArrayLike<T>} arr Array from which to remove value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\nfunction removeLast(arr, obj) {\n const i = lastIndexOf(arr, obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n}\nexports.removeLast = removeLast;\n\n\n/**\n * Removes from an array the element at index i\n * @param {IArrayLike<?>} arr Array or array like object from which to\n * remove value.\n * @param {number} i The index to remove.\n * @return {boolean} True if an element was removed.\n */\nfunction removeAt(arr, i) {\n asserts.assert(arr.length != null);\n\n // use generic form of splice\n // splice returns the removed items and if successful the length of that\n // will be 1\n return Array.prototype.splice.call(arr, i, 1).length == 1;\n}\nexports.removeAt = removeAt;\n\n\n/**\n * Removes the first value that satisfies the given condition.\n * @param {IArrayLike<T>} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {boolean} True if an element was removed.\n * @template T,S\n */\nfunction removeIf(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n}\nexports.removeIf = removeIf;\n\n\n/**\n * Removes all values that satisfy the given condition.\n * @param {IArrayLike<T>} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The number of items removed\n * @template T,S\n */\nfunction removeAllIf(arr, f, opt_obj) {\n let removedCount = 0;\n forEachRight(arr, function(val, index) {\n if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) {\n if (removeAt(arr, index)) {\n removedCount++;\n }\n }\n });\n return removedCount;\n}\nexports.removeAllIf = removeAllIf;\n\n\n/**\n * Returns a new array that is the result of joining the arguments. If arrays\n * are passed then their items are added, however, if non-arrays are passed they\n * will be added to the return array as is.\n *\n * Note that ArrayLike objects will be added as is, rather than having their\n * items added.\n *\n * concat([1, 2], [3, 4]) -> [1, 2, 3, 4]\n * concat(0, [1, 2]) -> [0, 1, 2]\n * concat([1, 2], null) -> [1, 2, null]\n *\n * @param {...*} var_args Items to concatenate. Arrays will have each item\n * added, while primitives and objects will be added as is.\n * @return {!Array<?>} The new resultant array.\n */\nfunction concat(var_args) {\n return Array.prototype.concat.apply([], arguments);\n}\nexports.concat = concat;\n\n\n/**\n * Returns a new array that contains the contents of all the arrays passed.\n * @param {...!Array<T>} var_args\n * @return {!Array<T>}\n * @template T\n */\nfunction join(var_args) {\n return Array.prototype.concat.apply([], arguments);\n}\nexports.join = join;\n\n\n/**\n * Converts an object to an array.\n * @param {IArrayLike<T>|string} object The object to convert to an\n * array.\n * @return {!Array<T>} The object converted into an array. If object has a\n * length property, every property indexed with a non-negative number\n * less than length will be included in the result. If object does not\n * have a length property, an empty array will be returned.\n * @template T\n */\nfunction toArray(object) {\n const length = object.length;\n\n // If length is not a number the following is false. This case is kept for\n // backwards compatibility since there are callers that pass objects that are\n // not array like.\n if (length > 0) {\n const rv = new Array(length);\n for (let i = 0; i < length; i++) {\n rv[i] = object[i];\n }\n return rv;\n }\n return [];\n}\nexports.toArray = toArray;\n\n\n/**\n * Does a shallow copy of an array.\n * @param {IArrayLike<T>|string} arr Array or array-like object to\n * clone.\n * @return {!Array<T>} Clone of the input array.\n * @template T\n */\nconst clone = toArray;\nexports.clone = clone;\n\n\n/**\n * Extends an array with another array, element, or \"array like\" object.\n * This function operates 'in-place', it does not create a new Array.\n *\n * Example:\n * var a = [];\n * extend(a, [0, 1]);\n * a; // [0, 1]\n * extend(a, 2);\n * a; // [0, 1, 2]\n *\n * @param {Array<VALUE>} arr1 The array to modify.\n * @param {...(IArrayLike<VALUE>|VALUE)} var_args The elements or arrays of\n * elements to add to arr1.\n * @template VALUE\n */\nfunction extend(arr1, var_args) {\n for (let i = 1; i < arguments.length; i++) {\n const arr2 = arguments[i];\n if (goog.isArrayLike(arr2)) {\n const len1 = arr1.length || 0;\n const len2 = arr2.length || 0;\n arr1.length = len1 + len2;\n for (let j = 0; j < len2; j++) {\n arr1[len1 + j] = arr2[j];\n }\n } else {\n arr1.push(arr2);\n }\n }\n}\nexports.extend = extend;\n\n\n/**\n * Adds or removes elements from an array. This is a generic version of Array\n * splice. This means that it might work on other objects similar to arrays,\n * such as the arguments object.\n *\n * @param {IArrayLike<T>} arr The array to modify.\n * @param {number|undefined} index The index at which to start changing the\n * array. If not defined, treated as 0.\n * @param {number} howMany How many elements to remove (0 means no removal. A\n * value below 0 is treated as zero and so is any other non number. Numbers\n * are floored).\n * @param {...T} var_args Optional, additional elements to insert into the\n * array.\n * @return {!Array<T>} the removed elements.\n * @template T\n */\nfunction splice(arr, index, howMany, var_args) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.splice.apply(arr, slice(arguments, 1));\n}\nexports.splice = splice;\n\n\n/**\n * Returns a new array from a segment of an array. This is a generic version of\n * Array slice. This means that it might work on other objects similar to\n * arrays, such as the arguments object.\n *\n * @param {IArrayLike<T>|string} arr The array from\n * which to copy a segment.\n * @param {number} start The index of the first element to copy.\n * @param {number=} opt_end The index after the last element to copy.\n * @return {!Array<T>} A new array containing the specified segment of the\n * original array.\n * @template T\n */\nfunction slice(arr, start, opt_end) {\n asserts.assert(arr.length != null);\n\n // passing 1 arg to slice is not the same as passing 2 where the second is\n // null or undefined (in that case the second argument is treated as 0).\n // we could use slice on the arguments object and then use apply instead of\n // testing the length\n if (arguments.length <= 2) {\n return Array.prototype.slice.call(arr, start);\n } else {\n return Array.prototype.slice.call(arr, start, opt_end);\n }\n}\nexports.slice = slice;\n\n\n/**\n * Removes all duplicates from an array (retaining only the first\n * occurrence of each array element). This function modifies the\n * array in place and doesn't change the order of the non-duplicate items.\n *\n * For objects, duplicates are identified as having the same unique ID as\n * defined by {@link goog.getUid}.\n *\n * Alternatively you can specify a custom hash function that returns a unique\n * value for each item in the array it should consider unique.\n *\n * Runtime: N,\n * Worstcase space: 2N (no dupes)\n *\n * @param {IArrayLike<T>} arr The array from which to remove\n * duplicates.\n * @param {Array=} opt_rv An optional array in which to return the results,\n * instead of performing the removal inplace. If specified, the original\n * array will remain unchanged.\n * @param {function(T):string=} opt_hashFn An optional function to use to\n * apply to every item in the array. This function should return a unique\n * value for each item in the array it should consider unique.\n * @template T\n */\nfunction removeDuplicates(arr, opt_rv, opt_hashFn) {\n const returnArray = opt_rv || arr;\n const defaultHashFn = function(item) {\n // Prefix each type with a single character representing the type to\n // prevent conflicting keys (e.g. true and 'true').\n return goog.isObject(item) ? 'o' + goog.getUid(item) :\n (typeof item).charAt(0) + item;\n };\n const hashFn = opt_hashFn || defaultHashFn;\n\n let cursorInsert = 0;\n let cursorRead = 0;\n const seen = {};\n\n while (cursorRead < arr.length) {\n const current = arr[cursorRead++];\n const key = hashFn(current);\n if (!Object.prototype.hasOwnProperty.call(seen, key)) {\n seen[key] = true;\n returnArray[cursorInsert++] = current;\n }\n }\n returnArray.length = cursorInsert;\n}\nexports.removeDuplicates = removeDuplicates;\n\n\n/**\n * Searches the specified array for the specified target using the binary\n * search algorithm. If no opt_compareFn is specified, elements are compared\n * using <code>defaultCompare</code>, which compares the elements\n * using the built in < and > operators. This will produce the expected\n * behavior for homogeneous arrays of String(s) and Number(s). The array\n * specified <b>must</b> be sorted in ascending order (as defined by the\n * comparison function). If the array is not sorted, results are undefined.\n * If the array contains multiple instances of the specified target value, the\n * left-most instance will be found.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<VALUE>} arr The array to be searched.\n * @param {TARGET} target The sought value.\n * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, the target value and an element from your array, and return a\n * negative number, zero, or a positive number depending on whether the\n * first argument is less than, equal to, or greater than the second.\n * @return {number} Lowest index of the target value if found, otherwise\n * (-(insertion point) - 1). The insertion point is where the value should\n * be inserted into arr to preserve the sorted property. Return value >= 0\n * iff target is found.\n * @template TARGET, VALUE\n */\nfunction binarySearch(arr, target, opt_compareFn) {\n return binarySearch_(\n arr, opt_compareFn || defaultCompare, false /* isEvaluator */, target);\n}\nexports.binarySearch = binarySearch;\n\n\n/**\n * Selects an index in the specified array using the binary search algorithm.\n * The evaluator receives an element and determines whether the desired index\n * is before, at, or after it. The evaluator must be consistent (formally,\n * map(map(arr, evaluator, opt_obj), goog.math.sign)\n * must be monotonically non-increasing).\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<VALUE>} arr The array to be searched.\n * @param {function(this:THIS, VALUE, number, ?): number} evaluator\n * Evaluator function that receives 3 arguments (the element, the index and\n * the array). Should return a negative number, zero, or a positive number\n * depending on whether the desired index is before, at, or after the\n * element passed to it.\n * @param {THIS=} opt_obj The object to be used as the value of 'this'\n * within evaluator.\n * @return {number} Index of the leftmost element matched by the evaluator, if\n * such exists; otherwise (-(insertion point) - 1). The insertion point is\n * the index of the first element for which the evaluator returns negative,\n * or arr.length if no such element exists. The return value is non-negative\n * iff a match is found.\n * @template THIS, VALUE\n */\nfunction binarySelect(arr, evaluator, opt_obj) {\n return binarySearch_(\n arr, evaluator, true /* isEvaluator */, undefined /* opt_target */,\n opt_obj);\n}\nexports.binarySelect = binarySelect;\n\n\n/**\n * Implementation of a binary search algorithm which knows how to use both\n * comparison functions and evaluators. If an evaluator is provided, will call\n * the evaluator with the given optional data object, conforming to the\n * interface defined in binarySelect. Otherwise, if a comparison function is\n * provided, will call the comparison function against the given data object.\n *\n * This implementation purposefully does not use goog.bind or goog.partial for\n * performance reasons.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike<?>} arr The array to be searched.\n * @param {function(?, ?, ?): number | function(?, ?): number} compareFn\n * Either an evaluator or a comparison function, as defined by binarySearch\n * and binarySelect above.\n * @param {boolean} isEvaluator Whether the function is an evaluator or a\n * comparison function.\n * @param {?=} opt_target If the function is a comparison function, then\n * this is the target to binary search for.\n * @param {Object=} opt_selfObj If the function is an evaluator, this is an\n * optional this object for the evaluator.\n * @return {number} Lowest index of the target value if found, otherwise\n * (-(insertion point) - 1). The insertion point is where the value should\n * be inserted into arr to preserve the sorted property. Return value >= 0\n * iff target is found.\n * @private\n */\nfunction binarySearch_(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\n let left = 0; // inclusive\n let right = arr.length; // exclusive\n let found;\n while (left < right) {\n const middle = left + ((right - left) >>> 1);\n let compareResult;\n if (isEvaluator) {\n compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\n } else {\n // NOTE(dimvar): To avoid this cast, we'd have to use function overloading\n // for the type of binarySearch_, which the type system can't express yet.\n compareResult = /** @type {function(?, ?): number} */ (compareFn)(\n opt_target, arr[middle]);\n }\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n // We are looking for the lowest index so we can't return immediately.\n found = !compareResult;\n }\n }\n // left is the index if found, or the insertion point otherwise.\n // Avoiding bitwise not operator, as that causes a loss in precision for array\n // indexes outside the bounds of a 32-bit signed integer. Array indexes have\n // a maximum value of 2^32-2 https://tc39.es/ecma262/#array-index\n return found ? left : -left - 1;\n}\n\n\n/**\n * Sorts the specified array into ascending order. If no opt_compareFn is\n * specified, elements are compared using\n * <code>defaultCompare</code>, which compares the elements using\n * the built in < and > operators. This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s), unlike the native sort,\n * but will give unpredictable results for heterogeneous lists of strings and\n * numbers with different numbers of digits.\n *\n * This sort is not guaranteed to be stable.\n *\n * Runtime: Same as `Array.prototype.sort`\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {?function(T,T):number=} opt_compareFn Optional comparison\n * function by which the\n * array is to be ordered. Should take 2 arguments to compare, and return a\n * negative number, zero, or a positive number depending on whether the\n * first argument is less than, equal to, or greater than the second.\n * @template T\n */\nfunction sort(arr, opt_compareFn) {\n // TODO(arv): Update type annotation since null is not accepted.\n arr.sort(opt_compareFn || defaultCompare);\n}\nexports.sort = sort;\n\n\n/**\n * Sorts the specified array into ascending order in a stable way. If no\n * opt_compareFn is specified, elements are compared using\n * <code>defaultCompare</code>, which compares the elements using\n * the built in < and > operators. This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s).\n *\n * Runtime: Same as `Array.prototype.sort`, plus an additional\n * O(n) overhead of copying the array twice.\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {?function(T, T): number=} opt_compareFn Optional comparison function\n * by which the array is to be ordered. Should take 2 arguments to compare,\n * and return a negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template T\n */\nfunction stableSort(arr, opt_compareFn) {\n const compArr = new Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n compArr[i] = {index: i, value: arr[i]};\n }\n const valueCompareFn = opt_compareFn || defaultCompare;\n function stableCompareFn(obj1, obj2) {\n return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\n }\n sort(compArr, stableCompareFn);\n for (let i = 0; i < arr.length; i++) {\n arr[i] = compArr[i].value;\n }\n}\nexports.stableSort = stableSort;\n\n\n/**\n * Sort the specified array into ascending order based on item keys\n * returned by the specified key function.\n * If no opt_compareFn is specified, the keys are compared in ascending order\n * using <code>defaultCompare</code>.\n *\n * Runtime: O(S(f(n)), where S is runtime of <code>sort</code>\n * and f(n) is runtime of the key function.\n *\n * @param {Array<T>} arr The array to be sorted.\n * @param {function(T): K} keyFn Function taking array element and returning\n * a key used for sorting this element.\n * @param {?function(K, K): number=} opt_compareFn Optional comparison function\n * by which the keys are to be ordered. Should take 2 arguments to compare,\n * and return a negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template T,K\n */\nfunction sortByKey(arr, keyFn, opt_compareFn) {\n const keyCompareFn = opt_compareFn || defaultCompare;\n sort(arr, function(a, b) {\n return keyCompareFn(keyFn(a), keyFn(b));\n });\n}\nexports.sortByKey = sortByKey;\n\n\n/**\n * Sorts an array of objects by the specified object key and compare\n * function. If no compare function is provided, the key values are\n * compared in ascending order using <code>defaultCompare</code>.\n * This won't work for keys that get renamed by the compiler. So use\n * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.\n * @param {Array<Object>} arr An array of objects to sort.\n * @param {string} key The object key to sort by.\n * @param {Function=} opt_compareFn The function to use to compare key\n * values.\n */\nfunction sortObjectsByKey(arr, key, opt_compareFn) {\n sortByKey(arr, function(obj) {\n return obj[key];\n }, opt_compareFn);\n}\nexports.sortObjectsByKey = sortObjectsByKey;\n\n\n/**\n * Tells if the array is sorted.\n * @param {!IArrayLike<T>} arr The array.\n * @param {?function(T,T):number=} opt_compareFn Function to compare the\n * array elements.\n * Should take 2 arguments to compare, and return a negative number, zero,\n * or a positive number depending on whether the first argument is less\n * than, equal to, or greater than the second.\n * @param {boolean=} opt_strict If true no equal elements are allowed.\n * @return {boolean} Whether the array is sorted.\n * @template T\n */\nfunction isSorted(arr, opt_compareFn, opt_strict) {\n const compare = opt_compareFn || defaultCompare;\n for (let i = 1; i < arr.length; i++) {\n const compareResult = compare(arr[i - 1], arr[i]);\n if (compareResult > 0 || compareResult == 0 && opt_strict) {\n return false;\n }\n }\n return true;\n}\nexports.isSorted = isSorted;\n\n\n/**\n * Compares two arrays for equality. Two arrays are considered equal if they\n * have the same length and their corresponding elements are equal according to\n * the comparison function.\n *\n * @param {IArrayLike<A>} arr1 The first array to compare.\n * @param {IArrayLike<B>} arr2 The second array to compare.\n * @param {?function(A,B):boolean=} opt_equalsFn Optional comparison function.\n * Should take 2 arguments to compare, and return true if the arguments\n * are equal. Defaults to {@link goog.array.defaultCompareEquality} which\n * compares the elements using the built-in '===' operator.\n * @return {boolean} Whether the two arrays are equal.\n * @template A\n * @template B\n */\nfunction equals(arr1, arr2, opt_equalsFn) {\n if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||\n arr1.length != arr2.length) {\n return false;\n }\n const l = arr1.length;\n const equalsFn = opt_equalsFn || defaultCompareEquality;\n for (let i = 0; i < l; i++) {\n if (!equalsFn(arr1[i], arr2[i])) {\n return false;\n }\n }\n return true;\n}\nexports.equals = equals;\n\n\n/**\n * 3-way array compare function.\n * @param {!IArrayLike<VALUE>} arr1 The first array to\n * compare.\n * @param {!IArrayLike<VALUE>} arr2 The second array to\n * compare.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is to be ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {number} Negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template VALUE\n */\nfunction compare3(arr1, arr2, opt_compareFn) {\n const compare = opt_compareFn || defaultCompare;\n const l = Math.min(arr1.length, arr2.length);\n for (let i = 0; i < l; i++) {\n const result = compare(arr1[i], arr2[i]);\n if (result != 0) {\n return result;\n }\n }\n return defaultCompare(arr1.length, arr2.length);\n}\nexports.compare3 = compare3;\n\n\n/**\n * Compares its two arguments for order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is less than, equal to, or greater than the second,\n * respectively.\n * @template VALUE\n */\nfunction defaultCompare(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n}\nexports.defaultCompare = defaultCompare;\n\n\n/**\n * Compares its two arguments for inverse order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is greater than, equal to, or less than the second,\n * respectively.\n * @template VALUE\n */\nfunction inverseDefaultCompare(a, b) {\n return -defaultCompare(a, b);\n}\nexports.inverseDefaultCompare = inverseDefaultCompare;\n\n\n/**\n * Compares its two arguments for equality, using the built in === operator.\n * @param {*} a The first object to compare.\n * @param {*} b The second object to compare.\n * @return {boolean} True if the two arguments are equal, false otherwise.\n */\nfunction defaultCompareEquality(a, b) {\n return a === b;\n}\nexports.defaultCompareEquality = defaultCompareEquality;\n\n\n/**\n * Inserts a value into a sorted array. The array is not modified if the\n * value is already present.\n * @param {IArrayLike<VALUE>} array The array to modify.\n * @param {VALUE} value The object to insert.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {boolean} True if an element was inserted.\n * @template VALUE\n */\nfunction binaryInsert(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n if (index < 0) {\n insertAt(array, value, -(index + 1));\n return true;\n }\n return false;\n}\nexports.binaryInsert = binaryInsert;\n\n\n/**\n * Removes a value from a sorted array.\n * @param {!IArrayLike<VALUE>} array The array to modify.\n * @param {VALUE} value The object to remove.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {boolean} True if an element was removed.\n * @template VALUE\n */\nfunction binaryRemove(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n return (index >= 0) ? removeAt(array, index) : false;\n}\nexports.binaryRemove = binaryRemove;\n\n\n/**\n * Splits an array into disjoint buckets according to a splitting function.\n * @param {IArrayLike<T>} array The array.\n * @param {function(this:S, T, number, !IArrayLike<T>):?} sorter Function to\n * call for every element. This takes 3 arguments (the element, the index\n * and the array) and must return a valid object key (a string, number,\n * etc), or undefined, if that object should not be placed in a bucket.\n * @param {S=} opt_obj The object to be used as the value of 'this' within\n * sorter.\n * @return {!Object<!Array<T>>} An object, with keys being all of the unique\n * return values of sorter, and values being arrays containing the items for\n * which the splitter returned that key.\n * @template T,S\n */\nfunction bucket(array, sorter, opt_obj) {\n const buckets = {};\n\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter.call(/** @type {?} */ (opt_obj), value, i, array);\n if (key !== undefined) {\n // Push the value to the right bucket, creating it if necessary.\n const bucket = buckets[key] || (buckets[key] = []);\n bucket.push(value);\n }\n }\n\n return buckets;\n}\nexports.bucket = bucket;\n\n\n/**\n * Splits an array into disjoint buckets according to a splitting function.\n * @param {!IArrayLike<V>} array The array.\n * @param {function(V, number, !IArrayLike<V>):(K|undefined)} sorter Function to\n * call for every element. This takes 3 arguments (the element, the index,\n * and the array) and must return a value to use as a key, or undefined, if\n * that object should not be placed in a bucket.\n * @return {!Map<K, !Array<V>>} A map, with keys being all of the unique\n * return values of sorter, and values being arrays containing the items for\n * which the splitter returned that key.\n * @template K,V\n */\nfunction bucketToMap(array, sorter) {\n const /** !Map<K, !Array<V>> */ buckets = new Map();\n\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter(value, i, array);\n if (key !== undefined) {\n // Push the value to the right bucket, creating it if necessary.\n let bucket = buckets.get(key);\n if (!bucket) {\n bucket = [];\n buckets.set(key, bucket);\n }\n bucket.push(value);\n }\n }\n\n return buckets;\n}\nexports.bucketToMap = bucketToMap;\n\n\n/**\n * Creates a new object built from the provided array and the key-generation\n * function.\n * @param {IArrayLike<T>} arr Array or array like object over\n * which to iterate whose elements will be the values in the new object.\n * @param {?function(this:S, T, number, ?) : string} keyFunc The function to\n * call for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a string that will be used as the\n * key for the element in the new object. If the function returns the same\n * key for more than one element, the value for that key is\n * implementation-defined.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within keyFunc.\n * @return {!Object<T>} The new object.\n * @template T,S\n */\nfunction toObject(arr, keyFunc, opt_obj) {\n const ret = {};\n forEach(arr, function(element, index) {\n ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] =\n element;\n });\n return ret;\n}\nexports.toObject = toObject;\n\n\n/**\n * Creates a new ES6 Map built from the provided array and the key-generation\n * function.\n * @param {!IArrayLike<V>} arr Array or array like object over which to iterate\n * whose elements will be the values in the new object.\n * @param {?function(V, number, ?) : K} keyFunc The function to call for every\n * element. This function takes 3 arguments (the element, the index, and the\n * array) and should return a value that will be used as the key for the\n * element in the new object. If the function returns the same key for more\n * than one element, the value for that key is implementation-defined.\n * @return {!Map<K, V>} The new map.\n * @template K,V\n */\nfunction toMap(arr, keyFunc) {\n const /** !Map<K, V> */ map = new Map();\n\n for (let i = 0; i < arr.length; i++) {\n const element = arr[i];\n map.set(keyFunc(element, i, arr), element);\n }\n\n return map;\n}\nexports.toMap = toMap;\n\n\n/**\n * Creates a range of numbers in an arithmetic progression.\n *\n * Range takes 1, 2, or 3 arguments:\n * <pre>\n * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]\n * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]\n * range(-2, -5, -1) produces [-2, -3, -4]\n * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.\n * </pre>\n *\n * @param {number} startOrEnd The starting value of the range if an end argument\n * is provided. Otherwise, the start value is 0, and this is the end value.\n * @param {number=} opt_end The optional end value of the range.\n * @param {number=} opt_step The step size between range values. Defaults to 1\n * if opt_step is undefined or 0.\n * @return {!Array<number>} An array of numbers for the requested range. May be\n * an empty array if adding the step would not converge toward the end\n * value.\n */\nfunction range(startOrEnd, opt_end, opt_step) {\n const array = [];\n let start = 0;\n let end = startOrEnd;\n const step = opt_step || 1;\n if (opt_end !== undefined) {\n start = startOrEnd;\n end = opt_end;\n }\n\n if (step * (end - start) < 0) {\n // Sign mismatch: start + step will never reach the end value.\n return [];\n }\n\n if (step > 0) {\n for (let i = start; i < end; i += step) {\n array.push(i);\n }\n } else {\n for (let i = start; i > end; i += step) {\n array.push(i);\n }\n }\n return array;\n}\nexports.range = range;\n\n\n/**\n * Returns an array consisting of the given value repeated N times.\n *\n * @param {VALUE} value The value to repeat.\n * @param {number} n The repeat count.\n * @return {!Array<VALUE>} An array with the repeated value.\n * @template VALUE\n */\nfunction repeat(value, n) {\n const array = [];\n for (let i = 0; i < n; i++) {\n array[i] = value;\n }\n return array;\n}\nexports.repeat = repeat;\n\n\n/**\n * Returns an array consisting of every argument with all arrays\n * expanded in-place recursively.\n *\n * @param {...*} var_args The values to flatten.\n * @return {!Array<?>} An array containing the flattened values.\n */\nfunction flatten(var_args) {\n const CHUNK_SIZE = 8192;\n\n const result = [];\n for (let i = 0; i < arguments.length; i++) {\n const element = arguments[i];\n if (Array.isArray(element)) {\n for (let c = 0; c < element.length; c += CHUNK_SIZE) {\n const chunk = slice(element, c, c + CHUNK_SIZE);\n const recurseResult = flatten.apply(null, chunk);\n for (let r = 0; r < recurseResult.length; r++) {\n result.push(recurseResult[r]);\n }\n }\n } else {\n result.push(element);\n }\n }\n return result;\n}\nexports.flatten = flatten;\n\n\n/**\n * Rotates an array in-place. After calling this method, the element at\n * index i will be the element previously at index (i - n) %\n * array.length, for all values of i between 0 and array.length - 1,\n * inclusive.\n *\n * For example, suppose list comprises [t, a, n, k, s]. After invoking\n * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].\n *\n * @param {!Array<T>} array The array to rotate.\n * @param {number} n The amount to rotate.\n * @return {!Array<T>} The array.\n * @template T\n */\nfunction rotate(array, n) {\n asserts.assert(array.length != null);\n\n if (array.length) {\n n %= array.length;\n if (n > 0) {\n Array.prototype.unshift.apply(array, array.splice(-n, n));\n } else if (n < 0) {\n Array.prototype.push.apply(array, array.splice(0, -n));\n }\n }\n return array;\n}\nexports.rotate = rotate;\n\n\n/**\n * Moves one item of an array to a new position keeping the order of the rest\n * of the items. Example use case: keeping a list of JavaScript objects\n * synchronized with the corresponding list of DOM elements after one of the\n * elements has been dragged to a new position.\n * @param {!IArrayLike<?>} arr The array to modify.\n * @param {number} fromIndex Index of the item to move between 0 and\n * `arr.length - 1`.\n * @param {number} toIndex Target index between 0 and `arr.length - 1`.\n */\nfunction moveItem(arr, fromIndex, toIndex) {\n asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\n asserts.assert(toIndex >= 0 && toIndex < arr.length);\n // Remove 1 item at fromIndex.\n const removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\n // Insert the removed item at toIndex.\n Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\n // We don't use goog.array.insertAt and goog.array.removeAt, because they're\n // significantly slower than splice.\n}\nexports.moveItem = moveItem;\n\n\n/**\n * Creates a new array for which the element at position i is an array of the\n * ith element of the provided arrays. The returned array will only be as long\n * as the shortest array provided; additional values are ignored. For example,\n * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].\n *\n * This is similar to the zip() function in Python. See {@link\n * http://docs.python.org/library/functions.html#zip}\n *\n * @param {...!IArrayLike<?>} var_args Arrays to be combined.\n * @return {!Array<!Array<?>>} A new array of arrays created from\n * provided arrays.\n */\nfunction zip(var_args) {\n if (!arguments.length) {\n return [];\n }\n const result = [];\n let minLen = arguments[0].length;\n for (let i = 1; i < arguments.length; i++) {\n if (arguments[i].length < minLen) {\n minLen = arguments[i].length;\n }\n }\n for (let i = 0; i < minLen; i++) {\n const value = [];\n for (let j = 0; j < arguments.length; j++) {\n value.push(arguments[j][i]);\n }\n result.push(value);\n }\n return result;\n}\nexports.zip = zip;\n\n\n/**\n * Shuffles the values in the specified array using the Fisher-Yates in-place\n * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()\n * and so resets the state of that random number generator. Similarly, may reset\n * the state of any other specified random number generator.\n *\n * Runtime: O(n)\n *\n * @param {!Array<?>} arr The array to be shuffled.\n * @param {function():number=} opt_randFn Optional random function to use for\n * shuffling.\n * Takes no arguments, and returns a random number on the interval [0, 1).\n * Defaults to Math.random() using JavaScript's built-in Math library.\n */\nfunction shuffle(arr, opt_randFn) {\n const randFn = opt_randFn || Math.random;\n\n for (let i = arr.length - 1; i > 0; i--) {\n // Choose a random array index in [0, i] (inclusive with i).\n const j = Math.floor(randFn() * (i + 1));\n\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n }\n}\nexports.shuffle = shuffle;\n\n\n/**\n * Returns a new array of elements from arr, based on the indexes of elements\n * provided by index_arr. For example, the result of index copying\n * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c'].\n *\n * @param {!IArrayLike<T>} arr The array to get a indexed copy from.\n * @param {!IArrayLike<number>} index_arr An array of indexes to get from arr.\n * @return {!Array<T>} A new array of elements from arr in index_arr order.\n * @template T\n */\nfunction copyByIndex(arr, index_arr) {\n const result = [];\n forEach(index_arr, function(index) {\n result.push(arr[index]);\n });\n return result;\n}\nexports.copyByIndex = copyByIndex;\n\n\n/**\n * Maps each element of the input array into zero or more elements of the output\n * array.\n *\n * @param {!IArrayLike<VALUE>|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): !Array<RESULT>} f The function\n * to call for every element. This function takes 3 arguments (the element,\n * the index and the array) and should return an array. The result will be\n * used to extend a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array<RESULT>} a new array with the concatenation of all arrays\n * returned from f.\n * @template THIS, VALUE, RESULT\n */\nfunction concatMap(arr, f, opt_obj) {\n return concat.apply([], map(arr, f, opt_obj));\n}\nexports.concatMap = concatMap;\n","~:compiled-at",1684858197907,"~:source-map-json","{\n\"version\":3,\n\"file\":\"goog.array.array.js\",\n\"lineCount\":656,\n\"mappings\":\"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\",\n\"sources\":[\"goog/array/array.js\"],\n\"sourcesContent\":[\"/**\\n * @license\\n * Copyright The Closure Library Authors.\\n * SPDX-License-Identifier: Apache-2.0\\n */\\n\\n/**\\n * @fileoverview Utilities for manipulating arrays.\\n */\\n\\n\\ngoog.module('goog.array');\\ngoog.module.declareLegacyNamespace();\\n\\nconst asserts = goog.require('goog.asserts');\\n\\n\\n/**\\n * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should\\n * rely on Array.prototype functions, if available.\\n *\\n * The Array.prototype functions can be defined by external libraries like\\n * Prototype and setting this flag to false forces closure to use its own\\n * goog.array implementation.\\n *\\n * If your javascript can be loaded by a third party site and you are wary about\\n * relying on the prototype functions, specify\\n * \\\"--define goog.NATIVE_ARRAY_PROTOTYPES=false\\\" to the JSCompiler.\\n *\\n * Setting goog.TRUSTED_SITE to false will automatically set\\n * NATIVE_ARRAY_PROTOTYPES to false.\\n */\\ngoog.NATIVE_ARRAY_PROTOTYPES =\\n goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);\\n\\n\\n/**\\n * @define {boolean} If true, JSCompiler will use the native implementation of\\n * array functions where appropriate (e.g., `Array#filter`) and remove the\\n * unused pure JS implementation.\\n */\\nconst ASSUME_NATIVE_FUNCTIONS = goog.define(\\n 'goog.array.ASSUME_NATIVE_FUNCTIONS', goog.FEATURESET_YEAR > 2012);\\nexports.ASSUME_NATIVE_FUNCTIONS = ASSUME_NATIVE_FUNCTIONS;\\n\\n\\n/**\\n * Returns the last element in an array without removing it.\\n * Same as {@link goog.array.last}.\\n * @param {IArrayLike<T>|string} array The array.\\n * @return {T} Last item in array.\\n * @template T\\n */\\nfunction peek(array) {\\n return array[array.length - 1];\\n}\\nexports.peek = peek;\\n\\n\\n/**\\n * Returns the last element in an array without removing it.\\n * Same as {@link goog.array.peek}.\\n * @param {IArrayLike<T>|string} array The array.\\n * @return {T} Last item in array.\\n * @template T\\n */\\nexports.last = peek;\\n\\n// NOTE(arv): Since most of the array functions are generic it allows you to\\n// pass an array-like object. Strings have a length and are considered array-\\n// like. However, the 'in' operator does not work on strings so we cannot just\\n// use the array path even if the browser supports indexing into strings. We\\n// therefore end up splitting the string.\\n\\n\\n/**\\n * Returns the index of the first element of an array with a specified value, or\\n * -1 if the element is not present in the array.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}\\n *\\n * @param {IArrayLike<T>|string} arr The array to be searched.\\n * @param {T} obj The object for which we are searching.\\n * @param {number=} opt_fromIndex The index at which to start the search. If\\n * omitted the search starts at index 0.\\n * @return {number} The index of the first matching array element.\\n * @template T\\n */\\nconst indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ?\\n function(arr, obj, opt_fromIndex) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\\n } :\\n function(arr, obj, opt_fromIndex) {\\n const fromIndex = opt_fromIndex == null ?\\n 0 :\\n (opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) :\\n opt_fromIndex);\\n\\n if (typeof arr === 'string') {\\n // Array.prototype.indexOf uses === so only strings should be found.\\n if (typeof obj !== 'string' || obj.length != 1) {\\n return -1;\\n }\\n return arr.indexOf(obj, fromIndex);\\n }\\n\\n for (let i = fromIndex; i < arr.length; i++) {\\n if (i in arr && arr[i] === obj) return i;\\n }\\n return -1;\\n };\\nexports.indexOf = indexOf;\\n\\n\\n/**\\n * Returns the index of the last element of an array with a specified value, or\\n * -1 if the element is not present in the array.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}\\n *\\n * @param {!IArrayLike<T>|string} arr The array to be searched.\\n * @param {T} obj The object for which we are searching.\\n * @param {?number=} opt_fromIndex The index at which to start the search. If\\n * omitted the search starts at the end of the array.\\n * @return {number} The index of the last matching array element.\\n * @template T\\n */\\nconst lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ?\\n function(arr, obj, opt_fromIndex) {\\n asserts.assert(arr.length != null);\\n\\n // Firefox treats undefined and null as 0 in the fromIndex argument which\\n // leads it to always return -1\\n const fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\\n return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\\n } :\\n function(arr, obj, opt_fromIndex) {\\n let fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\\n\\n if (fromIndex < 0) {\\n fromIndex = Math.max(0, arr.length + fromIndex);\\n }\\n\\n if (typeof arr === 'string') {\\n // Array.prototype.lastIndexOf uses === so only strings should be found.\\n if (typeof obj !== 'string' || obj.length != 1) {\\n return -1;\\n }\\n return arr.lastIndexOf(obj, fromIndex);\\n }\\n\\n for (let i = fromIndex; i >= 0; i--) {\\n if (i in arr && arr[i] === obj) return i;\\n }\\n return -1;\\n };\\nexports.lastIndexOf = lastIndexOf;\\n\\n\\n/**\\n * Calls a function for each element in an array. Skips holes in the array.\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}\\n *\\n * @param {IArrayLike<T>|string} arr Array or array like object over\\n * which to iterate.\\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\\n * element. This function takes 3 arguments (the element, the index and the\\n * array). The return value is ignored.\\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\\n * @template T,S\\n */\\nconst forEach = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n Array.prototype.forEach.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2) {\\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\\n }\\n }\\n };\\nexports.forEach = forEach;\\n\\n\\n/**\\n * Calls a function for each element in an array, starting from the last\\n * element rather than the first.\\n *\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\\n * element. This function\\n * takes 3 arguments (the element, the index and the array). The return\\n * value is ignored.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @template T,S\\n */\\nfunction forEachRight(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = l - 1; i >= 0; --i) {\\n if (i in arr2) {\\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\\n }\\n }\\n}\\nexports.forEachRight = forEachRight;\\n\\n\\n/**\\n * Calls a function for each element in an array, and if the function returns\\n * true adds the element to a new array.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}\\n *\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?):boolean} f The function to call for\\n * every element. This function\\n * takes 3 arguments (the element, the index and the array) and must\\n * return a Boolean. If the return value is true the element is added to the\\n * result array. If it is false the element is not included.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {!Array<T>} a new array in which only elements that passed the test\\n * are present.\\n * @template T,S\\n */\\nconst filter = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.filter.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const res = [];\\n let resLength = 0;\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2) {\\n const val = arr2[i]; // in case f mutates arr2\\n if (f.call(/** @type {?} */ (opt_obj), val, i, arr)) {\\n res[resLength++] = val;\\n }\\n }\\n }\\n return res;\\n };\\nexports.filter = filter;\\n\\n\\n/**\\n * Calls a function for each element in an array and inserts the result into a\\n * new array.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-map}\\n *\\n * @param {IArrayLike<VALUE>|string} arr Array or array like object\\n * over which to iterate.\\n * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call\\n * for every element. This function takes 3 arguments (the element,\\n * the index and the array) and should return something. The result will be\\n * inserted into a new array.\\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\\n * @return {!Array<RESULT>} a new array with the results from f.\\n * @template THIS, VALUE, RESULT\\n */\\nconst map = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.map.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const res = new Array(l);\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2) {\\n res[i] = f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\\n }\\n }\\n return res;\\n };\\nexports.map = map;\\n\\n\\n/**\\n * Passes every element of an array into a function and accumulates the result.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}\\n * Note that this implementation differs from the native Array.prototype.reduce\\n * in that the initial value is assumed to be defined (the MDN docs linked above\\n * recommend not omitting this parameter, although it is technically optional).\\n *\\n * For example:\\n * var a = [1, 2, 3, 4];\\n * reduce(a, function(r, v, i, arr) {return r + v;}, 0);\\n * returns 10\\n *\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {function(this:S, R, T, number, ?) : R} f The function to call for\\n * every element. This function\\n * takes 4 arguments (the function's previous result or the initial value,\\n * the value of the current array element, the current array index, and the\\n * array itself)\\n * function(previousValue, currentValue, index, array).\\n * @param {?} val The initial value to pass into the function on the first call.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {R} Result of evaluating f repeatedly across the values of the array.\\n * @template T,S,R\\n */\\nconst reduce = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ?\\n function(arr, f, val, opt_obj) {\\n asserts.assert(arr.length != null);\\n if (opt_obj) {\\n f = goog.bind(f, opt_obj);\\n }\\n return Array.prototype.reduce.call(arr, f, val);\\n } :\\n function(arr, f, val, opt_obj) {\\n let rval = val;\\n forEach(arr, function(val, index) {\\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\\n });\\n return rval;\\n };\\nexports.reduce = reduce;\\n\\n\\n/**\\n * Passes every element of an array into a function and accumulates the result,\\n * starting from the last element and working towards the first.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}\\n *\\n * For example:\\n * var a = ['a', 'b', 'c'];\\n * reduceRight(a, function(r, v, i, arr) {return r + v;}, '');\\n * returns 'cba'\\n *\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, R, T, number, ?) : R} f The function to call for\\n * every element. This function\\n * takes 4 arguments (the function's previous result or the initial value,\\n * the value of the current array element, the current array index, and the\\n * array itself)\\n * function(previousValue, currentValue, index, array).\\n * @param {?} val The initial value to pass into the function on the first call.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {R} Object returned as a result of evaluating f repeatedly across the\\n * values of the array.\\n * @template T,S,R\\n */\\nconst reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ?\\n function(arr, f, val, opt_obj) {\\n asserts.assert(arr.length != null);\\n asserts.assert(f != null);\\n if (opt_obj) {\\n f = goog.bind(f, opt_obj);\\n }\\n return Array.prototype.reduceRight.call(arr, f, val);\\n } :\\n function(arr, f, val, opt_obj) {\\n let rval = val;\\n forEachRight(arr, function(val, index) {\\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\\n });\\n return rval;\\n };\\nexports.reduceRight = reduceRight;\\n\\n\\n/**\\n * Calls f for each element of an array. If any call returns true, some()\\n * returns true (without checking the remaining elements). If all calls\\n * return false, some() returns false.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-some}\\n *\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\\n * for every element. This function takes 3 arguments (the element, the\\n * index and the array) and should return a boolean.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {boolean} true if any element passes the test.\\n * @template T,S\\n */\\nconst some = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.some.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\\n return true;\\n }\\n }\\n return false;\\n };\\nexports.some = some;\\n\\n\\n/**\\n * Call f for each element of an array. If all calls return true, every()\\n * returns true. If any call returns false, every() returns false and\\n * does not continue to check the remaining elements.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-every}\\n *\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\\n * for every element. This function takes 3 arguments (the element, the\\n * index and the array) and should return a boolean.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {boolean} false if any element fails the test.\\n * @template T,S\\n */\\nconst every = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.every.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2 && !f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\\n return false;\\n }\\n }\\n return true;\\n };\\nexports.every = every;\\n\\n\\n/**\\n * Counts the array elements that fulfill the predicate, i.e. for which the\\n * callback function returns true. Skips holes in the array.\\n *\\n * @param {!IArrayLike<T>|string} arr Array or array like object\\n * over which to iterate.\\n * @param {function(this: S, T, number, ?): boolean} f The function to call for\\n * every element. Takes 3 arguments (the element, the index and the array).\\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\\n * @return {number} The number of the matching elements.\\n * @template T,S\\n */\\nfunction count(arr, f, opt_obj) {\\n let count = 0;\\n forEach(arr, function(element, index, arr) {\\n if (f.call(/** @type {?} */ (opt_obj), element, index, arr)) {\\n ++count;\\n }\\n }, opt_obj);\\n return count;\\n}\\nexports.count = count;\\n\\n\\n/**\\n * Search an array for the first element that satisfies a given condition and\\n * return that element.\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function takes 3 arguments (the element, the\\n * index and the array) and should return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {T|null} The first array element that passes the test, or null if no\\n * element is found.\\n * @template T,S\\n */\\nfunction find(arr, f, opt_obj) {\\n const i = findIndex(arr, f, opt_obj);\\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\\n}\\nexports.find = find;\\n\\n\\n/**\\n * Search an array for the first element that satisfies a given condition and\\n * return its index.\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\\n * every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {number} The index of the first array element that passes the test,\\n * or -1 if no element is found.\\n * @template T,S\\n */\\nfunction findIndex(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\\n return i;\\n }\\n }\\n return -1;\\n}\\nexports.findIndex = findIndex;\\n\\n\\n/**\\n * Search an array (in reverse order) for the last element that satisfies a\\n * given condition and return that element.\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {T|null} The last array element that passes the test, or null if no\\n * element is found.\\n * @template T,S\\n */\\nfunction findRight(arr, f, opt_obj) {\\n const i = findIndexRight(arr, f, opt_obj);\\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\\n}\\nexports.findRight = findRight;\\n\\n\\n/**\\n * Search an array (in reverse order) for the last element that satisfies a\\n * given condition and return its index.\\n * @param {IArrayLike<T>|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {number} The index of the last array element that passes the test,\\n * or -1 if no element is found.\\n * @template T,S\\n */\\nfunction findIndexRight(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = l - 1; i >= 0; i--) {\\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\\n return i;\\n }\\n }\\n return -1;\\n}\\nexports.findIndexRight = findIndexRight;\\n\\n\\n/**\\n * Whether the array contains the given object.\\n * @param {IArrayLike<?>|string} arr The array to test for the presence of the\\n * element.\\n * @param {*} obj The object for which to test.\\n * @return {boolean} true if obj is present.\\n */\\nfunction contains(arr, obj) {\\n return indexOf(arr, obj) >= 0;\\n}\\nexports.contains = contains;\\n\\n\\n/**\\n * Whether the array is empty.\\n * @param {IArrayLike<?>|string} arr The array to test.\\n * @return {boolean} true if empty.\\n */\\nfunction isEmpty(arr) {\\n return arr.length == 0;\\n}\\nexports.isEmpty = isEmpty;\\n\\n\\n/**\\n * Clears the array.\\n * @param {IArrayLike<?>} arr Array or array like object to clear.\\n */\\nfunction clear(arr) {\\n // For non real arrays we don't have the magic length so we delete the\\n // indices.\\n if (!Array.isArray(arr)) {\\n for (let i = arr.length - 1; i >= 0; i--) {\\n delete arr[i];\\n }\\n }\\n arr.length = 0;\\n}\\nexports.clear = clear;\\n\\n\\n/**\\n * Pushes an item into an array, if it's not already in the array.\\n * @param {Array<T>} arr Array into which to insert the item.\\n * @param {T} obj Value to add.\\n * @template T\\n */\\nfunction insert(arr, obj) {\\n if (!contains(arr, obj)) {\\n arr.push(obj);\\n }\\n}\\nexports.insert = insert;\\n\\n\\n/**\\n * Inserts an object at the given index of the array.\\n * @param {IArrayLike<?>} arr The array to modify.\\n * @param {*} obj The object to insert.\\n * @param {number=} opt_i The index at which to insert the object. If omitted,\\n * treated as 0. A negative index is counted from the end of the array.\\n */\\nfunction insertAt(arr, obj, opt_i) {\\n splice(arr, opt_i, 0, obj);\\n}\\nexports.insertAt = insertAt;\\n\\n\\n/**\\n * Inserts at the given index of the array, all elements of another array.\\n * @param {IArrayLike<?>} arr The array to modify.\\n * @param {IArrayLike<?>} elementsToAdd The array of elements to add.\\n * @param {number=} opt_i The index at which to insert the object. If omitted,\\n * treated as 0. A negative index is counted from the end of the array.\\n */\\nfunction insertArrayAt(arr, elementsToAdd, opt_i) {\\n goog.partial(splice, arr, opt_i, 0).apply(null, elementsToAdd);\\n}\\nexports.insertArrayAt = insertArrayAt;\\n\\n\\n/**\\n * Inserts an object into an array before a specified object.\\n * @param {Array<T>} arr The array to modify.\\n * @param {T} obj The object to insert.\\n * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2\\n * is omitted or not found, obj is inserted at the end of the array.\\n * @template T\\n */\\nfunction insertBefore(arr, obj, opt_obj2) {\\n let i;\\n if (arguments.length == 2 || (i = indexOf(arr, opt_obj2)) < 0) {\\n arr.push(obj);\\n } else {\\n insertAt(arr, obj, i);\\n }\\n}\\nexports.insertBefore = insertBefore;\\n\\n\\n/**\\n * Removes the first occurrence of a particular value from an array.\\n * @param {IArrayLike<T>} arr Array from which to remove\\n * value.\\n * @param {T} obj Object to remove.\\n * @return {boolean} True if an element was removed.\\n * @template T\\n */\\nfunction remove(arr, obj) {\\n const i = indexOf(arr, obj);\\n let rv;\\n if ((rv = i >= 0)) {\\n removeAt(arr, i);\\n }\\n return rv;\\n}\\nexports.remove = remove;\\n\\n\\n/**\\n * Removes the last occurrence of a particular value from an array.\\n * @param {!IArrayLike<T>} arr Array from which to remove value.\\n * @param {T} obj Object to remove.\\n * @return {boolean} True if an element was removed.\\n * @template T\\n */\\nfunction removeLast(arr, obj) {\\n const i = lastIndexOf(arr, obj);\\n if (i >= 0) {\\n removeAt(arr, i);\\n return true;\\n }\\n return false;\\n}\\nexports.removeLast = removeLast;\\n\\n\\n/**\\n * Removes from an array the element at index i\\n * @param {IArrayLike<?>} arr Array or array like object from which to\\n * remove value.\\n * @param {number} i The index to remove.\\n * @return {boolean} True if an element was removed.\\n */\\nfunction removeAt(arr, i) {\\n asserts.assert(arr.length != null);\\n\\n // use generic form of splice\\n // splice returns the removed items and if successful the length of that\\n // will be 1\\n return Array.prototype.splice.call(arr, i, 1).length == 1;\\n}\\nexports.removeAt = removeAt;\\n\\n\\n/**\\n * Removes the first value that satisfies the given condition.\\n * @param {IArrayLike<T>} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {boolean} True if an element was removed.\\n * @template T,S\\n */\\nfunction removeIf(arr, f, opt_obj) {\\n const i = findIndex(arr, f, opt_obj);\\n if (i >= 0) {\\n removeAt(arr, i);\\n return true;\\n }\\n return false;\\n}\\nexports.removeIf = removeIf;\\n\\n\\n/**\\n * Removes all values that satisfy the given condition.\\n * @param {IArrayLike<T>} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {number} The number of items removed\\n * @template T,S\\n */\\nfunction removeAllIf(arr, f, opt_obj) {\\n let removedCount = 0;\\n forEachRight(arr, function(val, index) {\\n if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) {\\n if (removeAt(arr, index)) {\\n removedCount++;\\n }\\n }\\n });\\n return removedCount;\\n}\\nexports.removeAllIf = removeAllIf;\\n\\n\\n/**\\n * Returns a new array that is the result of joining the arguments. If arrays\\n * are passed then their items are added, however, if non-arrays are passed they\\n * will be added to the return array as is.\\n *\\n * Note that ArrayLike objects will be added as is, rather than having their\\n * items added.\\n *\\n * concat([1, 2], [3, 4]) -> [1, 2, 3, 4]\\n * concat(0, [1, 2]) -> [0, 1, 2]\\n * concat([1, 2], null) -> [1, 2, null]\\n *\\n * @param {...*} var_args Items to concatenate. Arrays will have each item\\n * added, while primitives and objects will be added as is.\\n * @return {!Array<?>} The new resultant array.\\n */\\nfunction concat(var_args) {\\n return Array.prototype.concat.apply([], arguments);\\n}\\nexports.concat = concat;\\n\\n\\n/**\\n * Returns a new array that contains the contents of all the arrays passed.\\n * @param {...!Array<T>} var_args\\n * @return {!Array<T>}\\n * @template T\\n */\\nfunction join(var_args) {\\n return Array.prototype.concat.apply([], arguments);\\n}\\nexports.join = join;\\n\\n\\n/**\\n * Converts an object to an array.\\n * @param {IArrayLike<T>|string} object The object to convert to an\\n * array.\\n * @return {!Array<T>} The object converted into an array. If object has a\\n * length property, every property indexed with a non-negative number\\n * less than length will be included in the result. If object does not\\n * have a length property, an empty array will be returned.\\n * @template T\\n */\\nfunction toArray(object) {\\n const length = object.length;\\n\\n // If length is not a number the following is false. This case is kept for\\n // backwards compatibility since there are callers that pass objects that are\\n // not array like.\\n if (length > 0) {\\n const rv = new Array(length);\\n for (let i = 0; i < length; i++) {\\n rv[i] = object[i];\\n }\\n return rv;\\n }\\n return [];\\n}\\nexports.toArray = toArray;\\n\\n\\n/**\\n * Does a shallow copy of an array.\\n * @param {IArrayLike<T>|string} arr Array or array-like object to\\n * clone.\\n * @return {!Array<T>} Clone of the input array.\\n * @template T\\n */\\nconst clone = toArray;\\nexports.clone = clone;\\n\\n\\n/**\\n * Extends an array with another array, element, or \\\"array like\\\" object.\\n * This function operates 'in-place', it does not create a new Array.\\n *\\n * Example:\\n * var a = [];\\n * extend(a, [0, 1]);\\n * a; // [0, 1]\\n * extend(a, 2);\\n * a; // [0, 1, 2]\\n *\\n * @param {Array<VALUE>} arr1 The array to modify.\\n * @param {...(IArrayLike<VALUE>|VALUE)} var_args The elements or arrays of\\n * elements to add to arr1.\\n * @template VALUE\\n */\\nfunction extend(arr1, var_args) {\\n for (let i = 1; i < arguments.length; i++) {\\n const arr2 = arguments[i];\\n if (goog.isArrayLike(arr2)) {\\n const len1 = arr1.length || 0;\\n const len2 = arr2.length || 0;\\n arr1.length = len1 + len2;\\n for (let j = 0; j < len2; j++) {\\n arr1[len1 + j] = arr2[j];\\n }\\n } else {\\n arr1.push(arr2);\\n }\\n }\\n}\\nexports.extend = extend;\\n\\n\\n/**\\n * Adds or removes elements from an array. This is a generic version of Array\\n * splice. This means that it might work on other objects similar to arrays,\\n * such as the arguments object.\\n *\\n * @param {IArrayLike<T>} arr The array to modify.\\n * @param {number|undefined} index The index at which to start changing the\\n * array. If not defined, treated as 0.\\n * @param {number} howMany How many elements to remove (0 means no removal. A\\n * value below 0 is treated as zero and so is any other non number. Numbers\\n * are floored).\\n * @param {...T} var_args Optional, additional elements to insert into the\\n * array.\\n * @return {!Array<T>} the removed elements.\\n * @template T\\n */\\nfunction splice(arr, index, howMany, var_args) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.splice.apply(arr, slice(arguments, 1));\\n}\\nexports.splice = splice;\\n\\n\\n/**\\n * Returns a new array from a segment of an array. This is a generic version of\\n * Array slice. This means that it might work on other objects similar to\\n * arrays, such as the arguments object.\\n *\\n * @param {IArrayLike<T>|string} arr The array from\\n * which to copy a segment.\\n * @param {number} start The index of the first element to copy.\\n * @param {number=} opt_end The index after the last element to copy.\\n * @return {!Array<T>} A new array containing the specified segment of the\\n * original array.\\n * @template T\\n */\\nfunction slice(arr, start, opt_end) {\\n asserts.assert(arr.length != null);\\n\\n // passing 1 arg to slice is not the same as passing 2 where the second is\\n // null or undefined (in that case the second argument is treated as 0).\\n // we could use slice on the arguments object and then use apply instead of\\n // testing the length\\n if (arguments.length <= 2) {\\n return Array.prototype.slice.call(arr, start);\\n } else {\\n return Array.prototype.slice.call(arr, start, opt_end);\\n }\\n}\\nexports.slice = slice;\\n\\n\\n/**\\n * Removes all duplicates from an array (retaining only the first\\n * occurrence of each array element). This function modifies the\\n * array in place and doesn't change the order of the non-duplicate items.\\n *\\n * For objects, duplicates are identified as having the same unique ID as\\n * defined by {@link goog.getUid}.\\n *\\n * Alternatively you can specify a custom hash function that returns a unique\\n * value for each item in the array it should consider unique.\\n *\\n * Runtime: N,\\n * Worstcase space: 2N (no dupes)\\n *\\n * @param {IArrayLike<T>} arr The array from which to remove\\n * duplicates.\\n * @param {Array=} opt_rv An optional array in which to return the results,\\n * instead of performing the removal inplace. If specified, the original\\n * array will remain unchanged.\\n * @param {function(T):string=} opt_hashFn An optional function to use to\\n * apply to every item in the array. This function should return a unique\\n * value for each item in the array it should consider unique.\\n * @template T\\n */\\nfunction removeDuplicates(arr, opt_rv, opt_hashFn) {\\n const returnArray = opt_rv || arr;\\n const defaultHashFn = function(item) {\\n // Prefix each type with a single character representing the type to\\n // prevent conflicting keys (e.g. true and 'true').\\n return goog.isObject(item) ? 'o' + goog.getUid(item) :\\n (typeof item).charAt(0) + item;\\n };\\n const hashFn = opt_hashFn || defaultHashFn;\\n\\n let cursorInsert = 0;\\n let cursorRead = 0;\\n const seen = {};\\n\\n while (cursorRead < arr.length) {\\n const current = arr[cursorRead++];\\n const key = hashFn(current);\\n if (!Object.prototype.hasOwnProperty.call(seen, key)) {\\n seen[key] = true;\\n returnArray[cursorInsert++] = current;\\n }\\n }\\n returnArray.length = cursorInsert;\\n}\\nexports.removeDuplicates = removeDuplicates;\\n\\n\\n/**\\n * Searches the specified array for the specified target using the binary\\n * search algorithm. If no opt_compareFn is specified, elements are compared\\n * using <code>defaultCompare</code>, which compares the elements\\n * using the built in < and > operators. This will produce the expected\\n * behavior for homogeneous arrays of String(s) and Number(s). The array\\n * specified <b>must</b> be sorted in ascending order (as defined by the\\n * comparison function). If the array is not sorted, results are undefined.\\n * If the array contains multiple instances of the specified target value, the\\n * left-most instance will be found.\\n *\\n * Runtime: O(log n)\\n *\\n * @param {IArrayLike<VALUE>} arr The array to be searched.\\n * @param {TARGET} target The sought value.\\n * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison\\n * function by which the array is ordered. Should take 2 arguments to\\n * compare, the target value and an element from your array, and return a\\n * negative number, zero, or a positive number depending on whether the\\n * first argument is less than, equal to, or greater than the second.\\n * @return {number} Lowest index of the target value if found, otherwise\\n * (-(insertion point) - 1). The insertion point is where the value should\\n * be inserted into arr to preserve the sorted property. Return value >= 0\\n * iff target is found.\\n * @template TARGET, VALUE\\n */\\nfunction binarySearch(arr, target, opt_compareFn) {\\n return binarySearch_(\\n arr, opt_compareFn || defaultCompare, false /* isEvaluator */, target);\\n}\\nexports.binarySearch = binarySearch;\\n\\n\\n/**\\n * Selects an index in the specified array using the binary search algorithm.\\n * The evaluator receives an element and determines whether the desired index\\n * is before, at, or after it. The evaluator must be consistent (formally,\\n * map(map(arr, evaluator, opt_obj), goog.math.sign)\\n * must be monotonically non-increasing).\\n *\\n * Runtime: O(log n)\\n *\\n * @param {IArrayLike<VALUE>} arr The array to be searched.\\n * @param {function(this:THIS, VALUE, number, ?): number} evaluator\\n * Evaluator function that receives 3 arguments (the element, the index and\\n * the array). Should return a negative number, zero, or a positive number\\n * depending on whether the desired index is before, at, or after the\\n * element passed to it.\\n * @param {THIS=} opt_obj The object to be used as the value of 'this'\\n * within evaluator.\\n * @return {number} Index of the leftmost element matched by the evaluator, if\\n * such exists; otherwise (-(insertion point) - 1). The insertion point is\\n * the index of the first element for which the evaluator returns negative,\\n * or arr.length if no such element exists. The return value is non-negative\\n * iff a match is found.\\n * @template THIS, VALUE\\n */\\nfunction binarySelect(arr, evaluator, opt_obj) {\\n return binarySearch_(\\n arr, evaluator, true /* isEvaluator */, undefined /* opt_target */,\\n opt_obj);\\n}\\nexports.binarySelect = binarySelect;\\n\\n\\n/**\\n * Implementation of a binary search algorithm which knows how to use both\\n * comparison functions and evaluators. If an evaluator is provided, will call\\n * the evaluator with the given optional data object, conforming to the\\n * interface defined in binarySelect. Otherwise, if a comparison function is\\n * provided, will call the comparison function against the given data object.\\n *\\n * This implementation purposefully does not use goog.bind or goog.partial for\\n * performance reasons.\\n *\\n * Runtime: O(log n)\\n *\\n * @param {IArrayLike<?>} arr The array to be searched.\\n * @param {function(?, ?, ?): number | function(?, ?): number} compareFn\\n * Either an evaluator or a comparison function, as defined by binarySearch\\n * and binarySelect above.\\n * @param {boolean} isEvaluator Whether the function is an evaluator or a\\n * comparison function.\\n * @param {?=} opt_target If the function is a comparison function, then\\n * this is the target to binary search for.\\n * @param {Object=} opt_selfObj If the function is an evaluator, this is an\\n * optional this object for the evaluator.\\n * @return {number} Lowest index of the target value if found, otherwise\\n * (-(insertion point) - 1). The insertion point is where the value should\\n * be inserted into arr to preserve the sorted property. Return value >= 0\\n * iff target is found.\\n * @private\\n */\\nfunction binarySearch_(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\\n let left = 0; // inclusive\\n let right = arr.length; // exclusive\\n let found;\\n while (left < right) {\\n const middle = left + ((right - left) >>> 1);\\n let compareResult;\\n if (isEvaluator) {\\n compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\\n } else {\\n // NOTE(dimvar): To avoid this cast, we'd have to use function overloading\\n // for the type of binarySearch_, which the type system can't express yet.\\n compareResult = /** @type {function(?, ?): number} */ (compareFn)(\\n opt_target, arr[middle]);\\n }\\n if (compareResult > 0) {\\n left = middle + 1;\\n } else {\\n right = middle;\\n // We are looking for the lowest index so we can't return immediately.\\n found = !compareResult;\\n }\\n }\\n // left is the index if found, or the insertion point otherwise.\\n // Avoiding bitwise not operator, as that causes a loss in precision for array\\n // indexes outside the bounds of a 32-bit signed integer. Array indexes have\\n // a maximum value of 2^32-2 https://tc39.es/ecma262/#array-index\\n return found ? left : -left - 1;\\n}\\n\\n\\n/**\\n * Sorts the specified array into ascending order. If no opt_compareFn is\\n * specified, elements are compared using\\n * <code>defaultCompare</code>, which compares the elements using\\n * the built in < and > operators. This will produce the expected behavior\\n * for homogeneous arrays of String(s) and Number(s), unlike the native sort,\\n * but will give unpredictable results for heterogeneous lists of strings and\\n * numbers with different numbers of digits.\\n *\\n * This sort is not guaranteed to be stable.\\n *\\n * Runtime: Same as `Array.prototype.sort`\\n *\\n * @param {Array<T>} arr The array to be sorted.\\n * @param {?function(T,T):number=} opt_compareFn Optional comparison\\n * function by which the\\n * array is to be ordered. Should take 2 arguments to compare, and return a\\n * negative number, zero, or a positive number depending on whether the\\n * first argument is less than, equal to, or greater than the second.\\n * @template T\\n */\\nfunction sort(arr, opt_compareFn) {\\n // TODO(arv): Update type annotation since null is not accepted.\\n arr.sort(opt_compareFn || defaultCompare);\\n}\\nexports.sort = sort;\\n\\n\\n/**\\n * Sorts the specified array into ascending order in a stable way. If no\\n * opt_compareFn is specified, elements are compared using\\n * <code>defaultCompare</code>, which compares the elements using\\n * the built in < and > operators. This will produce the expected behavior\\n * for homogeneous arrays of String(s) and Number(s).\\n *\\n * Runtime: Same as `Array.prototype.sort`, plus an additional\\n * O(n) overhead of copying the array twice.\\n *\\n * @param {Array<T>} arr The array to be sorted.\\n * @param {?function(T, T): number=} opt_compareFn Optional comparison function\\n * by which the array is to be ordered. Should take 2 arguments to compare,\\n * and return a negative number, zero, or a positive number depending on\\n * whether the first argument is less than, equal to, or greater than the\\n * second.\\n * @template T\\n */\\nfunction stableSort(arr, opt_compareFn) {\\n const compArr = new Array(arr.length);\\n for (let i = 0; i < arr.length; i++) {\\n compArr[i] = {index: i, value: arr[i]};\\n }\\n const valueCompareFn = opt_compareFn || defaultCompare;\\n function stableCompareFn(obj1, obj2) {\\n return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\\n }\\n sort(compArr, stableCompareFn);\\n for (let i = 0; i < arr.length; i++) {\\n arr[i] = compArr[i].value;\\n }\\n}\\nexports.stableSort = stableSort;\\n\\n\\n/**\\n * Sort the specified array into ascending order based on item keys\\n * returned by the specified key function.\\n * If no opt_compareFn is specified, the keys are compared in ascending order\\n * using <code>defaultCompare</code>.\\n *\\n * Runtime: O(S(f(n)), where S is runtime of <code>sort</code>\\n * and f(n) is runtime of the key function.\\n *\\n * @param {Array<T>} arr The array to be sorted.\\n * @param {function(T): K} keyFn Function taking array element and returning\\n * a key used for sorting this element.\\n * @param {?function(K, K): number=} opt_compareFn Optional comparison function\\n * by which the keys are to be ordered. Should take 2 arguments to compare,\\n * and return a negative number, zero, or a positive number depending on\\n * whether the first argument is less than, equal to, or greater than the\\n * second.\\n * @template T,K\\n */\\nfunction sortByKey(arr, keyFn, opt_compareFn) {\\n const keyCompareFn = opt_compareFn || defaultCompare;\\n sort(arr, function(a, b) {\\n return keyCompareFn(keyFn(a), keyFn(b));\\n });\\n}\\nexports.sortByKey = sortByKey;\\n\\n\\n/**\\n * Sorts an array of objects by the specified object key and compare\\n * function. If no compare function is provided, the key values are\\n * compared in ascending order using <code>defaultCompare</code>.\\n * This won't work for keys that get renamed by the compiler. So use\\n * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.\\n * @param {Array<Object>} arr An array of objects to sort.\\n * @param {string} key The object key to sort by.\\n * @param {Function=} opt_compareFn The function to use to compare key\\n * values.\\n */\\nfunction sortObjectsByKey(arr, key, opt_compareFn) {\\n sortByKey(arr, function(obj) {\\n return obj[key];\\n }, opt_compareFn);\\n}\\nexports.sortObjectsByKey = sortObjectsByKey;\\n\\n\\n/**\\n * Tells if the array is sorted.\\n * @param {!IArrayLike<T>} arr The array.\\n * @param {?function(T,T):number=} opt_compareFn Function to compare the\\n * array elements.\\n * Should take 2 arguments to compare, and return a negative number, zero,\\n * or a positive number depending on whether the first argument is less\\n * than, equal to, or greater than the second.\\n * @param {boolean=} opt_strict If true no equal elements are allowed.\\n * @return {boolean} Whether the array is sorted.\\n * @template T\\n */\\nfunction isSorted(arr, opt_compareFn, opt_strict) {\\n const compare = opt_compareFn || defaultCompare;\\n for (let i = 1; i < arr.length; i++) {\\n const compareResult = compare(arr[i - 1], arr[i]);\\n if (compareResult > 0 || compareResult == 0 && opt_strict) {\\n return false;\\n }\\n }\\n return true;\\n}\\nexports.isSorted = isSorted;\\n\\n\\n/**\\n * Compares two arrays for equality. Two arrays are considered equal if they\\n * have the same length and their corresponding elements are equal according to\\n * the comparison function.\\n *\\n * @param {IArrayLike<A>} arr1 The first array to compare.\\n * @param {IArrayLike<B>} arr2 The second array to compare.\\n * @param {?function(A,B):boolean=} opt_equalsFn Optional comparison function.\\n * Should take 2 arguments to compare, and return true if the arguments\\n * are equal. Defaults to {@link goog.array.defaultCompareEquality} which\\n * compares the elements using the built-in '===' operator.\\n * @return {boolean} Whether the two arrays are equal.\\n * @template A\\n * @template B\\n */\\nfunction equals(arr1, arr2, opt_equalsFn) {\\n if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||\\n arr1.length != arr2.length) {\\n return false;\\n }\\n const l = arr1.length;\\n const equalsFn = opt_equalsFn || defaultCompareEquality;\\n for (let i = 0; i < l; i++) {\\n if (!equalsFn(arr1[i], arr2[i])) {\\n return false;\\n }\\n }\\n return true;\\n}\\nexports.equals = equals;\\n\\n\\n/**\\n * 3-way array compare function.\\n * @param {!IArrayLike<VALUE>} arr1 The first array to\\n * compare.\\n * @param {!IArrayLike<VALUE>} arr2 The second array to\\n * compare.\\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\\n * function by which the array is to be ordered. Should take 2 arguments to\\n * compare, and return a negative number, zero, or a positive number\\n * depending on whether the first argument is less than, equal to, or\\n * greater than the second.\\n * @return {number} Negative number, zero, or a positive number depending on\\n * whether the first argument is less than, equal to, or greater than the\\n * second.\\n * @template VALUE\\n */\\nfunction compare3(arr1, arr2, opt_compareFn) {\\n const compare = opt_compareFn || defaultCompare;\\n const l = Math.min(arr1.length, arr2.length);\\n for (let i = 0; i < l; i++) {\\n const result = compare(arr1[i], arr2[i]);\\n if (result != 0) {\\n return result;\\n }\\n }\\n return defaultCompare(arr1.length, arr2.length);\\n}\\nexports.compare3 = compare3;\\n\\n\\n/**\\n * Compares its two arguments for order, using the built in < and >\\n * operators.\\n * @param {VALUE} a The first object to be compared.\\n * @param {VALUE} b The second object to be compared.\\n * @return {number} A negative number, zero, or a positive number as the first\\n * argument is less than, equal to, or greater than the second,\\n * respectively.\\n * @template VALUE\\n */\\nfunction defaultCompare(a, b) {\\n return a > b ? 1 : a < b ? -1 : 0;\\n}\\nexports.defaultCompare = defaultCompare;\\n\\n\\n/**\\n * Compares its two arguments for inverse order, using the built in < and >\\n * operators.\\n * @param {VALUE} a The first object to be compared.\\n * @param {VALUE} b The second object to be compared.\\n * @return {number} A negative number, zero, or a positive number as the first\\n * argument is greater than, equal to, or less than the second,\\n * respectively.\\n * @template VALUE\\n */\\nfunction inverseDefaultCompare(a, b) {\\n return -defaultCompare(a, b);\\n}\\nexports.inverseDefaultCompare = inverseDefaultCompare;\\n\\n\\n/**\\n * Compares its two arguments for equality, using the built in === operator.\\n * @param {*} a The first object to compare.\\n * @param {*} b The second object to compare.\\n * @return {boolean} True if the two arguments are equal, false otherwise.\\n */\\nfunction defaultCompareEquality(a, b) {\\n return a === b;\\n}\\nexports.defaultCompareEquality = defaultCompareEquality;\\n\\n\\n/**\\n * Inserts a value into a sorted array. The array is not modified if the\\n * value is already present.\\n * @param {IArrayLike<VALUE>} array The array to modify.\\n * @param {VALUE} value The object to insert.\\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\\n * function by which the array is ordered. Should take 2 arguments to\\n * compare, and return a negative number, zero, or a positive number\\n * depending on whether the first argument is less than, equal to, or\\n * greater than the second.\\n * @return {boolean} True if an element was inserted.\\n * @template VALUE\\n */\\nfunction binaryInsert(array, value, opt_compareFn) {\\n const index = binarySearch(array, value, opt_compareFn);\\n if (index < 0) {\\n insertAt(array, value, -(index + 1));\\n return true;\\n }\\n return false;\\n}\\nexports.binaryInsert = binaryInsert;\\n\\n\\n/**\\n * Removes a value from a sorted array.\\n * @param {!IArrayLike<VALUE>} array The array to modify.\\n * @param {VALUE} value The object to remove.\\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\\n * function by which the array is ordered. Should take 2 arguments to\\n * compare, and return a negative number, zero, or a positive number\\n * depending on whether the first argument is less than, equal to, or\\n * greater than the second.\\n * @return {boolean} True if an element was removed.\\n * @template VALUE\\n */\\nfunction binaryRemove(array, value, opt_compareFn) {\\n const index = binarySearch(array, value, opt_compareFn);\\n return (index >= 0) ? removeAt(array, index) : false;\\n}\\nexports.binaryRemove = binaryRemove;\\n\\n\\n/**\\n * Splits an array into disjoint buckets according to a splitting function.\\n * @param {IArrayLike<T>} array The array.\\n * @param {function(this:S, T, number, !IArrayLike<T>):?} sorter Function to\\n * call for every element. This takes 3 arguments (the element, the index\\n * and the array) and must return a valid object key (a string, number,\\n * etc), or undefined, if that object should not be placed in a bucket.\\n * @param {S=} opt_obj The object to be used as the value of 'this' within\\n * sorter.\\n * @return {!Object<!Array<T>>} An object, with keys being all of the unique\\n * return values of sorter, and values being arrays containing the items for\\n * which the splitter returned that key.\\n * @template T,S\\n */\\nfunction bucket(array, sorter, opt_obj) {\\n const buckets = {};\\n\\n for (let i = 0; i < array.length; i++) {\\n const value = array[i];\\n const key = sorter.call(/** @type {?} */ (opt_obj), value, i, array);\\n if (key !== undefined) {\\n // Push the value to the right bucket, creating it if necessary.\\n const bucket = buckets[key] || (buckets[key] = []);\\n bucket.push(value);\\n }\\n }\\n\\n return buckets;\\n}\\nexports.bucket = bucket;\\n\\n\\n/**\\n * Splits an array into disjoint buckets according to a splitting function.\\n * @param {!IArrayLike<V>} array The array.\\n * @param {function(V, number, !IArrayLike<V>):(K|undefined)} sorter Function to\\n * call for every element. This takes 3 arguments (the element, the index,\\n * and the array) and must return a value to use as a key, or undefined, if\\n * that object should not be placed in a bucket.\\n * @return {!Map<K, !Array<V>>} A map, with keys being all of the unique\\n * return values of sorter, and values being arrays containing the items for\\n * which the splitter returned that key.\\n * @template K,V\\n */\\nfunction bucketToMap(array, sorter) {\\n const /** !Map<K, !Array<V>> */ buckets = new Map();\\n\\n for (let i = 0; i < array.length; i++) {\\n const value = array[i];\\n const key = sorter(value, i, array);\\n if (key !== undefined) {\\n // Push the value to the right bucket, creating it if necessary.\\n let bucket = buckets.get(key);\\n if (!bucket) {\\n bucket = [];\\n buckets.set(key, bucket);\\n }\\n bucket.push(value);\\n }\\n }\\n\\n return buckets;\\n}\\nexports.bucketToMap = bucketToMap;\\n\\n\\n/**\\n * Creates a new object built from the provided array and the key-generation\\n * function.\\n * @param {IArrayLike<T>} arr Array or array like object over\\n * which to iterate whose elements will be the values in the new object.\\n * @param {?function(this:S, T, number, ?) : string} keyFunc The function to\\n * call for every element. This function takes 3 arguments (the element, the\\n * index and the array) and should return a string that will be used as the\\n * key for the element in the new object. If the function returns the same\\n * key for more than one element, the value for that key is\\n * implementation-defined.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within keyFunc.\\n * @return {!Object<T>} The new object.\\n * @template T,S\\n */\\nfunction toObject(arr, keyFunc, opt_obj) {\\n const ret = {};\\n forEach(arr, function(element, index) {\\n ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] =\\n element;\\n });\\n return ret;\\n}\\nexports.toObject = toObject;\\n\\n\\n/**\\n * Creates a new ES6 Map built from the provided array and the key-generation\\n * function.\\n * @param {!IArrayLike<V>} arr Array or array like object over which to iterate\\n * whose elements will be the values in the new object.\\n * @param {?function(V, number, ?) : K} keyFunc The function to call for every\\n * element. This function takes 3 arguments (the element, the index, and the\\n * array) and should return a value that will be used as the key for the\\n * element in the new object. If the function returns the same key for more\\n * than one element, the value for that key is implementation-defined.\\n * @return {!Map<K, V>} The new map.\\n * @template K,V\\n */\\nfunction toMap(arr, keyFunc) {\\n const /** !Map<K, V> */ map = new Map();\\n\\n for (let i = 0; i < arr.length; i++) {\\n const element = arr[i];\\n map.set(keyFunc(element, i, arr), element);\\n }\\n\\n return map;\\n}\\nexports.toMap = toMap;\\n\\n\\n/**\\n * Creates a range of numbers in an arithmetic progression.\\n *\\n * Range takes 1, 2, or 3 arguments:\\n * <pre>\\n * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]\\n * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]\\n * range(-2, -5, -1) produces [-2, -3, -4]\\n * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.\\n * </pre>\\n *\\n * @param {number} startOrEnd The starting value of the range if an end argument\\n * is provided. Otherwise, the start value is 0, and this is the end value.\\n * @param {number=} opt_end The optional end value of the range.\\n * @param {number=} opt_step The step size between range values. Defaults to 1\\n * if opt_step is undefined or 0.\\n * @return {!Array<number>} An array of numbers for the requested range. May be\\n * an empty array if adding the step would not converge toward the end\\n * value.\\n */\\nfunction range(startOrEnd, opt_end, opt_step) {\\n const array = [];\\n let start = 0;\\n let end = startOrEnd;\\n const step = opt_step || 1;\\n if (opt_end !== undefined) {\\n start = startOrEnd;\\n end = opt_end;\\n }\\n\\n if (step * (end - start) < 0) {\\n // Sign mismatch: start + step will never reach the end value.\\n return [];\\n }\\n\\n if (step > 0) {\\n for (let i = start; i < end; i += step) {\\n array.push(i);\\n }\\n } else {\\n for (let i = start; i > end; i += step) {\\n array.push(i);\\n }\\n }\\n return array;\\n}\\nexports.range = range;\\n\\n\\n/**\\n * Returns an array consisting of the given value repeated N times.\\n *\\n * @param {VALUE} value The value to repeat.\\n * @param {number} n The repeat count.\\n * @return {!Array<VALUE>} An array with the repeated value.\\n * @template VALUE\\n */\\nfunction repeat(value, n) {\\n const array = [];\\n for (let i = 0; i < n; i++) {\\n array[i] = value;\\n }\\n return array;\\n}\\nexports.repeat = repeat;\\n\\n\\n/**\\n * Returns an array consisting of every argument with all arrays\\n * expanded in-place recursively.\\n *\\n * @param {...*} var_args The values to flatten.\\n * @return {!Array<?>} An array containing the flattened values.\\n */\\nfunction flatten(var_args) {\\n const CHUNK_SIZE = 8192;\\n\\n const result = [];\\n for (let i = 0; i < arguments.length; i++) {\\n const element = arguments[i];\\n if (Array.isArray(element)) {\\n for (let c = 0; c < element.length; c += CHUNK_SIZE) {\\n const chunk = slice(element, c, c + CHUNK_SIZE);\\n const recurseResult = flatten.apply(null, chunk);\\n for (let r = 0; r < recurseResult.length; r++) {\\n result.push(recurseResult[r]);\\n }\\n }\\n } else {\\n result.push(element);\\n }\\n }\\n return result;\\n}\\nexports.flatten = flatten;\\n\\n\\n/**\\n * Rotates an array in-place. After calling this method, the element at\\n * index i will be the element previously at index (i - n) %\\n * array.length, for all values of i between 0 and array.length - 1,\\n * inclusive.\\n *\\n * For example, suppose list comprises [t, a, n, k, s]. After invoking\\n * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].\\n *\\n * @param {!Array<T>} array The array to rotate.\\n * @param {number} n The amount to rotate.\\n * @return {!Array<T>} The array.\\n * @template T\\n */\\nfunction rotate(array, n) {\\n asserts.assert(array.length != null);\\n\\n if (array.length) {\\n n %= array.length;\\n if (n > 0) {\\n Array.prototype.unshift.apply(array, array.splice(-n, n));\\n } else if (n < 0) {\\n Array.prototype.push.apply(array, array.splice(0, -n));\\n }\\n }\\n return array;\\n}\\nexports.rotate = rotate;\\n\\n\\n/**\\n * Moves one item of an array to a new position keeping the order of the rest\\n * of the items. Example use case: keeping a list of JavaScript objects\\n * synchronized with the corresponding list of DOM elements after one of the\\n * elements has been dragged to a new position.\\n * @param {!IArrayLike<?>} arr The array to modify.\\n * @param {number} fromIndex Index of the item to move between 0 and\\n * `arr.length - 1`.\\n * @param {number} toIndex Target index between 0 and `arr.length - 1`.\\n */\\nfunction moveItem(arr, fromIndex, toIndex) {\\n asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\\n asserts.assert(toIndex >= 0 && toIndex < arr.length);\\n // Remove 1 item at fromIndex.\\n const removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\\n // Insert the removed item at toIndex.\\n Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\\n // We don't use goog.array.insertAt and goog.array.removeAt, because they're\\n // significantly slower than splice.\\n}\\nexports.moveItem = moveItem;\\n\\n\\n/**\\n * Creates a new array for which the element at position i is an array of the\\n * ith element of the provided arrays. The returned array will only be as long\\n * as the shortest array provided; additional values are ignored. For example,\\n * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].\\n *\\n * This is similar to the zip() function in Python. See {@link\\n * http://docs.python.org/library/functions.html#zip}\\n *\\n * @param {...!IArrayLike<?>} var_args Arrays to be combined.\\n * @return {!Array<!Array<?>>} A new array of arrays created from\\n * provided arrays.\\n */\\nfunction zip(var_args) {\\n if (!arguments.length) {\\n return [];\\n }\\n const result = [];\\n let minLen = arguments[0].length;\\n for (let i = 1; i < arguments.length; i++) {\\n if (arguments[i].length < minLen) {\\n minLen = arguments[i].length;\\n }\\n }\\n for (let i = 0; i < minLen; i++) {\\n const value = [];\\n for (let j = 0; j < arguments.length; j++) {\\n value.push(arguments[j][i]);\\n }\\n result.push(value);\\n }\\n return result;\\n}\\nexports.zip = zip;\\n\\n\\n/**\\n * Shuffles the values in the specified array using the Fisher-Yates in-place\\n * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()\\n * and so resets the state of that random number generator. Similarly, may reset\\n * the state of any other specified random number generator.\\n *\\n * Runtime: O(n)\\n *\\n * @param {!Array<?>} arr The array to be shuffled.\\n * @param {function():number=} opt_randFn Optional random function to use for\\n * shuffling.\\n * Takes no arguments, and returns a random number on the interval [0, 1).\\n * Defaults to Math.random() using JavaScript's built-in Math library.\\n */\\nfunction shuffle(arr, opt_randFn) {\\n const randFn = opt_randFn || Math.random;\\n\\n for (let i = arr.length - 1; i > 0; i--) {\\n // Choose a random array index in [0, i] (inclusive with i).\\n const j = Math.floor(randFn() * (i + 1));\\n\\n const tmp = arr[i];\\n arr[i] = arr[j];\\n arr[j] = tmp;\\n }\\n}\\nexports.shuffle = shuffle;\\n\\n\\n/**\\n * Returns a new array of elements from arr, based on the indexes of elements\\n * provided by index_arr. For example, the result of index copying\\n * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c'].\\n *\\n * @param {!IArrayLike<T>} arr The array to get a indexed copy from.\\n * @param {!IArrayLike<number>} index_arr An array of indexes to get from arr.\\n * @return {!Array<T>} A new array of elements from arr in index_arr order.\\n * @template T\\n */\\nfunction copyByIndex(arr, index_arr) {\\n const result = [];\\n forEach(index_arr, function(index) {\\n result.push(arr[index]);\\n });\\n return result;\\n}\\nexports.copyByIndex = copyByIndex;\\n\\n\\n/**\\n * Maps each element of the input array into zero or more elements of the output\\n * array.\\n *\\n * @param {!IArrayLike<VALUE>|string} arr Array or array like object\\n * over which to iterate.\\n * @param {function(this:THIS, VALUE, number, ?): !Array<RESULT>} f The function\\n * to call for every element. This function takes 3 arguments (the element,\\n * the index and the array) and should return an array. The result will be\\n * used to extend a new array.\\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\\n * @return {!Array<RESULT>} a new array with the concatenation of all arrays\\n * returned from f.\\n * @template THIS, VALUE, RESULT\\n */\\nfunction concatMap(arr, f, opt_obj) {\\n return concat.apply([], map(arr, f, opt_obj));\\n}\\nexports.concatMap = concatMap;\\n\"],\n\"names\":[\"goog\",\"module\",\"declareLegacyNamespace\",\"asserts\",\"require\",\"NATIVE_ARRAY_PROTOTYPES\",\"define\",\"TRUSTED_SITE\",\"ASSUME_NATIVE_FUNCTIONS\",\"FEATURESET_YEAR\",\"exports\",\"peek\",\"array\",\"length\",\"last\",\"indexOf\",\"Array\",\"prototype\",\"arr\",\"obj\",\"opt_fromIndex\",\"assert\",\"call\",\"fromIndex\",\"Math\",\"max\",\"i\",\"lastIndexOf\",\"forEach\",\"f\",\"opt_obj\",\"l\",\"arr2\",\"split\",\"forEachRight\",\"filter\",\"res\",\"resLength\",\"val\",\"map\",\"reduce\",\"bind\",\"rval\",\"index\",\"reduceRight\",\"some\",\"every\",\"count\",\"element\",\"find\",\"findIndex\",\"charAt\",\"findRight\",\"findIndexRight\",\"contains\",\"isEmpty\",\"clear\",\"isArray\",\"insert\",\"push\",\"insertAt\",\"opt_i\",\"splice\",\"insertArrayAt\",\"elementsToAdd\",\"partial\",\"apply\",\"insertBefore\",\"opt_obj2\",\"arguments\",\"remove\",\"rv\",\"removeAt\",\"removeLast\",\"removeIf\",\"removeAllIf\",\"removedCount\",\"concat\",\"var_args\",\"join\",\"toArray\",\"object\",\"clone\",\"extend\",\"arr1\",\"isArrayLike\",\"len1\",\"len2\",\"j\",\"howMany\",\"slice\",\"start\",\"opt_end\",\"removeDuplicates\",\"opt_rv\",\"opt_hashFn\",\"returnArray\",\"defaultHashFn\",\"item\",\"isObject\",\"getUid\",\"hashFn\",\"cursorInsert\",\"cursorRead\",\"seen\",\"current\",\"key\",\"Object\",\"hasOwnProperty\",\"binarySearch\",\"target\",\"opt_compareFn\",\"binarySearch_\",\"defaultCompare\",\"binarySelect\",\"evaluator\",\"undefined\",\"compareFn\",\"isEvaluator\",\"opt_target\",\"opt_selfObj\",\"left\",\"right\",\"found\",\"middle\",\"compareResult\",\"sort\",\"stableSort\",\"compArr\",\"value\",\"valueCompareFn\",\"stableCompareFn\",\"obj1\",\"obj2\",\"sortByKey\",\"keyFn\",\"keyCompareFn\",\"a\",\"b\",\"sortObjectsByKey\",\"isSorted\",\"opt_strict\",\"compare\",\"equals\",\"opt_equalsFn\",\"equalsFn\",\"defaultCompareEquality\",\"compare3\",\"min\",\"result\",\"inverseDefaultCompare\",\"binaryInsert\",\"binaryRemove\",\"bucket\",\"sorter\",\"buckets\",\"bucketToMap\",\"Map\",\"get\",\"set\",\"toObject\",\"keyFunc\",\"ret\",\"toMap\",\"range\",\"startOrEnd\",\"opt_step\",\"end\",\"step\",\"repeat\",\"n\",\"flatten\",\"CHUNK_SIZE\",\"c\",\"chunk\",\"recurseResult\",\"r\",\"rotate\",\"unshift\",\"moveItem\",\"toIndex\",\"removedItems\",\"zip\",\"minLen\",\"shuffle\",\"opt_randFn\",\"randFn\",\"random\",\"floor\",\"tmp\",\"copyByIndex\",\"index_arr\",\"concatMap\"]\n}\n"]