["^ ","~:resources",[["^ ","~:cache-key",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"~:goog-provides",["~#set",["~$goog.vec.Float64Array"]],"~:output-name","goog.vec.float64array.js","~:resource-id",["~:shadow.build.classpath/resource","goog/vec/float64array.js"],"~:resource-name","goog/vec/float64array.js","~:type","~:goog","~:source","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Supplies a Float64Array implementation that implements\n * most of the Float64Array spec and that can be used when a built-in\n * implementation is not available.\n *\n * Note that if no existing Float64Array implementation is found then this\n * class and all its public properties are exported as Float64Array.\n *\n * Adding support for the other TypedArray classes here does not make sense\n * since this vector math library only needs Float32Array and Float64Array.\n */\ngoog.provide('goog.vec.Float64Array');\n\n\n\n/**\n * Constructs a new Float64Array. The new array is initialized to all zeros.\n *\n * @param {goog.vec.Float64Array|Array|ArrayBuffer|number} p0\n * The length of the array, or an array to initialize the contents of the\n * new Float64Array.\n * @constructor\n * @implements {IArrayLike}\n * @final\n */\ngoog.vec.Float64Array = function(p0) {\n 'use strict';\n /** @type {number} */\n this.length = /** @type {number} */ (/** @type {?} */ (p0).length || p0);\n for (let i = 0; i < this.length; i++) {\n this[i] = p0[i] || 0;\n }\n};\n\n\n/**\n * The number of bytes in an element (as defined by the Typed Array\n * specification).\n *\n * @type {number}\n */\ngoog.vec.Float64Array.BYTES_PER_ELEMENT = 8;\n\n\n/**\n * The number of bytes in an element (as defined by the Typed Array\n * specification).\n *\n * @type {number}\n */\ngoog.vec.Float64Array.prototype.BYTES_PER_ELEMENT = 8;\n\n\n/**\n * Sets elements of the array.\n * @param {Array|Float64Array} values The array of values.\n * @param {number=} opt_offset The offset in this array to start.\n */\ngoog.vec.Float64Array.prototype.set = function(values, opt_offset) {\n 'use strict';\n opt_offset = opt_offset || 0;\n for (let i = 0; i < values.length && opt_offset + i < this.length; i++) {\n this[opt_offset + i] = values[i];\n }\n};\n\n\n/**\n * Creates a string representation of this array.\n * @return {string} The string version of this array.\n * @override\n */\ngoog.vec.Float64Array.prototype.toString = Array.prototype.join;\n\n\n/**\n * Note that we cannot implement the subarray() or (deprecated) slice()\n * methods properly since doing so would require being able to overload\n * the [] operator which is not possible in javascript. So we leave\n * them unimplemented. Any attempt to call these methods will just result\n * in a javascript error since we leave them undefined.\n */\n\n\n/**\n * If no existing Float64Array implementation is found then we export\n * goog.vec.Float64Array as Float64Array.\n */\nif (typeof Float64Array == 'undefined') {\n try {\n goog.exportProperty(\n goog.vec.Float64Array, 'BYTES_PER_ELEMENT',\n goog.vec.Float64Array.BYTES_PER_ELEMENT);\n } catch (float64ArrayError) {\n // Do nothing. This code is in place to fix b/7225850, in which an error\n // is incorrectly thrown for Google TV on an old Chrome.\n // TODO(user): remove after that version is retired.\n }\n\n goog.exportProperty(\n goog.vec.Float64Array.prototype, 'BYTES_PER_ELEMENT',\n goog.vec.Float64Array.prototype.BYTES_PER_ELEMENT);\n goog.exportProperty(\n goog.vec.Float64Array.prototype, 'set',\n goog.vec.Float64Array.prototype.set);\n goog.exportProperty(\n goog.vec.Float64Array.prototype, 'toString',\n goog.vec.Float64Array.prototype.toString);\n goog.exportSymbol('Float64Array', goog.vec.Float64Array);\n}\n","~:last-modified",1684857788697,"~:requires",["^3",["~$goog"]],"~:pom-info",["^ ","~:description","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","~:group-id","~$org.clojure","~:artifact-id","~$google-closure-library","~:name","Google Closure Library","~:id","~$org.clojure/google-closure-library","~:url","http://code.google.com/p/closure-library/","~:parent-group-id","~$org.sonatype.oss","~:coordinate",["^G","0.0-20230227-c7c0a541"],"~:version","0.0-20230227-c7c0a541"],"~:goog-requires",["^3",[]],"~:inspect-info",["^ ","~:js-str-offsets",[],"~:js-esm",false,"~:js-imports",[],"~:js-invalid-requires",[],"^2",["goog.vec.Float64Array"],"~:js-language","es6","~:goog-module",null,"~:goog-module-legacy-namespace",false,"~:js-requires",[],"^M",[],"~:goog-require-types",[],"~:uses-global-buffer",false,"~:uses-global-process",false],"^H",["~#url","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/float64array.js"],"~:provides",["^3",["^4"]],"^W",["^3",[]],"~:from-jar",true,"~:goog-src",true,"~:deps",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.Mat3"]],"^5","goog.vec.mat3.js","^6",["^7","goog/vec/mat3.js"],"^8","goog/vec/mat3.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implements 3x3 matrices and their related functions which are\n * compatible with WebGL. The API is structured to avoid unnecessary memory\n * allocations. The last parameter will typically be the output vector and\n * an object can be both an input and output parameter to all methods except\n * where noted. Matrix operations follow the mathematical form when multiplying\n * vectors as follows: resultVec = matrix * vec.\n *\n * The matrices are stored in column-major order.\n */\ngoog.provide('goog.vec.Mat3');\n\ngoog.require('goog.vec');\ngoog.requireType('goog.vec.Vec3');\n\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.Mat3.Float32;\n/** @typedef {!goog.vec.Float64} */ goog.vec.Mat3.Float64;\n/** @typedef {!goog.vec.Number} */ goog.vec.Mat3.Number;\n/** @typedef {!goog.vec.AnyType} */ goog.vec.Mat3.AnyType;\n\n// The following two types are deprecated - use the above types instead.\n/** @typedef {!Float32Array} */ goog.vec.Mat3.Type;\n/** @typedef {!goog.vec.ArrayType} */ goog.vec.Mat3.Mat3Like;\n\n\n/**\n * Creates the array representation of a 3x3 matrix of Float32.\n * The use of the array directly instead of a class reduces overhead.\n * The returned matrix is cleared to all zeros.\n *\n * @return {!goog.vec.Mat3.Float32} The new matrix.\n */\ngoog.vec.Mat3.createFloat32 = function() {\n 'use strict';\n return new Float32Array(9);\n};\n\n\n/**\n * Creates the array representation of a 3x3 matrix of Float64.\n * The returned matrix is cleared to all zeros.\n *\n * @return {!goog.vec.Mat3.Float64} The new matrix.\n */\ngoog.vec.Mat3.createFloat64 = function() {\n 'use strict';\n return new Float64Array(9);\n};\n\n\n/**\n * Creates the array representation of a 3x3 matrix of Number.\n * The returned matrix is cleared to all zeros.\n *\n * @return {!goog.vec.Mat3.Number} The new matrix.\n */\ngoog.vec.Mat3.createNumber = function() {\n 'use strict';\n const a = new Array(9);\n goog.vec.Mat3.setFromValues(a, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n return a;\n};\n\n\n/**\n * Creates the array representation of a 3x3 matrix of Float32.\n * The returned matrix is cleared to all zeros.\n *\n * @deprecated Use createFloat32.\n * @return {!goog.vec.Mat3.Type} The new matrix.\n */\ngoog.vec.Mat3.create = function() {\n 'use strict';\n return goog.vec.Mat3.createFloat32();\n};\n\n\n/**\n * Creates a 3x3 identity matrix of Float32.\n *\n * @return {!goog.vec.Mat3.Float32} The new 9 element array.\n */\ngoog.vec.Mat3.createFloat32Identity = function() {\n 'use strict';\n const mat = goog.vec.Mat3.createFloat32();\n mat[0] = mat[4] = mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Creates a 3x3 identity matrix of Float64.\n *\n * @return {!goog.vec.Mat3.Float64} The new 9 element array.\n */\ngoog.vec.Mat3.createFloat64Identity = function() {\n 'use strict';\n const mat = goog.vec.Mat3.createFloat64();\n mat[0] = mat[4] = mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Creates a 3x3 identity matrix of Number.\n * The returned matrix is cleared to all zeros.\n *\n * @return {!goog.vec.Mat3.Number} The new 9 element array.\n */\ngoog.vec.Mat3.createNumberIdentity = function() {\n 'use strict';\n const a = new Array(9);\n goog.vec.Mat3.setFromValues(a, 1, 0, 0, 0, 1, 0, 0, 0, 1);\n return a;\n};\n\n\n/**\n * Creates the array representation of a 3x3 matrix of Float32.\n * The returned matrix is cleared to all zeros.\n *\n * @deprecated Use createFloat32Identity.\n * @return {!goog.vec.Mat3.Type} The new 9 element array.\n */\ngoog.vec.Mat3.createIdentity = function() {\n 'use strict';\n return goog.vec.Mat3.createFloat32Identity();\n};\n\n\n/**\n * Creates a 3x3 matrix of Float32 initialized from the given array.\n *\n * @param {goog.vec.Mat3.AnyType} matrix The array containing the\n * matrix values in column major order.\n * @return {!goog.vec.Mat3.Float32} The new, nine element array.\n */\ngoog.vec.Mat3.createFloat32FromArray = function(matrix) {\n 'use strict';\n const newMatrix = goog.vec.Mat3.createFloat32();\n goog.vec.Mat3.setFromArray(newMatrix, matrix);\n return newMatrix;\n};\n\n\n/**\n * Creates a 3x3 matrix of Float32 initialized from the given values.\n *\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @return {!goog.vec.Mat3.Float32} The new, nine element array.\n */\ngoog.vec.Mat3.createFloat32FromValues = function(\n v00, v10, v20, v01, v11, v21, v02, v12, v22) {\n 'use strict';\n const newMatrix = goog.vec.Mat3.createFloat32();\n goog.vec.Mat3.setFromValues(\n newMatrix, v00, v10, v20, v01, v11, v21, v02, v12, v22);\n return newMatrix;\n};\n\n\n/**\n * Creates a clone of a 3x3 matrix of Float32.\n *\n * @param {goog.vec.Mat3.Float32} matrix The source 3x3 matrix.\n * @return {!goog.vec.Mat3.Float32} The new 3x3 element matrix.\n */\ngoog.vec.Mat3.cloneFloat32 = goog.vec.Mat3.createFloat32FromArray;\n\n\n/**\n * Creates a 3x3 matrix of Float64 initialized from the given array.\n *\n * @param {goog.vec.Mat3.AnyType} matrix The array containing the\n * matrix values in column major order.\n * @return {!goog.vec.Mat3.Float64} The new, nine element array.\n */\ngoog.vec.Mat3.createFloat64FromArray = function(matrix) {\n 'use strict';\n const newMatrix = goog.vec.Mat3.createFloat64();\n goog.vec.Mat3.setFromArray(newMatrix, matrix);\n return newMatrix;\n};\n\n\n/**\n * Creates a 3x3 matrix of Float64 initialized from the given values.\n *\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @return {!goog.vec.Mat3.Float64} The new, nine element array.\n */\ngoog.vec.Mat3.createFloat64FromValues = function(\n v00, v10, v20, v01, v11, v21, v02, v12, v22) {\n 'use strict';\n const newMatrix = goog.vec.Mat3.createFloat64();\n goog.vec.Mat3.setFromValues(\n newMatrix, v00, v10, v20, v01, v11, v21, v02, v12, v22);\n return newMatrix;\n};\n\n\n/**\n * Creates a clone of a 3x3 matrix of Float64.\n *\n * @param {goog.vec.Mat3.Float64} matrix The source 3x3 matrix.\n * @return {!goog.vec.Mat3.Float64} The new 3x3 element matrix.\n */\ngoog.vec.Mat3.cloneFloat64 = goog.vec.Mat3.createFloat64FromArray;\n\n\n/**\n * Creates a 3x3 matrix of Float32 initialized from the given array.\n *\n * @deprecated Use createFloat32FromArray.\n * @param {goog.vec.Mat3.Mat3Like} matrix The array containing the\n * matrix values in column major order.\n * @return {!goog.vec.Mat3.Type} The new, nine element array.\n */\ngoog.vec.Mat3.createFromArray = function(matrix) {\n 'use strict';\n const newMatrix = goog.vec.Mat3.createFloat32();\n goog.vec.Mat3.setFromArray(newMatrix, matrix);\n return newMatrix;\n};\n\n\n/**\n * Creates a 3x3 matrix of Float32 initialized from the given values.\n *\n * @deprecated Use createFloat32FromValues.\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @return {!goog.vec.Mat3.Type} The new, nine element array.\n */\ngoog.vec.Mat3.createFromValues = function(\n v00, v10, v20, v01, v11, v21, v02, v12, v22) {\n 'use strict';\n const newMatrix = goog.vec.Mat3.create();\n goog.vec.Mat3.setFromValues(\n newMatrix, v00, v10, v20, v01, v11, v21, v02, v12, v22);\n return newMatrix;\n};\n\n\n/**\n * Creates a clone of a 3x3 matrix of Float32.\n *\n * @deprecated Use cloneFloat32.\n * @param {goog.vec.Mat3.Mat3Like} matrix The source 3x3 matrix.\n * @return {!goog.vec.Mat3.Type} The new 3x3 element matrix.\n */\ngoog.vec.Mat3.clone = goog.vec.Mat3.createFromArray;\n\n\n/**\n * Retrieves the element at the requested row and column.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @return {number} The element value at the requested row, column indices.\n */\ngoog.vec.Mat3.getElement = function(mat, row, column) {\n 'use strict';\n return mat[row + column * 3];\n};\n\n\n/**\n * Sets the element at the requested row and column.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @param {number} value The value to set at the requested row, column.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setElement = function(mat, row, column, value) {\n 'use strict';\n mat[row + column * 3] = value;\n return mat;\n};\n\n\n/**\n * Initializes the matrix from the set of values. Note the values supplied are\n * in column major order.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the\n * values.\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setFromValues = function(\n mat, v00, v10, v20, v01, v11, v21, v02, v12, v22) {\n 'use strict';\n mat[0] = v00;\n mat[1] = v10;\n mat[2] = v20;\n mat[3] = v01;\n mat[4] = v11;\n mat[5] = v21;\n mat[6] = v02;\n mat[7] = v12;\n mat[8] = v22;\n return mat;\n};\n\n\n/**\n * Sets the matrix from the array of values stored in column major order.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Mat3.AnyType} values The column major ordered\n * array of values to store in the matrix.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setFromArray = function(mat, values) {\n 'use strict';\n mat[0] = values[0];\n mat[1] = values[1];\n mat[2] = values[2];\n mat[3] = values[3];\n mat[4] = values[4];\n mat[5] = values[5];\n mat[6] = values[6];\n mat[7] = values[7];\n mat[8] = values[8];\n return mat;\n};\n\n\n/**\n * Sets the matrix from the array of values stored in row major order.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Mat3.AnyType} values The row major ordered array\n * of values to store in the matrix.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setFromRowMajorArray = function(mat, values) {\n 'use strict';\n mat[0] = values[0];\n mat[1] = values[3];\n mat[2] = values[6];\n mat[3] = values[1];\n mat[4] = values[4];\n mat[5] = values[7];\n mat[6] = values[2];\n mat[7] = values[5];\n mat[8] = values[8];\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given values.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {number} v00 The values for (0, 0).\n * @param {number} v11 The values for (1, 1).\n * @param {number} v22 The values for (2, 2).\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setDiagonalValues = function(mat, v00, v11, v22) {\n 'use strict';\n mat[0] = v00;\n mat[4] = v11;\n mat[8] = v22;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given vector.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Vec3.AnyType} vec The vector containing the values.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setDiagonal = function(mat, vec) {\n 'use strict';\n mat[0] = vec[0];\n mat[4] = vec[1];\n mat[8] = vec[2];\n return mat;\n};\n\n\n/**\n * Sets the specified column with the supplied values.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {number} v0 The value for row 0.\n * @param {number} v1 The value for row 1.\n * @param {number} v2 The value for row 2.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setColumnValues = function(mat, column, v0, v1, v2) {\n 'use strict';\n const i = column * 3;\n mat[i] = v0;\n mat[i + 1] = v1;\n mat[i + 2] = v2;\n return mat;\n};\n\n\n/**\n * Sets the specified column with the value from the supplied array.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {goog.vec.Vec3.AnyType} vec The vector elements for the column.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 3;\n mat[i] = vec[0];\n mat[i + 1] = vec[1];\n mat[i + 2] = vec[2];\n return mat;\n};\n\n\n/**\n * Retrieves the specified column from the matrix into the given vector\n * array.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix supplying the values.\n * @param {number} column The column to get the values from.\n * @param {goog.vec.Vec3.AnyType} vec The vector elements to receive the\n * column.\n * @return {goog.vec.Vec3.AnyType} return vec so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.getColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 3;\n vec[0] = mat[i];\n vec[1] = mat[i + 1];\n vec[2] = mat[i + 2];\n return vec;\n};\n\n\n/**\n * Sets the columns of the matrix from the set of vector elements.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Vec3.AnyType} vec0 The values for column 0.\n * @param {goog.vec.Vec3.AnyType} vec1 The values for column 1.\n * @param {goog.vec.Vec3.AnyType} vec2 The values for column 2.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setColumns = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.Mat3.setColumn(mat, 0, vec0);\n goog.vec.Mat3.setColumn(mat, 1, vec1);\n goog.vec.Mat3.setColumn(mat, 2, vec2);\n return mat;\n};\n\n\n/**\n * Retrieves the column values from the given matrix into the given vector\n * elements.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix supplying the columns.\n * @param {goog.vec.Vec3.AnyType} vec0 The vector to receive column 0.\n * @param {goog.vec.Vec3.AnyType} vec1 The vector to receive column 1.\n * @param {goog.vec.Vec3.AnyType} vec2 The vector to receive column 2.\n */\ngoog.vec.Mat3.getColumns = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.Mat3.getColumn(mat, 0, vec0);\n goog.vec.Mat3.getColumn(mat, 1, vec1);\n goog.vec.Mat3.getColumn(mat, 2, vec2);\n};\n\n\n/**\n * Sets the row values from the supplied values.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {number} row The index of the row to receive the values.\n * @param {number} v0 The value for column 0.\n * @param {number} v1 The value for column 1.\n * @param {number} v2 The value for column 2.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setRowValues = function(mat, row, v0, v1, v2) {\n 'use strict';\n mat[row] = v0;\n mat[row + 3] = v1;\n mat[row + 6] = v2;\n return mat;\n};\n\n\n/**\n * Sets the row values from the supplied vector.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the row values.\n * @param {number} row The index of the row.\n * @param {goog.vec.Vec3.AnyType} vec The vector containing the values.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setRow = function(mat, row, vec) {\n 'use strict';\n mat[row] = vec[0];\n mat[row + 3] = vec[1];\n mat[row + 6] = vec[2];\n return mat;\n};\n\n\n/**\n * Retrieves the row values into the given vector.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix supplying the values.\n * @param {number} row The index of the row supplying the values.\n * @param {goog.vec.Vec3.AnyType} vec The vector to receive the row.\n * @return {goog.vec.Vec3.AnyType} return vec so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.getRow = function(mat, row, vec) {\n 'use strict';\n vec[0] = mat[row];\n vec[1] = mat[row + 3];\n vec[2] = mat[row + 6];\n return vec;\n};\n\n\n/**\n * Sets the rows of the matrix from the supplied vectors.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Vec3.AnyType} vec0 The values for row 0.\n * @param {goog.vec.Vec3.AnyType} vec1 The values for row 1.\n * @param {goog.vec.Vec3.AnyType} vec2 The values for row 2.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.setRows = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.Mat3.setRow(mat, 0, vec0);\n goog.vec.Mat3.setRow(mat, 1, vec1);\n goog.vec.Mat3.setRow(mat, 2, vec2);\n return mat;\n};\n\n\n/**\n * Retrieves the rows of the matrix into the supplied vectors.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to supplying the values.\n * @param {goog.vec.Vec3.AnyType} vec0 The vector to receive row 0.\n * @param {goog.vec.Vec3.AnyType} vec1 The vector to receive row 1.\n * @param {goog.vec.Vec3.AnyType} vec2 The vector to receive row 2.\n */\ngoog.vec.Mat3.getRows = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.Mat3.getRow(mat, 0, vec0);\n goog.vec.Mat3.getRow(mat, 1, vec1);\n goog.vec.Mat3.getRow(mat, 2, vec2);\n};\n\n\n/**\n * Makes the given 3x3 matrix the zero matrix.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @return {goog.vec.Mat3.AnyType} return mat so operations can be chained.\n */\ngoog.vec.Mat3.makeZero = function(mat) {\n 'use strict';\n mat[0] = 0;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix the identity matrix.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @return {goog.vec.Mat3.AnyType} return mat so operations can be chained.\n */\ngoog.vec.Mat3.makeIdentity = function(mat) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 1;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Performs a per-component addition of the matrices mat0 and mat1, storing\n * the result into resultMat.\n *\n * @param {goog.vec.Mat3.AnyType} mat0 The first addend.\n * @param {goog.vec.Mat3.AnyType} mat1 The second addend.\n * @param {goog.vec.Mat3.AnyType} resultMat The matrix to\n * receive the results (may be either mat0 or mat1).\n * @return {goog.vec.Mat3.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.addMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] + mat1[0];\n resultMat[1] = mat0[1] + mat1[1];\n resultMat[2] = mat0[2] + mat1[2];\n resultMat[3] = mat0[3] + mat1[3];\n resultMat[4] = mat0[4] + mat1[4];\n resultMat[5] = mat0[5] + mat1[5];\n resultMat[6] = mat0[6] + mat1[6];\n resultMat[7] = mat0[7] + mat1[7];\n resultMat[8] = mat0[8] + mat1[8];\n return resultMat;\n};\n\n\n/**\n * Performs a per-component subtraction of the matrices mat0 and mat1,\n * storing the result into resultMat.\n *\n * @param {goog.vec.Mat3.AnyType} mat0 The minuend.\n * @param {goog.vec.Mat3.AnyType} mat1 The subtrahend.\n * @param {goog.vec.Mat3.AnyType} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {goog.vec.Mat3.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.subMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] - mat1[0];\n resultMat[1] = mat0[1] - mat1[1];\n resultMat[2] = mat0[2] - mat1[2];\n resultMat[3] = mat0[3] - mat1[3];\n resultMat[4] = mat0[4] - mat1[4];\n resultMat[5] = mat0[5] - mat1[5];\n resultMat[6] = mat0[6] - mat1[6];\n resultMat[7] = mat0[7] - mat1[7];\n resultMat[8] = mat0[8] - mat1[8];\n return resultMat;\n};\n\n\n/**\n * Multiplies matrix mat0 with the given scalar, storing the result\n * into resultMat.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} scalar The scalar value to multiple to each element of mat.\n * @param {goog.vec.Mat3.AnyType} resultMat The matrix to receive\n * the results (may be mat).\n * @return {goog.vec.Mat3.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.multScalar = function(mat, scalar, resultMat) {\n 'use strict';\n resultMat[0] = mat[0] * scalar;\n resultMat[1] = mat[1] * scalar;\n resultMat[2] = mat[2] * scalar;\n resultMat[3] = mat[3] * scalar;\n resultMat[4] = mat[4] * scalar;\n resultMat[5] = mat[5] * scalar;\n resultMat[6] = mat[6] * scalar;\n resultMat[7] = mat[7] * scalar;\n resultMat[8] = mat[8] * scalar;\n return resultMat;\n};\n\n\n/**\n * Multiplies the two matrices mat0 and mat1 using matrix multiplication,\n * storing the result into resultMat.\n *\n * @param {goog.vec.Mat3.AnyType} mat0 The first (left hand) matrix.\n * @param {goog.vec.Mat3.AnyType} mat1 The second (right hand) matrix.\n * @param {goog.vec.Mat3.AnyType} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {goog.vec.Mat3.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.multMat = function(mat0, mat1, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n\n const a01 = mat0[3];\n const a11 = mat0[4];\n const a21 = mat0[5];\n\n const a02 = mat0[6];\n const a12 = mat0[7];\n const a22 = mat0[8];\n\n\n const b00 = mat1[0];\n const b10 = mat1[1];\n const b20 = mat1[2];\n\n const b01 = mat1[3];\n const b11 = mat1[4];\n const b21 = mat1[5];\n\n const b02 = mat1[6];\n const b12 = mat1[7];\n const b22 = mat1[8];\n\n\n resultMat[0] = a00 * b00 + a01 * b10 + a02 * b20;\n resultMat[1] = a10 * b00 + a11 * b10 + a12 * b20;\n resultMat[2] = a20 * b00 + a21 * b10 + a22 * b20;\n resultMat[3] = a00 * b01 + a01 * b11 + a02 * b21;\n resultMat[4] = a10 * b01 + a11 * b11 + a12 * b21;\n resultMat[5] = a20 * b01 + a21 * b11 + a22 * b21;\n resultMat[6] = a00 * b02 + a01 * b12 + a02 * b22;\n resultMat[7] = a10 * b02 + a11 * b12 + a12 * b22;\n resultMat[8] = a20 * b02 + a21 * b12 + a22 * b22;\n return resultMat;\n};\n\n\n/**\n * Transposes the given matrix mat storing the result into resultMat.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix to transpose.\n * @param {goog.vec.Mat3.AnyType} resultMat The matrix to receive\n * the results (may be mat).\n * @return {goog.vec.Mat3.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.transpose = function(mat, resultMat) {\n 'use strict';\n if (resultMat == mat) {\n const a10 = mat[1];\n const a20 = mat[2];\n const a21 = mat[5];\n\n resultMat[1] = mat[3];\n resultMat[2] = mat[6];\n resultMat[3] = a10;\n resultMat[5] = mat[7];\n resultMat[6] = a20;\n resultMat[7] = a21;\n } else {\n resultMat[0] = mat[0];\n resultMat[1] = mat[3];\n resultMat[2] = mat[6];\n resultMat[3] = mat[1];\n resultMat[4] = mat[4];\n resultMat[5] = mat[7];\n resultMat[6] = mat[2];\n resultMat[7] = mat[5];\n resultMat[8] = mat[8];\n }\n return resultMat;\n};\n\n\n/**\n * Computes the inverse of mat0 storing the result into resultMat. If the\n * inverse is defined, this function returns true, false otherwise.\n *\n * @param {goog.vec.Mat3.AnyType} mat0 The matrix to invert.\n * @param {goog.vec.Mat3.AnyType} resultMat The matrix to receive\n * the result (may be mat0).\n * @return {boolean} True if the inverse is defined. If false is returned,\n * resultMat is not modified.\n */\ngoog.vec.Mat3.invert = function(mat0, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n\n const a01 = mat0[3];\n const a11 = mat0[4];\n const a21 = mat0[5];\n\n const a02 = mat0[6];\n const a12 = mat0[7];\n const a22 = mat0[8];\n\n\n const t00 = a11 * a22 - a12 * a21;\n const t10 = a12 * a20 - a10 * a22;\n const t20 = a10 * a21 - a11 * a20;\n const det = a00 * t00 + a01 * t10 + a02 * t20;\n if (det == 0) {\n return false;\n }\n\n const idet = 1 / det;\n resultMat[0] = t00 * idet;\n resultMat[3] = (a02 * a21 - a01 * a22) * idet;\n resultMat[6] = (a01 * a12 - a02 * a11) * idet;\n\n resultMat[1] = t10 * idet;\n resultMat[4] = (a00 * a22 - a02 * a20) * idet;\n resultMat[7] = (a02 * a10 - a00 * a12) * idet;\n\n resultMat[2] = t20 * idet;\n resultMat[5] = (a01 * a20 - a00 * a21) * idet;\n resultMat[8] = (a00 * a11 - a01 * a10) * idet;\n return true;\n};\n\n\n/**\n * Returns true if the components of mat0 are equal to the components of mat1.\n *\n * @param {goog.vec.Mat3.AnyType} mat0 The first matrix.\n * @param {goog.vec.Mat3.AnyType} mat1 The second matrix.\n * @return {boolean} True if the two matrices are equivalent.\n */\ngoog.vec.Mat3.equals = function(mat0, mat1) {\n 'use strict';\n return mat0.length == mat1.length && mat0[0] == mat1[0] &&\n mat0[1] == mat1[1] && mat0[2] == mat1[2] && mat0[3] == mat1[3] &&\n mat0[4] == mat1[4] && mat0[5] == mat1[5] && mat0[6] == mat1[6] &&\n mat0[7] == mat1[7] && mat0[8] == mat1[8];\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed matrix into resultVec.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix supplying the transformation.\n * @param {goog.vec.Vec3.AnyType} vec The vector to transform.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to\n * receive the results (may be vec).\n * @return {goog.vec.Vec3.AnyType} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.multVec3 = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[3] + z * mat[6];\n resultVec[1] = x * mat[1] + y * mat[4] + z * mat[7];\n resultVec[2] = x * mat[2] + y * mat[5] + z * mat[8];\n return resultVec;\n};\n\n\n/**\n * Makes the given 3x3 matrix a translation matrix with x and y\n * translation values.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.makeTranslate = function(mat, x, y) {\n 'use strict';\n goog.vec.Mat3.makeIdentity(mat);\n return goog.vec.Mat3.setColumnValues(mat, 2, x, y, 1);\n};\n\n\n/**\n * Makes the given 3x3 matrix a scale matrix with x, y, and z scale factors.\n *\n * @param {goog.vec.Mat3.AnyType} mat The 3x3 (9-element) matrix\n * array to receive the new scale matrix.\n * @param {number} x The scale along the x axis.\n * @param {number} y The scale along the y axis.\n * @param {number} z The scale along the z axis.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.makeScale = function(mat, x, y, z) {\n 'use strict';\n goog.vec.Mat3.makeIdentity(mat);\n return goog.vec.Mat3.setDiagonalValues(mat, x, y, z);\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the axis defined by the vector (ax, ay, az).\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @param {number} ax The x component of the rotation axis.\n * @param {number} ay The y component of the rotation axis.\n * @param {number} az The z component of the rotation axis.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.makeRotate = function(mat, angle, ax, ay, az) {\n 'use strict';\n const c = Math.cos(angle);\n const d = 1 - c;\n const s = Math.sin(angle);\n\n return goog.vec.Mat3.setFromValues(\n mat, ax * ax * d + c, ax * ay * d + az * s, ax * az * d - ay * s,\n\n ax * ay * d - az * s, ay * ay * d + c, ay * az * d + ax * s,\n\n ax * az * d + ay * s, ay * az * d - ax * s, az * az * d + c);\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the X axis.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.makeRotateX = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n return goog.vec.Mat3.setFromValues(mat, 1, 0, 0, 0, c, s, 0, -s, c);\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the Y axis.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.makeRotateY = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n return goog.vec.Mat3.setFromValues(mat, c, 0, -s, 0, 1, 0, s, 0, c);\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the Z axis.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.makeRotateZ = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n return goog.vec.Mat3.setFromValues(mat, c, s, 0, -s, c, 0, 0, 0, 1);\n};\n\n\n/**\n * Rotate the given matrix by angle about the x,y,z axis. Equivalent to:\n * goog.vec.Mat3.multMat(\n * mat,\n * goog.vec.Mat3.makeRotate(goog.vec.Mat3.create(), angle, x, y, z),\n * mat);\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} angle The angle in radians.\n * @param {number} x The x component of the rotation axis.\n * @param {number} y The y component of the rotation axis.\n * @param {number} z The z component of the rotation axis.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.rotate = function(mat, angle, x, y, z) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const cosAngle = Math.cos(angle);\n const sinAngle = Math.sin(angle);\n const diffCosAngle = 1 - cosAngle;\n const r00 = x * x * diffCosAngle + cosAngle;\n const r10 = x * y * diffCosAngle + z * sinAngle;\n const r20 = x * z * diffCosAngle - y * sinAngle;\n\n const r01 = x * y * diffCosAngle - z * sinAngle;\n const r11 = y * y * diffCosAngle + cosAngle;\n const r21 = y * z * diffCosAngle + x * sinAngle;\n\n const r02 = x * z * diffCosAngle + y * sinAngle;\n const r12 = y * z * diffCosAngle - x * sinAngle;\n const r22 = z * z * diffCosAngle + cosAngle;\n\n return goog.vec.Mat3.setFromValues(\n mat, m00 * r00 + m01 * r10 + m02 * r20, m10 * r00 + m11 * r10 + m12 * r20,\n m20 * r00 + m21 * r10 + m22 * r20,\n\n m00 * r01 + m01 * r11 + m02 * r21, m10 * r01 + m11 * r11 + m12 * r21,\n m20 * r01 + m21 * r11 + m22 * r21,\n\n m00 * r02 + m01 * r12 + m02 * r22, m10 * r02 + m11 * r12 + m12 * r22,\n m20 * r02 + m21 * r12 + m22 * r22);\n};\n\n\n/**\n * Rotate the given matrix by angle about the x axis. Equivalent to:\n * goog.vec.Mat3.multMat(\n * mat,\n * goog.vec.Mat3.makeRotateX(goog.vec.Mat3.create(), angle),\n * mat);\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.rotateX = function(mat, angle) {\n 'use strict';\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[3] = m01 * c + m02 * s;\n mat[4] = m11 * c + m12 * s;\n mat[5] = m21 * c + m22 * s;\n mat[6] = m01 * -s + m02 * c;\n mat[7] = m11 * -s + m12 * c;\n mat[8] = m21 * -s + m22 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the y axis. Equivalent to:\n * goog.vec.Mat3.multMat(\n * mat,\n * goog.vec.Mat3.makeRotateY(goog.vec.Mat3.create(), angle),\n * mat);\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.rotateY = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m02 * -s;\n mat[1] = m10 * c + m12 * -s;\n mat[2] = m20 * c + m22 * -s;\n mat[6] = m00 * s + m02 * c;\n mat[7] = m10 * s + m12 * c;\n mat[8] = m20 * s + m22 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the z axis. Equivalent to:\n * goog.vec.Mat3.multMat(\n * mat,\n * goog.vec.Mat3.makeRotateZ(goog.vec.Mat3.create(), angle),\n * mat);\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.rotateZ = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m01 * s;\n mat[1] = m10 * c + m11 * s;\n mat[2] = m20 * c + m21 * s;\n mat[3] = m00 * -s + m01 * c;\n mat[4] = m10 * -s + m11 * c;\n mat[5] = m20 * -s + m21 * c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix given Euler angles using\n * the ZXZ convention.\n * Given the euler angles [theta1, theta2, theta3], the rotation is defined as\n * rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {number} theta1 The angle of rotation around the Z axis in radians.\n * @param {number} theta2 The angle of rotation around the X axis in radians.\n * @param {number} theta3 The angle of rotation around the Z axis in radians.\n * @return {goog.vec.Mat3.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat3.makeEulerZXZ = function(mat, theta1, theta2, theta3) {\n 'use strict';\n const c1 = Math.cos(theta1);\n const s1 = Math.sin(theta1);\n\n const c2 = Math.cos(theta2);\n const s2 = Math.sin(theta2);\n\n const c3 = Math.cos(theta3);\n const s3 = Math.sin(theta3);\n\n mat[0] = c1 * c3 - c2 * s1 * s3;\n mat[1] = c2 * c1 * s3 + c3 * s1;\n mat[2] = s3 * s2;\n\n mat[3] = -c1 * s3 - c3 * c2 * s1;\n mat[4] = c1 * c2 * c3 - s1 * s3;\n mat[5] = c3 * s2;\n\n mat[6] = s2 * s1;\n mat[7] = -c1 * s2;\n mat[8] = c2;\n\n return mat;\n};\n\n\n/**\n * Decomposes a rotation matrix into Euler angles using the ZXZ convention so\n * that rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {goog.vec.Mat3.AnyType} mat The matrix.\n * @param {goog.vec.Vec3.AnyType} euler The ZXZ Euler angles in\n * radians as [theta1, theta2, theta3].\n * @param {boolean=} opt_theta2IsNegative Whether theta2 is in [-pi, 0] instead\n * of the default [0, pi].\n * @return {goog.vec.Vec3.AnyType} return euler so that operations can be\n * chained together.\n */\ngoog.vec.Mat3.toEulerZXZ = function(mat, euler, opt_theta2IsNegative) {\n 'use strict';\n // There is an ambiguity in the sign of sinTheta2 because of the sqrt.\n const sinTheta2 = Math.sqrt(mat[2] * mat[2] + mat[5] * mat[5]);\n\n // By default we explicitely constrain theta2 to be in [0, pi],\n // so sinTheta2 is always positive. We can change the behavior and specify\n // theta2 to be negative in [-pi, 0] with opt_Theta2IsNegative.\n const signTheta2 = opt_theta2IsNegative ? -1 : 1;\n\n if (sinTheta2 > goog.vec.EPSILON) {\n euler[2] = Math.atan2(mat[2] * signTheta2, mat[5] * signTheta2);\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[8]);\n euler[0] = Math.atan2(mat[6] * signTheta2, -mat[7] * signTheta2);\n } else {\n // There is also an arbitrary choice for theta1 = 0 or theta2 = 0 here.\n // We assume theta1 = 0 as some applications do not allow the camera to roll\n // (i.e. have theta1 != 0).\n euler[0] = 0;\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[8]);\n euler[2] = Math.atan2(mat[1], mat[0]);\n }\n\n // Atan2 outputs angles in [-pi, pi] so we bring them back to [0, 2 * pi].\n euler[0] = (euler[0] + Math.PI * 2) % (Math.PI * 2);\n euler[2] = (euler[2] + Math.PI * 2) % (Math.PI * 2);\n // For theta2 we want the angle to be in [0, pi] or [-pi, 0] depending on\n // signTheta2.\n euler[1] =\n ((euler[1] * signTheta2 + Math.PI * 2) % (Math.PI * 2)) * signTheta2;\n\n return euler;\n};\n","^<",1684857788697,"^=",["^3",["~$goog.vec","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.Mat3"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",["goog.vec.Vec3"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/mat3.js"],"^[",["^3",["^13"]],"^W",["^3",["~$goog.vec.Vec3"]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.Vec4"]],"^5","goog.vec.vec4.js","^6",["^7","goog/vec/vec4.js"],"^8","goog/vec/vec4.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Supplies 4 element vectors that are compatible with WebGL.\n * Each element is a float32 since that is typically the desired size of a\n * 4-vector in the GPU. The API is structured to avoid unnecessary memory\n * allocations. The last parameter will typically be the output vector and\n * an object can be both an input and output parameter to all methods except\n * where noted.\n */\ngoog.provide('goog.vec.Vec4');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.Vec4.Float32;\n/** @typedef {!goog.vec.Float64} */ goog.vec.Vec4.Float64;\n/** @typedef {!goog.vec.Number} */ goog.vec.Vec4.Number;\n/** @typedef {!goog.vec.AnyType} */ goog.vec.Vec4.AnyType;\n\n// The following two types are deprecated - use the above types instead.\n/** @typedef {!Float32Array} */ goog.vec.Vec4.Type;\n/** @typedef {!goog.vec.ArrayType} */ goog.vec.Vec4.Vec4Like;\n\n\n/**\n * Creates a 4 element vector of Float32. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec4.Float32} The new 3 element array.\n */\ngoog.vec.Vec4.createFloat32 = function() {\n 'use strict';\n return new Float32Array(4);\n};\n\n\n/**\n * Creates a 4 element vector of Float64. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec4.Float64} The new 4 element array.\n */\ngoog.vec.Vec4.createFloat64 = function() {\n 'use strict';\n return new Float64Array(4);\n};\n\n\n/**\n * Creates a 4 element vector of Number. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec4.Number} The new 4 element array.\n */\ngoog.vec.Vec4.createNumber = function() {\n 'use strict';\n const v = new Array(4);\n goog.vec.Vec4.setFromValues(v, 0, 0, 0, 0);\n return v;\n};\n\n\n/**\n * Creates a 4 element vector of Float32Array. The array is initialized to zero.\n *\n * @deprecated Use createFloat32.\n * @return {!goog.vec.Vec4.Type} The new 4 element array.\n */\ngoog.vec.Vec4.create = function() {\n 'use strict';\n return new Float32Array(4);\n};\n\n\n/**\n * Creates a new 4 element vector initialized with the value from the given\n * array.\n *\n * @deprecated Use createFloat32FromArray.\n * @param {goog.vec.Vec4.Vec4Like} vec The source 4 element array.\n * @return {!goog.vec.Vec4.Type} The new 4 element array.\n */\ngoog.vec.Vec4.createFromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.Vec4.create();\n goog.vec.Vec4.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new 4 element FLoat32 vector initialized with the value from the\n * given array.\n *\n * @param {goog.vec.Vec4.AnyType} vec The source 3 element array.\n * @return {!goog.vec.Vec4.Float32} The new 3 element array.\n */\ngoog.vec.Vec4.createFloat32FromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.Vec4.createFloat32();\n goog.vec.Vec4.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new 4 element Float32 vector initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.Vec4.Float32} The new vector.\n */\ngoog.vec.Vec4.createFloat32FromValues = function(v0, v1, v2, v3) {\n 'use strict';\n const vec = goog.vec.Vec4.createFloat32();\n goog.vec.Vec4.setFromValues(vec, v0, v1, v2, v3);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given 4 element Float32 vector.\n *\n * @param {goog.vec.Vec4.Float32} vec The source 3 element vector.\n * @return {!goog.vec.Vec4.Float32} The new cloned vector.\n */\ngoog.vec.Vec4.cloneFloat32 = goog.vec.Vec4.createFloat32FromArray;\n\n\n/**\n * Creates a new 4 element Float64 vector initialized with the value from the\n * given array.\n *\n * @param {goog.vec.Vec4.AnyType} vec The source 4 element array.\n * @return {!goog.vec.Vec4.Float64} The new 4 element array.\n */\ngoog.vec.Vec4.createFloat64FromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.Vec4.createFloat64();\n goog.vec.Vec4.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n* Creates a new 4 element Float64 vector initialized with the supplied values.\n*\n* @param {number} v0 The value for element at index 0.\n* @param {number} v1 The value for element at index 1.\n* @param {number} v2 The value for element at index 2.\n* @param {number} v3 The value for element at index 3.\n* @return {!goog.vec.Vec4.Float64} The new vector.\n*/\ngoog.vec.Vec4.createFloat64FromValues = function(v0, v1, v2, v3) {\n 'use strict';\n const vec = goog.vec.Vec4.createFloat64();\n goog.vec.Vec4.setFromValues(vec, v0, v1, v2, v3);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given 4 element vector.\n *\n * @param {goog.vec.Vec4.Float64} vec The source 4 element vector.\n * @return {!goog.vec.Vec4.Float64} The new cloned vector.\n */\ngoog.vec.Vec4.cloneFloat64 = goog.vec.Vec4.createFloat64FromArray;\n\n\n/**\n * Creates a new 4 element vector initialized with the supplied values.\n *\n * @deprecated Use createFloat32FromValues.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.Vec4.Type} The new vector.\n */\ngoog.vec.Vec4.createFromValues = function(v0, v1, v2, v3) {\n 'use strict';\n const vec = goog.vec.Vec4.create();\n goog.vec.Vec4.setFromValues(vec, v0, v1, v2, v3);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given 4 element vector.\n *\n * @deprecated Use cloneFloat32.\n * @param {goog.vec.Vec4.Vec4Like} vec The source 4 element vector.\n * @return {!goog.vec.Vec4.Type} The new cloned vector.\n */\ngoog.vec.Vec4.clone = goog.vec.Vec4.createFromArray;\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {goog.vec.Vec4.AnyType} vec The vector to receive the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.Vec4.AnyType} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.setFromValues = function(vec, v0, v1, v2, v3) {\n 'use strict';\n vec[0] = v0;\n vec[1] = v1;\n vec[2] = v2;\n vec[3] = v3;\n return vec;\n};\n\n\n/**\n * Initializes the vector with the given array of values.\n *\n * @param {goog.vec.Vec4.AnyType} vec The vector to receive the\n * values.\n * @param {goog.vec.Vec4.AnyType} values The array of values.\n * @return {!goog.vec.Vec4.AnyType} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.setFromArray = function(vec, values) {\n 'use strict';\n vec[0] = values[0];\n vec[1] = values[1];\n vec[2] = values[2];\n vec[3] = values[3];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The first addend.\n * @param {goog.vec.Vec4.AnyType} vec1 The second addend.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n resultVec[2] = vec0[2] + vec1[2];\n resultVec[3] = vec0[3] + vec1[3];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The minuend.\n * @param {goog.vec.Vec4.AnyType} vec1 The subtrahend.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n resultVec[2] = vec0[2] - vec1[2];\n resultVec[3] = vec0[3] - vec1[3];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The vector to negate.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n resultVec[2] = -vec0[2];\n resultVec[3] = -vec0[3];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n resultVec[2] = Math.abs(vec0[2]);\n resultVec[3] = Math.abs(vec0[3]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n resultVec[2] = vec0[2] * scalar;\n resultVec[3] = vec0[3] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.Vec4.magnitudeSquared = function(vec0) {\n 'use strict';\n const w = vec0[3];\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return x * x + y * y + z * z + w * w;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.Vec4.magnitude = function(vec0) {\n 'use strict';\n const w = vec0[3];\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return Math.sqrt(x * x + y * y + z * z + w * w);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The vector to normalize.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.normalize = function(vec0, resultVec) {\n 'use strict';\n const ilen = 1 / goog.vec.Vec4.magnitude(vec0);\n resultVec[0] = vec0[0] * ilen;\n resultVec[1] = vec0[1] * ilen;\n resultVec[2] = vec0[2] * ilen;\n resultVec[3] = vec0[3] * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors v0 and v1.\n *\n * @param {goog.vec.Vec4.AnyType} v0 The first vector.\n * @param {goog.vec.Vec4.AnyType} v1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.Vec4.dot = function(v0, v1) {\n 'use strict';\n return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2] + v0[3] * v1[3];\n};\n\n\n/**\n * Linearly interpolate from v0 to v1 according to f. The value of f should be\n * in the range [0..1] otherwise the results are undefined.\n *\n * @param {goog.vec.Vec4.AnyType} v0 The first vector.\n * @param {goog.vec.Vec4.AnyType} v1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to receive the\n * results (may be v0 or v1).\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.lerp = function(v0, v1, f, resultVec) {\n 'use strict';\n const w = v0[3];\n const x = v0[0];\n const y = v0[1];\n const z = v0[2];\n\n resultVec[0] = (v1[0] - x) * f + x;\n resultVec[1] = (v1[1] - y) * f + y;\n resultVec[2] = (v1[2] - z) * f + z;\n resultVec[3] = (v1[3] - w) * f + w;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec4.AnyType|number} limit The limit vector or scalar.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n resultVec[2] = Math.max(vec0[2], limit);\n resultVec[3] = Math.max(vec0[3], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n resultVec[2] = Math.max(vec0[2], limit[2]);\n resultVec[3] = Math.max(vec0[3], limit[3]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {goog.vec.Vec4.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec4.AnyType|number} limit The limit vector or scalar.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec4.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n resultVec[2] = Math.min(vec0[2], limit);\n resultVec[3] = Math.min(vec0[3], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n resultVec[2] = Math.min(vec0[2], limit[2]);\n resultVec[3] = Math.min(vec0[3], limit[3]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of v0 are equal to the components of v1.\n *\n * @param {goog.vec.Vec4.AnyType} v0 The first vector.\n * @param {goog.vec.Vec4.AnyType} v1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.Vec4.equals = function(v0, v1) {\n 'use strict';\n return v0.length == v1.length && v0[0] == v1[0] && v0[1] == v1[1] &&\n v0[2] == v1[2] && v0[3] == v1[3];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.Vec4"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec4.js"],"^[",["^3",["^16"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.vec2f","~$goog.vec.vec2f.Type"]],"^5","goog.vec.vec2f.js","^6",["^7","goog/vec/vec2f.js"],"^8","goog/vec/vec2f.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to vec2d.js by running: //\n// swap_type.sh vec2f.js > vec2d.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 2 element float (32bit)\n * vectors.\n *\n * The last parameter will typically be the output object and an object\n * can be both an input and output parameter to all methods except where\n * noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\n\ngoog.provide('goog.vec.vec2f');\ngoog.provide('goog.vec.vec2f.Type');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.vec2f.Type;\n\n\n/**\n * Creates a vec2f with all elements initialized to zero.\n *\n * @return {!goog.vec.vec2f.Type} The new vec2f.\n */\ngoog.vec.vec2f.create = function() {\n 'use strict';\n return new Float32Array(2);\n};\n\n\n/**\n * Creates a new vec2f initialized with the value from the given array.\n *\n * @param {!Array} vec The source 2 element array.\n * @return {!goog.vec.vec2f.Type} The new vec2f.\n */\ngoog.vec.vec2f.createFromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec2f.create();\n goog.vec.vec2f.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new vec2f initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @return {!goog.vec.vec2f.Type} The new vector.\n */\ngoog.vec.vec2f.createFromValues = function(v0, v1) {\n 'use strict';\n const vec = goog.vec.vec2f.create();\n goog.vec.vec2f.setFromValues(vec, v0, v1);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given vec2f.\n *\n * @param {!goog.vec.vec2f.Type} vec The source vec2f.\n * @return {!goog.vec.vec2f.Type} The new cloned vec2f.\n */\ngoog.vec.vec2f.clone = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec2f.create();\n goog.vec.vec2f.setFromVec2f(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {!goog.vec.vec2f.Type} vec The vector to receive the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @return {!goog.vec.vec2f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.setFromValues = function(vec, v0, v1) {\n 'use strict';\n vec[0] = v0;\n vec[1] = v1;\n return vec;\n};\n\n\n/**\n * Initializes vec2f vec from vec2f src.\n *\n * @param {!goog.vec.vec2f.Type} vec The destination vector.\n * @param {!goog.vec.vec2f.Type} src The source vector.\n * @return {!goog.vec.vec2f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.setFromVec2f = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n return vec;\n};\n\n\n/**\n * Initializes vec2f vec from vec2d src (typed as a Float64Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.vec2f.Type} vec The destination vector.\n * @param {Float64Array} src The source vector.\n * @return {!goog.vec.vec2f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.setFromVec2d = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n return vec;\n};\n\n\n/**\n * Initializes vec2f vec from Array src.\n *\n * @param {!goog.vec.vec2f.Type} vec The destination vector.\n * @param {Array} src The source vector.\n * @return {!goog.vec.vec2f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.setFromArray = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The first addend.\n * @param {!goog.vec.vec2f.Type} vec1 The second addend.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The minuend.\n * @param {!goog.vec.vec2f.Type} vec1 The subtrahend.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with the matching element of vec0\n * storing the products into resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The first vector.\n * @param {!goog.vec.vec2f.Type} vec1 The second vector.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.componentMultiply = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * vec1[0];\n resultVec[1] = vec0[1] * vec1[1];\n return resultVec;\n};\n\n\n/**\n * Divides each component of vec0 with the matching element of vec0\n * storing the divisor into resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The first vector.\n * @param {!goog.vec.vec2f.Type} vec1 The second vector.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.componentDivide = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] / vec1[0];\n resultVec[1] = vec0[1] / vec1[1];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The vector to negate.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The source vector.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec2f.magnitudeSquared = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n\n return x * x + y * y;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec2f.magnitude = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n\n return Math.sqrt(x * x + y * y);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The vector to normalize.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.normalize = function(vec0, resultVec) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n\n const ilen = 1 / Math.sqrt(x * x + y * y);\n resultVec[0] = x * ilen;\n resultVec[1] = y * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors vec0 and vec1.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The first vector.\n * @param {!goog.vec.vec2f.Type} vec1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.vec2f.dot = function(vec0, vec1) {\n 'use strict';\n return vec0[0] * vec1[0] + vec0[1] * vec1[1];\n};\n\n\n/**\n * Returns the squared distance between two points.\n *\n * @param {!goog.vec.vec2f.Type} vec0 First point.\n * @param {!goog.vec.vec2f.Type} vec1 Second point.\n * @return {number} The squared distance between the points.\n */\ngoog.vec.vec2f.distanceSquared = function(vec0, vec1) {\n 'use strict';\n const x = vec0[0] - vec1[0];\n const y = vec0[1] - vec1[1];\n return x * x + y * y;\n};\n\n\n/**\n * Returns the distance between two points.\n *\n * @param {!goog.vec.vec2f.Type} vec0 First point.\n * @param {!goog.vec.vec2f.Type} vec1 Second point.\n * @return {number} The distance between the points.\n */\ngoog.vec.vec2f.distance = function(vec0, vec1) {\n 'use strict';\n return Math.sqrt(goog.vec.vec2f.distanceSquared(vec0, vec1));\n};\n\n\n/**\n * Returns a unit vector pointing from one point to another.\n * If the input points are equal then the result will be all zeros.\n *\n * @param {!goog.vec.vec2f.Type} vec0 Origin point.\n * @param {!goog.vec.vec2f.Type} vec1 Target point.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.direction = function(vec0, vec1, resultVec) {\n 'use strict';\n const x = vec1[0] - vec0[0];\n const y = vec1[1] - vec0[1];\n let d = Math.sqrt(x * x + y * y);\n if (d) {\n d = 1 / d;\n resultVec[0] = x * d;\n resultVec[1] = y * d;\n } else {\n resultVec[0] = resultVec[1] = 0;\n }\n return resultVec;\n};\n\n\n/**\n * Linearly interpolate from vec0 to vec1 according to f. The value of f should\n * be in the range [0..1] otherwise the results are undefined.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The first vector.\n * @param {!goog.vec.vec2f.Type} vec1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.lerp = function(vec0, vec1, f, resultVec) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n\n resultVec[0] = (vec1[0] - x) * f + x;\n resultVec[1] = (vec1[1] - y) * f + y;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The source vector.\n * @param {!goog.vec.vec2f.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The source vector.\n * @param {!goog.vec.vec2f.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec2f.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2f.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of vec0 are equal to the components of vec1.\n *\n * @param {!goog.vec.vec2f.Type} vec0 The first vector.\n * @param {!goog.vec.vec2f.Type} vec1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.vec2f.equals = function(vec0, vec1) {\n 'use strict';\n return vec0.length == vec1.length && vec0[0] == vec1[0] && vec0[1] == vec1[1];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.vec2f","goog.vec.vec2f.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec2f.js"],"^[",["^3",["^17","^18"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.Number","^14","~$goog.vec.AnyType","~$goog.vec.Float32","~$goog.vec.Float64","~$goog.vec.ArrayType"]],"^5","goog.vec.vec.js","^6",["^7","goog/vec/vec.js"],"^8","goog/vec/vec.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Supplies global data types and constants for the vector math\n * library.\n */\ngoog.provide('goog.vec');\ngoog.provide('goog.vec.AnyType');\ngoog.provide('goog.vec.ArrayType');\ngoog.provide('goog.vec.Float32');\ngoog.provide('goog.vec.Float64');\ngoog.provide('goog.vec.Number');\n\n\n/**\n * On platforms that don't have native Float32Array or Float64Array support we\n * use a javascript implementation so that this math library can be used on all\n * platforms.\n * @suppress {extraRequire}\n */\ngoog.require('goog.vec.Float32Array');\n/** @suppress {extraRequire} */\ngoog.require('goog.vec.Float64Array');\n\n// All vector and matrix operations are based upon arrays of numbers using\n// either Float32Array, Float64Array, or a standard JavaScript Array of\n// Numbers.\n\n\n/** @typedef {!Float32Array} */\ngoog.vec.Float32;\n\n\n/** @typedef {!Float64Array} */\ngoog.vec.Float64;\n\n\n/** @typedef {!Array} */\ngoog.vec.Number;\n\n\n/** @typedef {!goog.vec.Float32|!goog.vec.Float64|!goog.vec.Number} */\ngoog.vec.AnyType;\n\n\n/**\n * @deprecated Use AnyType.\n * @typedef {!Float32Array|!Array}\n */\ngoog.vec.ArrayType;\n\n\n/**\n * For graphics work, 6 decimal places of accuracy are typically all that is\n * required.\n *\n * @type {number}\n * @const\n */\ngoog.vec.EPSILON = 1e-6;\n","^<",1684857788697,"^=",["^3",["^4","^>","~$goog.vec.Float32Array"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^4","^1>"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec","goog.vec.AnyType","goog.vec.ArrayType","goog.vec.Float32","goog.vec.Float64","goog.vec.Number"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.vec.Float32Array","goog.vec.Float64Array"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec.js"],"^[",["^3",["^19","^14","^1:","^1;","^1<","^1="]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1>","^4"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^15"]],"^5","goog.vec.vec3.js","^6",["^7","goog/vec/vec3.js"],"^8","goog/vec/vec3.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Supplies 3 element vectors that are compatible with WebGL.\n * Each element is a float32 since that is typically the desired size of a\n * 3-vector in the GPU. The API is structured to avoid unnecessary memory\n * allocations. The last parameter will typically be the output vector and\n * an object can be both an input and output parameter to all methods except\n * where noted.\n */\ngoog.provide('goog.vec.Vec3');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.Vec3.Float32;\n/** @typedef {!goog.vec.Float64} */ goog.vec.Vec3.Float64;\n/** @typedef {!goog.vec.Number} */ goog.vec.Vec3.Number;\n/** @typedef {!goog.vec.AnyType} */ goog.vec.Vec3.AnyType;\n\n// The following two types are deprecated - use the above types instead.\n/** @typedef {!Float32Array} */ goog.vec.Vec3.Type;\n/** @typedef {!goog.vec.ArrayType} */ goog.vec.Vec3.Vec3Like;\n\n\n/**\n * Creates a 3 element vector of Float32. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec3.Float32} The new 3 element array.\n */\ngoog.vec.Vec3.createFloat32 = function() {\n 'use strict';\n return new Float32Array(3);\n};\n\n\n/**\n * Creates a 3 element vector of Float64. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec3.Float64} The new 3 element array.\n */\ngoog.vec.Vec3.createFloat64 = function() {\n 'use strict';\n return new Float64Array(3);\n};\n\n\n/**\n * Creates a 3 element vector of Number. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec3.Number} The new 3 element array.\n */\ngoog.vec.Vec3.createNumber = function() {\n 'use strict';\n const a = new Array(3);\n goog.vec.Vec3.setFromValues(a, 0, 0, 0);\n return a;\n};\n\n\n/**\n * Creates a 3 element vector of Float32Array. The array is initialized to zero.\n *\n * @deprecated Use createFloat32.\n * @return {!goog.vec.Vec3.Type} The new 3 element array.\n */\ngoog.vec.Vec3.create = function() {\n 'use strict';\n return new Float32Array(3);\n};\n\n\n/**\n * Creates a new 3 element Float32 vector initialized with the value from the\n * given array.\n *\n * @param {goog.vec.Vec3.AnyType} vec The source 3 element array.\n * @return {!goog.vec.Vec3.Float32} The new 3 element array.\n */\ngoog.vec.Vec3.createFloat32FromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.Vec3.createFloat32();\n goog.vec.Vec3.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new 3 element Float32 vector initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @return {!goog.vec.Vec3.Float32} The new vector.\n */\ngoog.vec.Vec3.createFloat32FromValues = function(v0, v1, v2) {\n 'use strict';\n const a = goog.vec.Vec3.createFloat32();\n goog.vec.Vec3.setFromValues(a, v0, v1, v2);\n return a;\n};\n\n\n/**\n * Creates a clone of the given 3 element Float32 vector.\n *\n * @param {goog.vec.Vec3.Float32} vec The source 3 element vector.\n * @return {!goog.vec.Vec3.Float32} The new cloned vector.\n */\ngoog.vec.Vec3.cloneFloat32 = goog.vec.Vec3.createFloat32FromArray;\n\n\n/**\n * Creates a new 3 element Float64 vector initialized with the value from the\n * given array.\n *\n * @param {goog.vec.Vec3.AnyType} vec The source 3 element array.\n * @return {!goog.vec.Vec3.Float64} The new 3 element array.\n */\ngoog.vec.Vec3.createFloat64FromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.Vec3.createFloat64();\n goog.vec.Vec3.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n* Creates a new 3 element Float64 vector initialized with the supplied values.\n*\n* @param {number} v0 The value for element at index 0.\n* @param {number} v1 The value for element at index 1.\n* @param {number} v2 The value for element at index 2.\n* @return {!goog.vec.Vec3.Float64} The new vector.\n*/\ngoog.vec.Vec3.createFloat64FromValues = function(v0, v1, v2) {\n 'use strict';\n const vec = goog.vec.Vec3.createFloat64();\n goog.vec.Vec3.setFromValues(vec, v0, v1, v2);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given 3 element vector.\n *\n * @param {goog.vec.Vec3.Float64} vec The source 3 element vector.\n * @return {!goog.vec.Vec3.Float64} The new cloned vector.\n */\ngoog.vec.Vec3.cloneFloat64 = goog.vec.Vec3.createFloat64FromArray;\n\n\n/**\n * Creates a new 3 element vector initialized with the value from the given\n * array.\n *\n * @deprecated Use createFloat32FromArray.\n * @param {goog.vec.Vec3.Vec3Like} vec The source 3 element array.\n * @return {!goog.vec.Vec3.Type} The new 3 element array.\n */\ngoog.vec.Vec3.createFromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.Vec3.create();\n goog.vec.Vec3.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new 3 element vector initialized with the supplied values.\n *\n * @deprecated Use createFloat32FromValues.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @return {!goog.vec.Vec3.Type} The new vector.\n */\ngoog.vec.Vec3.createFromValues = function(v0, v1, v2) {\n 'use strict';\n const vec = goog.vec.Vec3.create();\n goog.vec.Vec3.setFromValues(vec, v0, v1, v2);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given 3 element vector.\n *\n * @deprecated Use cloneFloat32.\n * @param {goog.vec.Vec3.Vec3Like} vec The source 3 element vector.\n * @return {!goog.vec.Vec3.Type} The new cloned vector.\n */\ngoog.vec.Vec3.clone = function(vec) {\n 'use strict';\n const newVec = goog.vec.Vec3.create();\n goog.vec.Vec3.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {goog.vec.Vec3.AnyType} vec The vector to receive the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @return {!goog.vec.Vec3.AnyType} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.setFromValues = function(vec, v0, v1, v2) {\n 'use strict';\n vec[0] = v0;\n vec[1] = v1;\n vec[2] = v2;\n return vec;\n};\n\n\n/**\n * Initializes the vector with the given array of values.\n *\n * @param {goog.vec.Vec3.AnyType} vec The vector to receive the\n * values.\n * @param {goog.vec.Vec3.AnyType} values The array of values.\n * @return {!goog.vec.Vec3.AnyType} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.setFromArray = function(vec, values) {\n 'use strict';\n vec[0] = values[0];\n vec[1] = values[1];\n vec[2] = values[2];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The first addend.\n * @param {goog.vec.Vec3.AnyType} vec1 The second addend.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n resultVec[2] = vec0[2] + vec1[2];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The minuend.\n * @param {goog.vec.Vec3.AnyType} vec1 The subtrahend.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n resultVec[2] = vec0[2] - vec1[2];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The vector to negate.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n resultVec[2] = -vec0[2];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n resultVec[2] = Math.abs(vec0[2]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n resultVec[2] = vec0[2] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.Vec3.magnitudeSquared = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return x * x + y * y + z * z;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.Vec3.magnitude = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return Math.sqrt(x * x + y * y + z * z);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The vector to normalize.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.normalize = function(vec0, resultVec) {\n 'use strict';\n const ilen = 1 / goog.vec.Vec3.magnitude(vec0);\n resultVec[0] = vec0[0] * ilen;\n resultVec[1] = vec0[1] * ilen;\n resultVec[2] = vec0[2] * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors v0 and v1.\n *\n * @param {goog.vec.Vec3.AnyType} v0 The first vector.\n * @param {goog.vec.Vec3.AnyType} v1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.Vec3.dot = function(v0, v1) {\n 'use strict';\n return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];\n};\n\n\n/**\n * Computes the vector (cross) product of v0 and v1 storing the result into\n * resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} v0 The first vector.\n * @param {goog.vec.Vec3.AnyType} v1 The second vector.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the\n * results. May be either v0 or v1.\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.cross = function(v0, v1, resultVec) {\n 'use strict';\n const x0 = v0[0];\n const y0 = v0[1];\n const z0 = v0[2];\n\n const x1 = v1[0];\n const y1 = v1[1];\n const z1 = v1[2];\n\n resultVec[0] = y0 * z1 - z0 * y1;\n resultVec[1] = z0 * x1 - x0 * z1;\n resultVec[2] = x0 * y1 - y0 * x1;\n return resultVec;\n};\n\n\n/**\n * Returns the squared distance between two points.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 First point.\n * @param {goog.vec.Vec3.AnyType} vec1 Second point.\n * @return {number} The squared distance between the points.\n */\ngoog.vec.Vec3.distanceSquared = function(vec0, vec1) {\n 'use strict';\n const x = vec0[0] - vec1[0];\n const y = vec0[1] - vec1[1];\n const z = vec0[2] - vec1[2];\n return x * x + y * y + z * z;\n};\n\n\n/**\n * Returns the distance between two points.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 First point.\n * @param {goog.vec.Vec3.AnyType} vec1 Second point.\n * @return {number} The distance between the points.\n */\ngoog.vec.Vec3.distance = function(vec0, vec1) {\n 'use strict';\n return Math.sqrt(goog.vec.Vec3.distanceSquared(vec0, vec1));\n};\n\n\n/**\n * Returns a unit vector pointing from one point to another.\n * If the input points are equal then the result will be all zeros.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 Origin point.\n * @param {goog.vec.Vec3.AnyType} vec1 Target point.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.direction = function(vec0, vec1, resultVec) {\n 'use strict';\n const x = vec1[0] - vec0[0];\n const y = vec1[1] - vec0[1];\n const z = vec1[2] - vec0[2];\n let d = Math.sqrt(x * x + y * y + z * z);\n if (d) {\n d = 1 / d;\n resultVec[0] = x * d;\n resultVec[1] = y * d;\n resultVec[2] = z * d;\n } else {\n resultVec[0] = resultVec[1] = resultVec[2] = 0;\n }\n return resultVec;\n};\n\n\n/**\n * Linearly interpolate from vec0 to v1 according to f. The value of f should be\n * in the range [0..1] otherwise the results are undefined.\n *\n * @param {goog.vec.Vec3.AnyType} v0 The first vector.\n * @param {goog.vec.Vec3.AnyType} v1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the\n * results (may be v0 or v1).\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.lerp = function(v0, v1, f, resultVec) {\n 'use strict';\n const x = v0[0];\n const y = v0[1];\n const z = v0[2];\n\n resultVec[0] = (v1[0] - x) * f + x;\n resultVec[1] = (v1[1] - y) * f + y;\n resultVec[2] = (v1[2] - z) * f + z;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec3.AnyType|number} limit The limit vector or scalar.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n resultVec[2] = Math.max(vec0[2], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n resultVec[2] = Math.max(vec0[2], limit[2]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {goog.vec.Vec3.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec3.AnyType|number} limit The limit vector or scalar.\n * @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec3.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n resultVec[2] = Math.min(vec0[2], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n resultVec[2] = Math.min(vec0[2], limit[2]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of v0 are equal to the components of v1.\n *\n * @param {goog.vec.Vec3.AnyType} v0 The first vector.\n * @param {goog.vec.Vec3.AnyType} v1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.Vec3.equals = function(v0, v1) {\n 'use strict';\n return v0.length == v1.length && v0[0] == v1[0] && v0[1] == v1[1] &&\n v0[2] == v1[2];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.Vec3"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec3.js"],"^[",["^3",["^15"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.Ray"]],"^5","goog.vec.ray.js","^6",["^7","goog/vec/ray.js"],"^8","goog/vec/ray.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implements a 3D ray that are compatible with WebGL.\n * Each element is a float64 in case high precision is required.\n * The API is structured to avoid unnecessary memory allocations.\n * The last parameter will typically be the output vector and an\n * object can be both an input and output parameter to all methods\n * except where noted.\n *\n */\ngoog.provide('goog.vec.Ray');\n\ngoog.require('goog.vec.Vec3');\ngoog.requireType('goog.vec.AnyType');\n\n\n\n/**\n * Constructs a new ray with an optional origin and direction. If not specified,\n * the default is [0, 0, 0].\n * @param {goog.vec.Vec3.AnyType=} opt_origin The optional origin.\n * @param {goog.vec.Vec3.AnyType=} opt_dir The optional direction.\n * @constructor\n * @final\n */\ngoog.vec.Ray = function(opt_origin, opt_dir) {\n 'use strict';\n /**\n * @type {goog.vec.Vec3.Float64}\n */\n this.origin = goog.vec.Vec3.createFloat64();\n if (opt_origin) {\n goog.vec.Vec3.setFromArray(this.origin, opt_origin);\n }\n\n /**\n * @type {goog.vec.Vec3.Float64}\n */\n this.dir = goog.vec.Vec3.createFloat64();\n if (opt_dir) {\n goog.vec.Vec3.setFromArray(this.dir, opt_dir);\n }\n};\n\n\n/**\n * Sets the origin and direction of the ray.\n * @param {goog.vec.AnyType} origin The new origin.\n * @param {goog.vec.AnyType} dir The new direction.\n */\ngoog.vec.Ray.prototype.set = function(origin, dir) {\n 'use strict';\n goog.vec.Vec3.setFromArray(this.origin, origin);\n goog.vec.Vec3.setFromArray(this.dir, dir);\n};\n\n\n/**\n * Sets the origin of the ray.\n * @param {goog.vec.AnyType} origin the new origin.\n */\ngoog.vec.Ray.prototype.setOrigin = function(origin) {\n 'use strict';\n goog.vec.Vec3.setFromArray(this.origin, origin);\n};\n\n\n/**\n * Sets the direction of the ray.\n * @param {goog.vec.AnyType} dir The new direction.\n */\ngoog.vec.Ray.prototype.setDir = function(dir) {\n 'use strict';\n goog.vec.Vec3.setFromArray(this.dir, dir);\n};\n\n\n/**\n * Returns true if this ray is equal to the other ray.\n * @param {goog.vec.Ray} other The other ray.\n * @return {boolean} True if this ray is equal to the other ray.\n */\ngoog.vec.Ray.prototype.equals = function(other) {\n 'use strict';\n return other != null && goog.vec.Vec3.equals(this.origin, other.origin) &&\n goog.vec.Vec3.equals(this.dir, other.dir);\n};\n","^<",1684857788697,"^=",["^3",["^15","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^15"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.Ray"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.vec.Vec3"],"^W",["goog.vec.AnyType"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/ray.js"],"^[",["^3",["^1?"]],"^W",["^3",["^1:"]],"^10",true,"^11",true,"^12",["^>","^15"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.Quaternion.AnyType","~$goog.vec.Quaternion"]],"^5","goog.vec.quaternion.js","^6",["^7","goog/vec/quaternion.js"],"^8","goog/vec/quaternion.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Implements quaternions and their conversion functions. In this\n * implementation, quaternions are represented as 4 element vectors with the\n * first 3 elements holding the imaginary components and the 4th element holding\n * the real component.\n */\ngoog.provide('goog.vec.Quaternion');\ngoog.provide('goog.vec.Quaternion.AnyType');\n\ngoog.require('goog.vec');\ngoog.require('goog.vec.Vec3');\ngoog.require('goog.vec.Vec4');\n\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.Quaternion.Float32;\n/** @typedef {!goog.vec.Float64} */ goog.vec.Quaternion.Float64;\n/** @typedef {!goog.vec.Number} */ goog.vec.Quaternion.Number;\n/** @typedef {!goog.vec.AnyType} */ goog.vec.Quaternion.AnyType;\n\n\n/**\n * Creates a Float32 quaternion, initialized to zero.\n *\n * @return {!goog.vec.Quaternion.Float32} The new quaternion.\n */\ngoog.vec.Quaternion.createFloat32 = goog.vec.Vec4.createFloat32;\n\n\n/**\n * Creates a Float64 quaternion, initialized to zero.\n *\n * @return {!goog.vec.Quaternion.Float64} The new quaternion.\n */\ngoog.vec.Quaternion.createFloat64 = goog.vec.Vec4.createFloat64;\n\n\n/**\n * Creates a Number quaternion, initialized to zero.\n *\n * @return {goog.vec.Quaternion.Number} The new quaternion.\n */\ngoog.vec.Quaternion.createNumber = goog.vec.Vec4.createNumber;\n\n\n/**\n * Creates a new Float32 quaternion initialized with the values from the\n * supplied array.\n *\n * @param {!goog.vec.AnyType} vec The source 4 element array.\n * @return {!goog.vec.Quaternion.Float32} The new quaternion.\n */\ngoog.vec.Quaternion.createFloat32FromArray =\n goog.vec.Vec4.createFloat32FromArray;\n\n\n/**\n * Creates a new Float64 quaternion initialized with the values from the\n * supplied array.\n *\n * @param {!goog.vec.AnyType} vec The source 4 element array.\n * @return {!goog.vec.Quaternion.Float64} The new quaternion.\n */\ngoog.vec.Quaternion.createFloat64FromArray =\n goog.vec.Vec4.createFloat64FromArray;\n\n\n/**\n * Creates a new Float32 quaternion initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.Quaternion.Float32} The new quaternion.\n */\ngoog.vec.Quaternion.createFloat32FromValues =\n goog.vec.Vec4.createFloat32FromValues;\n\n\n/**\n * Creates a new Float64 quaternion initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.Quaternion.Float64} The new quaternion.\n */\ngoog.vec.Quaternion.createFloat64FromValues =\n goog.vec.Vec4.createFloat64FromValues;\n\n\n/**\n * Creates a clone of the given Float32 quaternion.\n *\n * @param {!goog.vec.Quaternion.Float32} q The source quaternion.\n * @return {!goog.vec.Quaternion.Float32} The new quaternion.\n */\ngoog.vec.Quaternion.cloneFloat32 = goog.vec.Vec4.cloneFloat32;\n\n\n/**\n * Creates a clone of the given Float64 quaternion.\n *\n * @param {!goog.vec.Quaternion.Float64} q The source quaternion.\n * @return {!goog.vec.Quaternion.Float64} The new quaternion.\n */\ngoog.vec.Quaternion.cloneFloat64 = goog.vec.Vec4.cloneFloat64;\n\n\n/**\n * Creates a Float32 quaternion, initialized to the identity.\n *\n * @return {!goog.vec.Quaternion.Float32} The new quaternion.\n */\ngoog.vec.Quaternion.createIdentityFloat32 = function() {\n 'use strict';\n const quat = goog.vec.Quaternion.createFloat32();\n goog.vec.Quaternion.makeIdentity(quat);\n return quat;\n};\n\n\n/**\n * Creates a Float64 quaternion, initialized to the identity.\n *\n * @return {!goog.vec.Quaternion.Float64} The new quaternion.\n */\ngoog.vec.Quaternion.createIdentityFloat64 = function() {\n 'use strict';\n const quat = goog.vec.Quaternion.createFloat64();\n goog.vec.Quaternion.makeIdentity(quat);\n return quat;\n};\n\n\n/**\n * Initializes the quaternion with the given values.\n *\n * @param {!goog.vec.Quaternion.AnyType} q The quaternion to receive\n * the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.Vec4.AnyType} return q so that operations can be\n * chained together.\n */\ngoog.vec.Quaternion.setFromValues = goog.vec.Vec4.setFromValues;\n\n\n/**\n * Initializes the quaternion with the given array of values.\n *\n * @param {!goog.vec.Quaternion.AnyType} q The quaternion to receive\n * the values.\n * @param {!goog.vec.AnyType} values The array of values.\n * @return {!goog.vec.Quaternion.AnyType} return q so that operations can be\n * chained together.\n */\ngoog.vec.Quaternion.setFromArray = goog.vec.Vec4.setFromArray;\n\n\n/**\n * Adds the two quaternions.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat0 The first addend.\n * @param {!goog.vec.Quaternion.AnyType} quat1 The second addend.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result. May be quat0 or quat1.\n */\ngoog.vec.Quaternion.add = goog.vec.Vec4.add;\n\n\n/**\n * Negates a quaternion, storing the result into resultQuat.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat0 The quaternion to negate.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result. May be quat0.\n */\ngoog.vec.Quaternion.negate = goog.vec.Vec4.negate;\n\n\n/**\n * Multiplies each component of quat0 with scalar storing the product into\n * resultVec.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat0 The source quaternion.\n * @param {number} scalar The value to multiply with each component of quat0.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result. May be quat0.\n */\ngoog.vec.Quaternion.scale = goog.vec.Vec4.scale;\n\n\n/**\n * Returns the square magnitude of the given quaternion.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat0 The quaternion.\n * @return {number} The magnitude of the quaternion.\n */\ngoog.vec.Quaternion.magnitudeSquared = goog.vec.Vec4.magnitudeSquared;\n\n\n/**\n * Returns the magnitude of the given quaternion.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat0 The quaternion.\n * @return {number} The magnitude of the quaternion.\n */\ngoog.vec.Quaternion.magnitude = goog.vec.Vec4.magnitude;\n\n\n/**\n * Normalizes the given quaternion storing the result into resultVec.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat0 The quaternion to\n * normalize.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result. May be quat0.\n */\ngoog.vec.Quaternion.normalize = goog.vec.Vec4.normalize;\n\n\n/**\n * Computes the dot (scalar) product of two quaternions.\n *\n * @param {!goog.vec.Quaternion.AnyType} q0 The first quaternion.\n * @param {!goog.vec.Quaternion.AnyType} q1 The second quaternion.\n * @return {number} The scalar product.\n */\ngoog.vec.Quaternion.dot = goog.vec.Vec4.dot;\n\n\n/**\n * Computes the inverse of the quaternion in quat, storing the result into\n * resultQuat.\n *\n * If the quaternion is already normalized, goog.vec.Quaternion.conjugate\n * is faster than this function and produces the same result.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat The quaternion to invert.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to receive\n * the result.\n * @return {!goog.vec.Quaternion.AnyType} Return resultQuat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.invert = function(quat, resultQuat) {\n 'use strict';\n const a0 = quat[0];\n const a1 = quat[1];\n const a2 = quat[2];\n const a3 = quat[3];\n\n const dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;\n const invDot = dot ? 1.0 / dot : 0;\n\n resultQuat[0] = -a0 * invDot;\n resultQuat[1] = -a1 * invDot;\n resultQuat[2] = -a2 * invDot;\n resultQuat[3] = a3 * invDot;\n return resultQuat;\n};\n\n\n/**\n * Computes the conjugate of the quaternion in quat, storing the result into\n * resultQuat.\n *\n * If the quaternion is normalized already, this function is faster than\n * goog.Quaternion.inverse and produces the same result.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat The source quaternion.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result.\n * @return {!goog.vec.Quaternion.AnyType} Return resultQuat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.conjugate = function(quat, resultQuat) {\n 'use strict';\n resultQuat[0] = -quat[0];\n resultQuat[1] = -quat[1];\n resultQuat[2] = -quat[2];\n resultQuat[3] = quat[3];\n return resultQuat;\n};\n\n\n/**\n * Concatenates the two quaternions storing the result into resultQuat.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat0 The first quaternion.\n * @param {!goog.vec.Quaternion.AnyType} quat1 The second quaternion.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result.\n * @return {!goog.vec.Quaternion.AnyType} Return resultQuat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.concat = function(quat0, quat1, resultQuat) {\n 'use strict';\n const w0 = quat0[3];\n const x0 = quat0[0];\n const y0 = quat0[1];\n const z0 = quat0[2];\n\n const w1 = quat1[3];\n const x1 = quat1[0];\n const y1 = quat1[1];\n const z1 = quat1[2];\n\n resultQuat[0] = w0 * x1 + x0 * w1 + y0 * z1 - z0 * y1;\n resultQuat[1] = w0 * y1 - x0 * z1 + y0 * w1 + z0 * x1;\n resultQuat[2] = w0 * z1 + x0 * y1 - y0 * x1 + z0 * w1;\n resultQuat[3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;\n return resultQuat;\n};\n\n\n/**\n * Makes the given quaternion the identity quaternion (0, 0, 0, 1).\n *\n * @param {!goog.vec.Quaternion.AnyType} quat The quaternion.\n * @return {!goog.vec.Quaternion.AnyType} Return quat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.makeIdentity = function(quat) {\n 'use strict';\n quat[0] = 0;\n quat[1] = 0;\n quat[2] = 0;\n quat[3] = 1;\n return quat;\n};\n\n\n/**\n * Generates a unit quaternion from the given angle-axis rotation pair.\n * The rotation axis is not required to be a unit vector, but should\n * have non-zero length. The angle should be specified in radians.\n *\n * @param {number} angle The angle (in radians) to rotate about the axis.\n * @param {!goog.vec.Quaternion.AnyType} axis Unit vector specifying the\n * axis of rotation.\n * @param {!goog.vec.Quaternion.AnyType} quat Unit quaternion to store the\n * result.\n * @return {!goog.vec.Quaternion.AnyType} Return quat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.fromAngleAxis = function(angle, axis, quat) {\n 'use strict';\n // Normalize the axis of rotation.\n goog.vec.Vec3.normalize(axis, axis);\n\n const halfAngle = 0.5 * angle;\n const sin = Math.sin(halfAngle);\n goog.vec.Quaternion.setFromValues(\n quat, sin * axis[0], sin * axis[1], sin * axis[2], Math.cos(halfAngle));\n\n // Normalize the resulting quaternion.\n goog.vec.Quaternion.normalize(quat, quat);\n return quat;\n};\n\n\n/**\n * Generates an angle-axis rotation pair from a unit quaternion.\n * The quaternion is assumed to be of unit length. The calculated\n * values are returned via the passed 'axis' object and the 'angle'\n * number returned by the function itself. The returned rotation axis\n * is a non-zero length unit vector, and the returned angle is in\n * radians in the range of [-PI, +PI].\n *\n * @param {!goog.vec.Quaternion.AnyType} quat Unit quaternion to convert.\n * @param {!goog.vec.Quaternion.AnyType} axis Vector to store the returned\n * rotation axis.\n * @return {number} angle Angle (in radians) to rotate about 'axis'.\n * The range of the returned angle is [-PI, +PI].\n */\ngoog.vec.Quaternion.toAngleAxis = function(quat, axis) {\n 'use strict';\n let angle = 2 * Math.acos(quat[3]);\n const magnitude = Math.min(Math.max(1 - quat[3] * quat[3], 0), 1);\n if (magnitude < goog.vec.EPSILON) {\n // This is nearly an identity rotation, so just use a fixed +X axis.\n goog.vec.Vec3.setFromValues(axis, 1, 0, 0);\n } else {\n // Compute the proper rotation axis.\n goog.vec.Vec3.setFromValues(axis, quat[0], quat[1], quat[2]);\n // Make sure the rotation axis is of unit length.\n goog.vec.Vec3.normalize(axis, axis);\n }\n // Adjust the range of the returned angle to [-PI, +PI].\n if (angle > Math.PI) {\n angle -= 2 * Math.PI;\n }\n return angle;\n};\n\n\n/**\n * Generates the quaternion from the given 3x3 rotation matrix.\n *\n * Perf: http://jsperf.com/conversion-of-3x3-matrix-to-quaternion\n * http://jsperf.com/goog-vec-fromrotationmatrix3-a\n *\n * @param {!goog.vec.AnyType} matrix The source matrix.\n * @param {!goog.vec.Quaternion.AnyType} quat The resulting quaternion.\n * @return {!goog.vec.Quaternion.AnyType} Return quat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.fromRotationMatrix3 = function(matrix, quat) {\n 'use strict';\n // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes\n // article \"Quaternion Calculus and Fast Animation\".\n const fTrace = matrix[0] + matrix[4] + matrix[8];\n let fRoot;\n\n if (fTrace > 0.0) {\n // |w| > 1/2, may as well choose w > 1/2\n fRoot = Math.sqrt(fTrace + 1.0); // 2w\n quat[3] = 0.5 * fRoot;\n fRoot = 0.5 / fRoot; // 1 / (4w)\n quat[0] = (matrix[5] - matrix[7]) * fRoot;\n quat[1] = (matrix[6] - matrix[2]) * fRoot;\n quat[2] = (matrix[1] - matrix[3]) * fRoot;\n } else {\n // |w| <= 1/2\n let i = 0;\n if (matrix[4] > matrix[0]) i = 1;\n if (matrix[8] > matrix[i * 3 + i]) i = 2;\n const j = (i + 1) % 3;\n const k = (i + 2) % 3;\n\n fRoot = Math.sqrt(\n matrix[i * 3 + i] - matrix[j * 3 + j] - matrix[k * 3 + k] + 1.0);\n quat[i] = 0.5 * fRoot;\n fRoot = 0.5 / fRoot;\n quat[3] = (matrix[j * 3 + k] - matrix[k * 3 + j]) * fRoot;\n quat[j] = (matrix[j * 3 + i] + matrix[i * 3 + j]) * fRoot;\n quat[k] = (matrix[k * 3 + i] + matrix[i * 3 + k]) * fRoot;\n\n // Flip all signs if w is negative.\n if (quat[3] < 0) {\n quat[0] = -quat[0];\n quat[1] = -quat[1];\n quat[2] = -quat[2];\n quat[3] = -quat[3];\n }\n }\n return quat;\n};\n\n\n/**\n * Generates the quaternion from the given 4x4 rotation matrix.\n *\n * Perf: http://jsperf.com/goog-vec-fromrotationmatrix4\n *\n * Implementation is the same as fromRotationMatrix3 but using indices from\n * the top left 3x3 in a 4x4 matrix.\n *\n * @param {!goog.vec.AnyType} matrix The source matrix.\n * @param {!goog.vec.Quaternion.AnyType} quat The resulting quaternion.\n * @return {!goog.vec.Quaternion.AnyType} Return quat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.fromRotationMatrix4 = function(matrix, quat) {\n 'use strict';\n const fTrace = matrix[0] + matrix[5] + matrix[10];\n let fRoot;\n\n if (fTrace > 0.0) {\n // |w| > 1/2, may as well choose w > 1/2\n fRoot = Math.sqrt(fTrace + 1.0); // 2w\n quat[3] = 0.5 * fRoot;\n fRoot = 0.5 / fRoot; // 1 / (4w)\n quat[0] = (matrix[6] - matrix[9]) * fRoot;\n quat[1] = (matrix[8] - matrix[2]) * fRoot;\n quat[2] = (matrix[1] - matrix[4]) * fRoot;\n } else {\n // |w| <= 1/2\n let i = 0;\n if (matrix[5] > matrix[0]) i = 1;\n if (matrix[10] > matrix[i * 4 + i]) i = 2;\n const j = (i + 1) % 3;\n const k = (i + 2) % 3;\n\n fRoot = Math.sqrt(\n matrix[i * 4 + i] - matrix[j * 4 + j] - matrix[k * 4 + k] + 1.0);\n quat[i] = 0.5 * fRoot;\n fRoot = 0.5 / fRoot;\n quat[3] = (matrix[j * 4 + k] - matrix[k * 4 + j]) * fRoot;\n quat[j] = (matrix[j * 4 + i] + matrix[i * 4 + j]) * fRoot;\n quat[k] = (matrix[k * 4 + i] + matrix[i * 4 + k]) * fRoot;\n\n // Flip all signs if w is negative.\n if (quat[3] < 0) {\n quat[0] = -quat[0];\n quat[1] = -quat[1];\n quat[2] = -quat[2];\n quat[3] = -quat[3];\n }\n }\n return quat;\n};\n\n\n/**\n * Generates the 3x3 rotation matrix from the given quaternion.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat The source quaternion.\n * @param {!goog.vec.AnyType} matrix The resulting matrix.\n * @return {!goog.vec.AnyType} Return resulting matrix so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.toRotationMatrix3 = function(quat, matrix) {\n 'use strict';\n const w = quat[3];\n const x = quat[0];\n const y = quat[1];\n const z = quat[2];\n\n const x2 = 2 * x;\n const y2 = 2 * y;\n const z2 = 2 * z;\n\n const wx = x2 * w;\n const wy = y2 * w;\n const wz = z2 * w;\n const xx = x2 * x;\n const xy = y2 * x;\n const xz = z2 * x;\n const yy = y2 * y;\n const yz = z2 * y;\n const zz = z2 * z;\n\n matrix[0] = 1 - (yy + zz);\n matrix[1] = xy + wz;\n matrix[2] = xz - wy;\n matrix[3] = xy - wz;\n matrix[4] = 1 - (xx + zz);\n matrix[5] = yz + wx;\n matrix[6] = xz + wy;\n matrix[7] = yz - wx;\n matrix[8] = 1 - (xx + yy);\n return matrix;\n};\n\n\n/**\n * Generates the 4x4 rotation matrix from the given quaternion.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat The source quaternion.\n * @param {!goog.vec.AnyType} matrix The resulting matrix.\n * @return {!goog.vec.AnyType} Return resulting matrix so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.toRotationMatrix4 = function(quat, matrix) {\n 'use strict';\n const w = quat[3];\n const x = quat[0];\n const y = quat[1];\n const z = quat[2];\n\n const x2 = 2 * x;\n const y2 = 2 * y;\n const z2 = 2 * z;\n\n const wx = x2 * w;\n const wy = y2 * w;\n const wz = z2 * w;\n const xx = x2 * x;\n const xy = y2 * x;\n const xz = z2 * x;\n const yy = y2 * y;\n const yz = z2 * y;\n const zz = z2 * z;\n\n matrix[0] = 1 - (yy + zz);\n matrix[1] = xy + wz;\n matrix[2] = xz - wy;\n matrix[3] = 0;\n matrix[4] = xy - wz;\n matrix[5] = 1 - (xx + zz);\n matrix[6] = yz + wx;\n matrix[7] = 0;\n matrix[8] = xz + wy;\n matrix[9] = yz - wx;\n matrix[10] = 1 - (xx + yy);\n matrix[11] = 0;\n matrix[12] = 0;\n matrix[13] = 0;\n matrix[14] = 0;\n matrix[15] = 1;\n return matrix;\n};\n\n\n/**\n * Rotates a quaternion by the given angle about the X axis.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat The quaternion.\n * @param {number} angle The angle in radians.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result.\n * @return {!goog.vec.Quaternion.AnyType} Return resultQuat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.rotateX = function(quat, angle, resultQuat) {\n 'use strict';\n angle *= 0.5;\n const aw = quat[3];\n const ax = quat[0];\n const ay = quat[1];\n const az = quat[2];\n\n const bw = Math.cos(angle);\n const bx = Math.sin(angle);\n\n\n resultQuat[0] = ax * bw + aw * bx;\n resultQuat[1] = ay * bw + az * bx;\n resultQuat[2] = az * bw - ay * bx;\n resultQuat[3] = aw * bw - ax * bx;\n return resultQuat;\n};\n\n\n/**\n * Rotates a quaternion by the given angle about the Y axis.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat The quaternion.\n * @param {number} angle The angle in radians.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result.\n * @return {!goog.vec.Quaternion.AnyType} Return resultQuat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.rotateY = function(quat, angle, resultQuat) {\n 'use strict';\n angle *= 0.5;\n const aw = quat[3];\n const ax = quat[0];\n const ay = quat[1];\n const az = quat[2];\n\n const bw = Math.cos(angle);\n const by = Math.sin(angle);\n\n\n resultQuat[0] = ax * bw - az * by;\n resultQuat[1] = ay * bw + aw * by;\n resultQuat[2] = az * bw + ax * by;\n resultQuat[3] = aw * bw - ay * by;\n return resultQuat;\n};\n\n\n/**\n * Rotates a quaternion by the given angle about the Z axis.\n *\n * @param {!goog.vec.Quaternion.AnyType} quat The quaternion.\n * @param {number} angle The angle in radians.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result.\n * @return {!goog.vec.Quaternion.AnyType} Return resultQuat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.rotateZ = function(quat, angle, resultQuat) {\n 'use strict';\n angle *= 0.5;\n const aw = quat[3];\n const ax = quat[0];\n const ay = quat[1];\n const az = quat[2];\n\n const bw = Math.cos(angle);\n const bz = Math.sin(angle);\n\n\n resultQuat[0] = ax * bw + ay * bz;\n resultQuat[1] = ay * bw - ax * bz;\n resultQuat[2] = az * bw + aw * bz;\n resultQuat[3] = aw * bw - az * bz;\n return resultQuat;\n};\n\n\n/**\n * Transforms a vec with a quaternion. Works on both vec3s and vec4s.\n *\n * @param {!goog.vec.AnyType} vec The vec to transform.\n * @param {!goog.vec.Quaternion.AnyType} quat The quaternion.\n * @param {!goog.vec.AnyType} resultVec The vec to receive the result.\n * @return {!goog.vec.AnyType} Return resultVec so that operations can be\n * chained together. Note that the caller is responsible for type-casting.\n */\ngoog.vec.Quaternion.transformVec = function(vec, quat, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n const qw = quat[3];\n const qx = quat[0];\n const qy = quat[1];\n const qz = quat[2];\n\n // Calculate quat * vec.\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = -qx * x - qy * y - qz * z;\n // Calculate result * inverse quat.\n resultVec[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;\n resultVec[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;\n resultVec[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;\n return resultVec;\n};\n\n\n/**\n * Computes the spherical linear interpolated value from the given quaternions\n * q0 and q1 according to the coefficient t. The resulting quaternion is stored\n * in resultQuat.\n *\n * @param {!goog.vec.Quaternion.AnyType} q0 The first quaternion.\n * @param {!goog.vec.Quaternion.AnyType} q1 The second quaternion.\n * @param {number} t The interpolating coefficient.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the result.\n * @return {!goog.vec.Quaternion.AnyType} Return resultQuat so that\n * operations can be chained together.\n */\ngoog.vec.Quaternion.slerp = function(q0, q1, t, resultQuat) {\n 'use strict';\n // Compute the dot product between q0 and q1 (cos of the angle between q0 and\n // q1). If it's outside the interval [-1,1], then the arccos is not defined.\n // The usual reason for this is that q0 and q1 are colinear. In this case\n // the angle between the two is zero, so just return q1.\n let cosVal = goog.vec.Quaternion.dot(q0, q1);\n if (cosVal > 1 || cosVal < -1) {\n goog.vec.Vec4.setFromArray(resultQuat, q1);\n return resultQuat;\n }\n\n // Quaternions are a double cover on the space of rotations. That is, q and -q\n // represent the same rotation. Thus we have two possibilities when\n // interpolating between q0 and q1: going the short way or the long way. We\n // prefer the short way since that is the likely expectation from users.\n let factor = 1;\n if (cosVal < 0) {\n factor = -1;\n cosVal = -cosVal;\n }\n\n // Compute the angle between q0 and q1. If it's very small, then just return\n // q1 to avoid a very large denominator below.\n const angle = Math.acos(cosVal);\n if (angle <= goog.vec.EPSILON) {\n goog.vec.Vec4.setFromArray(resultQuat, q1);\n return resultQuat;\n }\n\n // Compute the coefficients and interpolate.\n const invSinVal = 1 / Math.sin(angle);\n const c0 = Math.sin((1 - t) * angle) * invSinVal;\n const c1 = factor * Math.sin(t * angle) * invSinVal;\n\n resultQuat[0] = q0[0] * c0 + q1[0] * c1;\n resultQuat[1] = q0[1] * c0 + q1[1] * c1;\n resultQuat[2] = q0[2] * c0 + q1[2] * c1;\n resultQuat[3] = q0[3] * c0 + q1[3] * c1;\n return resultQuat;\n};\n\n\n/**\n * Compute the simple linear interpolation of the two quaternions q0 and q1\n * according to the coefficient t. The resulting quaternion is stored in\n * resultVec.\n *\n * @param {!goog.vec.Quaternion.AnyType} q0 The first quaternion.\n * @param {!goog.vec.Quaternion.AnyType} q1 The second quaternion.\n * @param {number} t The interpolation factor.\n * @param {!goog.vec.Quaternion.AnyType} resultQuat The quaternion to\n * receive the results (may be q0 or q1).\n */\ngoog.vec.Quaternion.nlerp = goog.vec.Vec4.lerp;\n","^<",1684857788697,"^=",["^3",["^16","^14","^15","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^16","^14","^15"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.Quaternion","goog.vec.Quaternion.AnyType"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec","goog.vec.Vec3","goog.vec.Vec4"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/quaternion.js"],"^[",["^3",["^1@","^1A"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14","^15","^16"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.vec3f.Type","~$goog.vec.vec3f"]],"^5","goog.vec.vec3f.js","^6",["^7","goog/vec/vec3f.js"],"^8","goog/vec/vec3f.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to vec3d.js by running: //\n// swap_type.sh vec3f.js > vec3d.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 3 element float (32bit)\n * vectors.\n *\n * The last parameter will typically be the output object and an object\n * can be both an input and output parameter to all methods except where\n * noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\ngoog.provide('goog.vec.vec3f');\ngoog.provide('goog.vec.vec3f.Type');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.vec3f.Type;\n\n\n/**\n * Creates a vec3f with all elements initialized to zero.\n *\n * @return {!goog.vec.vec3f.Type} The new vec3f.\n */\ngoog.vec.vec3f.create = function() {\n 'use strict';\n return new Float32Array(3);\n};\n\n\n/**\n * Creates a new vec3f initialized with the value from the given array.\n *\n * @param {!Array} vec The source 3 element array.\n * @return {!goog.vec.vec3f.Type} The new vec3f.\n */\ngoog.vec.vec3f.createFromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec3f.create();\n goog.vec.vec3f.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new vec3f initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @return {!goog.vec.vec3f.Type} The new vector.\n */\ngoog.vec.vec3f.createFromValues = function(v0, v1, v2) {\n 'use strict';\n const vec = goog.vec.vec3f.create();\n goog.vec.vec3f.setFromValues(vec, v0, v1, v2);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given vec3f.\n *\n * @param {!goog.vec.vec3f.Type} vec The source vec3f.\n * @return {!goog.vec.vec3f.Type} The new cloned vec3f.\n */\ngoog.vec.vec3f.clone = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec3f.create();\n goog.vec.vec3f.setFromVec3f(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {!goog.vec.vec3f.Type} vec The vector to receive the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @return {!goog.vec.vec3f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.setFromValues = function(vec, v0, v1, v2) {\n 'use strict';\n vec[0] = v0;\n vec[1] = v1;\n vec[2] = v2;\n return vec;\n};\n\n\n/**\n * Initializes vec3f vec from vec3f src.\n *\n * @param {!goog.vec.vec3f.Type} vec The destination vector.\n * @param {!goog.vec.vec3f.Type} src The source vector.\n * @return {!goog.vec.vec3f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.setFromVec3f = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n return vec;\n};\n\n\n/**\n * Initializes vec3f vec from vec3d src (typed as a Float64Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.vec3f.Type} vec The destination vector.\n * @param {Float64Array} src The source vector.\n * @return {!goog.vec.vec3f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.setFromVec3d = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n return vec;\n};\n\n\n/**\n * Initializes vec3f vec from Array src.\n *\n * @param {!goog.vec.vec3f.Type} vec The destination vector.\n * @param {Array} src The source vector.\n * @return {!goog.vec.vec3f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.setFromArray = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The first addend.\n * @param {!goog.vec.vec3f.Type} vec1 The second addend.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n resultVec[2] = vec0[2] + vec1[2];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The minuend.\n * @param {!goog.vec.vec3f.Type} vec1 The subtrahend.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n resultVec[2] = vec0[2] - vec1[2];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The vector to negate.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n resultVec[2] = -vec0[2];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The source vector.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n resultVec[2] = Math.abs(vec0[2]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n resultVec[2] = vec0[2] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec3f.magnitudeSquared = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return x * x + y * y + z * z;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec3f.magnitude = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return Math.sqrt(x * x + y * y + z * z);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The vector to normalize.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.normalize = function(vec0, resultVec) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n const ilen = 1 / Math.sqrt(x * x + y * y + z * z);\n resultVec[0] = x * ilen;\n resultVec[1] = y * ilen;\n resultVec[2] = z * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors v0 and v1.\n *\n * @param {!goog.vec.vec3f.Type} v0 The first vector.\n * @param {!goog.vec.vec3f.Type} v1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.vec3f.dot = function(v0, v1) {\n 'use strict';\n return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];\n};\n\n\n/**\n * Computes the vector (cross) product of v0 and v1 storing the result into\n * resultVec.\n *\n * @param {!goog.vec.vec3f.Type} v0 The first vector.\n * @param {!goog.vec.vec3f.Type} v1 The second vector.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to receive the\n * results. May be either v0 or v1.\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.cross = function(v0, v1, resultVec) {\n 'use strict';\n const x0 = v0[0];\n const y0 = v0[1];\n const z0 = v0[2];\n\n const x1 = v1[0];\n const y1 = v1[1];\n const z1 = v1[2];\n\n resultVec[0] = y0 * z1 - z0 * y1;\n resultVec[1] = z0 * x1 - x0 * z1;\n resultVec[2] = x0 * y1 - y0 * x1;\n return resultVec;\n};\n\n\n/**\n * Returns the squared distance between two points.\n *\n * @param {!goog.vec.vec3f.Type} vec0 First point.\n * @param {!goog.vec.vec3f.Type} vec1 Second point.\n * @return {number} The squared distance between the points.\n */\ngoog.vec.vec3f.distanceSquared = function(vec0, vec1) {\n 'use strict';\n const x = vec0[0] - vec1[0];\n const y = vec0[1] - vec1[1];\n const z = vec0[2] - vec1[2];\n return x * x + y * y + z * z;\n};\n\n\n/**\n * Returns the distance between two points.\n *\n * @param {!goog.vec.vec3f.Type} vec0 First point.\n * @param {!goog.vec.vec3f.Type} vec1 Second point.\n * @return {number} The distance between the points.\n */\ngoog.vec.vec3f.distance = function(vec0, vec1) {\n 'use strict';\n return Math.sqrt(goog.vec.vec3f.distanceSquared(vec0, vec1));\n};\n\n\n/**\n * Returns a unit vector pointing from one point to another.\n * If the input points are equal then the result will be all zeros.\n *\n * @param {!goog.vec.vec3f.Type} vec0 Origin point.\n * @param {!goog.vec.vec3f.Type} vec1 Target point.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.direction = function(vec0, vec1, resultVec) {\n 'use strict';\n const x = vec1[0] - vec0[0];\n const y = vec1[1] - vec0[1];\n const z = vec1[2] - vec0[2];\n let d = Math.sqrt(x * x + y * y + z * z);\n if (d) {\n d = 1 / d;\n resultVec[0] = x * d;\n resultVec[1] = y * d;\n resultVec[2] = z * d;\n } else {\n resultVec[0] = resultVec[1] = resultVec[2] = 0;\n }\n return resultVec;\n};\n\n\n/**\n * Linearly interpolate from vec0 to v1 according to f. The value of f should be\n * in the range [0..1] otherwise the results are undefined.\n *\n * @param {!goog.vec.vec3f.Type} v0 The first vector.\n * @param {!goog.vec.vec3f.Type} v1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to receive the\n * results (may be v0 or v1).\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.lerp = function(v0, v1, f, resultVec) {\n 'use strict';\n const x = v0[0];\n const y = v0[1];\n const z = v0[2];\n\n resultVec[0] = (v1[0] - x) * f + x;\n resultVec[1] = (v1[1] - y) * f + y;\n resultVec[2] = (v1[2] - z) * f + z;\n return resultVec;\n};\n\n\n/**\n * Perform a spherical linear interpolation from v0 to v1 according to f. The\n * value of f should be in the range [0..1] otherwise the results are undefined.\n *\n * Slerp is normally used to interpolate quaternions, but there is a geometric\n * formula for interpolating vectors directly, see \"Geometric Slerp\" in:\n * https://en.wikipedia.org/wiki/Slerp.\n *\n * This interpolates the vectors' directions via slerp, but linearly\n * interpolates the vectors' magnitudes.\n *\n * Results are undefined if v0 or v1 are of zero magnitude.\n *\n * @param {!goog.vec.vec3f.Type} v0 The first vector.\n * @param {!goog.vec.vec3f.Type} v1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to receive the\n * results (may be v0 or v1).\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.slerp = function(v0, v1, f, resultVec) {\n 'use strict';\n const v0Magnitude = goog.vec.vec3f.magnitude(v0);\n let v1Magnitude = goog.vec.vec3f.magnitude(v1);\n\n let cosAngle = goog.vec.vec3f.dot(v0, v1) / (v0Magnitude * v1Magnitude);\n\n // If v0 and v1 are almost the same direction, fall back on a straight lerp.\n if (cosAngle > 1 - goog.vec.EPSILON) {\n return goog.vec.vec3f.lerp(v0, v1, f, resultVec);\n }\n\n let angle = 0;\n let sinAngle = 0;\n\n // If v0 and v1 are opposite directions, pick an arbitrary 'mid' vector that\n // is perpendicular to both, and slerp from v0 -> mid -> v1.\n if (cosAngle < -1 + goog.vec.EPSILON) {\n const mid = goog.vec.vec3f.create();\n let magnitudeFactor = (v0Magnitude + v1Magnitude) / 2;\n if (v0[0]) { // v0 not parallel to [0,0,1].\n magnitudeFactor /= Math.sqrt(v0[0] * v0[0] + v0[1] + v0[1]);\n mid[0] = -v0[1] * magnitudeFactor;\n mid[1] = v0[0] * magnitudeFactor;\n mid[2] = 0;\n } else { // v0 not parallel to [1,0,0].\n magnitudeFactor /= Math.sqrt(v0[2] * v0[2] + v0[1] + v0[1]);\n mid[0] = 0;\n mid[1] = -v0[2] * magnitudeFactor;\n mid[2] = v0[1] * magnitudeFactor;\n }\n\n // Depending on f, slerp between either v0 and mid, or mid and v1.\n if (f <= 0.5) {\n v1Magnitude = v0Magnitude;\n v1 = mid;\n f *= 2;\n } else {\n v0 = mid;\n f = 2 * f - 1;\n }\n\n angle = Math.PI / 2;\n cosAngle = 0;\n sinAngle = 1;\n } else {\n angle = Math.acos(cosAngle);\n sinAngle = Math.sqrt(1 - cosAngle * cosAngle);\n }\n\n const coeff0 = (Math.sin((1 - f) * angle) / sinAngle) / v0Magnitude;\n const coeff1 = (Math.sin(f * angle) / sinAngle) / v1Magnitude;\n const magnitude = (1 - f) * v0Magnitude + f * v1Magnitude;\n\n resultVec[0] = (v0[0] * coeff0 + v1[0] * coeff1) * magnitude;\n resultVec[1] = (v0[1] * coeff0 + v1[1] * coeff1) * magnitude;\n resultVec[2] = (v0[2] * coeff0 + v1[2] * coeff1) * magnitude;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The source vector.\n * @param {!goog.vec.vec3f.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n resultVec[2] = Math.max(vec0[2], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n resultVec[2] = Math.max(vec0[2], limit[2]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {!goog.vec.vec3f.Type} vec0 The source vector.\n * @param {!goog.vec.vec3f.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3f.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n resultVec[2] = Math.min(vec0[2], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n resultVec[2] = Math.min(vec0[2], limit[2]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of v0 are equal to the components of v1.\n *\n * @param {!goog.vec.vec3f.Type} v0 The first vector.\n * @param {!goog.vec.vec3f.Type} v1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.vec3f.equals = function(v0, v1) {\n 'use strict';\n return v0.length == v1.length && v0[0] == v1[0] && v0[1] == v1[1] &&\n v0[2] == v1[2];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.vec3f","goog.vec.vec3f.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec3f.js"],"^[",["^3",["^1B","^1C"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.Mat4"]],"^5","goog.vec.mat4.js","^6",["^7","goog/vec/mat4.js"],"^8","goog/vec/mat4.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implements 4x4 matrices and their related functions which are\n * compatible with WebGL. The API is structured to avoid unnecessary memory\n * allocations. The last parameter will typically be the output vector and\n * an object can be both an input and output parameter to all methods except\n * where noted. Matrix operations follow the mathematical form when multiplying\n * vectors as follows: resultVec = matrix * vec.\n *\n * The matrices are stored in column-major order.\n */\ngoog.provide('goog.vec.Mat4');\n\ngoog.require('goog.vec');\ngoog.require('goog.vec.Vec3');\ngoog.require('goog.vec.Vec4');\n\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.Mat4.Float32;\n/** @typedef {!goog.vec.Float64} */ goog.vec.Mat4.Float64;\n/** @typedef {!goog.vec.Number} */ goog.vec.Mat4.Number;\n/** @typedef {!goog.vec.AnyType} */ goog.vec.Mat4.AnyType;\n\n// The following two types are deprecated - use the above types instead.\n/** @typedef {!Float32Array} */ goog.vec.Mat4.Type;\n/** @typedef {!goog.vec.ArrayType} */ goog.vec.Mat4.Mat4Like;\n\n\n/**\n * Creates the array representation of a 4x4 matrix of Float32.\n * The use of the array directly instead of a class reduces overhead.\n * The returned matrix is cleared to all zeros.\n *\n * @return {!goog.vec.Mat4.Float32} The new matrix.\n */\ngoog.vec.Mat4.createFloat32 = function() {\n 'use strict';\n return new Float32Array(16);\n};\n\n\n/**\n * Creates the array representation of a 4x4 matrix of Float64.\n * The returned matrix is cleared to all zeros.\n *\n * @return {!goog.vec.Mat4.Float64} The new matrix.\n */\ngoog.vec.Mat4.createFloat64 = function() {\n 'use strict';\n return new Float64Array(16);\n};\n\n\n/**\n * Creates the array representation of a 4x4 matrix of Number.\n * The returned matrix is cleared to all zeros.\n *\n * @return {!goog.vec.Mat4.Number} The new matrix.\n */\ngoog.vec.Mat4.createNumber = function() {\n 'use strict';\n const a = new Array(16);\n goog.vec.Mat4.setFromValues(\n a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n return a;\n};\n\n\n/**\n * Creates the array representation of a 4x4 matrix of Float32.\n * The returned matrix is cleared to all zeros.\n *\n * @deprecated Use createFloat32.\n * @return {!goog.vec.Mat4.Type} The new matrix.\n */\ngoog.vec.Mat4.create = function() {\n 'use strict';\n return goog.vec.Mat4.createFloat32();\n};\n\n\n/**\n * Creates a 4x4 identity matrix of Float32.\n *\n * @return {!goog.vec.Mat4.Float32} The new 16 element array.\n */\ngoog.vec.Mat4.createFloat32Identity = function() {\n 'use strict';\n const mat = goog.vec.Mat4.createFloat32();\n mat[0] = mat[5] = mat[10] = mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Creates a 4x4 identity matrix of Float64.\n *\n * @return {!goog.vec.Mat4.Float64} The new 16 element array.\n */\ngoog.vec.Mat4.createFloat64Identity = function() {\n 'use strict';\n const mat = goog.vec.Mat4.createFloat64();\n mat[0] = mat[5] = mat[10] = mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Creates a 4x4 identity matrix of Number.\n * The returned matrix is cleared to all zeros.\n *\n * @return {!goog.vec.Mat4.Number} The new 16 element array.\n */\ngoog.vec.Mat4.createNumberIdentity = function() {\n 'use strict';\n const a = new Array(16);\n goog.vec.Mat4.setFromValues(\n a, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);\n return a;\n};\n\n\n/**\n * Creates the array representation of a 4x4 matrix of Float32.\n * The returned matrix is cleared to all zeros.\n *\n * @deprecated Use createFloat32Identity.\n * @return {!goog.vec.Mat4.Type} The new 16 element array.\n */\ngoog.vec.Mat4.createIdentity = function() {\n 'use strict';\n return goog.vec.Mat4.createFloat32Identity();\n};\n\n\n/**\n * Creates a 4x4 matrix of Float32 initialized from the given array.\n *\n * @param {goog.vec.Mat4.AnyType} matrix The array containing the\n * matrix values in column major order.\n * @return {!goog.vec.Mat4.Float32} The new, 16 element array.\n */\ngoog.vec.Mat4.createFloat32FromArray = function(matrix) {\n 'use strict';\n const newMatrix = goog.vec.Mat4.createFloat32();\n goog.vec.Mat4.setFromArray(newMatrix, matrix);\n return newMatrix;\n};\n\n\n/**\n * Creates a 4x4 matrix of Float32 initialized from the given values.\n *\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v30 The values at (3, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v31 The values at (3, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @param {number} v32 The values at (3, 2).\n * @param {number} v03 The values at (0, 3).\n * @param {number} v13 The values at (1, 3).\n * @param {number} v23 The values at (2, 3).\n * @param {number} v33 The values at (3, 3).\n * @return {!goog.vec.Mat4.Float32} The new, 16 element array.\n */\ngoog.vec.Mat4.createFloat32FromValues = function(\n v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23,\n v33) {\n 'use strict';\n const newMatrix = goog.vec.Mat4.createFloat32();\n goog.vec.Mat4.setFromValues(\n newMatrix, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32,\n v03, v13, v23, v33);\n return newMatrix;\n};\n\n\n/**\n * Creates a clone of a 4x4 matrix of Float32.\n *\n * @param {goog.vec.Mat4.Float32} matrix The source 4x4 matrix.\n * @return {!goog.vec.Mat4.Float32} The new 4x4 element matrix.\n */\ngoog.vec.Mat4.cloneFloat32 = goog.vec.Mat4.createFloat32FromArray;\n\n\n/**\n * Creates a 4x4 matrix of Float64 initialized from the given array.\n *\n * @param {goog.vec.Mat4.AnyType} matrix The array containing the\n * matrix values in column major order.\n * @return {!goog.vec.Mat4.Float64} The new, nine element array.\n */\ngoog.vec.Mat4.createFloat64FromArray = function(matrix) {\n 'use strict';\n const newMatrix = goog.vec.Mat4.createFloat64();\n goog.vec.Mat4.setFromArray(newMatrix, matrix);\n return newMatrix;\n};\n\n\n/**\n * Creates a 4x4 matrix of Float64 initialized from the given values.\n *\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v30 The values at (3, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v31 The values at (3, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @param {number} v32 The values at (3, 2).\n * @param {number} v03 The values at (0, 3).\n * @param {number} v13 The values at (1, 3).\n * @param {number} v23 The values at (2, 3).\n * @param {number} v33 The values at (3, 3).\n * @return {!goog.vec.Mat4.Float64} The new, 16 element array.\n */\ngoog.vec.Mat4.createFloat64FromValues = function(\n v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23,\n v33) {\n 'use strict';\n const newMatrix = goog.vec.Mat4.createFloat64();\n goog.vec.Mat4.setFromValues(\n newMatrix, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32,\n v03, v13, v23, v33);\n return newMatrix;\n};\n\n\n/**\n * Creates a clone of a 4x4 matrix of Float64.\n *\n * @param {goog.vec.Mat4.Float64} matrix The source 4x4 matrix.\n * @return {!goog.vec.Mat4.Float64} The new 4x4 element matrix.\n */\ngoog.vec.Mat4.cloneFloat64 = goog.vec.Mat4.createFloat64FromArray;\n\n\n/**\n * Creates a 4x4 matrix of Float32 initialized from the given array.\n *\n * @deprecated Use createFloat32FromArray.\n * @param {goog.vec.Mat4.Mat4Like} matrix The array containing the\n * matrix values in column major order.\n * @return {!goog.vec.Mat4.Type} The new, nine element array.\n */\ngoog.vec.Mat4.createFromArray = function(matrix) {\n 'use strict';\n const newMatrix = goog.vec.Mat4.createFloat32();\n goog.vec.Mat4.setFromArray(newMatrix, matrix);\n return newMatrix;\n};\n\n\n/**\n * Creates a 4x4 matrix of Float32 initialized from the given values.\n *\n * @deprecated Use createFloat32FromValues.\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v30 The values at (3, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v31 The values at (3, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @param {number} v32 The values at (3, 2).\n * @param {number} v03 The values at (0, 3).\n * @param {number} v13 The values at (1, 3).\n * @param {number} v23 The values at (2, 3).\n * @param {number} v33 The values at (3, 3).\n * @return {!goog.vec.Mat4.Type} The new, 16 element array.\n */\ngoog.vec.Mat4.createFromValues = function(\n v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23,\n v33) {\n 'use strict';\n return goog.vec.Mat4.createFloat32FromValues(\n v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23,\n v33);\n};\n\n\n/**\n * Creates a clone of a 4x4 matrix of Float32.\n *\n * @deprecated Use cloneFloat32.\n * @param {goog.vec.Mat4.Mat4Like} matrix The source 4x4 matrix.\n * @return {!goog.vec.Mat4.Type} The new 4x4 element matrix.\n */\ngoog.vec.Mat4.clone = goog.vec.Mat4.createFromArray;\n\n\n/**\n * Retrieves the element at the requested row and column.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix containing the\n * value to retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @return {number} The element value at the requested row, column indices.\n */\ngoog.vec.Mat4.getElement = function(mat, row, column) {\n 'use strict';\n return mat[row + column * 4];\n};\n\n\n/**\n * Sets the element at the requested row and column.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to set the value on.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @param {number} value The value to set at the requested row, column.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setElement = function(mat, row, column, value) {\n 'use strict';\n mat[row + column * 4] = value;\n return mat;\n};\n\n\n/**\n * Initializes the matrix from the set of values. Note the values supplied are\n * in column major order.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the\n * values.\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v30 The values at (3, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v31 The values at (3, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @param {number} v32 The values at (3, 2).\n * @param {number} v03 The values at (0, 3).\n * @param {number} v13 The values at (1, 3).\n * @param {number} v23 The values at (2, 3).\n * @param {number} v33 The values at (3, 3).\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setFromValues = function(\n mat, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13,\n v23, v33) {\n 'use strict';\n mat[0] = v00;\n mat[1] = v10;\n mat[2] = v20;\n mat[3] = v30;\n mat[4] = v01;\n mat[5] = v11;\n mat[6] = v21;\n mat[7] = v31;\n mat[8] = v02;\n mat[9] = v12;\n mat[10] = v22;\n mat[11] = v32;\n mat[12] = v03;\n mat[13] = v13;\n mat[14] = v23;\n mat[15] = v33;\n return mat;\n};\n\n\n/**\n * Sets the matrix from the array of values stored in column major order.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Mat4.AnyType} values The column major ordered\n * array of values to store in the matrix.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setFromArray = function(mat, values) {\n 'use strict';\n mat[0] = values[0];\n mat[1] = values[1];\n mat[2] = values[2];\n mat[3] = values[3];\n mat[4] = values[4];\n mat[5] = values[5];\n mat[6] = values[6];\n mat[7] = values[7];\n mat[8] = values[8];\n mat[9] = values[9];\n mat[10] = values[10];\n mat[11] = values[11];\n mat[12] = values[12];\n mat[13] = values[13];\n mat[14] = values[14];\n mat[15] = values[15];\n return mat;\n};\n\n\n/**\n * Sets the matrix from the array of values stored in row major order.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Mat4.AnyType} values The row major ordered array of\n * values to store in the matrix.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setFromRowMajorArray = function(mat, values) {\n 'use strict';\n mat[0] = values[0];\n mat[1] = values[4];\n mat[2] = values[8];\n mat[3] = values[12];\n\n mat[4] = values[1];\n mat[5] = values[5];\n mat[6] = values[9];\n mat[7] = values[13];\n\n mat[8] = values[2];\n mat[9] = values[6];\n mat[10] = values[10];\n mat[11] = values[14];\n\n mat[12] = values[3];\n mat[13] = values[7];\n mat[14] = values[11];\n mat[15] = values[15];\n\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given values.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {number} v00 The values for (0, 0).\n * @param {number} v11 The values for (1, 1).\n * @param {number} v22 The values for (2, 2).\n * @param {number} v33 The values for (3, 3).\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setDiagonalValues = function(mat, v00, v11, v22, v33) {\n 'use strict';\n mat[0] = v00;\n mat[5] = v11;\n mat[10] = v22;\n mat[15] = v33;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given vector.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Vec4.AnyType} vec The vector containing the values.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setDiagonal = function(mat, vec) {\n 'use strict';\n mat[0] = vec[0];\n mat[5] = vec[1];\n mat[10] = vec[2];\n mat[15] = vec[3];\n return mat;\n};\n\n\n/**\n * Gets the diagonal values of the matrix into the given vector.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix containing the values.\n * @param {goog.vec.Vec4.AnyType} vec The vector to receive the values.\n * @param {number=} opt_diagonal Which diagonal to get. A value of 0 selects the\n * main diagonal, a positive number selects a super diagonal and a negative\n * number selects a sub diagonal.\n * @return {goog.vec.Vec4.AnyType} return vec so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.getDiagonal = function(mat, vec, opt_diagonal) {\n 'use strict';\n if (!opt_diagonal) {\n // This is the most common case, so we avoid the for loop.\n vec[0] = mat[0];\n vec[1] = mat[5];\n vec[2] = mat[10];\n vec[3] = mat[15];\n } else {\n const offset = opt_diagonal > 0 ? 4 * opt_diagonal : -opt_diagonal;\n for (let i = 0; i < 4 - Math.abs(opt_diagonal); i++) {\n vec[i] = mat[offset + 5 * i];\n }\n }\n return vec;\n};\n\n\n/**\n * Sets the specified column with the supplied values.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {number} v0 The value for row 0.\n * @param {number} v1 The value for row 1.\n * @param {number} v2 The value for row 2.\n * @param {number} v3 The value for row 3.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setColumnValues = function(mat, column, v0, v1, v2, v3) {\n 'use strict';\n const i = column * 4;\n mat[i] = v0;\n mat[i + 1] = v1;\n mat[i + 2] = v2;\n mat[i + 3] = v3;\n return mat;\n};\n\n\n/**\n * Sets the specified column with the value from the supplied vector.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {goog.vec.Vec4.AnyType} vec The vector of elements for the column.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 4;\n mat[i] = vec[0];\n mat[i + 1] = vec[1];\n mat[i + 2] = vec[2];\n mat[i + 3] = vec[3];\n return mat;\n};\n\n\n/**\n * Retrieves the specified column from the matrix into the given vector.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix supplying the values.\n * @param {number} column The column to get the values from.\n * @param {goog.vec.Vec4.AnyType} vec The vector of elements to\n * receive the column.\n * @return {goog.vec.Vec4.AnyType} return vec so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.getColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 4;\n vec[0] = mat[i];\n vec[1] = mat[i + 1];\n vec[2] = mat[i + 2];\n vec[3] = mat[i + 3];\n return vec;\n};\n\n\n/**\n * Sets the columns of the matrix from the given vectors.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Vec4.AnyType} vec0 The values for column 0.\n * @param {goog.vec.Vec4.AnyType} vec1 The values for column 1.\n * @param {goog.vec.Vec4.AnyType} vec2 The values for column 2.\n * @param {goog.vec.Vec4.AnyType} vec3 The values for column 3.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setColumns = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n goog.vec.Mat4.setColumn(mat, 0, vec0);\n goog.vec.Mat4.setColumn(mat, 1, vec1);\n goog.vec.Mat4.setColumn(mat, 2, vec2);\n goog.vec.Mat4.setColumn(mat, 3, vec3);\n return mat;\n};\n\n\n/**\n * Retrieves the column values from the given matrix into the given vectors.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix supplying the columns.\n * @param {goog.vec.Vec4.AnyType} vec0 The vector to receive column 0.\n * @param {goog.vec.Vec4.AnyType} vec1 The vector to receive column 1.\n * @param {goog.vec.Vec4.AnyType} vec2 The vector to receive column 2.\n * @param {goog.vec.Vec4.AnyType} vec3 The vector to receive column 3.\n */\ngoog.vec.Mat4.getColumns = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n goog.vec.Mat4.getColumn(mat, 0, vec0);\n goog.vec.Mat4.getColumn(mat, 1, vec1);\n goog.vec.Mat4.getColumn(mat, 2, vec2);\n goog.vec.Mat4.getColumn(mat, 3, vec3);\n};\n\n\n/**\n * Sets the row values from the supplied values.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {number} row The index of the row to receive the values.\n * @param {number} v0 The value for column 0.\n * @param {number} v1 The value for column 1.\n * @param {number} v2 The value for column 2.\n * @param {number} v3 The value for column 3.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setRowValues = function(mat, row, v0, v1, v2, v3) {\n 'use strict';\n mat[row] = v0;\n mat[row + 4] = v1;\n mat[row + 8] = v2;\n mat[row + 12] = v3;\n return mat;\n};\n\n\n/**\n * Sets the row values from the supplied vector.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the row values.\n * @param {number} row The index of the row.\n * @param {goog.vec.Vec4.AnyType} vec The vector containing the values.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setRow = function(mat, row, vec) {\n 'use strict';\n mat[row] = vec[0];\n mat[row + 4] = vec[1];\n mat[row + 8] = vec[2];\n mat[row + 12] = vec[3];\n return mat;\n};\n\n\n/**\n * Retrieves the row values into the given vector.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix supplying the values.\n * @param {number} row The index of the row supplying the values.\n * @param {goog.vec.Vec4.AnyType} vec The vector to receive the row.\n * @return {goog.vec.Vec4.AnyType} return vec so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.getRow = function(mat, row, vec) {\n 'use strict';\n vec[0] = mat[row];\n vec[1] = mat[row + 4];\n vec[2] = mat[row + 8];\n vec[3] = mat[row + 12];\n return vec;\n};\n\n\n/**\n * Sets the rows of the matrix from the supplied vectors.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to receive the values.\n * @param {goog.vec.Vec4.AnyType} vec0 The values for row 0.\n * @param {goog.vec.Vec4.AnyType} vec1 The values for row 1.\n * @param {goog.vec.Vec4.AnyType} vec2 The values for row 2.\n * @param {goog.vec.Vec4.AnyType} vec3 The values for row 3.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.setRows = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n goog.vec.Mat4.setRow(mat, 0, vec0);\n goog.vec.Mat4.setRow(mat, 1, vec1);\n goog.vec.Mat4.setRow(mat, 2, vec2);\n goog.vec.Mat4.setRow(mat, 3, vec3);\n return mat;\n};\n\n\n/**\n * Retrieves the rows of the matrix into the supplied vectors.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to supply the values.\n * @param {goog.vec.Vec4.AnyType} vec0 The vector to receive row 0.\n * @param {goog.vec.Vec4.AnyType} vec1 The vector to receive row 1.\n * @param {goog.vec.Vec4.AnyType} vec2 The vector to receive row 2.\n * @param {goog.vec.Vec4.AnyType} vec3 The vector to receive row 3.\n */\ngoog.vec.Mat4.getRows = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n goog.vec.Mat4.getRow(mat, 0, vec0);\n goog.vec.Mat4.getRow(mat, 1, vec1);\n goog.vec.Mat4.getRow(mat, 2, vec2);\n goog.vec.Mat4.getRow(mat, 3, vec3);\n};\n\n\n/**\n * Makes the given 4x4 matrix the zero matrix.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @return {!goog.vec.Mat4.AnyType} return mat so operations can be chained.\n */\ngoog.vec.Mat4.makeZero = function(mat) {\n 'use strict';\n mat[0] = 0;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 0;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 0;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix the identity matrix.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @return {goog.vec.Mat4.AnyType} return mat so operations can be chained.\n */\ngoog.vec.Mat4.makeIdentity = function(mat) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 1;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 1;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Performs a per-component addition of the matrix mat0 and mat1, storing\n * the result into resultMat.\n *\n * @param {goog.vec.Mat4.AnyType} mat0 The first addend.\n * @param {goog.vec.Mat4.AnyType} mat1 The second addend.\n * @param {goog.vec.Mat4.AnyType} resultMat The matrix to\n * receive the results (may be either mat0 or mat1).\n * @return {goog.vec.Mat4.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.addMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] + mat1[0];\n resultMat[1] = mat0[1] + mat1[1];\n resultMat[2] = mat0[2] + mat1[2];\n resultMat[3] = mat0[3] + mat1[3];\n resultMat[4] = mat0[4] + mat1[4];\n resultMat[5] = mat0[5] + mat1[5];\n resultMat[6] = mat0[6] + mat1[6];\n resultMat[7] = mat0[7] + mat1[7];\n resultMat[8] = mat0[8] + mat1[8];\n resultMat[9] = mat0[9] + mat1[9];\n resultMat[10] = mat0[10] + mat1[10];\n resultMat[11] = mat0[11] + mat1[11];\n resultMat[12] = mat0[12] + mat1[12];\n resultMat[13] = mat0[13] + mat1[13];\n resultMat[14] = mat0[14] + mat1[14];\n resultMat[15] = mat0[15] + mat1[15];\n return resultMat;\n};\n\n\n/**\n * Performs a per-component subtraction of the matrix mat0 and mat1,\n * storing the result into resultMat.\n *\n * @param {goog.vec.Mat4.AnyType} mat0 The minuend.\n * @param {goog.vec.Mat4.AnyType} mat1 The subtrahend.\n * @param {goog.vec.Mat4.AnyType} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {goog.vec.Mat4.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.subMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] - mat1[0];\n resultMat[1] = mat0[1] - mat1[1];\n resultMat[2] = mat0[2] - mat1[2];\n resultMat[3] = mat0[3] - mat1[3];\n resultMat[4] = mat0[4] - mat1[4];\n resultMat[5] = mat0[5] - mat1[5];\n resultMat[6] = mat0[6] - mat1[6];\n resultMat[7] = mat0[7] - mat1[7];\n resultMat[8] = mat0[8] - mat1[8];\n resultMat[9] = mat0[9] - mat1[9];\n resultMat[10] = mat0[10] - mat1[10];\n resultMat[11] = mat0[11] - mat1[11];\n resultMat[12] = mat0[12] - mat1[12];\n resultMat[13] = mat0[13] - mat1[13];\n resultMat[14] = mat0[14] - mat1[14];\n resultMat[15] = mat0[15] - mat1[15];\n return resultMat;\n};\n\n\n/**\n * Multiplies matrix mat with the given scalar, storing the result\n * into resultMat.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} scalar The scalar value to multiply to each element of mat.\n * @param {goog.vec.Mat4.AnyType} resultMat The matrix to receive\n * the results (may be mat).\n * @return {goog.vec.Mat4.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.multScalar = function(mat, scalar, resultMat) {\n 'use strict';\n resultMat[0] = mat[0] * scalar;\n resultMat[1] = mat[1] * scalar;\n resultMat[2] = mat[2] * scalar;\n resultMat[3] = mat[3] * scalar;\n resultMat[4] = mat[4] * scalar;\n resultMat[5] = mat[5] * scalar;\n resultMat[6] = mat[6] * scalar;\n resultMat[7] = mat[7] * scalar;\n resultMat[8] = mat[8] * scalar;\n resultMat[9] = mat[9] * scalar;\n resultMat[10] = mat[10] * scalar;\n resultMat[11] = mat[11] * scalar;\n resultMat[12] = mat[12] * scalar;\n resultMat[13] = mat[13] * scalar;\n resultMat[14] = mat[14] * scalar;\n resultMat[15] = mat[15] * scalar;\n return resultMat;\n};\n\n\n/**\n * Multiplies the two matrices mat0 and mat1 using matrix multiplication,\n * storing the result into resultMat.\n *\n * @param {goog.vec.Mat4.AnyType} mat0 The first (left hand) matrix.\n * @param {goog.vec.Mat4.AnyType} mat1 The second (right hand) matrix.\n * @param {goog.vec.Mat4.AnyType} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {goog.vec.Mat4.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.multMat = function(mat0, mat1, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n const a30 = mat0[3];\n\n const a01 = mat0[4];\n const a11 = mat0[5];\n const a21 = mat0[6];\n const a31 = mat0[7];\n\n const a02 = mat0[8];\n const a12 = mat0[9];\n const a22 = mat0[10];\n const a32 = mat0[11];\n\n const a03 = mat0[12];\n const a13 = mat0[13];\n const a23 = mat0[14];\n const a33 = mat0[15];\n\n\n const b00 = mat1[0];\n const b10 = mat1[1];\n const b20 = mat1[2];\n const b30 = mat1[3];\n\n const b01 = mat1[4];\n const b11 = mat1[5];\n const b21 = mat1[6];\n const b31 = mat1[7];\n\n const b02 = mat1[8];\n const b12 = mat1[9];\n const b22 = mat1[10];\n const b32 = mat1[11];\n\n const b03 = mat1[12];\n const b13 = mat1[13];\n const b23 = mat1[14];\n const b33 = mat1[15];\n\n\n resultMat[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;\n resultMat[1] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;\n resultMat[2] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;\n resultMat[3] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;\n\n resultMat[4] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;\n resultMat[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;\n resultMat[6] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;\n resultMat[7] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;\n\n resultMat[8] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;\n resultMat[9] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;\n resultMat[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;\n resultMat[11] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;\n\n resultMat[12] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;\n resultMat[13] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;\n resultMat[14] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;\n resultMat[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;\n return resultMat;\n};\n\n\n/**\n * Transposes the given matrix mat storing the result into resultMat.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to transpose.\n * @param {goog.vec.Mat4.AnyType} resultMat The matrix to receive\n * the results (may be mat).\n * @return {goog.vec.Mat4.AnyType} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.transpose = function(mat, resultMat) {\n 'use strict';\n if (resultMat == mat) {\n const a10 = mat[1];\n const a20 = mat[2];\n const a30 = mat[3];\n\n const a21 = mat[6];\n const a31 = mat[7];\n\n const a32 = mat[11];\n resultMat[1] = mat[4];\n resultMat[2] = mat[8];\n resultMat[3] = mat[12];\n resultMat[4] = a10;\n resultMat[6] = mat[9];\n resultMat[7] = mat[13];\n resultMat[8] = a20;\n resultMat[9] = a21;\n resultMat[11] = mat[14];\n resultMat[12] = a30;\n resultMat[13] = a31;\n resultMat[14] = a32;\n } else {\n resultMat[0] = mat[0];\n resultMat[1] = mat[4];\n resultMat[2] = mat[8];\n resultMat[3] = mat[12];\n\n resultMat[4] = mat[1];\n resultMat[5] = mat[5];\n resultMat[6] = mat[9];\n resultMat[7] = mat[13];\n\n resultMat[8] = mat[2];\n resultMat[9] = mat[6];\n resultMat[10] = mat[10];\n resultMat[11] = mat[14];\n\n resultMat[12] = mat[3];\n resultMat[13] = mat[7];\n resultMat[14] = mat[11];\n resultMat[15] = mat[15];\n }\n return resultMat;\n};\n\n\n/**\n * Computes the determinant of the matrix.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to compute the matrix for.\n * @return {number} The determinant of the matrix.\n */\ngoog.vec.Mat4.determinant = function(mat) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n const m03 = mat[12];\n const m13 = mat[13];\n const m23 = mat[14];\n const m33 = mat[15];\n\n\n const a0 = m00 * m11 - m10 * m01;\n const a1 = m00 * m21 - m20 * m01;\n const a2 = m00 * m31 - m30 * m01;\n const a3 = m10 * m21 - m20 * m11;\n const a4 = m10 * m31 - m30 * m11;\n const a5 = m20 * m31 - m30 * m21;\n const b0 = m02 * m13 - m12 * m03;\n const b1 = m02 * m23 - m22 * m03;\n const b2 = m02 * m33 - m32 * m03;\n const b3 = m12 * m23 - m22 * m13;\n const b4 = m12 * m33 - m32 * m13;\n const b5 = m22 * m33 - m32 * m23;\n\n return a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;\n};\n\n\n/**\n * Computes the inverse of mat storing the result into resultMat. If the\n * inverse is defined, this function returns true, false otherwise.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix to invert.\n * @param {goog.vec.Mat4.AnyType} resultMat The matrix to receive\n * the result (may be mat).\n * @return {boolean} True if the inverse is defined. If false is returned,\n * resultMat is not modified.\n */\ngoog.vec.Mat4.invert = function(mat, resultMat) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n const m03 = mat[12];\n const m13 = mat[13];\n const m23 = mat[14];\n const m33 = mat[15];\n\n\n const a0 = m00 * m11 - m10 * m01;\n const a1 = m00 * m21 - m20 * m01;\n const a2 = m00 * m31 - m30 * m01;\n const a3 = m10 * m21 - m20 * m11;\n const a4 = m10 * m31 - m30 * m11;\n const a5 = m20 * m31 - m30 * m21;\n const b0 = m02 * m13 - m12 * m03;\n const b1 = m02 * m23 - m22 * m03;\n const b2 = m02 * m33 - m32 * m03;\n const b3 = m12 * m23 - m22 * m13;\n const b4 = m12 * m33 - m32 * m13;\n const b5 = m22 * m33 - m32 * m23;\n\n const det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;\n if (det == 0) {\n return false;\n }\n\n const idet = 1.0 / det;\n resultMat[0] = (m11 * b5 - m21 * b4 + m31 * b3) * idet;\n resultMat[1] = (-m10 * b5 + m20 * b4 - m30 * b3) * idet;\n resultMat[2] = (m13 * a5 - m23 * a4 + m33 * a3) * idet;\n resultMat[3] = (-m12 * a5 + m22 * a4 - m32 * a3) * idet;\n resultMat[4] = (-m01 * b5 + m21 * b2 - m31 * b1) * idet;\n resultMat[5] = (m00 * b5 - m20 * b2 + m30 * b1) * idet;\n resultMat[6] = (-m03 * a5 + m23 * a2 - m33 * a1) * idet;\n resultMat[7] = (m02 * a5 - m22 * a2 + m32 * a1) * idet;\n resultMat[8] = (m01 * b4 - m11 * b2 + m31 * b0) * idet;\n resultMat[9] = (-m00 * b4 + m10 * b2 - m30 * b0) * idet;\n resultMat[10] = (m03 * a4 - m13 * a2 + m33 * a0) * idet;\n resultMat[11] = (-m02 * a4 + m12 * a2 - m32 * a0) * idet;\n resultMat[12] = (-m01 * b3 + m11 * b1 - m21 * b0) * idet;\n resultMat[13] = (m00 * b3 - m10 * b1 + m20 * b0) * idet;\n resultMat[14] = (-m03 * a3 + m13 * a1 - m23 * a0) * idet;\n resultMat[15] = (m02 * a3 - m12 * a1 + m22 * a0) * idet;\n return true;\n};\n\n\n/**\n * Returns true if the components of mat0 are equal to the components of mat1.\n *\n * @param {goog.vec.Mat4.AnyType} mat0 The first matrix.\n * @param {goog.vec.Mat4.AnyType} mat1 The second matrix.\n * @return {boolean} True if the two matrices are equivalent.\n */\ngoog.vec.Mat4.equals = function(mat0, mat1) {\n 'use strict';\n return mat0.length == mat1.length && mat0[0] == mat1[0] &&\n mat0[1] == mat1[1] && mat0[2] == mat1[2] && mat0[3] == mat1[3] &&\n mat0[4] == mat1[4] && mat0[5] == mat1[5] && mat0[6] == mat1[6] &&\n mat0[7] == mat1[7] && mat0[8] == mat1[8] && mat0[9] == mat1[9] &&\n mat0[10] == mat1[10] && mat0[11] == mat1[11] && mat0[12] == mat1[12] &&\n mat0[13] == mat1[13] && mat0[14] == mat1[14] && mat0[15] == mat1[15];\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * upper 3x4 matrix omitting the projective component.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix supplying the transformation.\n * @param {goog.vec.Vec3.AnyType} vec The 3 element vector to transform.\n * @param {goog.vec.Vec3.AnyType} resultVec The 3 element vector to\n * receive the results (may be vec).\n * @return {goog.vec.Vec3.AnyType} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.multVec3 = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8] + mat[12];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9] + mat[13];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10] + mat[14];\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * upper 3x3 matrix omitting the projective component and translation\n * components.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix supplying the transformation.\n * @param {goog.vec.Vec3.AnyType} vec The 3 element vector to transform.\n * @param {goog.vec.Vec3.AnyType} resultVec The 3 element vector to\n * receive the results (may be vec).\n * @return {goog.vec.Vec3.AnyType} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.multVec3NoTranslate = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10];\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * full 4x4 matrix with the homogeneous divide applied to reduce the 4 element\n * vector to a 3 element vector.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix supplying the transformation.\n * @param {goog.vec.Vec3.AnyType} vec The 3 element vector to transform.\n * @param {goog.vec.Vec3.AnyType} resultVec The 3 element vector\n * to receive the results (may be vec).\n * @return {goog.vec.Vec3.AnyType} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.multVec3Projective = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n const invw = 1 / (x * mat[3] + y * mat[7] + z * mat[11] + mat[15]);\n resultVec[0] = (x * mat[0] + y * mat[4] + z * mat[8] + mat[12]) * invw;\n resultVec[1] = (x * mat[1] + y * mat[5] + z * mat[9] + mat[13]) * invw;\n resultVec[2] = (x * mat[2] + y * mat[6] + z * mat[10] + mat[14]) * invw;\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix supplying the transformation.\n * @param {goog.vec.Vec4.AnyType} vec The vector to transform.\n * @param {goog.vec.Vec4.AnyType} resultVec The vector to\n * receive the results (may be vec).\n * @return {goog.vec.Vec4.AnyType} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.multVec4 = function(mat, vec, resultVec) {\n 'use strict';\n const w = vec[3];\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8] + w * mat[12];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9] + w * mat[13];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10] + w * mat[14];\n resultVec[3] = x * mat[3] + y * mat[7] + z * mat[11] + w * mat[15];\n return resultVec;\n};\n\n\n/**\n * Makes the given 4x4 matrix a translation matrix with x, y and z\n * translation factors.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @param {number} z The translation along the z axis.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeTranslate = function(mat, x, y, z) {\n 'use strict';\n goog.vec.Mat4.makeIdentity(mat);\n return goog.vec.Mat4.setColumnValues(mat, 3, x, y, z, 1);\n};\n\n\n/**\n * Makes the given 4x4 matrix as a scale matrix with x, y and z scale factors.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} x The scale along the x axis.\n * @param {number} y The scale along the y axis.\n * @param {number} z The scale along the z axis.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeScale = function(mat, x, y, z) {\n 'use strict';\n goog.vec.Mat4.makeIdentity(mat);\n return goog.vec.Mat4.setDiagonalValues(mat, x, y, z, 1);\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the axis defined by the vector (ax, ay, az).\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @param {number} ax The x component of the rotation axis.\n * @param {number} ay The y component of the rotation axis.\n * @param {number} az The z component of the rotation axis.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeRotate = function(mat, angle, ax, ay, az) {\n 'use strict';\n const c = Math.cos(angle);\n const d = 1 - c;\n const s = Math.sin(angle);\n\n return goog.vec.Mat4.setFromValues(\n mat, ax * ax * d + c, ax * ay * d + az * s, ax * az * d - ay * s, 0,\n\n ax * ay * d - az * s, ay * ay * d + c, ay * az * d + ax * s, 0,\n\n ax * az * d + ay * s, ay * az * d - ax * s, az * az * d + c, 0,\n\n 0, 0, 0, 1);\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the X axis.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeRotateX = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n return goog.vec.Mat4.setFromValues(\n mat, 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1);\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the Y axis.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeRotateY = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n return goog.vec.Mat4.setFromValues(\n mat, c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1);\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the Z axis.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeRotateZ = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n return goog.vec.Mat4.setFromValues(\n mat, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);\n};\n\n\n/**\n * Makes the given 4x4 matrix a perspective projection matrix.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} left The coordinate of the left clipping plane.\n * @param {number} right The coordinate of the right clipping plane.\n * @param {number} bottom The coordinate of the bottom clipping plane.\n * @param {number} top The coordinate of the top clipping plane.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeFrustum = function(mat, left, right, bottom, top, near, far) {\n 'use strict';\n const x = (2 * near) / (right - left);\n const y = (2 * near) / (top - bottom);\n const a = (right + left) / (right - left);\n const b = (top + bottom) / (top - bottom);\n const c = -(far + near) / (far - near);\n const d = -(2 * far * near) / (far - near);\n\n return goog.vec.Mat4.setFromValues(\n mat, x, 0, 0, 0, 0, y, 0, 0, a, b, c, -1, 0, 0, d, 0);\n};\n\n\n/**\n * Makes the given 4x4 matrix perspective projection matrix given a\n * field of view and aspect ratio.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} fovy The field of view along the y (vertical) axis in\n * radians.\n * @param {number} aspect The x (width) to y (height) aspect ratio.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makePerspective = function(mat, fovy, aspect, near, far) {\n 'use strict';\n const angle = fovy / 2;\n const dz = far - near;\n const sinAngle = Math.sin(angle);\n if (dz == 0 || sinAngle == 0 || aspect == 0) {\n return mat;\n }\n\n const cot = Math.cos(angle) / sinAngle;\n return goog.vec.Mat4.setFromValues(\n mat, cot / aspect, 0, 0, 0, 0, cot, 0, 0, 0, 0, -(far + near) / dz, -1, 0,\n 0, -(2 * near * far) / dz, 0);\n};\n\n\n/**\n * Makes the given 4x4 matrix an orthographic projection matrix.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} left The coordinate of the left clipping plane.\n * @param {number} right The coordinate of the right clipping plane.\n * @param {number} bottom The coordinate of the bottom clipping plane.\n * @param {number} top The coordinate of the top clipping plane.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeOrtho = function(mat, left, right, bottom, top, near, far) {\n 'use strict';\n const x = 2 / (right - left);\n const y = 2 / (top - bottom);\n const z = -2 / (far - near);\n const a = -(right + left) / (right - left);\n const b = -(top + bottom) / (top - bottom);\n const c = -(far + near) / (far - near);\n\n return goog.vec.Mat4.setFromValues(\n mat, x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, a, b, c, 1);\n};\n\n\n/**\n * Makes the given 4x4 matrix a modelview matrix of a camera so that\n * the camera is 'looking at' the given center point.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {goog.vec.Vec3.AnyType} eyePt The position of the eye point\n * (camera origin).\n * @param {goog.vec.Vec3.AnyType} centerPt The point to aim the camera at.\n * @param {goog.vec.Vec3.AnyType} worldUpVec The vector that identifies\n * the up direction for the camera.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeLookAt = function(mat, eyePt, centerPt, worldUpVec) {\n 'use strict';\n // Compute the direction vector from the eye point to the center point and\n // normalize.\n const fwdVec = goog.vec.Mat4.tmpVec4_[0];\n goog.vec.Vec3.subtract(centerPt, eyePt, fwdVec);\n goog.vec.Vec3.normalize(fwdVec, fwdVec);\n fwdVec[3] = 0;\n\n // Compute the side vector from the forward vector and the input up vector.\n const sideVec = goog.vec.Mat4.tmpVec4_[1];\n goog.vec.Vec3.cross(fwdVec, worldUpVec, sideVec);\n goog.vec.Vec3.normalize(sideVec, sideVec);\n sideVec[3] = 0;\n\n // Now the up vector to form the orthonormal basis.\n const upVec = goog.vec.Mat4.tmpVec4_[2];\n goog.vec.Vec3.cross(sideVec, fwdVec, upVec);\n goog.vec.Vec3.normalize(upVec, upVec);\n upVec[3] = 0;\n\n // Update the view matrix with the new orthonormal basis and position the\n // camera at the given eye point.\n goog.vec.Vec3.negate(fwdVec, fwdVec);\n goog.vec.Mat4.setRow(mat, 0, sideVec);\n goog.vec.Mat4.setRow(mat, 1, upVec);\n goog.vec.Mat4.setRow(mat, 2, fwdVec);\n goog.vec.Mat4.setRowValues(mat, 3, 0, 0, 0, 1);\n goog.vec.Mat4.translate(mat, -eyePt[0], -eyePt[1], -eyePt[2]);\n\n return mat;\n};\n\n\n/**\n * Decomposes a matrix into the lookAt vectors eyePt, fwdVec and worldUpVec.\n * The matrix represents the modelview matrix of a camera. It is the inverse\n * of lookAt except for the output of the fwdVec instead of centerPt.\n * The centerPt itself cannot be recovered from a modelview matrix.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {goog.vec.Vec3.AnyType} eyePt The position of the eye point\n * (camera origin).\n * @param {goog.vec.Vec3.AnyType} fwdVec The vector describing where\n * the camera points to.\n * @param {goog.vec.Vec3.AnyType} worldUpVec The vector that\n * identifies the up direction for the camera.\n * @return {boolean} True if the method succeeds, false otherwise.\n * The method can only fail if the inverse of viewMatrix is not defined.\n */\ngoog.vec.Mat4.toLookAt = function(mat, eyePt, fwdVec, worldUpVec) {\n 'use strict';\n // Get eye of the camera.\n const matInverse = goog.vec.Mat4.tmpMat4_[0];\n if (!goog.vec.Mat4.invert(mat, matInverse)) {\n // The input matrix does not have a valid inverse.\n return false;\n }\n\n if (eyePt) {\n eyePt[0] = matInverse[12];\n eyePt[1] = matInverse[13];\n eyePt[2] = matInverse[14];\n }\n\n // Get forward vector from the definition of lookAt.\n if (fwdVec || worldUpVec) {\n if (!fwdVec) {\n fwdVec = goog.vec.Mat4.tmpVec3_[0];\n }\n fwdVec[0] = -mat[2];\n fwdVec[1] = -mat[6];\n fwdVec[2] = -mat[10];\n // Normalize forward vector.\n goog.vec.Vec3.normalize(fwdVec, fwdVec);\n }\n\n if (worldUpVec) {\n // Get side vector from the definition of gluLookAt.\n const side = goog.vec.Mat4.tmpVec3_[1];\n side[0] = mat[0];\n side[1] = mat[4];\n side[2] = mat[8];\n // Compute up vector as a up = side x forward.\n goog.vec.Vec3.cross(side, fwdVec, worldUpVec);\n // Normalize up vector.\n goog.vec.Vec3.normalize(worldUpVec, worldUpVec);\n }\n return true;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix given Euler angles using\n * the ZXZ convention.\n * Given the euler angles [theta1, theta2, theta3], the rotation is defined as\n * rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians,\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} theta1 The angle of rotation around the Z axis in radians.\n * @param {number} theta2 The angle of rotation around the X axis in radians.\n * @param {number} theta3 The angle of rotation around the Z axis in radians.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.makeEulerZXZ = function(mat, theta1, theta2, theta3) {\n 'use strict';\n const c1 = Math.cos(theta1);\n const s1 = Math.sin(theta1);\n\n const c2 = Math.cos(theta2);\n const s2 = Math.sin(theta2);\n\n const c3 = Math.cos(theta3);\n const s3 = Math.sin(theta3);\n\n mat[0] = c1 * c3 - c2 * s1 * s3;\n mat[1] = c2 * c1 * s3 + c3 * s1;\n mat[2] = s3 * s2;\n mat[3] = 0;\n\n mat[4] = -c1 * s3 - c3 * c2 * s1;\n mat[5] = c1 * c2 * c3 - s1 * s3;\n mat[6] = c3 * s2;\n mat[7] = 0;\n\n mat[8] = s2 * s1;\n mat[9] = -c1 * s2;\n mat[10] = c2;\n mat[11] = 0;\n\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Decomposes a rotation matrix into Euler angles using the ZXZ convention so\n * that rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {goog.vec.Vec3.AnyType} euler The ZXZ Euler angles in\n * radians as [theta1, theta2, theta3].\n * @param {boolean=} opt_theta2IsNegative Whether theta2 is in [-pi, 0] instead\n * of the default [0, pi].\n * @return {goog.vec.Vec4.AnyType} return euler so that operations can be\n * chained together.\n */\ngoog.vec.Mat4.toEulerZXZ = function(mat, euler, opt_theta2IsNegative) {\n 'use strict';\n // There is an ambiguity in the sign of sinTheta2 because of the sqrt.\n const sinTheta2 = Math.sqrt(mat[2] * mat[2] + mat[6] * mat[6]);\n\n // By default we explicitely constrain theta2 to be in [0, pi],\n // so sinTheta2 is always positive. We can change the behavior and specify\n // theta2 to be negative in [-pi, 0] with opt_Theta2IsNegative.\n const signTheta2 = opt_theta2IsNegative ? -1 : 1;\n\n if (sinTheta2 > goog.vec.EPSILON) {\n euler[2] = Math.atan2(mat[2] * signTheta2, mat[6] * signTheta2);\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[10]);\n euler[0] = Math.atan2(mat[8] * signTheta2, -mat[9] * signTheta2);\n } else {\n // There is also an arbitrary choice for theta1 = 0 or theta2 = 0 here.\n // We assume theta1 = 0 as some applications do not allow the camera to roll\n // (i.e. have theta1 != 0).\n euler[0] = 0;\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[10]);\n euler[2] = Math.atan2(mat[1], mat[0]);\n }\n\n // Atan2 outputs angles in [-pi, pi] so we bring them back to [0, 2 * pi].\n euler[0] = (euler[0] + Math.PI * 2) % (Math.PI * 2);\n euler[2] = (euler[2] + Math.PI * 2) % (Math.PI * 2);\n // For theta2 we want the angle to be in [0, pi] or [-pi, 0] depending on\n // signTheta2.\n euler[1] =\n ((euler[1] * signTheta2 + Math.PI * 2) % (Math.PI * 2)) * signTheta2;\n\n return euler;\n};\n\n\n/**\n * Translates the given matrix by x,y,z. Equvialent to:\n * goog.vec.Mat4.multMat(\n * mat,\n * goog.vec.Mat4.makeTranslate(goog.vec.Mat4.create(), x, y, z),\n * mat);\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @param {number} z The translation along the z axis.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.translate = function(mat, x, y, z) {\n 'use strict';\n return goog.vec.Mat4.setColumnValues(\n mat, 3, mat[0] * x + mat[4] * y + mat[8] * z + mat[12],\n mat[1] * x + mat[5] * y + mat[9] * z + mat[13],\n mat[2] * x + mat[6] * y + mat[10] * z + mat[14],\n mat[3] * x + mat[7] * y + mat[11] * z + mat[15]);\n};\n\n\n/**\n * Scales the given matrix by x,y,z. Equivalent to:\n * goog.vec.Mat4.multMat(\n * mat,\n * goog.vec.Mat4.makeScale(goog.vec.Mat4.create(), x, y, z),\n * mat);\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} x The x scale factor.\n * @param {number} y The y scale factor.\n * @param {number} z The z scale factor.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.scale = function(mat, x, y, z) {\n 'use strict';\n return goog.vec.Mat4.setFromValues(\n mat, mat[0] * x, mat[1] * x, mat[2] * x, mat[3] * x, mat[4] * y,\n mat[5] * y, mat[6] * y, mat[7] * y, mat[8] * z, mat[9] * z, mat[10] * z,\n mat[11] * z, mat[12], mat[13], mat[14], mat[15]);\n};\n\n\n/**\n * Rotate the given matrix by angle about the x,y,z axis. Equivalent to:\n * goog.vec.Mat4.multMat(\n * mat,\n * goog.vec.Mat4.makeRotate(goog.vec.Mat4.create(), angle, x, y, z),\n * mat);\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} angle The angle in radians.\n * @param {number} x The x component of the rotation axis.\n * @param {number} y The y component of the rotation axis.\n * @param {number} z The z component of the rotation axis.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.rotate = function(mat, angle, x, y, z) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n const m03 = mat[12];\n const m13 = mat[13];\n const m23 = mat[14];\n const m33 = mat[15];\n\n\n const cosAngle = Math.cos(angle);\n const sinAngle = Math.sin(angle);\n const diffCosAngle = 1 - cosAngle;\n const r00 = x * x * diffCosAngle + cosAngle;\n const r10 = x * y * diffCosAngle + z * sinAngle;\n const r20 = x * z * diffCosAngle - y * sinAngle;\n\n const r01 = x * y * diffCosAngle - z * sinAngle;\n const r11 = y * y * diffCosAngle + cosAngle;\n const r21 = y * z * diffCosAngle + x * sinAngle;\n\n const r02 = x * z * diffCosAngle + y * sinAngle;\n const r12 = y * z * diffCosAngle - x * sinAngle;\n const r22 = z * z * diffCosAngle + cosAngle;\n\n return goog.vec.Mat4.setFromValues(\n mat, m00 * r00 + m01 * r10 + m02 * r20, m10 * r00 + m11 * r10 + m12 * r20,\n m20 * r00 + m21 * r10 + m22 * r20, m30 * r00 + m31 * r10 + m32 * r20,\n\n m00 * r01 + m01 * r11 + m02 * r21, m10 * r01 + m11 * r11 + m12 * r21,\n m20 * r01 + m21 * r11 + m22 * r21, m30 * r01 + m31 * r11 + m32 * r21,\n\n m00 * r02 + m01 * r12 + m02 * r22, m10 * r02 + m11 * r12 + m12 * r22,\n m20 * r02 + m21 * r12 + m22 * r22, m30 * r02 + m31 * r12 + m32 * r22,\n\n m03, m13, m23, m33);\n};\n\n\n/**\n * Rotate the given matrix by angle about the x axis. Equivalent to:\n * goog.vec.Mat4.multMat(\n * mat,\n * goog.vec.Mat4.makeRotateX(goog.vec.Mat4.create(), angle),\n * mat);\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.rotateX = function(mat, angle) {\n 'use strict';\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[4] = m01 * c + m02 * s;\n mat[5] = m11 * c + m12 * s;\n mat[6] = m21 * c + m22 * s;\n mat[7] = m31 * c + m32 * s;\n mat[8] = m01 * -s + m02 * c;\n mat[9] = m11 * -s + m12 * c;\n mat[10] = m21 * -s + m22 * c;\n mat[11] = m31 * -s + m32 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the y axis. Equivalent to:\n * goog.vec.Mat4.multMat(\n * mat,\n * goog.vec.Mat4.makeRotateY(goog.vec.Mat4.create(), angle),\n * mat);\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.rotateY = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m02 * -s;\n mat[1] = m10 * c + m12 * -s;\n mat[2] = m20 * c + m22 * -s;\n mat[3] = m30 * c + m32 * -s;\n mat[8] = m00 * s + m02 * c;\n mat[9] = m10 * s + m12 * c;\n mat[10] = m20 * s + m22 * c;\n mat[11] = m30 * s + m32 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the z axis. Equivalent to:\n * goog.vec.Mat4.multMat(\n * mat,\n * goog.vec.Mat4.makeRotateZ(goog.vec.Mat4.create(), angle),\n * mat);\n *\n * @param {goog.vec.Mat4.AnyType} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.rotateZ = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m01 * s;\n mat[1] = m10 * c + m11 * s;\n mat[2] = m20 * c + m21 * s;\n mat[3] = m30 * c + m31 * s;\n mat[4] = m00 * -s + m01 * c;\n mat[5] = m10 * -s + m11 * c;\n mat[6] = m20 * -s + m21 * c;\n mat[7] = m30 * -s + m31 * c;\n\n return mat;\n};\n\n\n/**\n * Retrieves the translation component of the transformation matrix.\n *\n * @param {goog.vec.Mat4.AnyType} mat The transformation matrix.\n * @param {goog.vec.Vec3.AnyType} translation The vector for storing the\n * result.\n * @return {goog.vec.Mat4.AnyType} return mat so that operations can be\n * chained.\n */\ngoog.vec.Mat4.getTranslation = function(mat, translation) {\n 'use strict';\n translation[0] = mat[12];\n translation[1] = mat[13];\n translation[2] = mat[14];\n return translation;\n};\n\n\n/**\n * @type {!Array}\n * @private\n */\ngoog.vec.Mat4.tmpVec3_ =\n [goog.vec.Vec3.createFloat64(), goog.vec.Vec3.createFloat64()];\n\n\n/**\n * @type {!Array}\n * @private\n */\ngoog.vec.Mat4.tmpVec4_ = [\n goog.vec.Vec4.createFloat64(), goog.vec.Vec4.createFloat64(),\n goog.vec.Vec4.createFloat64()\n];\n\n\n/**\n * @type {!Array}\n * @private\n */\ngoog.vec.Mat4.tmpMat4_ = [goog.vec.Mat4.createFloat64()];\n","^<",1684857788697,"^=",["^3",["^16","^14","^15","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^16","^14","^15"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.Mat4"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec","goog.vec.Vec3","goog.vec.Vec4"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/mat4.js"],"^[",["^3",["^1D"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14","^15","^16"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.vec2d","~$goog.vec.vec2d.Type"]],"^5","goog.vec.vec2d.js","^6",["^7","goog/vec/vec2d.js"],"^8","goog/vec/vec2d.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to vec2f.js by running: //\n// swap_type.sh vec2d.js > vec2f.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 2 element double (64bit)\n * vectors.\n *\n * The last parameter will typically be the output object and an object\n * can be both an input and output parameter to all methods except where\n * noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\n\ngoog.provide('goog.vec.vec2d');\ngoog.provide('goog.vec.vec2d.Type');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n\n/** @typedef {!goog.vec.Float64} */ goog.vec.vec2d.Type;\n\n\n/**\n * Creates a vec2d with all elements initialized to zero.\n *\n * @return {!goog.vec.vec2d.Type} The new vec2d.\n */\ngoog.vec.vec2d.create = function() {\n 'use strict';\n return new Float64Array(2);\n};\n\n\n/**\n * Creates a new vec2d initialized with the value from the given array.\n *\n * @param {!Array} vec The source 2 element array.\n * @return {!goog.vec.vec2d.Type} The new vec2d.\n */\ngoog.vec.vec2d.createFromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec2d.create();\n goog.vec.vec2d.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new vec2d initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @return {!goog.vec.vec2d.Type} The new vector.\n */\ngoog.vec.vec2d.createFromValues = function(v0, v1) {\n 'use strict';\n const vec = goog.vec.vec2d.create();\n goog.vec.vec2d.setFromValues(vec, v0, v1);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given vec2d.\n *\n * @param {!goog.vec.vec2d.Type} vec The source vec2d.\n * @return {!goog.vec.vec2d.Type} The new cloned vec2d.\n */\ngoog.vec.vec2d.clone = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec2d.create();\n goog.vec.vec2d.setFromVec2d(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {!goog.vec.vec2d.Type} vec The vector to receive the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @return {!goog.vec.vec2d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.setFromValues = function(vec, v0, v1) {\n 'use strict';\n vec[0] = v0;\n vec[1] = v1;\n return vec;\n};\n\n\n/**\n * Initializes vec2d vec from vec2d src.\n *\n * @param {!goog.vec.vec2d.Type} vec The destination vector.\n * @param {!goog.vec.vec2d.Type} src The source vector.\n * @return {!goog.vec.vec2d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.setFromVec2d = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n return vec;\n};\n\n\n/**\n * Initializes vec2d vec from vec2f src (typed as a Float32Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.vec2d.Type} vec The destination vector.\n * @param {Float32Array} src The source vector.\n * @return {!goog.vec.vec2d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.setFromVec2f = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n return vec;\n};\n\n\n/**\n * Initializes vec2d vec from Array src.\n *\n * @param {!goog.vec.vec2d.Type} vec The destination vector.\n * @param {Array} src The source vector.\n * @return {!goog.vec.vec2d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.setFromArray = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The first addend.\n * @param {!goog.vec.vec2d.Type} vec1 The second addend.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The minuend.\n * @param {!goog.vec.vec2d.Type} vec1 The subtrahend.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with the matching element of vec0\n * storing the products into resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The first vector.\n * @param {!goog.vec.vec2d.Type} vec1 The second vector.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.componentMultiply = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * vec1[0];\n resultVec[1] = vec0[1] * vec1[1];\n return resultVec;\n};\n\n\n/**\n * Divides each component of vec0 with the matching element of vec0\n * storing the divisor into resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The first vector.\n * @param {!goog.vec.vec2d.Type} vec1 The second vector.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.componentDivide = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] / vec1[0];\n resultVec[1] = vec0[1] / vec1[1];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The vector to negate.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The source vector.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec2d.magnitudeSquared = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n\n return x * x + y * y;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec2d.magnitude = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n\n return Math.sqrt(x * x + y * y);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The vector to normalize.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.normalize = function(vec0, resultVec) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n\n const ilen = 1 / Math.sqrt(x * x + y * y);\n resultVec[0] = x * ilen;\n resultVec[1] = y * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors vec0 and vec1.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The first vector.\n * @param {!goog.vec.vec2d.Type} vec1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.vec2d.dot = function(vec0, vec1) {\n 'use strict';\n return vec0[0] * vec1[0] + vec0[1] * vec1[1];\n};\n\n\n/**\n * Returns the squared distance between two points.\n *\n * @param {!goog.vec.vec2d.Type} vec0 First point.\n * @param {!goog.vec.vec2d.Type} vec1 Second point.\n * @return {number} The squared distance between the points.\n */\ngoog.vec.vec2d.distanceSquared = function(vec0, vec1) {\n 'use strict';\n const x = vec0[0] - vec1[0];\n const y = vec0[1] - vec1[1];\n return x * x + y * y;\n};\n\n\n/**\n * Returns the distance between two points.\n *\n * @param {!goog.vec.vec2d.Type} vec0 First point.\n * @param {!goog.vec.vec2d.Type} vec1 Second point.\n * @return {number} The distance between the points.\n */\ngoog.vec.vec2d.distance = function(vec0, vec1) {\n 'use strict';\n return Math.sqrt(goog.vec.vec2d.distanceSquared(vec0, vec1));\n};\n\n\n/**\n * Returns a unit vector pointing from one point to another.\n * If the input points are equal then the result will be all zeros.\n *\n * @param {!goog.vec.vec2d.Type} vec0 Origin point.\n * @param {!goog.vec.vec2d.Type} vec1 Target point.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.direction = function(vec0, vec1, resultVec) {\n 'use strict';\n const x = vec1[0] - vec0[0];\n const y = vec1[1] - vec0[1];\n let d = Math.sqrt(x * x + y * y);\n if (d) {\n d = 1 / d;\n resultVec[0] = x * d;\n resultVec[1] = y * d;\n } else {\n resultVec[0] = resultVec[1] = 0;\n }\n return resultVec;\n};\n\n\n/**\n * Linearly interpolate from vec0 to vec1 according to f. The value of f should\n * be in the range [0..1] otherwise the results are undefined.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The first vector.\n * @param {!goog.vec.vec2d.Type} vec1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.lerp = function(vec0, vec1, f, resultVec) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n\n resultVec[0] = (vec1[0] - x) * f + x;\n resultVec[1] = (vec1[1] - y) * f + y;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The source vector.\n * @param {!goog.vec.vec2d.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The source vector.\n * @param {!goog.vec.vec2d.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec2d.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec2d.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of vec0 are equal to the components of vec1.\n *\n * @param {!goog.vec.vec2d.Type} vec0 The first vector.\n * @param {!goog.vec.vec2d.Type} vec1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.vec2d.equals = function(vec0, vec1) {\n 'use strict';\n return vec0.length == vec1.length && vec0[0] == vec1[0] && vec0[1] == vec1[1];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.vec2d","goog.vec.vec2d.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec2d.js"],"^[",["^3",["^1E","^1F"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.Vec2"]],"^5","goog.vec.vec2.js","^6",["^7","goog/vec/vec2.js"],"^8","goog/vec/vec2.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of 2 element vectors. This follows the same design\n * patterns as Vec3 and Vec4.\n */\n\ngoog.provide('goog.vec.Vec2');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.Vec2.Float32;\n/** @typedef {!goog.vec.Float64} */ goog.vec.Vec2.Float64;\n/** @typedef {!goog.vec.Number} */ goog.vec.Vec2.Number;\n/** @typedef {!goog.vec.AnyType} */ goog.vec.Vec2.AnyType;\n\n\n/**\n * Creates a 2 element vector of Float32. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec2.Float32} The new 2 element array.\n */\ngoog.vec.Vec2.createFloat32 = function() {\n 'use strict';\n return new Float32Array(2);\n};\n\n\n/**\n * Creates a 2 element vector of Float64. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec2.Float64} The new 2 element array.\n */\ngoog.vec.Vec2.createFloat64 = function() {\n 'use strict';\n return new Float64Array(2);\n};\n\n\n/**\n * Creates a 2 element vector of Number. The array is initialized to zero.\n *\n * @return {!goog.vec.Vec2.Number} The new 2 element array.\n */\ngoog.vec.Vec2.createNumber = function() {\n 'use strict';\n var a = new Array(2);\n goog.vec.Vec2.setFromValues(a, 0, 0);\n return a;\n};\n\n\n/**\n * Creates a new 2 element FLoat32 vector initialized with the value from the\n * given array.\n *\n * @param {goog.vec.Vec2.AnyType} vec The source 2 element array.\n * @return {!goog.vec.Vec2.Float32} The new 2 element array.\n */\ngoog.vec.Vec2.createFloat32FromArray = function(vec) {\n 'use strict';\n var newVec = goog.vec.Vec2.createFloat32();\n goog.vec.Vec2.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new 2 element Float32 vector initialized with the supplied values.\n *\n * @param {number} vec0 The value for element at index 0.\n * @param {number} vec1 The value for element at index 1.\n * @return {!goog.vec.Vec2.Float32} The new vector.\n */\ngoog.vec.Vec2.createFloat32FromValues = function(vec0, vec1) {\n 'use strict';\n var a = goog.vec.Vec2.createFloat32();\n goog.vec.Vec2.setFromValues(a, vec0, vec1);\n return a;\n};\n\n\n/**\n * Creates a clone of the given 2 element Float32 vector.\n *\n * @param {goog.vec.Vec2.Float32} vec The source 2 element vector.\n * @return {!goog.vec.Vec2.Float32} The new cloned vector.\n */\ngoog.vec.Vec2.cloneFloat32 = goog.vec.Vec2.createFloat32FromArray;\n\n\n/**\n * Creates a new 2 element Float64 vector initialized with the value from the\n * given array.\n *\n * @param {goog.vec.Vec2.AnyType} vec The source 2 element array.\n * @return {!goog.vec.Vec2.Float64} The new 2 element array.\n */\ngoog.vec.Vec2.createFloat64FromArray = function(vec) {\n 'use strict';\n var newVec = goog.vec.Vec2.createFloat64();\n goog.vec.Vec2.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n* Creates a new 2 element Float64 vector initialized with the supplied values.\n*\n* @param {number} vec0 The value for element at index 0.\n* @param {number} vec1 The value for element at index 1.\n* @return {!goog.vec.Vec2.Float64} The new vector.\n*/\ngoog.vec.Vec2.createFloat64FromValues = function(vec0, vec1) {\n 'use strict';\n var vec = goog.vec.Vec2.createFloat64();\n goog.vec.Vec2.setFromValues(vec, vec0, vec1);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given 2 element vector.\n *\n * @param {goog.vec.Vec2.Float64} vec The source 2 element vector.\n * @return {!goog.vec.Vec2.Float64} The new cloned vector.\n */\ngoog.vec.Vec2.cloneFloat64 = goog.vec.Vec2.createFloat64FromArray;\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {goog.vec.Vec2.AnyType} vec The vector to receive the values.\n * @param {number} vec0 The value for element at index 0.\n * @param {number} vec1 The value for element at index 1.\n * @return {!goog.vec.Vec2.AnyType} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.setFromValues = function(vec, vec0, vec1) {\n 'use strict';\n vec[0] = vec0;\n vec[1] = vec1;\n return vec;\n};\n\n\n/**\n * Initializes the vector with the given array of values.\n *\n * @param {goog.vec.Vec2.AnyType} vec The vector to receive the\n * values.\n * @param {goog.vec.Vec2.AnyType} values The array of values.\n * @return {!goog.vec.Vec2.AnyType} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.setFromArray = function(vec, values) {\n 'use strict';\n vec[0] = values[0];\n vec[1] = values[1];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The first addend.\n * @param {goog.vec.Vec2.AnyType} vec1 The second addend.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The minuend.\n * @param {goog.vec.Vec2.AnyType} vec1 The subtrahend.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The vector to negate.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.Vec2.magnitudeSquared = function(vec0) {\n 'use strict';\n var x = vec0[0], y = vec0[1];\n return x * x + y * y;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.Vec2.magnitude = function(vec0) {\n 'use strict';\n var x = vec0[0], y = vec0[1];\n return Math.hypot(x, y);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The vector to normalize.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.normalize = function(vec0, resultVec) {\n 'use strict';\n var ilen = 1 / goog.vec.Vec2.magnitude(vec0);\n resultVec[0] = vec0[0] * ilen;\n resultVec[1] = vec0[1] * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors vec0 and vec1.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The first vector.\n * @param {goog.vec.Vec2.AnyType} vec1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.Vec2.dot = function(vec0, vec1) {\n 'use strict';\n return vec0[0] * vec1[0] + vec0[1] * vec1[1];\n};\n\n\n/**\n * Returns the squared distance between two points.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 First point.\n * @param {goog.vec.Vec2.AnyType} vec1 Second point.\n * @return {number} The squared distance between the points.\n */\ngoog.vec.Vec2.distanceSquared = function(vec0, vec1) {\n 'use strict';\n var x = vec0[0] - vec1[0];\n var y = vec0[1] - vec1[1];\n return x * x + y * y;\n};\n\n\n/**\n * Returns the distance between two points.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 First point.\n * @param {goog.vec.Vec2.AnyType} vec1 Second point.\n * @return {number} The distance between the points.\n */\ngoog.vec.Vec2.distance = function(vec0, vec1) {\n 'use strict';\n return Math.sqrt(goog.vec.Vec2.distanceSquared(vec0, vec1));\n};\n\n\n/**\n * Returns a unit vector pointing from one point to another.\n * If the input points are equal then the result will be all zeros.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 Origin point.\n * @param {goog.vec.Vec2.AnyType} vec1 Target point.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.direction = function(vec0, vec1, resultVec) {\n 'use strict';\n var x = vec1[0] - vec0[0];\n var y = vec1[1] - vec0[1];\n var d = Math.sqrt(x * x + y * y);\n if (d) {\n d = 1 / d;\n resultVec[0] = x * d;\n resultVec[1] = y * d;\n } else {\n resultVec[0] = resultVec[1] = 0;\n }\n return resultVec;\n};\n\n\n/**\n * Linearly interpolate from vec0 to vec1 according to f. The value of f should\n * be in the range [0..1] otherwise the results are undefined.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The first vector.\n * @param {goog.vec.Vec2.AnyType} vec1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.lerp = function(vec0, vec1, f, resultVec) {\n 'use strict';\n var x = vec0[0], y = vec0[1];\n resultVec[0] = (vec1[0] - x) * f + x;\n resultVec[1] = (vec1[1] - y) * f + y;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec2.AnyType|number} limit The limit vector or scalar.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The source vector.\n * @param {goog.vec.Vec2.AnyType|number} limit The limit vector or scalar.\n * @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.Vec2.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of vec0 are equal to the components of vec1.\n *\n * @param {goog.vec.Vec2.AnyType} vec0 The first vector.\n * @param {goog.vec.Vec2.AnyType} vec1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.Vec2.equals = function(vec0, vec1) {\n 'use strict';\n return vec0.length == vec1.length && vec0[0] == vec1[0] && vec0[1] == vec1[1];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.Vec2"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec2.js"],"^[",["^3",["^1G"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^1>"]],"^5","goog.vec.float32array.js","^6",["^7","goog/vec/float32array.js"],"^8","goog/vec/float32array.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n/**\n * @fileoverview Supplies a Float32Array implementation that implements\n * most of the Float32Array spec and that can be used when a built-in\n * implementation is not available.\n *\n * Note that if no existing Float32Array implementation is found then\n * this class and all its public properties are exported as Float32Array.\n *\n * Adding support for the other TypedArray classes here does not make sense\n * since this vector math library only needs Float32Array.\n */\ngoog.provide('goog.vec.Float32Array');\n\n\n\n/**\n * Constructs a new Float32Array. The new array is initialized to all zeros.\n *\n * @param {goog.vec.Float32Array|Array|ArrayBuffer|number} p0\n * The length of the array, or an array to initialize the contents of the\n * new Float32Array.\n * @constructor\n * @implements {IArrayLike}\n * @final\n */\ngoog.vec.Float32Array = function(p0) {\n 'use strict';\n /** @type {number} */\n this.length = /** @type {number} */ (/** @type {?} */ (p0).length || p0);\n for (let i = 0; i < this.length; i++) {\n this[i] = p0[i] || 0;\n }\n};\n\n\n/**\n * The number of bytes in an element (as defined by the Typed Array\n * specification).\n *\n * @type {number}\n */\ngoog.vec.Float32Array.BYTES_PER_ELEMENT = 4;\n\n\n/**\n * The number of bytes in an element (as defined by the Typed Array\n * specification).\n *\n * @type {number}\n */\ngoog.vec.Float32Array.prototype.BYTES_PER_ELEMENT = 4;\n\n\n/**\n * Sets elements of the array.\n * @param {Array|Float32Array} values The array of values.\n * @param {number=} opt_offset The offset in this array to start.\n */\ngoog.vec.Float32Array.prototype.set = function(values, opt_offset) {\n 'use strict';\n opt_offset = opt_offset || 0;\n for (let i = 0; i < values.length && opt_offset + i < this.length; i++) {\n this[opt_offset + i] = values[i];\n }\n};\n\n\n/**\n * Creates a string representation of this array.\n * @return {string} The string version of this array.\n * @override\n */\ngoog.vec.Float32Array.prototype.toString = Array.prototype.join;\n\n\n/**\n * Note that we cannot implement the subarray() or (deprecated) slice()\n * methods properly since doing so would require being able to overload\n * the [] operator which is not possible in javascript. So we leave\n * them unimplemented. Any attempt to call these methods will just result\n * in a javascript error since we leave them undefined.\n */\n\n\n/**\n * If no existing Float32Array implementation is found then we export\n * goog.vec.Float32Array as Float32Array.\n */\nif (typeof Float32Array == 'undefined') {\n goog.exportProperty(\n goog.vec.Float32Array, 'BYTES_PER_ELEMENT',\n goog.vec.Float32Array.BYTES_PER_ELEMENT);\n goog.exportProperty(\n goog.vec.Float32Array.prototype, 'BYTES_PER_ELEMENT',\n goog.vec.Float32Array.prototype.BYTES_PER_ELEMENT);\n goog.exportProperty(\n goog.vec.Float32Array.prototype, 'set',\n goog.vec.Float32Array.prototype.set);\n goog.exportProperty(\n goog.vec.Float32Array.prototype, 'toString',\n goog.vec.Float32Array.prototype.toString);\n goog.exportSymbol('Float32Array', goog.vec.Float32Array);\n}\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.Float32Array"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/float32array.js"],"^[",["^3",["^1>"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.vec3d.Type","~$goog.vec.vec3d"]],"^5","goog.vec.vec3d.js","^6",["^7","goog/vec/vec3d.js"],"^8","goog/vec/vec3d.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to vec3f.js by running: //\n// swap_type.sh vec3d.js > vec3f.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 3 element double (64bit)\n * vectors.\n *\n * The last parameter will typically be the output object and an object\n * can be both an input and output parameter to all methods except where\n * noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\ngoog.provide('goog.vec.vec3d');\ngoog.provide('goog.vec.vec3d.Type');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n/** @typedef {!goog.vec.Float64} */ goog.vec.vec3d.Type;\n\n\n/**\n * Creates a vec3d with all elements initialized to zero.\n *\n * @return {!goog.vec.vec3d.Type} The new vec3d.\n */\ngoog.vec.vec3d.create = function() {\n 'use strict';\n return new Float64Array(3);\n};\n\n\n/**\n * Creates a new vec3d initialized with the value from the given array.\n *\n * @param {!Array} vec The source 3 element array.\n * @return {!goog.vec.vec3d.Type} The new vec3d.\n */\ngoog.vec.vec3d.createFromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec3d.create();\n goog.vec.vec3d.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new vec3d initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @return {!goog.vec.vec3d.Type} The new vector.\n */\ngoog.vec.vec3d.createFromValues = function(v0, v1, v2) {\n 'use strict';\n const vec = goog.vec.vec3d.create();\n goog.vec.vec3d.setFromValues(vec, v0, v1, v2);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given vec3d.\n *\n * @param {!goog.vec.vec3d.Type} vec The source vec3d.\n * @return {!goog.vec.vec3d.Type} The new cloned vec3d.\n */\ngoog.vec.vec3d.clone = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec3d.create();\n goog.vec.vec3d.setFromVec3d(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {!goog.vec.vec3d.Type} vec The vector to receive the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @return {!goog.vec.vec3d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.setFromValues = function(vec, v0, v1, v2) {\n 'use strict';\n vec[0] = v0;\n vec[1] = v1;\n vec[2] = v2;\n return vec;\n};\n\n\n/**\n * Initializes vec3d vec from vec3d src.\n *\n * @param {!goog.vec.vec3d.Type} vec The destination vector.\n * @param {!goog.vec.vec3d.Type} src The source vector.\n * @return {!goog.vec.vec3d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.setFromVec3d = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n return vec;\n};\n\n\n/**\n * Initializes vec3d vec from vec3f src (typed as a Float32Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.vec3d.Type} vec The destination vector.\n * @param {Float32Array} src The source vector.\n * @return {!goog.vec.vec3d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.setFromVec3f = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n return vec;\n};\n\n\n/**\n * Initializes vec3d vec from Array src.\n *\n * @param {!goog.vec.vec3d.Type} vec The destination vector.\n * @param {Array} src The source vector.\n * @return {!goog.vec.vec3d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.setFromArray = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The first addend.\n * @param {!goog.vec.vec3d.Type} vec1 The second addend.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n resultVec[2] = vec0[2] + vec1[2];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The minuend.\n * @param {!goog.vec.vec3d.Type} vec1 The subtrahend.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n resultVec[2] = vec0[2] - vec1[2];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The vector to negate.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n resultVec[2] = -vec0[2];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The source vector.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n resultVec[2] = Math.abs(vec0[2]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n resultVec[2] = vec0[2] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec3d.magnitudeSquared = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return x * x + y * y + z * z;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec3d.magnitude = function(vec0) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return Math.sqrt(x * x + y * y + z * z);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The vector to normalize.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.normalize = function(vec0, resultVec) {\n 'use strict';\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n const ilen = 1 / Math.sqrt(x * x + y * y + z * z);\n resultVec[0] = x * ilen;\n resultVec[1] = y * ilen;\n resultVec[2] = z * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors v0 and v1.\n *\n * @param {!goog.vec.vec3d.Type} v0 The first vector.\n * @param {!goog.vec.vec3d.Type} v1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.vec3d.dot = function(v0, v1) {\n 'use strict';\n return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];\n};\n\n\n/**\n * Computes the vector (cross) product of v0 and v1 storing the result into\n * resultVec.\n *\n * @param {!goog.vec.vec3d.Type} v0 The first vector.\n * @param {!goog.vec.vec3d.Type} v1 The second vector.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to receive the\n * results. May be either v0 or v1.\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.cross = function(v0, v1, resultVec) {\n 'use strict';\n const x0 = v0[0];\n const y0 = v0[1];\n const z0 = v0[2];\n\n const x1 = v1[0];\n const y1 = v1[1];\n const z1 = v1[2];\n\n resultVec[0] = y0 * z1 - z0 * y1;\n resultVec[1] = z0 * x1 - x0 * z1;\n resultVec[2] = x0 * y1 - y0 * x1;\n return resultVec;\n};\n\n\n/**\n * Returns the squared distance between two points.\n *\n * @param {!goog.vec.vec3d.Type} vec0 First point.\n * @param {!goog.vec.vec3d.Type} vec1 Second point.\n * @return {number} The squared distance between the points.\n */\ngoog.vec.vec3d.distanceSquared = function(vec0, vec1) {\n 'use strict';\n const x = vec0[0] - vec1[0];\n const y = vec0[1] - vec1[1];\n const z = vec0[2] - vec1[2];\n return x * x + y * y + z * z;\n};\n\n\n/**\n * Returns the distance between two points.\n *\n * @param {!goog.vec.vec3d.Type} vec0 First point.\n * @param {!goog.vec.vec3d.Type} vec1 Second point.\n * @return {number} The distance between the points.\n */\ngoog.vec.vec3d.distance = function(vec0, vec1) {\n 'use strict';\n return Math.sqrt(goog.vec.vec3d.distanceSquared(vec0, vec1));\n};\n\n\n/**\n * Returns a unit vector pointing from one point to another.\n * If the input points are equal then the result will be all zeros.\n *\n * @param {!goog.vec.vec3d.Type} vec0 Origin point.\n * @param {!goog.vec.vec3d.Type} vec1 Target point.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to receive the\n * results (may be vec0 or vec1).\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.direction = function(vec0, vec1, resultVec) {\n 'use strict';\n const x = vec1[0] - vec0[0];\n const y = vec1[1] - vec0[1];\n const z = vec1[2] - vec0[2];\n let d = Math.sqrt(x * x + y * y + z * z);\n if (d) {\n d = 1 / d;\n resultVec[0] = x * d;\n resultVec[1] = y * d;\n resultVec[2] = z * d;\n } else {\n resultVec[0] = resultVec[1] = resultVec[2] = 0;\n }\n return resultVec;\n};\n\n\n/**\n * Linearly interpolate from vec0 to v1 according to f. The value of f should be\n * in the range [0..1] otherwise the results are undefined.\n *\n * @param {!goog.vec.vec3d.Type} v0 The first vector.\n * @param {!goog.vec.vec3d.Type} v1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to receive the\n * results (may be v0 or v1).\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.lerp = function(v0, v1, f, resultVec) {\n 'use strict';\n const x = v0[0];\n const y = v0[1];\n const z = v0[2];\n\n resultVec[0] = (v1[0] - x) * f + x;\n resultVec[1] = (v1[1] - y) * f + y;\n resultVec[2] = (v1[2] - z) * f + z;\n return resultVec;\n};\n\n\n/**\n * Perform a spherical linear interpolation from v0 to v1 according to f. The\n * value of f should be in the range [0..1] otherwise the results are undefined.\n *\n * Slerp is normally used to interpolate quaternions, but there is a geometric\n * formula for interpolating vectors directly, see \"Geometric Slerp\" in:\n * https://en.wikipedia.org/wiki/Slerp.\n *\n * This interpolates the vectors' directions via slerp, but linearly\n * interpolates the vectors' magnitudes.\n *\n * Results are undefined if v0 or v1 are of zero magnitude.\n *\n * @param {!goog.vec.vec3d.Type} v0 The first vector.\n * @param {!goog.vec.vec3d.Type} v1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to receive the\n * results (may be v0 or v1).\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.slerp = function(v0, v1, f, resultVec) {\n 'use strict';\n const v0Magnitude = goog.vec.vec3d.magnitude(v0);\n let v1Magnitude = goog.vec.vec3d.magnitude(v1);\n\n let cosAngle = goog.vec.vec3d.dot(v0, v1) / (v0Magnitude * v1Magnitude);\n\n // If v0 and v1 are almost the same direction, fall back on a straight lerp.\n if (cosAngle > 1 - goog.vec.EPSILON) {\n return goog.vec.vec3d.lerp(v0, v1, f, resultVec);\n }\n\n let angle = 0;\n let sinAngle = 0;\n\n // If v0 and v1 are opposite directions, pick an arbitrary 'mid' vector that\n // is perpendicular to both, and slerp from v0 -> mid -> v1.\n if (cosAngle < -1 + goog.vec.EPSILON) {\n const mid = goog.vec.vec3d.create();\n let magnitudeFactor = (v0Magnitude + v1Magnitude) / 2;\n if (v0[0]) { // v0 not parallel to [0,0,1].\n magnitudeFactor /= Math.sqrt(v0[0] * v0[0] + v0[1] + v0[1]);\n mid[0] = -v0[1] * magnitudeFactor;\n mid[1] = v0[0] * magnitudeFactor;\n mid[2] = 0;\n } else { // v0 not parallel to [1,0,0].\n magnitudeFactor /= Math.sqrt(v0[2] * v0[2] + v0[1] + v0[1]);\n mid[0] = 0;\n mid[1] = -v0[2] * magnitudeFactor;\n mid[2] = v0[1] * magnitudeFactor;\n }\n\n // Depending on f, slerp between either v0 and mid, or mid and v1.\n if (f <= 0.5) {\n v1Magnitude = v0Magnitude;\n v1 = mid;\n f *= 2;\n } else {\n v0 = mid;\n f = 2 * f - 1;\n }\n\n angle = Math.PI / 2;\n cosAngle = 0;\n sinAngle = 1;\n } else {\n angle = Math.acos(cosAngle);\n sinAngle = Math.sqrt(1 - cosAngle * cosAngle);\n }\n\n const coeff0 = (Math.sin((1 - f) * angle) / sinAngle) / v0Magnitude;\n const coeff1 = (Math.sin(f * angle) / sinAngle) / v1Magnitude;\n const magnitude = (1 - f) * v0Magnitude + f * v1Magnitude;\n\n resultVec[0] = (v0[0] * coeff0 + v1[0] * coeff1) * magnitude;\n resultVec[1] = (v0[1] * coeff0 + v1[1] * coeff1) * magnitude;\n resultVec[2] = (v0[2] * coeff0 + v1[2] * coeff1) * magnitude;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The source vector.\n * @param {!goog.vec.vec3d.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n resultVec[2] = Math.max(vec0[2], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n resultVec[2] = Math.max(vec0[2], limit[2]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {!goog.vec.vec3d.Type} vec0 The source vector.\n * @param {!goog.vec.vec3d.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec3d.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n resultVec[2] = Math.min(vec0[2], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n resultVec[2] = Math.min(vec0[2], limit[2]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of v0 are equal to the components of v1.\n *\n * @param {!goog.vec.vec3d.Type} v0 The first vector.\n * @param {!goog.vec.vec3d.Type} v1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.vec3d.equals = function(v0, v1) {\n 'use strict';\n return v0.length == v1.length && v0[0] == v1[0] && v0[1] == v1[1] &&\n v0[2] == v1[2];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.vec3d","goog.vec.vec3d.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec3d.js"],"^[",["^3",["^1H","^1I"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.mat3d","~$goog.vec.mat3d.Type"]],"^5","goog.vec.mat3d.js","^6",["^7","goog/vec/mat3d.js"],"^8","goog/vec/mat3d.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to mat3f.js by running: //\n// swap_type.sh mat3d.js > mat3f.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 3x3 double (64bit)\n * matrices. The matrices are stored in column-major order.\n *\n * The last parameter will typically be the output object and an object\n * can be both an input and output parameter to all methods except where\n * noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\ngoog.provide('goog.vec.mat3d');\ngoog.provide('goog.vec.mat3d.Type');\n\ngoog.require('goog.vec');\ngoog.require('goog.vec.vec3d.Type');\n\n\n/** @typedef {!goog.vec.Float64} */ goog.vec.mat3d.Type;\n\n\n/**\n * Creates a mat3d with all elements initialized to zero.\n *\n * @return {!goog.vec.mat3d.Type} The new mat3d.\n */\ngoog.vec.mat3d.create = function() {\n 'use strict';\n return new Float64Array(9);\n};\n\n\n/**\n * Creates a mat3d identity matrix.\n *\n * @return {!goog.vec.mat3d.Type} The new mat3d.\n */\ngoog.vec.mat3d.createIdentity = function() {\n 'use strict';\n const mat = goog.vec.mat3d.create();\n mat[0] = mat[4] = mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Initializes the matrix from the set of values. Note the values supplied are\n * in column major order.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the\n * values.\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setFromValues = function(\n mat, v00, v10, v20, v01, v11, v21, v02, v12, v22) {\n 'use strict';\n mat[0] = v00;\n mat[1] = v10;\n mat[2] = v20;\n mat[3] = v01;\n mat[4] = v11;\n mat[5] = v21;\n mat[6] = v02;\n mat[7] = v12;\n mat[8] = v22;\n return mat;\n};\n\n\n/**\n * Initializes mat3d mat from mat3d src.\n *\n * @param {!goog.vec.mat3d.Type} mat The destination matrix.\n * @param {!goog.vec.mat3d.Type} src The source matrix.\n * @return {!goog.vec.mat3d.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setFromMat3d = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n return mat;\n};\n\n\n/**\n * Initializes mat3d mat from mat3f src (typed as a Float32Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.mat3d.Type} mat The destination matrix.\n * @param {Float32Array} src The source matrix.\n * @return {!goog.vec.mat3d.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setFromMat3f = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n return mat;\n};\n\n\n/**\n * Initializes mat3d mat from Array src.\n *\n * @param {!goog.vec.mat3d.Type} mat The destination matrix.\n * @param {Array} src The source matrix.\n * @return {!goog.vec.mat3d.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setFromArray = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n return mat;\n};\n\n\n/**\n * Retrieves the element at the requested row and column.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @return {number} The element value at the requested row, column indices.\n */\ngoog.vec.mat3d.getElement = function(mat, row, column) {\n 'use strict';\n return mat[row + column * 3];\n};\n\n\n/**\n * Sets the element at the requested row and column.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @param {number} value The value to set at the requested row, column.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setElement = function(mat, row, column, value) {\n 'use strict';\n mat[row + column * 3] = value;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given values.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the values.\n * @param {number} v00 The values for (0, 0).\n * @param {number} v11 The values for (1, 1).\n * @param {number} v22 The values for (2, 2).\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setDiagonalValues = function(mat, v00, v11, v22) {\n 'use strict';\n mat[0] = v00;\n mat[4] = v11;\n mat[8] = v22;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given vector.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec3d.Type} vec The vector containing the values.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setDiagonal = function(mat, vec) {\n 'use strict';\n mat[0] = vec[0];\n mat[4] = vec[1];\n mat[8] = vec[2];\n return mat;\n};\n\n\n/**\n * Sets the specified column with the supplied values.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {number} v0 The value for row 0.\n * @param {number} v1 The value for row 1.\n * @param {number} v2 The value for row 2.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setColumnValues = function(mat, column, v0, v1, v2) {\n 'use strict';\n const i = column * 3;\n mat[i] = v0;\n mat[i + 1] = v1;\n mat[i + 2] = v2;\n return mat;\n};\n\n\n/**\n * Sets the specified column with the value from the supplied array.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {!goog.vec.vec3d.Type} vec The vector elements for the column.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 3;\n mat[i] = vec[0];\n mat[i + 1] = vec[1];\n mat[i + 2] = vec[2];\n return mat;\n};\n\n\n/**\n * Retrieves the specified column from the matrix into the given vector\n * array.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix supplying the values.\n * @param {number} column The column to get the values from.\n * @param {!goog.vec.vec3d.Type} vec The vector elements to receive the\n * column.\n * @return {!goog.vec.vec3d.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.getColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 3;\n vec[0] = mat[i];\n vec[1] = mat[i + 1];\n vec[2] = mat[i + 2];\n return vec;\n};\n\n\n/**\n * Sets the columns of the matrix from the set of vector elements.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec3d.Type} vec0 The values for column 0.\n * @param {!goog.vec.vec3d.Type} vec1 The values for column 1.\n * @param {!goog.vec.vec3d.Type} vec2 The values for column 2.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setColumns = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.mat3d.setColumn(mat, 0, vec0);\n goog.vec.mat3d.setColumn(mat, 1, vec1);\n goog.vec.mat3d.setColumn(mat, 2, vec2);\n return /** @type {!goog.vec.mat3d.Type} */ (mat);\n};\n\n\n/**\n * Retrieves the column values from the given matrix into the given vector\n * elements.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix supplying the columns.\n * @param {!goog.vec.vec3d.Type} vec0 The vector to receive column 0.\n * @param {!goog.vec.vec3d.Type} vec1 The vector to receive column 1.\n * @param {!goog.vec.vec3d.Type} vec2 The vector to receive column 2.\n */\ngoog.vec.mat3d.getColumns = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.mat3d.getColumn(mat, 0, vec0);\n goog.vec.mat3d.getColumn(mat, 1, vec1);\n goog.vec.mat3d.getColumn(mat, 2, vec2);\n};\n\n\n/**\n * Sets the row values from the supplied values.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the values.\n * @param {number} row The index of the row to receive the values.\n * @param {number} v0 The value for column 0.\n * @param {number} v1 The value for column 1.\n * @param {number} v2 The value for column 2.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setRowValues = function(mat, row, v0, v1, v2) {\n 'use strict';\n mat[row] = v0;\n mat[row + 3] = v1;\n mat[row + 6] = v2;\n return mat;\n};\n\n\n/**\n * Sets the row values from the supplied vector.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the row values.\n * @param {number} row The index of the row.\n * @param {!goog.vec.vec3d.Type} vec The vector containing the values.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setRow = function(mat, row, vec) {\n 'use strict';\n mat[row] = vec[0];\n mat[row + 3] = vec[1];\n mat[row + 6] = vec[2];\n return mat;\n};\n\n\n/**\n * Retrieves the row values into the given vector.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix supplying the values.\n * @param {number} row The index of the row supplying the values.\n * @param {!goog.vec.vec3d.Type} vec The vector to receive the row.\n * @return {!goog.vec.vec3d.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.getRow = function(mat, row, vec) {\n 'use strict';\n vec[0] = mat[row];\n vec[1] = mat[row + 3];\n vec[2] = mat[row + 6];\n return vec;\n};\n\n\n/**\n * Sets the rows of the matrix from the supplied vectors.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec3d.Type} vec0 The values for row 0.\n * @param {!goog.vec.vec3d.Type} vec1 The values for row 1.\n * @param {!goog.vec.vec3d.Type} vec2 The values for row 2.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.setRows = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.mat3d.setRow(mat, 0, vec0);\n goog.vec.mat3d.setRow(mat, 1, vec1);\n goog.vec.mat3d.setRow(mat, 2, vec2);\n return /** @type {!goog.vec.mat3d.Type} */ (mat);\n};\n\n\n/**\n * Retrieves the rows of the matrix into the supplied vectors.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to supplying the values.\n * @param {!goog.vec.vec3d.Type} vec0 The vector to receive row 0.\n * @param {!goog.vec.vec3d.Type} vec1 The vector to receive row 1.\n * @param {!goog.vec.vec3d.Type} vec2 The vector to receive row 2.\n */\ngoog.vec.mat3d.getRows = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.mat3d.getRow(mat, 0, vec0);\n goog.vec.mat3d.getRow(mat, 1, vec1);\n goog.vec.mat3d.getRow(mat, 2, vec2);\n};\n\n\n/**\n * Makes the given 3x3 matrix the zero matrix.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @return {!goog.vec.mat3d.Type} return mat so operations can be chained.\n */\ngoog.vec.mat3d.makeZero = function(mat) {\n 'use strict';\n mat[0] = 0;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix the identity matrix.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @return {!goog.vec.mat3d.Type} return mat so operations can be chained.\n */\ngoog.vec.mat3d.makeIdentity = function(mat) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 1;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Performs a per-component addition of the matrices mat0 and mat1, storing\n * the result into resultMat.\n *\n * @param {!goog.vec.mat3d.Type} mat0 The first addend.\n * @param {!goog.vec.mat3d.Type} mat1 The second addend.\n * @param {!goog.vec.mat3d.Type} resultMat The matrix to\n * receive the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat3d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.addMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] + mat1[0];\n resultMat[1] = mat0[1] + mat1[1];\n resultMat[2] = mat0[2] + mat1[2];\n resultMat[3] = mat0[3] + mat1[3];\n resultMat[4] = mat0[4] + mat1[4];\n resultMat[5] = mat0[5] + mat1[5];\n resultMat[6] = mat0[6] + mat1[6];\n resultMat[7] = mat0[7] + mat1[7];\n resultMat[8] = mat0[8] + mat1[8];\n return resultMat;\n};\n\n\n/**\n * Performs a per-component subtraction of the matrices mat0 and mat1,\n * storing the result into resultMat.\n *\n * @param {!goog.vec.mat3d.Type} mat0 The minuend.\n * @param {!goog.vec.mat3d.Type} mat1 The subtrahend.\n * @param {!goog.vec.mat3d.Type} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat3d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.subMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] - mat1[0];\n resultMat[1] = mat0[1] - mat1[1];\n resultMat[2] = mat0[2] - mat1[2];\n resultMat[3] = mat0[3] - mat1[3];\n resultMat[4] = mat0[4] - mat1[4];\n resultMat[5] = mat0[5] - mat1[5];\n resultMat[6] = mat0[6] - mat1[6];\n resultMat[7] = mat0[7] - mat1[7];\n resultMat[8] = mat0[8] - mat1[8];\n return resultMat;\n};\n\n\n/**\n * Multiplies matrix mat0 with the given scalar, storing the result\n * into resultMat.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} scalar The scalar value to multiple to each element of mat.\n * @param {!goog.vec.mat3d.Type} resultMat The matrix to receive\n * the results (may be mat).\n * @return {!goog.vec.mat3d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.multScalar = function(mat, scalar, resultMat) {\n 'use strict';\n resultMat[0] = mat[0] * scalar;\n resultMat[1] = mat[1] * scalar;\n resultMat[2] = mat[2] * scalar;\n resultMat[3] = mat[3] * scalar;\n resultMat[4] = mat[4] * scalar;\n resultMat[5] = mat[5] * scalar;\n resultMat[6] = mat[6] * scalar;\n resultMat[7] = mat[7] * scalar;\n resultMat[8] = mat[8] * scalar;\n return resultMat;\n};\n\n\n/**\n * Multiplies the two matrices mat0 and mat1 using matrix multiplication,\n * storing the result into resultMat.\n *\n * @param {!goog.vec.mat3d.Type} mat0 The first (left hand) matrix.\n * @param {!goog.vec.mat3d.Type} mat1 The second (right hand) matrix.\n * @param {!goog.vec.mat3d.Type} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat3d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.multMat = function(mat0, mat1, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n\n const a01 = mat0[3];\n const a11 = mat0[4];\n const a21 = mat0[5];\n\n const a02 = mat0[6];\n const a12 = mat0[7];\n const a22 = mat0[8];\n\n\n const b00 = mat1[0];\n const b10 = mat1[1];\n const b20 = mat1[2];\n\n const b01 = mat1[3];\n const b11 = mat1[4];\n const b21 = mat1[5];\n\n const b02 = mat1[6];\n const b12 = mat1[7];\n const b22 = mat1[8];\n\n\n resultMat[0] = a00 * b00 + a01 * b10 + a02 * b20;\n resultMat[1] = a10 * b00 + a11 * b10 + a12 * b20;\n resultMat[2] = a20 * b00 + a21 * b10 + a22 * b20;\n resultMat[3] = a00 * b01 + a01 * b11 + a02 * b21;\n resultMat[4] = a10 * b01 + a11 * b11 + a12 * b21;\n resultMat[5] = a20 * b01 + a21 * b11 + a22 * b21;\n resultMat[6] = a00 * b02 + a01 * b12 + a02 * b22;\n resultMat[7] = a10 * b02 + a11 * b12 + a12 * b22;\n resultMat[8] = a20 * b02 + a21 * b12 + a22 * b22;\n return resultMat;\n};\n\n\n/**\n * Transposes the given matrix mat storing the result into resultMat.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix to transpose.\n * @param {!goog.vec.mat3d.Type} resultMat The matrix to receive\n * the results (may be mat).\n * @return {!goog.vec.mat3d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.transpose = function(mat, resultMat) {\n 'use strict';\n if (resultMat == mat) {\n const a10 = mat[1];\n const a20 = mat[2];\n const a21 = mat[5];\n\n resultMat[1] = mat[3];\n resultMat[2] = mat[6];\n resultMat[3] = a10;\n resultMat[5] = mat[7];\n resultMat[6] = a20;\n resultMat[7] = a21;\n } else {\n resultMat[0] = mat[0];\n resultMat[1] = mat[3];\n resultMat[2] = mat[6];\n resultMat[3] = mat[1];\n resultMat[4] = mat[4];\n resultMat[5] = mat[7];\n resultMat[6] = mat[2];\n resultMat[7] = mat[5];\n resultMat[8] = mat[8];\n }\n return resultMat;\n};\n\n\n/**\n * Computes the inverse of mat0 storing the result into resultMat. If the\n * inverse is defined, this function returns true, false otherwise.\n *\n * @param {!goog.vec.mat3d.Type} mat0 The matrix to invert.\n * @param {!goog.vec.mat3d.Type} resultMat The matrix to receive\n * the result (may be mat0).\n * @return {boolean} True if the inverse is defined. If false is returned,\n * resultMat is not modified.\n */\ngoog.vec.mat3d.invert = function(mat0, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n\n const a01 = mat0[3];\n const a11 = mat0[4];\n const a21 = mat0[5];\n\n const a02 = mat0[6];\n const a12 = mat0[7];\n const a22 = mat0[8];\n\n\n const t00 = a11 * a22 - a12 * a21;\n const t10 = a12 * a20 - a10 * a22;\n const t20 = a10 * a21 - a11 * a20;\n const det = a00 * t00 + a01 * t10 + a02 * t20;\n if (det == 0) {\n return false;\n }\n\n const idet = 1 / det;\n resultMat[0] = t00 * idet;\n resultMat[3] = (a02 * a21 - a01 * a22) * idet;\n resultMat[6] = (a01 * a12 - a02 * a11) * idet;\n\n resultMat[1] = t10 * idet;\n resultMat[4] = (a00 * a22 - a02 * a20) * idet;\n resultMat[7] = (a02 * a10 - a00 * a12) * idet;\n\n resultMat[2] = t20 * idet;\n resultMat[5] = (a01 * a20 - a00 * a21) * idet;\n resultMat[8] = (a00 * a11 - a01 * a10) * idet;\n return true;\n};\n\n\n/**\n * Returns true if the components of mat0 are equal to the components of mat1.\n *\n * @param {!goog.vec.mat3d.Type} mat0 The first matrix.\n * @param {!goog.vec.mat3d.Type} mat1 The second matrix.\n * @return {boolean} True if the two matrices are equivalent.\n */\ngoog.vec.mat3d.equals = function(mat0, mat1) {\n 'use strict';\n return mat0.length == mat1.length && mat0[0] == mat1[0] &&\n mat0[1] == mat1[1] && mat0[2] == mat1[2] && mat0[3] == mat1[3] &&\n mat0[4] == mat1[4] && mat0[5] == mat1[5] && mat0[6] == mat1[6] &&\n mat0[7] == mat1[7] && mat0[8] == mat1[8];\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed matrix into resultVec.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec3d.Type} vec The vector to transform.\n * @param {!goog.vec.vec3d.Type} resultVec The vector to\n * receive the results (may be vec).\n * @return {!goog.vec.vec3d.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.multVec3 = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[3] + z * mat[6];\n resultVec[1] = x * mat[1] + y * mat[4] + z * mat[7];\n resultVec[2] = x * mat[2] + y * mat[5] + z * mat[8];\n return resultVec;\n};\n\n\n/**\n * Makes the given 3x3 matrix a translation matrix with x and y\n * translation values.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.makeTranslate = function(mat, x, y) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 1;\n mat[5] = 0;\n mat[6] = x;\n mat[7] = y;\n mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a scale matrix with x, y, and z scale factors.\n *\n * @param {!goog.vec.mat3d.Type} mat The 3x3 (9-element) matrix\n * array to receive the new scale matrix.\n * @param {number} x The scale along the x axis.\n * @param {number} y The scale along the y axis.\n * @param {number} z The scale along the z axis.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.makeScale = function(mat, x, y, z) {\n 'use strict';\n mat[0] = x;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = y;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = z;\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the axis defined by the vector (ax, ay, az).\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @param {number} ax The x component of the rotation axis.\n * @param {number} ay The y component of the rotation axis.\n * @param {number} az The z component of the rotation axis.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.makeRotate = function(mat, angle, ax, ay, az) {\n 'use strict';\n const c = Math.cos(angle);\n const d = 1 - c;\n const s = Math.sin(angle);\n\n mat[0] = ax * ax * d + c;\n mat[1] = ax * ay * d + az * s;\n mat[2] = ax * az * d - ay * s;\n mat[3] = ax * ay * d - az * s;\n mat[4] = ay * ay * d + c;\n mat[5] = ay * az * d + ax * s;\n mat[6] = ax * az * d + ay * s;\n mat[7] = ay * az * d - ax * s;\n mat[8] = az * az * d + c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the X axis.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.makeRotateX = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = c;\n mat[5] = s;\n mat[6] = 0;\n mat[7] = -s;\n mat[8] = c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the Y axis.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.makeRotateY = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = c;\n mat[1] = 0;\n mat[2] = -s;\n mat[3] = 0;\n mat[4] = 1;\n mat[5] = 0;\n mat[6] = s;\n mat[7] = 0;\n mat[8] = c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the Z axis.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.makeRotateZ = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = c;\n mat[1] = s;\n mat[2] = 0;\n mat[3] = -s;\n mat[4] = c;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 1;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the x,y,z axis. Equivalent to:\n * goog.vec.mat3d.multMat(\n * mat,\n * goog.vec.mat3d.makeRotate(goog.vec.mat3d.create(), angle, x, y, z),\n * mat);\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @param {number} x The x component of the rotation axis.\n * @param {number} y The y component of the rotation axis.\n * @param {number} z The z component of the rotation axis.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.rotate = function(mat, angle, x, y, z) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const cosAngle = Math.cos(angle);\n const sinAngle = Math.sin(angle);\n const diffCosAngle = 1 - cosAngle;\n const r00 = x * x * diffCosAngle + cosAngle;\n const r10 = x * y * diffCosAngle + z * sinAngle;\n const r20 = x * z * diffCosAngle - y * sinAngle;\n\n const r01 = x * y * diffCosAngle - z * sinAngle;\n const r11 = y * y * diffCosAngle + cosAngle;\n const r21 = y * z * diffCosAngle + x * sinAngle;\n\n const r02 = x * z * diffCosAngle + y * sinAngle;\n const r12 = y * z * diffCosAngle - x * sinAngle;\n const r22 = z * z * diffCosAngle + cosAngle;\n\n mat[0] = m00 * r00 + m01 * r10 + m02 * r20;\n mat[1] = m10 * r00 + m11 * r10 + m12 * r20;\n mat[2] = m20 * r00 + m21 * r10 + m22 * r20;\n mat[3] = m00 * r01 + m01 * r11 + m02 * r21;\n mat[4] = m10 * r01 + m11 * r11 + m12 * r21;\n mat[5] = m20 * r01 + m21 * r11 + m22 * r21;\n mat[6] = m00 * r02 + m01 * r12 + m02 * r22;\n mat[7] = m10 * r02 + m11 * r12 + m12 * r22;\n mat[8] = m20 * r02 + m21 * r12 + m22 * r22;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the x axis. Equivalent to:\n * goog.vec.mat3d.multMat(\n * mat,\n * goog.vec.mat3d.makeRotateX(goog.vec.mat3d.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.rotateX = function(mat, angle) {\n 'use strict';\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[3] = m01 * c + m02 * s;\n mat[4] = m11 * c + m12 * s;\n mat[5] = m21 * c + m22 * s;\n mat[6] = m01 * -s + m02 * c;\n mat[7] = m11 * -s + m12 * c;\n mat[8] = m21 * -s + m22 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the y axis. Equivalent to:\n * goog.vec.mat3d.multMat(\n * mat,\n * goog.vec.mat3d.makeRotateY(goog.vec.mat3d.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.rotateY = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m02 * -s;\n mat[1] = m10 * c + m12 * -s;\n mat[2] = m20 * c + m22 * -s;\n mat[6] = m00 * s + m02 * c;\n mat[7] = m10 * s + m12 * c;\n mat[8] = m20 * s + m22 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the z axis. Equivalent to:\n * goog.vec.mat3d.multMat(\n * mat,\n * goog.vec.mat3d.makeRotateZ(goog.vec.mat3d.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.rotateZ = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m01 * s;\n mat[1] = m10 * c + m11 * s;\n mat[2] = m20 * c + m21 * s;\n mat[3] = m00 * -s + m01 * c;\n mat[4] = m10 * -s + m11 * c;\n mat[5] = m20 * -s + m21 * c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix given Euler angles using\n * the ZXZ convention.\n * Given the euler angles [theta1, theta2, theta3], the rotation is defined as\n * rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {number} theta1 The angle of rotation around the Z axis in radians.\n * @param {number} theta2 The angle of rotation around the X axis in radians.\n * @param {number} theta3 The angle of rotation around the Z axis in radians.\n * @return {!goog.vec.mat3d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3d.makeEulerZXZ = function(mat, theta1, theta2, theta3) {\n 'use strict';\n const c1 = Math.cos(theta1);\n const s1 = Math.sin(theta1);\n\n const c2 = Math.cos(theta2);\n const s2 = Math.sin(theta2);\n\n const c3 = Math.cos(theta3);\n const s3 = Math.sin(theta3);\n\n mat[0] = c1 * c3 - c2 * s1 * s3;\n mat[1] = c2 * c1 * s3 + c3 * s1;\n mat[2] = s3 * s2;\n\n mat[3] = -c1 * s3 - c3 * c2 * s1;\n mat[4] = c1 * c2 * c3 - s1 * s3;\n mat[5] = c3 * s2;\n\n mat[6] = s2 * s1;\n mat[7] = -c1 * s2;\n mat[8] = c2;\n\n return mat;\n};\n\n\n/**\n * Decomposes a rotation matrix into Euler angles using the ZXZ convention so\n * that rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {!goog.vec.mat3d.Type} mat The matrix.\n * @param {!goog.vec.vec3d.Type} euler The ZXZ Euler angles in\n * radians as [theta1, theta2, theta3].\n * @param {boolean=} opt_theta2IsNegative Whether theta2 is in [-pi, 0] instead\n * of the default [0, pi].\n * @return {!goog.vec.vec3d.Type} return euler so that operations can be\n * chained together.\n */\ngoog.vec.mat3d.toEulerZXZ = function(mat, euler, opt_theta2IsNegative) {\n 'use strict';\n // There is an ambiguity in the sign of sinTheta2 because of the sqrt.\n const sinTheta2 = Math.sqrt(mat[2] * mat[2] + mat[5] * mat[5]);\n\n // By default we explicitely constrain theta2 to be in [0, pi],\n // so sinTheta2 is always positive. We can change the behavior and specify\n // theta2 to be negative in [-pi, 0] with opt_Theta2IsNegative.\n const signTheta2 = opt_theta2IsNegative ? -1 : 1;\n\n if (sinTheta2 > goog.vec.EPSILON) {\n euler[2] = Math.atan2(mat[2] * signTheta2, mat[5] * signTheta2);\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[8]);\n euler[0] = Math.atan2(mat[6] * signTheta2, -mat[7] * signTheta2);\n } else {\n // There is also an arbitrary choice for theta1 = 0 or theta2 = 0 here.\n // We assume theta1 = 0 as some applications do not allow the camera to roll\n // (i.e. have theta1 != 0).\n euler[0] = 0;\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[8]);\n euler[2] = Math.atan2(mat[1], mat[0]);\n }\n\n // Atan2 outputs angles in [-pi, pi] so we bring them back to [0, 2 * pi].\n euler[0] = (euler[0] + Math.PI * 2) % (Math.PI * 2);\n euler[2] = (euler[2] + Math.PI * 2) % (Math.PI * 2);\n // For theta2 we want the angle to be in [0, pi] or [-pi, 0] depending on\n // signTheta2.\n euler[1] =\n ((euler[1] * signTheta2 + Math.PI * 2) % (Math.PI * 2)) * signTheta2;\n\n return euler;\n};\n","^<",1684857788697,"^=",["^3",["^1H","^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^1H","^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.mat3d","goog.vec.mat3d.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec","goog.vec.vec3d.Type"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/mat3d.js"],"^[",["^3",["^1J","^1K"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14","^1H"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.mat4f","~$goog.vec.mat4f.Type"]],"^5","goog.vec.mat4f.js","^6",["^7","goog/vec/mat4f.js"],"^8","goog/vec/mat4f.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to mat4d.js by running: //\n// swap_type.sh mat4f.js > mat4d.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 4x4 float (32bit)\n * matrices. The matrices are stored in column-major order.\n *\n * The last parameter will typically be the output matrix and an\n * object can be both an input and output parameter to all methods except\n * where noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\ngoog.provide('goog.vec.mat4f');\ngoog.provide('goog.vec.mat4f.Type');\n\ngoog.require('goog.vec');\n/** @suppress {extraRequire} */\ngoog.require('goog.vec.Quaternion');\ngoog.require('goog.vec.vec3f');\ngoog.require('goog.vec.vec4f');\n\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.mat4f.Type;\n\n\n/**\n * Creates a mat4f with all elements initialized to zero.\n *\n * @return {!goog.vec.mat4f.Type} The new mat4f.\n */\ngoog.vec.mat4f.create = function() {\n 'use strict';\n return new Float32Array(16);\n};\n\n\n/**\n * Creates a mat4f identity matrix.\n *\n * @return {!goog.vec.mat4f.Type} The new mat4f.\n */\ngoog.vec.mat4f.createIdentity = function() {\n 'use strict';\n const mat = goog.vec.mat4f.create();\n mat[0] = mat[5] = mat[10] = mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Initializes the matrix from the set of values. Note the values supplied are\n * in column major order.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the\n * values.\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v30 The values at (3, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v31 The values at (3, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @param {number} v32 The values at (3, 2).\n * @param {number} v03 The values at (0, 3).\n * @param {number} v13 The values at (1, 3).\n * @param {number} v23 The values at (2, 3).\n * @param {number} v33 The values at (3, 3).\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setFromValues = function(\n mat, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13,\n v23, v33) {\n 'use strict';\n mat[0] = v00;\n mat[1] = v10;\n mat[2] = v20;\n mat[3] = v30;\n mat[4] = v01;\n mat[5] = v11;\n mat[6] = v21;\n mat[7] = v31;\n mat[8] = v02;\n mat[9] = v12;\n mat[10] = v22;\n mat[11] = v32;\n mat[12] = v03;\n mat[13] = v13;\n mat[14] = v23;\n mat[15] = v33;\n return mat;\n};\n\n\n/**\n * Initializes mat4f mat from mat4f src.\n *\n * @param {!goog.vec.mat4f.Type} mat The destination matrix.\n * @param {!goog.vec.mat4f.Type} src The source matrix.\n * @return {!goog.vec.mat4f.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setFromMat4f = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n mat[9] = src[9];\n mat[10] = src[10];\n mat[11] = src[11];\n mat[12] = src[12];\n mat[13] = src[13];\n mat[14] = src[14];\n mat[15] = src[15];\n return mat;\n};\n\n\n/**\n * Initializes mat4f mat from mat4d src (typed as a Float64Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.mat4f.Type} mat The destination matrix.\n * @param {Float64Array} src The source matrix.\n * @return {!goog.vec.mat4f.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setFromMat4d = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n mat[9] = src[9];\n mat[10] = src[10];\n mat[11] = src[11];\n mat[12] = src[12];\n mat[13] = src[13];\n mat[14] = src[14];\n mat[15] = src[15];\n return mat;\n};\n\n\n/**\n * Initializes mat4f mat from Array src.\n *\n * @param {!goog.vec.mat4f.Type} mat The destination matrix.\n * @param {Array} src The source matrix.\n * @return {!goog.vec.mat4f.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setFromArray = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n mat[9] = src[9];\n mat[10] = src[10];\n mat[11] = src[11];\n mat[12] = src[12];\n mat[13] = src[13];\n mat[14] = src[14];\n mat[15] = src[15];\n return mat;\n};\n\n\n/**\n * Retrieves the element at the requested row and column.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @return {number} The element value at the requested row, column indices.\n */\ngoog.vec.mat4f.getElement = function(mat, row, column) {\n 'use strict';\n return mat[row + column * 4];\n};\n\n\n/**\n * Sets the element at the requested row and column.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @param {number} value The value to set at the requested row, column.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setElement = function(mat, row, column, value) {\n 'use strict';\n mat[row + column * 4] = value;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given values.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the values.\n * @param {number} v00 The values for (0, 0).\n * @param {number} v11 The values for (1, 1).\n * @param {number} v22 The values for (2, 2).\n * @param {number} v33 The values for (3, 3).\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setDiagonalValues = function(mat, v00, v11, v22, v33) {\n 'use strict';\n mat[0] = v00;\n mat[5] = v11;\n mat[10] = v22;\n mat[15] = v33;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given vector.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec4f.Type} vec The vector containing the values.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setDiagonal = function(mat, vec) {\n 'use strict';\n mat[0] = vec[0];\n mat[5] = vec[1];\n mat[10] = vec[2];\n mat[15] = vec[3];\n return mat;\n};\n\n\n/**\n * Gets the diagonal values of the matrix into the given vector.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix containing the values.\n * @param {!goog.vec.vec4f.Type} vec The vector to receive the values.\n * @param {number=} opt_diagonal Which diagonal to get. A value of 0 selects the\n * main diagonal, a positive number selects a super diagonal and a negative\n * number selects a sub diagonal.\n * @return {!goog.vec.vec4f.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.getDiagonal = function(mat, vec, opt_diagonal) {\n 'use strict';\n if (!opt_diagonal) {\n // This is the most common case, so we avoid the for loop.\n vec[0] = mat[0];\n vec[1] = mat[5];\n vec[2] = mat[10];\n vec[3] = mat[15];\n } else {\n const offset = opt_diagonal > 0 ? 4 * opt_diagonal : -opt_diagonal;\n for (let i = 0; i < 4 - Math.abs(opt_diagonal); i++) {\n vec[i] = mat[offset + 5 * i];\n }\n }\n return vec;\n};\n\n\n/**\n * Sets the specified column with the supplied values.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {number} v0 The value for row 0.\n * @param {number} v1 The value for row 1.\n * @param {number} v2 The value for row 2.\n * @param {number} v3 The value for row 3.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setColumnValues = function(mat, column, v0, v1, v2, v3) {\n 'use strict';\n const i = column * 4;\n mat[i] = v0;\n mat[i + 1] = v1;\n mat[i + 2] = v2;\n mat[i + 3] = v3;\n return mat;\n};\n\n\n/**\n * Sets the specified column with the value from the supplied vector.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {!goog.vec.vec4f.Type} vec The vector of elements for the column.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 4;\n mat[i] = vec[0];\n mat[i + 1] = vec[1];\n mat[i + 2] = vec[2];\n mat[i + 3] = vec[3];\n return mat;\n};\n\n\n/**\n * Retrieves the specified column from the matrix into the given vector.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix supplying the values.\n * @param {number} column The column to get the values from.\n * @param {!goog.vec.vec4f.Type} vec The vector of elements to\n * receive the column.\n * @return {!goog.vec.vec4f.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.getColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 4;\n vec[0] = mat[i];\n vec[1] = mat[i + 1];\n vec[2] = mat[i + 2];\n vec[3] = mat[i + 3];\n return vec;\n};\n\n\n/**\n * Sets the columns of the matrix from the given vectors.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec4f.Type} vec0 The values for column 0.\n * @param {!goog.vec.vec4f.Type} vec1 The values for column 1.\n * @param {!goog.vec.vec4f.Type} vec2 The values for column 2.\n * @param {!goog.vec.vec4f.Type} vec3 The values for column 3.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setColumns = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n mat[0] = vec0[0];\n mat[1] = vec0[1];\n mat[2] = vec0[2];\n mat[3] = vec0[3];\n mat[4] = vec1[0];\n mat[5] = vec1[1];\n mat[6] = vec1[2];\n mat[7] = vec1[3];\n mat[8] = vec2[0];\n mat[9] = vec2[1];\n mat[10] = vec2[2];\n mat[11] = vec2[3];\n mat[12] = vec3[0];\n mat[13] = vec3[1];\n mat[14] = vec3[2];\n mat[15] = vec3[3];\n return mat;\n};\n\n\n/**\n * Retrieves the column values from the given matrix into the given vectors.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix supplying the columns.\n * @param {!goog.vec.vec4f.Type} vec0 The vector to receive column 0.\n * @param {!goog.vec.vec4f.Type} vec1 The vector to receive column 1.\n * @param {!goog.vec.vec4f.Type} vec2 The vector to receive column 2.\n * @param {!goog.vec.vec4f.Type} vec3 The vector to receive column 3.\n */\ngoog.vec.mat4f.getColumns = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n vec0[0] = mat[0];\n vec0[1] = mat[1];\n vec0[2] = mat[2];\n vec0[3] = mat[3];\n vec1[0] = mat[4];\n vec1[1] = mat[5];\n vec1[2] = mat[6];\n vec1[3] = mat[7];\n vec2[0] = mat[8];\n vec2[1] = mat[9];\n vec2[2] = mat[10];\n vec2[3] = mat[11];\n vec3[0] = mat[12];\n vec3[1] = mat[13];\n vec3[2] = mat[14];\n vec3[3] = mat[15];\n};\n\n\n/**\n * Sets the row values from the supplied values.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the values.\n * @param {number} row The index of the row to receive the values.\n * @param {number} v0 The value for column 0.\n * @param {number} v1 The value for column 1.\n * @param {number} v2 The value for column 2.\n * @param {number} v3 The value for column 3.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setRowValues = function(mat, row, v0, v1, v2, v3) {\n 'use strict';\n mat[row] = v0;\n mat[row + 4] = v1;\n mat[row + 8] = v2;\n mat[row + 12] = v3;\n return mat;\n};\n\n\n/**\n * Sets the row values from the supplied vector.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the row values.\n * @param {number} row The index of the row.\n * @param {!goog.vec.vec4f.Type} vec The vector containing the values.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setRow = function(mat, row, vec) {\n 'use strict';\n mat[row] = vec[0];\n mat[row + 4] = vec[1];\n mat[row + 8] = vec[2];\n mat[row + 12] = vec[3];\n return mat;\n};\n\n\n/**\n * Retrieves the row values into the given vector.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix supplying the values.\n * @param {number} row The index of the row supplying the values.\n * @param {!goog.vec.vec4f.Type} vec The vector to receive the row.\n * @return {!goog.vec.vec4f.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.getRow = function(mat, row, vec) {\n 'use strict';\n vec[0] = mat[row];\n vec[1] = mat[row + 4];\n vec[2] = mat[row + 8];\n vec[3] = mat[row + 12];\n return vec;\n};\n\n\n/**\n * Sets the rows of the matrix from the supplied vectors.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec4f.Type} vec0 The values for row 0.\n * @param {!goog.vec.vec4f.Type} vec1 The values for row 1.\n * @param {!goog.vec.vec4f.Type} vec2 The values for row 2.\n * @param {!goog.vec.vec4f.Type} vec3 The values for row 3.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.setRows = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n mat[0] = vec0[0];\n mat[1] = vec1[0];\n mat[2] = vec2[0];\n mat[3] = vec3[0];\n mat[4] = vec0[1];\n mat[5] = vec1[1];\n mat[6] = vec2[1];\n mat[7] = vec3[1];\n mat[8] = vec0[2];\n mat[9] = vec1[2];\n mat[10] = vec2[2];\n mat[11] = vec3[2];\n mat[12] = vec0[3];\n mat[13] = vec1[3];\n mat[14] = vec2[3];\n mat[15] = vec3[3];\n return mat;\n};\n\n\n/**\n * Retrieves the rows of the matrix into the supplied vectors.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to supply the values.\n * @param {!goog.vec.vec4f.Type} vec0 The vector to receive row 0.\n * @param {!goog.vec.vec4f.Type} vec1 The vector to receive row 1.\n * @param {!goog.vec.vec4f.Type} vec2 The vector to receive row 2.\n * @param {!goog.vec.vec4f.Type} vec3 The vector to receive row 3.\n */\ngoog.vec.mat4f.getRows = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n vec0[0] = mat[0];\n vec1[0] = mat[1];\n vec2[0] = mat[2];\n vec3[0] = mat[3];\n vec0[1] = mat[4];\n vec1[1] = mat[5];\n vec2[1] = mat[6];\n vec3[1] = mat[7];\n vec0[2] = mat[8];\n vec1[2] = mat[9];\n vec2[2] = mat[10];\n vec3[2] = mat[11];\n vec0[3] = mat[12];\n vec1[3] = mat[13];\n vec2[3] = mat[14];\n vec3[3] = mat[15];\n};\n\n\n/**\n * Makes the given 4x4 matrix the zero matrix.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @return {!goog.vec.mat4f.Type} return mat so operations can be chained.\n */\ngoog.vec.mat4f.makeZero = function(mat) {\n 'use strict';\n mat[0] = 0;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 0;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 0;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix the identity matrix.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @return {!goog.vec.mat4f.Type} return mat so operations can be chained.\n */\ngoog.vec.mat4f.makeIdentity = function(mat) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 1;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 1;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Performs a per-component addition of the matrix mat0 and mat1, storing\n * the result into resultMat.\n *\n * @param {!goog.vec.mat4f.Type} mat0 The first addend.\n * @param {!goog.vec.mat4f.Type} mat1 The second addend.\n * @param {!goog.vec.mat4f.Type} resultMat The matrix to\n * receive the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat4f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.addMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] + mat1[0];\n resultMat[1] = mat0[1] + mat1[1];\n resultMat[2] = mat0[2] + mat1[2];\n resultMat[3] = mat0[3] + mat1[3];\n resultMat[4] = mat0[4] + mat1[4];\n resultMat[5] = mat0[5] + mat1[5];\n resultMat[6] = mat0[6] + mat1[6];\n resultMat[7] = mat0[7] + mat1[7];\n resultMat[8] = mat0[8] + mat1[8];\n resultMat[9] = mat0[9] + mat1[9];\n resultMat[10] = mat0[10] + mat1[10];\n resultMat[11] = mat0[11] + mat1[11];\n resultMat[12] = mat0[12] + mat1[12];\n resultMat[13] = mat0[13] + mat1[13];\n resultMat[14] = mat0[14] + mat1[14];\n resultMat[15] = mat0[15] + mat1[15];\n return resultMat;\n};\n\n\n/**\n * Performs a per-component subtraction of the matrix mat0 and mat1,\n * storing the result into resultMat.\n *\n * @param {!goog.vec.mat4f.Type} mat0 The minuend.\n * @param {!goog.vec.mat4f.Type} mat1 The subtrahend.\n * @param {!goog.vec.mat4f.Type} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat4f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.subMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] - mat1[0];\n resultMat[1] = mat0[1] - mat1[1];\n resultMat[2] = mat0[2] - mat1[2];\n resultMat[3] = mat0[3] - mat1[3];\n resultMat[4] = mat0[4] - mat1[4];\n resultMat[5] = mat0[5] - mat1[5];\n resultMat[6] = mat0[6] - mat1[6];\n resultMat[7] = mat0[7] - mat1[7];\n resultMat[8] = mat0[8] - mat1[8];\n resultMat[9] = mat0[9] - mat1[9];\n resultMat[10] = mat0[10] - mat1[10];\n resultMat[11] = mat0[11] - mat1[11];\n resultMat[12] = mat0[12] - mat1[12];\n resultMat[13] = mat0[13] - mat1[13];\n resultMat[14] = mat0[14] - mat1[14];\n resultMat[15] = mat0[15] - mat1[15];\n return resultMat;\n};\n\n\n/**\n * Multiplies matrix mat with the given scalar, storing the result\n * into resultMat.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} scalar The scalar value to multiply to each element of mat.\n * @param {!goog.vec.mat4f.Type} resultMat The matrix to receive\n * the results (may be mat).\n * @return {!goog.vec.mat4f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.multScalar = function(mat, scalar, resultMat) {\n 'use strict';\n resultMat[0] = mat[0] * scalar;\n resultMat[1] = mat[1] * scalar;\n resultMat[2] = mat[2] * scalar;\n resultMat[3] = mat[3] * scalar;\n resultMat[4] = mat[4] * scalar;\n resultMat[5] = mat[5] * scalar;\n resultMat[6] = mat[6] * scalar;\n resultMat[7] = mat[7] * scalar;\n resultMat[8] = mat[8] * scalar;\n resultMat[9] = mat[9] * scalar;\n resultMat[10] = mat[10] * scalar;\n resultMat[11] = mat[11] * scalar;\n resultMat[12] = mat[12] * scalar;\n resultMat[13] = mat[13] * scalar;\n resultMat[14] = mat[14] * scalar;\n resultMat[15] = mat[15] * scalar;\n return resultMat;\n};\n\n\n/**\n * Multiplies the two matrices mat0 and mat1 using matrix multiplication,\n * storing the result into resultMat.\n *\n * @param {!goog.vec.mat4f.Type} mat0 The first (left hand) matrix.\n * @param {!goog.vec.mat4f.Type} mat1 The second (right hand) matrix.\n * @param {!goog.vec.mat4f.Type} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat4f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.multMat = function(mat0, mat1, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n const a30 = mat0[3];\n\n const a01 = mat0[4];\n const a11 = mat0[5];\n const a21 = mat0[6];\n const a31 = mat0[7];\n\n const a02 = mat0[8];\n const a12 = mat0[9];\n const a22 = mat0[10];\n const a32 = mat0[11];\n\n const a03 = mat0[12];\n const a13 = mat0[13];\n const a23 = mat0[14];\n const a33 = mat0[15];\n\n\n const b00 = mat1[0];\n const b10 = mat1[1];\n const b20 = mat1[2];\n const b30 = mat1[3];\n\n const b01 = mat1[4];\n const b11 = mat1[5];\n const b21 = mat1[6];\n const b31 = mat1[7];\n\n const b02 = mat1[8];\n const b12 = mat1[9];\n const b22 = mat1[10];\n const b32 = mat1[11];\n\n const b03 = mat1[12];\n const b13 = mat1[13];\n const b23 = mat1[14];\n const b33 = mat1[15];\n\n\n resultMat[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;\n resultMat[1] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;\n resultMat[2] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;\n resultMat[3] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;\n\n resultMat[4] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;\n resultMat[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;\n resultMat[6] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;\n resultMat[7] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;\n\n resultMat[8] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;\n resultMat[9] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;\n resultMat[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;\n resultMat[11] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;\n\n resultMat[12] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;\n resultMat[13] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;\n resultMat[14] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;\n resultMat[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;\n return resultMat;\n};\n\n\n/**\n * Transposes the given matrix mat storing the result into resultMat.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to transpose.\n * @param {!goog.vec.mat4f.Type} resultMat The matrix to receive\n * the results (may be mat).\n * @return {!goog.vec.mat4f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.transpose = function(mat, resultMat) {\n 'use strict';\n if (resultMat == mat) {\n const a10 = mat[1];\n const a20 = mat[2];\n const a30 = mat[3];\n\n const a21 = mat[6];\n const a31 = mat[7];\n\n const a32 = mat[11];\n resultMat[1] = mat[4];\n resultMat[2] = mat[8];\n resultMat[3] = mat[12];\n resultMat[4] = a10;\n resultMat[6] = mat[9];\n resultMat[7] = mat[13];\n resultMat[8] = a20;\n resultMat[9] = a21;\n resultMat[11] = mat[14];\n resultMat[12] = a30;\n resultMat[13] = a31;\n resultMat[14] = a32;\n } else {\n resultMat[0] = mat[0];\n resultMat[1] = mat[4];\n resultMat[2] = mat[8];\n resultMat[3] = mat[12];\n\n resultMat[4] = mat[1];\n resultMat[5] = mat[5];\n resultMat[6] = mat[9];\n resultMat[7] = mat[13];\n\n resultMat[8] = mat[2];\n resultMat[9] = mat[6];\n resultMat[10] = mat[10];\n resultMat[11] = mat[14];\n\n resultMat[12] = mat[3];\n resultMat[13] = mat[7];\n resultMat[14] = mat[11];\n resultMat[15] = mat[15];\n }\n return resultMat;\n};\n\n\n/**\n * Computes the determinant of the matrix.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to compute the matrix for.\n * @return {number} The determinant of the matrix.\n */\ngoog.vec.mat4f.determinant = function(mat) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n const m03 = mat[12];\n const m13 = mat[13];\n const m23 = mat[14];\n const m33 = mat[15];\n\n\n const a0 = m00 * m11 - m10 * m01;\n const a1 = m00 * m21 - m20 * m01;\n const a2 = m00 * m31 - m30 * m01;\n const a3 = m10 * m21 - m20 * m11;\n const a4 = m10 * m31 - m30 * m11;\n const a5 = m20 * m31 - m30 * m21;\n const b0 = m02 * m13 - m12 * m03;\n const b1 = m02 * m23 - m22 * m03;\n const b2 = m02 * m33 - m32 * m03;\n const b3 = m12 * m23 - m22 * m13;\n const b4 = m12 * m33 - m32 * m13;\n const b5 = m22 * m33 - m32 * m23;\n\n return a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;\n};\n\n\n/**\n * Computes the inverse of mat storing the result into resultMat. If the\n * inverse is defined, this function returns true, false otherwise.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix to invert.\n * @param {!goog.vec.mat4f.Type} resultMat The matrix to receive\n * the result (may be mat).\n * @return {boolean} True if the inverse is defined. If false is returned,\n * resultMat is not modified.\n */\ngoog.vec.mat4f.invert = function(mat, resultMat) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n const m03 = mat[12];\n const m13 = mat[13];\n const m23 = mat[14];\n const m33 = mat[15];\n\n\n const a0 = m00 * m11 - m10 * m01;\n const a1 = m00 * m21 - m20 * m01;\n const a2 = m00 * m31 - m30 * m01;\n const a3 = m10 * m21 - m20 * m11;\n const a4 = m10 * m31 - m30 * m11;\n const a5 = m20 * m31 - m30 * m21;\n const b0 = m02 * m13 - m12 * m03;\n const b1 = m02 * m23 - m22 * m03;\n const b2 = m02 * m33 - m32 * m03;\n const b3 = m12 * m23 - m22 * m13;\n const b4 = m12 * m33 - m32 * m13;\n const b5 = m22 * m33 - m32 * m23;\n\n const det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;\n if (det == 0) {\n return false;\n }\n\n const idet = 1.0 / det;\n resultMat[0] = (m11 * b5 - m21 * b4 + m31 * b3) * idet;\n resultMat[1] = (-m10 * b5 + m20 * b4 - m30 * b3) * idet;\n resultMat[2] = (m13 * a5 - m23 * a4 + m33 * a3) * idet;\n resultMat[3] = (-m12 * a5 + m22 * a4 - m32 * a3) * idet;\n resultMat[4] = (-m01 * b5 + m21 * b2 - m31 * b1) * idet;\n resultMat[5] = (m00 * b5 - m20 * b2 + m30 * b1) * idet;\n resultMat[6] = (-m03 * a5 + m23 * a2 - m33 * a1) * idet;\n resultMat[7] = (m02 * a5 - m22 * a2 + m32 * a1) * idet;\n resultMat[8] = (m01 * b4 - m11 * b2 + m31 * b0) * idet;\n resultMat[9] = (-m00 * b4 + m10 * b2 - m30 * b0) * idet;\n resultMat[10] = (m03 * a4 - m13 * a2 + m33 * a0) * idet;\n resultMat[11] = (-m02 * a4 + m12 * a2 - m32 * a0) * idet;\n resultMat[12] = (-m01 * b3 + m11 * b1 - m21 * b0) * idet;\n resultMat[13] = (m00 * b3 - m10 * b1 + m20 * b0) * idet;\n resultMat[14] = (-m03 * a3 + m13 * a1 - m23 * a0) * idet;\n resultMat[15] = (m02 * a3 - m12 * a1 + m22 * a0) * idet;\n return true;\n};\n\n\n/**\n * Returns true if the components of mat0 are equal to the components of mat1.\n *\n * @param {!goog.vec.mat4f.Type} mat0 The first matrix.\n * @param {!goog.vec.mat4f.Type} mat1 The second matrix.\n * @return {boolean} True if the two matrices are equivalent.\n */\ngoog.vec.mat4f.equals = function(mat0, mat1) {\n 'use strict';\n return mat0.length == mat1.length && mat0[0] == mat1[0] &&\n mat0[1] == mat1[1] && mat0[2] == mat1[2] && mat0[3] == mat1[3] &&\n mat0[4] == mat1[4] && mat0[5] == mat1[5] && mat0[6] == mat1[6] &&\n mat0[7] == mat1[7] && mat0[8] == mat1[8] && mat0[9] == mat1[9] &&\n mat0[10] == mat1[10] && mat0[11] == mat1[11] && mat0[12] == mat1[12] &&\n mat0[13] == mat1[13] && mat0[14] == mat1[14] && mat0[15] == mat1[15];\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * upper 3x4 matrix omitting the projective component.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec3f.Type} vec The 3 element vector to transform.\n * @param {!goog.vec.vec3f.Type} resultVec The 3 element vector to\n * receive the results (may be vec).\n * @return {!goog.vec.vec3f.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.multVec3 = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8] + mat[12];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9] + mat[13];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10] + mat[14];\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * upper 3x3 matrix omitting the projective component and translation\n * components.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec3f.Type} vec The 3 element vector to transform.\n * @param {!goog.vec.vec3f.Type} resultVec The 3 element vector to\n * receive the results (may be vec).\n * @return {!goog.vec.vec3f.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.multVec3NoTranslate = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10];\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * full 4x4 matrix with the homogeneous divide applied to reduce the 4 element\n * vector to a 3 element vector.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec3f.Type} vec The 3 element vector to transform.\n * @param {!goog.vec.vec3f.Type} resultVec The 3 element vector\n * to receive the results (may be vec).\n * @return {!goog.vec.vec3f.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.multVec3Projective = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n const invw = 1 / (x * mat[3] + y * mat[7] + z * mat[11] + mat[15]);\n resultVec[0] = (x * mat[0] + y * mat[4] + z * mat[8] + mat[12]) * invw;\n resultVec[1] = (x * mat[1] + y * mat[5] + z * mat[9] + mat[13]) * invw;\n resultVec[2] = (x * mat[2] + y * mat[6] + z * mat[10] + mat[14]) * invw;\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec4f.Type} vec The vector to transform.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to\n * receive the results (may be vec).\n * @return {!goog.vec.vec4f.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.multVec4 = function(mat, vec, resultVec) {\n 'use strict';\n const w = vec[3];\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8] + w * mat[12];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9] + w * mat[13];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10] + w * mat[14];\n resultVec[3] = x * mat[3] + y * mat[7] + z * mat[11] + w * mat[15];\n return resultVec;\n};\n\n\n/**\n * Makes the given 4x4 matrix a translation matrix with x, y and z\n * translation factors.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @param {number} z The translation along the z axis.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeTranslate = function(mat, x, y, z) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 1;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 1;\n mat[11] = 0;\n mat[12] = x;\n mat[13] = y;\n mat[14] = z;\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix as a scale matrix with x, y and z scale factors.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} x The scale along the x axis.\n * @param {number} y The scale along the y axis.\n * @param {number} z The scale along the z axis.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeScale = function(mat, x, y, z) {\n 'use strict';\n mat[0] = x;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = y;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = z;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the axis defined by the vector (ax, ay, az).\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @param {number} ax The x component of the rotation axis.\n * @param {number} ay The y component of the rotation axis.\n * @param {number} az The z component of the rotation axis.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeRotate = function(mat, angle, ax, ay, az) {\n 'use strict';\n const c = Math.cos(angle);\n const d = 1 - c;\n const s = Math.sin(angle);\n\n mat[0] = ax * ax * d + c;\n mat[1] = ax * ay * d + az * s;\n mat[2] = ax * az * d - ay * s;\n mat[3] = 0;\n mat[4] = ax * ay * d - az * s;\n mat[5] = ay * ay * d + c;\n mat[6] = ay * az * d + ax * s;\n mat[7] = 0;\n mat[8] = ax * az * d + ay * s;\n mat[9] = ay * az * d - ax * s;\n mat[10] = az * az * d + c;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the X axis.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeRotateX = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = c;\n mat[6] = s;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = -s;\n mat[10] = c;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the Y axis.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeRotateY = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = c;\n mat[1] = 0;\n mat[2] = -s;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 1;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = s;\n mat[9] = 0;\n mat[10] = c;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the Z axis.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeRotateZ = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = c;\n mat[1] = s;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = -s;\n mat[5] = c;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 1;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Creates a matrix from a quaternion rotation and vector translation.\n *\n * This is a specialization of makeRotationTranslationScaleOrigin.\n *\n * This is equivalent to, but faster than:\n * goog.vec.mat4f.makeIdentity(m);\n * goog.vec.mat4f.translate(m, tx, ty, tz);\n * goog.vec.mat4f.rotate(m, theta, rx, ry, rz);\n * and:\n * goog.vec.Quaternion.toRotationMatrix4(rotation, mat);\n * mat[12] = translation[0];\n * mat[13] = translation[1];\n * mat[14] = translation[2];\n * See http://jsperf.com/goog-vec-makerotationtranslation2 .\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {!goog.vec.Quaternion.AnyType} rotation The quaternion rotation.\n * Note: this quaternion is assumed to already be normalized.\n * @param {!goog.vec.vec3f.Type} translation The vector translation.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeRotationTranslation = function(mat, rotation, translation) {\n 'use strict';\n // Quaternion math\n const w = rotation[3];\n const x = rotation[0];\n const y = rotation[1];\n const z = rotation[2];\n\n const x2 = 2 * x;\n const y2 = 2 * y;\n const z2 = 2 * z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n mat[0] = 1 - (yy + zz);\n mat[1] = xy + wz;\n mat[2] = xz - wy;\n mat[3] = 0;\n mat[4] = xy - wz;\n mat[5] = 1 - (xx + zz);\n mat[6] = yz + wx;\n mat[7] = 0;\n mat[8] = xz + wy;\n mat[9] = yz - wx;\n mat[10] = 1 - (xx + yy);\n mat[11] = 0;\n mat[12] = translation[0];\n mat[13] = translation[1];\n mat[14] = translation[2];\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation, and\n * vector scale.\n *\n * This is a specialization of makeRotationTranslationScaleOrigin.\n *\n * This is equivalent to, but faster than:\n * goog.vec.mat4f.makeIdentity(m);\n * goog.vec.mat4f.translate(m, tx, ty, tz);\n * goog.vec.mat4f.rotate(m, theta, rx, ry, rz);\n * goog.vec.mat4f.scale(m, sx, sy, sz);\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {!goog.vec.Quaternion.AnyType} rotation The quaternion rotation.\n * Note: this quaternion is assumed to already be normalized.\n * @param {!goog.vec.vec3f.Type} translation The vector translation.\n * @param {!goog.vec.vec3f.Type} scale The vector scale.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeRotationTranslationScale = function(\n mat, rotation, translation, scale) {\n 'use strict';\n // Quaternion math\n const w = rotation[3];\n const x = rotation[0];\n const y = rotation[1];\n const z = rotation[2];\n\n const x2 = 2 * x;\n const y2 = 2 * y;\n const z2 = 2 * z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n const sx = scale[0];\n const sy = scale[1];\n const sz = scale[2];\n\n mat[0] = (1 - (yy + zz)) * sx;\n mat[1] = (xy + wz) * sx;\n mat[2] = (xz - wy) * sx;\n mat[3] = 0;\n mat[4] = (xy - wz) * sy;\n mat[5] = (1 - (xx + zz)) * sy;\n mat[6] = (yz + wx) * sy;\n mat[7] = 0;\n mat[8] = (xz + wy) * sz;\n mat[9] = (yz - wx) * sz;\n mat[10] = (1 - (xx + yy)) * sz;\n mat[11] = 0;\n mat[12] = translation[0];\n mat[13] = translation[1];\n mat[14] = translation[2];\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation, and\n * vector scale, rotating and scaling about the given origin.\n *\n * This is equivalent to, but faster than:\n * goog.vec.mat4f.makeIdentity(m);\n * goog.vec.mat4f.translate(m, tx, ty, tz);\n * goog.vec.mat4f.translate(m, ox, oy, oz);\n * goog.vec.mat4f.rotate(m, theta, rx, ry, rz);\n * goog.vec.mat4f.scale(m, sx, sy, sz);\n * goog.vec.mat4f.translate(m, -ox, -oy, -oz);\n * See http://jsperf.com/glmatrix-matrix-variant-test/3 for performance\n * results of a similar function in the glmatrix library.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {!goog.vec.Quaternion.AnyType} rotation The quaternion rotation.\n * Note: this quaternion is assumed to already be normalized.\n * @param {!goog.vec.vec3f.Type} translation The vector translation.\n * @param {!goog.vec.vec3f.Type} scale The vector scale.\n * @param {!goog.vec.vec3f.Type} origin The origin about which to scale and\n * rotate.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeRotationTranslationScaleOrigin = function(\n mat, rotation, translation, scale, origin) {\n 'use strict';\n // Quaternion math\n const w = rotation[3];\n const x = rotation[0];\n const y = rotation[1];\n const z = rotation[2];\n\n const x2 = 2 * x;\n const y2 = 2 * y;\n const z2 = 2 * z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n const sx = scale[0];\n const sy = scale[1];\n const sz = scale[2];\n const ox = origin[0];\n const oy = origin[1];\n const oz = origin[2];\n\n mat[0] = (1 - (yy + zz)) * sx;\n mat[1] = (xy + wz) * sx;\n mat[2] = (xz - wy) * sx;\n mat[3] = 0;\n mat[4] = (xy - wz) * sy;\n mat[5] = (1 - (xx + zz)) * sy;\n mat[6] = (yz + wx) * sy;\n mat[7] = 0;\n mat[8] = (xz + wy) * sz;\n mat[9] = (yz - wx) * sz;\n mat[10] = (1 - (xx + yy)) * sz;\n mat[11] = 0;\n mat[12] = translation[0] + ox - (mat[0] * ox + mat[4] * oy + mat[8] * oz);\n mat[13] = translation[1] + oy - (mat[1] * ox + mat[5] * oy + mat[9] * oz);\n mat[14] = translation[2] + oz - (mat[2] * ox + mat[6] * oy + mat[10] * oz);\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a perspective projection matrix.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} left The coordinate of the left clipping plane.\n * @param {number} right The coordinate of the right clipping plane.\n * @param {number} bottom The coordinate of the bottom clipping plane.\n * @param {number} top The coordinate of the top clipping plane.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeFrustum = function(\n mat, left, right, bottom, top, near, far) {\n 'use strict';\n const x = (2 * near) / (right - left);\n const y = (2 * near) / (top - bottom);\n const a = (right + left) / (right - left);\n const b = (top + bottom) / (top - bottom);\n const c = -(far + near) / (far - near);\n const d = -(2 * far * near) / (far - near);\n\n mat[0] = x;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = y;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = a;\n mat[9] = b;\n mat[10] = c;\n mat[11] = -1;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = d;\n mat[15] = 0;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix perspective projection matrix given a\n * field of view and aspect ratio.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} fovy The field of view along the y (vertical) axis in\n * radians.\n * @param {number} aspect The x (width) to y (height) aspect ratio.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makePerspective = function(mat, fovy, aspect, near, far) {\n 'use strict';\n const angle = fovy / 2;\n const dz = far - near;\n const sinAngle = Math.sin(angle);\n if (dz == 0 || sinAngle == 0 || aspect == 0) {\n return mat;\n }\n\n const cot = Math.cos(angle) / sinAngle;\n\n mat[0] = cot / aspect;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = cot;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = -(far + near) / dz;\n mat[11] = -1;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = -(2 * near * far) / dz;\n mat[15] = 0;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix an orthographic projection matrix.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} left The coordinate of the left clipping plane.\n * @param {number} right The coordinate of the right clipping plane.\n * @param {number} bottom The coordinate of the bottom clipping plane.\n * @param {number} top The coordinate of the top clipping plane.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeOrtho = function(mat, left, right, bottom, top, near, far) {\n 'use strict';\n const x = 2 / (right - left);\n const y = 2 / (top - bottom);\n const z = -2 / (far - near);\n const a = -(right + left) / (right - left);\n const b = -(top + bottom) / (top - bottom);\n const c = -(far + near) / (far - near);\n\n mat[0] = x;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = y;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = z;\n mat[11] = 0;\n mat[12] = a;\n mat[13] = b;\n mat[14] = c;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a modelview matrix of a camera so that\n * the camera is 'looking at' the given center point.\n *\n * Note that unlike most other goog.vec functions where we inline\n * everything, this function does not inline various goog.vec\n * functions. This makes the code more readable, but somewhat\n * less efficient.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {!goog.vec.vec3f.Type} eyePt The position of the eye point\n * (camera origin).\n * @param {!goog.vec.vec3f.Type} centerPt The point to aim the camera at.\n * @param {!goog.vec.vec3f.Type} worldUpVec The vector that identifies\n * the up direction for the camera.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeLookAt = function(mat, eyePt, centerPt, worldUpVec) {\n 'use strict';\n // Compute the direction vector from the eye point to the center point and\n // normalize.\n const fwdVec = goog.vec.mat4f.tmpvec4f_[0];\n goog.vec.vec3f.subtract(centerPt, eyePt, fwdVec);\n goog.vec.vec3f.normalize(fwdVec, fwdVec);\n fwdVec[3] = 0;\n\n // Compute the side vector from the forward vector and the input up vector.\n const sideVec = goog.vec.mat4f.tmpvec4f_[1];\n goog.vec.vec3f.cross(fwdVec, worldUpVec, sideVec);\n goog.vec.vec3f.normalize(sideVec, sideVec);\n sideVec[3] = 0;\n\n // Now the up vector to form the orthonormal basis.\n const upVec = goog.vec.mat4f.tmpvec4f_[2];\n goog.vec.vec3f.cross(sideVec, fwdVec, upVec);\n goog.vec.vec3f.normalize(upVec, upVec);\n upVec[3] = 0;\n\n // Update the view matrix with the new orthonormal basis and position the\n // camera at the given eye point.\n goog.vec.vec3f.negate(fwdVec, fwdVec);\n goog.vec.mat4f.setRow(mat, 0, sideVec);\n goog.vec.mat4f.setRow(mat, 1, upVec);\n goog.vec.mat4f.setRow(mat, 2, fwdVec);\n goog.vec.mat4f.setRowValues(mat, 3, 0, 0, 0, 1);\n goog.vec.mat4f.translate(mat, -eyePt[0], -eyePt[1], -eyePt[2]);\n\n return mat;\n};\n\n\n/**\n * Decomposes a matrix into the lookAt vectors eyePt, fwdVec and worldUpVec.\n * The matrix represents the modelview matrix of a camera. It is the inverse\n * of lookAt except for the output of the fwdVec instead of centerPt.\n * The centerPt itself cannot be recovered from a modelview matrix.\n *\n * Note that unlike most other goog.vec functions where we inline\n * everything, this function does not inline various goog.vec\n * functions. This makes the code more readable, but somewhat\n * less efficient.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {!goog.vec.vec3f.Type} eyePt The position of the eye point\n * (camera origin).\n * @param {!goog.vec.vec3f.Type} fwdVec The vector describing where\n * the camera points to.\n * @param {!goog.vec.vec3f.Type} worldUpVec The vector that\n * identifies the up direction for the camera.\n * @return {boolean} True if the method succeeds, false otherwise.\n * The method can only fail if the inverse of viewMatrix is not defined.\n */\ngoog.vec.mat4f.toLookAt = function(mat, eyePt, fwdVec, worldUpVec) {\n 'use strict';\n // Get eye of the camera.\n const matInverse = goog.vec.mat4f.tmpmat4f_[0];\n if (!goog.vec.mat4f.invert(mat, matInverse)) {\n // The input matrix does not have a valid inverse.\n return false;\n }\n\n if (eyePt) {\n eyePt[0] = matInverse[12];\n eyePt[1] = matInverse[13];\n eyePt[2] = matInverse[14];\n }\n\n // Get forward vector from the definition of lookAt.\n if (fwdVec || worldUpVec) {\n if (!fwdVec) {\n fwdVec = goog.vec.mat4f.tmpvec3f_[0];\n }\n fwdVec[0] = -mat[2];\n fwdVec[1] = -mat[6];\n fwdVec[2] = -mat[10];\n // Normalize forward vector.\n goog.vec.vec3f.normalize(fwdVec, fwdVec);\n }\n\n if (worldUpVec) {\n // Get side vector from the definition of gluLookAt.\n const side = goog.vec.mat4f.tmpvec3f_[1];\n side[0] = mat[0];\n side[1] = mat[4];\n side[2] = mat[8];\n // Compute up vector as a up = side x forward.\n goog.vec.vec3f.cross(side, fwdVec, worldUpVec);\n // Normalize up vector.\n goog.vec.vec3f.normalize(worldUpVec, worldUpVec);\n }\n return true;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix given Euler angles using\n * the ZXZ convention.\n * Given the euler angles [theta1, theta2, theta3], the rotation is defined as\n * rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians,\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} theta1 The angle of rotation around the Z axis in radians.\n * @param {number} theta2 The angle of rotation around the X axis in radians.\n * @param {number} theta3 The angle of rotation around the Z axis in radians.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.makeEulerZXZ = function(mat, theta1, theta2, theta3) {\n 'use strict';\n const c1 = Math.cos(theta1);\n const s1 = Math.sin(theta1);\n\n const c2 = Math.cos(theta2);\n const s2 = Math.sin(theta2);\n\n const c3 = Math.cos(theta3);\n const s3 = Math.sin(theta3);\n\n mat[0] = c1 * c3 - c2 * s1 * s3;\n mat[1] = c2 * c1 * s3 + c3 * s1;\n mat[2] = s3 * s2;\n mat[3] = 0;\n\n mat[4] = -c1 * s3 - c3 * c2 * s1;\n mat[5] = c1 * c2 * c3 - s1 * s3;\n mat[6] = c3 * s2;\n mat[7] = 0;\n\n mat[8] = s2 * s1;\n mat[9] = -c1 * s2;\n mat[10] = c2;\n mat[11] = 0;\n\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Decomposes a rotation matrix into Euler angles using the ZXZ convention so\n * that rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {!goog.vec.vec3f.Type} euler The ZXZ Euler angles in\n * radians as [theta1, theta2, theta3].\n * @param {boolean=} opt_theta2IsNegative Whether theta2 is in [-pi, 0] instead\n * of the default [0, pi].\n * @return {!goog.vec.vec4f.Type} return euler so that operations can be\n * chained together.\n */\ngoog.vec.mat4f.toEulerZXZ = function(mat, euler, opt_theta2IsNegative) {\n 'use strict';\n // There is an ambiguity in the sign of sinTheta2 because of the sqrt.\n const sinTheta2 = Math.sqrt(mat[2] * mat[2] + mat[6] * mat[6]);\n\n // By default we explicitely constrain theta2 to be in [0, pi],\n // so sinTheta2 is always positive. We can change the behavior and specify\n // theta2 to be negative in [-pi, 0] with opt_Theta2IsNegative.\n const signTheta2 = opt_theta2IsNegative ? -1 : 1;\n\n if (sinTheta2 > goog.vec.EPSILON) {\n euler[2] = Math.atan2(mat[2] * signTheta2, mat[6] * signTheta2);\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[10]);\n euler[0] = Math.atan2(mat[8] * signTheta2, -mat[9] * signTheta2);\n } else {\n // There is also an arbitrary choice for theta1 = 0 or theta2 = 0 here.\n // We assume theta1 = 0 as some applications do not allow the camera to roll\n // (i.e. have theta1 != 0).\n euler[0] = 0;\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[10]);\n euler[2] = Math.atan2(mat[1], mat[0]);\n }\n\n // Atan2 outputs angles in [-pi, pi] so we bring them back to [0, 2 * pi].\n euler[0] = (euler[0] + Math.PI * 2) % (Math.PI * 2);\n euler[2] = (euler[2] + Math.PI * 2) % (Math.PI * 2);\n // For theta2 we want the angle to be in [0, pi] or [-pi, 0] depending on\n // signTheta2.\n euler[1] =\n ((euler[1] * signTheta2 + Math.PI * 2) % (Math.PI * 2)) * signTheta2;\n\n return euler;\n};\n\n\n/**\n * Translates the given matrix by x,y,z. Equvialent to:\n * goog.vec.mat4f.multMat(\n * mat,\n * goog.vec.mat4f.makeTranslate(goog.vec.mat4f.create(), x, y, z),\n * mat);\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @param {number} z The translation along the z axis.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.translate = function(mat, x, y, z) {\n 'use strict';\n mat[12] += mat[0] * x + mat[4] * y + mat[8] * z;\n mat[13] += mat[1] * x + mat[5] * y + mat[9] * z;\n mat[14] += mat[2] * x + mat[6] * y + mat[10] * z;\n mat[15] += mat[3] * x + mat[7] * y + mat[11] * z;\n\n return mat;\n};\n\n\n/**\n * Scales the given matrix by x,y,z. Equivalent to:\n * goog.vec.mat4f.multMat(\n * mat,\n * goog.vec.mat4f.makeScale(goog.vec.mat4f.create(), x, y, z),\n * mat);\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} x The x scale factor.\n * @param {number} y The y scale factor.\n * @param {number} z The z scale factor.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.scale = function(mat, x, y, z) {\n 'use strict';\n mat[0] = mat[0] * x;\n mat[1] = mat[1] * x;\n mat[2] = mat[2] * x;\n mat[3] = mat[3] * x;\n mat[4] = mat[4] * y;\n mat[5] = mat[5] * y;\n mat[6] = mat[6] * y;\n mat[7] = mat[7] * y;\n mat[8] = mat[8] * z;\n mat[9] = mat[9] * z;\n mat[10] = mat[10] * z;\n mat[11] = mat[11] * z;\n mat[12] = mat[12];\n mat[13] = mat[13];\n mat[14] = mat[14];\n mat[15] = mat[15];\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the x,y,z axis. Equivalent to:\n * goog.vec.mat4f.multMat(\n * mat,\n * goog.vec.mat4f.makeRotate(goog.vec.mat4f.create(), angle, x, y, z),\n * mat);\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @param {number} x The x component of the rotation axis.\n * @param {number} y The y component of the rotation axis.\n * @param {number} z The z component of the rotation axis.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.rotate = function(mat, angle, x, y, z) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n\n const cosAngle = Math.cos(angle);\n const sinAngle = Math.sin(angle);\n const diffCosAngle = 1 - cosAngle;\n const r00 = x * x * diffCosAngle + cosAngle;\n const r10 = x * y * diffCosAngle + z * sinAngle;\n const r20 = x * z * diffCosAngle - y * sinAngle;\n\n const r01 = x * y * diffCosAngle - z * sinAngle;\n const r11 = y * y * diffCosAngle + cosAngle;\n const r21 = y * z * diffCosAngle + x * sinAngle;\n\n const r02 = x * z * diffCosAngle + y * sinAngle;\n const r12 = y * z * diffCosAngle - x * sinAngle;\n const r22 = z * z * diffCosAngle + cosAngle;\n\n mat[0] = m00 * r00 + m01 * r10 + m02 * r20;\n mat[1] = m10 * r00 + m11 * r10 + m12 * r20;\n mat[2] = m20 * r00 + m21 * r10 + m22 * r20;\n mat[3] = m30 * r00 + m31 * r10 + m32 * r20;\n mat[4] = m00 * r01 + m01 * r11 + m02 * r21;\n mat[5] = m10 * r01 + m11 * r11 + m12 * r21;\n mat[6] = m20 * r01 + m21 * r11 + m22 * r21;\n mat[7] = m30 * r01 + m31 * r11 + m32 * r21;\n mat[8] = m00 * r02 + m01 * r12 + m02 * r22;\n mat[9] = m10 * r02 + m11 * r12 + m12 * r22;\n mat[10] = m20 * r02 + m21 * r12 + m22 * r22;\n mat[11] = m30 * r02 + m31 * r12 + m32 * r22;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the x axis. Equivalent to:\n * goog.vec.mat4f.multMat(\n * mat,\n * goog.vec.mat4f.makeRotateX(goog.vec.mat4f.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.rotateX = function(mat, angle) {\n 'use strict';\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[4] = m01 * c + m02 * s;\n mat[5] = m11 * c + m12 * s;\n mat[6] = m21 * c + m22 * s;\n mat[7] = m31 * c + m32 * s;\n mat[8] = m01 * -s + m02 * c;\n mat[9] = m11 * -s + m12 * c;\n mat[10] = m21 * -s + m22 * c;\n mat[11] = m31 * -s + m32 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the y axis. Equivalent to:\n * goog.vec.mat4f.multMat(\n * mat,\n * goog.vec.mat4f.makeRotateY(goog.vec.mat4f.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.rotateY = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m02 * -s;\n mat[1] = m10 * c + m12 * -s;\n mat[2] = m20 * c + m22 * -s;\n mat[3] = m30 * c + m32 * -s;\n mat[8] = m00 * s + m02 * c;\n mat[9] = m10 * s + m12 * c;\n mat[10] = m20 * s + m22 * c;\n mat[11] = m30 * s + m32 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the z axis. Equivalent to:\n * goog.vec.mat4f.multMat(\n * mat,\n * goog.vec.mat4f.makeRotateZ(goog.vec.mat4f.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat4f.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat4f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4f.rotateZ = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m01 * s;\n mat[1] = m10 * c + m11 * s;\n mat[2] = m20 * c + m21 * s;\n mat[3] = m30 * c + m31 * s;\n mat[4] = m00 * -s + m01 * c;\n mat[5] = m10 * -s + m11 * c;\n mat[6] = m20 * -s + m21 * c;\n mat[7] = m30 * -s + m31 * c;\n\n return mat;\n};\n\n\n/**\n * Retrieves the translation component of the transformation matrix.\n *\n * @param {!goog.vec.mat4f.Type} mat The transformation matrix.\n * @param {!goog.vec.vec3f.Type} translation The vector for storing the\n * result.\n * @return {!goog.vec.vec3f.Type} return translation so that operations can be\n * chained.\n */\ngoog.vec.mat4f.getTranslation = function(mat, translation) {\n 'use strict';\n translation[0] = mat[12];\n translation[1] = mat[13];\n translation[2] = mat[14];\n return translation;\n};\n\n\n/**\n * @type {Array}\n * @private\n */\ngoog.vec.mat4f.tmpvec3f_ = [goog.vec.vec3f.create(), goog.vec.vec3f.create()];\n\n\n/**\n * @type {Array}\n * @private\n */\ngoog.vec.mat4f.tmpvec4f_ =\n [goog.vec.vec4f.create(), goog.vec.vec4f.create(), goog.vec.vec4f.create()];\n\n\n/**\n * @type {Array}\n * @private\n */\ngoog.vec.mat4f.tmpmat4f_ = [goog.vec.mat4f.create()];\n","^<",1684857788697,"^=",["^3",["^14","^>","^1A","^1C","~$goog.vec.vec4f"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14","^1A","^1C","^1N"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.mat4f","goog.vec.mat4f.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec","goog.vec.Quaternion","goog.vec.vec3f","goog.vec.vec4f"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/mat4f.js"],"^[",["^3",["^1L","^1M"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14","^1A","^1C","^1N"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.vec4f.Type","^1N"]],"^5","goog.vec.vec4f.js","^6",["^7","goog/vec/vec4f.js"],"^8","goog/vec/vec4f.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to vec4d.js by running: //\n// swap_type.sh vec4f.js > vec4d.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 4 element float (32bit)\n * vectors.\n *\n * The last parameter will typically be the output object and an object\n * can be both an input and output parameter to all methods except where\n * noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\ngoog.provide('goog.vec.vec4f');\ngoog.provide('goog.vec.vec4f.Type');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.vec4f.Type;\n\n\n/**\n * Creates a vec4f with all elements initialized to zero.\n *\n * @return {!goog.vec.vec4f.Type} The new vec4f.\n */\ngoog.vec.vec4f.create = function() {\n 'use strict';\n return new Float32Array(4);\n};\n\n\n/**\n * Creates a new vec4f initialized with the value from the given array.\n *\n * @param {!Array} vec The source 4 element array.\n * @return {!goog.vec.vec4f.Type} The new vec4f.\n */\ngoog.vec.vec4f.createFromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec4f.create();\n goog.vec.vec4f.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new vec4f initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.vec4f.Type} The new vector.\n */\ngoog.vec.vec4f.createFromValues = function(v0, v1, v2, v3) {\n 'use strict';\n const vec = goog.vec.vec4f.create();\n goog.vec.vec4f.setFromValues(vec, v0, v1, v2, v3);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given vec4f.\n *\n * @param {!goog.vec.vec4f.Type} vec The source vec4f.\n * @return {!goog.vec.vec4f.Type} The new cloned vec4f.\n */\ngoog.vec.vec4f.clone = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec4f.create();\n goog.vec.vec4f.setFromVec4f(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {!goog.vec.vec4f.Type} vec The vector to receive the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.vec4f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.setFromValues = function(vec, v0, v1, v2, v3) {\n 'use strict';\n vec[0] = v0;\n vec[1] = v1;\n vec[2] = v2;\n vec[3] = v3;\n return vec;\n};\n\n\n/**\n * Initializes vec4f vec from vec4f src.\n *\n * @param {!goog.vec.vec4f.Type} vec The destination vector.\n * @param {!goog.vec.vec4f.Type} src The source vector.\n * @return {!goog.vec.vec4f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.setFromVec4f = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n vec[3] = src[3];\n return vec;\n};\n\n\n/**\n * Initializes vec4f vec from vec4d src (typed as a Float64Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.vec4f.Type} vec The destination vector.\n * @param {Float64Array} src The source vector.\n * @return {!goog.vec.vec4f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.setFromVec4d = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n vec[3] = src[3];\n return vec;\n};\n\n\n/**\n * Initializes vec4f vec from Array src.\n *\n * @param {!goog.vec.vec4f.Type} vec The destination vector.\n * @param {Array} src The source vector.\n * @return {!goog.vec.vec4f.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.setFromArray = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n vec[3] = src[3];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The first addend.\n * @param {!goog.vec.vec4f.Type} vec1 The second addend.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n resultVec[2] = vec0[2] + vec1[2];\n resultVec[3] = vec0[3] + vec1[3];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The minuend.\n * @param {!goog.vec.vec4f.Type} vec1 The subtrahend.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n resultVec[2] = vec0[2] - vec1[2];\n resultVec[3] = vec0[3] - vec1[3];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The vector to negate.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n resultVec[2] = -vec0[2];\n resultVec[3] = -vec0[3];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The source vector.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n resultVec[2] = Math.abs(vec0[2]);\n resultVec[3] = Math.abs(vec0[3]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n resultVec[2] = vec0[2] * scalar;\n resultVec[3] = vec0[3] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec4f.magnitudeSquared = function(vec0) {\n 'use strict';\n const w = vec0[3];\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return x * x + y * y + z * z + w * w;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec4f.magnitude = function(vec0) {\n 'use strict';\n const w = vec0[3];\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return Math.sqrt(x * x + y * y + z * z + w * w);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The vector to normalize.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.normalize = function(vec0, resultVec) {\n 'use strict';\n const w = vec0[3];\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n const ilen = 1 / Math.sqrt(x * x + y * y + z * z + w * w);\n resultVec[0] = x * ilen;\n resultVec[1] = y * ilen;\n resultVec[2] = z * ilen;\n resultVec[3] = w * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors v0 and v1.\n *\n * @param {!goog.vec.vec4f.Type} v0 The first vector.\n * @param {!goog.vec.vec4f.Type} v1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.vec4f.dot = function(v0, v1) {\n 'use strict';\n return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2] + v0[3] * v1[3];\n};\n\n\n/**\n * Linearly interpolate from v0 to v1 according to f. The value of f should be\n * in the range [0..1] otherwise the results are undefined.\n *\n * @param {!goog.vec.vec4f.Type} v0 The first vector.\n * @param {!goog.vec.vec4f.Type} v1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to receive the\n * results (may be v0 or v1).\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.lerp = function(v0, v1, f, resultVec) {\n 'use strict';\n const w = v0[3];\n const x = v0[0];\n const y = v0[1];\n const z = v0[2];\n\n resultVec[0] = (v1[0] - x) * f + x;\n resultVec[1] = (v1[1] - y) * f + y;\n resultVec[2] = (v1[2] - z) * f + z;\n resultVec[3] = (v1[3] - w) * f + w;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The source vector.\n * @param {!goog.vec.vec4f.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n resultVec[2] = Math.max(vec0[2], limit);\n resultVec[3] = Math.max(vec0[3], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n resultVec[2] = Math.max(vec0[2], limit[2]);\n resultVec[3] = Math.max(vec0[3], limit[3]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {!goog.vec.vec4f.Type} vec0 The source vector.\n * @param {!goog.vec.vec4f.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec4f.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4f.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n resultVec[2] = Math.min(vec0[2], limit);\n resultVec[3] = Math.min(vec0[3], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n resultVec[2] = Math.min(vec0[2], limit[2]);\n resultVec[3] = Math.min(vec0[3], limit[3]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of v0 are equal to the components of v1.\n *\n * @param {!goog.vec.vec4f.Type} v0 The first vector.\n * @param {!goog.vec.vec4f.Type} v1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.vec4f.equals = function(v0, v1) {\n 'use strict';\n return v0.length == v1.length && v0[0] == v1[0] && v0[1] == v1[1] &&\n v0[2] == v1[2] && v0[3] == v1[3];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.vec4f","goog.vec.vec4f.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec4f.js"],"^[",["^3",["^1O","^1N"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.mat3f.Type","~$goog.vec.mat3f"]],"^5","goog.vec.mat3f.js","^6",["^7","goog/vec/mat3f.js"],"^8","goog/vec/mat3f.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to mat3d.js by running: //\n// swap_type.sh mat3f.js > mat3d.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 3x3 float (32bit)\n * matrices. The matrices are stored in column-major order.\n *\n * The last parameter will typically be the output object and an object\n * can be both an input and output parameter to all methods except where\n * noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\ngoog.provide('goog.vec.mat3f');\ngoog.provide('goog.vec.mat3f.Type');\n\ngoog.require('goog.vec');\ngoog.require('goog.vec.vec3f.Type');\n\n\n/** @typedef {!goog.vec.Float32} */ goog.vec.mat3f.Type;\n\n\n/**\n * Creates a mat3f with all elements initialized to zero.\n *\n * @return {!goog.vec.mat3f.Type} The new mat3f.\n */\ngoog.vec.mat3f.create = function() {\n 'use strict';\n return new Float32Array(9);\n};\n\n\n/**\n * Creates a mat3f identity matrix.\n *\n * @return {!goog.vec.mat3f.Type} The new mat3f.\n */\ngoog.vec.mat3f.createIdentity = function() {\n 'use strict';\n const mat = goog.vec.mat3f.create();\n mat[0] = mat[4] = mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Initializes the matrix from the set of values. Note the values supplied are\n * in column major order.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the\n * values.\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setFromValues = function(\n mat, v00, v10, v20, v01, v11, v21, v02, v12, v22) {\n 'use strict';\n mat[0] = v00;\n mat[1] = v10;\n mat[2] = v20;\n mat[3] = v01;\n mat[4] = v11;\n mat[5] = v21;\n mat[6] = v02;\n mat[7] = v12;\n mat[8] = v22;\n return mat;\n};\n\n\n/**\n * Initializes mat3f mat from mat3f src.\n *\n * @param {!goog.vec.mat3f.Type} mat The destination matrix.\n * @param {!goog.vec.mat3f.Type} src The source matrix.\n * @return {!goog.vec.mat3f.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setFromMat3f = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n return mat;\n};\n\n\n/**\n * Initializes mat3f mat from mat3d src (typed as a Float64Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.mat3f.Type} mat The destination matrix.\n * @param {Float64Array} src The source matrix.\n * @return {!goog.vec.mat3f.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setFromMat3d = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n return mat;\n};\n\n\n/**\n * Initializes mat3f mat from Array src.\n *\n * @param {!goog.vec.mat3f.Type} mat The destination matrix.\n * @param {Array} src The source matrix.\n * @return {!goog.vec.mat3f.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setFromArray = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n return mat;\n};\n\n\n/**\n * Retrieves the element at the requested row and column.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @return {number} The element value at the requested row, column indices.\n */\ngoog.vec.mat3f.getElement = function(mat, row, column) {\n 'use strict';\n return mat[row + column * 3];\n};\n\n\n/**\n * Sets the element at the requested row and column.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @param {number} value The value to set at the requested row, column.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setElement = function(mat, row, column, value) {\n 'use strict';\n mat[row + column * 3] = value;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given values.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the values.\n * @param {number} v00 The values for (0, 0).\n * @param {number} v11 The values for (1, 1).\n * @param {number} v22 The values for (2, 2).\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setDiagonalValues = function(mat, v00, v11, v22) {\n 'use strict';\n mat[0] = v00;\n mat[4] = v11;\n mat[8] = v22;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given vector.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec3f.Type} vec The vector containing the values.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setDiagonal = function(mat, vec) {\n 'use strict';\n mat[0] = vec[0];\n mat[4] = vec[1];\n mat[8] = vec[2];\n return mat;\n};\n\n\n/**\n * Sets the specified column with the supplied values.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {number} v0 The value for row 0.\n * @param {number} v1 The value for row 1.\n * @param {number} v2 The value for row 2.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setColumnValues = function(mat, column, v0, v1, v2) {\n 'use strict';\n const i = column * 3;\n mat[i] = v0;\n mat[i + 1] = v1;\n mat[i + 2] = v2;\n return mat;\n};\n\n\n/**\n * Sets the specified column with the value from the supplied array.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {!goog.vec.vec3f.Type} vec The vector elements for the column.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 3;\n mat[i] = vec[0];\n mat[i + 1] = vec[1];\n mat[i + 2] = vec[2];\n return mat;\n};\n\n\n/**\n * Retrieves the specified column from the matrix into the given vector\n * array.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix supplying the values.\n * @param {number} column The column to get the values from.\n * @param {!goog.vec.vec3f.Type} vec The vector elements to receive the\n * column.\n * @return {!goog.vec.vec3f.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.getColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 3;\n vec[0] = mat[i];\n vec[1] = mat[i + 1];\n vec[2] = mat[i + 2];\n return vec;\n};\n\n\n/**\n * Sets the columns of the matrix from the set of vector elements.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec3f.Type} vec0 The values for column 0.\n * @param {!goog.vec.vec3f.Type} vec1 The values for column 1.\n * @param {!goog.vec.vec3f.Type} vec2 The values for column 2.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setColumns = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.mat3f.setColumn(mat, 0, vec0);\n goog.vec.mat3f.setColumn(mat, 1, vec1);\n goog.vec.mat3f.setColumn(mat, 2, vec2);\n return /** @type {!goog.vec.mat3f.Type} */ (mat);\n};\n\n\n/**\n * Retrieves the column values from the given matrix into the given vector\n * elements.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix supplying the columns.\n * @param {!goog.vec.vec3f.Type} vec0 The vector to receive column 0.\n * @param {!goog.vec.vec3f.Type} vec1 The vector to receive column 1.\n * @param {!goog.vec.vec3f.Type} vec2 The vector to receive column 2.\n */\ngoog.vec.mat3f.getColumns = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.mat3f.getColumn(mat, 0, vec0);\n goog.vec.mat3f.getColumn(mat, 1, vec1);\n goog.vec.mat3f.getColumn(mat, 2, vec2);\n};\n\n\n/**\n * Sets the row values from the supplied values.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the values.\n * @param {number} row The index of the row to receive the values.\n * @param {number} v0 The value for column 0.\n * @param {number} v1 The value for column 1.\n * @param {number} v2 The value for column 2.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setRowValues = function(mat, row, v0, v1, v2) {\n 'use strict';\n mat[row] = v0;\n mat[row + 3] = v1;\n mat[row + 6] = v2;\n return mat;\n};\n\n\n/**\n * Sets the row values from the supplied vector.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the row values.\n * @param {number} row The index of the row.\n * @param {!goog.vec.vec3f.Type} vec The vector containing the values.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setRow = function(mat, row, vec) {\n 'use strict';\n mat[row] = vec[0];\n mat[row + 3] = vec[1];\n mat[row + 6] = vec[2];\n return mat;\n};\n\n\n/**\n * Retrieves the row values into the given vector.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix supplying the values.\n * @param {number} row The index of the row supplying the values.\n * @param {!goog.vec.vec3f.Type} vec The vector to receive the row.\n * @return {!goog.vec.vec3f.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.getRow = function(mat, row, vec) {\n 'use strict';\n vec[0] = mat[row];\n vec[1] = mat[row + 3];\n vec[2] = mat[row + 6];\n return vec;\n};\n\n\n/**\n * Sets the rows of the matrix from the supplied vectors.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec3f.Type} vec0 The values for row 0.\n * @param {!goog.vec.vec3f.Type} vec1 The values for row 1.\n * @param {!goog.vec.vec3f.Type} vec2 The values for row 2.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.setRows = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.mat3f.setRow(mat, 0, vec0);\n goog.vec.mat3f.setRow(mat, 1, vec1);\n goog.vec.mat3f.setRow(mat, 2, vec2);\n return /** @type {!goog.vec.mat3f.Type} */ (mat);\n};\n\n\n/**\n * Retrieves the rows of the matrix into the supplied vectors.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to supplying the values.\n * @param {!goog.vec.vec3f.Type} vec0 The vector to receive row 0.\n * @param {!goog.vec.vec3f.Type} vec1 The vector to receive row 1.\n * @param {!goog.vec.vec3f.Type} vec2 The vector to receive row 2.\n */\ngoog.vec.mat3f.getRows = function(mat, vec0, vec1, vec2) {\n 'use strict';\n goog.vec.mat3f.getRow(mat, 0, vec0);\n goog.vec.mat3f.getRow(mat, 1, vec1);\n goog.vec.mat3f.getRow(mat, 2, vec2);\n};\n\n\n/**\n * Makes the given 3x3 matrix the zero matrix.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @return {!goog.vec.mat3f.Type} return mat so operations can be chained.\n */\ngoog.vec.mat3f.makeZero = function(mat) {\n 'use strict';\n mat[0] = 0;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix the identity matrix.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @return {!goog.vec.mat3f.Type} return mat so operations can be chained.\n */\ngoog.vec.mat3f.makeIdentity = function(mat) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 1;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Performs a per-component addition of the matrices mat0 and mat1, storing\n * the result into resultMat.\n *\n * @param {!goog.vec.mat3f.Type} mat0 The first addend.\n * @param {!goog.vec.mat3f.Type} mat1 The second addend.\n * @param {!goog.vec.mat3f.Type} resultMat The matrix to\n * receive the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat3f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.addMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] + mat1[0];\n resultMat[1] = mat0[1] + mat1[1];\n resultMat[2] = mat0[2] + mat1[2];\n resultMat[3] = mat0[3] + mat1[3];\n resultMat[4] = mat0[4] + mat1[4];\n resultMat[5] = mat0[5] + mat1[5];\n resultMat[6] = mat0[6] + mat1[6];\n resultMat[7] = mat0[7] + mat1[7];\n resultMat[8] = mat0[8] + mat1[8];\n return resultMat;\n};\n\n\n/**\n * Performs a per-component subtraction of the matrices mat0 and mat1,\n * storing the result into resultMat.\n *\n * @param {!goog.vec.mat3f.Type} mat0 The minuend.\n * @param {!goog.vec.mat3f.Type} mat1 The subtrahend.\n * @param {!goog.vec.mat3f.Type} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat3f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.subMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] - mat1[0];\n resultMat[1] = mat0[1] - mat1[1];\n resultMat[2] = mat0[2] - mat1[2];\n resultMat[3] = mat0[3] - mat1[3];\n resultMat[4] = mat0[4] - mat1[4];\n resultMat[5] = mat0[5] - mat1[5];\n resultMat[6] = mat0[6] - mat1[6];\n resultMat[7] = mat0[7] - mat1[7];\n resultMat[8] = mat0[8] - mat1[8];\n return resultMat;\n};\n\n\n/**\n * Multiplies matrix mat0 with the given scalar, storing the result\n * into resultMat.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} scalar The scalar value to multiple to each element of mat.\n * @param {!goog.vec.mat3f.Type} resultMat The matrix to receive\n * the results (may be mat).\n * @return {!goog.vec.mat3f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.multScalar = function(mat, scalar, resultMat) {\n 'use strict';\n resultMat[0] = mat[0] * scalar;\n resultMat[1] = mat[1] * scalar;\n resultMat[2] = mat[2] * scalar;\n resultMat[3] = mat[3] * scalar;\n resultMat[4] = mat[4] * scalar;\n resultMat[5] = mat[5] * scalar;\n resultMat[6] = mat[6] * scalar;\n resultMat[7] = mat[7] * scalar;\n resultMat[8] = mat[8] * scalar;\n return resultMat;\n};\n\n\n/**\n * Multiplies the two matrices mat0 and mat1 using matrix multiplication,\n * storing the result into resultMat.\n *\n * @param {!goog.vec.mat3f.Type} mat0 The first (left hand) matrix.\n * @param {!goog.vec.mat3f.Type} mat1 The second (right hand) matrix.\n * @param {!goog.vec.mat3f.Type} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat3f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.multMat = function(mat0, mat1, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n\n const a01 = mat0[3];\n const a11 = mat0[4];\n const a21 = mat0[5];\n\n const a02 = mat0[6];\n const a12 = mat0[7];\n const a22 = mat0[8];\n\n\n const b00 = mat1[0];\n const b10 = mat1[1];\n const b20 = mat1[2];\n\n const b01 = mat1[3];\n const b11 = mat1[4];\n const b21 = mat1[5];\n\n const b02 = mat1[6];\n const b12 = mat1[7];\n const b22 = mat1[8];\n\n\n resultMat[0] = a00 * b00 + a01 * b10 + a02 * b20;\n resultMat[1] = a10 * b00 + a11 * b10 + a12 * b20;\n resultMat[2] = a20 * b00 + a21 * b10 + a22 * b20;\n resultMat[3] = a00 * b01 + a01 * b11 + a02 * b21;\n resultMat[4] = a10 * b01 + a11 * b11 + a12 * b21;\n resultMat[5] = a20 * b01 + a21 * b11 + a22 * b21;\n resultMat[6] = a00 * b02 + a01 * b12 + a02 * b22;\n resultMat[7] = a10 * b02 + a11 * b12 + a12 * b22;\n resultMat[8] = a20 * b02 + a21 * b12 + a22 * b22;\n return resultMat;\n};\n\n\n/**\n * Transposes the given matrix mat storing the result into resultMat.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix to transpose.\n * @param {!goog.vec.mat3f.Type} resultMat The matrix to receive\n * the results (may be mat).\n * @return {!goog.vec.mat3f.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.transpose = function(mat, resultMat) {\n 'use strict';\n if (resultMat == mat) {\n const a10 = mat[1];\n const a20 = mat[2];\n const a21 = mat[5];\n\n resultMat[1] = mat[3];\n resultMat[2] = mat[6];\n resultMat[3] = a10;\n resultMat[5] = mat[7];\n resultMat[6] = a20;\n resultMat[7] = a21;\n } else {\n resultMat[0] = mat[0];\n resultMat[1] = mat[3];\n resultMat[2] = mat[6];\n resultMat[3] = mat[1];\n resultMat[4] = mat[4];\n resultMat[5] = mat[7];\n resultMat[6] = mat[2];\n resultMat[7] = mat[5];\n resultMat[8] = mat[8];\n }\n return resultMat;\n};\n\n\n/**\n * Computes the inverse of mat0 storing the result into resultMat. If the\n * inverse is defined, this function returns true, false otherwise.\n *\n * @param {!goog.vec.mat3f.Type} mat0 The matrix to invert.\n * @param {!goog.vec.mat3f.Type} resultMat The matrix to receive\n * the result (may be mat0).\n * @return {boolean} True if the inverse is defined. If false is returned,\n * resultMat is not modified.\n */\ngoog.vec.mat3f.invert = function(mat0, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n\n const a01 = mat0[3];\n const a11 = mat0[4];\n const a21 = mat0[5];\n\n const a02 = mat0[6];\n const a12 = mat0[7];\n const a22 = mat0[8];\n\n\n const t00 = a11 * a22 - a12 * a21;\n const t10 = a12 * a20 - a10 * a22;\n const t20 = a10 * a21 - a11 * a20;\n const det = a00 * t00 + a01 * t10 + a02 * t20;\n if (det == 0) {\n return false;\n }\n\n const idet = 1 / det;\n resultMat[0] = t00 * idet;\n resultMat[3] = (a02 * a21 - a01 * a22) * idet;\n resultMat[6] = (a01 * a12 - a02 * a11) * idet;\n\n resultMat[1] = t10 * idet;\n resultMat[4] = (a00 * a22 - a02 * a20) * idet;\n resultMat[7] = (a02 * a10 - a00 * a12) * idet;\n\n resultMat[2] = t20 * idet;\n resultMat[5] = (a01 * a20 - a00 * a21) * idet;\n resultMat[8] = (a00 * a11 - a01 * a10) * idet;\n return true;\n};\n\n\n/**\n * Returns true if the components of mat0 are equal to the components of mat1.\n *\n * @param {!goog.vec.mat3f.Type} mat0 The first matrix.\n * @param {!goog.vec.mat3f.Type} mat1 The second matrix.\n * @return {boolean} True if the two matrices are equivalent.\n */\ngoog.vec.mat3f.equals = function(mat0, mat1) {\n 'use strict';\n return mat0.length == mat1.length && mat0[0] == mat1[0] &&\n mat0[1] == mat1[1] && mat0[2] == mat1[2] && mat0[3] == mat1[3] &&\n mat0[4] == mat1[4] && mat0[5] == mat1[5] && mat0[6] == mat1[6] &&\n mat0[7] == mat1[7] && mat0[8] == mat1[8];\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed matrix into resultVec.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec3f.Type} vec The vector to transform.\n * @param {!goog.vec.vec3f.Type} resultVec The vector to\n * receive the results (may be vec).\n * @return {!goog.vec.vec3f.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.multVec3 = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[3] + z * mat[6];\n resultVec[1] = x * mat[1] + y * mat[4] + z * mat[7];\n resultVec[2] = x * mat[2] + y * mat[5] + z * mat[8];\n return resultVec;\n};\n\n\n/**\n * Makes the given 3x3 matrix a translation matrix with x and y\n * translation values.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.makeTranslate = function(mat, x, y) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 1;\n mat[5] = 0;\n mat[6] = x;\n mat[7] = y;\n mat[8] = 1;\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a scale matrix with x, y, and z scale factors.\n *\n * @param {!goog.vec.mat3f.Type} mat The 3x3 (9-element) matrix\n * array to receive the new scale matrix.\n * @param {number} x The scale along the x axis.\n * @param {number} y The scale along the y axis.\n * @param {number} z The scale along the z axis.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.makeScale = function(mat, x, y, z) {\n 'use strict';\n mat[0] = x;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = y;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = z;\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the axis defined by the vector (ax, ay, az).\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @param {number} ax The x component of the rotation axis.\n * @param {number} ay The y component of the rotation axis.\n * @param {number} az The z component of the rotation axis.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.makeRotate = function(mat, angle, ax, ay, az) {\n 'use strict';\n const c = Math.cos(angle);\n const d = 1 - c;\n const s = Math.sin(angle);\n\n mat[0] = ax * ax * d + c;\n mat[1] = ax * ay * d + az * s;\n mat[2] = ax * az * d - ay * s;\n mat[3] = ax * ay * d - az * s;\n mat[4] = ay * ay * d + c;\n mat[5] = ay * az * d + ax * s;\n mat[6] = ax * az * d + ay * s;\n mat[7] = ay * az * d - ax * s;\n mat[8] = az * az * d + c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the X axis.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.makeRotateX = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = c;\n mat[5] = s;\n mat[6] = 0;\n mat[7] = -s;\n mat[8] = c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the Y axis.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.makeRotateY = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = c;\n mat[1] = 0;\n mat[2] = -s;\n mat[3] = 0;\n mat[4] = 1;\n mat[5] = 0;\n mat[6] = s;\n mat[7] = 0;\n mat[8] = c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix with the given rotation\n * angle about the Z axis.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.makeRotateZ = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = c;\n mat[1] = s;\n mat[2] = 0;\n mat[3] = -s;\n mat[4] = c;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 1;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the x,y,z axis. Equivalent to:\n * goog.vec.mat3f.multMat(\n * mat,\n * goog.vec.mat3f.makeRotate(goog.vec.mat3f.create(), angle, x, y, z),\n * mat);\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @param {number} x The x component of the rotation axis.\n * @param {number} y The y component of the rotation axis.\n * @param {number} z The z component of the rotation axis.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.rotate = function(mat, angle, x, y, z) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const cosAngle = Math.cos(angle);\n const sinAngle = Math.sin(angle);\n const diffCosAngle = 1 - cosAngle;\n const r00 = x * x * diffCosAngle + cosAngle;\n const r10 = x * y * diffCosAngle + z * sinAngle;\n const r20 = x * z * diffCosAngle - y * sinAngle;\n\n const r01 = x * y * diffCosAngle - z * sinAngle;\n const r11 = y * y * diffCosAngle + cosAngle;\n const r21 = y * z * diffCosAngle + x * sinAngle;\n\n const r02 = x * z * diffCosAngle + y * sinAngle;\n const r12 = y * z * diffCosAngle - x * sinAngle;\n const r22 = z * z * diffCosAngle + cosAngle;\n\n mat[0] = m00 * r00 + m01 * r10 + m02 * r20;\n mat[1] = m10 * r00 + m11 * r10 + m12 * r20;\n mat[2] = m20 * r00 + m21 * r10 + m22 * r20;\n mat[3] = m00 * r01 + m01 * r11 + m02 * r21;\n mat[4] = m10 * r01 + m11 * r11 + m12 * r21;\n mat[5] = m20 * r01 + m21 * r11 + m22 * r21;\n mat[6] = m00 * r02 + m01 * r12 + m02 * r22;\n mat[7] = m10 * r02 + m11 * r12 + m12 * r22;\n mat[8] = m20 * r02 + m21 * r12 + m22 * r22;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the x axis. Equivalent to:\n * goog.vec.mat3f.multMat(\n * mat,\n * goog.vec.mat3f.makeRotateX(goog.vec.mat3f.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.rotateX = function(mat, angle) {\n 'use strict';\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[3] = m01 * c + m02 * s;\n mat[4] = m11 * c + m12 * s;\n mat[5] = m21 * c + m22 * s;\n mat[6] = m01 * -s + m02 * c;\n mat[7] = m11 * -s + m12 * c;\n mat[8] = m21 * -s + m22 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the y axis. Equivalent to:\n * goog.vec.mat3f.multMat(\n * mat,\n * goog.vec.mat3f.makeRotateY(goog.vec.mat3f.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.rotateY = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m02 = mat[6];\n const m12 = mat[7];\n const m22 = mat[8];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m02 * -s;\n mat[1] = m10 * c + m12 * -s;\n mat[2] = m20 * c + m22 * -s;\n mat[6] = m00 * s + m02 * c;\n mat[7] = m10 * s + m12 * c;\n mat[8] = m20 * s + m22 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the z axis. Equivalent to:\n * goog.vec.mat3f.multMat(\n * mat,\n * goog.vec.mat3f.makeRotateZ(goog.vec.mat3f.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.rotateZ = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n\n const m01 = mat[3];\n const m11 = mat[4];\n const m21 = mat[5];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m01 * s;\n mat[1] = m10 * c + m11 * s;\n mat[2] = m20 * c + m21 * s;\n mat[3] = m00 * -s + m01 * c;\n mat[4] = m10 * -s + m11 * c;\n mat[5] = m20 * -s + m21 * c;\n\n return mat;\n};\n\n\n/**\n * Makes the given 3x3 matrix a rotation matrix given Euler angles using\n * the ZXZ convention.\n * Given the euler angles [theta1, theta2, theta3], the rotation is defined as\n * rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {number} theta1 The angle of rotation around the Z axis in radians.\n * @param {number} theta2 The angle of rotation around the X axis in radians.\n * @param {number} theta3 The angle of rotation around the Z axis in radians.\n * @return {!goog.vec.mat3f.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat3f.makeEulerZXZ = function(mat, theta1, theta2, theta3) {\n 'use strict';\n const c1 = Math.cos(theta1);\n const s1 = Math.sin(theta1);\n\n const c2 = Math.cos(theta2);\n const s2 = Math.sin(theta2);\n\n const c3 = Math.cos(theta3);\n const s3 = Math.sin(theta3);\n\n mat[0] = c1 * c3 - c2 * s1 * s3;\n mat[1] = c2 * c1 * s3 + c3 * s1;\n mat[2] = s3 * s2;\n\n mat[3] = -c1 * s3 - c3 * c2 * s1;\n mat[4] = c1 * c2 * c3 - s1 * s3;\n mat[5] = c3 * s2;\n\n mat[6] = s2 * s1;\n mat[7] = -c1 * s2;\n mat[8] = c2;\n\n return mat;\n};\n\n\n/**\n * Decomposes a rotation matrix into Euler angles using the ZXZ convention so\n * that rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {!goog.vec.mat3f.Type} mat The matrix.\n * @param {!goog.vec.vec3f.Type} euler The ZXZ Euler angles in\n * radians as [theta1, theta2, theta3].\n * @param {boolean=} opt_theta2IsNegative Whether theta2 is in [-pi, 0] instead\n * of the default [0, pi].\n * @return {!goog.vec.vec3f.Type} return euler so that operations can be\n * chained together.\n */\ngoog.vec.mat3f.toEulerZXZ = function(mat, euler, opt_theta2IsNegative) {\n 'use strict';\n // There is an ambiguity in the sign of sinTheta2 because of the sqrt.\n const sinTheta2 = Math.sqrt(mat[2] * mat[2] + mat[5] * mat[5]);\n\n // By default we explicitely constrain theta2 to be in [0, pi],\n // so sinTheta2 is always positive. We can change the behavior and specify\n // theta2 to be negative in [-pi, 0] with opt_Theta2IsNegative.\n const signTheta2 = opt_theta2IsNegative ? -1 : 1;\n\n if (sinTheta2 > goog.vec.EPSILON) {\n euler[2] = Math.atan2(mat[2] * signTheta2, mat[5] * signTheta2);\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[8]);\n euler[0] = Math.atan2(mat[6] * signTheta2, -mat[7] * signTheta2);\n } else {\n // There is also an arbitrary choice for theta1 = 0 or theta2 = 0 here.\n // We assume theta1 = 0 as some applications do not allow the camera to roll\n // (i.e. have theta1 != 0).\n euler[0] = 0;\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[8]);\n euler[2] = Math.atan2(mat[1], mat[0]);\n }\n\n // Atan2 outputs angles in [-pi, pi] so we bring them back to [0, 2 * pi].\n euler[0] = (euler[0] + Math.PI * 2) % (Math.PI * 2);\n euler[2] = (euler[2] + Math.PI * 2) % (Math.PI * 2);\n // For theta2 we want the angle to be in [0, pi] or [-pi, 0] depending on\n // signTheta2.\n euler[1] =\n ((euler[1] * signTheta2 + Math.PI * 2) % (Math.PI * 2)) * signTheta2;\n\n return euler;\n};\n","^<",1684857788697,"^=",["^3",["^14","^1B","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14","^1B"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.mat3f","goog.vec.mat3f.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec","goog.vec.vec3f.Type"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/mat3f.js"],"^[",["^3",["^1P","^1Q"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14","^1B"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.vec4d.Type","~$goog.vec.vec4d"]],"^5","goog.vec.vec4d.js","^6",["^7","goog/vec/vec4d.js"],"^8","goog/vec/vec4d.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to vec4f.js by running: //\n// swap_type.sh vec4d.js > vec4f.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 4 element double (64bit)\n * vectors.\n *\n * The last parameter will typically be the output object and an object\n * can be both an input and output parameter to all methods except where\n * noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\ngoog.provide('goog.vec.vec4d');\ngoog.provide('goog.vec.vec4d.Type');\n\n/** @suppress {extraRequire} */\ngoog.require('goog.vec');\n\n/** @typedef {!goog.vec.Float64} */ goog.vec.vec4d.Type;\n\n\n/**\n * Creates a vec4d with all elements initialized to zero.\n *\n * @return {!goog.vec.vec4d.Type} The new vec4d.\n */\ngoog.vec.vec4d.create = function() {\n 'use strict';\n return new Float64Array(4);\n};\n\n\n/**\n * Creates a new vec4d initialized with the value from the given array.\n *\n * @param {!Array} vec The source 4 element array.\n * @return {!goog.vec.vec4d.Type} The new vec4d.\n */\ngoog.vec.vec4d.createFromArray = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec4d.create();\n goog.vec.vec4d.setFromArray(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Creates a new vec4d initialized with the supplied values.\n *\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.vec4d.Type} The new vector.\n */\ngoog.vec.vec4d.createFromValues = function(v0, v1, v2, v3) {\n 'use strict';\n const vec = goog.vec.vec4d.create();\n goog.vec.vec4d.setFromValues(vec, v0, v1, v2, v3);\n return vec;\n};\n\n\n/**\n * Creates a clone of the given vec4d.\n *\n * @param {!goog.vec.vec4d.Type} vec The source vec4d.\n * @return {!goog.vec.vec4d.Type} The new cloned vec4d.\n */\ngoog.vec.vec4d.clone = function(vec) {\n 'use strict';\n const newVec = goog.vec.vec4d.create();\n goog.vec.vec4d.setFromVec4d(newVec, vec);\n return newVec;\n};\n\n\n/**\n * Initializes the vector with the given values.\n *\n * @param {!goog.vec.vec4d.Type} vec The vector to receive the values.\n * @param {number} v0 The value for element at index 0.\n * @param {number} v1 The value for element at index 1.\n * @param {number} v2 The value for element at index 2.\n * @param {number} v3 The value for element at index 3.\n * @return {!goog.vec.vec4d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.setFromValues = function(vec, v0, v1, v2, v3) {\n 'use strict';\n vec[0] = v0;\n vec[1] = v1;\n vec[2] = v2;\n vec[3] = v3;\n return vec;\n};\n\n\n/**\n * Initializes vec4d vec from vec4d src.\n *\n * @param {!goog.vec.vec4d.Type} vec The destination vector.\n * @param {!goog.vec.vec4d.Type} src The source vector.\n * @return {!goog.vec.vec4d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.setFromVec4d = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n vec[3] = src[3];\n return vec;\n};\n\n\n/**\n * Initializes vec4d vec from vec4f src (typed as a Float32Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.vec4d.Type} vec The destination vector.\n * @param {Float32Array} src The source vector.\n * @return {!goog.vec.vec4d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.setFromVec4f = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n vec[3] = src[3];\n return vec;\n};\n\n\n/**\n * Initializes vec4d vec from Array src.\n *\n * @param {!goog.vec.vec4d.Type} vec The destination vector.\n * @param {Array} src The source vector.\n * @return {!goog.vec.vec4d.Type} Return vec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.setFromArray = function(vec, src) {\n 'use strict';\n vec[0] = src[0];\n vec[1] = src[1];\n vec[2] = src[2];\n vec[3] = src[3];\n return vec;\n};\n\n\n/**\n * Performs a component-wise addition of vec0 and vec1 together storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The first addend.\n * @param {!goog.vec.vec4d.Type} vec1 The second addend.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.add = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] + vec1[0];\n resultVec[1] = vec0[1] + vec1[1];\n resultVec[2] = vec0[2] + vec1[2];\n resultVec[3] = vec0[3] + vec1[3];\n return resultVec;\n};\n\n\n/**\n * Performs a component-wise subtraction of vec1 from vec0 storing the\n * result into resultVec.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The minuend.\n * @param {!goog.vec.vec4d.Type} vec1 The subtrahend.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to\n * receive the result. May be vec0 or vec1.\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.subtract = function(vec0, vec1, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] - vec1[0];\n resultVec[1] = vec0[1] - vec1[1];\n resultVec[2] = vec0[2] - vec1[2];\n resultVec[3] = vec0[3] - vec1[3];\n return resultVec;\n};\n\n\n/**\n * Negates vec0, storing the result into resultVec.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The vector to negate.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.negate = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = -vec0[0];\n resultVec[1] = -vec0[1];\n resultVec[2] = -vec0[2];\n resultVec[3] = -vec0[3];\n return resultVec;\n};\n\n\n/**\n * Takes the absolute value of each component of vec0 storing the result in\n * resultVec.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The source vector.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to receive the result.\n * May be vec0.\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.abs = function(vec0, resultVec) {\n 'use strict';\n resultVec[0] = Math.abs(vec0[0]);\n resultVec[1] = Math.abs(vec0[1]);\n resultVec[2] = Math.abs(vec0[2]);\n resultVec[3] = Math.abs(vec0[3]);\n return resultVec;\n};\n\n\n/**\n * Multiplies each component of vec0 with scalar storing the product into\n * resultVec.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The source vector.\n * @param {number} scalar The value to multiply with each component of vec0.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.scale = function(vec0, scalar, resultVec) {\n 'use strict';\n resultVec[0] = vec0[0] * scalar;\n resultVec[1] = vec0[1] * scalar;\n resultVec[2] = vec0[2] * scalar;\n resultVec[3] = vec0[3] * scalar;\n return resultVec;\n};\n\n\n/**\n * Returns the magnitudeSquared of the given vector.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec4d.magnitudeSquared = function(vec0) {\n 'use strict';\n const w = vec0[3];\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return x * x + y * y + z * z + w * w;\n};\n\n\n/**\n * Returns the magnitude of the given vector.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The vector.\n * @return {number} The magnitude of the vector.\n */\ngoog.vec.vec4d.magnitude = function(vec0) {\n 'use strict';\n const w = vec0[3];\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n return Math.sqrt(x * x + y * y + z * z + w * w);\n};\n\n\n/**\n * Normalizes the given vector storing the result into resultVec.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The vector to normalize.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to\n * receive the result. May be vec0.\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.normalize = function(vec0, resultVec) {\n 'use strict';\n const w = vec0[3];\n const x = vec0[0];\n const y = vec0[1];\n const z = vec0[2];\n\n const ilen = 1 / Math.sqrt(x * x + y * y + z * z + w * w);\n resultVec[0] = x * ilen;\n resultVec[1] = y * ilen;\n resultVec[2] = z * ilen;\n resultVec[3] = w * ilen;\n return resultVec;\n};\n\n\n/**\n * Returns the scalar product of vectors v0 and v1.\n *\n * @param {!goog.vec.vec4d.Type} v0 The first vector.\n * @param {!goog.vec.vec4d.Type} v1 The second vector.\n * @return {number} The scalar product.\n */\ngoog.vec.vec4d.dot = function(v0, v1) {\n 'use strict';\n return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2] + v0[3] * v1[3];\n};\n\n\n/**\n * Linearly interpolate from v0 to v1 according to f. The value of f should be\n * in the range [0..1] otherwise the results are undefined.\n *\n * @param {!goog.vec.vec4d.Type} v0 The first vector.\n * @param {!goog.vec.vec4d.Type} v1 The second vector.\n * @param {number} f The interpolation factor.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to receive the\n * results (may be v0 or v1).\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.lerp = function(v0, v1, f, resultVec) {\n 'use strict';\n const w = v0[3];\n const x = v0[0];\n const y = v0[1];\n const z = v0[2];\n\n resultVec[0] = (v1[0] - x) * f + x;\n resultVec[1] = (v1[1] - y) * f + y;\n resultVec[2] = (v1[2] - z) * f + z;\n resultVec[3] = (v1[3] - w) * f + w;\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the larger values in resultVec.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The source vector.\n * @param {!goog.vec.vec4d.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.max = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.max(vec0[0], limit);\n resultVec[1] = Math.max(vec0[1], limit);\n resultVec[2] = Math.max(vec0[2], limit);\n resultVec[3] = Math.max(vec0[3], limit);\n } else {\n resultVec[0] = Math.max(vec0[0], limit[0]);\n resultVec[1] = Math.max(vec0[1], limit[1]);\n resultVec[2] = Math.max(vec0[2], limit[2]);\n resultVec[3] = Math.max(vec0[3], limit[3]);\n }\n return resultVec;\n};\n\n\n/**\n * Compares the components of vec0 with the components of another vector or\n * scalar, storing the smaller values in resultVec.\n *\n * @param {!goog.vec.vec4d.Type} vec0 The source vector.\n * @param {!goog.vec.vec4d.Type|number} limit The limit vector or scalar.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to receive the\n * results (may be vec0 or limit).\n * @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.vec4d.min = function(vec0, limit, resultVec) {\n 'use strict';\n if (typeof limit === 'number') {\n resultVec[0] = Math.min(vec0[0], limit);\n resultVec[1] = Math.min(vec0[1], limit);\n resultVec[2] = Math.min(vec0[2], limit);\n resultVec[3] = Math.min(vec0[3], limit);\n } else {\n resultVec[0] = Math.min(vec0[0], limit[0]);\n resultVec[1] = Math.min(vec0[1], limit[1]);\n resultVec[2] = Math.min(vec0[2], limit[2]);\n resultVec[3] = Math.min(vec0[3], limit[3]);\n }\n return resultVec;\n};\n\n\n/**\n * Returns true if the components of v0 are equal to the components of v1.\n *\n * @param {!goog.vec.vec4d.Type} v0 The first vector.\n * @param {!goog.vec.vec4d.Type} v1 The second vector.\n * @return {boolean} True if the vectors are equal, false otherwise.\n */\ngoog.vec.vec4d.equals = function(v0, v1) {\n 'use strict';\n return v0.length == v1.length && v0[0] == v1[0] && v0[1] == v1[1] &&\n v0[2] == v1[2] && v0[3] == v1[3];\n};\n","^<",1684857788697,"^=",["^3",["^14","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.vec4d","goog.vec.vec4d.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/vec4d.js"],"^[",["^3",["^1R","^1S"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.vec.mat4d.Type","~$goog.vec.mat4d"]],"^5","goog.vec.mat4d.js","^6",["^7","goog/vec/mat4d.js"],"^8","goog/vec/mat4d.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n// //\n// Any edits to this file must be applied to mat4f.js by running: //\n// swap_type.sh mat4d.js > mat4f.js //\n// //\n////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////\n\n\n/**\n * @fileoverview Provides functions for operating on 4x4 double (64bit)\n * matrices. The matrices are stored in column-major order.\n *\n * The last parameter will typically be the output matrix and an\n * object can be both an input and output parameter to all methods except\n * where noted.\n *\n * See the README for notes about the design and structure of the API\n * (especially related to performance).\n */\ngoog.provide('goog.vec.mat4d');\ngoog.provide('goog.vec.mat4d.Type');\n\ngoog.require('goog.vec');\n/** @suppress {extraRequire} */\ngoog.require('goog.vec.Quaternion');\ngoog.require('goog.vec.vec3d');\ngoog.require('goog.vec.vec4d');\n\n\n/** @typedef {!goog.vec.Float64} */ goog.vec.mat4d.Type;\n\n\n/**\n * Creates a mat4d with all elements initialized to zero.\n *\n * @return {!goog.vec.mat4d.Type} The new mat4d.\n */\ngoog.vec.mat4d.create = function() {\n 'use strict';\n return new Float64Array(16);\n};\n\n\n/**\n * Creates a mat4d identity matrix.\n *\n * @return {!goog.vec.mat4d.Type} The new mat4d.\n */\ngoog.vec.mat4d.createIdentity = function() {\n 'use strict';\n const mat = goog.vec.mat4d.create();\n mat[0] = mat[5] = mat[10] = mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Initializes the matrix from the set of values. Note the values supplied are\n * in column major order.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the\n * values.\n * @param {number} v00 The values at (0, 0).\n * @param {number} v10 The values at (1, 0).\n * @param {number} v20 The values at (2, 0).\n * @param {number} v30 The values at (3, 0).\n * @param {number} v01 The values at (0, 1).\n * @param {number} v11 The values at (1, 1).\n * @param {number} v21 The values at (2, 1).\n * @param {number} v31 The values at (3, 1).\n * @param {number} v02 The values at (0, 2).\n * @param {number} v12 The values at (1, 2).\n * @param {number} v22 The values at (2, 2).\n * @param {number} v32 The values at (3, 2).\n * @param {number} v03 The values at (0, 3).\n * @param {number} v13 The values at (1, 3).\n * @param {number} v23 The values at (2, 3).\n * @param {number} v33 The values at (3, 3).\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setFromValues = function(\n mat, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13,\n v23, v33) {\n 'use strict';\n mat[0] = v00;\n mat[1] = v10;\n mat[2] = v20;\n mat[3] = v30;\n mat[4] = v01;\n mat[5] = v11;\n mat[6] = v21;\n mat[7] = v31;\n mat[8] = v02;\n mat[9] = v12;\n mat[10] = v22;\n mat[11] = v32;\n mat[12] = v03;\n mat[13] = v13;\n mat[14] = v23;\n mat[15] = v33;\n return mat;\n};\n\n\n/**\n * Initializes mat4d mat from mat4d src.\n *\n * @param {!goog.vec.mat4d.Type} mat The destination matrix.\n * @param {!goog.vec.mat4d.Type} src The source matrix.\n * @return {!goog.vec.mat4d.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setFromMat4d = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n mat[9] = src[9];\n mat[10] = src[10];\n mat[11] = src[11];\n mat[12] = src[12];\n mat[13] = src[13];\n mat[14] = src[14];\n mat[15] = src[15];\n return mat;\n};\n\n\n/**\n * Initializes mat4d mat from mat4f src (typed as a Float32Array to\n * avoid circular goog.requires).\n *\n * @param {!goog.vec.mat4d.Type} mat The destination matrix.\n * @param {Float32Array} src The source matrix.\n * @return {!goog.vec.mat4d.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setFromMat4f = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n mat[9] = src[9];\n mat[10] = src[10];\n mat[11] = src[11];\n mat[12] = src[12];\n mat[13] = src[13];\n mat[14] = src[14];\n mat[15] = src[15];\n return mat;\n};\n\n\n/**\n * Initializes mat4d mat from Array src.\n *\n * @param {!goog.vec.mat4d.Type} mat The destination matrix.\n * @param {Array} src The source matrix.\n * @return {!goog.vec.mat4d.Type} Return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setFromArray = function(mat, src) {\n 'use strict';\n mat[0] = src[0];\n mat[1] = src[1];\n mat[2] = src[2];\n mat[3] = src[3];\n mat[4] = src[4];\n mat[5] = src[5];\n mat[6] = src[6];\n mat[7] = src[7];\n mat[8] = src[8];\n mat[9] = src[9];\n mat[10] = src[10];\n mat[11] = src[11];\n mat[12] = src[12];\n mat[13] = src[13];\n mat[14] = src[14];\n mat[15] = src[15];\n return mat;\n};\n\n\n/**\n * Retrieves the element at the requested row and column.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @return {number} The element value at the requested row, column indices.\n */\ngoog.vec.mat4d.getElement = function(mat, row, column) {\n 'use strict';\n return mat[row + column * 4];\n};\n\n\n/**\n * Sets the element at the requested row and column.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix containing the value to\n * retrieve.\n * @param {number} row The row index.\n * @param {number} column The column index.\n * @param {number} value The value to set at the requested row, column.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setElement = function(mat, row, column, value) {\n 'use strict';\n mat[row + column * 4] = value;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given values.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the values.\n * @param {number} v00 The values for (0, 0).\n * @param {number} v11 The values for (1, 1).\n * @param {number} v22 The values for (2, 2).\n * @param {number} v33 The values for (3, 3).\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setDiagonalValues = function(mat, v00, v11, v22, v33) {\n 'use strict';\n mat[0] = v00;\n mat[5] = v11;\n mat[10] = v22;\n mat[15] = v33;\n return mat;\n};\n\n\n/**\n * Sets the diagonal values of the matrix from the given vector.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec4d.Type} vec The vector containing the values.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setDiagonal = function(mat, vec) {\n 'use strict';\n mat[0] = vec[0];\n mat[5] = vec[1];\n mat[10] = vec[2];\n mat[15] = vec[3];\n return mat;\n};\n\n\n/**\n * Gets the diagonal values of the matrix into the given vector.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix containing the values.\n * @param {!goog.vec.vec4d.Type} vec The vector to receive the values.\n * @param {number=} opt_diagonal Which diagonal to get. A value of 0 selects the\n * main diagonal, a positive number selects a super diagonal and a negative\n * number selects a sub diagonal.\n * @return {!goog.vec.vec4d.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.getDiagonal = function(mat, vec, opt_diagonal) {\n 'use strict';\n if (!opt_diagonal) {\n // This is the most common case, so we avoid the for loop.\n vec[0] = mat[0];\n vec[1] = mat[5];\n vec[2] = mat[10];\n vec[3] = mat[15];\n } else {\n const offset = opt_diagonal > 0 ? 4 * opt_diagonal : -opt_diagonal;\n for (let i = 0; i < 4 - Math.abs(opt_diagonal); i++) {\n vec[i] = mat[offset + 5 * i];\n }\n }\n return vec;\n};\n\n\n/**\n * Sets the specified column with the supplied values.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {number} v0 The value for row 0.\n * @param {number} v1 The value for row 1.\n * @param {number} v2 The value for row 2.\n * @param {number} v3 The value for row 3.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setColumnValues = function(mat, column, v0, v1, v2, v3) {\n 'use strict';\n const i = column * 4;\n mat[i] = v0;\n mat[i + 1] = v1;\n mat[i + 2] = v2;\n mat[i + 3] = v3;\n return mat;\n};\n\n\n/**\n * Sets the specified column with the value from the supplied vector.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the values.\n * @param {number} column The column index to set the values on.\n * @param {!goog.vec.vec4d.Type} vec The vector of elements for the column.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 4;\n mat[i] = vec[0];\n mat[i + 1] = vec[1];\n mat[i + 2] = vec[2];\n mat[i + 3] = vec[3];\n return mat;\n};\n\n\n/**\n * Retrieves the specified column from the matrix into the given vector.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix supplying the values.\n * @param {number} column The column to get the values from.\n * @param {!goog.vec.vec4d.Type} vec The vector of elements to\n * receive the column.\n * @return {!goog.vec.vec4d.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.getColumn = function(mat, column, vec) {\n 'use strict';\n const i = column * 4;\n vec[0] = mat[i];\n vec[1] = mat[i + 1];\n vec[2] = mat[i + 2];\n vec[3] = mat[i + 3];\n return vec;\n};\n\n\n/**\n * Sets the columns of the matrix from the given vectors.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec4d.Type} vec0 The values for column 0.\n * @param {!goog.vec.vec4d.Type} vec1 The values for column 1.\n * @param {!goog.vec.vec4d.Type} vec2 The values for column 2.\n * @param {!goog.vec.vec4d.Type} vec3 The values for column 3.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setColumns = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n mat[0] = vec0[0];\n mat[1] = vec0[1];\n mat[2] = vec0[2];\n mat[3] = vec0[3];\n mat[4] = vec1[0];\n mat[5] = vec1[1];\n mat[6] = vec1[2];\n mat[7] = vec1[3];\n mat[8] = vec2[0];\n mat[9] = vec2[1];\n mat[10] = vec2[2];\n mat[11] = vec2[3];\n mat[12] = vec3[0];\n mat[13] = vec3[1];\n mat[14] = vec3[2];\n mat[15] = vec3[3];\n return mat;\n};\n\n\n/**\n * Retrieves the column values from the given matrix into the given vectors.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix supplying the columns.\n * @param {!goog.vec.vec4d.Type} vec0 The vector to receive column 0.\n * @param {!goog.vec.vec4d.Type} vec1 The vector to receive column 1.\n * @param {!goog.vec.vec4d.Type} vec2 The vector to receive column 2.\n * @param {!goog.vec.vec4d.Type} vec3 The vector to receive column 3.\n */\ngoog.vec.mat4d.getColumns = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n vec0[0] = mat[0];\n vec0[1] = mat[1];\n vec0[2] = mat[2];\n vec0[3] = mat[3];\n vec1[0] = mat[4];\n vec1[1] = mat[5];\n vec1[2] = mat[6];\n vec1[3] = mat[7];\n vec2[0] = mat[8];\n vec2[1] = mat[9];\n vec2[2] = mat[10];\n vec2[3] = mat[11];\n vec3[0] = mat[12];\n vec3[1] = mat[13];\n vec3[2] = mat[14];\n vec3[3] = mat[15];\n};\n\n\n/**\n * Sets the row values from the supplied values.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the values.\n * @param {number} row The index of the row to receive the values.\n * @param {number} v0 The value for column 0.\n * @param {number} v1 The value for column 1.\n * @param {number} v2 The value for column 2.\n * @param {number} v3 The value for column 3.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setRowValues = function(mat, row, v0, v1, v2, v3) {\n 'use strict';\n mat[row] = v0;\n mat[row + 4] = v1;\n mat[row + 8] = v2;\n mat[row + 12] = v3;\n return mat;\n};\n\n\n/**\n * Sets the row values from the supplied vector.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the row values.\n * @param {number} row The index of the row.\n * @param {!goog.vec.vec4d.Type} vec The vector containing the values.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setRow = function(mat, row, vec) {\n 'use strict';\n mat[row] = vec[0];\n mat[row + 4] = vec[1];\n mat[row + 8] = vec[2];\n mat[row + 12] = vec[3];\n return mat;\n};\n\n\n/**\n * Retrieves the row values into the given vector.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix supplying the values.\n * @param {number} row The index of the row supplying the values.\n * @param {!goog.vec.vec4d.Type} vec The vector to receive the row.\n * @return {!goog.vec.vec4d.Type} return vec so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.getRow = function(mat, row, vec) {\n 'use strict';\n vec[0] = mat[row];\n vec[1] = mat[row + 4];\n vec[2] = mat[row + 8];\n vec[3] = mat[row + 12];\n return vec;\n};\n\n\n/**\n * Sets the rows of the matrix from the supplied vectors.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to receive the values.\n * @param {!goog.vec.vec4d.Type} vec0 The values for row 0.\n * @param {!goog.vec.vec4d.Type} vec1 The values for row 1.\n * @param {!goog.vec.vec4d.Type} vec2 The values for row 2.\n * @param {!goog.vec.vec4d.Type} vec3 The values for row 3.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.setRows = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n mat[0] = vec0[0];\n mat[1] = vec1[0];\n mat[2] = vec2[0];\n mat[3] = vec3[0];\n mat[4] = vec0[1];\n mat[5] = vec1[1];\n mat[6] = vec2[1];\n mat[7] = vec3[1];\n mat[8] = vec0[2];\n mat[9] = vec1[2];\n mat[10] = vec2[2];\n mat[11] = vec3[2];\n mat[12] = vec0[3];\n mat[13] = vec1[3];\n mat[14] = vec2[3];\n mat[15] = vec3[3];\n return mat;\n};\n\n\n/**\n * Retrieves the rows of the matrix into the supplied vectors.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to supply the values.\n * @param {!goog.vec.vec4d.Type} vec0 The vector to receive row 0.\n * @param {!goog.vec.vec4d.Type} vec1 The vector to receive row 1.\n * @param {!goog.vec.vec4d.Type} vec2 The vector to receive row 2.\n * @param {!goog.vec.vec4d.Type} vec3 The vector to receive row 3.\n */\ngoog.vec.mat4d.getRows = function(mat, vec0, vec1, vec2, vec3) {\n 'use strict';\n vec0[0] = mat[0];\n vec1[0] = mat[1];\n vec2[0] = mat[2];\n vec3[0] = mat[3];\n vec0[1] = mat[4];\n vec1[1] = mat[5];\n vec2[1] = mat[6];\n vec3[1] = mat[7];\n vec0[2] = mat[8];\n vec1[2] = mat[9];\n vec2[2] = mat[10];\n vec3[2] = mat[11];\n vec0[3] = mat[12];\n vec1[3] = mat[13];\n vec2[3] = mat[14];\n vec3[3] = mat[15];\n};\n\n\n/**\n * Makes the given 4x4 matrix the zero matrix.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @return {!goog.vec.mat4d.Type} return mat so operations can be chained.\n */\ngoog.vec.mat4d.makeZero = function(mat) {\n 'use strict';\n mat[0] = 0;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 0;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 0;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 0;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix the identity matrix.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @return {!goog.vec.mat4d.Type} return mat so operations can be chained.\n */\ngoog.vec.mat4d.makeIdentity = function(mat) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 1;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 1;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Performs a per-component addition of the matrix mat0 and mat1, storing\n * the result into resultMat.\n *\n * @param {!goog.vec.mat4d.Type} mat0 The first addend.\n * @param {!goog.vec.mat4d.Type} mat1 The second addend.\n * @param {!goog.vec.mat4d.Type} resultMat The matrix to\n * receive the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat4d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.addMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] + mat1[0];\n resultMat[1] = mat0[1] + mat1[1];\n resultMat[2] = mat0[2] + mat1[2];\n resultMat[3] = mat0[3] + mat1[3];\n resultMat[4] = mat0[4] + mat1[4];\n resultMat[5] = mat0[5] + mat1[5];\n resultMat[6] = mat0[6] + mat1[6];\n resultMat[7] = mat0[7] + mat1[7];\n resultMat[8] = mat0[8] + mat1[8];\n resultMat[9] = mat0[9] + mat1[9];\n resultMat[10] = mat0[10] + mat1[10];\n resultMat[11] = mat0[11] + mat1[11];\n resultMat[12] = mat0[12] + mat1[12];\n resultMat[13] = mat0[13] + mat1[13];\n resultMat[14] = mat0[14] + mat1[14];\n resultMat[15] = mat0[15] + mat1[15];\n return resultMat;\n};\n\n\n/**\n * Performs a per-component subtraction of the matrix mat0 and mat1,\n * storing the result into resultMat.\n *\n * @param {!goog.vec.mat4d.Type} mat0 The minuend.\n * @param {!goog.vec.mat4d.Type} mat1 The subtrahend.\n * @param {!goog.vec.mat4d.Type} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat4d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.subMat = function(mat0, mat1, resultMat) {\n 'use strict';\n resultMat[0] = mat0[0] - mat1[0];\n resultMat[1] = mat0[1] - mat1[1];\n resultMat[2] = mat0[2] - mat1[2];\n resultMat[3] = mat0[3] - mat1[3];\n resultMat[4] = mat0[4] - mat1[4];\n resultMat[5] = mat0[5] - mat1[5];\n resultMat[6] = mat0[6] - mat1[6];\n resultMat[7] = mat0[7] - mat1[7];\n resultMat[8] = mat0[8] - mat1[8];\n resultMat[9] = mat0[9] - mat1[9];\n resultMat[10] = mat0[10] - mat1[10];\n resultMat[11] = mat0[11] - mat1[11];\n resultMat[12] = mat0[12] - mat1[12];\n resultMat[13] = mat0[13] - mat1[13];\n resultMat[14] = mat0[14] - mat1[14];\n resultMat[15] = mat0[15] - mat1[15];\n return resultMat;\n};\n\n\n/**\n * Multiplies matrix mat with the given scalar, storing the result\n * into resultMat.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} scalar The scalar value to multiply to each element of mat.\n * @param {!goog.vec.mat4d.Type} resultMat The matrix to receive\n * the results (may be mat).\n * @return {!goog.vec.mat4d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.multScalar = function(mat, scalar, resultMat) {\n 'use strict';\n resultMat[0] = mat[0] * scalar;\n resultMat[1] = mat[1] * scalar;\n resultMat[2] = mat[2] * scalar;\n resultMat[3] = mat[3] * scalar;\n resultMat[4] = mat[4] * scalar;\n resultMat[5] = mat[5] * scalar;\n resultMat[6] = mat[6] * scalar;\n resultMat[7] = mat[7] * scalar;\n resultMat[8] = mat[8] * scalar;\n resultMat[9] = mat[9] * scalar;\n resultMat[10] = mat[10] * scalar;\n resultMat[11] = mat[11] * scalar;\n resultMat[12] = mat[12] * scalar;\n resultMat[13] = mat[13] * scalar;\n resultMat[14] = mat[14] * scalar;\n resultMat[15] = mat[15] * scalar;\n return resultMat;\n};\n\n\n/**\n * Multiplies the two matrices mat0 and mat1 using matrix multiplication,\n * storing the result into resultMat.\n *\n * @param {!goog.vec.mat4d.Type} mat0 The first (left hand) matrix.\n * @param {!goog.vec.mat4d.Type} mat1 The second (right hand) matrix.\n * @param {!goog.vec.mat4d.Type} resultMat The matrix to receive\n * the results (may be either mat0 or mat1).\n * @return {!goog.vec.mat4d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.multMat = function(mat0, mat1, resultMat) {\n 'use strict';\n const a00 = mat0[0];\n const a10 = mat0[1];\n const a20 = mat0[2];\n const a30 = mat0[3];\n\n const a01 = mat0[4];\n const a11 = mat0[5];\n const a21 = mat0[6];\n const a31 = mat0[7];\n\n const a02 = mat0[8];\n const a12 = mat0[9];\n const a22 = mat0[10];\n const a32 = mat0[11];\n\n const a03 = mat0[12];\n const a13 = mat0[13];\n const a23 = mat0[14];\n const a33 = mat0[15];\n\n\n const b00 = mat1[0];\n const b10 = mat1[1];\n const b20 = mat1[2];\n const b30 = mat1[3];\n\n const b01 = mat1[4];\n const b11 = mat1[5];\n const b21 = mat1[6];\n const b31 = mat1[7];\n\n const b02 = mat1[8];\n const b12 = mat1[9];\n const b22 = mat1[10];\n const b32 = mat1[11];\n\n const b03 = mat1[12];\n const b13 = mat1[13];\n const b23 = mat1[14];\n const b33 = mat1[15];\n\n\n resultMat[0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;\n resultMat[1] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;\n resultMat[2] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;\n resultMat[3] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;\n\n resultMat[4] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;\n resultMat[5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;\n resultMat[6] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;\n resultMat[7] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;\n\n resultMat[8] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;\n resultMat[9] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;\n resultMat[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;\n resultMat[11] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;\n\n resultMat[12] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;\n resultMat[13] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;\n resultMat[14] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;\n resultMat[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;\n return resultMat;\n};\n\n\n/**\n * Transposes the given matrix mat storing the result into resultMat.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to transpose.\n * @param {!goog.vec.mat4d.Type} resultMat The matrix to receive\n * the results (may be mat).\n * @return {!goog.vec.mat4d.Type} return resultMat so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.transpose = function(mat, resultMat) {\n 'use strict';\n if (resultMat == mat) {\n const a10 = mat[1];\n const a20 = mat[2];\n const a30 = mat[3];\n\n const a21 = mat[6];\n const a31 = mat[7];\n\n const a32 = mat[11];\n resultMat[1] = mat[4];\n resultMat[2] = mat[8];\n resultMat[3] = mat[12];\n resultMat[4] = a10;\n resultMat[6] = mat[9];\n resultMat[7] = mat[13];\n resultMat[8] = a20;\n resultMat[9] = a21;\n resultMat[11] = mat[14];\n resultMat[12] = a30;\n resultMat[13] = a31;\n resultMat[14] = a32;\n } else {\n resultMat[0] = mat[0];\n resultMat[1] = mat[4];\n resultMat[2] = mat[8];\n resultMat[3] = mat[12];\n\n resultMat[4] = mat[1];\n resultMat[5] = mat[5];\n resultMat[6] = mat[9];\n resultMat[7] = mat[13];\n\n resultMat[8] = mat[2];\n resultMat[9] = mat[6];\n resultMat[10] = mat[10];\n resultMat[11] = mat[14];\n\n resultMat[12] = mat[3];\n resultMat[13] = mat[7];\n resultMat[14] = mat[11];\n resultMat[15] = mat[15];\n }\n return resultMat;\n};\n\n\n/**\n * Computes the determinant of the matrix.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to compute the matrix for.\n * @return {number} The determinant of the matrix.\n */\ngoog.vec.mat4d.determinant = function(mat) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n const m03 = mat[12];\n const m13 = mat[13];\n const m23 = mat[14];\n const m33 = mat[15];\n\n\n const a0 = m00 * m11 - m10 * m01;\n const a1 = m00 * m21 - m20 * m01;\n const a2 = m00 * m31 - m30 * m01;\n const a3 = m10 * m21 - m20 * m11;\n const a4 = m10 * m31 - m30 * m11;\n const a5 = m20 * m31 - m30 * m21;\n const b0 = m02 * m13 - m12 * m03;\n const b1 = m02 * m23 - m22 * m03;\n const b2 = m02 * m33 - m32 * m03;\n const b3 = m12 * m23 - m22 * m13;\n const b4 = m12 * m33 - m32 * m13;\n const b5 = m22 * m33 - m32 * m23;\n\n return a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;\n};\n\n\n/**\n * Computes the inverse of mat storing the result into resultMat. If the\n * inverse is defined, this function returns true, false otherwise.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix to invert.\n * @param {!goog.vec.mat4d.Type} resultMat The matrix to receive\n * the result (may be mat).\n * @return {boolean} True if the inverse is defined. If false is returned,\n * resultMat is not modified.\n */\ngoog.vec.mat4d.invert = function(mat, resultMat) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n const m03 = mat[12];\n const m13 = mat[13];\n const m23 = mat[14];\n const m33 = mat[15];\n\n\n const a0 = m00 * m11 - m10 * m01;\n const a1 = m00 * m21 - m20 * m01;\n const a2 = m00 * m31 - m30 * m01;\n const a3 = m10 * m21 - m20 * m11;\n const a4 = m10 * m31 - m30 * m11;\n const a5 = m20 * m31 - m30 * m21;\n const b0 = m02 * m13 - m12 * m03;\n const b1 = m02 * m23 - m22 * m03;\n const b2 = m02 * m33 - m32 * m03;\n const b3 = m12 * m23 - m22 * m13;\n const b4 = m12 * m33 - m32 * m13;\n const b5 = m22 * m33 - m32 * m23;\n\n const det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;\n if (det == 0) {\n return false;\n }\n\n const idet = 1.0 / det;\n resultMat[0] = (m11 * b5 - m21 * b4 + m31 * b3) * idet;\n resultMat[1] = (-m10 * b5 + m20 * b4 - m30 * b3) * idet;\n resultMat[2] = (m13 * a5 - m23 * a4 + m33 * a3) * idet;\n resultMat[3] = (-m12 * a5 + m22 * a4 - m32 * a3) * idet;\n resultMat[4] = (-m01 * b5 + m21 * b2 - m31 * b1) * idet;\n resultMat[5] = (m00 * b5 - m20 * b2 + m30 * b1) * idet;\n resultMat[6] = (-m03 * a5 + m23 * a2 - m33 * a1) * idet;\n resultMat[7] = (m02 * a5 - m22 * a2 + m32 * a1) * idet;\n resultMat[8] = (m01 * b4 - m11 * b2 + m31 * b0) * idet;\n resultMat[9] = (-m00 * b4 + m10 * b2 - m30 * b0) * idet;\n resultMat[10] = (m03 * a4 - m13 * a2 + m33 * a0) * idet;\n resultMat[11] = (-m02 * a4 + m12 * a2 - m32 * a0) * idet;\n resultMat[12] = (-m01 * b3 + m11 * b1 - m21 * b0) * idet;\n resultMat[13] = (m00 * b3 - m10 * b1 + m20 * b0) * idet;\n resultMat[14] = (-m03 * a3 + m13 * a1 - m23 * a0) * idet;\n resultMat[15] = (m02 * a3 - m12 * a1 + m22 * a0) * idet;\n return true;\n};\n\n\n/**\n * Returns true if the components of mat0 are equal to the components of mat1.\n *\n * @param {!goog.vec.mat4d.Type} mat0 The first matrix.\n * @param {!goog.vec.mat4d.Type} mat1 The second matrix.\n * @return {boolean} True if the two matrices are equivalent.\n */\ngoog.vec.mat4d.equals = function(mat0, mat1) {\n 'use strict';\n return mat0.length == mat1.length && mat0[0] == mat1[0] &&\n mat0[1] == mat1[1] && mat0[2] == mat1[2] && mat0[3] == mat1[3] &&\n mat0[4] == mat1[4] && mat0[5] == mat1[5] && mat0[6] == mat1[6] &&\n mat0[7] == mat1[7] && mat0[8] == mat1[8] && mat0[9] == mat1[9] &&\n mat0[10] == mat1[10] && mat0[11] == mat1[11] && mat0[12] == mat1[12] &&\n mat0[13] == mat1[13] && mat0[14] == mat1[14] && mat0[15] == mat1[15];\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * upper 3x4 matrix omitting the projective component.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec3d.Type} vec The 3 element vector to transform.\n * @param {!goog.vec.vec3d.Type} resultVec The 3 element vector to\n * receive the results (may be vec).\n * @return {!goog.vec.vec3d.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.multVec3 = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8] + mat[12];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9] + mat[13];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10] + mat[14];\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * upper 3x3 matrix omitting the projective component and translation\n * components.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec3d.Type} vec The 3 element vector to transform.\n * @param {!goog.vec.vec3d.Type} resultVec The 3 element vector to\n * receive the results (may be vec).\n * @return {!goog.vec.vec3d.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.multVec3NoTranslate = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10];\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec. The input vector is multiplied against the\n * full 4x4 matrix with the homogeneous divide applied to reduce the 4 element\n * vector to a 3 element vector.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec3d.Type} vec The 3 element vector to transform.\n * @param {!goog.vec.vec3d.Type} resultVec The 3 element vector\n * to receive the results (may be vec).\n * @return {!goog.vec.vec3d.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.multVec3Projective = function(mat, vec, resultVec) {\n 'use strict';\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n const invw = 1 / (x * mat[3] + y * mat[7] + z * mat[11] + mat[15]);\n resultVec[0] = (x * mat[0] + y * mat[4] + z * mat[8] + mat[12]) * invw;\n resultVec[1] = (x * mat[1] + y * mat[5] + z * mat[9] + mat[13]) * invw;\n resultVec[2] = (x * mat[2] + y * mat[6] + z * mat[10] + mat[14]) * invw;\n return resultVec;\n};\n\n\n/**\n * Transforms the given vector with the given matrix storing the resulting,\n * transformed vector into resultVec.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix supplying the transformation.\n * @param {!goog.vec.vec4d.Type} vec The vector to transform.\n * @param {!goog.vec.vec4d.Type} resultVec The vector to\n * receive the results (may be vec).\n * @return {!goog.vec.vec4d.Type} return resultVec so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.multVec4 = function(mat, vec, resultVec) {\n 'use strict';\n const w = vec[3];\n const x = vec[0];\n const y = vec[1];\n const z = vec[2];\n\n resultVec[0] = x * mat[0] + y * mat[4] + z * mat[8] + w * mat[12];\n resultVec[1] = x * mat[1] + y * mat[5] + z * mat[9] + w * mat[13];\n resultVec[2] = x * mat[2] + y * mat[6] + z * mat[10] + w * mat[14];\n resultVec[3] = x * mat[3] + y * mat[7] + z * mat[11] + w * mat[15];\n return resultVec;\n};\n\n\n/**\n * Makes the given 4x4 matrix a translation matrix with x, y and z\n * translation factors.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @param {number} z The translation along the z axis.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeTranslate = function(mat, x, y, z) {\n 'use strict';\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 1;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 1;\n mat[11] = 0;\n mat[12] = x;\n mat[13] = y;\n mat[14] = z;\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix as a scale matrix with x, y and z scale factors.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} x The scale along the x axis.\n * @param {number} y The scale along the y axis.\n * @param {number} z The scale along the z axis.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeScale = function(mat, x, y, z) {\n 'use strict';\n mat[0] = x;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = y;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = z;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the axis defined by the vector (ax, ay, az).\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @param {number} ax The x component of the rotation axis.\n * @param {number} ay The y component of the rotation axis.\n * @param {number} az The z component of the rotation axis.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeRotate = function(mat, angle, ax, ay, az) {\n 'use strict';\n const c = Math.cos(angle);\n const d = 1 - c;\n const s = Math.sin(angle);\n\n mat[0] = ax * ax * d + c;\n mat[1] = ax * ay * d + az * s;\n mat[2] = ax * az * d - ay * s;\n mat[3] = 0;\n mat[4] = ax * ay * d - az * s;\n mat[5] = ay * ay * d + c;\n mat[6] = ay * az * d + ax * s;\n mat[7] = 0;\n mat[8] = ax * az * d + ay * s;\n mat[9] = ay * az * d - ax * s;\n mat[10] = az * az * d + c;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the X axis.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeRotateX = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = 1;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = c;\n mat[6] = s;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = -s;\n mat[10] = c;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the Y axis.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeRotateY = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = c;\n mat[1] = 0;\n mat[2] = -s;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = 1;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = s;\n mat[9] = 0;\n mat[10] = c;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix with the given rotation\n * angle about the Z axis.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} angle The rotation angle in radians.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeRotateZ = function(mat, angle) {\n 'use strict';\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = c;\n mat[1] = s;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = -s;\n mat[5] = c;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = 1;\n mat[11] = 0;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Creates a matrix from a quaternion rotation and vector translation.\n *\n * This is a specialization of makeRotationTranslationScaleOrigin.\n *\n * This is equivalent to, but faster than:\n * goog.vec.mat4d.makeIdentity(m);\n * goog.vec.mat4d.translate(m, tx, ty, tz);\n * goog.vec.mat4d.rotate(m, theta, rx, ry, rz);\n * and:\n * goog.vec.Quaternion.toRotationMatrix4(rotation, mat);\n * mat[12] = translation[0];\n * mat[13] = translation[1];\n * mat[14] = translation[2];\n * See http://jsperf.com/goog-vec-makerotationtranslation2 .\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {!goog.vec.Quaternion.AnyType} rotation The quaternion rotation.\n * Note: this quaternion is assumed to already be normalized.\n * @param {!goog.vec.vec3d.Type} translation The vector translation.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeRotationTranslation = function(mat, rotation, translation) {\n 'use strict';\n // Quaternion math\n const w = rotation[3];\n const x = rotation[0];\n const y = rotation[1];\n const z = rotation[2];\n\n const x2 = 2 * x;\n const y2 = 2 * y;\n const z2 = 2 * z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n mat[0] = 1 - (yy + zz);\n mat[1] = xy + wz;\n mat[2] = xz - wy;\n mat[3] = 0;\n mat[4] = xy - wz;\n mat[5] = 1 - (xx + zz);\n mat[6] = yz + wx;\n mat[7] = 0;\n mat[8] = xz + wy;\n mat[9] = yz - wx;\n mat[10] = 1 - (xx + yy);\n mat[11] = 0;\n mat[12] = translation[0];\n mat[13] = translation[1];\n mat[14] = translation[2];\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation, and\n * vector scale.\n *\n * This is a specialization of makeRotationTranslationScaleOrigin.\n *\n * This is equivalent to, but faster than:\n * goog.vec.mat4d.makeIdentity(m);\n * goog.vec.mat4d.translate(m, tx, ty, tz);\n * goog.vec.mat4d.rotate(m, theta, rx, ry, rz);\n * goog.vec.mat4d.scale(m, sx, sy, sz);\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {!goog.vec.Quaternion.AnyType} rotation The quaternion rotation.\n * Note: this quaternion is assumed to already be normalized.\n * @param {!goog.vec.vec3d.Type} translation The vector translation.\n * @param {!goog.vec.vec3d.Type} scale The vector scale.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeRotationTranslationScale = function(\n mat, rotation, translation, scale) {\n 'use strict';\n // Quaternion math\n const w = rotation[3];\n const x = rotation[0];\n const y = rotation[1];\n const z = rotation[2];\n\n const x2 = 2 * x;\n const y2 = 2 * y;\n const z2 = 2 * z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n const sx = scale[0];\n const sy = scale[1];\n const sz = scale[2];\n\n mat[0] = (1 - (yy + zz)) * sx;\n mat[1] = (xy + wz) * sx;\n mat[2] = (xz - wy) * sx;\n mat[3] = 0;\n mat[4] = (xy - wz) * sy;\n mat[5] = (1 - (xx + zz)) * sy;\n mat[6] = (yz + wx) * sy;\n mat[7] = 0;\n mat[8] = (xz + wy) * sz;\n mat[9] = (yz - wx) * sz;\n mat[10] = (1 - (xx + yy)) * sz;\n mat[11] = 0;\n mat[12] = translation[0];\n mat[13] = translation[1];\n mat[14] = translation[2];\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation, and\n * vector scale, rotating and scaling about the given origin.\n *\n * This is equivalent to, but faster than:\n * goog.vec.mat4d.makeIdentity(m);\n * goog.vec.mat4d.translate(m, tx, ty, tz);\n * goog.vec.mat4d.translate(m, ox, oy, oz);\n * goog.vec.mat4d.rotate(m, theta, rx, ry, rz);\n * goog.vec.mat4d.scale(m, sx, sy, sz);\n * goog.vec.mat4d.translate(m, -ox, -oy, -oz);\n * See http://jsperf.com/glmatrix-matrix-variant-test/3 for performance\n * results of a similar function in the glmatrix library.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {!goog.vec.Quaternion.AnyType} rotation The quaternion rotation.\n * Note: this quaternion is assumed to already be normalized.\n * @param {!goog.vec.vec3d.Type} translation The vector translation.\n * @param {!goog.vec.vec3d.Type} scale The vector scale.\n * @param {!goog.vec.vec3d.Type} origin The origin about which to scale and\n * rotate.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeRotationTranslationScaleOrigin = function(\n mat, rotation, translation, scale, origin) {\n 'use strict';\n // Quaternion math\n const w = rotation[3];\n const x = rotation[0];\n const y = rotation[1];\n const z = rotation[2];\n\n const x2 = 2 * x;\n const y2 = 2 * y;\n const z2 = 2 * z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n const sx = scale[0];\n const sy = scale[1];\n const sz = scale[2];\n const ox = origin[0];\n const oy = origin[1];\n const oz = origin[2];\n\n mat[0] = (1 - (yy + zz)) * sx;\n mat[1] = (xy + wz) * sx;\n mat[2] = (xz - wy) * sx;\n mat[3] = 0;\n mat[4] = (xy - wz) * sy;\n mat[5] = (1 - (xx + zz)) * sy;\n mat[6] = (yz + wx) * sy;\n mat[7] = 0;\n mat[8] = (xz + wy) * sz;\n mat[9] = (yz - wx) * sz;\n mat[10] = (1 - (xx + yy)) * sz;\n mat[11] = 0;\n mat[12] = translation[0] + ox - (mat[0] * ox + mat[4] * oy + mat[8] * oz);\n mat[13] = translation[1] + oy - (mat[1] * ox + mat[5] * oy + mat[9] * oz);\n mat[14] = translation[2] + oz - (mat[2] * ox + mat[6] * oy + mat[10] * oz);\n mat[15] = 1;\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a perspective projection matrix.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} left The coordinate of the left clipping plane.\n * @param {number} right The coordinate of the right clipping plane.\n * @param {number} bottom The coordinate of the bottom clipping plane.\n * @param {number} top The coordinate of the top clipping plane.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeFrustum = function(\n mat, left, right, bottom, top, near, far) {\n 'use strict';\n const x = (2 * near) / (right - left);\n const y = (2 * near) / (top - bottom);\n const a = (right + left) / (right - left);\n const b = (top + bottom) / (top - bottom);\n const c = -(far + near) / (far - near);\n const d = -(2 * far * near) / (far - near);\n\n mat[0] = x;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = y;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = a;\n mat[9] = b;\n mat[10] = c;\n mat[11] = -1;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = d;\n mat[15] = 0;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix perspective projection matrix given a\n * field of view and aspect ratio.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} fovy The field of view along the y (vertical) axis in\n * radians.\n * @param {number} aspect The x (width) to y (height) aspect ratio.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makePerspective = function(mat, fovy, aspect, near, far) {\n 'use strict';\n const angle = fovy / 2;\n const dz = far - near;\n const sinAngle = Math.sin(angle);\n if (dz == 0 || sinAngle == 0 || aspect == 0) {\n return mat;\n }\n\n const cot = Math.cos(angle) / sinAngle;\n\n mat[0] = cot / aspect;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = cot;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = -(far + near) / dz;\n mat[11] = -1;\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = -(2 * near * far) / dz;\n mat[15] = 0;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix an orthographic projection matrix.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} left The coordinate of the left clipping plane.\n * @param {number} right The coordinate of the right clipping plane.\n * @param {number} bottom The coordinate of the bottom clipping plane.\n * @param {number} top The coordinate of the top clipping plane.\n * @param {number} near The distance to the near clipping plane.\n * @param {number} far The distance to the far clipping plane.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeOrtho = function(mat, left, right, bottom, top, near, far) {\n 'use strict';\n const x = 2 / (right - left);\n const y = 2 / (top - bottom);\n const z = -2 / (far - near);\n const a = -(right + left) / (right - left);\n const b = -(top + bottom) / (top - bottom);\n const c = -(far + near) / (far - near);\n\n mat[0] = x;\n mat[1] = 0;\n mat[2] = 0;\n mat[3] = 0;\n mat[4] = 0;\n mat[5] = y;\n mat[6] = 0;\n mat[7] = 0;\n mat[8] = 0;\n mat[9] = 0;\n mat[10] = z;\n mat[11] = 0;\n mat[12] = a;\n mat[13] = b;\n mat[14] = c;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Makes the given 4x4 matrix a modelview matrix of a camera so that\n * the camera is 'looking at' the given center point.\n *\n * Note that unlike most other goog.vec functions where we inline\n * everything, this function does not inline various goog.vec\n * functions. This makes the code more readable, but somewhat\n * less efficient.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {!goog.vec.vec3d.Type} eyePt The position of the eye point\n * (camera origin).\n * @param {!goog.vec.vec3d.Type} centerPt The point to aim the camera at.\n * @param {!goog.vec.vec3d.Type} worldUpVec The vector that identifies\n * the up direction for the camera.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeLookAt = function(mat, eyePt, centerPt, worldUpVec) {\n 'use strict';\n // Compute the direction vector from the eye point to the center point and\n // normalize.\n const fwdVec = goog.vec.mat4d.tmpvec4d_[0];\n goog.vec.vec3d.subtract(centerPt, eyePt, fwdVec);\n goog.vec.vec3d.normalize(fwdVec, fwdVec);\n fwdVec[3] = 0;\n\n // Compute the side vector from the forward vector and the input up vector.\n const sideVec = goog.vec.mat4d.tmpvec4d_[1];\n goog.vec.vec3d.cross(fwdVec, worldUpVec, sideVec);\n goog.vec.vec3d.normalize(sideVec, sideVec);\n sideVec[3] = 0;\n\n // Now the up vector to form the orthonormal basis.\n const upVec = goog.vec.mat4d.tmpvec4d_[2];\n goog.vec.vec3d.cross(sideVec, fwdVec, upVec);\n goog.vec.vec3d.normalize(upVec, upVec);\n upVec[3] = 0;\n\n // Update the view matrix with the new orthonormal basis and position the\n // camera at the given eye point.\n goog.vec.vec3d.negate(fwdVec, fwdVec);\n goog.vec.mat4d.setRow(mat, 0, sideVec);\n goog.vec.mat4d.setRow(mat, 1, upVec);\n goog.vec.mat4d.setRow(mat, 2, fwdVec);\n goog.vec.mat4d.setRowValues(mat, 3, 0, 0, 0, 1);\n goog.vec.mat4d.translate(mat, -eyePt[0], -eyePt[1], -eyePt[2]);\n\n return mat;\n};\n\n\n/**\n * Decomposes a matrix into the lookAt vectors eyePt, fwdVec and worldUpVec.\n * The matrix represents the modelview matrix of a camera. It is the inverse\n * of lookAt except for the output of the fwdVec instead of centerPt.\n * The centerPt itself cannot be recovered from a modelview matrix.\n *\n * Note that unlike most other goog.vec functions where we inline\n * everything, this function does not inline various goog.vec\n * functions. This makes the code more readable, but somewhat\n * less efficient.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {!goog.vec.vec3d.Type} eyePt The position of the eye point\n * (camera origin).\n * @param {!goog.vec.vec3d.Type} fwdVec The vector describing where\n * the camera points to.\n * @param {!goog.vec.vec3d.Type} worldUpVec The vector that\n * identifies the up direction for the camera.\n * @return {boolean} True if the method succeeds, false otherwise.\n * The method can only fail if the inverse of viewMatrix is not defined.\n */\ngoog.vec.mat4d.toLookAt = function(mat, eyePt, fwdVec, worldUpVec) {\n 'use strict';\n // Get eye of the camera.\n const matInverse = goog.vec.mat4d.tmpmat4d_[0];\n if (!goog.vec.mat4d.invert(mat, matInverse)) {\n // The input matrix does not have a valid inverse.\n return false;\n }\n\n if (eyePt) {\n eyePt[0] = matInverse[12];\n eyePt[1] = matInverse[13];\n eyePt[2] = matInverse[14];\n }\n\n // Get forward vector from the definition of lookAt.\n if (fwdVec || worldUpVec) {\n if (!fwdVec) {\n fwdVec = goog.vec.mat4d.tmpvec3d_[0];\n }\n fwdVec[0] = -mat[2];\n fwdVec[1] = -mat[6];\n fwdVec[2] = -mat[10];\n // Normalize forward vector.\n goog.vec.vec3d.normalize(fwdVec, fwdVec);\n }\n\n if (worldUpVec) {\n // Get side vector from the definition of gluLookAt.\n const side = goog.vec.mat4d.tmpvec3d_[1];\n side[0] = mat[0];\n side[1] = mat[4];\n side[2] = mat[8];\n // Compute up vector as a up = side x forward.\n goog.vec.vec3d.cross(side, fwdVec, worldUpVec);\n // Normalize up vector.\n goog.vec.vec3d.normalize(worldUpVec, worldUpVec);\n }\n return true;\n};\n\n\n/**\n * Makes the given 4x4 matrix a rotation matrix given Euler angles using\n * the ZXZ convention.\n * Given the euler angles [theta1, theta2, theta3], the rotation is defined as\n * rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians,\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} theta1 The angle of rotation around the Z axis in radians.\n * @param {number} theta2 The angle of rotation around the X axis in radians.\n * @param {number} theta3 The angle of rotation around the Z axis in radians.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.makeEulerZXZ = function(mat, theta1, theta2, theta3) {\n 'use strict';\n const c1 = Math.cos(theta1);\n const s1 = Math.sin(theta1);\n\n const c2 = Math.cos(theta2);\n const s2 = Math.sin(theta2);\n\n const c3 = Math.cos(theta3);\n const s3 = Math.sin(theta3);\n\n mat[0] = c1 * c3 - c2 * s1 * s3;\n mat[1] = c2 * c1 * s3 + c3 * s1;\n mat[2] = s3 * s2;\n mat[3] = 0;\n\n mat[4] = -c1 * s3 - c3 * c2 * s1;\n mat[5] = c1 * c2 * c3 - s1 * s3;\n mat[6] = c3 * s2;\n mat[7] = 0;\n\n mat[8] = s2 * s1;\n mat[9] = -c1 * s2;\n mat[10] = c2;\n mat[11] = 0;\n\n mat[12] = 0;\n mat[13] = 0;\n mat[14] = 0;\n mat[15] = 1;\n\n return mat;\n};\n\n\n/**\n * Decomposes a rotation matrix into Euler angles using the ZXZ convention so\n * that rotation = rotation_z(theta1) * rotation_x(theta2) * rotation_z(theta3),\n * with theta1 in [0, 2 * pi], theta2 in [0, pi] and theta3 in [0, 2 * pi].\n * rotation_x(theta) means rotation around the X axis of theta radians.\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {!goog.vec.vec3d.Type} euler The ZXZ Euler angles in\n * radians as [theta1, theta2, theta3].\n * @param {boolean=} opt_theta2IsNegative Whether theta2 is in [-pi, 0] instead\n * of the default [0, pi].\n * @return {!goog.vec.vec4d.Type} return euler so that operations can be\n * chained together.\n */\ngoog.vec.mat4d.toEulerZXZ = function(mat, euler, opt_theta2IsNegative) {\n 'use strict';\n // There is an ambiguity in the sign of sinTheta2 because of the sqrt.\n const sinTheta2 = Math.sqrt(mat[2] * mat[2] + mat[6] * mat[6]);\n\n // By default we explicitely constrain theta2 to be in [0, pi],\n // so sinTheta2 is always positive. We can change the behavior and specify\n // theta2 to be negative in [-pi, 0] with opt_Theta2IsNegative.\n const signTheta2 = opt_theta2IsNegative ? -1 : 1;\n\n if (sinTheta2 > goog.vec.EPSILON) {\n euler[2] = Math.atan2(mat[2] * signTheta2, mat[6] * signTheta2);\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[10]);\n euler[0] = Math.atan2(mat[8] * signTheta2, -mat[9] * signTheta2);\n } else {\n // There is also an arbitrary choice for theta1 = 0 or theta2 = 0 here.\n // We assume theta1 = 0 as some applications do not allow the camera to roll\n // (i.e. have theta1 != 0).\n euler[0] = 0;\n euler[1] = Math.atan2(sinTheta2 * signTheta2, mat[10]);\n euler[2] = Math.atan2(mat[1], mat[0]);\n }\n\n // Atan2 outputs angles in [-pi, pi] so we bring them back to [0, 2 * pi].\n euler[0] = (euler[0] + Math.PI * 2) % (Math.PI * 2);\n euler[2] = (euler[2] + Math.PI * 2) % (Math.PI * 2);\n // For theta2 we want the angle to be in [0, pi] or [-pi, 0] depending on\n // signTheta2.\n euler[1] =\n ((euler[1] * signTheta2 + Math.PI * 2) % (Math.PI * 2)) * signTheta2;\n\n return euler;\n};\n\n\n/**\n * Translates the given matrix by x,y,z. Equvialent to:\n * goog.vec.mat4d.multMat(\n * mat,\n * goog.vec.mat4d.makeTranslate(goog.vec.mat4d.create(), x, y, z),\n * mat);\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} x The translation along the x axis.\n * @param {number} y The translation along the y axis.\n * @param {number} z The translation along the z axis.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.translate = function(mat, x, y, z) {\n 'use strict';\n mat[12] += mat[0] * x + mat[4] * y + mat[8] * z;\n mat[13] += mat[1] * x + mat[5] * y + mat[9] * z;\n mat[14] += mat[2] * x + mat[6] * y + mat[10] * z;\n mat[15] += mat[3] * x + mat[7] * y + mat[11] * z;\n\n return mat;\n};\n\n\n/**\n * Scales the given matrix by x,y,z. Equivalent to:\n * goog.vec.mat4d.multMat(\n * mat,\n * goog.vec.mat4d.makeScale(goog.vec.mat4d.create(), x, y, z),\n * mat);\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} x The x scale factor.\n * @param {number} y The y scale factor.\n * @param {number} z The z scale factor.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.scale = function(mat, x, y, z) {\n 'use strict';\n mat[0] = mat[0] * x;\n mat[1] = mat[1] * x;\n mat[2] = mat[2] * x;\n mat[3] = mat[3] * x;\n mat[4] = mat[4] * y;\n mat[5] = mat[5] * y;\n mat[6] = mat[6] * y;\n mat[7] = mat[7] * y;\n mat[8] = mat[8] * z;\n mat[9] = mat[9] * z;\n mat[10] = mat[10] * z;\n mat[11] = mat[11] * z;\n mat[12] = mat[12];\n mat[13] = mat[13];\n mat[14] = mat[14];\n mat[15] = mat[15];\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the x,y,z axis. Equivalent to:\n * goog.vec.mat4d.multMat(\n * mat,\n * goog.vec.mat4d.makeRotate(goog.vec.mat4d.create(), angle, x, y, z),\n * mat);\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @param {number} x The x component of the rotation axis.\n * @param {number} y The y component of the rotation axis.\n * @param {number} z The z component of the rotation axis.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.rotate = function(mat, angle, x, y, z) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n\n const cosAngle = Math.cos(angle);\n const sinAngle = Math.sin(angle);\n const diffCosAngle = 1 - cosAngle;\n const r00 = x * x * diffCosAngle + cosAngle;\n const r10 = x * y * diffCosAngle + z * sinAngle;\n const r20 = x * z * diffCosAngle - y * sinAngle;\n\n const r01 = x * y * diffCosAngle - z * sinAngle;\n const r11 = y * y * diffCosAngle + cosAngle;\n const r21 = y * z * diffCosAngle + x * sinAngle;\n\n const r02 = x * z * diffCosAngle + y * sinAngle;\n const r12 = y * z * diffCosAngle - x * sinAngle;\n const r22 = z * z * diffCosAngle + cosAngle;\n\n mat[0] = m00 * r00 + m01 * r10 + m02 * r20;\n mat[1] = m10 * r00 + m11 * r10 + m12 * r20;\n mat[2] = m20 * r00 + m21 * r10 + m22 * r20;\n mat[3] = m30 * r00 + m31 * r10 + m32 * r20;\n mat[4] = m00 * r01 + m01 * r11 + m02 * r21;\n mat[5] = m10 * r01 + m11 * r11 + m12 * r21;\n mat[6] = m20 * r01 + m21 * r11 + m22 * r21;\n mat[7] = m30 * r01 + m31 * r11 + m32 * r21;\n mat[8] = m00 * r02 + m01 * r12 + m02 * r22;\n mat[9] = m10 * r02 + m11 * r12 + m12 * r22;\n mat[10] = m20 * r02 + m21 * r12 + m22 * r22;\n mat[11] = m30 * r02 + m31 * r12 + m32 * r22;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the x axis. Equivalent to:\n * goog.vec.mat4d.multMat(\n * mat,\n * goog.vec.mat4d.makeRotateX(goog.vec.mat4d.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.rotateX = function(mat, angle) {\n 'use strict';\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[4] = m01 * c + m02 * s;\n mat[5] = m11 * c + m12 * s;\n mat[6] = m21 * c + m22 * s;\n mat[7] = m31 * c + m32 * s;\n mat[8] = m01 * -s + m02 * c;\n mat[9] = m11 * -s + m12 * c;\n mat[10] = m21 * -s + m22 * c;\n mat[11] = m31 * -s + m32 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the y axis. Equivalent to:\n * goog.vec.mat4d.multMat(\n * mat,\n * goog.vec.mat4d.makeRotateY(goog.vec.mat4d.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.rotateY = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m02 = mat[8];\n const m12 = mat[9];\n const m22 = mat[10];\n const m32 = mat[11];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m02 * -s;\n mat[1] = m10 * c + m12 * -s;\n mat[2] = m20 * c + m22 * -s;\n mat[3] = m30 * c + m32 * -s;\n mat[8] = m00 * s + m02 * c;\n mat[9] = m10 * s + m12 * c;\n mat[10] = m20 * s + m22 * c;\n mat[11] = m30 * s + m32 * c;\n\n return mat;\n};\n\n\n/**\n * Rotate the given matrix by angle about the z axis. Equivalent to:\n * goog.vec.mat4d.multMat(\n * mat,\n * goog.vec.mat4d.makeRotateZ(goog.vec.mat4d.create(), angle),\n * mat);\n *\n * @param {!goog.vec.mat4d.Type} mat The matrix.\n * @param {number} angle The angle in radians.\n * @return {!goog.vec.mat4d.Type} return mat so that operations can be\n * chained.\n */\ngoog.vec.mat4d.rotateZ = function(mat, angle) {\n 'use strict';\n const m00 = mat[0];\n const m10 = mat[1];\n const m20 = mat[2];\n const m30 = mat[3];\n\n const m01 = mat[4];\n const m11 = mat[5];\n const m21 = mat[6];\n const m31 = mat[7];\n\n\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n\n mat[0] = m00 * c + m01 * s;\n mat[1] = m10 * c + m11 * s;\n mat[2] = m20 * c + m21 * s;\n mat[3] = m30 * c + m31 * s;\n mat[4] = m00 * -s + m01 * c;\n mat[5] = m10 * -s + m11 * c;\n mat[6] = m20 * -s + m21 * c;\n mat[7] = m30 * -s + m31 * c;\n\n return mat;\n};\n\n\n/**\n * Retrieves the translation component of the transformation matrix.\n *\n * @param {!goog.vec.mat4d.Type} mat The transformation matrix.\n * @param {!goog.vec.vec3d.Type} translation The vector for storing the\n * result.\n * @return {!goog.vec.vec3d.Type} return translation so that operations can be\n * chained.\n */\ngoog.vec.mat4d.getTranslation = function(mat, translation) {\n 'use strict';\n translation[0] = mat[12];\n translation[1] = mat[13];\n translation[2] = mat[14];\n return translation;\n};\n\n\n/**\n * @type {Array}\n * @private\n */\ngoog.vec.mat4d.tmpvec3d_ = [goog.vec.vec3d.create(), goog.vec.vec3d.create()];\n\n\n/**\n * @type {Array}\n * @private\n */\ngoog.vec.mat4d.tmpvec4d_ =\n [goog.vec.vec4d.create(), goog.vec.vec4d.create(), goog.vec.vec4d.create()];\n\n\n/**\n * @type {Array}\n * @private\n */\ngoog.vec.mat4d.tmpmat4d_ = [goog.vec.mat4d.create()];\n","^<",1684857788697,"^=",["^3",["^14","^>","^1A","^1S","^1I"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^14","^1A","^1S","^1I"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.vec.mat4d","goog.vec.mat4d.Type"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.vec","goog.vec.Quaternion","goog.vec.vec3d","goog.vec.vec4d"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/vec/mat4d.js"],"^[",["^3",["^1T","^1U"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^14","^1A","^1I","^1S"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.async.Delay"]],"^5","goog.async.delay.js","^6",["^7","goog/async/delay.js"],"^8","goog/async/delay.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Defines a class useful for handling functions that must be\n * invoked after a delay, especially when that delay is frequently restarted.\n * Examples include delaying before displaying a tooltip, menu hysteresis,\n * idle timers, etc.\n * @see ../demos/timers.html\n */\n\n\ngoog.provide('goog.async.Delay');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.Timer');\n\n\n\n/**\n * A Delay object invokes the associated function after a specified delay. The\n * interval duration can be specified once in the constructor, or can be defined\n * each time the delay is started. Calling start on an active delay will reset\n * the timer.\n *\n * @param {function(this:THIS)} listener Function to call when the\n * delay completes.\n * @param {number=} opt_interval The default length of the invocation delay (in\n * milliseconds).\n * @param {THIS=} opt_handler The object scope to invoke the function in.\n * @template THIS\n * @constructor\n * @struct\n * @extends {goog.Disposable}\n * @final\n */\ngoog.async.Delay = function(listener, opt_interval, opt_handler) {\n 'use strict';\n goog.async.Delay.base(this, 'constructor');\n\n /**\n * The function that will be invoked after a delay.\n * @private {function(this:THIS)}\n */\n this.listener_ = listener;\n\n /**\n * The default amount of time to delay before invoking the callback.\n * @type {number}\n * @private\n */\n this.interval_ = opt_interval || 0;\n\n /**\n * The object context to invoke the callback in.\n * @type {Object|undefined}\n * @private\n */\n this.handler_ = opt_handler;\n\n\n /**\n * Cached callback function invoked when the delay finishes.\n * @type {Function}\n * @private\n */\n this.callback_ = goog.bind(this.doAction_, this);\n};\ngoog.inherits(goog.async.Delay, goog.Disposable);\n\n\n/**\n * Identifier of the active delay timeout, or 0 when inactive.\n * @type {number}\n * @private\n */\ngoog.async.Delay.prototype.id_ = 0;\n\n\n/**\n * Disposes of the object, cancelling the timeout if it is still outstanding and\n * removing all object references.\n * @override\n * @protected\n */\ngoog.async.Delay.prototype.disposeInternal = function() {\n 'use strict';\n goog.async.Delay.base(this, 'disposeInternal');\n this.stop();\n delete this.listener_;\n delete this.handler_;\n};\n\n\n/**\n * Starts the delay timer. The provided listener function will be called after\n * the specified interval. Calling start on an active timer will reset the\n * delay interval.\n * @param {number=} opt_interval If specified, overrides the object's default\n * interval with this one (in milliseconds).\n */\ngoog.async.Delay.prototype.start = function(opt_interval) {\n 'use strict';\n this.stop();\n this.id_ = goog.Timer.callOnce(\n this.callback_,\n opt_interval !== undefined ? opt_interval : this.interval_);\n};\n\n\n/**\n * Starts the delay timer if it's not already active.\n * @param {number=} opt_interval If specified and the timer is not already\n * active, overrides the object's default interval with this one (in\n * milliseconds).\n */\ngoog.async.Delay.prototype.startIfNotActive = function(opt_interval) {\n 'use strict';\n if (!this.isActive()) {\n this.start(opt_interval);\n }\n};\n\n\n/**\n * Stops the delay timer if it is active. No action is taken if the timer is not\n * in use.\n */\ngoog.async.Delay.prototype.stop = function() {\n 'use strict';\n if (this.isActive()) {\n goog.Timer.clear(this.id_);\n }\n this.id_ = 0;\n};\n\n\n/**\n * Fires delay's action even if timer has already gone off or has not been\n * started yet; guarantees action firing. Stops the delay timer.\n */\ngoog.async.Delay.prototype.fire = function() {\n 'use strict';\n this.stop();\n this.doAction_();\n};\n\n\n/**\n * Fires delay's action only if timer is currently active. Stops the delay\n * timer.\n */\ngoog.async.Delay.prototype.fireIfActive = function() {\n 'use strict';\n if (this.isActive()) {\n this.fire();\n }\n};\n\n\n/**\n * @return {boolean} True if the delay is currently active, false otherwise.\n */\ngoog.async.Delay.prototype.isActive = function() {\n 'use strict';\n return this.id_ != 0;\n};\n\n\n/**\n * Invokes the callback function after the delay successfully completes.\n * @private\n */\ngoog.async.Delay.prototype.doAction_ = function() {\n 'use strict';\n this.id_ = 0;\n if (this.listener_) {\n this.listener_.call(this.handler_);\n }\n};\n","^<",1684857788697,"^=",["^3",["~$goog.Timer","^>","~$goog.Disposable"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^1W","^1X"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.async.Delay"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.Timer"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/delay.js"],"^[",["^3",["^1V"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1X","^1W"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.async.Throttle","~:ns","~$goog.async.Throttle","^U",true,"^5","goog.async.throttle.js","^6",["^7","goog/async/throttle.js"],"^8","goog/async/throttle.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of the goog.async.Throttle class.\n *\n * @see ../demos/timers.html\n */\n\ngoog.module('goog.async.Throttle');\ngoog.module.declareLegacyNamespace();\n\nconst Disposable = goog.require('goog.Disposable');\nconst Timer = goog.require('goog.Timer');\n\n\n/**\n * Throttle will perform an action that is passed in no more than once\n * per interval (specified in milliseconds). If it gets multiple signals\n * to perform the action while it is waiting, it will only perform the action\n * once at the end of the interval.\n * @final\n * @template T\n */\nclass Throttle extends Disposable {\n /**\n * @param {function(this: T, ...?)} listener Function to callback when the\n * action is triggered.\n * @param {number} interval Interval over which to throttle. The listener can\n * only be called once per interval.\n * @param {T=} handler Object in whose scope to call the listener.\n */\n constructor(listener, interval, handler) {\n super();\n /**\n * Function to callback\n * @type {function(this: T, ...?)}\n * @private\n */\n this.listener_ = handler != null ? listener.bind(handler) : listener;\n\n /**\n * Interval for the throttle time\n * @type {number}\n * @private\n */\n this.interval_ = interval;\n\n /**\n * The last arguments passed into `fire`, or null if there is no pending\n * call.\n * @private {?IArrayLike}\n */\n this.args_ = null;\n\n /**\n * Indicates that the action is pending and needs to be fired.\n * @type {boolean}\n * @private\n */\n this.shouldFire_ = false;\n\n /**\n * Indicates the count of nested pauses currently in effect on the throttle.\n * When this count is not zero, fired actions will be postponed until the\n * throttle is resumed enough times to drop the pause count to zero.\n * @type {number}\n * @private\n */\n this.pauseCount_ = 0;\n\n /**\n * Timer for scheduling the next callback\n * @type {?number}\n * @private\n */\n this.timer_ = null;\n }\n\n /**\n * Notifies the throttle that the action has happened. It will throttle\n * the call so that the callback is not called too often according to the\n * interval parameter passed to the constructor, passing the arguments\n * from the last call of this function into the throttled function.\n * @param {...?} var_args Arguments to pass on to the throttled function.\n */\n fire(var_args) {\n this.args_ = arguments;\n if (!this.timer_ && !this.pauseCount_) {\n this.doAction_();\n } else {\n this.shouldFire_ = true;\n }\n }\n\n /**\n * Cancels any pending action callback. The throttle can be restarted by\n * calling {@link #fire}.\n */\n stop() {\n if (this.timer_) {\n Timer.clear(this.timer_);\n this.timer_ = null;\n this.shouldFire_ = false;\n this.args_ = null;\n }\n }\n\n /**\n * Pauses the throttle. All pending and future action callbacks will be\n * delayed until the throttle is resumed. Pauses can be nested.\n */\n pause() {\n this.pauseCount_++;\n }\n\n /**\n * Resumes the throttle. If doing so drops the pausing count to zero,\n * pending action callbacks will be executed as soon as possible, but\n * still no sooner than an interval's delay after the previous call.\n * Future action callbacks will be executed as normal.\n */\n resume() {\n this.pauseCount_--;\n if (!this.pauseCount_ && this.shouldFire_ && !this.timer_) {\n this.shouldFire_ = false;\n this.doAction_();\n }\n }\n\n /** @override */\n disposeInternal() {\n super.disposeInternal();\n this.stop();\n }\n\n /**\n * Handler for the timer to fire the throttle\n * @private\n */\n onTimer_() {\n this.timer_ = null;\n\n if (this.shouldFire_ && !this.pauseCount_) {\n this.shouldFire_ = false;\n this.doAction_();\n }\n }\n\n /**\n * Calls the callback\n * @private\n */\n doAction_() {\n this.timer_ = Timer.callOnce(() => this.onTimer_(), this.interval_);\n const args = this.args_;\n // release memory first so it always happens even if listener throws\n this.args_ = null;\n this.listener_.apply(null, args);\n }\n}\n\nexports = Throttle;\n","^<",1684857788697,"^=",["^3",["^1W","^>","^1X"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^1W","^1X"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.async.Throttle","^U",true,"^V",[],"^M",["goog.Disposable","goog.Timer"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/throttle.js"],"^[",["^3",["^1Z"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1X","^1W"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.async.ConditionalDelay"]],"^5","goog.async.conditionaldelay.js","^6",["^7","goog/async/conditionaldelay.js"],"^8","goog/async/conditionaldelay.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Defines a class useful for handling functions that must be\n * invoked later when some condition holds. Examples include deferred function\n * calls that return a boolean flag whether it succedeed or not.\n *\n * Example:\n *\n * function deferred() {\n * var succeeded = false;\n * // ... custom code\n * return succeeded;\n * }\n *\n * var deferredCall = new goog.async.ConditionalDelay(deferred);\n * deferredCall.onSuccess = function() {\n * alert('Success: The deferred function has been successfully executed.');\n * }\n * deferredCall.onFailure = function() {\n * alert('Failure: Time limit exceeded.');\n * }\n *\n * // Call the deferred() every 100 msec until it returns true,\n * // or 5 seconds pass.\n * deferredCall.start(100, 5000);\n *\n * // Stop the deferred function call (does nothing if it's not active).\n * deferredCall.stop();\n */\n\n\ngoog.provide('goog.async.ConditionalDelay');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.async.Delay');\n\n\n\n/**\n * A ConditionalDelay object invokes the associated function after a specified\n * interval delay and checks its return value. If the function returns\n * `true` the conditional delay is cancelled and {@see #onSuccess}\n * is called. Otherwise this object keeps to invoke the deferred function until\n * either it returns `true` or the timeout is exceeded. In the latter case\n * the {@see #onFailure} method will be called.\n *\n * The interval duration and timeout can be specified each time the delay is\n * started. Calling start on an active delay will reset the timer.\n *\n * @param {function():boolean} listener Function to call when the delay\n * completes. Should return a value that type-converts to `true` if\n * the call succeeded and this delay should be stopped.\n * @param {Object=} opt_handler The object scope to invoke the function in.\n * @constructor\n * @struct\n * @extends {goog.Disposable}\n */\ngoog.async.ConditionalDelay = function(listener, opt_handler) {\n 'use strict';\n goog.async.ConditionalDelay.base(this, 'constructor');\n\n /**\n * The delay interval in milliseconds to between the calls to the callback.\n * Note, that the callback may be invoked earlier than this interval if the\n * timeout is exceeded.\n * @private {number}\n */\n this.interval_ = 0;\n\n /**\n * The timeout timestamp until which the delay is to be executed.\n * A negative value means no timeout.\n * @private {number}\n */\n this.runUntil_ = 0;\n\n /**\n * True if the listener has been executed, and it returned `true`.\n * @private {boolean}\n */\n this.isDone_ = false;\n\n /**\n * The function that will be invoked after a delay.\n * @private {function():boolean}\n */\n this.listener_ = listener;\n\n /**\n * The object context to invoke the callback in.\n * @private {Object|undefined}\n */\n this.handler_ = opt_handler;\n\n /**\n * The underlying goog.async.Delay delegate object.\n * @private {goog.async.Delay}\n */\n this.delay_ = new goog.async.Delay(\n goog.bind(this.onTick_, this), 0 /*interval*/, this /*scope*/);\n};\ngoog.inherits(goog.async.ConditionalDelay, goog.Disposable);\n\n\n/** @override */\ngoog.async.ConditionalDelay.prototype.disposeInternal = function() {\n 'use strict';\n this.delay_.dispose();\n delete this.listener_;\n delete this.handler_;\n goog.async.ConditionalDelay.superClass_.disposeInternal.call(this);\n};\n\n\n/**\n * Starts the delay timer. The provided listener function will be called\n * repeatedly after the specified interval until the function returns\n * `true` or the timeout is exceeded. Calling start on an active timer\n * will stop the timer first.\n * @param {number=} opt_interval The time interval between the function\n * invocations (in milliseconds). Default is 0.\n * @param {number=} opt_timeout The timeout interval (in milliseconds). Takes\n * precedence over the `opt_interval`, i.e. if the timeout is less\n * than the invocation interval, the function will be called when the\n * timeout is exceeded. A negative value means no timeout. Default is 0.\n */\ngoog.async.ConditionalDelay.prototype.start = function(\n opt_interval, opt_timeout) {\n 'use strict';\n this.stop();\n this.isDone_ = false;\n\n var timeout = opt_timeout || 0;\n this.interval_ = Math.max(opt_interval || 0, 0);\n this.runUntil_ = timeout < 0 ? -1 : (goog.now() + timeout);\n this.delay_.start(\n timeout < 0 ? this.interval_ : Math.min(this.interval_, timeout));\n};\n\n\n/**\n * Stops the delay timer if it is active. No action is taken if the timer is not\n * in use.\n */\ngoog.async.ConditionalDelay.prototype.stop = function() {\n 'use strict';\n this.delay_.stop();\n};\n\n\n/**\n * @return {boolean} True if the delay is currently active, false otherwise.\n */\ngoog.async.ConditionalDelay.prototype.isActive = function() {\n 'use strict';\n return this.delay_.isActive();\n};\n\n\n/**\n * @return {boolean} True if the listener has been executed and returned\n * `true` since the last call to {@see #start}.\n */\ngoog.async.ConditionalDelay.prototype.isDone = function() {\n 'use strict';\n return this.isDone_;\n};\n\n\n/**\n * Called when the listener has been successfully executed and returned\n * `true`. The {@see #isDone} method should return `true` by now.\n * Designed for inheritance, should be overridden by subclasses or on the\n * instances if they care.\n */\ngoog.async.ConditionalDelay.prototype.onSuccess = function() {\n // Do nothing by default.\n};\n\n\n/**\n * Called when this delayed call is cancelled because the timeout has been\n * exceeded, and the listener has never returned `true`.\n * Designed for inheritance, should be overridden by subclasses or on the\n * instances if they care.\n */\ngoog.async.ConditionalDelay.prototype.onFailure = function() {\n // Do nothing by default.\n};\n\n\n/**\n * A callback function for the underlying `goog.async.Delay` object. When\n * executed the listener function is called, and if it returns `true`\n * the delay is stopped and the {@see #onSuccess} method is invoked.\n * If the timeout is exceeded the delay is stopped and the\n * {@see #onFailure} method is called.\n * @private\n */\ngoog.async.ConditionalDelay.prototype.onTick_ = function() {\n 'use strict';\n var successful = this.listener_.call(this.handler_);\n if (successful) {\n this.isDone_ = true;\n this.onSuccess();\n } else {\n // Try to reschedule the task.\n if (this.runUntil_ < 0) {\n // No timeout.\n this.delay_.start(this.interval_);\n } else {\n var timeLeft = this.runUntil_ - goog.now();\n if (timeLeft <= 0) {\n this.onFailure();\n } else {\n this.delay_.start(Math.min(this.interval_, timeLeft));\n }\n }\n }\n};\n","^<",1684857788697,"^=",["^3",["^>","^1X","^1V"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^1X","^1V"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.async.ConditionalDelay"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.async.Delay"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/conditionaldelay.js"],"^[",["^3",["^1["]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1X","^1V"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.async.throwException","^1Y","~$goog.async.throwException","^U",true,"^5","goog.async.throwexception.js","^6",["^7","goog/async/throwexception.js"],"^8","goog/async/throwexception.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides a function to throw an error without interrupting\n * the current execution context.\n */\n\ngoog.module('goog.async.throwException');\ngoog.module.declareLegacyNamespace();\n\n/**\n * Throw an item without interrupting the current execution context. For\n * example, if processing a group of items in a loop, sometimes it is useful\n * to report an error while still allowing the rest of the batch to be\n * processed.\n * @param {*} exception\n */\nfunction throwException(exception) {\n // Each throw needs to be in its own context.\n goog.global.setTimeout(() => {\n throw exception;\n }, 0);\n}\nexports = throwException;\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.async.throwException","^U",true,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/throwexception.js"],"^[",["^3",["^20"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.async.AnimationDelay"]],"^5","goog.async.animationdelay.js","^6",["^7","goog/async/animationdelay.js"],"^8","goog/async/animationdelay.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A delayed callback that pegs to the next animation frame\n * instead of a user-configurable timeout.\n */\n\ngoog.provide('goog.async.AnimationDelay');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.events');\ngoog.require('goog.functions');\n\n\n\n// TODO(nicksantos): Should we factor out the common code between this and\n// goog.async.Delay? I'm not sure if there's enough code for this to really\n// make sense. Subclassing seems like the wrong approach for a variety of\n// reasons. Maybe there should be a common interface?\n\n\n\n/**\n * A delayed callback that pegs to the next animation frame\n * instead of a user configurable timeout. By design, this should have\n * the same interface as goog.async.Delay.\n *\n * Uses requestAnimationFrame and friends when available, but falls\n * back to a timeout of goog.async.AnimationDelay.TIMEOUT.\n *\n * For more on requestAnimationFrame and how you can use it to create smoother\n * animations, see:\n * @see http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n *\n * @param {function(this: THIS, number): void} listener Function to call\n * when the delay completes. Will be passed the timestamp when it's called,\n * in unix ms.\n * @param {Window=} opt_window The window object to execute the delay in.\n * Defaults to the global object.\n * @param {THIS=} opt_handler The object scope to invoke the function in.\n * @template THIS\n * @constructor\n * @struct\n * @extends {goog.Disposable}\n * @final\n */\ngoog.async.AnimationDelay = function(listener, opt_window, opt_handler) {\n 'use strict';\n goog.async.AnimationDelay.base(this, 'constructor');\n\n /**\n * Identifier of the active delay timeout, or event listener,\n * or null when inactive.\n * @private {?goog.events.Key|number}\n */\n this.id_ = null;\n\n /**\n * If we're using dom listeners.\n * @private {?boolean}\n */\n this.usingListeners_ = false;\n\n /**\n * The function that will be invoked after a delay.\n * @const\n * @private {function(this: THIS, number): void}\n */\n this.listener_ = listener;\n\n /**\n * The object context to invoke the callback in.\n * @const\n * @private {(THIS|undefined)}\n */\n this.handler_ = opt_handler;\n\n /**\n * @private {Window}\n */\n this.win_ = opt_window || window;\n\n /**\n * Cached callback function invoked when the delay finishes.\n * @private {function()}\n */\n this.callback_ = goog.bind(this.doAction_, this);\n};\ngoog.inherits(goog.async.AnimationDelay, goog.Disposable);\n\n\n/**\n * Default wait timeout for animations (in milliseconds). Only used for timed\n * animation, which uses a timer (setTimeout) to schedule animation.\n *\n * @type {number}\n * @const\n */\ngoog.async.AnimationDelay.TIMEOUT = 20;\n\n\n/**\n * Name of event received from the requestAnimationFrame in Firefox.\n *\n * @type {string}\n * @const\n * @private\n */\ngoog.async.AnimationDelay.MOZ_BEFORE_PAINT_EVENT_ = 'MozBeforePaint';\n\n\n/**\n * Starts the delay timer. The provided listener function will be called\n * before the next animation frame.\n */\ngoog.async.AnimationDelay.prototype.start = function() {\n 'use strict';\n this.stop();\n this.usingListeners_ = false;\n\n var raf = this.getRaf_();\n var cancelRaf = this.getCancelRaf_();\n if (raf && !cancelRaf && this.win_.mozRequestAnimationFrame) {\n // Because Firefox (Gecko) runs animation in separate threads, it also saves\n // time by running the requestAnimationFrame callbacks in that same thread.\n // Sadly this breaks the assumption of implicit thread-safety in JS, and can\n // thus create thread-based inconsistencies on counters etc.\n //\n // Calling cycleAnimations_ using the MozBeforePaint event instead of as\n // callback fixes this.\n //\n // Trigger this condition only if the mozRequestAnimationFrame is available,\n // but not the W3C requestAnimationFrame function (as in draft) or the\n // equivalent cancel functions.\n this.id_ = goog.events.listen(\n this.win_, goog.async.AnimationDelay.MOZ_BEFORE_PAINT_EVENT_,\n this.callback_);\n this.win_.mozRequestAnimationFrame(null);\n this.usingListeners_ = true;\n } else if (raf && cancelRaf) {\n this.id_ = raf.call(this.win_, this.callback_);\n } else {\n this.id_ = this.win_.setTimeout(\n // Prior to Firefox 13, Gecko passed a non-standard parameter\n // to the callback that we want to ignore.\n goog.functions.lock(this.callback_), goog.async.AnimationDelay.TIMEOUT);\n }\n};\n\n\n/**\n * Starts the delay timer if it's not already active.\n */\ngoog.async.AnimationDelay.prototype.startIfNotActive = function() {\n 'use strict';\n if (!this.isActive()) {\n this.start();\n }\n};\n\n\n/**\n * Stops the delay timer if it is active. No action is taken if the timer is not\n * in use.\n */\ngoog.async.AnimationDelay.prototype.stop = function() {\n 'use strict';\n if (this.isActive()) {\n var raf = this.getRaf_();\n var cancelRaf = this.getCancelRaf_();\n if (raf && !cancelRaf && this.win_.mozRequestAnimationFrame) {\n goog.events.unlistenByKey(this.id_);\n } else if (raf && cancelRaf) {\n cancelRaf.call(this.win_, /** @type {number} */ (this.id_));\n } else {\n this.win_.clearTimeout(/** @type {number} */ (this.id_));\n }\n }\n this.id_ = null;\n};\n\n\n/**\n * Fires delay's action even if timer has already gone off or has not been\n * started yet; guarantees action firing. Stops the delay timer.\n */\ngoog.async.AnimationDelay.prototype.fire = function() {\n 'use strict';\n this.stop();\n this.doAction_();\n};\n\n\n/**\n * Fires delay's action only if timer is currently active. Stops the delay\n * timer.\n */\ngoog.async.AnimationDelay.prototype.fireIfActive = function() {\n 'use strict';\n if (this.isActive()) {\n this.fire();\n }\n};\n\n\n/**\n * @return {boolean} True if the delay is currently active, false otherwise.\n */\ngoog.async.AnimationDelay.prototype.isActive = function() {\n 'use strict';\n return this.id_ != null;\n};\n\n\n/**\n * Invokes the callback function after the delay successfully completes.\n * @private\n */\ngoog.async.AnimationDelay.prototype.doAction_ = function() {\n 'use strict';\n if (this.usingListeners_ && this.id_) {\n goog.events.unlistenByKey(this.id_);\n }\n this.id_ = null;\n\n // We are not using the timestamp returned by requestAnimationFrame\n // because it may be either a Date.now-style time or a\n // high-resolution time (depending on browser implementation). Using\n // goog.now() will ensure that the timestamp used is consistent and\n // compatible with goog.fx.Animation.\n this.listener_.call(this.handler_, goog.now());\n};\n\n\n/** @override */\ngoog.async.AnimationDelay.prototype.disposeInternal = function() {\n 'use strict';\n this.stop();\n goog.async.AnimationDelay.base(this, 'disposeInternal');\n};\n\n\n/**\n * @return {?function(function(number)): number} The requestAnimationFrame\n * function, or null if not available on this browser.\n * @private\n */\ngoog.async.AnimationDelay.prototype.getRaf_ = function() {\n 'use strict';\n var win = this.win_;\n return win.requestAnimationFrame || win.webkitRequestAnimationFrame ||\n win.mozRequestAnimationFrame || win.oRequestAnimationFrame ||\n win.msRequestAnimationFrame || null;\n};\n\n\n/**\n * @return {?function(number): undefined} The cancelAnimationFrame function,\n * or null if not available on this browser.\n * @private\n */\ngoog.async.AnimationDelay.prototype.getCancelRaf_ = function() {\n 'use strict';\n var win = this.win_;\n return win.cancelAnimationFrame || win.cancelRequestAnimationFrame ||\n win.webkitCancelRequestAnimationFrame ||\n win.mozCancelRequestAnimationFrame || win.oCancelRequestAnimationFrame ||\n win.msCancelRequestAnimationFrame || null;\n};\n","^<",1684857788697,"^=",["^3",["~$goog.functions","^>","^1X","~$goog.events"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^22","^1X","^23"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.async.AnimationDelay"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.events","goog.functions"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/animationdelay.js"],"^[",["^3",["^21"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1X","^23","^22"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.async.FreeList","^1Y","~$goog.async.FreeList","^U",true,"^5","goog.async.freelist.js","^6",["^7","goog/async/freelist.js"],"^8","goog/async/freelist.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Simple freelist.\n *\n * An anterative to goog.structs.SimplePool, it imposes the requirement that the\n * objects in the list contain a \"next\" property that can be used to maintain\n * the pool.\n */\ngoog.module('goog.async.FreeList');\ngoog.module.declareLegacyNamespace();\n\n/** @template ITEM */\nclass FreeList {\n /**\n * @param {function():ITEM} create\n * @param {function(ITEM):void} reset\n * @param {number} limit\n */\n constructor(create, reset, limit) {\n /** @private @const {number} */\n this.limit_ = limit;\n /** @private @const {function()} */\n this.create_ = create;\n /** @private @const {function(ITEM):void} */\n this.reset_ = reset;\n\n /** @private {number} */\n this.occupants_ = 0;\n /** @private {ITEM} */\n this.head_ = null;\n }\n\n /** @return {ITEM} */\n get() {\n let item;\n if (this.occupants_ > 0) {\n this.occupants_--;\n item = this.head_;\n this.head_ = item.next;\n item.next = null;\n } else {\n item = this.create_();\n }\n return item;\n }\n\n /** @param {ITEM} item An item available for possible future reuse. */\n put(item) {\n this.reset_(item);\n if (this.occupants_ < this.limit_) {\n this.occupants_++;\n item.next = this.head_;\n this.head_ = item;\n }\n }\n\n /**\n * Visible for testing.\n * @return {number}\n * @package\n */\n occupants() {\n return this.occupants_;\n }\n}\n\nexports = FreeList;\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.async.FreeList","^U",true,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/freelist.js"],"^[",["^3",["^24"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.async.promises","^1Y","~$goog.async.promises","^U",false,"^5","goog.async.promises.js","^6",["^7","goog/async/promises.js"],"^8","goog/async/promises.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides utility functions for promises.\n */\n\ngoog.module('goog.async.promises');\n\n\n/**\n * Resolves when all promise values in the map resolve. The resolved value will\n * be a Map with the same keys as the input map, but with the resolved values of\n * the promises. Rejects with first error if any promise rejects. Like\n * Promise.all(), but for Maps.\n *\n * @template OUT_VALUE :=\n * mapunion(IN_VALUE, (V) =>\n * cond(isTemplatized(V) && sub(rawTypeOf(V), 'IThenable'),\n * templateTypeOf(V, 0),\n * cond(sub(V, 'Thenable'),\n * unknown(),\n * V)))\n * =:\n * @template KEY\n * @template IN_VALUE\n *\n * @param {!Map} promiseMap\n * @return {!Promise>}\n */\nexports.allMapValues = (promiseMap) => {\n // Maps return keys and values in insertion order, so these will match each\n // other.\n const keys = Array.from(promiseMap.keys());\n const values = Array.from(promiseMap.values());\n return Promise.all(values).then((results) => {\n const resultMap = new Map();\n results.forEach((result, i) => resultMap.set(keys[i], result));\n return resultMap;\n });\n};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.async.promises","^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/promises.js"],"^[",["^3",["^25"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.async.nextTick"]],"^5","goog.async.nexttick.js","^6",["^7","goog/async/nexttick.js"],"^8","goog/async/nexttick.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides a function to schedule running a function as soon\n * as possible after the current JS execution stops and yields to the event\n * loop.\n */\n\ngoog.provide('goog.async.nextTick');\n\ngoog.require('goog.debug.entryPointRegistry');\ngoog.require('goog.dom');\ngoog.require('goog.dom.TagName');\ngoog.require('goog.functions');\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\n\n\n/**\n * Fires the provided callbacks as soon as possible after the current JS\n * execution context. setTimeout(…, 0) takes at least 4ms when called from\n * within another setTimeout(…, 0) for legacy reasons.\n *\n * This will not schedule the callback as a microtask (i.e. a task that can\n * preempt user input or networking callbacks). It is meant to emulate what\n * setTimeout(_, 0) would do if it were not throttled. If you desire microtask\n * behavior, use {@see goog.Promise} instead.\n *\n * @param {function(this:SCOPE)} callback Callback function to fire as soon as\n * possible.\n * @param {SCOPE=} opt_context Object in whose scope to call the listener.\n * @param {boolean=} opt_useSetImmediate Avoid the IE workaround that\n * ensures correctness at the cost of speed. See comments for details.\n * @template SCOPE\n */\ngoog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) {\n 'use strict';\n var cb = callback;\n if (opt_context) {\n cb = goog.bind(callback, opt_context);\n }\n cb = goog.async.nextTick.wrapCallback_(cb);\n // Note we do allow callers to also request setImmediate if they are willing\n // to accept the possible tradeoffs of incorrectness in exchange for speed.\n // The IE fallback of readystate change is much slower. See useSetImmediate_\n // for details.\n if (typeof goog.global.setImmediate === 'function' &&\n (opt_useSetImmediate || goog.async.nextTick.useSetImmediate_())) {\n goog.global.setImmediate(cb);\n return;\n }\n\n // Look for and cache the custom fallback version of setImmediate.\n if (!goog.async.nextTick.nextTickImpl) {\n goog.async.nextTick.nextTickImpl = goog.async.nextTick.getNextTickImpl_();\n }\n goog.async.nextTick.nextTickImpl(cb);\n};\n\n\n/**\n * Returns whether should use setImmediate implementation currently on window.\n *\n * window.setImmediate was introduced and currently only supported by IE10+,\n * but due to a bug in the implementation it is not guaranteed that\n * setImmediate is faster than setTimeout nor that setImmediate N is before\n * setImmediate N+1. That is why we do not use the native version if\n * available. We do, however, call setImmediate if it is a non-native function\n * because that indicates that it has been replaced by goog.testing.MockClock\n * which we do want to support.\n * See\n * http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10\n *\n * @return {boolean} Whether to use the implementation of setImmediate defined\n * on Window.\n * @private\n * @suppress {missingProperties} For \"Window.prototype.setImmediate\"\n */\ngoog.async.nextTick.useSetImmediate_ = function() {\n 'use strict';\n // Not a browser environment.\n if (!goog.global.Window || !goog.global.Window.prototype) {\n return true;\n }\n\n // MS Edge has window.setImmediate natively, but it's not on Window.prototype.\n // Also, there's no clean way to detect if the goog.global.setImmediate has\n // been replaced by mockClock as its replacement also shows up as \"[native\n // code]\" when using toString. Therefore, just always use\n // goog.global.setImmediate for Edge. It's unclear if it suffers the same\n // issues as IE10/11, but based on\n // https://dev.modern.ie/testdrive/demos/setimmediatesorting/\n // it seems they've been working to ensure it's WAI.\n if (goog.labs.userAgent.browser.isEdge() ||\n goog.global.Window.prototype.setImmediate != goog.global.setImmediate) {\n // Something redefined setImmediate in which case we decide to use it (This\n // is so that we use the mockClock setImmediate).\n return true;\n }\n\n return false;\n};\n\n\n/**\n * Cache for the nextTick implementation. Exposed so tests can replace it,\n * if needed.\n * @type {function(function())}\n */\ngoog.async.nextTick.nextTickImpl;\n\n\n/**\n * Determines the best possible implementation to run a function as soon as\n * the JS event loop is idle.\n * @return {function(function())} The \"setImmediate\" implementation.\n * @private\n */\ngoog.async.nextTick.getNextTickImpl_ = function() {\n 'use strict';\n // Create a private message channel and use it to postMessage empty messages\n // to ourselves.\n /** @type {!Function|undefined} */\n var Channel = goog.global['MessageChannel'];\n // If MessageChannel is not available and we are in a browser, implement\n // an iframe based polyfill in browsers that have postMessage and\n // document.addEventListener. The latter excludes IE8 because it has a\n // synchronous postMessage implementation.\n if (typeof Channel === 'undefined' && typeof window !== 'undefined' &&\n window.postMessage && window.addEventListener &&\n // Presto (The old pre-blink Opera engine) has problems with iframes\n // and contentWindow.\n !goog.labs.userAgent.engine.isPresto()) {\n /** @constructor */\n Channel = function() {\n 'use strict';\n // Make an empty, invisible iframe.\n var iframe = goog.dom.createElement(goog.dom.TagName.IFRAME);\n iframe.style.display = 'none';\n document.documentElement.appendChild(iframe);\n var win = iframe.contentWindow;\n var doc = win.document;\n doc.open();\n doc.close();\n // Do not post anything sensitive over this channel, as the workaround for\n // pages with file: origin could allow that information to be modified or\n // intercepted.\n var message = 'callImmediate' + Math.random();\n // The same origin policy rejects attempts to postMessage from file: urls\n // unless the origin is '*'.\n var origin = win.location.protocol == 'file:' ?\n '*' :\n win.location.protocol + '//' + win.location.host;\n var onmessage = goog.bind(function(e) {\n 'use strict';\n // Validate origin and message to make sure that this message was\n // intended for us. If the origin is set to '*' (see above) only the\n // message needs to match since, for example, '*' != 'file://'. Allowing\n // the wildcard is ok, as we are not concerned with security here.\n if ((origin != '*' && e.origin != origin) || e.data != message) {\n return;\n }\n this['port1'].onmessage();\n }, this);\n win.addEventListener('message', onmessage, false);\n this['port1'] = {};\n this['port2'] = {\n postMessage: function() {\n 'use strict';\n win.postMessage(message, origin);\n }\n };\n };\n }\n if (typeof Channel !== 'undefined' && !goog.labs.userAgent.browser.isIE()) {\n // Exclude all of IE due to\n // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/\n // which allows starving postMessage with a busy setTimeout loop.\n // This currently affects IE10 and IE11 which would otherwise be able\n // to use the postMessage based fallbacks.\n var channel = new Channel();\n // Use a fifo linked list to call callbacks in the right order.\n var head = {};\n var tail = head;\n channel['port1'].onmessage = function() {\n 'use strict';\n if (head.next !== undefined) {\n head = head.next;\n var cb = head.cb;\n head.cb = null;\n cb();\n }\n };\n return function(cb) {\n 'use strict';\n tail.next = {cb: cb};\n tail = tail.next;\n channel['port2'].postMessage(0);\n };\n }\n // Fall back to setTimeout with 0. In browsers this creates a delay of 5ms\n // or more.\n // NOTE(user): This fallback is used for IE.\n return function(cb) {\n 'use strict';\n goog.global.setTimeout(/** @type {function()} */ (cb), 0);\n };\n};\n\n\n/**\n * Helper function that is overrided to protect callbacks with entry point\n * monitor if the application monitors entry points.\n * @param {function()} callback Callback function to fire as soon as possible.\n * @return {function()} The wrapped callback.\n * @private\n */\ngoog.async.nextTick.wrapCallback_ = goog.functions.identity;\n\n\n// Register the callback function as an entry point, so that it can be\n// monitored for exception handling, etc. This has to be done in this file\n// since it requires special code to handle all browsers.\ngoog.debug.entryPointRegistry.register(\n /**\n * @param {function(!Function): !Function} transformer The transforming\n * function.\n */\n function(transformer) {\n 'use strict';\n goog.async.nextTick.wrapCallback_ = transformer;\n });\n","^<",1684857788697,"^=",["^3",["~$goog.dom","^22","^>","~$goog.labs.userAgent.engine","~$goog.debug.entryPointRegistry","~$goog.labs.userAgent.browser","~$goog.dom.TagName"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^27","^22","^28","^29","^2:","^2;"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.async.nextTick"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.debug.entryPointRegistry","goog.dom","goog.dom.TagName","goog.functions","goog.labs.userAgent.browser","goog.labs.userAgent.engine"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/nexttick.js"],"^[",["^3",["^26"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^29","^27","^2;","^22","^2:","^28"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.async.run","^1Y","~$goog.async.run","^U",true,"^5","goog.async.run.js","^6",["^7","goog/async/run.js"],"^8","goog/async/run.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\ngoog.module('goog.async.run');\ngoog.module.declareLegacyNamespace();\n\nconst WorkQueue = goog.require('goog.async.WorkQueue');\nconst asyncStackTag = goog.require('goog.debug.asyncStackTag');\nconst nextTick = goog.require('goog.async.nextTick');\nconst throwException = goog.require('goog.async.throwException');\n\n/**\n * @define {boolean} If true, use the global Promise to implement run\n * assuming either the native, or polyfill version will be used. Does still\n * permit tests to use forceNextTick.\n */\ngoog.ASSUME_NATIVE_PROMISE = goog.define('goog.ASSUME_NATIVE_PROMISE', false);\n\n/**\n * The function used to schedule work asynchronousely.\n * @private {function()}\n */\nlet schedule;\n\n/** @private {boolean} */\nlet workQueueScheduled = false;\n\n/** @type {!WorkQueue} */\nlet workQueue = new WorkQueue();\n\n/**\n * Fires the provided callback just before the current callstack unwinds, or as\n * soon as possible after the current JS execution context.\n * @param {function(this:THIS)} callback\n * @param {THIS=} context Object to use as the \"this value\" when calling the\n * provided function.\n * @template THIS\n */\nlet run = (callback, context = undefined) => {\n if (!schedule) {\n initializeRunner();\n }\n if (!workQueueScheduled) {\n // Nothing is currently scheduled, schedule it now.\n schedule();\n workQueueScheduled = true;\n }\n callback = asyncStackTag.wrap(callback, 'goog.async.run');\n\n workQueue.add(callback, context);\n};\n\n/** Initializes the function to use to process the work queue. */\nlet initializeRunner = () => {\n if (goog.ASSUME_NATIVE_PROMISE ||\n (goog.global.Promise && goog.global.Promise.resolve)) {\n // Use goog.global.Promise instead of just Promise because the relevant\n // externs may be missing, and don't alias it because this could confuse the\n // compiler into thinking the polyfill is required when it should be treated\n // as optional.\n const promise = goog.global.Promise.resolve(undefined);\n schedule = () => {\n promise.then(run.processWorkQueue);\n };\n } else {\n schedule = () => {\n nextTick(run.processWorkQueue);\n };\n }\n};\n\n/**\n * Forces run to use nextTick instead of Promise.\n * This should only be done in unit tests. It's useful because MockClock\n * replaces nextTick, but not the browser Promise implementation, so it allows\n * Promise-based code to be tested with MockClock.\n * However, we also want to run promises if the MockClock is no longer in\n * control so we schedule a backup \"setTimeout\" to the unmocked timeout if\n * provided.\n * @param {function(function())=} realSetTimeout\n */\nrun.forceNextTick = (realSetTimeout = undefined) => {\n schedule = () => {\n nextTick(run.processWorkQueue);\n if (realSetTimeout) {\n realSetTimeout(run.processWorkQueue);\n }\n };\n};\n\nif (goog.DEBUG) {\n /** Reset the work queue. Only available for tests in debug mode. */\n run.resetQueue = () => {\n workQueueScheduled = false;\n workQueue = new WorkQueue();\n };\n\n /** Resets the scheduler. Only available for tests in debug mode. */\n run.resetSchedulerForTest = () => {\n initializeRunner();\n };\n}\n\n/**\n * Run any pending run work items. This function is not intended\n * for general use, but for use by entry point handlers to run items ahead of\n * nextTick.\n */\nrun.processWorkQueue = () => {\n // NOTE: additional work queue items may be added while processing.\n let item = null;\n while (item = workQueue.remove()) {\n try {\n item.fn.call(item.scope);\n } catch (e) {\n throwException(e);\n }\n workQueue.returnUnused(item);\n }\n\n // There are no more work items, allow processing to be scheduled again.\n workQueueScheduled = false;\n};\n\nexports = run;\n","^<",1684857788697,"^=",["^3",["^20","^>","~$goog.debug.asyncStackTag","~$goog.async.WorkQueue","^26"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^20","^2=","^2>","^26"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.async.run","^U",true,"^V",[],"^M",["goog.async.WorkQueue","goog.debug.asyncStackTag","goog.async.nextTick","goog.async.throwException"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/run.js"],"^[",["^3",["^2<"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2>","^2=","^26","^20"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.async.WorkQueue","^1Y","^2>","^U",true,"^5","goog.async.workqueue.js","^6",["^7","goog/async/workqueue.js"],"^8","goog/async/workqueue.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.module('goog.async.WorkQueue');\ngoog.module.declareLegacyNamespace();\n\nconst FreeList = goog.require('goog.async.FreeList');\nconst {assert} = goog.require('goog.asserts');\n\n// TODO(johnlenz): generalize the WorkQueue if this is used by more\n// than goog.async.run.\n\n\n/**\n * A low GC workqueue. The key elements of this design:\n * - avoids the need for goog.bind or equivalent by carrying scope\n * - avoids the need for array reallocation by using a linked list\n * - minimizes work entry objects allocation by recycling objects\n * @final\n * @struct\n */\nclass WorkQueue {\n constructor() {\n this.workHead_ = null;\n this.workTail_ = null;\n }\n\n /**\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\n add(fn, scope) {\n const item = this.getUnusedItem_();\n item.set(fn, scope);\n\n if (this.workTail_) {\n this.workTail_.next = item;\n this.workTail_ = item;\n } else {\n assert(!this.workHead_);\n this.workHead_ = item;\n this.workTail_ = item;\n }\n }\n\n /**\n * @return {?WorkItem}\n */\n remove() {\n let item = null;\n\n if (this.workHead_) {\n item = this.workHead_;\n this.workHead_ = this.workHead_.next;\n if (!this.workHead_) {\n this.workTail_ = null;\n }\n item.next = null;\n }\n return item;\n }\n\n /**\n * @param {!WorkItem} item\n */\n returnUnused(item) {\n WorkQueue.freelist_.put(item);\n }\n\n /**\n * @return {!WorkItem}\n * @private\n */\n getUnusedItem_() {\n return WorkQueue.freelist_.get();\n }\n}\n\n/** @define {number} The maximum number of entries to keep for recycling. */\nWorkQueue.DEFAULT_MAX_UNUSED =\n goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100);\n\n/** @const @private {!FreeList} */\nWorkQueue.freelist_ = new FreeList(\n () => new WorkItem(), item => item.reset(), WorkQueue.DEFAULT_MAX_UNUSED);\n\n/**\n * @final\n * @struct\n */\nclass WorkItem {\n constructor() {\n /** @type {?function()} */\n this.fn = null;\n /** @type {?Object|null|undefined} */\n this.scope = null;\n /** @type {?WorkItem} */\n this.next = null;\n }\n\n /**\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\n set(fn, scope) {\n this.fn = fn;\n this.scope = scope;\n this.next = null;\n }\n\n /** Reset the work item so they don't prevent GC before reuse */\n reset() {\n this.fn = null;\n this.scope = null;\n this.next = null;\n }\n}\n\nexports = WorkQueue;\n","^<",1684857788697,"^=",["^3",["~$goog.asserts","^>","^24"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2?","^24"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.async.WorkQueue","^U",true,"^V",[],"^M",["goog.async.FreeList","goog.asserts"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/workqueue.js"],"^[",["^3",["^2>"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^24","^2?"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.async.Debouncer"]],"^5","goog.async.debouncer.js","^6",["^7","goog/async/debouncer.js"],"^8","goog/async/debouncer.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of the goog.async.Debouncer class.\n *\n * @see ../demos/timers.html\n */\n\ngoog.provide('goog.async.Debouncer');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.Timer');\n\n\n\n/**\n * Debouncer will perform a specified action exactly once for any sequence of\n * signals fired repeatedly so long as they are fired less than a specified\n * interval apart (in milliseconds). Whether it receives one signal or multiple,\n * it will always wait until a full interval has elapsed since the last signal\n * before performing the action.\n * @param {function(this: T, ...?)} listener Function to callback when the\n * action is triggered.\n * @param {number} interval Interval over which to debounce. The listener will\n * only be called after the full interval has elapsed since the last signal.\n * @param {T=} opt_handler Object in whose scope to call the listener.\n * @constructor\n * @struct\n * @extends {goog.Disposable}\n * @final\n * @template T\n */\ngoog.async.Debouncer = function(listener, interval, opt_handler) {\n 'use strict';\n goog.async.Debouncer.base(this, 'constructor');\n\n /**\n * Function to callback\n * @const @private {function(this: T, ...?)}\n */\n this.listener_ =\n opt_handler != null ? goog.bind(listener, opt_handler) : listener;\n\n /**\n * Interval for the debounce time\n * @const @private {number}\n */\n this.interval_ = interval;\n\n /**\n * Cached callback function invoked after the debounce timeout completes\n * @const @private {!Function}\n */\n this.callback_ = goog.bind(this.onTimer_, this);\n\n /**\n * Indicates that the action is pending and needs to be fired.\n * @private {boolean}\n */\n this.shouldFire_ = false;\n\n /**\n * Indicates the count of nested pauses currently in effect on the debouncer.\n * When this count is not zero, fired actions will be postponed until the\n * debouncer is resumed enough times to drop the pause count to zero.\n * @private {number}\n */\n this.pauseCount_ = 0;\n\n /**\n * Timer for scheduling the next callback\n * @private {?number}\n */\n this.timer_ = null;\n\n /**\n * When set this is a timestamp. On the onfire we want to reschedule the\n * callback so it ends up at this time.\n * @private {?number}\n */\n this.refireAt_ = null;\n\n /**\n * The last arguments passed into `fire`.\n * @private {!IArrayLike}\n */\n this.args_ = [];\n};\ngoog.inherits(goog.async.Debouncer, goog.Disposable);\n\n\n/**\n * Notifies the debouncer that the action has happened. It will debounce the\n * call so that the callback is only called after the last action in a sequence\n * of actions separated by periods less the interval parameter passed to the\n * constructor, passing the arguments from the last call of this function into\n * the debounced function.\n * @param {...?} var_args Arguments to pass on to the debounced function.\n */\ngoog.async.Debouncer.prototype.fire = function(var_args) {\n 'use strict';\n this.args_ = arguments;\n // When this method is called, we need to prevent fire() calls from within the\n // previous interval from calling the callback. The simplest way of doing this\n // is to call this.stop() which calls clearTimeout, and then reschedule the\n // timeout. However clearTimeout and setTimeout are expensive, so we just\n // leave them untouched and when they do happen we potentially reschedule.\n this.shouldFire_ = false;\n if (this.timer_) {\n this.refireAt_ = goog.now() + this.interval_;\n return;\n }\n this.timer_ = goog.Timer.callOnce(this.callback_, this.interval_);\n};\n\n\n/**\n * Cancels any pending action callback. The debouncer can be restarted by\n * calling {@link #fire}.\n */\ngoog.async.Debouncer.prototype.stop = function() {\n 'use strict';\n this.clearTimer_();\n this.refireAt_ = null;\n this.shouldFire_ = false;\n this.args_ = [];\n};\n\n\n/**\n * Pauses the debouncer. All pending and future action callbacks will be delayed\n * until the debouncer is resumed. Pauses can be nested.\n */\ngoog.async.Debouncer.prototype.pause = function() {\n 'use strict';\n ++this.pauseCount_;\n};\n\n\n/**\n * Resumes the debouncer. If doing so drops the pausing count to zero, pending\n * action callbacks will be executed as soon as possible, but still no sooner\n * than an interval's delay after the previous call. Future action callbacks\n * will be executed as normal.\n */\ngoog.async.Debouncer.prototype.resume = function() {\n 'use strict';\n if (!this.pauseCount_) {\n return;\n }\n\n --this.pauseCount_;\n if (!this.pauseCount_ && this.shouldFire_) {\n this.doAction_();\n }\n};\n\n\n/** @override */\ngoog.async.Debouncer.prototype.disposeInternal = function() {\n 'use strict';\n this.stop();\n goog.async.Debouncer.base(this, 'disposeInternal');\n};\n\n\n/**\n * Handler for the timer to fire the debouncer.\n * @private\n */\ngoog.async.Debouncer.prototype.onTimer_ = function() {\n 'use strict';\n this.clearTimer_();\n // There is a newer call to fire() within the debounce interval.\n // Reschedule the callback and return.\n if (this.refireAt_) {\n this.timer_ =\n goog.Timer.callOnce(this.callback_, this.refireAt_ - goog.now());\n this.refireAt_ = null;\n return;\n }\n\n if (!this.pauseCount_) {\n this.doAction_();\n } else {\n this.shouldFire_ = true;\n }\n};\n\n\n/**\n * Cleans the initialized timer.\n * @private\n */\ngoog.async.Debouncer.prototype.clearTimer_ = function() {\n 'use strict';\n if (this.timer_) {\n goog.Timer.clear(this.timer_);\n this.timer_ = null;\n }\n};\n\n\n/**\n * Calls the callback.\n * @private\n */\ngoog.async.Debouncer.prototype.doAction_ = function() {\n 'use strict';\n this.shouldFire_ = false;\n this.listener_.apply(null, this.args_);\n};\n","^<",1684857788697,"^=",["^3",["^1W","^>","^1X"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^1W","^1X"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.async.Debouncer"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.Timer"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/debouncer.js"],"^[",["^3",["^2@"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1X","^1W"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.Throttle","^1Y","~$goog.Throttle","^U",true,"^5","goog.async.legacy_throttle.js","^6",["^7","goog/async/legacy_throttle.js"],"^8","goog/async/legacy_throttle.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Provides a deprecated alias for goog.async.Throttle\n * @deprecated Use goog.async.Throttle instead.\n */\ngoog.module('goog.Throttle');\ngoog.module.declareLegacyNamespace();\n\nconst Throttle = goog.require('goog.async.Throttle');\n\nexports = Throttle;\n","^<",1684857788697,"^=",["^3",["^1Z","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^1Z"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.Throttle","^U",true,"^V",[],"^M",["goog.async.Throttle"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/async/legacy_throttle.js"],"^[",["^3",["^2A"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1Z"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^5","goog.base.js","^6",["^7","goog/base.js"],"^8","goog/base.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Bootstrap for the Google JS Library (Closure).\n *\n * In uncompiled mode base.js will attempt to load Closure's deps file, unless\n * the global CLOSURE_NO_DEPS is set to true. This allows projects\n * to include their own deps file(s) from different locations.\n *\n * Avoid including base.js more than once. This is strictly discouraged and not\n * supported. goog.require(...) won't work properly in that case.\n *\n * @suppress {deprecated} Users cannot remove deprecated uses here.\n * @provideGoog\n */\n\n\n/**\n * @define {boolean} Overridden to true by the compiler.\n */\nvar COMPILED = false;\n\n\n/**\n * Base namespace for the Closure library. Checks to see goog is already\n * defined in the current scope before assigning to prevent clobbering if\n * base.js is loaded more than once.\n *\n * @const\n */\nvar goog = goog || {};\n\n/**\n * Reference to the global object.\n * https://www.ecma-international.org/ecma-262/9.0/index.html#sec-global-object\n *\n * More info on this implementation here:\n * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI/edit\n *\n * @const\n * @suppress {undefinedVars} self won't be referenced unless `this` is falsy.\n * @type {!Global}\n */\ngoog.global =\n // Check `this` first for backwards compatibility.\n // Valid unless running as an ES module or in a function wrapper called\n // without setting `this` properly.\n // Note that base.js can't usefully be imported as an ES module, but it may\n // be compiled into bundles that are loadable as ES modules.\n this ||\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/self\n // For in-page browser environments and workers.\n self;\n\n\n/**\n * A hook for overriding the define values in uncompiled mode.\n *\n * In uncompiled mode, `CLOSURE_UNCOMPILED_DEFINES` may be defined before\n * loading base.js. If a key is defined in `CLOSURE_UNCOMPILED_DEFINES`,\n * `goog.define` will use the value instead of the default value. This\n * allows flags to be overwritten without compilation (this is normally\n * accomplished with the compiler's \"define\" flag).\n *\n * Example:\n *
\n *   var CLOSURE_UNCOMPILED_DEFINES = {'goog.DEBUG': false};\n * 
\n *\n * @type {Object|undefined}\n */\ngoog.global.CLOSURE_UNCOMPILED_DEFINES;\n\n\n/**\n * A hook for overriding the define values in uncompiled or compiled mode,\n * like CLOSURE_UNCOMPILED_DEFINES but effective in compiled code. In\n * uncompiled code CLOSURE_UNCOMPILED_DEFINES takes precedence.\n *\n * Also unlike CLOSURE_UNCOMPILED_DEFINES the values must be number, boolean or\n * string literals or the compiler will emit an error.\n *\n * While any @define value may be set, only those set with goog.define will be\n * effective for uncompiled code.\n *\n * Example:\n *
\n *   var CLOSURE_DEFINES = {'goog.DEBUG': false} ;\n * 
\n *\n * Currently the Closure Compiler will only recognize very simple definitions of\n * this value when looking for values to apply to compiled code and ignore all\n * other references. Specifically, it looks the value defined at the variable\n * declaration, as with the example above.\n *\n * TODO(user): Improve the recognized definitions.\n *\n * @type {!Object|null|undefined}\n */\ngoog.global.CLOSURE_DEFINES;\n\n\n/**\n * Builds an object structure for the provided namespace path, ensuring that\n * names that already exist are not overwritten. For example:\n * \"a.b.c\" -> a = {};a.b={};a.b.c={};\n * Used by goog.provide and goog.exportSymbol.\n * @param {string} name The name of the object that this file defines.\n * @param {*=} object The object to expose at the end of the path.\n * @param {boolean=} overwriteImplicit If object is set and a previous call\n * implicitly constructed the namespace given by name, this parameter\n * controls whether object should overwrite the implicitly constructed\n * namespace or be merged into it. Defaults to false.\n * @param {?Object=} objectToExportTo The object to add the path to; if this\n * field is not specified, its value defaults to `goog.global`.\n * @private\n */\ngoog.exportPath_ = function(name, object, overwriteImplicit, objectToExportTo) {\n var parts = name.split('.');\n var cur = objectToExportTo || goog.global;\n\n // Internet Explorer exhibits strange behavior when throwing errors from\n // methods externed in this manner. See the testExportSymbolExceptions in\n // base_test.html for an example.\n if (!(parts[0] in cur) && typeof cur.execScript != 'undefined') {\n cur.execScript('var ' + parts[0]);\n }\n\n for (var part; parts.length && (part = parts.shift());) {\n if (!parts.length && object !== undefined) {\n if (!overwriteImplicit && goog.isObject(object) &&\n goog.isObject(cur[part])) {\n // Merge properties on object (the input parameter) with the existing\n // implicitly defined namespace, so as to not clobber previously\n // defined child namespaces.\n for (var prop in object) {\n if (object.hasOwnProperty(prop)) {\n cur[part][prop] = object[prop];\n }\n }\n } else {\n // Either there is no existing implicit namespace, or overwriteImplicit\n // is set to true, so directly assign object (the input parameter) to\n // the namespace.\n cur[part] = object;\n }\n } else if (cur[part] && cur[part] !== Object.prototype[part]) {\n cur = cur[part];\n } else {\n cur = cur[part] = {};\n }\n }\n};\n\n\n/**\n * Defines a named value. In uncompiled mode, the value is retrieved from\n * CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and\n * has the property specified, and otherwise used the defined defaultValue.\n * When compiled the default can be overridden using the compiler options or the\n * value set in the CLOSURE_DEFINES object. Returns the defined value so that it\n * can be used safely in modules. Note that the value type MUST be either\n * boolean, number, or string.\n *\n * @param {string} name The distinguished name to provide.\n * @param {T} defaultValue\n * @return {T} The defined value.\n * @template T\n */\ngoog.define = function(name, defaultValue) {\n var value = defaultValue;\n if (!COMPILED) {\n var uncompiledDefines = goog.global.CLOSURE_UNCOMPILED_DEFINES;\n var defines = goog.global.CLOSURE_DEFINES;\n if (uncompiledDefines &&\n // Anti DOM-clobbering runtime check (b/37736576).\n /** @type {?} */ (uncompiledDefines).nodeType === undefined &&\n Object.prototype.hasOwnProperty.call(uncompiledDefines, name)) {\n value = uncompiledDefines[name];\n } else if (\n defines &&\n // Anti DOM-clobbering runtime check (b/37736576).\n /** @type {?} */ (defines).nodeType === undefined &&\n Object.prototype.hasOwnProperty.call(defines, name)) {\n value = defines[name];\n }\n }\n return value;\n};\n\n\n/**\n * @define {number} Integer year indicating the set of browser features that are\n * guaranteed to be present. This is defined to include exactly features that\n * work correctly on all \"modern\" browsers that are stable on January 1 of the\n * specified year. For example,\n * ```js\n * if (goog.FEATURESET_YEAR >= 2019) {\n * // use APIs known to be available on all major stable browsers Jan 1, 2019\n * } else {\n * // polyfill for older browsers\n * }\n * ```\n * This is intended to be the primary define for removing\n * unnecessary browser compatibility code (such as ponyfills and workarounds),\n * and should inform the default value for most other defines:\n * ```js\n * const ASSUME_NATIVE_PROMISE =\n * goog.define('ASSUME_NATIVE_PROMISE', goog.FEATURESET_YEAR >= 2016);\n * ```\n *\n * The default assumption is that IE9 is the lowest supported browser, which was\n * first available Jan 1, 2012.\n *\n * TODO(user): Reference more thorough documentation when it's available.\n */\ngoog.FEATURESET_YEAR = goog.define('goog.FEATURESET_YEAR', 2012);\n\n\n/**\n * @define {boolean} DEBUG is provided as a convenience so that debugging code\n * that should not be included in a production. It can be easily stripped\n * by specifying --define goog.DEBUG=false to the Closure Compiler aka\n * JSCompiler. For example, most toString() methods should be declared inside an\n * \"if (goog.DEBUG)\" conditional because they are generally used for debugging\n * purposes and it is difficult for the JSCompiler to statically determine\n * whether they are used.\n */\ngoog.DEBUG = goog.define('goog.DEBUG', true);\n\n\n/**\n * @define {string} LOCALE defines the locale being used for compilation. It is\n * used to select locale specific data to be compiled in js binary. BUILD rule\n * can specify this value by \"--define goog.LOCALE=\" as a compiler\n * option.\n *\n * Take into account that the locale code format is important. You should use\n * the canonical Unicode format with hyphen as a delimiter. Language must be\n * lowercase, Language Script - Capitalized, Region - UPPERCASE.\n * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.\n *\n * See more info about locale codes here:\n * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers\n *\n * For language codes you should use values defined by ISO 693-1. See it here\n * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from\n * this rule: the Hebrew language. For legacy reasons the old code (iw) should\n * be used instead of the new code (he).\n *\n */\ngoog.LOCALE = goog.define('goog.LOCALE', 'en'); // default to en\n\n\n/**\n * @define {boolean} Whether this code is running on trusted sites.\n *\n * On untrusted sites, several native functions can be defined or overridden by\n * external libraries like Prototype, Datejs, and JQuery and setting this flag\n * to false forces closure to use its own implementations when possible.\n *\n * If your JavaScript can be loaded by a third party site and you are wary about\n * relying on non-standard implementations, specify\n * \"--define goog.TRUSTED_SITE=false\" to the compiler.\n */\ngoog.TRUSTED_SITE = goog.define('goog.TRUSTED_SITE', true);\n\n\n/**\n * @define {boolean} Whether code that calls {@link goog.setTestOnly} should\n * be disallowed in the compilation unit.\n */\ngoog.DISALLOW_TEST_ONLY_CODE =\n goog.define('goog.DISALLOW_TEST_ONLY_CODE', COMPILED && !goog.DEBUG);\n\n\n/**\n * @define {boolean} Whether to use a Chrome app CSP-compliant method for\n * loading scripts via goog.require. @see appendScriptSrcNode_.\n */\ngoog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING =\n goog.define('goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING', false);\n\n\n/**\n * Defines a namespace in Closure.\n *\n * A namespace may only be defined once in a codebase. It may be defined using\n * goog.provide() or goog.module().\n *\n * The presence of one or more goog.provide() calls in a file indicates\n * that the file defines the given objects/namespaces.\n * Provided symbols must not be null or undefined.\n *\n * In addition, goog.provide() creates the object stubs for a namespace\n * (for example, goog.provide(\"goog.foo.bar\") will create the object\n * goog.foo.bar if it does not already exist).\n *\n * Build tools also scan for provide/require/module statements\n * to discern dependencies, build dependency files (see deps.js), etc.\n *\n * @see goog.require\n * @see goog.module\n * @param {string} name Namespace provided by this file in the form\n * \"goog.package.part\".\n * deprecated Use goog.module (see b/159289405)\n */\ngoog.provide = function(name) {\n if (goog.isInModuleLoader_()) {\n throw new Error('goog.provide cannot be used within a module.');\n }\n if (!COMPILED) {\n // Ensure that the same namespace isn't provided twice.\n // A goog.module/goog.provide maps a goog.require to a specific file\n if (goog.isProvided_(name)) {\n throw new Error('Namespace \"' + name + '\" already declared.');\n }\n }\n\n goog.constructNamespace_(name);\n};\n\n\n/**\n * @param {string} name Namespace provided by this file in the form\n * \"goog.package.part\".\n * @param {?Object=} object The object to embed in the namespace.\n * @param {boolean=} overwriteImplicit If object is set and a previous call\n * implicitly constructed the namespace given by name, this parameter\n * controls whether opt_obj should overwrite the implicitly constructed\n * namespace or be merged into it. Defaults to false.\n * @private\n */\ngoog.constructNamespace_ = function(name, object, overwriteImplicit) {\n if (!COMPILED) {\n delete goog.implicitNamespaces_[name];\n\n var namespace = name;\n while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {\n if (goog.getObjectByName(namespace)) {\n break;\n }\n goog.implicitNamespaces_[namespace] = true;\n }\n }\n\n goog.exportPath_(name, object, overwriteImplicit);\n};\n\n\n/**\n * According to the CSP3 spec a nonce must be a valid base64 string.\n * @see https://www.w3.org/TR/CSP3/#grammardef-base64-value\n * @private @const\n */\ngoog.NONCE_PATTERN_ = /^[\\w+/_-]+[=]{0,2}$/;\n\n\n/**\n * Returns CSP nonce, if set for any script tag.\n * @param {?Window=} opt_window The window context used to retrieve the nonce.\n * Defaults to global context.\n * @return {string} CSP nonce or empty string if no nonce is present.\n * @private\n */\ngoog.getScriptNonce_ = function(opt_window) {\n var doc = (opt_window || goog.global).document;\n var script = doc.querySelector && doc.querySelector('script[nonce]');\n if (script) {\n // Try to get the nonce from the IDL property first, because browsers that\n // implement additional nonce protection features (currently only Chrome) to\n // prevent nonce stealing via CSS do not expose the nonce via attributes.\n // See https://github.com/whatwg/html/issues/2369\n var nonce = script['nonce'] || script.getAttribute('nonce');\n if (nonce && goog.NONCE_PATTERN_.test(nonce)) {\n return nonce;\n }\n }\n return '';\n};\n\n\n/**\n * Module identifier validation regexp.\n * Note: This is a conservative check, it is very possible to be more lenient,\n * the primary exclusion here is \"/\" and \"\\\" and a leading \".\", these\n * restrictions are intended to leave the door open for using goog.require\n * with relative file paths rather than module identifiers.\n * @private\n */\ngoog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/;\n\n\n/**\n * Defines a module in Closure.\n *\n * Marks that this file must be loaded as a module and claims the namespace.\n *\n * A namespace may only be defined once in a codebase. It may be defined using\n * goog.provide() or goog.module().\n *\n * goog.module() has three requirements:\n * - goog.module may not be used in the same file as goog.provide.\n * - goog.module must be the first statement in the file.\n * - only one goog.module is allowed per file.\n *\n * When a goog.module annotated file is loaded, it is enclosed in\n * a strict function closure. This means that:\n * - any variables declared in a goog.module file are private to the file\n * (not global), though the compiler is expected to inline the module.\n * - The code must obey all the rules of \"strict\" JavaScript.\n * - the file will be marked as \"use strict\"\n *\n * NOTE: unlike goog.provide, goog.module does not declare any symbols by\n * itself. If declared symbols are desired, use\n * goog.module.declareLegacyNamespace().\n *\n *\n * See the public goog.module proposal: http://goo.gl/Va1hin\n *\n * @param {string} name Namespace provided by this file in the form\n * \"goog.package.part\", is expected but not required.\n * @return {void}\n */\ngoog.module = function(name) {\n if (typeof name !== 'string' || !name ||\n name.search(goog.VALID_MODULE_RE_) == -1) {\n throw new Error('Invalid module identifier');\n }\n if (!goog.isInGoogModuleLoader_()) {\n throw new Error(\n 'Module ' + name + ' has been loaded incorrectly. Note, ' +\n 'modules cannot be loaded as normal scripts. They require some kind of ' +\n 'pre-processing step. You\\'re likely trying to load a module via a ' +\n 'script tag or as a part of a concatenated bundle without rewriting the ' +\n 'module. For more info see: ' +\n 'https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.');\n }\n if (goog.moduleLoaderState_.moduleName) {\n throw new Error('goog.module may only be called once per module.');\n }\n\n // Store the module name for the loader.\n goog.moduleLoaderState_.moduleName = name;\n if (!COMPILED) {\n // Ensure that the same namespace isn't provided twice.\n // A goog.module/goog.provide maps a goog.require to a specific file\n if (goog.isProvided_(name)) {\n throw new Error('Namespace \"' + name + '\" already declared.');\n }\n delete goog.implicitNamespaces_[name];\n }\n};\n\n\n/**\n * @param {string} name The module identifier.\n * @return {?} The module exports for an already loaded module or null.\n *\n * Note: This is not an alternative to goog.require, it does not\n * indicate a hard dependency, instead it is used to indicate\n * an optional dependency or to access the exports of a module\n * that has already been loaded.\n * @suppress {missingProvide}\n */\ngoog.module.get = function(name) {\n return goog.module.getInternal_(name);\n};\n\n\n/**\n * @param {string} name The module identifier.\n * @return {?} The module exports for an already loaded module or null.\n * @private\n */\ngoog.module.getInternal_ = function(name) {\n if (!COMPILED) {\n if (name in goog.loadedModules_) {\n return goog.loadedModules_[name].exports;\n } else if (!goog.implicitNamespaces_[name]) {\n var ns = goog.getObjectByName(name);\n return ns != null ? ns : null;\n }\n }\n return null;\n};\n\n/**\n * Types of modules the debug loader can load.\n * @enum {string}\n */\ngoog.ModuleType = {\n ES6: 'es6',\n GOOG: 'goog'\n};\n\n\n/**\n * @private {?{\n * moduleName: (string|undefined),\n * declareLegacyNamespace:boolean,\n * type: ?goog.ModuleType\n * }}\n */\ngoog.moduleLoaderState_ = null;\n\n\n/**\n * @private\n * @return {boolean} Whether a goog.module or an es6 module is currently being\n * initialized.\n */\ngoog.isInModuleLoader_ = function() {\n return goog.isInGoogModuleLoader_() || goog.isInEs6ModuleLoader_();\n};\n\n\n/**\n * @private\n * @return {boolean} Whether a goog.module is currently being initialized.\n */\ngoog.isInGoogModuleLoader_ = function() {\n return !!goog.moduleLoaderState_ &&\n goog.moduleLoaderState_.type == goog.ModuleType.GOOG;\n};\n\n\n/**\n * @private\n * @return {boolean} Whether an es6 module is currently being initialized.\n */\ngoog.isInEs6ModuleLoader_ = function() {\n var inLoader = !!goog.moduleLoaderState_ &&\n goog.moduleLoaderState_.type == goog.ModuleType.ES6;\n\n if (inLoader) {\n return true;\n }\n\n var jscomp = goog.global['$jscomp'];\n\n if (jscomp) {\n // jscomp may not have getCurrentModulePath if this is a compiled bundle\n // that has some of the runtime, but not all of it. This can happen if\n // optimizations are turned on so the unused runtime is removed but renaming\n // and Closure pass are off (so $jscomp is still named $jscomp and the\n // goog.provide/require calls still exist).\n if (typeof jscomp.getCurrentModulePath != 'function') {\n return false;\n }\n\n // Bundled ES6 module.\n return !!jscomp.getCurrentModulePath();\n }\n\n return false;\n};\n\n\n/**\n * Provide the module's exports as a globally accessible object under the\n * module's declared name. This is intended to ease migration to goog.module\n * for files that have existing usages.\n * @suppress {missingProvide}\n */\ngoog.module.declareLegacyNamespace = function() {\n if (!COMPILED && !goog.isInGoogModuleLoader_()) {\n throw new Error(\n 'goog.module.declareLegacyNamespace must be called from ' +\n 'within a goog.module');\n }\n if (!COMPILED && !goog.moduleLoaderState_.moduleName) {\n throw new Error(\n 'goog.module must be called prior to ' +\n 'goog.module.declareLegacyNamespace.');\n }\n goog.moduleLoaderState_.declareLegacyNamespace = true;\n};\n\n\n/**\n * Associates an ES6 module with a Closure module ID so that is available via\n * goog.require. The associated ID acts like a goog.module ID - it does not\n * create any global names, it is merely available via goog.require /\n * goog.module.get / goog.forwardDeclare / goog.requireType. goog.require and\n * goog.module.get will return the entire module as if it was import *'d. This\n * allows Closure files to reference ES6 modules for the sake of migration.\n *\n * @param {string} namespace\n * @suppress {missingProvide}\n */\ngoog.declareModuleId = function(namespace) {\n if (!COMPILED) {\n if (!goog.isInEs6ModuleLoader_()) {\n throw new Error(\n 'goog.declareModuleId may only be called from ' +\n 'within an ES6 module');\n }\n if (goog.moduleLoaderState_ && goog.moduleLoaderState_.moduleName) {\n throw new Error(\n 'goog.declareModuleId may only be called once per module.');\n }\n if (namespace in goog.loadedModules_) {\n throw new Error(\n 'Module with namespace \"' + namespace + '\" already exists.');\n }\n }\n if (goog.moduleLoaderState_) {\n // Not bundled - debug loading.\n goog.moduleLoaderState_.moduleName = namespace;\n } else {\n // Bundled - not debug loading, no module loader state.\n var jscomp = goog.global['$jscomp'];\n if (!jscomp || typeof jscomp.getCurrentModulePath != 'function') {\n throw new Error(\n 'Module with namespace \"' + namespace +\n '\" has been loaded incorrectly.');\n }\n var exports = jscomp.require(jscomp.getCurrentModulePath());\n goog.loadedModules_[namespace] = {\n exports: exports,\n type: goog.ModuleType.ES6,\n moduleId: namespace\n };\n }\n};\n\n\n/**\n * Marks that the current file should only be used for testing, and never for\n * live code in production.\n *\n * In the case of unit tests, the message may optionally be an exact namespace\n * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra\n * provide (if not explicitly defined in the code).\n *\n * @param {string=} opt_message Optional message to add to the error that's\n * raised when used in production code.\n */\ngoog.setTestOnly = function(opt_message) {\n if (goog.DISALLOW_TEST_ONLY_CODE) {\n opt_message = opt_message || '';\n throw new Error(\n 'Importing test-only code into non-debug environment' +\n (opt_message ? ': ' + opt_message : '.'));\n }\n};\n\n\n/**\n * Forward declares a symbol. This is an indication to the compiler that the\n * symbol may be used in the source yet is not required and may not be provided\n * in compilation.\n *\n * The most common usage of forward declaration is code that takes a type as a\n * function parameter but does not need to require it. By forward declaring\n * instead of requiring, no hard dependency is made, and (if not required\n * elsewhere) the namespace may never be required and thus, not be pulled\n * into the JavaScript binary. If it is required elsewhere, it will be type\n * checked as normal.\n *\n * Before using goog.forwardDeclare, please read the documentation at\n * https://github.com/google/closure-compiler/wiki/Bad-Type-Annotation to\n * understand the options and tradeoffs when working with forward declarations.\n *\n * @param {string} name The namespace to forward declare in the form of\n * \"goog.package.part\".\n * @deprecated See go/noforwarddeclaration, Use `goog.requireType` instead.\n */\ngoog.forwardDeclare = function(name) {};\n\n\n/**\n * Forward declare type information. Used to assign types to goog.global\n * referenced object that would otherwise result in unknown type references\n * and thus block property disambiguation.\n */\ngoog.forwardDeclare('Document');\ngoog.forwardDeclare('HTMLScriptElement');\ngoog.forwardDeclare('XMLHttpRequest');\n\n\nif (!COMPILED) {\n /**\n * Check if the given name has been goog.provided. This will return false for\n * names that are available only as implicit namespaces.\n * @param {string} name name of the object to look for.\n * @return {boolean} Whether the name has been provided.\n * @private\n */\n goog.isProvided_ = function(name) {\n return (name in goog.loadedModules_) ||\n (!goog.implicitNamespaces_[name] && goog.getObjectByName(name) != null);\n };\n\n /**\n * Namespaces implicitly defined by goog.provide. For example,\n * goog.provide('goog.events.Event') implicitly declares that 'goog' and\n * 'goog.events' must be namespaces.\n *\n * @type {!Object}\n * @private\n */\n goog.implicitNamespaces_ = {'goog.module': true};\n\n // NOTE: We add goog.module as an implicit namespace as goog.module is defined\n // here and because the existing module package has not been moved yet out of\n // the goog.module namespace. This satisifies both the debug loader and\n // ahead-of-time dependency management.\n}\n\n\n/**\n * Returns an object based on its fully qualified external name. The object\n * is not found if null or undefined. If you are using a compilation pass that\n * renames property names beware that using this function will not find renamed\n * properties.\n *\n * @param {string} name The fully qualified name.\n * @param {Object=} opt_obj The object within which to look; default is\n * |goog.global|.\n * @return {?} The value (object or primitive) or, if not found, null.\n */\ngoog.getObjectByName = function(name, opt_obj) {\n var parts = name.split('.');\n var cur = opt_obj || goog.global;\n for (var i = 0; i < parts.length; i++) {\n cur = cur[parts[i]];\n if (cur == null) {\n return null;\n }\n }\n return cur;\n};\n\n\n/**\n * Adds a dependency from a file to the files it requires.\n * @param {string} relPath The path to the js file.\n * @param {!Array} provides An array of strings with\n * the names of the objects this file provides.\n * @param {!Array} requires An array of strings with\n * the names of the objects this file requires.\n * @param {boolean|!Object=} opt_loadFlags Parameters indicating\n * how the file must be loaded. The boolean 'true' is equivalent\n * to {'module': 'goog'} for backwards-compatibility. Valid properties\n * and values include {'module': 'goog'} and {'lang': 'es6'}.\n */\ngoog.addDependency = function(relPath, provides, requires, opt_loadFlags) {\n if (!COMPILED && goog.DEPENDENCIES_ENABLED) {\n goog.debugLoader_.addDependency(relPath, provides, requires, opt_loadFlags);\n }\n};\n\n\n// NOTE(nnaze): The debug DOM loader was included in base.js as an original way\n// to do \"debug-mode\" development. The dependency system can sometimes be\n// confusing, as can the debug DOM loader's asynchronous nature.\n//\n// With the DOM loader, a call to goog.require() is not blocking -- the script\n// will not load until some point after the current script. If a namespace is\n// needed at runtime, it needs to be defined in a previous script, or loaded via\n// require() with its registered dependencies.\n//\n// User-defined namespaces may need their own deps file. For a reference on\n// creating a deps file, see:\n// Externally: https://developers.google.com/closure/library/docs/depswriter\n//\n// Because of legacy clients, the DOM loader can't be easily removed from\n// base.js. Work was done to make it disableable or replaceable for\n// different environments (DOM-less JavaScript interpreters like Rhino or V8,\n// for example). See bootstrap/ for more information.\n\n\n/**\n * @define {boolean} Whether to enable the debug loader.\n *\n * If enabled, a call to goog.require() will attempt to load the namespace by\n * appending a script tag to the DOM (if the namespace has been registered).\n *\n * If disabled, goog.require() will simply assert that the namespace has been\n * provided (and depend on the fact that some outside tool correctly ordered\n * the script).\n */\ngoog.ENABLE_DEBUG_LOADER = goog.define('goog.ENABLE_DEBUG_LOADER', true);\n\n\n/**\n * @param {string} msg\n * @private\n */\ngoog.logToConsole_ = function(msg) {\n if (goog.global.console) {\n goog.global.console['error'](msg);\n }\n};\n\n\n/**\n * Implements a system for the dynamic resolution of dependencies that works in\n * parallel with the BUILD system.\n *\n * Note that all calls to goog.require will be stripped by the compiler.\n *\n * @see goog.provide\n * @param {string} namespace Namespace (as was given in goog.provide,\n * goog.module, or goog.declareModuleId) in the form\n * \"goog.package.part\".\n * @return {?} If called within a goog.module or ES6 module file, the associated\n * namespace or module otherwise null.\n */\ngoog.require = function(namespace) {\n if (!COMPILED) {\n // Might need to lazy load on old IE.\n if (goog.ENABLE_DEBUG_LOADER) {\n goog.debugLoader_.requested(namespace);\n }\n\n // If the object already exists we do not need to do anything.\n if (goog.isProvided_(namespace)) {\n if (goog.isInModuleLoader_()) {\n return goog.module.getInternal_(namespace);\n }\n } else if (goog.ENABLE_DEBUG_LOADER) {\n var moduleLoaderState = goog.moduleLoaderState_;\n goog.moduleLoaderState_ = null;\n try {\n goog.debugLoader_.load_(namespace);\n } finally {\n goog.moduleLoaderState_ = moduleLoaderState;\n }\n }\n\n return null;\n }\n};\n\n\n/**\n * Requires a symbol for its type information. This is an indication to the\n * compiler that the symbol may appear in type annotations, yet it is not\n * referenced at runtime.\n *\n * When called within a goog.module or ES6 module file, the return value may be\n * assigned to or destructured into a variable, but it may not be otherwise used\n * in code outside of a type annotation.\n *\n * Note that all calls to goog.requireType will be stripped by the compiler.\n *\n * @param {string} namespace Namespace (as was given in goog.provide,\n * goog.module, or goog.declareModuleId) in the form\n * \"goog.package.part\".\n * @return {?}\n */\ngoog.requireType = function(namespace) {\n // Return an empty object so that single-level destructuring of the return\n // value doesn't crash at runtime when using the debug loader. Multi-level\n // destructuring isn't supported.\n return {};\n};\n\n\n/**\n * Path for included scripts.\n * @type {string}\n */\ngoog.basePath = '';\n\n\n/**\n * A hook for overriding the base path.\n * @type {string|undefined}\n */\ngoog.global.CLOSURE_BASE_PATH;\n\n\n/**\n * Whether to attempt to load Closure's deps file. By default, when uncompiled,\n * deps files will attempt to be loaded.\n * @type {boolean|undefined}\n */\ngoog.global.CLOSURE_NO_DEPS;\n\n\n/**\n * A function to import a single script. This is meant to be overridden when\n * Closure is being run in non-HTML contexts, such as web workers. It's defined\n * in the global scope so that it can be set before base.js is loaded, which\n * allows deps.js to be imported properly.\n *\n * The first parameter the script source, which is a relative URI. The second,\n * optional parameter is the script contents, in the event the script needed\n * transformation. It should return true if the script was imported, false\n * otherwise.\n * @type {(function(string, string=): boolean)|undefined}\n */\ngoog.global.CLOSURE_IMPORT_SCRIPT;\n\n\n/**\n * When defining a class Foo with an abstract method bar(), you can do:\n * Foo.prototype.bar = goog.abstractMethod\n *\n * Now if a subclass of Foo fails to override bar(), an error will be thrown\n * when bar() is invoked.\n *\n * @type {!Function}\n * @throws {Error} when invoked to indicate the method should be overridden.\n * @deprecated Use \"@abstract\" annotation instead of goog.abstractMethod in new\n * code. See\n * https://github.com/google/closure-compiler/wiki/@abstract-classes-and-methods\n */\ngoog.abstractMethod = function() {\n throw new Error('unimplemented abstract method');\n};\n\n\n/**\n * Adds a `getInstance` static method that always returns the same\n * instance object.\n * @param {!Function} ctor The constructor for the class to add the static\n * method to.\n * @suppress {missingProperties} 'instance_' isn't a property on 'Function'\n * but we don't have a better type to use here.\n */\ngoog.addSingletonGetter = function(ctor) {\n // instance_ is immediately set to prevent issues with sealed constructors\n // such as are encountered when a constructor is returned as the export object\n // of a goog.module in unoptimized code.\n // Delcare type to avoid conformance violations that ctor.instance_ is unknown\n /** @type {undefined|!Object} @suppress {underscore} */\n ctor.instance_ = undefined;\n ctor.getInstance = function() {\n if (ctor.instance_) {\n return ctor.instance_;\n }\n if (goog.DEBUG) {\n // NOTE: JSCompiler can't optimize away Array#push.\n goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;\n }\n // Cast to avoid conformance violations that ctor.instance_ is unknown\n return /** @type {!Object|undefined} */ (ctor.instance_) = new ctor;\n };\n};\n\n\n/**\n * All singleton classes that have been instantiated, for testing. Don't read\n * it directly, use the `goog.testing.singleton` module. The compiler\n * removes this variable if unused.\n * @type {!Array}\n * @private\n */\ngoog.instantiatedSingletons_ = [];\n\n\n/**\n * @define {boolean} Whether to load goog.modules using `eval` when using\n * the debug loader. This provides a better debugging experience as the\n * source is unmodified and can be edited using Chrome Workspaces or similar.\n * However in some environments the use of `eval` is banned\n * so we provide an alternative.\n */\ngoog.LOAD_MODULE_USING_EVAL = goog.define('goog.LOAD_MODULE_USING_EVAL', true);\n\n\n/**\n * @define {boolean} Whether the exports of goog.modules should be sealed when\n * possible.\n */\ngoog.SEAL_MODULE_EXPORTS = goog.define('goog.SEAL_MODULE_EXPORTS', goog.DEBUG);\n\n\n/**\n * The registry of initialized modules:\n * The module identifier or path to module exports map.\n * @private @const {!Object}\n */\ngoog.loadedModules_ = {};\n\n\n/**\n * True if the debug loader enabled and used.\n * @const {boolean}\n */\ngoog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;\n\n\n/**\n * @define {string} How to decide whether to transpile. Valid values\n * are 'always', 'never', and 'detect'. The default ('detect') is to\n * use feature detection to determine which language levels need\n * transpilation.\n */\n// NOTE(sdh): we could expand this to accept a language level to bypass\n// detection: e.g. goog.TRANSPILE == 'es5' would transpile ES6 files but\n// would leave ES3 and ES5 files alone.\ngoog.TRANSPILE = goog.define('goog.TRANSPILE', 'detect');\n\n/**\n * @define {boolean} If true assume that ES modules have already been\n * transpiled by the jscompiler (in the same way that transpile.js would\n * transpile them - to jscomp modules). Useful only for servers that wish to use\n * the debug loader and transpile server side. Thus this is only respected if\n * goog.TRANSPILE is \"never\".\n */\ngoog.ASSUME_ES_MODULES_TRANSPILED =\n goog.define('goog.ASSUME_ES_MODULES_TRANSPILED', false);\n\n\n/**\n * @define {string} Trusted Types policy name. If non-empty then Closure will\n * use Trusted Types.\n */\ngoog.TRUSTED_TYPES_POLICY_NAME =\n goog.define('goog.TRUSTED_TYPES_POLICY_NAME', 'goog');\n\n\n/**\n * @package {?boolean}\n * Visible for testing.\n */\ngoog.hasBadLetScoping = null;\n\n\n/**\n * @param {function(?):?|string} moduleDef The module definition.\n */\ngoog.loadModule = function(moduleDef) {\n // NOTE: we allow function definitions to be either in the from\n // of a string to eval (which keeps the original source intact) or\n // in a eval forbidden environment (CSP) we allow a function definition\n // which in its body must call `goog.module`, and return the exports\n // of the module.\n var previousState = goog.moduleLoaderState_;\n try {\n goog.moduleLoaderState_ = {\n moduleName: '',\n declareLegacyNamespace: false,\n type: goog.ModuleType.GOOG\n };\n var origExports = {};\n var exports = origExports;\n if (typeof moduleDef === 'function') {\n exports = moduleDef.call(undefined, exports);\n } else if (typeof moduleDef === 'string') {\n exports = goog.loadModuleFromSource_.call(undefined, exports, moduleDef);\n } else {\n throw new Error('Invalid module definition');\n }\n\n var moduleName = goog.moduleLoaderState_.moduleName;\n if (typeof moduleName === 'string' && moduleName) {\n // Don't seal legacy namespaces as they may be used as a parent of\n // another namespace\n if (goog.moduleLoaderState_.declareLegacyNamespace) {\n // Whether exports was overwritten via default export assignment.\n // This is important for legacy namespaces as it dictates whether\n // previously a previously loaded implicit namespace should be clobbered\n // or not.\n var isDefaultExport = origExports !== exports;\n goog.constructNamespace_(moduleName, exports, isDefaultExport);\n } else if (\n goog.SEAL_MODULE_EXPORTS && Object.seal &&\n typeof exports == 'object' && exports != null) {\n Object.seal(exports);\n }\n\n var data = {\n exports: exports,\n type: goog.ModuleType.GOOG,\n moduleId: goog.moduleLoaderState_.moduleName\n };\n goog.loadedModules_[moduleName] = data;\n } else {\n throw new Error('Invalid module name \\\"' + moduleName + '\\\"');\n }\n } finally {\n goog.moduleLoaderState_ = previousState;\n }\n};\n\n\n/**\n * @private @const\n */\ngoog.loadModuleFromSource_ =\n /** @type {function(!Object, string):?} */ (function(exports) {\n // NOTE: we avoid declaring parameters or local variables here to avoid\n // masking globals or leaking values into the module definition.\n 'use strict';\n eval(goog.CLOSURE_EVAL_PREFILTER_.createScript(arguments[1]));\n return exports;\n });\n\n\n/**\n * Normalize a file path by removing redundant \"..\" and extraneous \".\" file\n * path components.\n * @param {string} path\n * @return {string}\n * @private\n */\ngoog.normalizePath_ = function(path) {\n var components = path.split('/');\n var i = 0;\n while (i < components.length) {\n if (components[i] == '.') {\n components.splice(i, 1);\n } else if (\n i && components[i] == '..' && components[i - 1] &&\n components[i - 1] != '..') {\n components.splice(--i, 2);\n } else {\n i++;\n }\n }\n return components.join('/');\n};\n\n\n/**\n * Provides a hook for loading a file when using Closure's goog.require() API\n * with goog.modules. In particular this hook is provided to support Node.js.\n *\n * @type {(function(string):string)|undefined}\n */\ngoog.global.CLOSURE_LOAD_FILE_SYNC;\n\n\n/**\n * Loads file by synchronous XHR. Should not be used in production environments.\n * @param {string} src Source URL.\n * @return {?string} File contents, or null if load failed.\n * @private\n */\ngoog.loadFileSync_ = function(src) {\n if (goog.global.CLOSURE_LOAD_FILE_SYNC) {\n return goog.global.CLOSURE_LOAD_FILE_SYNC(src);\n } else {\n try {\n /** @type {XMLHttpRequest} */\n var xhr = new goog.global['XMLHttpRequest']();\n xhr.open('get', src, false);\n xhr.send();\n // NOTE: Successful http: requests have a status of 200, but successful\n // file: requests may have a status of zero. Any other status, or a\n // thrown exception (particularly in case of file: requests) indicates\n // some sort of error, which we treat as a missing or unavailable file.\n return xhr.status == 0 || xhr.status == 200 ? xhr.responseText : null;\n } catch (err) {\n // No need to rethrow or log, since errors should show up on their own.\n return null;\n }\n }\n};\n\n//==============================================================================\n// Language Enhancements\n//==============================================================================\n\n\n/**\n * This is a \"fixed\" version of the typeof operator. It differs from the typeof\n * operator in such a way that null returns 'null' and arrays return 'array'.\n * @param {?} value The value to get the type of.\n * @return {string} The name of the type.\n */\ngoog.typeOf = function(value) {\n var s = typeof value;\n\n if (s != 'object') {\n return s;\n }\n\n if (!value) {\n return 'null';\n }\n\n if (Array.isArray(value)) {\n return 'array';\n }\n return s;\n};\n\n\n/**\n * Returns true if the object looks like an array. To qualify as array like\n * the value needs to be either a NodeList or an object with a Number length\n * property. Note that for this function neither strings nor functions are\n * considered \"array-like\".\n *\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an array.\n */\ngoog.isArrayLike = function(val) {\n var type = goog.typeOf(val);\n // We do not use goog.isObject here in order to exclude function values.\n return type == 'array' || type == 'object' && typeof val.length == 'number';\n};\n\n\n/**\n * Returns true if the object looks like a Date. To qualify as Date-like the\n * value needs to be an object and have a getFullYear() function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a like a Date.\n */\ngoog.isDateLike = function(val) {\n return goog.isObject(val) && typeof val.getFullYear == 'function';\n};\n\n\n/**\n * Returns true if the specified value is an object. This includes arrays and\n * functions.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an object.\n */\ngoog.isObject = function(val) {\n var type = typeof val;\n return type == 'object' && val != null || type == 'function';\n // return Object(val) === val also works, but is slower, especially if val is\n // not an object.\n};\n\n\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. The unique ID is\n * guaranteed to be unique across the current session amongst objects that are\n * passed into `getUid`. There is no guarantee that the ID is unique or\n * consistent across sessions. It is unsafe to generate unique ID for function\n * prototypes.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {number} The unique ID for the object.\n */\ngoog.getUid = function(obj) {\n // TODO(arv): Make the type stricter, do not accept null.\n return Object.prototype.hasOwnProperty.call(obj, goog.UID_PROPERTY_) &&\n obj[goog.UID_PROPERTY_] ||\n (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);\n};\n\n\n/**\n * Whether the given object is already assigned a unique ID.\n *\n * This does not modify the object.\n *\n * @param {!Object} obj The object to check.\n * @return {boolean} Whether there is an assigned unique id for the object.\n */\ngoog.hasUid = function(obj) {\n return !!obj[goog.UID_PROPERTY_];\n};\n\n\n/**\n * Removes the unique ID from an object. This is useful if the object was\n * previously mutated using `goog.getUid` in which case the mutation is\n * undone.\n * @param {Object} obj The object to remove the unique ID field from.\n */\ngoog.removeUid = function(obj) {\n // TODO(arv): Make the type stricter, do not accept null.\n\n // In IE, DOM nodes are not instances of Object and throw an exception if we\n // try to delete. Instead we try to use removeAttribute.\n if (obj !== null && 'removeAttribute' in obj) {\n obj.removeAttribute(goog.UID_PROPERTY_);\n }\n\n try {\n delete obj[goog.UID_PROPERTY_];\n } catch (ex) {\n }\n};\n\n\n/**\n * Name for unique ID property. Initialized in a way to help avoid collisions\n * with other closure JavaScript on the same page.\n * @type {string}\n * @private\n */\ngoog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);\n\n\n/**\n * Counter for UID.\n * @type {number}\n * @private\n */\ngoog.uidCounter_ = 0;\n\n\n/**\n * Clones a value. The input may be an Object, Array, or basic type. Objects and\n * arrays will be cloned recursively.\n *\n * WARNINGS:\n * goog.cloneObject does not detect reference loops. Objects that\n * refer to themselves will cause infinite recursion.\n *\n * goog.cloneObject is unaware of unique identifiers, and copies\n * UIDs created by getUid into cloned results.\n *\n * @param {*} obj The value to clone.\n * @return {*} A clone of the input value.\n * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.\n */\ngoog.cloneObject = function(obj) {\n var type = goog.typeOf(obj);\n if (type == 'object' || type == 'array') {\n if (typeof obj.clone === 'function') {\n return obj.clone();\n }\n if (typeof Map !== 'undefined' && obj instanceof Map) {\n return new Map(obj);\n } else if (typeof Set !== 'undefined' && obj instanceof Set) {\n return new Set(obj);\n }\n var clone = type == 'array' ? [] : {};\n for (var key in obj) {\n clone[key] = goog.cloneObject(obj[key]);\n }\n return clone;\n }\n\n return obj;\n};\n\n\n/**\n * A native implementation of goog.bind.\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n * function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n * function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n * invoked as a method of.\n * @template T\n * @private\n */\ngoog.bindNative_ = function(fn, selfObj, var_args) {\n return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));\n};\n\n\n/**\n * A pure-JS implementation of goog.bind.\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n * function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n * function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n * invoked as a method of.\n * @template T\n * @private\n */\ngoog.bindJs_ = function(fn, selfObj, var_args) {\n if (!fn) {\n throw new Error();\n }\n\n if (arguments.length > 2) {\n var boundArgs = Array.prototype.slice.call(arguments, 2);\n return function() {\n // Prepend the bound arguments to the current arguments.\n var newArgs = Array.prototype.slice.call(arguments);\n Array.prototype.unshift.apply(newArgs, boundArgs);\n return fn.apply(selfObj, newArgs);\n };\n\n } else {\n return function() {\n return fn.apply(selfObj, arguments);\n };\n }\n};\n\n\n/**\n * Partially applies this function to a particular 'this object' and zero or\n * more arguments. The result is a new function with some arguments of the first\n * function pre-filled and the value of this 'pre-specified'.\n *\n * Remaining arguments specified at call-time are appended to the pre-specified\n * ones.\n *\n * Also see: {@link #partial}.\n *\n * Usage:\n *
var barMethBound = goog.bind(myFunction, myObj, 'arg1', 'arg2');\n * barMethBound('arg3', 'arg4');
\n *\n * @param {?function(this:T, ...)} fn A function to partially apply.\n * @param {T} selfObj Specifies the object which this should point to when the\n * function is run.\n * @param {...*} var_args Additional arguments that are partially applied to the\n * function.\n * @return {!Function} A partially-applied form of the function goog.bind() was\n * invoked as a method of.\n * @template T\n * @suppress {deprecated} See above.\n * @deprecated use `=> {}` or Function.prototype.bind instead.\n */\ngoog.bind = function(fn, selfObj, var_args) {\n // TODO(nicksantos): narrow the type signature.\n if (Function.prototype.bind &&\n // NOTE(nicksantos): Somebody pulled base.js into the default Chrome\n // extension environment. This means that for Chrome extensions, they get\n // the implementation of Function.prototype.bind that calls goog.bind\n // instead of the native one. Even worse, we don't want to introduce a\n // circular dependency between goog.bind and Function.prototype.bind, so\n // we have to hack this to make sure it works correctly.\n Function.prototype.bind.toString().indexOf('native code') != -1) {\n goog.bind = goog.bindNative_;\n } else {\n goog.bind = goog.bindJs_;\n }\n return goog.bind.apply(null, arguments);\n};\n\n\n/**\n * Like goog.bind(), except that a 'this object' is not required. Useful when\n * the target function is already bound.\n *\n * Usage:\n * var g = goog.partial(f, arg1, arg2);\n * g(arg3, arg4);\n *\n * @param {Function} fn A function to partially apply.\n * @param {...*} var_args Additional arguments that are partially applied to fn.\n * @return {!Function} A partially-applied form of the function goog.partial()\n * was invoked as a method of.\n */\ngoog.partial = function(fn, var_args) {\n var args = Array.prototype.slice.call(arguments, 1);\n return function() {\n // Clone the array (with slice()) and append additional arguments\n // to the existing arguments.\n var newArgs = args.slice();\n newArgs.push.apply(newArgs, arguments);\n return fn.apply(/** @type {?} */ (this), newArgs);\n };\n};\n\n\n/**\n * @return {number} An integer value representing the number of milliseconds\n * between midnight, January 1, 1970 and the current time.\n * @deprecated Use Date.now\n */\ngoog.now = function() {\n return Date.now();\n};\n\n\n/**\n * Evals JavaScript in the global scope.\n *\n * Throws an exception if neither execScript or eval is defined.\n * @param {string|!TrustedScript} script JavaScript string.\n */\ngoog.globalEval = function(script) {\n (0, eval)(script);\n};\n\n\n/**\n * Optional map of CSS class names to obfuscated names used with\n * goog.getCssName().\n * @private {!Object|undefined}\n * @see goog.setCssNameMapping\n */\ngoog.cssNameMapping_;\n\n\n/**\n * Optional obfuscation style for CSS class names. Should be set to either\n * 'BY_WHOLE' or 'BY_PART' if defined.\n * @type {string|undefined}\n * @private\n * @see goog.setCssNameMapping\n */\ngoog.cssNameMappingStyle_;\n\n\n\n/**\n * A hook for modifying the default behavior goog.getCssName. The function\n * if present, will receive the standard output of the goog.getCssName as\n * its input.\n *\n * @type {(function(string):string)|undefined}\n */\ngoog.global.CLOSURE_CSS_NAME_MAP_FN;\n\n\n/**\n * Handles strings that are intended to be used as CSS class names.\n *\n * This function works in tandem with @see goog.setCssNameMapping.\n *\n * Without any mapping set, the arguments are simple joined with a hyphen and\n * passed through unaltered.\n *\n * When there is a mapping, there are two possible styles in which these\n * mappings are used. In the BY_PART style, each part (i.e. in between hyphens)\n * of the passed in css name is rewritten according to the map. In the BY_WHOLE\n * style, the full css name is looked up in the map directly. If a rewrite is\n * not specified by the map, the compiler will output a warning.\n *\n * When the mapping is passed to the compiler, it will replace calls to\n * goog.getCssName with the strings from the mapping, e.g.\n * var x = goog.getCssName('foo');\n * var y = goog.getCssName(this.baseClass, 'active');\n * becomes:\n * var x = 'foo';\n * var y = this.baseClass + '-active';\n *\n * If one argument is passed it will be processed, if two are passed only the\n * modifier will be processed, as it is assumed the first argument was generated\n * as a result of calling goog.getCssName.\n *\n * @param {string} className The class name.\n * @param {string=} opt_modifier A modifier to be appended to the class name.\n * @return {string} The class name or the concatenation of the class name and\n * the modifier.\n */\ngoog.getCssName = function(className, opt_modifier) {\n // String() is used for compatibility with compiled soy where the passed\n // className can be non-string objects.\n if (String(className).charAt(0) == '.') {\n throw new Error(\n 'className passed in goog.getCssName must not start with \".\".' +\n ' You passed: ' + className);\n }\n\n var getMapping = function(cssName) {\n return goog.cssNameMapping_[cssName] || cssName;\n };\n\n var renameByParts = function(cssName) {\n // Remap all the parts individually.\n var parts = cssName.split('-');\n var mapped = [];\n for (var i = 0; i < parts.length; i++) {\n mapped.push(getMapping(parts[i]));\n }\n return mapped.join('-');\n };\n\n var rename;\n if (goog.cssNameMapping_) {\n rename =\n goog.cssNameMappingStyle_ == 'BY_WHOLE' ? getMapping : renameByParts;\n } else {\n rename = function(a) {\n return a;\n };\n }\n\n var result =\n opt_modifier ? className + '-' + rename(opt_modifier) : rename(className);\n\n // The special CLOSURE_CSS_NAME_MAP_FN allows users to specify further\n // processing of the class name.\n if (goog.global.CLOSURE_CSS_NAME_MAP_FN) {\n return goog.global.CLOSURE_CSS_NAME_MAP_FN(result);\n }\n\n return result;\n};\n\n\n/**\n * Sets the map to check when returning a value from goog.getCssName(). Example:\n *
\n * goog.setCssNameMapping({\n *   \"goog\": \"a\",\n *   \"disabled\": \"b\",\n * });\n *\n * var x = goog.getCssName('goog');\n * // The following evaluates to: \"a a-b\".\n * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')\n * 
\n * When declared as a map of string literals to string literals, the JSCompiler\n * will replace all calls to goog.getCssName() using the supplied map if the\n * --process_closure_primitives flag is set.\n *\n * @param {!Object} mapping A map of strings to strings where keys are possible\n * arguments to goog.getCssName() and values are the corresponding values\n * that should be returned.\n * @param {string=} opt_style The style of css name mapping. There are two valid\n * options: 'BY_PART', and 'BY_WHOLE'.\n * @see goog.getCssName for a description.\n */\ngoog.setCssNameMapping = function(mapping, opt_style) {\n goog.cssNameMapping_ = mapping;\n goog.cssNameMappingStyle_ = opt_style;\n};\n\n\n/**\n * To use CSS renaming in compiled mode, one of the input files should have a\n * call to goog.setCssNameMapping() with an object literal that the JSCompiler\n * can extract and use to replace all calls to goog.getCssName(). In uncompiled\n * mode, JavaScript code should be loaded before this base.js file that declares\n * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is\n * to ensure that the mapping is loaded before any calls to goog.getCssName()\n * are made in uncompiled mode.\n *\n * A hook for overriding the CSS name mapping.\n * @type {!Object|undefined}\n */\ngoog.global.CLOSURE_CSS_NAME_MAPPING;\n\n\nif (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {\n // This does not call goog.setCssNameMapping() because the JSCompiler\n // requires that goog.setCssNameMapping() be called with an object literal.\n goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;\n}\n\n/**\n * Options bag type for `goog.getMsg()` third argument.\n *\n * It is important to note that these options need to be known at compile time,\n * so they must always be provided to `goog.getMsg()` as an actual object\n * literal in the function call. Otherwise, closure-compiler will report an\n * error.\n * @record\n */\ngoog.GetMsgOptions = function() {};\n\n/**\n * If `true`, escape '<' in the message string to '<'.\n *\n * Used by Closure Templates where the generated code size and performance is\n * critical which is why {@link goog.html.SafeHtmlFormatter} is not used.\n * The value must be literal `true` or `false`.\n * @type {boolean|undefined}\n */\ngoog.GetMsgOptions.prototype.html;\n\n/**\n * If `true`, unescape common html entities: >, <, ', " and\n * &.\n *\n * Used for messages not in HTML context, such as with the `textContent`\n * property.\n * The value must be literal `true` or `false`.\n * @type {boolean|undefined}\n */\ngoog.GetMsgOptions.prototype.unescapeHtmlEntities;\n\n/**\n * Associates placeholder names with strings showing how their values are\n * obtained.\n *\n * This field is intended for use in automatically generated JS code.\n * Human-written code should use meaningful placeholder names instead.\n *\n * closure-compiler uses this as the contents of the `` tag in the\n * XMB file it generates or defaults to `-` for historical reasons.\n *\n * Must be an object literal.\n * Ignored at runtime.\n * Keys are placeholder names.\n * Values are string literals indicating how the value is obtained.\n * Typically this is a snippet of source code.\n * @type {!Object|undefined}\n */\ngoog.GetMsgOptions.prototype.original_code;\n\n/**\n * Associates placeholder names with example values.\n *\n * closure-compiler uses this as the contents of the `` tag in the\n * XMB file it generates or defaults to `-` for historical reasons.\n *\n * Must be an object literal.\n * Ignored at runtime.\n * Keys are placeholder names.\n * Values are string literals containing example placeholder values.\n * (e.g. \"George McFly\" for a name placeholder)\n * @type {!Object|undefined}\n */\ngoog.GetMsgOptions.prototype.example;\n\n/**\n * Gets a localized message.\n *\n * This function is a compiler primitive. If you give the compiler a localized\n * message bundle, it will replace the string at compile-time with a localized\n * version, and expand goog.getMsg call to a concatenated string.\n *\n * Messages must be initialized in the form:\n * \n * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'});\n * \n *\n * This function produces a string which should be treated as plain text. Use\n * {@link goog.html.SafeHtmlFormatter} in conjunction with goog.getMsg to\n * produce SafeHtml.\n *\n * @param {string} str Translatable string, places holders in the form {$foo}.\n * @param {!Object=} opt_values Maps place holder name to value.\n * @param {!goog.GetMsgOptions=} opt_options see `goog.GetMsgOptions`\n * @return {string} message with placeholders filled.\n */\ngoog.getMsg = function(str, opt_values, opt_options) {\n if (opt_options && opt_options.html) {\n // Note that '&' is not replaced because the translation can contain HTML\n // entities.\n str = str.replace(/')\n .replace(/'/g, '\\'')\n .replace(/"/g, '\"')\n .replace(/&/g, '&');\n }\n if (opt_values) {\n str = str.replace(/\\{\\$([^}]+)}/g, function(match, key) {\n return (opt_values != null && key in opt_values) ? opt_values[key] :\n match;\n });\n }\n return str;\n};\n\n\n/**\n * Gets a localized message. If the message does not have a translation, gives a\n * fallback message.\n *\n * This is useful when introducing a new message that has not yet been\n * translated into all languages.\n *\n * This function is a compiler primitive. Must be used in the form:\n * var x = goog.getMsgWithFallback(MSG_A, MSG_B);\n * where MSG_A and MSG_B were initialized with goog.getMsg.\n *\n * @param {string} a The preferred message.\n * @param {string} b The fallback message.\n * @return {string} The best translated message.\n */\ngoog.getMsgWithFallback = function(a, b) {\n return a;\n};\n\n\n/**\n * Exposes an unobfuscated global namespace path for the given object.\n * Note that fields of the exported object *will* be obfuscated, unless they are\n * exported in turn via this function or goog.exportProperty.\n *\n * Also handy for making public items that are defined in anonymous closures.\n *\n * ex. goog.exportSymbol('public.path.Foo', Foo);\n *\n * ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction);\n * public.path.Foo.staticFunction();\n *\n * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',\n * Foo.prototype.myMethod);\n * new public.path.Foo().myMethod();\n *\n * @param {string} publicPath Unobfuscated name to export.\n * @param {*} object Object the name should point to.\n * @param {?Object=} objectToExportTo The object to add the path to; default\n * is goog.global.\n */\ngoog.exportSymbol = function(publicPath, object, objectToExportTo) {\n goog.exportPath_(\n publicPath, object, /* overwriteImplicit= */ true, objectToExportTo);\n};\n\n\n/**\n * Exports a property unobfuscated into the object's namespace.\n * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);\n * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);\n * @param {Object} object Object whose static property is being exported.\n * @param {string} publicName Unobfuscated name to export.\n * @param {*} symbol Object the name should point to.\n */\ngoog.exportProperty = function(object, publicName, symbol) {\n object[publicName] = symbol;\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * Usage:\n *
\n * function ParentClass(a, b) { }\n * ParentClass.prototype.foo = function(a) { };\n *\n * function ChildClass(a, b, c) {\n *   ChildClass.base(this, 'constructor', a, b);\n * }\n * goog.inherits(ChildClass, ParentClass);\n *\n * var child = new ChildClass('a', 'b', 'see');\n * child.foo(); // This works.\n * 
\n *\n * @param {!Function} childCtor Child class.\n * @param {!Function} parentCtor Parent class.\n * @suppress {strictMissingProperties} superClass_ and base is not defined on\n * Function.\n * @deprecated Use ECMAScript class syntax instead.\n */\ngoog.inherits = function(childCtor, parentCtor) {\n /** @constructor */\n function tempCtor() {}\n tempCtor.prototype = parentCtor.prototype;\n childCtor.superClass_ = parentCtor.prototype;\n childCtor.prototype = new tempCtor();\n /** @override */\n childCtor.prototype.constructor = childCtor;\n\n /**\n * Calls superclass constructor/method.\n *\n * This function is only available if you use goog.inherits to\n * express inheritance relationships between classes.\n *\n * NOTE: This is a replacement for goog.base and for superClass_\n * property defined in childCtor.\n *\n * @param {!Object} me Should always be \"this\".\n * @param {string} methodName The method name to call. Calling\n * superclass constructor can be done with the special string\n * 'constructor'.\n * @param {...*} var_args The arguments to pass to superclass\n * method/constructor.\n * @return {*} The return value of the superclass method/constructor.\n */\n childCtor.base = function(me, methodName, var_args) {\n // Copying using loop to avoid deop due to passing arguments object to\n // function. This is faster in many JS engines as of late 2014.\n var args = new Array(arguments.length - 2);\n for (var i = 2; i < arguments.length; i++) {\n args[i - 2] = arguments[i];\n }\n return parentCtor.prototype[methodName].apply(me, args);\n };\n};\n\n\n/**\n * Allow for aliasing within scope functions. This function exists for\n * uncompiled code - in compiled code the calls will be inlined and the aliases\n * applied. In uncompiled code the function is simply run since the aliases as\n * written are valid JavaScript.\n *\n *\n * @param {function()} fn Function to call. This function can contain aliases\n * to namespaces (e.g. \"var dom = goog.dom\") or classes\n * (e.g. \"var Timer = goog.Timer\").\n * @deprecated Use goog.module instead.\n */\ngoog.scope = function(fn) {\n if (goog.isInModuleLoader_()) {\n throw new Error('goog.scope is not supported within a module.');\n }\n fn.call(goog.global);\n};\n\n\n/*\n * To support uncompiled, strict mode bundles that use eval to divide source\n * like so:\n * eval('someSource;//# sourceUrl sourcefile.js');\n * We need to export the globally defined symbols \"goog\" and \"COMPILED\".\n * Exporting \"goog\" breaks the compiler optimizations, so we required that\n * be defined externally.\n * NOTE: We don't use goog.exportSymbol here because we don't want to trigger\n * extern generation when that compiler option is enabled.\n */\nif (!COMPILED) {\n goog.global['COMPILED'] = COMPILED;\n}\n\n\n//==============================================================================\n// goog.defineClass implementation\n//==============================================================================\n\n\n/**\n * Creates a restricted form of a Closure \"class\":\n * - from the compiler's perspective, the instance returned from the\n * constructor is sealed (no new properties may be added). This enables\n * better checks.\n * - the compiler will rewrite this definition to a form that is optimal\n * for type checking and optimization (initially this will be a more\n * traditional form).\n *\n * @param {Function} superClass The superclass, Object or null.\n * @param {goog.defineClass.ClassDescriptor} def\n * An object literal describing\n * the class. It may have the following properties:\n * \"constructor\": the constructor function\n * \"statics\": an object literal containing methods to add to the constructor\n * as \"static\" methods or a function that will receive the constructor\n * function as its only parameter to which static properties can\n * be added.\n * all other properties are added to the prototype.\n * @return {!Function} The class constructor.\n * @deprecated Use ECMAScript class syntax instead.\n */\ngoog.defineClass = function(superClass, def) {\n // TODO(johnlenz): consider making the superClass an optional parameter.\n var constructor = def.constructor;\n var statics = def.statics;\n // Wrap the constructor prior to setting up the prototype and static methods.\n if (!constructor || constructor == Object.prototype.constructor) {\n constructor = function() {\n throw new Error(\n 'cannot instantiate an interface (no constructor defined).');\n };\n }\n\n var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);\n if (superClass) {\n goog.inherits(cls, superClass);\n }\n\n // Remove all the properties that should not be copied to the prototype.\n delete def.constructor;\n delete def.statics;\n\n goog.defineClass.applyProperties_(cls.prototype, def);\n if (statics != null) {\n if (statics instanceof Function) {\n statics(cls);\n } else {\n goog.defineClass.applyProperties_(cls, statics);\n }\n }\n\n return cls;\n};\n\n\n/**\n * @typedef {{\n * constructor: (!Function|undefined),\n * statics: (Object|undefined|function(Function):void)\n * }}\n */\ngoog.defineClass.ClassDescriptor;\n\n\n/**\n * @define {boolean} Whether the instances returned by goog.defineClass should\n * be sealed when possible.\n *\n * When sealing is disabled the constructor function will not be wrapped by\n * goog.defineClass, making it incompatible with ES6 class methods.\n */\ngoog.defineClass.SEAL_CLASS_INSTANCES =\n goog.define('goog.defineClass.SEAL_CLASS_INSTANCES', goog.DEBUG);\n\n\n/**\n * If goog.defineClass.SEAL_CLASS_INSTANCES is enabled and Object.seal is\n * defined, this function will wrap the constructor in a function that seals the\n * results of the provided constructor function.\n *\n * @param {!Function} ctr The constructor whose results maybe be sealed.\n * @param {Function} superClass The superclass constructor.\n * @return {!Function} The replacement constructor.\n * @private\n */\ngoog.defineClass.createSealingConstructor_ = function(ctr, superClass) {\n if (!goog.defineClass.SEAL_CLASS_INSTANCES) {\n // Do now wrap the constructor when sealing is disabled. Angular code\n // depends on this for injection to work properly.\n return ctr;\n }\n\n // NOTE: The sealing behavior has been removed\n\n /**\n * @this {Object}\n * @return {?}\n */\n var wrappedCtr = function() {\n // Don't seal an instance of a subclass when it calls the constructor of\n // its super class as there is most likely still setup to do.\n var instance = ctr.apply(this, arguments) || this;\n instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];\n\n return instance;\n };\n\n return wrappedCtr;\n};\n\n\n\n// TODO(johnlenz): share these values with the goog.object\n/**\n * The names of the fields that are defined on Object.prototype.\n * @type {!Array}\n * @private\n * @const\n */\ngoog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = [\n 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',\n 'toLocaleString', 'toString', 'valueOf'\n];\n\n\n// TODO(johnlenz): share this function with the goog.object\n/**\n * @param {!Object} target The object to add properties to.\n * @param {!Object} source The object to copy properties from.\n * @private\n */\ngoog.defineClass.applyProperties_ = function(target, source) {\n // TODO(johnlenz): update this to support ES5 getters/setters\n\n var key;\n for (key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n\n // For IE the for-in-loop does not contain any properties that are not\n // enumerable on the prototype object (for example isPrototypeOf from\n // Object.prototype) and it will also not include 'replace' on objects that\n // extend String and change 'replace' (not that it is common for anyone to\n // extend anything except Object).\n for (var i = 0; i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length; i++) {\n key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n};\n\n/**\n * Returns the parameter.\n * @param {string} s\n * @return {string}\n * @private\n */\ngoog.identity_ = function(s) {\n return s;\n};\n\n\n/**\n * Creates Trusted Types policy if Trusted Types are supported by the browser.\n * The policy just blesses any string as a Trusted Type. It is not visibility\n * restricted because anyone can also call trustedTypes.createPolicy directly.\n * However, the allowed names should be restricted by a HTTP header and the\n * reference to the created policy should be visibility restricted.\n * @param {string} name\n * @return {?TrustedTypePolicy}\n */\ngoog.createTrustedTypesPolicy = function(name) {\n var policy = null;\n var policyFactory = goog.global.trustedTypes;\n if (!policyFactory || !policyFactory.createPolicy) {\n return policy;\n }\n // trustedTypes.createPolicy throws if called with a name that is already\n // registered, even in report-only mode. Until the API changes, catch the\n // error not to break the applications functionally. In such case, the code\n // will fall back to using regular Safe Types.\n // TODO(koto): Remove catching once createPolicy API stops throwing.\n try {\n policy = policyFactory.createPolicy(name, {\n createHTML: goog.identity_,\n createScript: goog.identity_,\n createScriptURL: goog.identity_\n });\n } catch (e) {\n goog.logToConsole_(e.message);\n }\n return policy;\n};\n\n// There's a bug in the compiler where without collapse properties the\n// Closure namespace defines do not guard code correctly. To help reduce code\n// size also check for !COMPILED even though it redundant until this is fixed.\nif (!COMPILED && goog.DEPENDENCIES_ENABLED) {\n\n\n /**\n * Tries to detect whether the current browser is Edge, based on the user\n * agent. This matches only pre-Chromium Edge.\n * @see https://docs.microsoft.com/en-us/microsoft-edge/web-platform/user-agent-string\n * @return {boolean} True if the current browser is Edge.\n * @private\n */\n goog.isEdge_ = function() {\n var userAgent = goog.global.navigator && goog.global.navigator.userAgent ?\n goog.global.navigator.userAgent :\n '';\n var edgeRe = /Edge\\/(\\d+)(\\.\\d)*/i;\n return !!userAgent.match(edgeRe);\n };\n\n\n /**\n * Tries to detect whether is in the context of an HTML document.\n * @return {boolean} True if it looks like HTML document.\n * @private\n */\n goog.inHtmlDocument_ = function() {\n /** @type {!Document} */\n var doc = goog.global.document;\n return doc != null && 'write' in doc; // XULDocument misses write.\n };\n\n\n /**\n * We'd like to check for if the document readyState is 'loading'; however\n * there are bugs on IE 10 and below where the readyState being anything other\n * than 'complete' is not reliable.\n * @return {boolean}\n * @private\n */\n goog.isDocumentLoading_ = function() {\n // attachEvent is available on IE 6 thru 10 only, and thus can be used to\n // detect those browsers.\n /** @type {!HTMLDocument} */\n var doc = goog.global.document;\n return doc.attachEvent ? doc.readyState != 'complete' :\n doc.readyState == 'loading';\n };\n\n\n /**\n * Tries to detect the base path of base.js script that bootstraps Closure.\n * @private\n */\n goog.findBasePath_ = function() {\n if (goog.global.CLOSURE_BASE_PATH != undefined &&\n // Anti DOM-clobbering runtime check (b/37736576).\n typeof goog.global.CLOSURE_BASE_PATH === 'string') {\n goog.basePath = goog.global.CLOSURE_BASE_PATH;\n return;\n } else if (!goog.inHtmlDocument_()) {\n return;\n }\n /** @type {!Document} */\n var doc = goog.global.document;\n // If we have a currentScript available, use it exclusively.\n var currentScript = doc.currentScript;\n if (currentScript) {\n var scripts = [currentScript];\n } else {\n var scripts = doc.getElementsByTagName('SCRIPT');\n }\n // Search backwards since the current script is in almost all cases the one\n // that has base.js.\n for (var i = scripts.length - 1; i >= 0; --i) {\n var script = /** @type {!HTMLScriptElement} */ (scripts[i]);\n var src = script.src;\n var qmark = src.lastIndexOf('?');\n var l = qmark == -1 ? src.length : qmark;\n if (src.slice(l - 7, l) == 'base.js') {\n goog.basePath = src.slice(0, l - 7);\n return;\n }\n }\n };\n\n goog.findBasePath_();\n\n /**\n * Rewrites closing script tags in input to avoid ending an enclosing script\n * tag.\n *\n * @param {string} str\n * @return {string}\n * @private\n */\n goog.protectScriptTag_ = function(str) {\n return str.replace(/<\\/(SCRIPT)/ig, '\\\\x3c/$1');\n };\n\n\n /**\n * A debug loader is responsible for downloading and executing javascript\n * files in an unbundled, uncompiled environment.\n *\n * This can be custimized via the setDependencyFactory method, or by\n * CLOSURE_IMPORT_SCRIPT/CLOSURE_LOAD_FILE_SYNC.\n *\n * @struct @constructor @final @private\n */\n goog.DebugLoader_ = function() {\n /** @private @const {!Object} */\n this.dependencies_ = {};\n /** @private @const {!Object} */\n this.idToPath_ = {};\n /** @private @const {!Object} */\n this.written_ = {};\n /** @private @const {!Array} */\n this.loadingDeps_ = [];\n /** @private {!Array} */\n this.depsToLoad_ = [];\n /** @private {boolean} */\n this.paused_ = false;\n /** @private {!goog.DependencyFactory} */\n this.factory_ = new goog.DependencyFactory();\n /** @private @const {!Object} */\n this.deferredCallbacks_ = {};\n /** @private @const {!Array} */\n this.deferredQueue_ = [];\n };\n\n /**\n * @param {!Array} namespaces\n * @param {function(): undefined} callback Function to call once all the\n * namespaces have loaded.\n */\n goog.DebugLoader_.prototype.bootstrap = function(namespaces, callback) {\n var cb = callback;\n function resolve() {\n if (cb) {\n goog.global.setTimeout(cb, 0);\n cb = null;\n }\n }\n\n if (!namespaces.length) {\n resolve();\n return;\n }\n\n var deps = [];\n for (var i = 0; i < namespaces.length; i++) {\n var path = this.getPathFromDeps_(namespaces[i]);\n if (!path) {\n throw new Error('Unregonized namespace: ' + namespaces[i]);\n }\n deps.push(this.dependencies_[path]);\n }\n\n var require = goog.require;\n var loaded = 0;\n for (var i = 0; i < namespaces.length; i++) {\n require(namespaces[i]);\n deps[i].onLoad(function() {\n if (++loaded == namespaces.length) {\n resolve();\n }\n });\n }\n };\n\n\n /**\n * Loads the Closure Dependency file.\n *\n * Exposed a public function so CLOSURE_NO_DEPS can be set to false, base\n * loaded, setDependencyFactory called, and then this called. i.e. allows\n * custom loading of the deps file.\n */\n goog.DebugLoader_.prototype.loadClosureDeps = function() {\n // Circumvent addDependency, which would try to transpile deps.js if\n // transpile is set to always.\n var relPath = 'deps.js';\n this.depsToLoad_.push(this.factory_.createDependency(\n goog.normalizePath_(goog.basePath + relPath), relPath, [], [], {}));\n this.loadDeps_();\n };\n\n\n /**\n * Notifies the debug loader when a dependency has been requested.\n *\n * @param {string} absPathOrId Path of the dependency or goog id.\n * @param {boolean=} opt_force\n */\n goog.DebugLoader_.prototype.requested = function(absPathOrId, opt_force) {\n var path = this.getPathFromDeps_(absPathOrId);\n if (path &&\n (opt_force || this.areDepsLoaded_(this.dependencies_[path].requires))) {\n var callback = this.deferredCallbacks_[path];\n if (callback) {\n delete this.deferredCallbacks_[path];\n callback();\n }\n }\n };\n\n\n /**\n * Sets the dependency factory, which can be used to create custom\n * goog.Dependency implementations to control how dependencies are loaded.\n *\n * @param {!goog.DependencyFactory} factory\n */\n goog.DebugLoader_.prototype.setDependencyFactory = function(factory) {\n this.factory_ = factory;\n };\n\n\n /**\n * Travserses the dependency graph and queues the given dependency, and all of\n * its transitive dependencies, for loading and then starts loading if not\n * paused.\n *\n * @param {string} namespace\n * @private\n */\n goog.DebugLoader_.prototype.load_ = function(namespace) {\n if (!this.getPathFromDeps_(namespace)) {\n var errorMessage = 'goog.require could not find: ' + namespace;\n goog.logToConsole_(errorMessage);\n } else {\n var loader = this;\n\n var deps = [];\n\n /** @param {string} namespace */\n var visit = function(namespace) {\n var path = loader.getPathFromDeps_(namespace);\n\n if (!path) {\n throw new Error('Bad dependency path or symbol: ' + namespace);\n }\n\n if (loader.written_[path]) {\n return;\n }\n\n loader.written_[path] = true;\n\n var dep = loader.dependencies_[path];\n for (var i = 0; i < dep.requires.length; i++) {\n if (!goog.isProvided_(dep.requires[i])) {\n visit(dep.requires[i]);\n }\n }\n\n deps.push(dep);\n };\n\n visit(namespace);\n\n var wasLoading = !!this.depsToLoad_.length;\n this.depsToLoad_ = this.depsToLoad_.concat(deps);\n\n if (!this.paused_ && !wasLoading) {\n this.loadDeps_();\n }\n }\n };\n\n\n /**\n * Loads any queued dependencies until they are all loaded or paused.\n *\n * @private\n */\n goog.DebugLoader_.prototype.loadDeps_ = function() {\n var loader = this;\n var paused = this.paused_;\n\n while (this.depsToLoad_.length && !paused) {\n (function() {\n var loadCallDone = false;\n var dep = loader.depsToLoad_.shift();\n\n var loaded = false;\n loader.loading_(dep);\n\n var controller = {\n pause: function() {\n if (loadCallDone) {\n throw new Error('Cannot call pause after the call to load.');\n } else {\n paused = true;\n }\n },\n resume: function() {\n if (loadCallDone) {\n loader.resume_();\n } else {\n // Some dep called pause and then resume in the same load call.\n // Just keep running this same loop.\n paused = false;\n }\n },\n loaded: function() {\n if (loaded) {\n throw new Error('Double call to loaded.');\n }\n\n loaded = true;\n loader.loaded_(dep);\n },\n pending: function() {\n // Defensive copy.\n var pending = [];\n for (var i = 0; i < loader.loadingDeps_.length; i++) {\n pending.push(loader.loadingDeps_[i]);\n }\n return pending;\n },\n /**\n * @param {goog.ModuleType} type\n */\n setModuleState: function(type) {\n goog.moduleLoaderState_ = {\n type: type,\n moduleName: '',\n declareLegacyNamespace: false\n };\n },\n /** @type {function(string, string, string=)} */\n registerEs6ModuleExports: function(\n path, exports, opt_closureNamespace) {\n if (opt_closureNamespace) {\n goog.loadedModules_[opt_closureNamespace] = {\n exports: exports,\n type: goog.ModuleType.ES6,\n moduleId: opt_closureNamespace || ''\n };\n }\n },\n /** @type {function(string, ?)} */\n registerGoogModuleExports: function(moduleId, exports) {\n goog.loadedModules_[moduleId] = {\n exports: exports,\n type: goog.ModuleType.GOOG,\n moduleId: moduleId\n };\n },\n clearModuleState: function() {\n goog.moduleLoaderState_ = null;\n },\n defer: function(callback) {\n if (loadCallDone) {\n throw new Error(\n 'Cannot register with defer after the call to load.');\n }\n loader.defer_(dep, callback);\n },\n areDepsLoaded: function() {\n return loader.areDepsLoaded_(dep.requires);\n }\n };\n\n try {\n dep.load(controller);\n } finally {\n loadCallDone = true;\n }\n })();\n }\n\n if (paused) {\n this.pause_();\n }\n };\n\n\n /** @private */\n goog.DebugLoader_.prototype.pause_ = function() {\n this.paused_ = true;\n };\n\n\n /** @private */\n goog.DebugLoader_.prototype.resume_ = function() {\n if (this.paused_) {\n this.paused_ = false;\n this.loadDeps_();\n }\n };\n\n\n /**\n * Marks the given dependency as loading (load has been called but it has not\n * yet marked itself as finished). Useful for dependencies that want to know\n * what else is loading. Example: goog.modules cannot eval if there are\n * loading dependencies.\n *\n * @param {!goog.Dependency} dep\n * @private\n */\n goog.DebugLoader_.prototype.loading_ = function(dep) {\n this.loadingDeps_.push(dep);\n };\n\n\n /**\n * Marks the given dependency as having finished loading and being available\n * for require.\n *\n * @param {!goog.Dependency} dep\n * @private\n */\n goog.DebugLoader_.prototype.loaded_ = function(dep) {\n for (var i = 0; i < this.loadingDeps_.length; i++) {\n if (this.loadingDeps_[i] == dep) {\n this.loadingDeps_.splice(i, 1);\n break;\n }\n }\n\n for (var i = 0; i < this.deferredQueue_.length; i++) {\n if (this.deferredQueue_[i] == dep.path) {\n this.deferredQueue_.splice(i, 1);\n break;\n }\n }\n\n if (this.loadingDeps_.length == this.deferredQueue_.length &&\n !this.depsToLoad_.length) {\n // Something has asked to load these, but they may not be directly\n // required again later, so load them now that we know we're done loading\n // everything else. e.g. a goog module entry point.\n while (this.deferredQueue_.length) {\n this.requested(this.deferredQueue_.shift(), true);\n }\n }\n\n dep.loaded();\n };\n\n\n /**\n * @param {!Array} pathsOrIds\n * @return {boolean}\n * @private\n */\n goog.DebugLoader_.prototype.areDepsLoaded_ = function(pathsOrIds) {\n for (var i = 0; i < pathsOrIds.length; i++) {\n var path = this.getPathFromDeps_(pathsOrIds[i]);\n if (!path ||\n (!(path in this.deferredCallbacks_) &&\n !goog.isProvided_(pathsOrIds[i]))) {\n return false;\n }\n }\n\n return true;\n };\n\n\n /**\n * @param {string} absPathOrId\n * @return {?string}\n * @private\n */\n goog.DebugLoader_.prototype.getPathFromDeps_ = function(absPathOrId) {\n if (absPathOrId in this.idToPath_) {\n return this.idToPath_[absPathOrId];\n } else if (absPathOrId in this.dependencies_) {\n return absPathOrId;\n } else {\n return null;\n }\n };\n\n\n /**\n * @param {!goog.Dependency} dependency\n * @param {!Function} callback\n * @private\n */\n goog.DebugLoader_.prototype.defer_ = function(dependency, callback) {\n this.deferredCallbacks_[dependency.path] = callback;\n this.deferredQueue_.push(dependency.path);\n };\n\n\n /**\n * Interface for goog.Dependency implementations to have some control over\n * loading of dependencies.\n *\n * @record\n */\n goog.LoadController = function() {};\n\n\n /**\n * Tells the controller to halt loading of more dependencies.\n */\n goog.LoadController.prototype.pause = function() {};\n\n\n /**\n * Tells the controller to resume loading of more dependencies if paused.\n */\n goog.LoadController.prototype.resume = function() {};\n\n\n /**\n * Tells the controller that this dependency has finished loading.\n *\n * This causes this to be removed from pending() and any load callbacks to\n * fire.\n */\n goog.LoadController.prototype.loaded = function() {};\n\n\n /**\n * List of dependencies on which load has been called but which have not\n * called loaded on their controller. This includes the current dependency.\n *\n * @return {!Array}\n */\n goog.LoadController.prototype.pending = function() {};\n\n\n /**\n * Registers an object as an ES6 module's exports so that goog.modules may\n * require it by path.\n *\n * @param {string} path Full path of the module.\n * @param {?} exports\n * @param {string=} opt_closureNamespace Closure namespace to associate with\n * this module.\n */\n goog.LoadController.prototype.registerEs6ModuleExports = function(\n path, exports, opt_closureNamespace) {};\n\n\n /**\n * Sets the current module state.\n *\n * @param {goog.ModuleType} type Type of module.\n */\n goog.LoadController.prototype.setModuleState = function(type) {};\n\n\n /**\n * Clears the current module state.\n */\n goog.LoadController.prototype.clearModuleState = function() {};\n\n\n /**\n * Registers a callback to call once the dependency is actually requested\n * via goog.require + all of the immediate dependencies have been loaded or\n * all other files have been loaded. Allows for lazy loading until\n * require'd without pausing dependency loading, which is needed on old IE.\n *\n * @param {!Function} callback\n */\n goog.LoadController.prototype.defer = function(callback) {};\n\n\n /**\n * @return {boolean}\n */\n goog.LoadController.prototype.areDepsLoaded = function() {};\n\n\n /**\n * Basic super class for all dependencies Closure Library can load.\n *\n * This default implementation is designed to load untranspiled, non-module\n * scripts in a web broswer.\n *\n * For goog.modules see {@see goog.GoogModuleDependency}.\n * For untranspiled ES6 modules {@see goog.Es6ModuleDependency}.\n *\n * @param {string} path Absolute path of this script.\n * @param {string} relativePath Path of this script relative to goog.basePath.\n * @param {!Array} provides goog.provided or goog.module symbols\n * in this file.\n * @param {!Array} requires goog symbols or relative paths to Closure\n * this depends on.\n * @param {!Object} loadFlags\n * @struct @constructor\n */\n goog.Dependency = function(\n path, relativePath, provides, requires, loadFlags) {\n /** @const */\n this.path = path;\n /** @const */\n this.relativePath = relativePath;\n /** @const */\n this.provides = provides;\n /** @const */\n this.requires = requires;\n /** @const */\n this.loadFlags = loadFlags;\n /** @private {boolean} */\n this.loaded_ = false;\n /** @private {!Array} */\n this.loadCallbacks_ = [];\n };\n\n\n /**\n * @return {string} The pathname part of this dependency's path if it is a\n * URI.\n */\n goog.Dependency.prototype.getPathName = function() {\n var pathName = this.path;\n var protocolIndex = pathName.indexOf('://');\n if (protocolIndex >= 0) {\n pathName = pathName.substring(protocolIndex + 3);\n var slashIndex = pathName.indexOf('/');\n if (slashIndex >= 0) {\n pathName = pathName.substring(slashIndex + 1);\n }\n }\n return pathName;\n };\n\n\n /**\n * @param {function()} callback Callback to fire as soon as this has loaded.\n * @final\n */\n goog.Dependency.prototype.onLoad = function(callback) {\n if (this.loaded_) {\n callback();\n } else {\n this.loadCallbacks_.push(callback);\n }\n };\n\n\n /**\n * Marks this dependency as loaded and fires any callbacks registered with\n * onLoad.\n * @final\n */\n goog.Dependency.prototype.loaded = function() {\n this.loaded_ = true;\n var callbacks = this.loadCallbacks_;\n this.loadCallbacks_ = [];\n for (var i = 0; i < callbacks.length; i++) {\n callbacks[i]();\n }\n };\n\n\n /**\n * Whether or not document.written / appended script tags should be deferred.\n *\n * @private {boolean}\n */\n goog.Dependency.defer_ = false;\n\n\n /**\n * Map of script ready / state change callbacks. Old IE cannot handle putting\n * these properties on goog.global.\n *\n * @private @const {!Object}\n */\n goog.Dependency.callbackMap_ = {};\n\n\n /**\n * @param {function(...?):?} callback\n * @return {string}\n * @private\n */\n goog.Dependency.registerCallback_ = function(callback) {\n var key = Math.random().toString(32);\n goog.Dependency.callbackMap_[key] = callback;\n return key;\n };\n\n\n /**\n * @param {string} key\n * @private\n */\n goog.Dependency.unregisterCallback_ = function(key) {\n delete goog.Dependency.callbackMap_[key];\n };\n\n\n /**\n * @param {string} key\n * @param {...?} var_args\n * @private\n * @suppress {unusedPrivateMembers}\n */\n goog.Dependency.callback_ = function(key, var_args) {\n if (key in goog.Dependency.callbackMap_) {\n var callback = goog.Dependency.callbackMap_[key];\n var args = [];\n for (var i = 1; i < arguments.length; i++) {\n args.push(arguments[i]);\n }\n callback.apply(undefined, args);\n } else {\n var errorMessage = 'Callback key ' + key +\n ' does not exist (was base.js loaded more than once?).';\n throw Error(errorMessage);\n }\n };\n\n\n /**\n * Starts loading this dependency. This dependency can pause loading if it\n * needs to and resume it later via the controller interface.\n *\n * When this is loaded it should call controller.loaded(). Note that this will\n * end up calling the loaded method of this dependency; there is no need to\n * call it explicitly.\n *\n * @param {!goog.LoadController} controller\n */\n goog.Dependency.prototype.load = function(controller) {\n if (goog.global.CLOSURE_IMPORT_SCRIPT) {\n if (goog.global.CLOSURE_IMPORT_SCRIPT(this.path)) {\n controller.loaded();\n } else {\n controller.pause();\n }\n return;\n }\n\n if (!goog.inHtmlDocument_()) {\n goog.logToConsole_(\n 'Cannot use default debug loader outside of HTML documents.');\n if (this.relativePath == 'deps.js') {\n // Some old code is relying on base.js auto loading deps.js failing with\n // no error before later setting CLOSURE_IMPORT_SCRIPT.\n // CLOSURE_IMPORT_SCRIPT should be set *before* base.js is loaded, or\n // CLOSURE_NO_DEPS set to true.\n goog.logToConsole_(\n 'Consider setting CLOSURE_IMPORT_SCRIPT before loading base.js, ' +\n 'or setting CLOSURE_NO_DEPS to true.');\n controller.loaded();\n } else {\n controller.pause();\n }\n return;\n }\n\n /** @type {!HTMLDocument} */\n var doc = goog.global.document;\n\n // If the user tries to require a new symbol after document load,\n // something has gone terribly wrong. Doing a document.write would\n // wipe out the page. This does not apply to the CSP-compliant method\n // of writing script tags.\n if (doc.readyState == 'complete' &&\n !goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING) {\n // Certain test frameworks load base.js multiple times, which tries\n // to write deps.js each time. If that happens, just fail silently.\n // These frameworks wipe the page between each load of base.js, so this\n // is OK.\n var isDeps = /\\bdeps.js$/.test(this.path);\n if (isDeps) {\n controller.loaded();\n return;\n } else {\n throw Error('Cannot write \"' + this.path + '\" after document load');\n }\n }\n\n var nonce = goog.getScriptNonce_();\n if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&\n goog.isDocumentLoading_()) {\n var key;\n var callback = function(script) {\n if (script.readyState && script.readyState != 'complete') {\n script.onload = callback;\n return;\n }\n goog.Dependency.unregisterCallback_(key);\n controller.loaded();\n };\n key = goog.Dependency.registerCallback_(callback);\n\n var defer = goog.Dependency.defer_ ? ' defer' : '';\n var nonceAttr = nonce ? ' nonce=\"' + nonce + '\"' : '';\n var script = 'world';\n\n\n\n/** @unrestricted */\nclass test {\n constructor() {}\n}\n\n// Verify that when this module loads the script tag is not modified by\n// escaping code in base.js.\ntest.CLOSING_SCRIPT_TAG = '';\n\nexports = test;\n","^<",1684857788697,"^=",["^3",["~$goog.test-module-dep","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^FP"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.test_module","^U",true,"^V",[],"^M",["goog.test_module_dep"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/test_module.js"],"^[",["^3",["~$goog.test_module","^FO"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^FP"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^3Q","^3R","~$goog.iter.Iterable"]],"^5","goog.iter.iter.js","^6",["^7","goog/iter/iter.js"],"^8","goog/iter/iter.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Python style iteration utilities.\n */\n\n\ngoog.provide('goog.iter');\ngoog.provide('goog.iter.Iterable');\ngoog.provide('goog.iter.Iterator');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.debug');\ngoog.require('goog.functions');\ngoog.require('goog.math');\n\n\n/**\n * @typedef {{length:number}|{__iterator__}}\n */\ngoog.iter.Iterable;\n\n\n/**\n * Class/interface for iterators.\n * @constructor\n * @template VALUE\n * @implements {Iterator}\n * @deprecated Use objects implementing JavaScript iterable protocol introduced\n * in ES6.\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols\n */\ngoog.iter.Iterator = function() {};\n\n\n/**\n * Returns the next value of the iteration as an an ES6 IIterableResult.\n * @return {!IIterableResult}\n * @override\n */\ngoog.iter.Iterator.prototype.next = function() {\n 'use strict';\n return goog.iter.ES6_ITERATOR_DONE;\n};\n\n\n/**\n * An ES6 Iteration protocol result indicating iteration has completed for an\n * iterator.\n * @const {!IIterableResult}\n */\ngoog.iter.ES6_ITERATOR_DONE = goog.debug.freeze({done: true, value: undefined});\n\n\n/**\n * Wraps a VALUE in the ES6 Iterator protocol's IIterableResult container,\n * including the compiler-mandated 'done' key, set to false.\n * @param {VALUE} value\n * @return {!IIterableResult} An ES6 Iteration Protocol compatible result\n * object, indicating iteration is not done.\n * @template VALUE\n */\ngoog.iter.createEs6IteratorYield = function(value) {\n return {value, done: false};\n};\n\n\n/**\n * Returns the `Iterator` object itself. This is used to implement\n * the iterator protocol in JavaScript 1.7\n * @param {boolean=} opt_keys Whether to return the keys or values. Default is\n * to only return the values. This is being used by the for-in loop (true)\n * and the for-each-in loop (false). Even though the param gives a hint\n * about what the iterator will return there is no guarantee that it will\n * return the keys when true is passed.\n * @return {!goog.iter.Iterator} The object itself.\n */\ngoog.iter.Iterator.prototype.__iterator__ = function(opt_keys) {\n 'use strict';\n return this;\n};\n\n\n/**\n * Returns an iterator that knows how to iterate over the values in the object.\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable If the\n * object is an iterator it will be returned as is. If the object has an\n * `__iterator__` method that will be called to get the value\n * iterator. If the object is an array-like object we create an iterator\n * for that.\n * @return {!goog.iter.Iterator} An iterator that knows how to iterate\n * over the values in `iterable`.\n * @template VALUE\n */\ngoog.iter.toIterator = function(iterable) {\n 'use strict';\n if (iterable instanceof goog.iter.Iterator) {\n return iterable;\n }\n if (typeof iterable.__iterator__ == 'function') {\n return /** @type {{__iterator__:function(this:?, boolean=)}} */ (iterable)\n .__iterator__(false);\n }\n if (goog.isArrayLike(iterable)) {\n const like = /** @type {!IArrayLike} */ (iterable);\n let i = 0;\n const newIter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n /**\n * @return {!IIterableResult}\n * @override\n */\n newIter.next = function() {\n 'use strict';\n while (true) {\n if (i >= like.length) {\n return goog.iter.ES6_ITERATOR_DONE;\n }\n // Don't include deleted elements.\n if (!(i in like)) {\n i++;\n continue;\n }\n return goog.iter.createEs6IteratorYield(like[i++]);\n }\n };\n\n return newIter;\n }\n\n\n // TODO(arv): Should we fall back on goog.structs.getValues()?\n throw new Error('Not implemented');\n};\n\n\n/**\n * Calls a function for each element in the iterator with the element of the\n * iterator passed as argument.\n *\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * to iterate over. If the iterable is an object `toIterator` will be\n * called on it.\n * @param {function(this:THIS,VALUE,?,!goog.iter.Iterator)} f\n * The function to call for every element. This function takes 3 arguments\n * (the element, undefined, and the iterator) and the return value is\n * irrelevant. The reason for passing undefined as the second argument is\n * so that the same function can be used in {@see goog.array.forEach} as\n * well as others. The third parameter is of type \"number\" for\n * arraylike objects, undefined, otherwise.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * `f`.\n * @template THIS, VALUE\n */\ngoog.iter.forEach = function(iterable, f, opt_obj) {\n 'use strict';\n if (goog.isArrayLike(iterable)) {\n // NOTES: this passes the index number to the second parameter\n // of the callback contrary to the documentation above.\n goog.array.forEach(\n /** @type {IArrayLike} */ (iterable), f, opt_obj);\n } else {\n const iterator = goog.iter.toIterator(iterable);\n while (true) {\n const {done, value} = iterator.next();\n if (done) return;\n f.call(opt_obj, value, undefined, iterator);\n }\n }\n};\n\n\n/**\n * Calls a function for every element in the iterator, and if the function\n * returns true adds the element to a new iterator.\n *\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * to iterate over.\n * @param {\n * function(this:THIS,VALUE,undefined,!goog.iter.Iterator):boolean} f\n * The function to call for every element. This function takes 3 arguments\n * (the element, undefined, and the iterator) and should return a boolean.\n * If the return value is true the element will be included in the returned\n * iterator. If it is false the element is not included.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * `f`.\n * @return {!goog.iter.Iterator} A new iterator in which only elements\n * that passed the test are present.\n * @template THIS, VALUE\n */\ngoog.iter.filter = function(iterable, f, opt_obj) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n const newIter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n /**\n * @return {!IIterableResult}\n * @override\n */\n newIter.next = function() {\n 'use strict';\n while (true) {\n const {done, value} = iterator.next();\n if (done) return goog.iter.ES6_ITERATOR_DONE;\n if (f.call(opt_obj, value, undefined, iterator)) {\n return goog.iter.createEs6IteratorYield(value);\n }\n }\n };\n\n return newIter;\n};\n\n\n/**\n * Calls a function for every element in the iterator, and if the function\n * returns false adds the element to a new iterator.\n *\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * to iterate over.\n * @param {\n * function(this:THIS,VALUE,undefined,!goog.iter.Iterator):boolean} f\n * The function to call for every element. This function takes 3 arguments\n * (the element, undefined, and the iterator) and should return a boolean.\n * If the return value is false the element will be included in the returned\n * iterator. If it is true the element is not included.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * `f`.\n * @return {!goog.iter.Iterator} A new iterator in which only elements\n * that did not pass the test are present.\n * @template THIS, VALUE\n */\ngoog.iter.filterFalse = function(iterable, f, opt_obj) {\n 'use strict';\n return goog.iter.filter(iterable, goog.functions.not(f), opt_obj);\n};\n\n\n/**\n * Creates a new iterator that returns the values in a range. This function\n * can take 1, 2 or 3 arguments:\n *
\n * range(5) same as range(0, 5, 1)\n * range(2, 5) same as range(2, 5, 1)\n * 
\n *\n * @param {number} startOrStop The stop value if only one argument is provided.\n * The start value if 2 or more arguments are provided. If only one\n * argument is used the start value is 0.\n * @param {number=} opt_stop The stop value. If left out then the first\n * argument is used as the stop value.\n * @param {number=} opt_step The number to increment with between each call to\n * next. This can be negative.\n * @return {!goog.iter.Iterator} A new iterator that returns the values\n * in the range.\n */\ngoog.iter.range = function(startOrStop, opt_stop, opt_step) {\n 'use strict';\n let start = 0;\n let stop = startOrStop;\n let step = opt_step || 1;\n if (arguments.length > 1) {\n start = startOrStop;\n stop = +opt_stop;\n }\n if (step == 0) {\n throw new Error('Range step argument must not be zero');\n }\n\n const newIter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n /**\n * @return {!IIterableResult}\n * @override\n */\n newIter.next = function() {\n 'use strict';\n if (step > 0 && start >= stop || step < 0 && start <= stop) {\n return goog.iter.ES6_ITERATOR_DONE;\n }\n const rv = start;\n start += step;\n return goog.iter.createEs6IteratorYield(rv);\n };\n\n return newIter;\n};\n\n\n/**\n * Joins the values in a iterator with a delimiter.\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * to get the values from.\n * @param {string} deliminator The text to put between the values.\n * @return {string} The joined value string.\n * @template VALUE\n */\ngoog.iter.join = function(iterable, deliminator) {\n 'use strict';\n return goog.iter.toArray(iterable).join(deliminator);\n};\n\n\n/**\n * For every element in the iterator call a function and return a new iterator\n * with that value.\n *\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterator to iterate over.\n * @param {\n * function(this:THIS,VALUE,undefined,!goog.iter.Iterator):RESULT} f\n * The function to call for every element. This function takes 3 arguments\n * (the element, undefined, and the iterator) and should return a new value.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * `f`.\n * @return {!goog.iter.Iterator} A new iterator that returns the\n * results of applying the function to each element in the original\n * iterator.\n * @template THIS, VALUE, RESULT\n */\ngoog.iter.map = function(iterable, f, opt_obj) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n const newIter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n /**\n * @return {!IIterableResult}\n * @override\n */\n newIter.next = function() {\n 'use strict';\n const {done, value} = iterator.next();\n if (done) return goog.iter.ES6_ITERATOR_DONE;\n const mappedVal = f.call(opt_obj, value, undefined, iterator);\n return goog.iter.createEs6IteratorYield(mappedVal);\n };\n\n return newIter;\n};\n\n\n/**\n * Passes every element of an iterator into a function and accumulates the\n * result.\n *\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterator to iterate over.\n * @param {function(this:THIS,RVALUE,VALUE):RVALUE} f The function to call for\n * every element. This function takes 2 arguments (the function's previous\n * result or the initial value, and the value of the current element).\n * function(previousValue, currentElement) : newValue.\n * @param {RVALUE} val The initial value to pass into the function on the first\n * call.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * f.\n * @return {RVALUE} Result of evaluating f repeatedly across the values of\n * the iterator.\n * @template THIS, VALUE, RVALUE\n */\ngoog.iter.reduce = function(iterable, f, val, opt_obj) {\n 'use strict';\n let rval = val;\n goog.iter.forEach(iterable, function(val) {\n 'use strict';\n rval = f.call(opt_obj, rval, val);\n });\n return rval;\n};\n\n\n/**\n * Goes through the values in the iterator. Calls f for each of these, and if\n * any of them returns true, this returns true (without checking the rest). If\n * all return false this will return false.\n *\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * object.\n * @param {\n * function(this:THIS,VALUE,undefined,!goog.iter.Iterator):boolean} f\n * The function to call for every value. This function takes 3 arguments\n * (the value, undefined, and the iterator) and should return a boolean.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * `f`.\n * @return {boolean} true if any value passes the test.\n * @template THIS, VALUE\n */\ngoog.iter.some = function(iterable, f, opt_obj) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n\n while (true) {\n const {done, value} = iterator.next();\n if (done) return false;\n if (f.call(opt_obj, value, undefined, iterator)) {\n return true;\n }\n }\n};\n\n\n/**\n * Goes through the values in the iterator. Calls f for each of these and if any\n * of them returns false this returns false (without checking the rest). If all\n * return true this will return true.\n *\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * object.\n * @param {\n * function(this:THIS,VALUE,undefined,!goog.iter.Iterator):boolean} f\n * The function to call for every value. This function takes 3 arguments\n * (the value, undefined, and the iterator) and should return a boolean.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * `f`.\n * @return {boolean} true if every value passes the test.\n * @template THIS, VALUE\n */\ngoog.iter.every = function(iterable, f, opt_obj) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n\n while (true) {\n const {done, value} = iterator.next();\n if (done) return true;\n if (!f.call(opt_obj, value, undefined, iterator)) {\n return false;\n }\n }\n};\n\n\n/**\n * Takes zero or more iterables and returns one iterator that will iterate over\n * them in the order chained.\n * @param {...!goog.iter.Iterator|!goog.iter.Iterable} var_args Any\n * number of iterable objects.\n * @return {!goog.iter.Iterator} Returns a new iterator that will\n * iterate over all the given iterables' contents.\n * @template VALUE\n */\ngoog.iter.chain = function(var_args) {\n 'use strict';\n return goog.iter.chainFromIterable(arguments);\n};\n\n\n/**\n * Takes a single iterable containing zero or more iterables and returns one\n * iterator that will iterate over each one in the order given.\n * @see https://goo.gl/5NRp5d\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterable of\n * iterables to chain.\n * @return {!goog.iter.Iterator} Returns a new iterator that will\n * iterate over all the contents of the iterables contained within\n * `iterable`.\n * @template VALUE\n */\ngoog.iter.chainFromIterable = function(iterable) {\n 'use strict';\n const iteratorOfIterators = goog.iter.toIterator(iterable);\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n let current = null;\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n while (true) {\n if (current == null) {\n const it = iteratorOfIterators.next();\n if (it.done) return goog.iter.ES6_ITERATOR_DONE;\n const value = /** @type {!goog.iter.Iterator} */ (it.value);\n current = goog.iter.toIterator(value);\n }\n const it = current.next();\n if (it.done) {\n // If the child iterator is out of values, set current to null which\n // triggers iterating over the parent above.\n current = null;\n continue;\n }\n const value = /** @type {VALUE} */ (it.value);\n return goog.iter.createEs6IteratorYield(value);\n }\n };\n\n return iter;\n};\n\n\n/**\n * Builds a new iterator that iterates over the original, but skips elements as\n * long as a supplied function returns true.\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * object.\n * @param {\n * function(this:THIS,VALUE,undefined,!goog.iter.Iterator):boolean} f\n * The function to call for every value. This function takes 3 arguments\n * (the value, undefined, and the iterator) and should return a boolean.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * `f`.\n * @return {!goog.iter.Iterator} A new iterator that drops elements from\n * the original iterator as long as `f` is true.\n * @template THIS, VALUE\n */\ngoog.iter.dropWhile = function(iterable, f, opt_obj) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n\n const newIter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n let dropping = true;\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n newIter.next = function() {\n 'use strict';\n while (true) {\n const {done, value} = iterator.next();\n if (done) return goog.iter.ES6_ITERATOR_DONE;\n if (dropping && f.call(opt_obj, value, undefined, iterator)) {\n continue;\n } else {\n dropping = false;\n }\n return goog.iter.createEs6IteratorYield(value);\n }\n };\n\n return newIter;\n};\n\n\n/**\n * Builds a new iterator that iterates over the original, but only as long as a\n * supplied function returns true.\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * object.\n * @param {\n * function(this:THIS,VALUE,undefined,!goog.iter.Iterator):boolean} f\n * The function to call for every value. This function takes 3 arguments\n * (the value, undefined, and the iterator) and should return a boolean.\n * @param {THIS=} opt_obj This is used as the 'this' object in f when called.\n * @return {!goog.iter.Iterator} A new iterator that keeps elements in\n * the original iterator as long as the function is true.\n * @template THIS, VALUE\n */\ngoog.iter.takeWhile = function(iterable, f, opt_obj) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n const {done, value} = iterator.next();\n if (done) return goog.iter.ES6_ITERATOR_DONE;\n if (f.call(opt_obj, value, undefined, iterator)) {\n return goog.iter.createEs6IteratorYield(value);\n }\n return goog.iter.ES6_ITERATOR_DONE;\n };\n\n return iter;\n};\n\n\n/**\n * Converts the iterator to an array\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterator\n * to convert to an array.\n * @return {!Array} An array of the elements the iterator iterates over.\n * @template VALUE\n */\ngoog.iter.toArray = function(iterable) {\n 'use strict';\n // Fast path for array-like.\n if (goog.isArrayLike(iterable)) {\n return goog.array.toArray(/** @type {!IArrayLike} */ (iterable));\n }\n iterable = goog.iter.toIterator(iterable);\n const array = [];\n goog.iter.forEach(iterable, function(val) {\n 'use strict';\n array.push(val);\n });\n return array;\n};\n\n\n/**\n * Iterates over two iterables and returns true if they contain the same\n * sequence of elements and have the same length.\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable1 The first\n * iterable object.\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable2 The second\n * iterable object.\n * @param {function(VALUE,VALUE):boolean=} opt_equalsFn Optional comparison\n * function.\n * Should take two 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} true if the iterables contain the same sequence of elements\n * and have the same length.\n * @template VALUE\n */\ngoog.iter.equals = function(iterable1, iterable2, opt_equalsFn) {\n 'use strict';\n const fillValue = {};\n const pairs = goog.iter.zipLongest(fillValue, iterable1, iterable2);\n const equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;\n return goog.iter.every(pairs, function(pair) {\n 'use strict';\n return equalsFn(pair[0], pair[1]);\n });\n};\n\n\n/**\n * Advances the iterator to the next position, returning the given default value\n * instead of throwing an exception if the iterator has no more entries.\n * @param {goog.iter.Iterator|goog.iter.Iterable} iterable The iterable\n * object.\n * @param {VALUE} defaultValue The value to return if the iterator is empty.\n * @return {VALUE} The next item in the iteration, or defaultValue if the\n * iterator was empty.\n * @template VALUE\n */\ngoog.iter.nextOrValue = function(iterable, defaultValue) {\n 'use strict';\n const iterator = /** @type {!goog.iter.Iterator} */ (\n goog.iter.toIterator(iterable));\n const {done, value} = iterator.next();\n if (done) return defaultValue;\n return value;\n};\n\n\n/**\n * Cartesian product of zero or more sets. Gives an iterator that gives every\n * combination of one element chosen from each set. For example,\n * ([1, 2], [3, 4]) gives ([1, 3], [1, 4], [2, 3], [2, 4]).\n * @see http://docs.python.org/library/itertools.html#itertools.product\n * @param {...!IArrayLike} var_args Zero or more sets, as\n * arrays.\n * @return {!goog.iter.Iterator>} An iterator that gives each\n * n-tuple (as an array).\n * @template VALUE\n */\ngoog.iter.product = function(var_args) {\n 'use strict';\n const someArrayEmpty = Array.prototype.some.call(arguments, function(arr) {\n 'use strict';\n return !arr.length;\n });\n\n // An empty set in a cartesian product gives an empty set.\n if (someArrayEmpty || !arguments.length) {\n return /** @type {!goog.iter.Iterator>} */ (\n new goog.iter.Iterator());\n }\n\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n const arrays = arguments;\n\n // The first indices are [0, 0, ...]\n /** @type {?Array} */\n let indices = goog.array.repeat(0, arrays.length);\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n if (indices) {\n const retVal = goog.array.map(indices, function(valueIndex, arrayIndex) {\n 'use strict';\n return arrays[arrayIndex][valueIndex];\n });\n\n // Generate the next-largest indices for the next call.\n // Increase the rightmost index. If it goes over, increase the next\n // rightmost (like carry-over addition).\n for (let i = indices.length - 1; i >= 0; i--) {\n // Assertion prevents compiler warning below.\n goog.asserts.assert(indices);\n if (indices[i] < arrays[i].length - 1) {\n indices[i]++;\n break;\n }\n\n // We're at the last indices (the last element of every array), so\n // the iteration is over on the next call.\n if (i == 0) {\n indices = null;\n break;\n }\n // Reset the index in this column and loop back to increment the\n // next one.\n indices[i] = 0;\n }\n return goog.iter.createEs6IteratorYield(retVal);\n }\n\n return goog.iter.ES6_ITERATOR_DONE;\n };\n\n\n return iter;\n};\n\n\n/**\n * Create an iterator to cycle over the iterable's elements indefinitely.\n * For example, ([1, 2, 3]) would return : 1, 2, 3, 1, 2, 3, ...\n * @see: http://docs.python.org/library/itertools.html#itertools.cycle.\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable object.\n * @return {!goog.iter.Iterator} An iterator that iterates indefinitely\n * over the values in `iterable`.\n * @template VALUE\n */\ngoog.iter.cycle = function(iterable) {\n 'use strict';\n const baseIterator = /** @type {!goog.iter.Iterator} */ (\n goog.iter.toIterator(iterable));\n\n // We maintain a cache to store the iterable elements as we iterate\n // over them. The cache is used to return elements once we have\n // iterated over the iterable once.\n const cache = [];\n let cacheIndex = 0;\n\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n // This flag is set after the iterable is iterated over once\n let useCache = false;\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n let returnElement = null;\n\n // Pull elements off the original iterator if not using cache\n if (!useCache) {\n const it = baseIterator.next();\n if (it.done) {\n if (goog.array.isEmpty(cache)) {\n return goog.iter.ES6_ITERATOR_DONE;\n }\n // set useCache to true after we've exhausted the inner iterator and\n // there is at least one element in the cache.\n useCache = true;\n // Fallthrough to using the cache immediately.\n } else {\n cache.push(it.value);\n return it;\n }\n }\n\n returnElement = cache[cacheIndex];\n cacheIndex = (cacheIndex + 1) % cache.length;\n\n return goog.iter.createEs6IteratorYield(returnElement);\n };\n\n return iter;\n};\n\n\n/**\n * Creates an iterator that counts indefinitely from a starting value.\n * @see http://docs.python.org/2/library/itertools.html#itertools.count\n * @param {number=} opt_start The starting value. Default is 0.\n * @param {number=} opt_step The number to increment with between each call to\n * next. Negative and floating point numbers are allowed. Default is 1.\n * @return {!goog.iter.Iterator} A new iterator that returns the values\n * in the series.\n */\ngoog.iter.count = function(opt_start, opt_step) {\n 'use strict';\n let counter = opt_start || 0;\n const step = (opt_step !== undefined) ? opt_step : 1;\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n /**\n * @return {!IIterableResult}\n * @override @see {!goog.iter.Iterator}\n */\n iter.next = function() {\n 'use strict';\n const returnValue = counter;\n counter += step;\n return goog.iter.createEs6IteratorYield(returnValue);\n };\n\n return iter;\n};\n\n\n/**\n * Creates an iterator that returns the same object or value repeatedly.\n * @param {VALUE} value Any object or value to repeat.\n * @return {!goog.iter.Iterator} A new iterator that returns the\n * repeated value.\n * @template VALUE\n */\ngoog.iter.repeat = function(value) {\n 'use strict';\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n return goog.iter.createEs6IteratorYield(value);\n };\n\n return iter;\n};\n\n\n/**\n * Creates an iterator that returns running totals from the numbers in\n * `iterable`. For example, the array {@code [1, 2, 3, 4, 5]} yields\n * {@code 1 -> 3 -> 6 -> 10 -> 15}.\n * @see http://docs.python.org/3.2/library/itertools.html#itertools.accumulate\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable of numbers to accumulate.\n * @return {!goog.iter.Iterator} A new iterator that returns the\n * numbers in the series.\n */\ngoog.iter.accumulate = function(iterable) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n let total = 0;\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n /**\n * @return {!IIterableResult}\n * @override @see {!goog.iter.Iterator}\n */\n iter.next = function() {\n 'use strict';\n const {done, value} = iterator.next();\n if (done) return goog.iter.ES6_ITERATOR_DONE;\n total += value;\n return goog.iter.createEs6IteratorYield(total);\n };\n\n return iter;\n};\n\n\n/**\n * Creates an iterator that returns arrays containing the ith elements from the\n * provided iterables. The returned arrays will be the same size as the number\n * of iterables given in `var_args`. Once the shortest iterable is\n * exhausted, subsequent calls to `next()` will return\n * `goog.iter.ES6_ITERATOR_DONE`.\n * @see http://docs.python.org/2/library/itertools.html#itertools.izip\n * @param {...!goog.iter.Iterator|!goog.iter.Iterable} var_args Any\n * number of iterable objects.\n * @return {!goog.iter.Iterator>} A new iterator that returns\n * arrays of elements from the provided iterables.\n * @template VALUE\n */\ngoog.iter.zip = function(var_args) {\n 'use strict';\n const args = arguments;\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n if (args.length > 0) {\n const iterators = goog.array.map(args, goog.iter.toIterator);\n let allDone = false;\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n if (allDone) return goog.iter.ES6_ITERATOR_DONE;\n\n const arr = [];\n for (let i = 0, iterator; iterator = iterators[i++];) {\n const it = /** @type {!IIterableResult} */ (iterator.next());\n if (it.done) {\n // One of the iterators being zipped is done, so set allDone and\n // return.\n allDone = true;\n return goog.iter.ES6_ITERATOR_DONE;\n }\n arr.push(it.value);\n }\n return goog.iter.createEs6IteratorYield(arr);\n };\n }\n\n return iter;\n};\n\n\n/**\n * Creates an iterator that returns arrays containing the ith elements from the\n * provided iterables. The returned arrays will be the same size as the number\n * of iterables given in `var_args`. Shorter iterables will be extended\n * with `fillValue`. Once the longest iterable is exhausted, subsequent\n * calls to `next()` will return `goog.iter.ES6_ITERATOR_DONE`.\n * @see http://docs.python.org/2/library/itertools.html#itertools.izip_longest\n * @param {VALUE} fillValue The object or value used to fill shorter iterables.\n * @param {...!goog.iter.Iterator|!goog.iter.Iterable} var_args Any\n * number of iterable objects.\n * @return {!goog.iter.Iterator>} A new iterator that returns\n * arrays of elements from the provided iterables.\n * @template VALUE\n */\ngoog.iter.zipLongest = function(fillValue, var_args) {\n 'use strict';\n const args = Array.prototype.slice.call(arguments, 1);\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n if (args.length > 0) {\n const iterators = goog.array.map(args, goog.iter.toIterator);\n\n let allDone = false; // set to true once all iterators are empty.\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n if (allDone) return goog.iter.ES6_ITERATOR_DONE;\n\n let iteratorsHaveValues = false;\n const arr = [];\n for (let i = 0, iterator; iterator = iterators[i++];) {\n const it = /** @type {!IIterableResult} */ (iterator.next());\n if (it.done) {\n // If this iterator is empty, others might not be, so use the\n // fillValue.\n arr.push(fillValue);\n continue;\n }\n arr.push(it.value);\n iteratorsHaveValues = true;\n }\n\n if (!iteratorsHaveValues) {\n allDone = true;\n return goog.iter.ES6_ITERATOR_DONE;\n }\n return goog.iter.createEs6IteratorYield(arr);\n };\n }\n\n return iter;\n};\n\n\n/**\n * Creates an iterator that filters `iterable` based on a series of\n * `selectors`. On each call to `next()`, one item is taken from\n * both the `iterable` and `selectors` iterators. If the item from\n * `selectors` evaluates to true, the item from `iterable` is given.\n * Otherwise, it is skipped. Once either `iterable` or `selectors`\n * is exhausted, subsequent calls to `next()` will return\n * `goog.iter.ES6_ITERATOR_DONE`.\n * @see http://docs.python.org/2/library/itertools.html#itertools.compress\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to filter.\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} selectors An\n * iterable of items to be evaluated in a boolean context to determine if\n * the corresponding element in `iterable` should be included in the\n * result.\n * @return {!goog.iter.Iterator} A new iterator that returns the\n * filtered values.\n * @template VALUE\n */\ngoog.iter.compress = function(iterable, selectors) {\n 'use strict';\n const valueIterator = goog.iter.toIterator(iterable);\n const selectorIterator = goog.iter.toIterator(selectors);\n\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n let allDone = false;\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n if (allDone) return goog.iter.ES6_ITERATOR_DONE;\n\n while (true) {\n const valIt = valueIterator.next();\n if (valIt.done) {\n allDone = true;\n return goog.iter.ES6_ITERATOR_DONE;\n }\n\n const selectorIt = selectorIterator.next();\n if (selectorIt.done) {\n allDone = true;\n return goog.iter.ES6_ITERATOR_DONE;\n }\n\n const val = valIt.value;\n const selectorVal = selectorIt.value;\n if (selectorVal) return goog.iter.createEs6IteratorYield(val);\n }\n };\n\n return iter;\n};\n\n\n\n/**\n * Implements the `goog.iter.groupBy` iterator.\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to group.\n * @param {function(VALUE): KEY=} opt_keyFunc Optional function for\n * determining the key value for each group in the `iterable`. Default\n * is the identity function.\n * @constructor\n * @extends {goog.iter.Iterator>}\n * @template KEY, VALUE\n * @private\n */\ngoog.iter.GroupByIterator_ = function(iterable, opt_keyFunc) {\n 'use strict';\n /**\n * The iterable to group, coerced to an iterator.\n * @type {!goog.iter.Iterator}\n */\n this.iterator = goog.iter.toIterator(iterable);\n\n /**\n * A function for determining the key value for each element in the iterable.\n * If no function is provided, the identity function is used and returns the\n * element unchanged.\n * @type {function(VALUE): KEY}\n */\n this.keyFunc = opt_keyFunc || goog.functions.identity;\n\n /**\n * The target key for determining the start of a group.\n * @type {KEY}\n */\n this.targetKey;\n\n /**\n * The current key visited during iteration.\n * @type {KEY}\n */\n this.currentKey;\n\n /**\n * The current value being added to the group.\n * @type {VALUE}\n */\n this.currentValue;\n};\ngoog.inherits(goog.iter.GroupByIterator_, goog.iter.Iterator);\n\n\n/**\n * @return {!IIterableResult>}\n * @override\n */\ngoog.iter.GroupByIterator_.prototype.next = function() {\n 'use strict';\n while (this.currentKey == this.targetKey) {\n const it = this.iterator.next();\n if (it.done) return goog.iter.ES6_ITERATOR_DONE;\n this.currentValue = it.value;\n this.currentKey = this.keyFunc(this.currentValue);\n }\n this.targetKey = this.currentKey;\n return goog.iter.createEs6IteratorYield(\n [this.currentKey, this.groupItems_(this.targetKey)]);\n};\n\n\n/**\n * Performs the grouping of objects using the given key.\n * @param {KEY} targetKey The target key object for the group.\n * @return {!Array} An array of grouped objects.\n * @private\n */\ngoog.iter.GroupByIterator_.prototype.groupItems_ = function(targetKey) {\n 'use strict';\n const arr = [];\n while (this.currentKey == targetKey) {\n arr.push(this.currentValue);\n const it = this.iterator.next();\n if (it.done) break;\n this.currentValue = it.value;\n this.currentKey = this.keyFunc(this.currentValue);\n }\n return arr;\n};\n\n\n/**\n * Creates an iterator that returns arrays containing elements from the\n * `iterable` grouped by a key value. For iterables with repeated\n * elements (i.e. sorted according to a particular key function), this function\n * has a `uniq`-like effect. For example, grouping the array:\n * {@code [A, B, B, C, C, A]} produces\n * {@code [A, [A]], [B, [B, B]], [C, [C, C]], [A, [A]]}.\n * @see http://docs.python.org/2/library/itertools.html#itertools.groupby\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to group.\n * @param {function(VALUE): KEY=} opt_keyFunc Optional function for\n * determining the key value for each group in the `iterable`. Default\n * is the identity function.\n * @return {!goog.iter.Iterator>} A new iterator that returns\n * arrays of consecutive key and groups.\n * @template KEY, VALUE\n */\ngoog.iter.groupBy = function(iterable, opt_keyFunc) {\n 'use strict';\n return new goog.iter.GroupByIterator_(iterable, opt_keyFunc);\n};\n\n\n/**\n * Gives an iterator that gives the result of calling the given function\n * f with the arguments taken from the next element from\n * iterable (the elements are expected to also be iterables).\n *\n * Similar to {@see goog.iter.map} but allows the function to accept multiple\n * arguments from the iterable.\n *\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The iterable of\n * iterables to iterate over.\n * @param {function(this:THIS,...*):RESULT} f The function to call for every\n * element. This function takes N+2 arguments, where N represents the\n * number of items from the next element of the iterable. The two\n * additional arguments passed to the function are undefined and the\n * iterator itself. The function should return a new value.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within\n * `f`.\n * @return {!goog.iter.Iterator} A new iterator that returns the\n * results of applying the function to each element in the original\n * iterator.\n * @template THIS, RESULT\n */\ngoog.iter.starMap = function(iterable, f, opt_obj) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n const it = /** @type {!IIterableResult>} */ (\n iterator.next());\n if (it.done) return goog.iter.ES6_ITERATOR_DONE;\n const args = goog.iter.toArray(it.value);\n const value = f.apply(opt_obj, [].concat(args, undefined, iterator));\n return goog.iter.createEs6IteratorYield(value);\n };\n\n\n return iter;\n};\n\n\n/**\n * Returns an array of iterators each of which can iterate over the values in\n * `iterable` without advancing the others.\n * @see http://docs.python.org/2/library/itertools.html#itertools.tee\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to tee.\n * @param {number=} opt_num The number of iterators to create. Default is 2.\n * @return {!Array>} An array of iterators.\n * @template VALUE\n */\ngoog.iter.tee = function(iterable, opt_num) {\n 'use strict';\n const iterator = goog.iter.toIterator(iterable);\n const num = (typeof opt_num === 'number') ? opt_num : 2;\n const buffers = goog.array.map(goog.array.range(num), function() {\n 'use strict';\n return [];\n });\n\n /***\n * @return {boolean} True iff something was added to the buffers, false\n * otherwise. Used to signal whether there were any more iterators, or if\n * the parent iterator should indicate exhaustion.\n */\n function addNextIteratorValueToBuffers() {\n 'use strict';\n const {done, value} = iterator.next();\n if (done) return false;\n for (let i = 0, buffer; buffer = buffers[i++];) {\n buffer.push(value);\n }\n return true;\n }\n\n /***\n * @param {!Array} buffer\n * @return {!goog.iter.Iterator}\n */\n function createIterator(buffer) {\n 'use strict';\n // Each tee'd iterator has an associated buffer (initially empty). When a\n // tee'd iterator's buffer is empty, it calls\n // addNextIteratorValueToBuffers(), adding the next value to all tee'd\n // iterators' buffers, and then returns that value. This allows each\n // iterator to be advanced independently.\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n if (goog.array.isEmpty(buffer)) {\n const added = addNextIteratorValueToBuffers();\n if (!added) return goog.iter.ES6_ITERATOR_DONE;\n }\n goog.asserts.assert(!goog.array.isEmpty(buffer));\n return goog.iter.createEs6IteratorYield(buffer.shift());\n };\n\n return iter;\n }\n\n return goog.array.map(buffers, createIterator);\n};\n\n\n/**\n * Creates an iterator that returns arrays containing a count and an element\n * obtained from the given `iterable`.\n * @see http://docs.python.org/2/library/functions.html#enumerate\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to enumerate.\n * @param {number=} opt_start Optional starting value. Default is 0.\n * @return {!goog.iter.Iterator>} A new iterator containing\n * count/item pairs.\n * @template VALUE\n */\ngoog.iter.enumerate = function(iterable, opt_start) {\n 'use strict';\n return goog.iter.zip(goog.iter.count(opt_start), iterable);\n};\n\n\n/**\n * Creates an iterator that returns the first `limitSize` elements from an\n * iterable. If this number is greater than the number of elements in the\n * iterable, all the elements are returned.\n * @see http://goo.gl/V0sihp Inspired by the limit iterator in Guava.\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to limit.\n * @param {number} limitSize The maximum number of elements to return.\n * @return {!goog.iter.Iterator} A new iterator containing\n * `limitSize` elements.\n * @template VALUE\n */\ngoog.iter.limit = function(iterable, limitSize) {\n 'use strict';\n goog.asserts.assert(goog.math.isInt(limitSize) && limitSize >= 0);\n\n const iterator = goog.iter.toIterator(iterable);\n\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n let remaining = limitSize;\n\n /**\n * @return {!IIterableResult}\n * @override\n */\n iter.next = function() {\n 'use strict';\n if (remaining-- > 0) {\n return iterator.next();\n }\n return goog.iter.ES6_ITERATOR_DONE;\n };\n\n return iter;\n};\n\n\n/**\n * Creates an iterator that is advanced `count` steps ahead. Consumed\n * values are silently discarded. If `count` is greater than the number\n * of elements in `iterable`, an empty iterator is returned. Subsequent\n * calls to `next()` will return `goog.iter.ES6_ITERATOR_DONE`.\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to consume.\n * @param {number} count The number of elements to consume from the iterator.\n * @return {!goog.iter.Iterator} An iterator advanced zero or more steps\n * ahead.\n * @template VALUE\n */\ngoog.iter.consume = function(iterable, count) {\n 'use strict';\n goog.asserts.assert(goog.math.isInt(count) && count >= 0);\n\n const iterator = goog.iter.toIterator(iterable);\n\n while (count-- > 0) {\n goog.iter.nextOrValue(iterator, null);\n }\n\n return iterator;\n};\n\n\n/**\n * Creates an iterator that returns a range of elements from an iterable.\n * Similar to {@see goog.array.slice} but does not support negative indexes.\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to slice.\n * @param {number} start The index of the first element to return.\n * @param {number=} opt_end The index after the last element to return. If\n * defined, must be greater than or equal to `start`.\n * @return {!goog.iter.Iterator} A new iterator containing a slice of\n * the original.\n * @template VALUE\n */\ngoog.iter.slice = function(iterable, start, opt_end) {\n 'use strict';\n goog.asserts.assert(goog.math.isInt(start) && start >= 0);\n\n let iterator = goog.iter.consume(iterable, start);\n\n if (typeof opt_end === 'number') {\n goog.asserts.assert(goog.math.isInt(opt_end) && opt_end >= start);\n iterator = goog.iter.limit(iterator, opt_end - start /* limitSize */);\n }\n\n return iterator;\n};\n\n\n/**\n * Checks an array for duplicate elements.\n * @param {?IArrayLike} arr The array to check for\n * duplicates.\n * @return {boolean} True, if the array contains duplicates, false otherwise.\n * @private\n * @template VALUE\n */\n// TODO(user): Consider moving this into goog.array as a public function.\ngoog.iter.hasDuplicates_ = function(arr) {\n 'use strict';\n const deduped = [];\n goog.array.removeDuplicates(arr, deduped);\n return arr.length != deduped.length;\n};\n\n\n/**\n * Creates an iterator that returns permutations of elements in\n * `iterable`.\n *\n * Permutations are obtained by taking the Cartesian product of\n * `opt_length` iterables and filtering out those with repeated\n * elements. For example, the permutations of {@code [1,2,3]} are\n * {@code [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]}.\n * @see http://docs.python.org/2/library/itertools.html#itertools.permutations\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable from which to generate permutations.\n * @param {number=} opt_length Length of each permutation. If omitted, defaults\n * to the length of `iterable`.\n * @return {!goog.iter.Iterator>} A new iterator containing the\n * permutations of `iterable`.\n * @template VALUE\n */\ngoog.iter.permutations = function(iterable, opt_length) {\n 'use strict';\n const elements = goog.iter.toArray(iterable);\n const length =\n (typeof opt_length === 'number') ? opt_length : elements.length;\n\n const sets = goog.array.repeat(elements, length);\n const product = goog.iter.product.apply(undefined, sets);\n\n return goog.iter.filter(product, function(arr) {\n 'use strict';\n return !goog.iter.hasDuplicates_(arr);\n });\n};\n\n\n/**\n * Creates an iterator that returns combinations of elements from\n * `iterable`.\n *\n * Combinations are obtained by taking the {@see goog.iter.permutations} of\n * `iterable` and filtering those whose elements appear in the order they\n * are encountered in `iterable`. For example, the 3-length combinations\n * of {@code [0,1,2,3]} are {@code [[0,1,2], [0,1,3], [0,2,3], [1,2,3]]}.\n * @see http://docs.python.org/2/library/itertools.html#itertools.combinations\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable from which to generate combinations.\n * @param {number} length The length of each combination.\n * @return {!goog.iter.Iterator>} A new iterator containing\n * combinations from the `iterable`.\n * @template VALUE\n */\ngoog.iter.combinations = function(iterable, length) {\n 'use strict';\n const elements = goog.iter.toArray(iterable);\n const indexes = goog.iter.range(elements.length);\n const indexIterator = goog.iter.permutations(indexes, length);\n // sortedIndexIterator will now give arrays of with the given length that\n // indicate what indexes into \"elements\" should be returned on each iteration.\n const sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) {\n 'use strict';\n return goog.array.isSorted(arr);\n });\n\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n function getIndexFromElements(index) {\n return elements[index];\n }\n /**\n * @return {!IIterableResult>}\n * @override\n */\n iter.next = function() {\n 'use strict';\n const {done, value} = sortedIndexIterator.next();\n if (done) return goog.iter.ES6_ITERATOR_DONE;\n return goog.iter.createEs6IteratorYield(\n goog.array.map(value, getIndexFromElements));\n };\n\n return iter;\n};\n\n\n/**\n * Creates an iterator that returns combinations of elements from\n * `iterable`, with repeated elements possible.\n *\n * Combinations are obtained by taking the Cartesian product of `length`\n * iterables and filtering those whose elements appear in the order they are\n * encountered in `iterable`. For example, the 2-length combinations of\n * {@code [1,2,3]} are {@code [[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]}.\n * @see https://goo.gl/C0yXe4\n * @see https://goo.gl/djOCsk\n * @param {!goog.iter.Iterator|!goog.iter.Iterable} iterable The\n * iterable to combine.\n * @param {number} length The length of each combination.\n * @return {!goog.iter.Iterator>} A new iterator containing\n * combinations from the `iterable`.\n * @template VALUE\n */\ngoog.iter.combinationsWithReplacement = function(iterable, length) {\n 'use strict';\n const elements = goog.iter.toArray(iterable);\n const indexes = goog.array.range(elements.length);\n const sets = goog.array.repeat(indexes, length);\n const indexIterator = goog.iter.product.apply(undefined, sets);\n // sortedIndexIterator will now give arrays of with the given length that\n // indicate what indexes into \"elements\" should be returned on each iteration.\n const sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) {\n 'use strict';\n return goog.array.isSorted(arr);\n });\n\n const iter =\n /** @type {!goog.iter.Iterator} */ (new goog.iter.Iterator());\n\n function getIndexFromElements(index) {\n return elements[index];\n }\n\n /**\n * @return {!IIterableResult>}\n * @override\n */\n iter.next = function() {\n 'use strict';\n const {done, value} = sortedIndexIterator.next();\n if (done) return goog.iter.ES6_ITERATOR_DONE;\n return goog.iter.createEs6IteratorYield(goog.array.map(\n /** @type {!Array} */ (value), getIndexFromElements));\n };\n\n return iter;\n};\n","^<",1684857788697,"^=",["^3",["^2?","^22","^>","^40","^77","^4I"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2?","^22","^40","^77","^4I"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.iter","goog.iter.Iterable","goog.iter.Iterator"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.array","goog.asserts","goog.debug","goog.functions","goog.math"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/iter/iter.js"],"^[",["^3",["^3Q","^3R","^FR"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^4I","^2?","^40","^22","^77"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.iter.es6","^1Y","^>L","^U",true,"^5","goog.iter.es6.js","^6",["^7","goog/iter/es6.js"],"^8","goog/iter/es6.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Shims between goog.iter.Iterator and ES6 iterator.\n */\n\ngoog.module('goog.iter.es6');\ngoog.module.declareLegacyNamespace();\n\nconst GoogIterable = goog.require('goog.iter.Iterable');\nconst GoogIterator = goog.require('goog.iter.Iterator');\n\n\n/**\n * Common interface extending both `goog.iter.Iterable` and ES6 `Iterable`,\n * and providing `toGoog()` and `toEs6()` methods to get either kind\n * of iterator. `ShimIterable.of()` is the primary entry point for\n * this library. If it is given an iterable that is *not* also an\n * iterator, then it will inherit any reusability from its argument\n * (i.e. `ShimIterable.of(mySet)` will be reusable, since mySet makes\n * a fresh Iterator every time, whereas `ShimIterable.of(myIterator)`\n * will be one-shot).\n *\n * `ShimGoogIterator` and `ShimEs6Iterator` extend `ShimIterable` and\n * also implement one or the other iterator API. Since they extend\n * `ShimIterable`, it is easy to convert back and forth between the two\n * APIs. Any such conversion will expose a view to the same underlying\n * iterator, so elements pulled via one API will not be available from\n * the other.\n *\n * @interface\n * @extends {Iterable}\n * @template VALUE\n */\nclass ShimIterable {\n /** @return {!GoogIterator} */\n __iterator__() {}\n\n /** @return {!ShimGoogIterator} */\n toGoog() {}\n\n /** @return {!ShimEs6Iterator} */\n toEs6() {}\n\n /**\n * @param {!Iterable|!Iterator|\n * !GoogIterator|!GoogIterable} iter\n * @return {!ShimIterable}\n * @template VALUE\n */\n static of(iter) {\n if (iter instanceof ShimIterableImpl || iter instanceof ShimGoogIterator ||\n iter instanceof ShimEs6Iterator) {\n return iter;\n } else if (typeof iter.next == 'function') {\n return new ShimIterableImpl(\n () => /** @type {!Iterator|!GoogIterator} */ (iter));\n } else if (typeof iter[Symbol.iterator] == 'function') {\n return new ShimIterableImpl(() => iter[Symbol.iterator]());\n } else if (typeof iter.__iterator__ == 'function') {\n return new ShimIterableImpl(\n () => /** @type {{__iterator__:function(this:?, boolean=)}} */ (iter)\n .__iterator__());\n }\n throw new Error('Not an iterator or iterable.');\n }\n}\n\n\n/**\n * Concrete (private) implementation of a non-iterator iterable. This is\n * separate from the iterator versions since it supports iterables that\n * are not \"one-shot\".\n * @implements {ShimIterable}\n * @template VALUE\n */\nclass ShimIterableImpl {\n /** @param {function(): !Iterator} func */\n constructor(func) {\n /** @const @private */\n this.func_ = func;\n }\n\n /** @override */\n __iterator__() {\n return new ShimGoogIterator(this.func_());\n }\n\n /** @override */\n toGoog() {\n return new ShimGoogIterator(this.func_());\n }\n\n /** @override */\n [Symbol.iterator]() {\n return new ShimEs6Iterator(this.func_());\n }\n\n /** @override */\n toEs6() {\n return new ShimEs6Iterator(this.func_());\n }\n}\n\n\n/**\n * Concrete `goog.iter.Iterator` subclass that also implements `ShimIterable`.\n * @extends {GoogIterator}\n * @implements {ShimIterable}\n * @template VALUE\n */\nclass ShimGoogIterator extends GoogIterator {\n /** @param {!Iterator} iter */\n constructor(iter) {\n super();\n this.iter_ = iter;\n }\n\n /**\n * @override @see {!goog.iter.Iterator}\n * @return {!IIterableResult}\n */\n next() {\n return this.iter_.next();\n }\n\n\n /** @override */\n toGoog() {\n return this;\n }\n\n /** @override */\n [Symbol.iterator]() {\n return new ShimEs6Iterator(this.iter_);\n }\n\n /** @override */\n toEs6() {\n return new ShimEs6Iterator(this.iter_);\n }\n}\n\n\n/**\n * Concrete ES6 `Iterator` that also implements `ShimIterable`.\n * @implements {IteratorIterable}\n * @extends {ShimIterableImpl}\n * @template VALUE\n */\nclass ShimEs6Iterator extends ShimIterableImpl {\n /** @param {!Iterator} iter */\n constructor(iter) {\n super(() => iter);\n /** @const @private */\n this.iter_ = iter;\n }\n\n /** @override */\n next() {\n return this.iter_.next();\n }\n}\n\n\nexports = {\n ShimIterable,\n ShimEs6Iterator,\n ShimGoogIterator,\n};\n","^<",1684857788697,"^=",["^3",["^>","^3R","^FR"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^3R","^FR"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.iter.es6","^U",true,"^V",[],"^M",["goog.iter.Iterable","goog.iter.Iterator"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/iter/es6.js"],"^[",["^3",["^>L"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^FR","^3R"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.fs.FileSystemImpl"]],"^5","goog.fs.filesystemimpl.js","^6",["^7","goog/fs/filesystemimpl.js"],"^8","goog/fs/filesystemimpl.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Concrete implementation of the goog.fs.FileSystem interface\n * using an HTML FileSystem object.\n */\ngoog.provide('goog.fs.FileSystemImpl');\n\ngoog.require('goog.fs.DirectoryEntryImpl');\ngoog.require('goog.fs.FileSystem');\n\n\n\n/**\n * A local filesystem.\n *\n * This shouldn't be instantiated directly. Instead, it should be accessed via\n * {@link goog.fs.getTemporary} or {@link goog.fs.getPersistent}.\n *\n * @param {!FileSystem} fs The underlying FileSystem object.\n * @constructor\n * @implements {goog.fs.FileSystem}\n * @final\n */\ngoog.fs.FileSystemImpl = function(fs) {\n 'use strict';\n /**\n * The underlying FileSystem object.\n *\n * @type {!FileSystem}\n * @private\n */\n this.fs_ = fs;\n};\n\n\n/** @override */\ngoog.fs.FileSystemImpl.prototype.getName = function() {\n 'use strict';\n return this.fs_.name;\n};\n\n\n/** @override */\ngoog.fs.FileSystemImpl.prototype.getRoot = function() {\n 'use strict';\n return new goog.fs.DirectoryEntryImpl(this, this.fs_.root);\n};\n\n\n/**\n * @return {!FileSystem} The underlying FileSystem object.\n */\ngoog.fs.FileSystemImpl.prototype.getBrowserFileSystem = function() {\n 'use strict';\n return this.fs_;\n};\n","^<",1684857788697,"^=",["^3",["^>","^=7","^=L"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^=7","^=L"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.FileSystemImpl"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.fs.DirectoryEntryImpl","goog.fs.FileSystem"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/filesystemimpl.js"],"^[",["^3",["^FS"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^=L","^=7"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^=7"]],"^5","goog.fs.filesystem.js","^6",["^7","goog/fs/filesystem.js"],"^8","goog/fs/filesystem.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A wrapper for the HTML5 FileSystem object.\n */\n\ngoog.provide('goog.fs.FileSystem');\n\ngoog.requireType('goog.fs.DirectoryEntry');\n\n\n\n/**\n * A local filesystem.\n *\n * @interface\n */\ngoog.fs.FileSystem = function() {};\n\n\n/**\n * @return {string} The name of the filesystem.\n */\ngoog.fs.FileSystem.prototype.getName = function() {};\n\n\n/**\n * @return {!goog.fs.DirectoryEntry} The root directory of the filesystem.\n */\ngoog.fs.FileSystem.prototype.getRoot = function() {};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.FileSystem"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",[],"^W",["goog.fs.DirectoryEntry"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/filesystem.js"],"^[",["^3",["^=7"]],"^W",["^3",["^=K"]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.fs.ProgressEvent"]],"^5","goog.fs.progressevent.js","^6",["^7","goog/fs/progressevent.js"],"^8","goog/fs/progressevent.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A wrapper for the HTML5 File ProgressEvent objects.\n */\ngoog.provide('goog.fs.ProgressEvent');\n\ngoog.require('goog.events.Event');\n\n\n\n/**\n * A wrapper for the progress events emitted by the File APIs.\n *\n * @param {!ProgressEvent} event The underlying event object.\n * @param {!Object} target The file access object emitting the event.\n * @extends {goog.events.Event}\n * @constructor\n * @final\n */\ngoog.fs.ProgressEvent = function(event, target) {\n 'use strict';\n goog.fs.ProgressEvent.base(this, 'constructor', event.type, target);\n\n /**\n * The underlying event object.\n * @type {!ProgressEvent}\n * @private\n */\n this.event_ = event;\n};\ngoog.inherits(goog.fs.ProgressEvent, goog.events.Event);\n\n\n/**\n * @return {boolean} Whether or not the total size of the of the file being\n * saved is known.\n */\ngoog.fs.ProgressEvent.prototype.isLengthComputable = function() {\n 'use strict';\n return this.event_.lengthComputable;\n};\n\n\n/**\n * @return {number} The number of bytes saved so far.\n */\ngoog.fs.ProgressEvent.prototype.getLoaded = function() {\n 'use strict';\n return this.event_.loaded;\n};\n\n\n/**\n * @return {number} The total number of bytes in the file being saved.\n */\ngoog.fs.ProgressEvent.prototype.getTotal = function() {\n 'use strict';\n return this.event_.total;\n};\n","^<",1684857788697,"^=",["^3",["^>","^4<"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^4<"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.ProgressEvent"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.events.Event"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/progressevent.js"],"^[",["^3",["^FT"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^4<"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.fs.FileEntryImpl","~$goog.fs.EntryImpl","^=L"]],"^5","goog.fs.entryimpl.js","^6",["^7","goog/fs/entryimpl.js"],"^8","goog/fs/entryimpl.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Concrete implementations of the\n * goog.fs.DirectoryEntry, and goog.fs.FileEntry interfaces.\n */\ngoog.provide('goog.fs.DirectoryEntryImpl');\ngoog.provide('goog.fs.EntryImpl');\ngoog.provide('goog.fs.FileEntryImpl');\n\ngoog.require('goog.async.Deferred');\ngoog.require('goog.fs.DirectoryEntry');\ngoog.require('goog.fs.Entry');\ngoog.require('goog.fs.Error');\ngoog.require('goog.fs.FileEntry');\ngoog.require('goog.fs.FileWriter');\ngoog.require('goog.functions');\ngoog.require('goog.string');\ngoog.requireType('goog.fs.FileSystem');\n\n\n\n/**\n * Base class for concrete implementations of goog.fs.Entry.\n * @param {!goog.fs.FileSystem} fs The wrapped filesystem.\n * @param {!Entry} entry The underlying Entry object.\n * @constructor\n * @implements {goog.fs.Entry}\n */\ngoog.fs.EntryImpl = function(fs, entry) {\n 'use strict';\n /**\n * The wrapped filesystem.\n *\n * @type {!goog.fs.FileSystem}\n * @private\n */\n this.fs_ = fs;\n\n /**\n * The underlying Entry object.\n *\n * @type {!Entry}\n * @private\n */\n this.entry_ = entry;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.isFile = function() {\n 'use strict';\n return this.entry_.isFile;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.isDirectory = function() {\n 'use strict';\n return this.entry_.isDirectory;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.getName = function() {\n 'use strict';\n return this.entry_.name;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.getFullPath = function() {\n 'use strict';\n return this.entry_.fullPath;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.getFileSystem = function() {\n 'use strict';\n return this.fs_;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.getLastModified = function() {\n 'use strict';\n return this.getMetadata().addCallback(function(metadata) {\n 'use strict';\n return metadata.modificationTime;\n });\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.getMetadata = function() {\n 'use strict';\n const d = new goog.async.Deferred();\n\n this.entry_.getMetadata(function(metadata) {\n 'use strict';\n d.callback(metadata);\n }, goog.bind(function(err) {\n 'use strict';\n const msg = 'retrieving metadata for ' + this.getFullPath();\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.moveTo = function(parent, opt_newName) {\n 'use strict';\n const d = new goog.async.Deferred();\n this.entry_.moveTo(\n /** @type {!goog.fs.DirectoryEntryImpl} */ (parent).dir_, opt_newName,\n goog.bind(function(entry) {\n 'use strict';\n d.callback(this.wrapEntry(entry));\n }, this), goog.bind(function(err) {\n 'use strict';\n const msg = 'moving ' + this.getFullPath() + ' into ' +\n parent.getFullPath() +\n (opt_newName ? ', renaming to ' + opt_newName : '');\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.copyTo = function(parent, opt_newName) {\n 'use strict';\n const d = new goog.async.Deferred();\n this.entry_.copyTo(\n /** @type {!goog.fs.DirectoryEntryImpl} */ (parent).dir_, opt_newName,\n goog.bind(function(entry) {\n 'use strict';\n d.callback(this.wrapEntry(entry));\n }, this), goog.bind(function(err) {\n 'use strict';\n const msg = 'copying ' + this.getFullPath() + ' into ' +\n parent.getFullPath() +\n (opt_newName ? ', renaming to ' + opt_newName : '');\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.wrapEntry = function(entry) {\n 'use strict';\n return entry.isFile ?\n new goog.fs.FileEntryImpl(this.fs_, /** @type {!FileEntry} */ (entry)) :\n new goog.fs.DirectoryEntryImpl(\n this.fs_, /** @type {!DirectoryEntry} */ (entry));\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.toUrl = function(opt_mimeType) {\n 'use strict';\n return this.entry_.toURL(opt_mimeType);\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.toUri = goog.fs.EntryImpl.prototype.toUrl;\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.remove = function() {\n 'use strict';\n const d = new goog.async.Deferred();\n this.entry_.remove(\n goog.bind(d.callback, d, true /* result */), goog.bind(function(err) {\n 'use strict';\n const msg = 'removing ' + this.getFullPath();\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n/** @override */\ngoog.fs.EntryImpl.prototype.getParent = function() {\n 'use strict';\n const d = new goog.async.Deferred();\n this.entry_.getParent(goog.bind(function(parent) {\n 'use strict';\n d.callback(new goog.fs.DirectoryEntryImpl(this.fs_, parent));\n }, this), goog.bind(function(err) {\n 'use strict';\n const msg = 'getting parent of ' + this.getFullPath();\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n\n/**\n * A directory in a local FileSystem.\n *\n * This should not be instantiated directly. Instead, it should be accessed via\n * {@link goog.fs.FileSystem#getRoot} or\n * {@link goog.fs.DirectoryEntry#getDirectoryEntry}.\n *\n * @param {!goog.fs.FileSystem} fs The wrapped filesystem.\n * @param {!DirectoryEntry} dir The underlying DirectoryEntry object.\n * @constructor\n * @extends {goog.fs.EntryImpl}\n * @implements {goog.fs.DirectoryEntry}\n * @final\n */\ngoog.fs.DirectoryEntryImpl = function(fs, dir) {\n 'use strict';\n goog.fs.DirectoryEntryImpl.base(this, 'constructor', fs, dir);\n\n /**\n * The underlying DirectoryEntry object.\n *\n * @type {!DirectoryEntry}\n * @private\n */\n this.dir_ = dir;\n};\ngoog.inherits(goog.fs.DirectoryEntryImpl, goog.fs.EntryImpl);\n\n\n/** @override */\ngoog.fs.DirectoryEntryImpl.prototype.getFile = function(path, opt_behavior) {\n 'use strict';\n const d = new goog.async.Deferred();\n this.dir_.getFile(\n path, this.getOptions_(opt_behavior), goog.bind(function(entry) {\n 'use strict';\n d.callback(new goog.fs.FileEntryImpl(this.fs_, entry));\n }, this), goog.bind(function(err) {\n 'use strict';\n const msg = 'loading file ' + path + ' from ' + this.getFullPath();\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n/** @override */\ngoog.fs.DirectoryEntryImpl.prototype.getDirectory = function(\n path, opt_behavior) {\n 'use strict';\n const d = new goog.async.Deferred();\n this.dir_.getDirectory(\n path, this.getOptions_(opt_behavior), goog.bind(function(entry) {\n 'use strict';\n d.callback(new goog.fs.DirectoryEntryImpl(this.fs_, entry));\n }, this), goog.bind(function(err) {\n 'use strict';\n const msg = 'loading directory ' + path + ' from ' + this.getFullPath();\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n/** @override */\ngoog.fs.DirectoryEntryImpl.prototype.createPath = function(path) {\n 'use strict';\n // If the path begins at the root, reinvoke createPath on the root directory.\n if (goog.string.startsWith(path, '/')) {\n const root = this.getFileSystem().getRoot();\n if (this.getFullPath() != root.getFullPath()) {\n return root.createPath(path);\n }\n }\n\n // Filter out any empty path components caused by '//' or a leading slash.\n const parts = path.split('/').filter(goog.functions.identity);\n\n /**\n * @param {goog.fs.DirectoryEntryImpl} dir\n * @return {!goog.async.Deferred}\n */\n function getNextDirectory(dir) {\n if (!parts.length) {\n return goog.async.Deferred.succeed(dir);\n }\n\n let def;\n const nextDir = parts.shift();\n\n if (nextDir == '..') {\n def = dir.getParent();\n } else if (nextDir == '.') {\n def = goog.async.Deferred.succeed(dir);\n } else {\n def = dir.getDirectory(nextDir, goog.fs.DirectoryEntry.Behavior.CREATE);\n }\n return def.addCallback(getNextDirectory);\n }\n\n return getNextDirectory(this);\n};\n\n\n/** @override */\ngoog.fs.DirectoryEntryImpl.prototype.listDirectory = function() {\n 'use strict';\n const d = new goog.async.Deferred();\n const reader = this.dir_.createReader();\n const results = [];\n\n const errorCallback = goog.bind(function(err) {\n 'use strict';\n const msg = 'listing directory ' + this.getFullPath();\n d.errback(new goog.fs.Error(err, msg));\n }, this);\n\n const successCallback = goog.bind(function(entries) {\n 'use strict';\n if (entries.length) {\n for (let i = 0, entry; entry = entries[i]; i++) {\n results.push(this.wrapEntry(entry));\n }\n reader.readEntries(successCallback, errorCallback);\n } else {\n d.callback(results);\n }\n }, this);\n\n reader.readEntries(successCallback, errorCallback);\n return d;\n};\n\n\n/** @override */\ngoog.fs.DirectoryEntryImpl.prototype.removeRecursively = function() {\n 'use strict';\n const d = new goog.async.Deferred();\n this.dir_.removeRecursively(\n goog.bind(d.callback, d, true /* result */), goog.bind(function(err) {\n 'use strict';\n const msg = 'removing ' + this.getFullPath() + ' recursively';\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n/**\n * Converts a value in the Behavior enum into an options object expected by the\n * File API.\n *\n * @param {goog.fs.DirectoryEntry.Behavior=} opt_behavior The behavior for\n * existing files.\n * @return {!Object} The options object expected by the File API.\n * @private\n */\ngoog.fs.DirectoryEntryImpl.prototype.getOptions_ = function(opt_behavior) {\n 'use strict';\n if (opt_behavior == goog.fs.DirectoryEntry.Behavior.CREATE) {\n return {'create': true};\n } else if (opt_behavior == goog.fs.DirectoryEntry.Behavior.CREATE_EXCLUSIVE) {\n return {'create': true, 'exclusive': true};\n } else {\n return {};\n }\n};\n\n\n\n/**\n * A file in a local filesystem.\n *\n * This should not be instantiated directly. Instead, it should be accessed via\n * {@link goog.fs.DirectoryEntry#getFile}.\n *\n * @param {!goog.fs.FileSystem} fs The wrapped filesystem.\n * @param {!FileEntry} file The underlying FileEntry object.\n * @constructor\n * @extends {goog.fs.EntryImpl}\n * @implements {goog.fs.FileEntry}\n * @final\n */\ngoog.fs.FileEntryImpl = function(fs, file) {\n 'use strict';\n goog.fs.FileEntryImpl.base(this, 'constructor', fs, file);\n\n /**\n * The underlying FileEntry object.\n *\n * @type {!FileEntry}\n * @private\n */\n this.file_ = file;\n};\ngoog.inherits(goog.fs.FileEntryImpl, goog.fs.EntryImpl);\n\n\n/** @override */\ngoog.fs.FileEntryImpl.prototype.createWriter = function() {\n 'use strict';\n const d = new goog.async.Deferred();\n this.file_.createWriter(function(w) {\n 'use strict';\n d.callback(new goog.fs.FileWriter(w));\n }, goog.bind(function(err) {\n 'use strict';\n const msg = 'creating writer for ' + this.getFullPath();\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n\n\n/** @override */\ngoog.fs.FileEntryImpl.prototype.file = function() {\n 'use strict';\n const d = new goog.async.Deferred();\n this.file_.file(function(f) {\n 'use strict';\n d.callback(f);\n }, goog.bind(function(err) {\n 'use strict';\n const msg = 'getting file for ' + this.getFullPath();\n d.errback(new goog.fs.Error(err, msg));\n }, this));\n return d;\n};\n","^<",1684857788697,"^=",["^3",["^22","^2L","^=I","^=>","^>","~$goog.fs.FileWriter","^=J","^=K","^42"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^22","^2L","^=I","^=>","^FW","^=J","^=K","^42"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.DirectoryEntryImpl","goog.fs.EntryImpl","goog.fs.FileEntryImpl"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.async.Deferred","goog.fs.DirectoryEntry","goog.fs.Entry","goog.fs.Error","goog.fs.FileEntry","goog.fs.FileWriter","goog.functions","goog.string"],"^W",["goog.fs.FileSystem"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/entryimpl.js"],"^[",["^3",["^FU","^FV","^=L"]],"^W",["^3",["^=7"]],"^10",true,"^11",true,"^12",["^>","^42","^=K","^=J","^=>","^=I","^FW","^22","^2L"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^FW"]],"^5","goog.fs.filewriter.js","^6",["^7","goog/fs/filewriter.js"],"^8","goog/fs/filewriter.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A wrapper for the HTML5 FileWriter object.\n *\n * When adding or modifying functionality in this namespace, be sure to update\n * the mock counterparts in goog.testing.fs.\n */\n\ngoog.provide('goog.fs.FileWriter');\n\ngoog.require('goog.fs.Error');\ngoog.require('goog.fs.FileSaver');\n\n\n\n/**\n * An object for monitoring the saving of files, as well as other fine-grained\n * writing operations.\n *\n * This should not be instantiated directly. Instead, it should be accessed via\n * {@link goog.fs.FileEntry#createWriter}.\n *\n * @param {!FileWriter} writer The underlying FileWriter object.\n * @constructor\n * @extends {goog.fs.FileSaver}\n * @final\n */\ngoog.fs.FileWriter = function(writer) {\n 'use strict';\n goog.fs.FileWriter.base(this, 'constructor', writer);\n\n /**\n * The underlying FileWriter object.\n *\n * @type {!FileWriter}\n * @private\n */\n this.writer_ = writer;\n};\ngoog.inherits(goog.fs.FileWriter, goog.fs.FileSaver);\n\n\n/**\n * @return {number} The byte offset at which the next write will occur.\n */\ngoog.fs.FileWriter.prototype.getPosition = function() {\n 'use strict';\n return this.writer_.position;\n};\n\n\n/**\n * @return {number} The length of the file.\n */\ngoog.fs.FileWriter.prototype.getLength = function() {\n 'use strict';\n return this.writer_.length;\n};\n\n\n/**\n * Write data to the file.\n *\n * @param {!Blob} blob The data to write.\n */\ngoog.fs.FileWriter.prototype.write = function(blob) {\n 'use strict';\n try {\n this.writer_.write(blob);\n } catch (e) {\n throw new goog.fs.Error(e, 'writing file');\n }\n};\n\n\n/**\n * Set the file position at which the next write will occur.\n *\n * @param {number} offset An absolute byte offset into the file.\n */\ngoog.fs.FileWriter.prototype.seek = function(offset) {\n 'use strict';\n try {\n this.writer_.seek(offset);\n } catch (e) {\n throw new goog.fs.Error(e, 'seeking in file');\n }\n};\n\n\n/**\n * Changes the length of the file to that specified.\n *\n * @param {number} size The new size of the file, in bytes.\n */\ngoog.fs.FileWriter.prototype.truncate = function(size) {\n 'use strict';\n try {\n this.writer_.truncate(size);\n } catch (e) {\n throw new goog.fs.Error(e, 'truncating file');\n }\n};\n","^<",1684857788697,"^=",["^3",["^=<","^=>","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^=<","^=>"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.FileWriter"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.fs.Error","goog.fs.FileSaver"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/filewriter.js"],"^[",["^3",["^FW"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^=>","^=<"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.fs.Error.ErrorCode","^=>","~$goog.fs.DOMErrorLike"]],"^5","goog.fs.error.js","^6",["^7","goog/fs/error.js"],"^8","goog/fs/error.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A wrapper for the HTML5 FileError object.\n */\n\n\n// TODO(user): We're trying to migrate all ES5 subclasses of Closure\n// Library to ES6. In ES6 this cannot be referenced before super is called. This\n// file has at least one this before a super call (in ES5) and cannot be\n// automatically upgraded to ES6 as a result. Please fix this if you have a\n// chance. Note: This can sometimes be caused by not calling the super\n// constructor at all. You can run the conversion tool yourself to see what it\n// does on this file: blaze run //javascript/refactoring/es6_classes:convert.\n\ngoog.provide('goog.fs.DOMErrorLike');\ngoog.provide('goog.fs.Error');\ngoog.provide('goog.fs.Error.ErrorCode');\n\ngoog.require('goog.asserts');\ngoog.require('goog.debug.Error');\ngoog.require('goog.object');\ngoog.require('goog.string');\n\n/** @record */\ngoog.fs.DOMErrorLike = function() {};\n\n/** @type {string|undefined} */\ngoog.fs.DOMErrorLike.prototype.name;\n\n/** @type {!goog.fs.Error.ErrorCode|undefined} */\ngoog.fs.DOMErrorLike.prototype.code;\n\n\n\n/**\n * A filesystem error. Since the filesystem API is asynchronous, stack traces\n * are less useful for identifying where errors come from, so this includes a\n * large amount of metadata in the message.\n *\n * @param {!DOMError|!goog.fs.DOMErrorLike} error\n * @param {string} action The action being undertaken when the error was raised.\n * @constructor\n * @extends {goog.debug.Error}\n * @final\n */\ngoog.fs.Error = function(error, action) {\n 'use strict';\n /** @type {string} */\n this.name;\n\n /**\n * @type {!goog.fs.Error.ErrorCode}\n * @deprecated Use the 'name' or 'message' field instead.\n */\n this.code;\n\n if (error.name !== undefined) {\n this.name = error.name;\n // TODO(user): Remove warning suppression after JSCompiler stops\n // firing a spurious warning here.\n /** @suppress {deprecated} */\n this.code = goog.fs.Error.getCodeFromName_(error.name);\n } else {\n const code =\n /** @type {!goog.fs.Error.ErrorCode} */ (goog.asserts.assertNumber(\n /** @type {!goog.fs.DOMErrorLike} */ (error).code));\n this.code = code;\n this.name = goog.fs.Error.getNameFromCode_(code);\n }\n goog.fs.Error.base(\n this, 'constructor', goog.string.subs('%s %s', this.name, action));\n};\ngoog.inherits(goog.fs.Error, goog.debug.Error);\n\n\n/**\n * Names of errors that may be thrown by the File API, the File System API, or\n * the File Writer API.\n *\n * @see http://dev.w3.org/2006/webapi/FileAPI/#ErrorAndException\n * @see http://www.w3.org/TR/file-system-api/#definitions\n * @see http://dev.w3.org/2009/dap/file-system/file-writer.html#definitions\n * @enum {string}\n */\ngoog.fs.Error.ErrorName = {\n ABORT: 'AbortError',\n ENCODING: 'EncodingError',\n INVALID_MODIFICATION: 'InvalidModificationError',\n INVALID_STATE: 'InvalidStateError',\n NOT_FOUND: 'NotFoundError',\n NOT_READABLE: 'NotReadableError',\n NO_MODIFICATION_ALLOWED: 'NoModificationAllowedError',\n PATH_EXISTS: 'PathExistsError',\n QUOTA_EXCEEDED: 'QuotaExceededError',\n SECURITY: 'SecurityError',\n SYNTAX: 'SyntaxError',\n TYPE_MISMATCH: 'TypeMismatchError'\n};\n\n\n/**\n * Error codes for file errors.\n * @see http://www.w3.org/TR/file-system-api/#idl-def-FileException\n *\n * @enum {number}\n * @deprecated Use the 'name' or 'message' attribute instead.\n */\ngoog.fs.Error.ErrorCode = {\n NOT_FOUND: 1,\n SECURITY: 2,\n ABORT: 3,\n NOT_READABLE: 4,\n ENCODING: 5,\n NO_MODIFICATION_ALLOWED: 6,\n INVALID_STATE: 7,\n SYNTAX: 8,\n INVALID_MODIFICATION: 9,\n QUOTA_EXCEEDED: 10,\n TYPE_MISMATCH: 11,\n PATH_EXISTS: 12\n};\n\n\n/**\n * @param {goog.fs.Error.ErrorCode|undefined} code\n * @return {string} name\n * @private\n */\ngoog.fs.Error.getNameFromCode_ = function(code) {\n 'use strict';\n const name = goog.object.findKey(goog.fs.Error.NameToCodeMap_, function(c) {\n 'use strict';\n return code == c;\n });\n if (name === undefined) {\n throw new Error('Invalid code: ' + code);\n }\n return name;\n};\n\n\n/**\n * Returns the code that corresponds to the given name.\n * @param {string} name\n * @return {goog.fs.Error.ErrorCode} code\n * @private\n */\ngoog.fs.Error.getCodeFromName_ = function(name) {\n 'use strict';\n return goog.fs.Error.NameToCodeMap_[name];\n};\n\n\n/**\n * Mapping from error names to values from the ErrorCode enum.\n * @see http://www.w3.org/TR/file-system-api/#definitions.\n * @private {!Object}\n */\ngoog.fs.Error.NameToCodeMap_ = {\n [goog.fs.Error.ErrorName.ABORT]: goog.fs.Error.ErrorCode.ABORT,\n [goog.fs.Error.ErrorName.ENCODING]: goog.fs.Error.ErrorCode.ENCODING,\n [goog.fs.Error.ErrorName.INVALID_MODIFICATION]:\n goog.fs.Error.ErrorCode.INVALID_MODIFICATION,\n [goog.fs.Error.ErrorName.INVALID_STATE]:\n goog.fs.Error.ErrorCode.INVALID_STATE,\n [goog.fs.Error.ErrorName.NOT_FOUND]: goog.fs.Error.ErrorCode.NOT_FOUND,\n [goog.fs.Error.ErrorName.NOT_READABLE]: goog.fs.Error.ErrorCode.NOT_READABLE,\n [goog.fs.Error.ErrorName.NO_MODIFICATION_ALLOWED]:\n goog.fs.Error.ErrorCode.NO_MODIFICATION_ALLOWED,\n [goog.fs.Error.ErrorName.PATH_EXISTS]: goog.fs.Error.ErrorCode.PATH_EXISTS,\n [goog.fs.Error.ErrorName.QUOTA_EXCEEDED]:\n goog.fs.Error.ErrorCode.QUOTA_EXCEEDED,\n [goog.fs.Error.ErrorName.SECURITY]: goog.fs.Error.ErrorCode.SECURITY,\n [goog.fs.Error.ErrorName.SYNTAX]: goog.fs.Error.ErrorCode.SYNTAX,\n [goog.fs.Error.ErrorName.TYPE_MISMATCH]: goog.fs.Error.ErrorCode.TYPE_MISMATCH\n};\n","^<",1684857788697,"^=",["^3",["^2?","^2L","^>","^2F","^45"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2?","^2L","^2F","^45"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.DOMErrorLike","goog.fs.Error","goog.fs.Error.ErrorCode"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.asserts","goog.debug.Error","goog.object","goog.string"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/error.js"],"^[",["^3",["^FX","^=>","^FY"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2?","^45","^2F","^2L"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^=E"]],"^5","goog.fs.url.js","^6",["^7","goog/fs/url.js"],"^8","goog/fs/url.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Wrapper for URL and its createObjectUrl and revokeObjectUrl\n * methods that are part of the HTML5 File API.\n */\n\ngoog.provide('goog.fs.url');\n\n\n/**\n * Creates a blob URL for a blob object.\n * Throws an error if the browser does not support Object Urls.\n *\n * @param {!File|!Blob|!MediaSource|!MediaStream} obj The object for which\n * to create the URL.\n * @return {string} The URL for the object.\n */\ngoog.fs.url.createObjectUrl = function(obj) {\n 'use strict';\n return goog.fs.url.getUrlObject_().createObjectURL(obj);\n};\n\n\n/**\n * Revokes a URL created by {@link goog.fs.url.createObjectUrl}.\n * Throws an error if the browser does not support Object Urls.\n *\n * @param {string} url The URL to revoke.\n * @return {void}\n */\ngoog.fs.url.revokeObjectUrl = function(url) {\n 'use strict';\n goog.fs.url.getUrlObject_().revokeObjectURL(url);\n};\n\n\n/**\n * @record\n * @private\n */\ngoog.fs.url.UrlObject_ = function() {};\n\n/**\n * @param {!File|!Blob|!MediaSource|!MediaStream} arg\n * @return {string}\n */\ngoog.fs.url.UrlObject_.prototype.createObjectURL = function(arg) {};\n\n/**\n * @param {string} s\n * @return {void}\n */\ngoog.fs.url.UrlObject_.prototype.revokeObjectURL = function(s) {};\n\n\n/**\n * Get the object that has the createObjectURL and revokeObjectURL functions for\n * this browser.\n *\n * @return {!goog.fs.url.UrlObject_} The object for this browser.\n * @private\n */\ngoog.fs.url.getUrlObject_ = function() {\n 'use strict';\n const urlObject = goog.fs.url.findUrlObject_();\n if (urlObject != null) {\n return urlObject;\n } else {\n throw new Error('This browser doesn\\'t seem to support blob URLs');\n }\n};\n\n\n/**\n * Finds the object that has the createObjectURL and revokeObjectURL functions\n * for this browser.\n *\n * @return {?goog.fs.url.UrlObject_} The object for this browser or null if the\n * browser does not support Object Urls.\n * @private\n */\ngoog.fs.url.findUrlObject_ = function() {\n 'use strict';\n // This is what the spec says to do\n // http://dev.w3.org/2006/webapi/FileAPI/#dfn-createObjectURL\n if (goog.global.URL !== undefined &&\n goog.global.URL.createObjectURL !== undefined) {\n return /** @type {!goog.fs.url.UrlObject_} */ (goog.global.URL);\n // This is what the spec used to say to do\n } else if (goog.global.createObjectURL !== undefined) {\n return /** @type {!goog.fs.url.UrlObject_} */ (goog.global);\n } else {\n return null;\n }\n};\n\n\n/**\n * Checks whether this browser supports Object Urls. If not, calls to\n * createObjectUrl and revokeObjectUrl will result in an error.\n *\n * @return {boolean} True if this browser supports Object Urls.\n */\ngoog.fs.url.browserSupportsObjectUrls = function() {\n 'use strict';\n return goog.fs.url.findUrlObject_() != null;\n};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.url"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/url.js"],"^[",["^3",["^=E"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.fs.blob"]],"^5","goog.fs.blob.js","^6",["^7","goog/fs/blob.js"],"^8","goog/fs/blob.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Wrappers for the HTML5 File API. These wrappers closely mirror\n * the underlying APIs, but use Closure-style events and Deferred return values.\n * Their existence also makes it possible to mock the FileSystem API for testing\n * in browsers that don't support it natively.\n *\n * When adding public functions to anything under this namespace, be sure to add\n * its mock counterpart to goog.testing.fs.\n */\n\ngoog.provide('goog.fs.blob');\n\n\n\n/**\n * Concatenates one or more values together and converts them to a Blob.\n *\n * @param {...(string|!Blob|!ArrayBuffer)} var_args The values that will make up\n * the resulting blob.\n * @return {!Blob} The blob.\n */\ngoog.fs.blob.getBlob = function(var_args) {\n 'use strict';\n const BlobBuilder = goog.global.BlobBuilder || goog.global.WebKitBlobBuilder;\n\n if (BlobBuilder !== undefined) {\n const bb = new BlobBuilder();\n for (let i = 0; i < arguments.length; i++) {\n bb.append(arguments[i]);\n }\n return bb.getBlob();\n } else {\n return goog.fs.blob.getBlobWithProperties(\n Array.prototype.slice.call(arguments));\n }\n};\n\n\n/**\n * Creates a blob with the given properties.\n * See https://developer.mozilla.org/en-US/docs/Web/API/Blob for more details.\n *\n * @param {!Array} parts The values that will make up\n * the resulting blob (subset supported by both BlobBuilder.append() and\n * Blob constructor).\n * @param {string=} opt_type The MIME type of the Blob.\n * @param {string=} opt_endings Specifies how strings containing newlines are to\n * be written out.\n * @return {!Blob} The blob.\n */\ngoog.fs.blob.getBlobWithProperties = function(parts, opt_type, opt_endings) {\n 'use strict';\n const BlobBuilder = goog.global.BlobBuilder || goog.global.WebKitBlobBuilder;\n\n if (BlobBuilder !== undefined) {\n const bb = new BlobBuilder();\n for (let i = 0; i < parts.length; i++) {\n bb.append(parts[i], opt_endings);\n }\n return bb.getBlob(opt_type);\n } else if (goog.global.Blob !== undefined) {\n const properties = {};\n if (opt_type) {\n properties['type'] = opt_type;\n }\n if (opt_endings) {\n properties['endings'] = opt_endings;\n }\n return new Blob(parts, properties);\n } else {\n throw new Error('This browser doesn\\'t seem to support creating Blobs');\n }\n};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.blob"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/blob.js"],"^[",["^3",["^FZ"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^=D"]],"^5","goog.fs.fs.js","^6",["^7","goog/fs/fs.js"],"^8","goog/fs/fs.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Wrappers for the HTML5 File API. These wrappers closely mirror\n * the underlying APIs, but use Closure-style events and Deferred return values.\n * Their existence also makes it possible to mock the FileSystem API for testing\n * in browsers that don't support it natively.\n *\n * When adding public functions to anything under this namespace, be sure to add\n * its mock counterpart to goog.testing.fs.\n */\n\ngoog.provide('goog.fs');\n\ngoog.require('goog.async.Deferred');\ngoog.require('goog.fs.Error');\ngoog.require('goog.fs.FileSystemImpl');\n\n\n/**\n * Get a wrapped FileSystem object.\n *\n * @param {goog.fs.FileSystemType_} type The type of the filesystem to get.\n * @param {number} size The size requested for the filesystem, in bytes.\n * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileSystem}. If an\n * error occurs, the errback is called with a {@link goog.fs.Error}.\n * @private\n */\ngoog.fs.get_ = function(type, size) {\n 'use strict';\n const requestFileSystem =\n goog.global.requestFileSystem || goog.global.webkitRequestFileSystem;\n\n if (typeof requestFileSystem !== 'function') {\n return goog.async.Deferred.fail(new Error('File API unsupported'));\n }\n\n const d = new goog.async.Deferred();\n requestFileSystem(\n type, size,\n function(fs) {\n 'use strict';\n d.callback(new goog.fs.FileSystemImpl(fs));\n },\n function(err) {\n 'use strict';\n d.errback(new goog.fs.Error(err, 'requesting filesystem'));\n });\n return d;\n};\n\n\n/**\n * The two types of filesystem.\n *\n * @enum {number}\n * @private\n */\ngoog.fs.FileSystemType_ = {\n /**\n * A temporary filesystem may be deleted by the user agent at its discretion.\n */\n TEMPORARY: 0,\n /**\n * A persistent filesystem will never be deleted without the user's or\n * application's authorization.\n */\n PERSISTENT: 1\n};\n\n\n/**\n * Returns a temporary FileSystem object. A temporary filesystem may be deleted\n * by the user agent at its discretion.\n *\n * @param {number} size The size requested for the filesystem, in bytes.\n * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileSystem}. If an\n * error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.getTemporary = function(size) {\n 'use strict';\n return goog.fs.get_(goog.fs.FileSystemType_.TEMPORARY, size);\n};\n\n\n/**\n * Returns a persistent FileSystem object. A persistent filesystem will never be\n * deleted without the user's or application's authorization.\n *\n * @param {number} size The size requested for the filesystem, in bytes.\n * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileSystem}. If an\n * error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.getPersistent = function(size) {\n 'use strict';\n return goog.fs.get_(goog.fs.FileSystemType_.PERSISTENT, size);\n};\n\n\n/**\n * Slices the blob. The returned blob contains data from the start byte\n * (inclusive) till the end byte (exclusive). Negative indices can be used\n * to count bytes from the end of the blob (-1 == blob.size - 1). Indices\n * are always clamped to blob range. If end is omitted, all the data till\n * the end of the blob is taken.\n *\n * @param {!Blob} blob The blob to be sliced.\n * @param {number} start Index of the starting byte.\n * @param {number=} opt_end Index of the ending byte.\n * @return {Blob} The blob slice or null if not supported.\n */\ngoog.fs.sliceBlob = function(blob, start, opt_end) {\n 'use strict';\n if (opt_end === undefined) {\n opt_end = blob.size;\n }\n if (blob.slice) {\n return blob.slice(start, opt_end);\n }\n return null;\n};\n","^<",1684857788697,"^=",["^3",["^=>","^>","^FS","^42"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^=>","^FS","^42"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.async.Deferred","goog.fs.Error","goog.fs.FileSystemImpl"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/fs.js"],"^[",["^3",["^=D"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^42","^=>","^FS"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^=9","~$goog.fs.FileReader.ReadyState","^=G"]],"^5","goog.fs.filereader.js","^6",["^7","goog/fs/filereader.js"],"^8","goog/fs/filereader.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A wrapper for the HTML5 FileReader object.\n */\n\ngoog.provide('goog.fs.FileReader');\ngoog.provide('goog.fs.FileReader.EventType');\ngoog.provide('goog.fs.FileReader.ReadyState');\n\ngoog.require('goog.async.Deferred');\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.fs.Error');\ngoog.require('goog.fs.ProgressEvent');\n\n\n\n/**\n * An object for monitoring the reading of files. This emits ProgressEvents of\n * the types listed in {@link goog.fs.FileReader.EventType}.\n *\n * @constructor\n * @extends {goog.events.EventTarget}\n * @final\n */\ngoog.fs.FileReader = function() {\n 'use strict';\n goog.fs.FileReader.base(this, 'constructor');\n\n /**\n * The underlying FileReader object.\n *\n * @type {!FileReader}\n * @private\n */\n this.reader_ = new FileReader();\n\n this.reader_.onloadstart = goog.bind(this.dispatchProgressEvent_, this);\n this.reader_.onprogress = goog.bind(this.dispatchProgressEvent_, this);\n this.reader_.onload = goog.bind(this.dispatchProgressEvent_, this);\n this.reader_.onabort = goog.bind(this.dispatchProgressEvent_, this);\n this.reader_.onerror = goog.bind(this.dispatchProgressEvent_, this);\n this.reader_.onloadend = goog.bind(this.dispatchProgressEvent_, this);\n};\ngoog.inherits(goog.fs.FileReader, goog.events.EventTarget);\n\n\n/**\n * Possible states for a FileReader.\n *\n * @enum {number}\n */\ngoog.fs.FileReader.ReadyState = {\n /**\n * The object has been constructed, but there is no pending read.\n */\n INIT: 0,\n /**\n * Data is being read.\n */\n LOADING: 1,\n /**\n * The data has been read from the file, the read was aborted, or an error\n * occurred.\n */\n DONE: 2\n};\n\n\n/**\n * Events emitted by a FileReader.\n *\n * @enum {string}\n */\ngoog.fs.FileReader.EventType = {\n /**\n * Emitted when the reading begins. readyState will be LOADING.\n */\n LOAD_START: 'loadstart',\n /**\n * Emitted when progress has been made in reading the file. readyState will be\n * LOADING.\n */\n PROGRESS: 'progress',\n /**\n * Emitted when the data has been successfully read. readyState will be\n * LOADING.\n */\n LOAD: 'load',\n /**\n * Emitted when the reading has been aborted. readyState will be LOADING.\n */\n ABORT: 'abort',\n /**\n * Emitted when an error is encountered or the reading has been aborted.\n * readyState will be LOADING.\n */\n ERROR: 'error',\n /**\n * Emitted when the reading is finished, whether successfully or not.\n * readyState will be DONE.\n */\n LOAD_END: 'loadend'\n};\n\n\n/**\n * Abort the reading of the file.\n */\ngoog.fs.FileReader.prototype.abort = function() {\n 'use strict';\n try {\n this.reader_.abort();\n } catch (e) {\n throw new goog.fs.Error(e, 'aborting read');\n }\n};\n\n\n/**\n * @return {goog.fs.FileReader.ReadyState} The current state of the FileReader.\n */\ngoog.fs.FileReader.prototype.getReadyState = function() {\n 'use strict';\n return /** @type {goog.fs.FileReader.ReadyState} */ (this.reader_.readyState);\n};\n\n\n/**\n * @return {*} The result of the file read.\n */\ngoog.fs.FileReader.prototype.getResult = function() {\n 'use strict';\n return this.reader_.result;\n};\n\n\n/**\n * @return {goog.fs.Error} The error encountered while reading, if any.\n */\ngoog.fs.FileReader.prototype.getError = function() {\n 'use strict';\n return this.reader_.error &&\n new goog.fs.Error(this.reader_.error, 'reading file');\n};\n\n\n/**\n * Wrap a progress event emitted by the underlying file reader and re-emit it.\n *\n * @param {!ProgressEvent} event The underlying event.\n * @private\n */\ngoog.fs.FileReader.prototype.dispatchProgressEvent_ = function(event) {\n 'use strict';\n this.dispatchEvent(new goog.fs.ProgressEvent(event, this));\n};\n\n\n/** @override */\ngoog.fs.FileReader.prototype.disposeInternal = function() {\n 'use strict';\n goog.fs.FileReader.base(this, 'disposeInternal');\n delete this.reader_;\n};\n\n\n/**\n * Starts reading a blob as a binary string.\n * @param {!Blob} blob The blob to read.\n */\ngoog.fs.FileReader.prototype.readAsBinaryString = function(blob) {\n 'use strict';\n this.reader_.readAsBinaryString(blob);\n};\n\n\n/**\n * Reads a blob as a binary string.\n * @param {!Blob} blob The blob to read.\n * @return {!goog.async.Deferred} The deferred Blob contents as a binary string.\n * If an error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.FileReader.readAsBinaryString = function(blob) {\n 'use strict';\n const reader = new goog.fs.FileReader();\n const d = goog.fs.FileReader.createDeferred_(reader);\n reader.readAsBinaryString(blob);\n return d;\n};\n\n\n/**\n * Starts reading a blob as an array buffer.\n * @param {!Blob} blob The blob to read.\n */\ngoog.fs.FileReader.prototype.readAsArrayBuffer = function(blob) {\n 'use strict';\n this.reader_.readAsArrayBuffer(blob);\n};\n\n\n/**\n * Reads a blob as an array buffer.\n * @param {!Blob} blob The blob to read.\n * @return {!goog.async.Deferred} The deferred Blob contents as an array buffer.\n * If an error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.FileReader.readAsArrayBuffer = function(blob) {\n 'use strict';\n const reader = new goog.fs.FileReader();\n const d = goog.fs.FileReader.createDeferred_(reader);\n reader.readAsArrayBuffer(blob);\n return d;\n};\n\n\n/**\n * Starts reading a blob as text.\n * @param {!Blob} blob The blob to read.\n * @param {string=} opt_encoding The name of the encoding to use.\n */\ngoog.fs.FileReader.prototype.readAsText = function(blob, opt_encoding) {\n 'use strict';\n this.reader_.readAsText(blob, opt_encoding);\n};\n\n\n/**\n * Reads a blob as text.\n * @param {!Blob} blob The blob to read.\n * @param {string=} opt_encoding The name of the encoding to use.\n * @return {!goog.async.Deferred} The deferred Blob contents as text.\n * If an error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.FileReader.readAsText = function(blob, opt_encoding) {\n 'use strict';\n const reader = new goog.fs.FileReader();\n const d = goog.fs.FileReader.createDeferred_(reader);\n reader.readAsText(blob, opt_encoding);\n return d;\n};\n\n\n/**\n * Starts reading a blob as a data URL.\n * @param {!Blob} blob The blob to read.\n */\ngoog.fs.FileReader.prototype.readAsDataUrl = function(blob) {\n 'use strict';\n this.reader_.readAsDataURL(blob);\n};\n\n\n/**\n * Reads a blob as a data URL.\n * @param {!Blob} blob The blob to read.\n * @return {!goog.async.Deferred} The deferred Blob contents as a data URL.\n * If an error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.FileReader.readAsDataUrl = function(blob) {\n 'use strict';\n const reader = new goog.fs.FileReader();\n const d = goog.fs.FileReader.createDeferred_(reader);\n reader.readAsDataUrl(blob);\n return d;\n};\n\n\n/**\n * Creates a new deferred object for the results of a read method.\n * @param {goog.fs.FileReader} reader The reader to create a deferred for.\n * @return {!goog.async.Deferred} The deferred results.\n * @private\n */\ngoog.fs.FileReader.createDeferred_ = function(reader) {\n 'use strict';\n const deferred = new goog.async.Deferred();\n reader.listen(\n goog.fs.FileReader.EventType.LOAD_END, goog.partial(function(d, r, e) {\n 'use strict';\n const result = r.getResult();\n const error = r.getError();\n if (result != null && !error) {\n d.callback(result);\n } else {\n d.errback(error);\n }\n r.dispose();\n }, deferred, reader));\n return deferred;\n};\n","^<",1684857788697,"^=",["^3",["^=>","^>","^3[","^42","^FT"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^=>","^3[","^42","^FT"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.FileReader","goog.fs.FileReader.EventType","goog.fs.FileReader.ReadyState"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.async.Deferred","goog.events.EventTarget","goog.fs.Error","goog.fs.ProgressEvent"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/filereader.js"],"^[",["^3",["^=9","^F[","^=G"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^42","^3[","^=>","^FT"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.fs.DirectoryEntry.Behavior","^=I","^=J","^=K"]],"^5","goog.fs.entry.js","^6",["^7","goog/fs/entry.js"],"^8","goog/fs/entry.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Wrappers for HTML5 Entry objects. These are all in the same\n * file to avoid circular dependency issues.\n *\n * When adding or modifying functionality in this namespace, be sure to update\n * the mock counterparts in goog.testing.fs.\n */\ngoog.provide('goog.fs.DirectoryEntry');\ngoog.provide('goog.fs.DirectoryEntry.Behavior');\ngoog.provide('goog.fs.Entry');\ngoog.provide('goog.fs.FileEntry');\n\ngoog.requireType('goog.async.Deferred');\ngoog.requireType('goog.fs.FileSystem');\ngoog.requireType('goog.fs.FileWriter');\n\n\n\n/**\n * The interface for entries in the filesystem.\n * @interface\n */\ngoog.fs.Entry = function() {};\n\n\n/**\n * @return {boolean} Whether or not this entry is a file.\n */\ngoog.fs.Entry.prototype.isFile = function() {};\n\n\n/**\n * @return {boolean} Whether or not this entry is a directory.\n */\ngoog.fs.Entry.prototype.isDirectory = function() {};\n\n\n/**\n * @return {string} The name of this entry.\n */\ngoog.fs.Entry.prototype.getName = function() {};\n\n\n/**\n * @return {string} The full path to this entry.\n */\ngoog.fs.Entry.prototype.getFullPath = function() {};\n\n\n/**\n * @return {!goog.fs.FileSystem} The filesystem backing this entry.\n */\ngoog.fs.Entry.prototype.getFileSystem = function() {};\n\n\n/**\n * Retrieves the last modified date for this entry.\n *\n * @return {!goog.async.Deferred} The deferred Date for this entry. If an error\n * occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.Entry.prototype.getLastModified = function() {};\n\n\n/**\n * Retrieves the metadata for this entry.\n *\n * @return {!goog.async.Deferred} The deferred Metadata for this entry. If an\n * error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.Entry.prototype.getMetadata = function() {};\n\n\n/**\n * Move this entry to a new location.\n *\n * @param {!goog.fs.DirectoryEntry} parent The new parent directory.\n * @param {string=} opt_newName The new name of the entry. If omitted, the entry\n * retains its original name.\n * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileEntry} or\n * {@link goog.fs.DirectoryEntry} for the new entry. If an error occurs, the\n * errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.Entry.prototype.moveTo = function(parent, opt_newName) {};\n\n\n/**\n * Copy this entry to a new location.\n *\n * @param {!goog.fs.DirectoryEntry} parent The new parent directory.\n * @param {string=} opt_newName The name of the new entry. If omitted, the new\n * entry has the same name as the original.\n * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileEntry} or\n * {@link goog.fs.DirectoryEntry} for the new entry. If an error occurs, the\n * errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.Entry.prototype.copyTo = function(parent, opt_newName) {};\n\n\n/**\n * Wrap an HTML5 entry object in an appropriate subclass instance.\n *\n * @param {!Entry} entry The underlying Entry object.\n * @return {!goog.fs.Entry} The appropriate subclass wrapper.\n * @protected\n */\ngoog.fs.Entry.prototype.wrapEntry = function(entry) {};\n\n\n/**\n * Get the URL for this file.\n *\n * @param {string=} opt_mimeType The MIME type that will be served for the URL.\n * @return {string} The URL.\n */\ngoog.fs.Entry.prototype.toUrl = function(opt_mimeType) {};\n\n\n/**\n * Get the URI for this file.\n *\n * @deprecated Use {@link #toUrl} instead.\n * @param {string=} opt_mimeType The MIME type that will be served for the URI.\n * @return {string} The URI.\n */\ngoog.fs.Entry.prototype.toUri = function(opt_mimeType) {};\n\n\n/**\n * Remove this entry.\n *\n * @return {!goog.async.Deferred} A deferred object. If the removal succeeds,\n * the callback is called with true. If an error occurs, the errback is\n * called a {@link goog.fs.Error}.\n */\ngoog.fs.Entry.prototype.remove = function() {};\n\n\n/**\n * Gets the parent directory.\n *\n * @return {!goog.async.Deferred} The deferred {@link goog.fs.DirectoryEntry}.\n * If an error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.Entry.prototype.getParent = function() {};\n\n\n\n/**\n * A directory in a local FileSystem.\n *\n * @interface\n * @extends {goog.fs.Entry}\n */\ngoog.fs.DirectoryEntry = function() {};\n\n\n/**\n * Behaviors for getting files and directories.\n * @enum {number}\n */\ngoog.fs.DirectoryEntry.Behavior = {\n /**\n * Get the file if it exists, error out if it doesn't.\n */\n DEFAULT: 1,\n /**\n * Get the file if it exists, create it if it doesn't.\n */\n CREATE: 2,\n /**\n * Error out if the file exists, create it if it doesn't.\n */\n CREATE_EXCLUSIVE: 3\n};\n\n\n/**\n * Get a file in the directory.\n *\n * @param {string} path The path to the file, relative to this directory.\n * @param {goog.fs.DirectoryEntry.Behavior=} opt_behavior The behavior for\n * handling an existing file, or the lack thereof.\n * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileEntry}. If an\n * error occurs, the errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.DirectoryEntry.prototype.getFile = function(path, opt_behavior) {};\n\n\n/**\n * Get a directory within this directory.\n *\n * @param {string} path The path to the directory, relative to this directory.\n * @param {goog.fs.DirectoryEntry.Behavior=} opt_behavior The behavior for\n * handling an existing directory, or the lack thereof.\n * @return {!goog.async.Deferred} The deferred {@link goog.fs.DirectoryEntry}.\n * If an error occurs, the errback is called a {@link goog.fs.Error}.\n */\ngoog.fs.DirectoryEntry.prototype.getDirectory = function(path, opt_behavior) {};\n\n\n/**\n * Opens the directory for the specified path, creating the directory and any\n * intermediate directories as necessary.\n *\n * @param {string} path The directory path to create. May be absolute or\n * relative to the current directory. The parent directory \"..\" and current\n * directory \".\" are supported.\n * @return {!goog.async.Deferred} A deferred {@link goog.fs.DirectoryEntry} for\n * the requested path. If an error occurs, the errback is called with a\n * {@link goog.fs.Error}.\n */\ngoog.fs.DirectoryEntry.prototype.createPath = function(path) {};\n\n\n/**\n * Gets a list of all entries in this directory.\n *\n * @return {!goog.async.Deferred} The deferred list of {@link goog.fs.Entry}\n * results. If an error occurs, the errback is called with a\n * {@link goog.fs.Error}.\n */\ngoog.fs.DirectoryEntry.prototype.listDirectory = function() {};\n\n\n/**\n * Removes this directory and all its contents.\n *\n * @return {!goog.async.Deferred} A deferred object. If the removal succeeds,\n * the callback is called with true. If an error occurs, the errback is\n * called a {@link goog.fs.Error}.\n */\ngoog.fs.DirectoryEntry.prototype.removeRecursively = function() {};\n\n\n\n/**\n * A file in a local filesystem.\n *\n * @interface\n * @extends {goog.fs.Entry}\n */\ngoog.fs.FileEntry = function() {};\n\n\n/**\n * Create a writer for writing to the file.\n *\n * @return {!goog.async.Deferred} If an error occurs, the\n * errback is called with a {@link goog.fs.Error}.\n */\ngoog.fs.FileEntry.prototype.createWriter = function() {};\n\n\n/**\n * Get the file contents as a File blob.\n *\n * @return {!goog.async.Deferred} If an error occurs, the errback is\n * called with a {@link goog.fs.Error}.\n */\ngoog.fs.FileEntry.prototype.file = function() {};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.DirectoryEntry","goog.fs.DirectoryEntry.Behavior","goog.fs.Entry","goog.fs.FileEntry"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",[],"^W",["goog.async.Deferred","goog.fs.FileSystem","goog.fs.FileWriter"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/entry.js"],"^[",["^3",["^G0","^=I","^=J","^=K"]],"^W",["^3",["^FW","^=7","^42"]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^=<","^=:","~$goog.fs.FileSaver.ReadyState"]],"^5","goog.fs.filesaver.js","^6",["^7","goog/fs/filesaver.js"],"^8","goog/fs/filesaver.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A wrapper for the HTML5 FileSaver object.\n */\n\ngoog.provide('goog.fs.FileSaver');\ngoog.provide('goog.fs.FileSaver.EventType');\ngoog.provide('goog.fs.FileSaver.ReadyState');\n\ngoog.require('goog.events.EventTarget');\ngoog.require('goog.fs.Error');\ngoog.require('goog.fs.ProgressEvent');\n\n\n\n/**\n * An object for monitoring the saving of files. This emits ProgressEvents of\n * the types listed in {@link goog.fs.FileSaver.EventType}.\n *\n * This should not be instantiated directly. Instead, its subclass\n * {@link goog.fs.FileWriter} should be accessed via\n * {@link goog.fs.FileEntry#createWriter}.\n *\n * @param {!FileSaver} fileSaver The underlying FileSaver object.\n * @constructor\n * @extends {goog.events.EventTarget}\n */\ngoog.fs.FileSaver = function(fileSaver) {\n 'use strict';\n goog.fs.FileSaver.base(this, 'constructor');\n\n /**\n * The underlying FileSaver object.\n *\n * @type {!FileSaver}\n * @private\n */\n this.saver_ = fileSaver;\n\n this.saver_.onwritestart = goog.bind(this.dispatchProgressEvent_, this);\n this.saver_.onprogress = goog.bind(this.dispatchProgressEvent_, this);\n this.saver_.onwrite = goog.bind(this.dispatchProgressEvent_, this);\n this.saver_.onabort = goog.bind(this.dispatchProgressEvent_, this);\n this.saver_.onerror = goog.bind(this.dispatchProgressEvent_, this);\n this.saver_.onwriteend = goog.bind(this.dispatchProgressEvent_, this);\n};\ngoog.inherits(goog.fs.FileSaver, goog.events.EventTarget);\n\n\n/**\n * Possible states for a FileSaver.\n *\n * @enum {number}\n */\ngoog.fs.FileSaver.ReadyState = {\n /**\n * The object has been constructed, but there is no pending write.\n */\n INIT: 0,\n /**\n * Data is being written.\n */\n WRITING: 1,\n /**\n * The data has been written to the file, the write was aborted, or an error\n * occurred.\n */\n DONE: 2\n};\n\n\n/**\n * Events emitted by a FileSaver.\n *\n * @enum {string}\n */\ngoog.fs.FileSaver.EventType = {\n /**\n * Emitted when the writing begins. readyState will be WRITING.\n */\n WRITE_START: 'writestart',\n /**\n * Emitted when progress has been made in saving the file. readyState will be\n * WRITING.\n */\n PROGRESS: 'progress',\n /**\n * Emitted when the data has been successfully written. readyState will be\n * WRITING.\n */\n WRITE: 'write',\n /**\n * Emitted when the writing has been aborted. readyState will be WRITING.\n */\n ABORT: 'abort',\n /**\n * Emitted when an error is encountered or the writing has been aborted.\n * readyState will be WRITING.\n */\n ERROR: 'error',\n /**\n * Emitted when the writing is finished, whether successfully or not.\n * readyState will be DONE.\n */\n WRITE_END: 'writeend'\n};\n\n\n/**\n * Abort the writing of the file.\n */\ngoog.fs.FileSaver.prototype.abort = function() {\n 'use strict';\n try {\n this.saver_.abort();\n } catch (e) {\n throw new goog.fs.Error(e, 'aborting save');\n }\n};\n\n\n/**\n * @return {goog.fs.FileSaver.ReadyState} The current state of the FileSaver.\n */\ngoog.fs.FileSaver.prototype.getReadyState = function() {\n 'use strict';\n return /** @type {goog.fs.FileSaver.ReadyState} */ (this.saver_.readyState);\n};\n\n\n/**\n * @return {goog.fs.Error} The error encountered while writing, if any.\n */\ngoog.fs.FileSaver.prototype.getError = function() {\n 'use strict';\n return this.saver_.error &&\n new goog.fs.Error(this.saver_.error, 'saving file');\n};\n\n\n/**\n * Wrap a progress event emitted by the underlying file saver and re-emit it.\n *\n * @param {!ProgressEvent} event The underlying event.\n * @private\n */\ngoog.fs.FileSaver.prototype.dispatchProgressEvent_ = function(event) {\n 'use strict';\n this.dispatchEvent(new goog.fs.ProgressEvent(event, this));\n};\n\n\n/** @override */\ngoog.fs.FileSaver.prototype.disposeInternal = function() {\n 'use strict';\n delete this.saver_;\n goog.fs.FileSaver.base(this, 'disposeInternal');\n};\n","^<",1684857788697,"^=",["^3",["^=>","^>","^3[","^FT"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^=>","^3[","^FT"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.fs.FileSaver","goog.fs.FileSaver.EventType","goog.fs.FileSaver.ReadyState"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.events.EventTarget","goog.fs.Error","goog.fs.ProgressEvent"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/fs/filesaver.js"],"^[",["^3",["^=<","^=:","^G1"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^3[","^=>","^FT"]],["^ ","^O",[["^ ","^6L","fs","^6M",1280,"^6N",false],["^ ","^6L","path","^6M",1306,"^6N",false],["^ ","^6L","vm","^6M",1332,"^6N",false]],"^\n * require('./bootstrap/nodejs')\n * goog.require('goog.ui.Component')\n * \n *\n * This loads goog.ui.Component in the global scope.\n *\n * If you want to load custom libraries, you can require the custom deps file\n * directly. If your custom libraries introduce new globals, you may\n * need to run goog.nodeGlobalRequire to get them to load correctly.\n *\n * \n * require('./path/to/my/deps.js')\n * goog.bootstrap.nodeJs.nodeGlobalRequire('./path/to/my/base.js')\n * goog.require('my.Class')\n * \n *\n * @nocompile\n */\n\n\nvar fs = require('fs');\nvar path = require('path');\nvar vm = require('vm');\n\n\n/**\n * The goog namespace in the global scope.\n */\nglobal.goog = {};\n\n\n/**\n * Imports a script using Node's require() API.\n *\n * @param {string} src The script source.\n * @param {string=} opt_sourceText The optional source text to evaluate.\n * @return {boolean} True if the script was imported, false otherwise.\n */\nglobal.CLOSURE_IMPORT_SCRIPT = function(src, opt_sourceText) {\n // Sources are always expressed relative to closure's base.js, but\n // require() is always relative to the current source.\n if (opt_sourceText === undefined) {\n require('./../' + src);\n } else {\n eval(opt_sourceText);\n }\n return true;\n};\n\n\n/**\n * Loads a file when using Closure's goog.require() API with goog.modules.\n *\n * @param {string} src The file source.\n * @return {string} The file contents.\n */\nglobal.CLOSURE_LOAD_FILE_SYNC = function(src) {\n return fs.readFileSync(\n path.resolve(__dirname, '..', src), {encoding: 'utf-8'});\n};\n\n\n// Declared here so it can be used to require base.js\nfunction nodeGlobalRequire(file) {\n vm.runInThisContext.call(global, fs.readFileSync(file), file);\n}\n\n\n// Load Closure's base.js into memory. It is assumed base.js is in the\n// directory above this directory given this script's location in\n// bootstrap/nodejs.js.\nnodeGlobalRequire(path.resolve(__dirname, '..', 'base.js'));\n\n\n/**\n * Bootstraps a file into the global scope.\n *\n * This is strictly for cases where normal require() won't work,\n * because the file declares global symbols with 'var' that need to\n * be added to the global scope.\n *\n * @param {string} file The path to the file.\n */\ngoog.nodeGlobalRequire = nodeGlobalRequire;\n","^<",1684857788697,"^=",["^3",[]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",[],"^N",["^ ","^O",[["^ ","^6L","fs","^6M",1280,"^6N",false],["^ ","^6L","path","^6M",1306,"^6N",false],["^ ","^6L","vm","^6M",1332,"^6N",false]],"^P",false,"^Q",[],"^R",[["^ ","^2B",63,"^2C",4]],"^2",[],"^S","es3","^T",null,"^U",false,"^V",["fs","path","vm"],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/bootstrap/nodejs.js"],"^[",["^3",["^G2"]],"^W",[],"^X",false,"^10",true,"^12",["fs","path","vm"],"^Y",false],["^ ","^O",[],"^"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es3","^T","goog.dispose","^U",true,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/disposable/dispose.js"],"^[",["^3",["^5S"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.disposeAll","^1Y","^CJ","^U",true,"^5","goog.disposable.disposeall.js","^6",["^7","goog/disposable/disposeall.js"],"^8","goog/disposable/disposeall.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The disposeAll method is used to clean up references and\n * resources.\n */\n\ngoog.module('goog.disposeAll');\ngoog.module.declareLegacyNamespace();\n\nconst dispose = goog.require('goog.dispose');\n\n/**\n * Calls `dispose` on each member of the list that supports it. (If the\n * member is an ArrayLike, then `goog.disposeAll()` will be called\n * recursively on each of its members.) If the member is not an object with a\n * `dispose()` method, then it is ignored.\n * @param {...*} var_args The list.\n */\nfunction disposeAll(var_args) {\n for (let i = 0, len = arguments.length; i < len; ++i) {\n const disposable = arguments[i];\n if (goog.isArrayLike(disposable)) {\n disposeAll.apply(null, disposable);\n } else {\n dispose(disposable);\n }\n }\n}\nexports = disposeAll;\n","^<",1684857788697,"^=",["^3",["^>","^5S"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^5S"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.disposeAll","^U",true,"^V",[],"^M",["goog.dispose"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/disposable/disposeall.js"],"^[",["^3",["^CJ"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^5S"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.disposable.IDisposable"]],"^5","goog.disposable.idisposable.js","^6",["^7","goog/disposable/idisposable.js"],"^8","goog/disposable/idisposable.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of the disposable interface. A disposable object\n * has a dispose method to to clean up references and resources.\n */\n\n\ngoog.provide('goog.disposable.IDisposable');\n\n\n\n/**\n * Interface for a disposable object. If a instance requires cleanup, it should\n * implement this interface (it may subclass goog.Disposable).\n *\n * Examples of cleanup that can be done in `dispose` method:\n * 1. Remove event listeners.\n * 2. Cancel timers (setTimeout, setInterval, goog.Timer).\n * 3. Call `dispose` on other disposable objects hold by current object.\n * 4. Close connections (e.g. WebSockets).\n *\n * Note that it's not required to delete properties (e.g. DOM nodes) or set them\n * to null as garbage collector will collect them assuming that references to\n * current object will be lost after it is disposed.\n *\n * See also http://go/mdn/JavaScript/Memory_Management.\n *\n * @record\n */\ngoog.disposable.IDisposable = function() {};\n\n\n/**\n * Disposes of the object and its resources.\n * @return {void} Nothing.\n */\ngoog.disposable.IDisposable.prototype.dispose = goog.abstractMethod;\n\n\n/**\n * @return {boolean} Whether the object has been disposed of.\n */\ngoog.disposable.IDisposable.prototype.isDisposed = goog.abstractMethod;\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.disposable.IDisposable"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/disposable/idisposable.js"],"^[",["^3",["^G4"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^1X"]],"^5","goog.disposable.disposable.js","^6",["^7","goog/disposable/disposable.js"],"^8","goog/disposable/disposable.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implements the disposable interface.\n */\n\ngoog.provide('goog.Disposable');\n\ngoog.require('goog.disposable.IDisposable');\ngoog.require('goog.dispose');\n/**\n * TODO(user): Remove this require.\n * @suppress {extraRequire}\n */\ngoog.require('goog.disposeAll');\n\n/**\n * Class that provides the basic implementation for disposable objects. If your\n * class holds references or resources that can't be collected by standard GC,\n * it should extend this class or implement the disposable interface (defined\n * in goog.disposable.IDisposable). See description of\n * goog.disposable.IDisposable for examples of cleanup.\n * @constructor\n * @implements {goog.disposable.IDisposable}\n */\ngoog.Disposable = function() {\n 'use strict';\n /**\n * If monitoring the goog.Disposable instances is enabled, stores the creation\n * stack trace of the Disposable instance.\n * @type {string|undefined}\n */\n this.creationStack;\n\n if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {\n if (goog.Disposable.INCLUDE_STACK_ON_CREATION) {\n this.creationStack = new Error().stack;\n }\n goog.Disposable.instances_[goog.getUid(this)] = this;\n }\n // Support sealing\n this.disposed_ = this.disposed_;\n this.onDisposeCallbacks_ = this.onDisposeCallbacks_;\n};\n\n\n/**\n * @enum {number} Different monitoring modes for Disposable.\n */\ngoog.Disposable.MonitoringMode = {\n /**\n * No monitoring.\n */\n OFF: 0,\n /**\n * Creating and disposing the goog.Disposable instances is monitored. All\n * disposable objects need to call the `goog.Disposable` base\n * constructor. The PERMANENT mode must be switched on before creating any\n * goog.Disposable instances.\n */\n PERMANENT: 1,\n /**\n * INTERACTIVE mode can be switched on and off on the fly without producing\n * errors. It also doesn't warn if the disposable objects don't call the\n * `goog.Disposable` base constructor.\n */\n INTERACTIVE: 2\n};\n\n\n/**\n * @define {number} The monitoring mode of the goog.Disposable\n * instances. Default is OFF. Switching on the monitoring is only\n * recommended for debugging because it has a significant impact on\n * performance and memory usage. If switched off, the monitoring code\n * compiles down to 0 bytes.\n */\ngoog.Disposable.MONITORING_MODE =\n goog.define('goog.Disposable.MONITORING_MODE', 0);\n\n\n/**\n * @define {boolean} Whether to attach creation stack to each created disposable\n * instance; This is only relevant for when MonitoringMode != OFF.\n */\ngoog.Disposable.INCLUDE_STACK_ON_CREATION =\n goog.define('goog.Disposable.INCLUDE_STACK_ON_CREATION', true);\n\n\n/**\n * Maps the unique ID of every undisposed `goog.Disposable` object to\n * the object itself.\n * @type {!Object}\n * @private\n */\ngoog.Disposable.instances_ = {};\n\n\n/**\n * @return {!Array} All `goog.Disposable` objects that\n * haven't been disposed of.\n */\ngoog.Disposable.getUndisposedObjects = function() {\n 'use strict';\n var ret = [];\n for (var id in goog.Disposable.instances_) {\n if (goog.Disposable.instances_.hasOwnProperty(id)) {\n ret.push(goog.Disposable.instances_[Number(id)]);\n }\n }\n return ret;\n};\n\n\n/**\n * Clears the registry of undisposed objects but doesn't dispose of them.\n */\ngoog.Disposable.clearUndisposedObjects = function() {\n 'use strict';\n goog.Disposable.instances_ = {};\n};\n\n\n/**\n * Whether the object has been disposed of.\n * @type {boolean}\n * @private\n */\ngoog.Disposable.prototype.disposed_ = false;\n\n\n/**\n * Callbacks to invoke when this object is disposed.\n * @type {Array}\n * @private\n */\ngoog.Disposable.prototype.onDisposeCallbacks_;\n\n\n/**\n * @return {boolean} Whether the object has been disposed of.\n * @override\n */\ngoog.Disposable.prototype.isDisposed = function() {\n 'use strict';\n return this.disposed_;\n};\n\n\n/**\n * @return {boolean} Whether the object has been disposed of.\n * @deprecated Use {@link #isDisposed} instead.\n */\ngoog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed;\n\n\n/**\n * Disposes of the object. If the object hasn't already been disposed of, calls\n * {@link #disposeInternal}. Classes that extend `goog.Disposable` should\n * override {@link #disposeInternal} in order to cleanup references, resources\n * and other disposable objects. Reentrant.\n *\n * @return {void} Nothing.\n * @override\n */\ngoog.Disposable.prototype.dispose = function() {\n 'use strict';\n if (!this.disposed_) {\n // Set disposed_ to true first, in case during the chain of disposal this\n // gets disposed recursively.\n this.disposed_ = true;\n this.disposeInternal();\n if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {\n var uid = goog.getUid(this);\n if (goog.Disposable.MONITORING_MODE ==\n goog.Disposable.MonitoringMode.PERMANENT &&\n !goog.Disposable.instances_.hasOwnProperty(uid)) {\n throw new Error(\n this + ' did not call the goog.Disposable base ' +\n 'constructor or was disposed of after a clearUndisposedObjects ' +\n 'call');\n }\n if (goog.Disposable.MONITORING_MODE !=\n goog.Disposable.MonitoringMode.OFF &&\n this.onDisposeCallbacks_ && this.onDisposeCallbacks_.length > 0) {\n throw new Error(\n this + ' did not empty its onDisposeCallbacks queue. This ' +\n 'probably means it overrode dispose() or disposeInternal() ' +\n 'without calling the superclass\\' method.');\n }\n delete goog.Disposable.instances_[uid];\n }\n }\n};\n\n\n/**\n * Associates a disposable object with this object so that they will be disposed\n * together.\n * @param {goog.disposable.IDisposable} disposable that will be disposed when\n * this object is disposed.\n */\ngoog.Disposable.prototype.registerDisposable = function(disposable) {\n 'use strict';\n this.addOnDisposeCallback(goog.partial(goog.dispose, disposable));\n};\n\n\n/**\n * Invokes a callback function when this object is disposed. Callbacks are\n * invoked in the order in which they were added. If a callback is added to\n * an already disposed Disposable, it will be called immediately.\n * @param {function(this:T):?} callback The callback function.\n * @param {T=} opt_scope An optional scope to call the callback in.\n * @template T\n */\ngoog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) {\n 'use strict';\n if (this.disposed_) {\n opt_scope !== undefined ? callback.call(opt_scope) : callback();\n return;\n }\n if (!this.onDisposeCallbacks_) {\n this.onDisposeCallbacks_ = [];\n }\n\n this.onDisposeCallbacks_.push(\n opt_scope !== undefined ? goog.bind(callback, opt_scope) : callback);\n};\n\n\n/**\n * Performs appropriate cleanup. See description of goog.disposable.IDisposable\n * for examples. Classes that extend `goog.Disposable` should override this\n * method. Not reentrant. To avoid calling it twice, it must only be called from\n * the subclass' `disposeInternal` method. Everywhere else the public `dispose`\n * method must be used. For example:\n *\n *
\n * mypackage.MyClass = function() {\n * mypackage.MyClass.base(this, 'constructor');\n *     // Constructor logic specific to MyClass.\n *     ...\n *   };\n *   goog.inherits(mypackage.MyClass, goog.Disposable);\n *\n *   mypackage.MyClass.prototype.disposeInternal = function() {\n *     // Dispose logic specific to MyClass.\n *     ...\n *     // Call superclass's disposeInternal at the end of the subclass's, like\n *     // in C++, to avoid hard-to-catch issues.\n *     mypackage.MyClass.base(this, 'disposeInternal');\n *   };\n * 
\n *\n * @protected\n */\ngoog.Disposable.prototype.disposeInternal = function() {\n 'use strict';\n if (this.onDisposeCallbacks_) {\n while (this.onDisposeCallbacks_.length) {\n this.onDisposeCallbacks_.shift()();\n }\n }\n};\n\n\n/**\n * Returns True if we can verify the object is disposed.\n * Calls `isDisposed` on the argument if it supports it. If obj\n * is not an object with an isDisposed() method, return false.\n * @param {*} obj The object to investigate.\n * @return {boolean} True if we can verify the object is disposed.\n */\ngoog.Disposable.isDisposed = function(obj) {\n 'use strict';\n if (obj && typeof obj.isDisposed == 'function') {\n return obj.isDisposed();\n }\n return false;\n};\n","^<",1684857788697,"^=",["^3",["^>","^CJ","^G4","^5S"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^CJ","^G4","^5S"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.Disposable"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.disposable.IDisposable","goog.dispose","goog.disposeAll"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/disposable/disposable.js"],"^[",["^3",["^1X"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^G4","^5S","^CJ"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.RespondingChannel"]],"^5","goog.messaging.respondingchannel.js","^6",["^7","goog/messaging/respondingchannel.js"],"^8","goog/messaging/respondingchannel.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of goog.messaging.RespondingChannel, which wraps a\n * MessageChannel and allows the user to get the response from the services.\n */\n\n\ngoog.provide('goog.messaging.RespondingChannel');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.Promise');\ngoog.require('goog.dispose');\ngoog.require('goog.log');\ngoog.require('goog.messaging.MultiChannel');\ngoog.requireType('goog.messaging.MessageChannel');\n\n\n\n/**\n * Creates a new RespondingChannel wrapping a single MessageChannel.\n * @param {goog.messaging.MessageChannel} messageChannel The messageChannel to\n * to wrap and allow for responses. This channel must not have any existing\n * services registered. All service registration must be done through the\n * {@link RespondingChannel#registerService} api instead. The other end of\n * channel must also be a RespondingChannel.\n * @constructor\n * @extends {goog.Disposable}\n */\ngoog.messaging.RespondingChannel = function(messageChannel) {\n 'use strict';\n goog.messaging.RespondingChannel.base(this, 'constructor');\n\n /**\n * The message channel wrapped in a MultiChannel so we can send private and\n * public messages on it.\n * @type {goog.messaging.MultiChannel}\n * @private\n */\n this.messageChannel_ = new goog.messaging.MultiChannel(messageChannel);\n\n /**\n * Map of invocation signatures to function callbacks. These are used to keep\n * track of the asyncronous service invocations so the result of a service\n * call can be passed back to a callback in the calling frame.\n * @type {Object}\n * @private\n */\n this.sigCallbackMap_ = {};\n\n /**\n * The virtual channel to send private messages on.\n * @type {goog.messaging.MultiChannel.VirtualChannel}\n * @private\n */\n this.privateChannel_ = this.messageChannel_.createVirtualChannel(\n goog.messaging.RespondingChannel.PRIVATE_CHANNEL_);\n\n /**\n * The virtual channel to send public messages on.\n * @type {goog.messaging.MultiChannel.VirtualChannel}\n * @private\n */\n this.publicChannel_ = this.messageChannel_.createVirtualChannel(\n goog.messaging.RespondingChannel.PUBLIC_CHANNEL_);\n\n this.privateChannel_.registerService(\n goog.messaging.RespondingChannel.CALLBACK_SERVICE_,\n goog.bind(this.callbackServiceHandler_, this), true);\n};\ngoog.inherits(goog.messaging.RespondingChannel, goog.Disposable);\n\n\n/**\n * The name of the method invocation callback service (used internally).\n * @type {string}\n * @const\n * @private\n */\ngoog.messaging.RespondingChannel.CALLBACK_SERVICE_ = 'mics';\n\n\n/**\n * The name of the channel to send private control messages on.\n * @type {string}\n * @const\n * @private\n */\ngoog.messaging.RespondingChannel.PRIVATE_CHANNEL_ = 'private';\n\n\n/**\n * The name of the channel to send public messages on.\n * @type {string}\n * @const\n * @private\n */\ngoog.messaging.RespondingChannel.PUBLIC_CHANNEL_ = 'public';\n\n\n/**\n * The next signature index to save the callback against.\n * @type {number}\n * @private\n */\ngoog.messaging.RespondingChannel.prototype.nextSignatureIndex_ = 0;\n\n\n/**\n * Logger object for goog.messaging.RespondingChannel.\n * @type {goog.log.Logger}\n * @private\n */\ngoog.messaging.RespondingChannel.prototype.logger_ =\n goog.log.getLogger('goog.messaging.RespondingChannel');\n\n\n/**\n * Gets a random number to use for method invocation results.\n * @return {number} A unique random signature.\n * @private\n */\ngoog.messaging.RespondingChannel.prototype.getNextSignature_ = function() {\n 'use strict';\n return this.nextSignatureIndex_++;\n};\n\n\n/** @override */\ngoog.messaging.RespondingChannel.prototype.disposeInternal = function() {\n 'use strict';\n goog.dispose(this.messageChannel_);\n delete this.messageChannel_;\n // Note: this.publicChannel_ and this.privateChannel_ get disposed by\n // this.messageChannel_\n delete this.publicChannel_;\n delete this.privateChannel_;\n};\n\n\n/**\n * Sends a message over the channel.\n * @param {string} serviceName The name of the service this message should be\n * delivered to.\n * @param {string|!Object} payload The value of the message. If this is an\n * Object, it is serialized to a string before sending if necessary.\n * @param {function(?Object)} callback The callback invoked with\n * the result of the service call.\n */\ngoog.messaging.RespondingChannel.prototype.send = function(\n serviceName, payload, callback) {\n 'use strict';\n const signature = this.getNextSignature_();\n this.sigCallbackMap_[signature] = callback;\n\n const message = {};\n message['signature'] = signature;\n message['data'] = payload;\n\n this.publicChannel_.send(serviceName, message);\n};\n\n\n/**\n * Receives the results of the peer's service results.\n * @param {!Object|string} message The results from the remote service\n * invocation.\n * @private\n */\ngoog.messaging.RespondingChannel.prototype.callbackServiceHandler_ = function(\n message) {\n 'use strict';\n const signature = message['signature'];\n const result = message['data'];\n\n if (signature in this.sigCallbackMap_) {\n const callback =\n /** @type {function(Object)} */ (this.sigCallbackMap_[signature]);\n callback(result);\n delete this.sigCallbackMap_[signature];\n } else {\n goog.log.warning(this.logger_, 'Received signature is invalid');\n }\n};\n\n\n/**\n * Registers a service to be called when a message is received.\n * @param {string} serviceName The name of the service.\n * @param {function(!Object)} callback The callback to process the\n * incoming messages. Passed the payload.\n */\ngoog.messaging.RespondingChannel.prototype.registerService = function(\n serviceName, callback) {\n 'use strict';\n this.publicChannel_.registerService(\n serviceName, goog.bind(this.callbackProxy_, this, callback), true);\n};\n\n\n/**\n * A intermediary proxy for service callbacks to be invoked and return their\n * their results to the remote caller's callback.\n * @param {function((string|!Object))} callback The callback to process the\n * incoming messages. Passed the payload.\n * @param {!Object|string} message The message containing the signature and\n * the data to invoke the service callback with.\n * @private\n */\ngoog.messaging.RespondingChannel.prototype.callbackProxy_ = function(\n callback, message) {\n 'use strict';\n const response = callback(message['data']);\n const signature = message['signature'];\n goog.Promise.resolve(response).then(goog.bind(function(result) {\n 'use strict';\n this.sendResponse_(result, signature);\n }, this));\n};\n\n\n/**\n * Sends the results of the service callback to the remote caller's callback.\n * @param {(string|!Object)} result The results of the service callback.\n * @param {string} signature The signature of the request to the service\n * callback.\n * @private\n */\ngoog.messaging.RespondingChannel.prototype.sendResponse_ = function(\n result, signature) {\n 'use strict';\n const resultMessage = {};\n resultMessage['data'] = result;\n resultMessage['signature'] = signature;\n // The callback invoked above may have disposed the channel so check if it\n // exists.\n if (this.privateChannel_) {\n this.privateChannel_.send(\n goog.messaging.RespondingChannel.CALLBACK_SERVICE_, resultMessage);\n }\n};\n","^<",1684857788697,"^=",["^3",["^>","^3X","^6K","^1X","^5S","~$goog.messaging.MultiChannel"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^3X","^6K","^1X","^5S","^G6"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.RespondingChannel"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.Promise","goog.dispose","goog.log","goog.messaging.MultiChannel"],"^W",["goog.messaging.MessageChannel"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/respondingchannel.js"],"^[",["^3",["^G5"]],"^W",["^3",["~$goog.messaging.MessageChannel"]],"^10",true,"^11",true,"^12",["^>","^1X","^6K","^5S","^3X","^G6"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.PortChannel"]],"^5","goog.messaging.portchannel.js","^6",["^7","goog/messaging/portchannel.js"],"^8","goog/messaging/portchannel.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A class that wraps several types of HTML5 message-passing\n * entities ({@link MessagePort}s, {@link Worker}s, and {@link Window}s),\n * providing a unified interface.\n *\n * This is tested under Chrome, Safari, and Firefox. Since Firefox 3.6 has an\n * incomplete implementation of web workers, it doesn't support sending ports\n * over Window connections. IE has no web worker support at all, and so is\n * unsupported by this class.\n */\n\ngoog.provide('goog.messaging.PortChannel');\n\ngoog.require('goog.Timer');\ngoog.require('goog.async.Deferred');\ngoog.require('goog.debug');\ngoog.require('goog.dispose');\ngoog.require('goog.events');\ngoog.require('goog.events.EventType');\ngoog.require('goog.json');\ngoog.require('goog.log');\ngoog.require('goog.messaging.AbstractChannel');\ngoog.require('goog.messaging.DeferredChannel');\ngoog.require('goog.object');\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\ngoog.requireType('goog.events.Event');\ngoog.requireType('goog.messaging.MessageChannel');\n\n\n\n/**\n * A wrapper for several types of HTML5 message-passing entities\n * ({@link MessagePort}s and {@link Worker}s). This class implements the\n * {@link goog.messaging.MessageChannel} interface.\n *\n * This class can be used in conjunction with other communication on the port.\n * It sets {@link goog.messaging.PortChannel.FLAG} to true on all messages it\n * sends.\n *\n * @param {!MessagePort|!Worker} underlyingPort The message-passing\n * entity to wrap. If this is a {@link MessagePort}, it should be started.\n * The remote end should also be wrapped in a PortChannel. This will be\n * disposed along with the PortChannel; this means terminating it if it's a\n * worker or removing it from the DOM if it's an iframe.\n * @constructor\n * @extends {goog.messaging.AbstractChannel}\n * @final\n */\ngoog.messaging.PortChannel = function(underlyingPort) {\n 'use strict';\n goog.messaging.PortChannel.base(this, 'constructor');\n\n /**\n * The wrapped message-passing entity.\n * @type {!MessagePort|!Worker}\n * @private\n */\n this.port_ = underlyingPort;\n\n /**\n * The key for the event listener.\n * @type {goog.events.Key}\n * @private\n */\n this.listenerKey_ = goog.events.listen(\n this.port_, goog.events.EventType.MESSAGE, this.deliver_, false, this);\n};\ngoog.inherits(goog.messaging.PortChannel, goog.messaging.AbstractChannel);\n\n\n/**\n * Create a PortChannel that communicates with a window embedded in the current\n * page (e.g. an iframe contentWindow). The code within the window should call\n * {@link forGlobalWindow} to establish the connection.\n *\n * It's possible to use this channel in conjunction with other messages to the\n * embedded window. However, only one PortChannel should be used for a given\n * window at a time.\n *\n * @param {!Window} peerWindow The window object to communicate with.\n * @param {string} peerOrigin The expected origin of the window. See\n * http://dev.w3.org/html5/postmsg/#dom-window-postmessage.\n * @param {goog.Timer=} opt_timer The timer that regulates how often the initial\n * connection message is attempted. This will be automatically disposed once\n * the connection is established, or when the connection is cancelled.\n * @return {!goog.messaging.DeferredChannel} The PortChannel. Although this is\n * not actually an instance of the PortChannel class, it will behave like\n * one in that MessagePorts may be sent across it. The DeferredChannel may\n * be cancelled before a connection is established in order to abort the\n * attempt to make a connection.\n */\ngoog.messaging.PortChannel.forEmbeddedWindow = function(\n peerWindow, peerOrigin, opt_timer) {\n 'use strict';\n if (peerOrigin == '*') {\n return new goog.messaging.DeferredChannel(\n goog.async.Deferred.fail(new Error('Invalid origin')));\n }\n\n const timer = opt_timer || new goog.Timer(50);\n\n const disposeTimer = goog.partial(goog.dispose, timer);\n const deferred = new goog.async.Deferred(disposeTimer);\n deferred.addBoth(disposeTimer);\n\n timer.start();\n // Every tick, attempt to set up a connection by sending in one end of an\n // HTML5 MessageChannel. If the inner window posts a response along a channel,\n // then we'll use that channel to create the PortChannel.\n //\n // As per http://dev.w3.org/html5/postmsg/#ports-and-garbage-collection, any\n // ports that are not ultimately used to set up the channel will be garbage\n // collected (since there are no references in this context, and the remote\n // context hasn't seen them).\n goog.events.listen(timer, goog.Timer.TICK, function() {\n 'use strict';\n const channel = new MessageChannel();\n const gotMessage = function(e) {\n 'use strict';\n channel.port1.removeEventListener(\n goog.events.EventType.MESSAGE, gotMessage, true);\n // If the connection has been cancelled, don't create the channel.\n if (!timer.isDisposed()) {\n deferred.callback(new goog.messaging.PortChannel(channel.port1));\n }\n };\n channel.port1.start();\n // Don't use goog.events because we don't want any lingering references to\n // the ports to prevent them from getting GCed. Only modern browsers support\n // these APIs anyway, so we don't need to worry about event API\n // compatibility.\n channel.port1.addEventListener(\n goog.events.EventType.MESSAGE, gotMessage, true);\n\n const msg = {};\n msg[goog.messaging.PortChannel.FLAG] = true;\n peerWindow.postMessage(msg, peerOrigin, [channel.port2]);\n });\n\n return new goog.messaging.DeferredChannel(deferred);\n};\n\n\n/**\n * Create a PortChannel that communicates with the document in which this window\n * is embedded (e.g. within an iframe). The enclosing document should call\n * {@link forEmbeddedWindow} to establish the connection.\n *\n * It's possible to use this channel in conjunction with other messages posted\n * to the global window. However, only one PortChannel should be used for the\n * global window at a time.\n *\n * @param {string} peerOrigin The expected origin of the enclosing document. See\n * http://dev.w3.org/html5/postmsg/#dom-window-postmessage.\n * @return {!goog.messaging.MessageChannel} The PortChannel. Although this may\n * not actually be an instance of the PortChannel class, it will behave like\n * one in that MessagePorts may be sent across it.\n */\ngoog.messaging.PortChannel.forGlobalWindow = function(peerOrigin) {\n 'use strict';\n if (peerOrigin == '*') {\n return new goog.messaging.DeferredChannel(\n goog.async.Deferred.fail(new Error('Invalid origin')));\n }\n\n const deferred = new goog.async.Deferred();\n // Wait for the external page to post a message containing the message port\n // which we'll use to set up the PortChannel. Ignore all other messages. Once\n // we receive the port, notify the other end and then set up the PortChannel.\n const key =\n goog.events.listen(window, goog.events.EventType.MESSAGE, function(e) {\n 'use strict';\n const browserEvent = e.getBrowserEvent();\n const data = browserEvent.data;\n if (!goog.isObject(data) || !data[goog.messaging.PortChannel.FLAG]) {\n return;\n }\n\n if (window.parent != browserEvent.source ||\n peerOrigin != browserEvent.origin) {\n return;\n }\n\n const port = browserEvent.ports[0];\n // Notify the other end of the channel that we've received our port\n port.postMessage({});\n\n port.start();\n deferred.callback(new goog.messaging.PortChannel(port));\n goog.events.unlistenByKey(key);\n });\n return new goog.messaging.DeferredChannel(deferred);\n};\n\n\n/**\n * The flag added to messages that are sent by a PortChannel, and are meant to\n * be handled by one on the other side.\n * @type {string}\n */\ngoog.messaging.PortChannel.FLAG = '--goog.messaging.PortChannel';\n\n\n/**\n * Whether the messages sent across the channel must be JSON-serialized. This is\n * required for older versions of Webkit, which can only send string messages.\n *\n * Although Safari and Chrome have separate implementations of message passing,\n * both of them support passing objects by Webkit 533.\n *\n * @type {boolean}\n * @private\n */\ngoog.messaging.PortChannel.REQUIRES_SERIALIZATION_ = goog.userAgent.WEBKIT &&\n goog.string.compareVersions(goog.userAgent.VERSION, '533') < 0;\n\n\n/**\n * Logger for this class.\n * @type {goog.log.Logger}\n * @protected\n * @override\n */\ngoog.messaging.PortChannel.prototype.logger =\n goog.log.getLogger('goog.messaging.PortChannel');\n\n\n/**\n * Sends a message over the channel.\n *\n * As an addition to the basic MessageChannel send API, PortChannels can send\n * objects that contain MessagePorts. Note that only plain Objects and Arrays,\n * not their subclasses, can contain MessagePorts.\n *\n * As per {@link http://www.w3.org/TR/html5/comms.html#clone-a-port}, once a\n * port is copied to be sent across a channel, the original port will cease\n * being able to send or receive messages.\n *\n * @override\n * @param {string} serviceName The name of the service this message should be\n * delivered to.\n * @param {string|!Object|!MessagePort} payload The value of the message. May\n * contain MessagePorts or be a MessagePort.\n */\ngoog.messaging.PortChannel.prototype.send = function(serviceName, payload) {\n 'use strict';\n const ports = [];\n payload = this.extractPorts_(ports, payload);\n let message = {'serviceName': serviceName, 'payload': payload};\n message[goog.messaging.PortChannel.FLAG] = true;\n\n if (goog.messaging.PortChannel.REQUIRES_SERIALIZATION_) {\n message = goog.json.serialize(message);\n }\n\n // Avoid a type error by casting to unknown as the type checker doesn't\n // know which variant we are calling here.\n this.port_.postMessage(/** @type {?} */ (message), ports);\n};\n\n\n/**\n * Delivers a message to the appropriate service handler. If this message isn't\n * a GearsWorkerChannel message, it's ignored and passed on to other handlers.\n *\n * @param {goog.events.Event} e The event.\n * @private\n */\ngoog.messaging.PortChannel.prototype.deliver_ = function(e) {\n 'use strict';\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n const browserEvent = e.getBrowserEvent();\n let data = browserEvent.data;\n\n if (goog.messaging.PortChannel.REQUIRES_SERIALIZATION_) {\n try {\n data = JSON.parse(data);\n } catch (error) {\n // Ignore any non-JSON messages.\n return;\n }\n }\n\n if (!goog.isObject(data) || !data[goog.messaging.PortChannel.FLAG]) {\n return;\n }\n\n if (this.validateMessage_(data)) {\n const serviceName = data['serviceName'];\n let payload = data['payload'];\n const service = this.getService(serviceName, payload);\n if (!service) {\n return;\n }\n\n payload = this.decodePayload(\n serviceName, this.injectPorts_(browserEvent.ports || [], payload),\n service.objectPayload);\n if (payload != null) {\n service.callback(payload);\n }\n }\n};\n\n\n/**\n * Checks whether the message is invalid in some way.\n *\n * @param {Object} data The contents of the message.\n * @return {boolean} True if the message is valid, false otherwise.\n * @private\n */\ngoog.messaging.PortChannel.prototype.validateMessage_ = function(data) {\n 'use strict';\n if (!('serviceName' in data)) {\n goog.log.warning(\n this.logger,\n 'Message object doesn\\'t contain service name: ' +\n goog.debug.deepExpose(data));\n return false;\n }\n\n if (!('payload' in data)) {\n goog.log.warning(\n this.logger,\n 'Message object doesn\\'t contain payload: ' +\n goog.debug.deepExpose(data));\n return false;\n }\n\n return true;\n};\n\n\n/**\n * Extracts all MessagePort objects from a message to be sent into an array.\n *\n * The message ports are replaced by placeholder objects that will be replaced\n * with the ports again on the other side of the channel.\n *\n * @param {Array} ports The array that will contain ports\n * extracted from the message. Will be destructively modified. Should be\n * empty initially.\n * @param {string|!Object} message The message from which ports will be\n * extracted.\n * @return {string|!Object} The message with ports extracted.\n * @private\n */\ngoog.messaging.PortChannel.prototype.extractPorts_ = function(ports, message) {\n 'use strict';\n // Can't use instanceof here because MessagePort is undefined in workers\n if (message &&\n Object.prototype.toString.call(/** @type {!Object} */ (message)) ==\n '[object MessagePort]') {\n ports.push(/** @type {MessagePort} */ (message));\n return {'_port': {'type': 'real', 'index': ports.length - 1}};\n } else if (Array.isArray(message)) {\n return message.map(goog.bind(this.extractPorts_, this, ports));\n // We want to compare the exact constructor here because we only want to\n // recurse into object literals, not native objects like Date.\n } else if (message && message.constructor == Object) {\n return goog.object.map(\n /** @type {!Object} */ (message), function(val, key) {\n 'use strict';\n val = this.extractPorts_(ports, val);\n return key == '_port' ? {'type': 'escaped', 'val': val} : val;\n }, this);\n } else {\n return message;\n }\n};\n\n\n/**\n * Injects MessagePorts back into a message received from across the channel.\n *\n * @param {Array} ports The array of ports to be injected into the\n * message.\n * @param {string|!Object} message The message into which the ports will be\n * injected.\n * @return {string|!Object} The message with ports injected.\n * @private\n */\ngoog.messaging.PortChannel.prototype.injectPorts_ = function(ports, message) {\n 'use strict';\n if (Array.isArray(message)) {\n return message.map(goog.bind(this.injectPorts_, this, ports));\n } else if (message && message.constructor == Object) {\n message = /** @type {!Object} */ (message);\n if (message['_port'] && message['_port']['type'] == 'real') {\n return /** @type {!MessagePort} */ (ports[message['_port']['index']]);\n }\n return goog.object.map(message, function(val, key) {\n 'use strict';\n return this.injectPorts_(ports, key == '_port' ? val['val'] : val);\n }, this);\n } else {\n return message;\n }\n};\n\n\n/**\n * @override\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.messaging.PortChannel.prototype.disposeInternal = function() {\n 'use strict';\n goog.events.unlistenByKey(this.listenerKey_);\n // Can't use instanceof here because MessagePort is undefined in workers and\n // in Firefox\n if (Object.prototype.toString.call(this.port_) == '[object MessagePort]') {\n this.port_.close();\n // Worker is undefined in workers as well as of Chrome 9\n } else if (Object.prototype.toString.call(this.port_) == '[object Worker]') {\n this.port_.terminate();\n }\n delete this.port_;\n goog.messaging.PortChannel.base(this, 'disposeInternal');\n};\n","^<",1684857788697,"^=",["^3",["^=Z","^1W","^2K","^2L","~$goog.messaging.DeferredChannel","^>","^2F","^2T","^3X","^4N","^40","^42","^5S","^23"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^=Z","^1W","^2K","^2L","^G9","^2F","^2T","^3X","^4N","^40","^42","^5S","^23"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.PortChannel"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.Timer","goog.async.Deferred","goog.debug","goog.dispose","goog.events","goog.events.EventType","goog.json","goog.log","goog.messaging.AbstractChannel","goog.messaging.DeferredChannel","goog.object","goog.string","goog.userAgent"],"^W",["goog.events.Event","goog.messaging.MessageChannel"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/portchannel.js"],"^[",["^3",["^G8"]],"^W",["^3",["^G7","^4<"]],"^10",true,"^11",true,"^12",["^>","^1W","^42","^40","^5S","^23","^4N","^2K","^3X","^=Z","^G9","^2F","^2L","^2T"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^G7"]],"^5","goog.messaging.messagechannel.js","^6",["^7","goog/messaging/messagechannel.js"],"^8","goog/messaging/messagechannel.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An interface for asynchronous message-passing channels.\n *\n * This interface is useful for writing code in a message-passing style that's\n * independent of the underlying communication medium. It's also useful for\n * adding decorators that wrap message channels and add extra functionality on\n * top. For example, {@link goog.messaging.BufferedChannel} enqueues messages\n * until communication is established, while {@link goog.messaging.MultiChannel}\n * splits a single underlying channel into multiple virtual ones.\n *\n * Decorators should be passed their underlying channel(s) in the constructor,\n * and should assume that those channels are already connected. Decorators are\n * responsible for disposing of the channels they wrap when the decorators\n * themselves are disposed. Decorators should also follow the APIs of the\n * individual methods listed below.\n */\n\n\ngoog.provide('goog.messaging.MessageChannel');\n\n\n\n/**\n * @interface\n */\ngoog.messaging.MessageChannel = function() {};\n\n\n/**\n * Initiates the channel connection. When this method is called, all the\n * information needed to connect the channel has to be available.\n *\n * Implementers should only require this method to be called if the channel\n * needs to be configured in some way between when it's created and when it\n * becomes active. Otherwise, the channel should be immediately active and this\n * method should do nothing but immediately call opt_connectCb.\n *\n * @param {Function=} opt_connectCb Called when the channel has been connected\n * and is ready to use.\n */\ngoog.messaging.MessageChannel.prototype.connect = function(opt_connectCb) {};\n\n\n/**\n * Gets whether the channel is connected.\n *\n * If {@link #connect} is not required for this class, this should always return\n * true. Otherwise, this should return true by the time the callback passed to\n * {@link #connect} has been called and always after that.\n *\n * @return {boolean} Whether the channel is connected.\n */\ngoog.messaging.MessageChannel.prototype.isConnected = function() {};\n\n\n/**\n * Registers a service to be called when a message is received.\n *\n * Implementers shouldn't impose any restrictions on the service names that may\n * be registered. If some services are needed as control codes,\n * {@link goog.messaging.MultiMessageChannel} can be used to safely split the\n * channel into \"public\" and \"control\" virtual channels.\n *\n * @param {string} serviceName The name of the service.\n * @param {function((string|!Object))} callback The callback to process the\n * incoming messages. Passed the payload. If opt_objectPayload is set, the\n * payload is decoded and passed as an object.\n * @param {boolean=} opt_objectPayload If true, incoming messages for this\n * service are expected to contain an object, and will be deserialized from\n * a string automatically if necessary. It's the responsibility of\n * implementors of this class to perform the deserialization.\n */\ngoog.messaging.MessageChannel.prototype.registerService = function(\n serviceName, callback, opt_objectPayload) {};\n\n\n/**\n * Registers a service to be called when a message is received that doesn't\n * match any other services.\n *\n * @param {function(string, (string|!Object))} callback The callback to process\n * the incoming messages. Passed the service name and the payload. Since\n * some channels can pass objects natively, the payload may be either an\n * object or a string.\n */\ngoog.messaging.MessageChannel.prototype.registerDefaultService = function(\n callback) {};\n\n\n/**\n * Sends a message over the channel.\n *\n * @param {string} serviceName The name of the service this message should be\n * delivered to.\n * @param {string|!Object} payload The value of the message. If this is an\n * Object, it is serialized to a string before sending if necessary. It's\n * the responsibility of implementors of this class to perform the\n * serialization.\n */\ngoog.messaging.MessageChannel.prototype.send = function(serviceName, payload) {\n};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.MessageChannel"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/messagechannel.js"],"^[",["^3",["^G7"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.messaging.LoggerServer","^1Y","~$goog.messaging.LoggerServer","^U",true,"^5","goog.messaging.loggerserver.js","^6",["^7","goog/messaging/loggerserver.js"],"^8","goog/messaging/loggerserver.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview This class listens on a message channel for logger commands and\n * logs them on the local page. This is useful when dealing with message\n * channels to contexts that don't have access to their own logging facilities.\n */\n\ngoog.module('goog.messaging.LoggerServer');\ngoog.module.declareLegacyNamespace();\n\nconst Disposable = goog.require('goog.Disposable');\nconst Level = goog.require('goog.log.Level');\nconst MessageChannel = goog.requireType('goog.messaging.MessageChannel');\nconst log = goog.require('goog.log');\n\n/**\n * A logger server that logs messages on behalf of the remote end of a\n * message channel. The remote end of the channel should use a\n * {LoggerClient} with the same service name.\n * @final\n */\nclass LoggerServer extends Disposable {\n /**\n * Creates a LoggerServer instance.\n *\n * @param {!MessageChannel} channel The channel that is sending\n * the log messages.\n * @param {string} serviceName The name of the logging service to listen for.\n * @param {string=} channelName The name of this channel. Used to help\n * distinguish this client's messages.\n */\n constructor(channel, serviceName, channelName) {\n super();\n\n /**\n * The channel that is sending the log messages.\n * @type {!MessageChannel}\n * @private\n */\n this.channel_ = channel;\n\n /**\n * The name of the logging service to listen for.\n * @type {string}\n * @private\n */\n this.serviceName_ = serviceName;\n\n /**\n * The name of the channel.\n * @type {string}\n * @private\n */\n this.channelName_ = channelName || 'remote logger';\n\n this.channel_.registerService(\n this.serviceName_, this.log_.bind(this), true /* opt_json */);\n }\n\n /**\n * Handles logging messages from the client.\n * @param {!Object|string} message\n * The logging information from the client.\n * @private\n */\n log_(message) {\n const args =\n /**\n * @type {{level: number, message: string,\n * name: string, exception: Object}}\n */\n (message);\n const level = Level.getPredefinedLevelByValue(args['level']);\n if (level) {\n const msg = '[' + this.channelName_ + '] ' + args['message'];\n log.log(log.getLogger(args['name']), level, msg, args['exception']);\n }\n }\n\n /** @override */\n disposeInternal() {\n super.disposeInternal();\n this.channel_.registerService(this.serviceName_, () => {}, true);\n delete this.channel_;\n }\n}\nexports = LoggerServer;\n","^<",1684857788697,"^=",["^3",["^?3","^>","^3X","^1X"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^?3","^3X","^1X"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.messaging.LoggerServer","^U",true,"^V",[],"^M",["goog.Disposable","goog.log.Level","goog.log"],"^W",["goog.messaging.MessageChannel"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/loggerserver.js"],"^[",["^3",["^G:"]],"^W",["^3",["^G7"]],"^10",true,"^11",true,"^12",["^>","^1X","^?3","^3X"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^G9"]],"^5","goog.messaging.deferredchannel.js","^6",["^7","goog/messaging/deferredchannel.js"],"^8","goog/messaging/deferredchannel.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A MessageChannel decorator that wraps a deferred MessageChannel\n * and enqueues messages and service registrations until that channel exists.\n */\n\ngoog.provide('goog.messaging.DeferredChannel');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.messaging.MessageChannel');\ngoog.requireType('goog.async.Deferred');\n\n\n/**\n * Creates a new DeferredChannel, which wraps a deferred MessageChannel and\n * enqueues messages to be sent once the wrapped channel is resolved.\n *\n * @param {!goog.async.Deferred} deferredChannel\n * The underlying deferred MessageChannel.\n * @constructor\n * @extends {goog.Disposable}\n * @implements {goog.messaging.MessageChannel}\n * @final\n */\ngoog.messaging.DeferredChannel = function(deferredChannel) {\n 'use strict';\n goog.messaging.DeferredChannel.base(this, 'constructor');\n\n /** @private {!goog.async.Deferred} */\n this.deferred_ = deferredChannel;\n};\ngoog.inherits(goog.messaging.DeferredChannel, goog.Disposable);\n\n\n/**\n * Cancels the wrapped Deferred.\n */\ngoog.messaging.DeferredChannel.prototype.cancel = function() {\n 'use strict';\n this.deferred_.cancel();\n};\n\n\n/** @override */\ngoog.messaging.DeferredChannel.prototype.connect = function(opt_connectCb) {\n 'use strict';\n if (opt_connectCb) {\n opt_connectCb();\n }\n};\n\n\n/** @override */\ngoog.messaging.DeferredChannel.prototype.isConnected = function() {\n 'use strict';\n return true;\n};\n\n\n/** @override */\ngoog.messaging.DeferredChannel.prototype.registerService = function(\n serviceName, callback, opt_objectPayload) {\n 'use strict';\n this.deferred_.addCallback(function(resolved) {\n 'use strict';\n resolved.registerService(serviceName, callback, opt_objectPayload);\n });\n};\n\n\n/** @override */\ngoog.messaging.DeferredChannel.prototype.registerDefaultService = function(\n callback) {\n 'use strict';\n this.deferred_.addCallback(function(resolved) {\n 'use strict';\n resolved.registerDefaultService(callback);\n });\n};\n\n\n/** @override */\ngoog.messaging.DeferredChannel.prototype.send = function(serviceName, payload) {\n 'use strict';\n this.deferred_.addCallback(function(resolved) {\n 'use strict';\n resolved.send(serviceName, payload);\n });\n};\n\n\n/** @override */\ngoog.messaging.DeferredChannel.prototype.disposeInternal = function() {\n 'use strict';\n this.cancel();\n goog.messaging.DeferredChannel.base(this, 'disposeInternal');\n};\n","^<",1684857788697,"^=",["^3",["^G7","^>","^1X"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^G7","^1X"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.DeferredChannel"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.messaging.MessageChannel"],"^W",["goog.async.Deferred"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/deferredchannel.js"],"^[",["^3",["^G9"]],"^W",["^3",["^42"]],"^10",true,"^11",true,"^12",["^>","^1X","^G7"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging"]],"^5","goog.messaging.messaging.js","^6",["^7","goog/messaging/messaging.js"],"^8","goog/messaging/messaging.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Functions for manipulating message channels.\n */\n\ngoog.provide('goog.messaging');\n\ngoog.requireType('goog.messaging.MessageChannel');\n\n\n/**\n * Creates a bidirectional pipe between two message channels.\n *\n * @param {goog.messaging.MessageChannel} channel1 The first channel.\n * @param {goog.messaging.MessageChannel} channel2 The second channel.\n */\ngoog.messaging.pipe = function(channel1, channel2) {\n 'use strict';\n channel1.registerDefaultService(goog.bind(channel2.send, channel2));\n channel2.registerDefaultService(goog.bind(channel1.send, channel1));\n};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",[],"^W",["goog.messaging.MessageChannel"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/messaging.js"],"^[",["^3",["^G;"]],"^W",["^3",["^G7"]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.testdata.portchannel-worker"]],"^5","goog.messaging.testdata.portchannel_worker.js","^6",["^7","goog/messaging/testdata/portchannel_worker.js"],"^8","goog/messaging/testdata/portchannel_worker.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// Use of this source code is governed by the Apache License, Version 2.0.\n// See the COPYING file for details.\n\n/**\n * @fileoverview A web worker for integration testing the PortChannel class.\n *\n * @nocompile\n */\n\nself.CLOSURE_BASE_PATH =\nself.CLOSURE_BASE_PATH = '../../';\nimportScripts('../../bootstrap/webworkers.js');\nimportScripts('../../base.js');\n\n// The provide is necessary to stop the jscompiler from thinking this is an\n// entry point and adding it into the manifest incorrectly.\ngoog.provide('goog.messaging.testdata.portchannel_worker');\ngoog.require('goog.messaging.PortChannel');\n\nfunction registerPing(channel) {\n channel.registerService('ping', function(msg) {\n 'use strict';\n channel.send('pong', msg);\n }, true);\n}\n\nfunction startListening() {\n const channel = new goog.messaging.PortChannel(self);\n registerPing(channel);\n\n channel.registerService('addPort', function(port) {\n 'use strict';\n port.start();\n registerPing(new goog.messaging.PortChannel(port));\n }, true);\n}\n\nstartListening();\n// Signal to portchannel_test that the worker is ready.\npostMessage('loaded');\n","^<",1684857788697,"^=",["^3",["^G8","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^G8"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.testdata.portchannel_worker"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.messaging.PortChannel"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/testdata/portchannel_worker.js"],"^[",["^3",["^G<","~$goog.messaging.testdata.portchannel_worker"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^G8"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.testdata.portnetwork-worker1"]],"^5","goog.messaging.testdata.portnetwork_worker1.js","^6",["^7","goog/messaging/testdata/portnetwork_worker1.js"],"^8","goog/messaging/testdata/portnetwork_worker1.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// Use of this source code is governed by the Apache License, Version 2.0.\n// See the COPYING file for details.\n\n/**\n * @fileoverview A web worker for integration testing the PortPool class.\n *\n * @nocompile\n */\n\nself.CLOSURE_BASE_PATH =\nself.CLOSURE_BASE_PATH = '../../';\nimportScripts('../../bootstrap/webworkers.js');\nimportScripts('../../base.js');\n\n// The provide is necessary to stop the jscompiler from thinking this is an\n// entry point and adding it into the manifest incorrectly.\ngoog.provide('goog.messaging.testdata.portnetwork_worker1');\ngoog.require('goog.messaging.PortCaller');\ngoog.require('goog.messaging.PortChannel');\n\nfunction startListening() {\n const caller =\n new goog.messaging.PortCaller(new goog.messaging.PortChannel(self));\n\n caller.dial('frame').registerService('sendToMain', function(msg) {\n 'use strict';\n msg.push('worker1');\n caller.dial('main').send('result', msg);\n }, true);\n}\n\nstartListening();\n","^<",1684857788697,"^=",["^3",["~$goog.messaging.PortCaller","^G8","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^G?","^G8"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.testdata.portnetwork_worker1"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.messaging.PortCaller","goog.messaging.PortChannel"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/testdata/portnetwork_worker1.js"],"^[",["^3",["~$goog.messaging.testdata.portnetwork_worker1","^G>"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^G?","^G8"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.testdata.portnetwork-worker2"]],"^5","goog.messaging.testdata.portnetwork_worker2.js","^6",["^7","goog/messaging/testdata/portnetwork_worker2.js"],"^8","goog/messaging/testdata/portnetwork_worker2.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// Use of this source code is governed by the Apache License, Version 2.0.\n// See the COPYING file for details.\n\n/**\n * @fileoverview A web worker for integration testing the PortPool class.\n *\n * @nocompile\n */\n\nself.CLOSURE_BASE_PATH =\nself.CLOSURE_BASE_PATH = '../../';\nimportScripts('../../bootstrap/webworkers.js');\nimportScripts('../../base.js');\n\n// The provide is necessary to stop the jscompiler from thinking this is an\n// entry point and adding it into the manifest incorrectly.\ngoog.provide('goog.messaging.testdata.portnetwork_worker2');\ngoog.require('goog.messaging.PortCaller');\ngoog.require('goog.messaging.PortChannel');\n\nfunction startListening() {\n const caller =\n new goog.messaging.PortCaller(new goog.messaging.PortChannel(self));\n\n caller.dial('main').registerService('sendToFrame', function(msg) {\n 'use strict';\n msg.push('worker2');\n caller.dial('frame').send('sendToWorker1', msg);\n }, true);\n}\n\nstartListening();\n","^<",1684857788697,"^=",["^3",["^G?","^G8","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^G?","^G8"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.testdata.portnetwork_worker2"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.messaging.PortCaller","goog.messaging.PortChannel"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/testdata/portnetwork_worker2.js"],"^[",["^3",["^GA","~$goog.messaging.testdata.portnetwork_worker2"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^G?","^G8"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.LoggerClient"]],"^5","goog.messaging.loggerclient.js","^6",["^7","goog/messaging/loggerclient.js"],"^8","goog/messaging/loggerclient.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview This class sends logging messages over a message channel to a\n * server on the main page that prints them using standard logging mechanisms.\n */\n\ngoog.provide('goog.messaging.LoggerClient');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.debug');\ngoog.require('goog.log');\ngoog.requireType('goog.messaging.MessageChannel');\n\n\n/**\n * Creates a logger client that sends messages along a message channel for the\n * remote end to log. The remote end of the channel should use a\n * {goog.messaging.LoggerServer} with the same service name.\n *\n * @param {!goog.messaging.MessageChannel} channel The channel that on which to\n * send the log messages.\n * @param {string} serviceName The name of the logging service to use.\n * @constructor\n * @extends {goog.Disposable}\n * @final\n */\ngoog.messaging.LoggerClient = function(channel, serviceName) {\n 'use strict';\n if (goog.messaging.LoggerClient.instance_) {\n return goog.messaging.LoggerClient.instance_;\n }\n\n goog.messaging.LoggerClient.base(this, 'constructor');\n\n /**\n * The channel on which to send the log messages.\n * @type {!goog.messaging.MessageChannel}\n * @private\n */\n this.channel_ = channel;\n\n /**\n * The name of the logging service to use.\n * @type {string}\n * @private\n */\n this.serviceName_ = serviceName;\n\n /**\n * The bound handler function for handling log messages. This is kept in a\n * variable so that it can be deregistered when the logger client is disposed.\n * @type {!Function}\n * @private\n */\n this.publishHandler_ = goog.bind(this.sendLog_, this);\n goog.log.addHandler(goog.log.getRootLogger(), this.publishHandler_);\n\n goog.messaging.LoggerClient.instance_ = this;\n};\ngoog.inherits(goog.messaging.LoggerClient, goog.Disposable);\n\n\n/**\n * The singleton instance, if any.\n * @type {?goog.messaging.LoggerClient}\n * @private\n */\ngoog.messaging.LoggerClient.instance_ = null;\n\n\n/**\n * Sends a log message through the channel.\n * @param {!goog.log.LogRecord} logRecord The log message.\n * @private\n */\ngoog.messaging.LoggerClient.prototype.sendLog_ = function(logRecord) {\n 'use strict';\n var name = logRecord.getLoggerName();\n var level = logRecord.getLevel();\n var msg = logRecord.getMessage();\n var originalException = logRecord.getException();\n\n var exception;\n if (originalException !== undefined) {\n var normalizedException =\n goog.debug.normalizeErrorObject(originalException);\n /** @suppress {strictMissingProperties} Added to tighten compiler checks */\n exception = {\n 'name': normalizedException.name,\n 'message': normalizedException.message,\n 'lineNumber': normalizedException.lineNumber,\n 'fileName': normalizedException.fileName,\n // Normalized exceptions without a stack have 'stack' set to 'Not\n // available', so we check for the existence of 'stack' on the original\n // exception instead.\n 'stack': originalException.stack || goog.debug.getStacktrace(goog.log.log)\n };\n\n if (goog.isObject(originalException)) {\n // Add messageN to the exception in case it was added using\n // goog.debug.enhanceError.\n for (var i = 0; 'message' + i in originalException; i++) {\n exception['message' + i] = String(originalException['message' + i]);\n }\n }\n }\n this.channel_.send(this.serviceName_, {\n 'name': name,\n 'level': level.value,\n 'message': msg,\n 'exception': exception\n });\n};\n\n\n/** @override */\ngoog.messaging.LoggerClient.prototype.disposeInternal = function() {\n 'use strict';\n goog.messaging.LoggerClient.base(this, 'disposeInternal');\n goog.log.removeHandler(goog.log.getRootLogger(), this.publishHandler_);\n delete this.channel_;\n goog.messaging.LoggerClient.instance_ = null;\n};\n","^<",1684857788697,"^=",["^3",["^>","^3X","^40","^1X"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^3X","^40","^1X"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.LoggerClient"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.debug","goog.log"],"^W",["goog.messaging.MessageChannel"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/loggerclient.js"],"^[",["^3",["^GC"]],"^W",["^3",["^G7"]],"^10",true,"^11",true,"^12",["^>","^1X","^40","^3X"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^=V"]],"^5","goog.messaging.portnetwork.js","^6",["^7","goog/messaging/portnetwork.js"],"^8","goog/messaging/portnetwork.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An interface for classes that connect a collection of HTML5\n * message-passing entities ({@link MessagePort}s, {@link Worker}s, and\n * {@link Window}s) and allow them to seamlessly communicate with one another.\n *\n * Conceptually, a PortNetwork is a collection of JS contexts, such as pages (in\n * or outside of iframes) or web workers. Each context has a unique name, and\n * each one can communicate with any of the others in the same network. This\n * communication takes place through a {@link goog.messaging.PortChannel} that\n * is retrieved via {#link goog.messaging.PortNetwork#dial}.\n *\n * One context (usually the main page) has a\n * {@link goog.messaging.PortOperator}, which is in charge of connecting each\n * context to each other context. All other contexts have\n * {@link goog.messaging.PortCaller}s which connect to the operator.\n */\n\ngoog.provide('goog.messaging.PortNetwork');\n\ngoog.requireType('goog.messaging.MessageChannel');\n\n\n/**\n * @interface\n */\ngoog.messaging.PortNetwork = function() {};\n\n\n/**\n * Returns a message channel that communicates with the named context. If no\n * such port exists, an error will either be thrown immediately or after a round\n * trip with the operator, depending on whether this pool is the operator or a\n * caller.\n *\n * If context A calls dial('B') and context B calls dial('A'), the two\n * ports returned will be connected to one another.\n *\n * @param {string} name The name of the context to get.\n * @return {goog.messaging.MessageChannel} The channel communicating with the\n * given context. This is either a {@link goog.messaging.PortChannel} or a\n * decorator around a PortChannel, so it's safe to send {@link MessagePorts}\n * across it. This will be disposed along with the PortNetwork.\n */\ngoog.messaging.PortNetwork.prototype.dial = function(name) {};\n\n\n/**\n * The name of the service exported by the operator for creating a connection\n * between two callers.\n *\n * @type {string}\n * @const\n */\ngoog.messaging.PortNetwork.REQUEST_CONNECTION_SERVICE = 'requestConnection';\n\n\n/**\n * The name of the service exported by the callers for adding a connection to\n * another context.\n *\n * @type {string}\n * @const\n */\ngoog.messaging.PortNetwork.GRANT_CONNECTION_SERVICE = 'grantConnection';\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.PortNetwork"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",[],"^W",["goog.messaging.MessageChannel"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/portnetwork.js"],"^[",["^3",["^=V"]],"^W",["^3",["^G7"]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^=Z"]],"^5","goog.messaging.abstractchannel.js","^6",["^7","goog/messaging/abstractchannel.js"],"^8","goog/messaging/abstractchannel.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview An abstract superclass for message channels that handles the\n * repetitive details of registering and dispatching to services. This is more\n * useful for full-fledged channels than for decorators, since decorators\n * generally delegate service registering anyway.\n */\n\n\ngoog.provide('goog.messaging.AbstractChannel');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.json');\ngoog.require('goog.log');\ngoog.require('goog.messaging.MessageChannel'); // interface\n\n\n\n/**\n * Creates an abstract message channel.\n *\n * @constructor\n * @extends {goog.Disposable}\n * @implements {goog.messaging.MessageChannel}\n */\ngoog.messaging.AbstractChannel = function() {\n 'use strict';\n goog.messaging.AbstractChannel.base(this, 'constructor');\n\n /**\n * The services registered for this channel.\n * @type {Object}\n * @private\n */\n this.services_ = {};\n};\ngoog.inherits(goog.messaging.AbstractChannel, goog.Disposable);\n\n\n/**\n * The default service to be run when no other services match.\n *\n * @type {?function(string, (string|!Object))}\n * @private\n */\ngoog.messaging.AbstractChannel.prototype.defaultService_;\n\n\n/**\n * Logger for this class.\n * @type {goog.log.Logger}\n * @protected\n */\ngoog.messaging.AbstractChannel.prototype.logger =\n goog.log.getLogger('goog.messaging.AbstractChannel');\n\n\n/**\n * Immediately calls opt_connectCb if given, and is otherwise a no-op. If\n * subclasses have configuration that needs to happen before the channel is\n * connected, they should override this and {@link #isConnected}.\n * @override\n */\ngoog.messaging.AbstractChannel.prototype.connect = function(opt_connectCb) {\n 'use strict';\n if (opt_connectCb) {\n opt_connectCb();\n }\n};\n\n\n/**\n * Always returns true. If subclasses have configuration that needs to happen\n * before the channel is connected, they should override this and\n * {@link #connect}.\n * @override\n */\ngoog.messaging.AbstractChannel.prototype.isConnected = function() {\n 'use strict';\n return true;\n};\n\n\n/** @override */\ngoog.messaging.AbstractChannel.prototype.registerService = function(\n serviceName, callback, opt_objectPayload) {\n 'use strict';\n this.services_[serviceName] = {\n callback: callback,\n objectPayload: !!opt_objectPayload\n };\n};\n\n\n/** @override */\ngoog.messaging.AbstractChannel.prototype.registerDefaultService = function(\n callback) {\n 'use strict';\n this.defaultService_ = callback;\n};\n\n\n/** @override */\ngoog.messaging.AbstractChannel.prototype.send = goog.abstractMethod;\n\n\n/**\n * Delivers a message to the appropriate service. This is meant to be called by\n * subclasses when they receive messages.\n *\n * This method takes into account both explicitly-registered and default\n * services, as well as making sure that JSON payloads are decoded when\n * necessary. If the subclass is capable of passing objects as payloads, those\n * objects can be passed in to this method directly. Otherwise, the (potentially\n * JSON-encoded) strings should be passed in.\n *\n * @param {string} serviceName The name of the service receiving the message.\n * @param {string|!Object} payload The contents of the message.\n * @protected\n */\ngoog.messaging.AbstractChannel.prototype.deliver = function(\n serviceName, payload) {\n 'use strict';\n const service = this.getService(serviceName, payload);\n if (!service) {\n return;\n }\n\n const decodedPayload =\n this.decodePayload(serviceName, payload, service.objectPayload);\n if (decodedPayload != null) {\n service.callback(decodedPayload);\n }\n};\n\n\n/**\n * Find the service object for a given service name. If there's no service\n * explicitly registered, but there is a default service, a service object is\n * constructed for it.\n *\n * @param {string} serviceName The name of the service receiving the message.\n * @param {string|!Object} payload The contents of the message.\n * @return {?{callback: function((string|!Object)), objectPayload: boolean}} The\n * service object for the given service, or null if none was found.\n * @protected\n */\ngoog.messaging.AbstractChannel.prototype.getService = function(\n serviceName, payload) {\n 'use strict';\n const service = this.services_[serviceName];\n if (service) {\n return service;\n } else if (this.defaultService_) {\n const callback = goog.partial(this.defaultService_, serviceName);\n const objectPayload = goog.isObject(payload);\n return {callback: callback, objectPayload: objectPayload};\n }\n\n goog.log.warning(this.logger, 'Unknown service name \"' + serviceName + '\"');\n return null;\n};\n\n\n/**\n * Converts the message payload into the format expected by the registered\n * service (either JSON or string).\n *\n * @param {string} serviceName The name of the service receiving the message.\n * @param {string|!Object} payload The contents of the message.\n * @param {boolean} objectPayload Whether the service expects an object or a\n * plain string.\n * @return {string|Object} The payload in the format expected by the service, or\n * null if something went wrong.\n * @protected\n */\ngoog.messaging.AbstractChannel.prototype.decodePayload = function(\n serviceName, payload, objectPayload) {\n 'use strict';\n if (objectPayload && typeof payload === 'string') {\n try {\n return /** @type {!Object} */ (JSON.parse(payload));\n } catch (err) {\n goog.log.warning(\n this.logger, 'Expected JSON payload for ' + serviceName + ', was \"' +\n payload + '\"');\n return null;\n }\n } else if (!objectPayload && typeof payload !== 'string') {\n return goog.json.serialize(payload);\n }\n return payload;\n};\n\n\n/** @override */\ngoog.messaging.AbstractChannel.prototype.disposeInternal = function() {\n 'use strict';\n goog.messaging.AbstractChannel.base(this, 'disposeInternal');\n delete this.services_;\n delete this.defaultService_;\n};\n","^<",1684857788697,"^=",["^3",["^2K","^G7","^>","^3X","^1X"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2K","^G7","^3X","^1X"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.AbstractChannel"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.json","goog.log","goog.messaging.MessageChannel"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/abstractchannel.js"],"^[",["^3",["^=Z"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1X","^2K","^3X","^G7"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.MultiChannel.VirtualChannel","^G6"]],"^5","goog.messaging.multichannel.js","^6",["^7","goog/messaging/multichannel.js"],"^8","goog/messaging/multichannel.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Definition of goog.messaging.MultiChannel, which uses a\n * single underlying MessageChannel to carry several independent virtual message\n * channels.\n */\n\n\ngoog.provide('goog.messaging.MultiChannel');\ngoog.provide('goog.messaging.MultiChannel.VirtualChannel');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.dispose');\ngoog.require('goog.log');\ngoog.require('goog.messaging.MessageChannel'); // interface\ngoog.require('goog.object');\n\n\n\n/**\n * Creates a new MultiChannel wrapping a single MessageChannel. The\n * underlying channel shouldn't have any other listeners registered, but it\n * should be connected.\n *\n * Note that the other side of the channel should also be connected to a\n * MultiChannel with the same number of virtual channels.\n *\n * @param {goog.messaging.MessageChannel} underlyingChannel The underlying\n * channel to use as transport for the virtual channels.\n * @constructor\n * @extends {goog.Disposable}\n * @final\n */\ngoog.messaging.MultiChannel = function(underlyingChannel) {\n 'use strict';\n goog.messaging.MultiChannel.base(this, 'constructor');\n\n /**\n * The underlying channel across which all requests are sent.\n * @type {goog.messaging.MessageChannel}\n * @private\n */\n this.underlyingChannel_ = underlyingChannel;\n\n /**\n * All the virtual channels that are registered for this MultiChannel.\n * These are null if they've been disposed.\n * @type {Object}\n * @private\n */\n this.virtualChannels_ = {};\n\n this.underlyingChannel_.registerDefaultService(\n goog.bind(this.handleDefault_, this));\n};\ngoog.inherits(goog.messaging.MultiChannel, goog.Disposable);\n\n\n/**\n * Logger object for goog.messaging.MultiChannel.\n * @type {goog.log.Logger}\n * @private\n */\ngoog.messaging.MultiChannel.prototype.logger_ =\n goog.log.getLogger('goog.messaging.MultiChannel');\n\n\n/**\n * Creates a new virtual channel that will communicate across the underlying\n * channel.\n * @param {string} name The name of the virtual channel. Must be unique for this\n * MultiChannel. Cannot contain colons.\n * @return {!goog.messaging.MultiChannel.VirtualChannel} The new virtual\n * channel.\n */\ngoog.messaging.MultiChannel.prototype.createVirtualChannel = function(name) {\n 'use strict';\n if (name.indexOf(':') != -1) {\n throw new Error(\n 'Virtual channel name \"' + name + '\" should not contain colons');\n }\n\n if (name in this.virtualChannels_) {\n throw new Error(\n 'Virtual channel \"' + name + '\" was already created for ' +\n 'this multichannel.');\n }\n\n const channel = new goog.messaging.MultiChannel.VirtualChannel(this, name);\n this.virtualChannels_[name] = channel;\n return channel;\n};\n\n\n/**\n * Handles the default service for the underlying channel. This dispatches any\n * unrecognized services to the appropriate virtual channel.\n *\n * @param {string} serviceName The name of the service being called.\n * @param {string|!Object} payload The message payload.\n * @private\n */\ngoog.messaging.MultiChannel.prototype.handleDefault_ = function(\n serviceName, payload) {\n 'use strict';\n const match = serviceName.match(/^([^:]*):(.*)/);\n if (!match) {\n goog.log.warning(\n this.logger_, 'Invalid service name \"' + serviceName + '\": no ' +\n 'virtual channel specified');\n return;\n }\n\n const channelName = match[1];\n serviceName = match[2];\n if (!(channelName in this.virtualChannels_)) {\n goog.log.warning(\n this.logger_, 'Virtual channel \"' + channelName + ' does not ' +\n 'exist, but a message was received for it: \"' + serviceName + '\"');\n return;\n }\n\n const virtualChannel = this.virtualChannels_[channelName];\n if (!virtualChannel) {\n goog.log.warning(\n this.logger_, 'Virtual channel \"' + channelName + ' has been ' +\n 'disposed, but a message was received for it: \"' + serviceName +\n '\"');\n return;\n }\n\n if (!virtualChannel.defaultService_) {\n goog.log.warning(\n this.logger_, 'Service \"' + serviceName + '\" is not registered ' +\n 'on virtual channel \"' + channelName + '\"');\n return;\n }\n\n virtualChannel.defaultService_(serviceName, payload);\n};\n\n\n/** @override */\ngoog.messaging.MultiChannel.prototype.disposeInternal = function() {\n 'use strict';\n goog.object.forEach(this.virtualChannels_, function(channel) {\n 'use strict';\n goog.dispose(channel);\n });\n goog.dispose(this.underlyingChannel_);\n delete this.virtualChannels_;\n delete this.underlyingChannel_;\n};\n\n\n\n/**\n * A message channel that proxies its messages over another underlying channel.\n *\n * @param {goog.messaging.MultiChannel} parent The MultiChannel\n * which created this channel, and which contains the underlying\n * MessageChannel that's used as the transport.\n * @param {string} name The name of this virtual channel. Unique among the\n * virtual channels in parent.\n * @constructor\n * @implements {goog.messaging.MessageChannel}\n * @extends {goog.Disposable}\n * @final\n */\ngoog.messaging.MultiChannel.VirtualChannel = function(parent, name) {\n 'use strict';\n goog.messaging.MultiChannel.VirtualChannel.base(this, 'constructor');\n\n /**\n * The MultiChannel containing the underlying transport channel.\n * @type {goog.messaging.MultiChannel}\n * @private\n */\n this.parent_ = parent;\n\n /**\n * The name of this virtual channel.\n * @type {string}\n * @private\n */\n this.name_ = name;\n};\ngoog.inherits(goog.messaging.MultiChannel.VirtualChannel, goog.Disposable);\n\n\n/**\n * The default service to run if no other services match.\n * @type {?function(string, (string|!Object))}\n * @private\n */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.defaultService_;\n\n\n/**\n * Logger object for goog.messaging.MultiChannel.VirtualChannel.\n * @type {goog.log.Logger}\n * @private\n */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.logger_ =\n goog.log.getLogger('goog.messaging.MultiChannel.VirtualChannel');\n\n\n/**\n * This is a no-op, since the underlying channel is expected to already be\n * initialized when it's passed in.\n *\n * @override\n */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.connect = function(\n opt_connectCb) {\n 'use strict';\n if (opt_connectCb) {\n opt_connectCb();\n }\n};\n\n\n/**\n * This always returns true, since the underlying channel is expected to already\n * be initialized when it's passed in.\n *\n * @override\n */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.isConnected = function() {\n 'use strict';\n return true;\n};\n\n\n/**\n * @override\n */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.registerService = function(\n serviceName, callback, opt_objectPayload) {\n 'use strict';\n this.parent_.underlyingChannel_.registerService(\n this.name_ + ':' + serviceName,\n goog.bind(this.doCallback_, this, callback), opt_objectPayload);\n};\n\n\n/**\n * @override\n */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.registerDefaultService =\n function(callback) {\n 'use strict';\n this.defaultService_ = goog.bind(this.doCallback_, this, callback);\n};\n\n\n/**\n * @override\n */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.send = function(\n serviceName, payload) {\n 'use strict';\n if (this.isDisposed()) {\n throw new Error('#send called for disposed VirtualChannel.');\n }\n\n this.parent_.underlyingChannel_.send(this.name_ + ':' + serviceName, payload);\n};\n\n\n/**\n * Wraps a callback with a function that will log a warning and abort if it's\n * called when this channel is disposed.\n *\n * @param {!Function} callback The callback to wrap.\n * @param {...*} var_args Other arguments, passed to the callback.\n * @private\n */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.doCallback_ = function(\n callback, var_args) {\n 'use strict';\n if (this.isDisposed()) {\n goog.log.warning(\n this.logger_, 'Virtual channel \"' + this.name_ + '\" received ' +\n ' a message after being disposed.');\n return;\n }\n\n callback.apply({}, Array.prototype.slice.call(arguments, 1));\n};\n\n\n/** @override */\ngoog.messaging.MultiChannel.VirtualChannel.prototype.disposeInternal =\n function() {\n 'use strict';\n this.parent_.virtualChannels_[this.name_] = null;\n this.parent_ = null;\n};\n","^<",1684857788697,"^=",["^3",["^G7","^>","^2F","^3X","^1X","^5S"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^G7","^2F","^3X","^1X","^5S"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.MultiChannel","goog.messaging.MultiChannel.VirtualChannel"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.dispose","goog.log","goog.messaging.MessageChannel","goog.object"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/multichannel.js"],"^[",["^3",["^GD","^G6"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1X","^5S","^3X","^G7","^2F"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.PortOperator"]],"^5","goog.messaging.portoperator.js","^6",["^7","goog/messaging/portoperator.js"],"^8","goog/messaging/portoperator.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The central node of a {@link goog.messaging.PortNetwork}. The\n * operator is responsible for providing the two-way communication channels (via\n * {@link MessageChannel}s) between each pair of nodes in the network that need\n * to communicate with one another. Each network should have one and only one\n * operator.\n */\n\ngoog.provide('goog.messaging.PortOperator');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.asserts');\ngoog.require('goog.dispose');\ngoog.require('goog.log');\ngoog.require('goog.messaging.PortChannel');\ngoog.require('goog.messaging.PortNetwork'); // interface\ngoog.require('goog.object');\ngoog.requireType('goog.messaging.MessageChannel');\n\n\n\n/**\n * The central node of a PortNetwork.\n *\n * @param {string} name The name of this node.\n * @constructor\n * @extends {goog.Disposable}\n * @implements {goog.messaging.PortNetwork}\n * @final\n */\ngoog.messaging.PortOperator = function(name) {\n 'use strict';\n goog.messaging.PortOperator.base(this, 'constructor');\n\n /**\n * The collection of channels for communicating with other contexts in the\n * network. These are the channels that are returned to the user, as opposed\n * to the channels used for internal network communication. This is lazily\n * populated as the user requests communication with other contexts, or other\n * contexts request communication with the operator.\n *\n * @type {!Object}\n * @private\n */\n this.connections_ = {};\n\n /**\n * The collection of channels for internal network communication with other\n * contexts. This is not lazily populated, and always contains entries for\n * each member of the network.\n *\n * @type {!Object}\n * @private\n */\n this.switchboard_ = {};\n\n /**\n * The name of the operator context.\n *\n * @type {string}\n * @private\n */\n this.name_ = name;\n};\ngoog.inherits(goog.messaging.PortOperator, goog.Disposable);\n\n\n/**\n * The logger for PortOperator.\n * @type {goog.log.Logger}\n * @private\n */\ngoog.messaging.PortOperator.prototype.logger_ =\n goog.log.getLogger('goog.messaging.PortOperator');\n\n\n/** @override */\ngoog.messaging.PortOperator.prototype.dial = function(name) {\n 'use strict';\n this.connectSelfToPort_(name);\n return this.connections_[name];\n};\n\n\n/**\n * Adds a caller to the network with the given name. This port should have no\n * services registered on it. It will be disposed along with the PortOperator.\n *\n * @param {string} name The name of the port to add.\n * @param {!goog.messaging.MessageChannel} port The port to add. Must be either\n * a {@link goog.messaging.PortChannel} or a decorator wrapping a\n * PortChannel; in particular, it must be able to send and receive\n * {@link MessagePort}s.\n */\ngoog.messaging.PortOperator.prototype.addPort = function(name, port) {\n 'use strict';\n this.switchboard_[name] = port;\n port.registerService(\n goog.messaging.PortNetwork.REQUEST_CONNECTION_SERVICE,\n goog.bind(this.requestConnection_, this, name));\n};\n\n\n/**\n * Connects two contexts by creating a {@link MessageChannel} and sending one\n * end to one context and the other end to the other. Called when we receive a\n * request from a caller to connect it to another context (including potentially\n * the operator).\n *\n * @param {string} sourceName The name of the context requesting the connection.\n * @param {!Object|string} message The name of the context to which\n * the connection is requested.\n * @private\n */\ngoog.messaging.PortOperator.prototype.requestConnection_ = function(\n sourceName, message) {\n 'use strict';\n const requestedName = /** @type {string} */ (message);\n if (requestedName == this.name_) {\n this.connectSelfToPort_(sourceName);\n return;\n }\n\n const sourceChannel = this.switchboard_[sourceName];\n const requestedChannel = this.switchboard_[requestedName];\n\n goog.asserts.assert(sourceChannel != null);\n if (!requestedChannel) {\n const err = 'Port \"' + sourceName + '\" requested a connection to port \"' +\n requestedName + '\", which doesn\\'t exist';\n goog.log.warning(this.logger_, err);\n sourceChannel.send(\n goog.messaging.PortNetwork.GRANT_CONNECTION_SERVICE,\n {'success': false, 'message': err});\n return;\n }\n\n const messageChannel = new MessageChannel();\n sourceChannel.send(\n goog.messaging.PortNetwork.GRANT_CONNECTION_SERVICE,\n {'success': true, 'name': requestedName, 'port': messageChannel.port1});\n requestedChannel.send(\n goog.messaging.PortNetwork.GRANT_CONNECTION_SERVICE,\n {'success': true, 'name': sourceName, 'port': messageChannel.port2});\n};\n\n\n/**\n * Connects together the operator and a caller by creating a\n * {@link MessageChannel} and sending one end to the remote context.\n *\n * @param {string} contextName The name of the context to which to connect the\n * operator.\n * @private\n */\ngoog.messaging.PortOperator.prototype.connectSelfToPort_ = function(\n contextName) {\n 'use strict';\n if (contextName in this.connections_) {\n // We've already established a connection with this port.\n return;\n }\n\n const contextChannel = this.switchboard_[contextName];\n if (!contextChannel) {\n throw new Error('Port \"' + contextName + '\" doesn\\'t exist');\n }\n\n const messageChannel = new MessageChannel();\n contextChannel.send(\n goog.messaging.PortNetwork.GRANT_CONNECTION_SERVICE,\n {'success': true, 'name': this.name_, 'port': messageChannel.port1});\n messageChannel.port2.start();\n this.connections_[contextName] =\n new goog.messaging.PortChannel(messageChannel.port2);\n};\n\n\n/** @override */\ngoog.messaging.PortOperator.prototype.disposeInternal = function() {\n 'use strict';\n goog.object.forEach(this.switchboard_, goog.dispose);\n goog.object.forEach(this.connections_, goog.dispose);\n delete this.switchboard_;\n delete this.connections_;\n goog.messaging.PortOperator.base(this, 'disposeInternal');\n};\n","^<",1684857788697,"^=",["^3",["^2?","^=V","^G8","^>","^2F","^3X","^1X","^5S"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2?","^=V","^G8","^2F","^3X","^1X","^5S"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.PortOperator"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.asserts","goog.dispose","goog.log","goog.messaging.PortChannel","goog.messaging.PortNetwork","goog.object"],"^W",["goog.messaging.MessageChannel"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/portoperator.js"],"^[",["^3",["^GE"]],"^W",["^3",["^G7"]],"^10",true,"^11",true,"^12",["^>","^1X","^2?","^5S","^3X","^G8","^=V","^2F"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.messaging.BufferedChannel"]],"^5","goog.messaging.bufferedchannel.js","^6",["^7","goog/messaging/bufferedchannel.js"],"^8","goog/messaging/bufferedchannel.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A wrapper for asynchronous message-passing channels that buffer\n * their output until both ends of the channel are connected.\n */\n\ngoog.provide('goog.messaging.BufferedChannel');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.Timer');\ngoog.require('goog.dispose');\ngoog.require('goog.events');\ngoog.require('goog.log');\ngoog.require('goog.messaging.MessageChannel');\ngoog.require('goog.messaging.MultiChannel');\n\n\n\n/**\n * Creates a new BufferedChannel, which operates like its underlying channel\n * except that it buffers calls to send until it receives a message from its\n * peer claiming that the peer is ready to receive. The peer is also expected\n * to be a BufferedChannel, though this is not enforced.\n *\n * @param {!goog.messaging.MessageChannel} messageChannel The MessageChannel\n * we're wrapping.\n * @param {number=} opt_interval Polling interval for sending ready\n * notifications to peer, in ms. Default is 50.\n * @constructor\n * @extends {goog.Disposable}\n * @implements {goog.messaging.MessageChannel};\n * @final\n */\ngoog.messaging.BufferedChannel = function(messageChannel, opt_interval) {\n 'use strict';\n goog.Disposable.call(this);\n\n /**\n * Buffer of messages to be sent when the channel's peer is ready.\n *\n * @type {Array}\n * @private\n */\n this.buffer_ = [];\n\n /**\n * Channel dispatcher wrapping the underlying delegate channel.\n *\n * @type {!goog.messaging.MultiChannel}\n * @private\n */\n this.multiChannel_ = new goog.messaging.MultiChannel(messageChannel);\n\n /**\n * Virtual channel for carrying the user's messages.\n *\n * @type {!goog.messaging.MessageChannel}\n * @private\n */\n this.userChannel_ = this.multiChannel_.createVirtualChannel(\n goog.messaging.BufferedChannel.USER_CHANNEL_NAME_);\n\n /**\n * Virtual channel for carrying control messages for BufferedChannel.\n *\n * @type {!goog.messaging.MessageChannel}\n * @private\n */\n this.controlChannel_ = this.multiChannel_.createVirtualChannel(\n goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_);\n\n /**\n * Timer for the peer ready ping loop.\n *\n * @type {goog.Timer}\n * @private\n */\n this.timer_ = new goog.Timer(\n opt_interval || goog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_);\n\n this.timer_.start();\n goog.events.listen(\n this.timer_, goog.Timer.TICK, this.sendReadyPing_, false, this);\n\n this.controlChannel_.registerService(\n goog.messaging.BufferedChannel.PEER_READY_SERVICE_NAME_,\n goog.bind(this.setPeerReady_, this));\n};\ngoog.inherits(goog.messaging.BufferedChannel, goog.Disposable);\n\n\n/**\n * Default polling interval (in ms) for setPeerReady_ notifications.\n *\n * @type {number}\n * @const\n * @private\n */\ngoog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_ = 50;\n\n\n/**\n * The name of the private service which handles peer ready pings. The\n * service registered with this name is bound to this.setPeerReady_, an internal\n * part of BufferedChannel's implementation that clients should not send to\n * directly.\n *\n * @type {string}\n * @const\n * @private\n */\ngoog.messaging.BufferedChannel.PEER_READY_SERVICE_NAME_ = 'setPeerReady_';\n\n\n/**\n * The name of the virtual channel along which user messages are sent.\n *\n * @type {string}\n * @const\n * @private\n */\ngoog.messaging.BufferedChannel.USER_CHANNEL_NAME_ = 'user';\n\n\n/**\n * The name of the virtual channel along which internal control messages are\n * sent.\n *\n * @type {string}\n * @const\n * @private\n */\ngoog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ = 'control';\n\n\n/** @override */\ngoog.messaging.BufferedChannel.prototype.connect = function(opt_connectCb) {\n 'use strict';\n if (opt_connectCb) {\n opt_connectCb();\n }\n};\n\n\n/** @override */\ngoog.messaging.BufferedChannel.prototype.isConnected = function() {\n 'use strict';\n return true;\n};\n\n\n/**\n * @return {boolean} Whether the channel's peer is ready.\n */\ngoog.messaging.BufferedChannel.prototype.isPeerReady = function() {\n 'use strict';\n return this.peerReady_;\n};\n\n\n/**\n * Logger.\n *\n * @type {goog.log.Logger}\n * @const\n * @private\n */\ngoog.messaging.BufferedChannel.prototype.logger_ =\n goog.log.getLogger('goog.messaging.bufferedchannel');\n\n\n/**\n * Handles one tick of our peer ready notification loop. This entails sending a\n * ready ping to the peer and shutting down the loop if we've received a ping\n * ourselves.\n *\n * @private\n */\ngoog.messaging.BufferedChannel.prototype.sendReadyPing_ = function() {\n 'use strict';\n try {\n this.controlChannel_.send(\n goog.messaging.BufferedChannel.PEER_READY_SERVICE_NAME_,\n /* payload */ this.isPeerReady() ? '1' : '');\n } catch (e) {\n this.timer_.stop(); // So we don't keep calling send and re-throwing.\n throw e;\n }\n};\n\n\n/**\n * Whether or not the peer channel is ready to receive messages.\n *\n * @type {boolean}\n * @private\n */\ngoog.messaging.BufferedChannel.prototype.peerReady_;\n\n\n/** @override */\ngoog.messaging.BufferedChannel.prototype.registerService = function(\n serviceName, callback, opt_objectPayload) {\n 'use strict';\n this.userChannel_.registerService(serviceName, callback, opt_objectPayload);\n};\n\n\n/** @override */\ngoog.messaging.BufferedChannel.prototype.registerDefaultService = function(\n callback) {\n 'use strict';\n this.userChannel_.registerDefaultService(callback);\n};\n\n\n/**\n * Send a message over the channel. If the peer is not ready, the message will\n * be buffered and sent once we've received a ready message from our peer.\n *\n * @param {string} serviceName The name of the service this message should be\n * delivered to.\n * @param {string|!Object} payload The value of the message. If this is an\n * Object, it is serialized to JSON before sending. It's the responsibility\n * of implementors of this class to perform the serialization.\n * @see goog.net.xpc.BufferedChannel.send\n * @override\n */\ngoog.messaging.BufferedChannel.prototype.send = function(serviceName, payload) {\n 'use strict';\n if (this.isPeerReady()) {\n this.userChannel_.send(serviceName, payload);\n } else {\n goog.log.fine(\n goog.messaging.BufferedChannel.prototype.logger_,\n 'buffering message ' + serviceName);\n this.buffer_.push({serviceName: serviceName, payload: payload});\n }\n};\n\n\n/**\n * Marks the channel's peer as ready, then sends buffered messages and nulls the\n * buffer. Subsequent calls to setPeerReady_ have no effect.\n *\n * @param {(!Object|string)} peerKnowsWeKnowItsReady Passed by the peer to\n * indicate whether it knows that we've received its ping and that it's\n * ready. Non-empty if true, empty if false.\n * @private\n * @suppress {strictMissingProperties} Added to tighten compiler checks\n */\ngoog.messaging.BufferedChannel.prototype.setPeerReady_ = function(\n peerKnowsWeKnowItsReady) {\n 'use strict';\n if (peerKnowsWeKnowItsReady) {\n this.timer_.stop();\n } else {\n // Our peer doesn't know we're ready, so restart (or continue) pinging.\n // Restarting may be needed if the peer iframe was reloaded after the\n // connection was first established.\n this.timer_.start();\n }\n\n if (this.peerReady_) {\n return;\n }\n this.peerReady_ = true;\n // Send one last ping so that the peer knows we know it's ready.\n this.sendReadyPing_();\n for (let i = 0; i < this.buffer_.length; i++) {\n const message = this.buffer_[i];\n goog.log.fine(\n goog.messaging.BufferedChannel.prototype.logger_,\n 'sending buffered message ' + message.serviceName);\n this.userChannel_.send(message.serviceName, message.payload);\n }\n this.buffer_ = null;\n};\n\n\n/** @override */\ngoog.messaging.BufferedChannel.prototype.disposeInternal = function() {\n 'use strict';\n goog.dispose(this.multiChannel_);\n goog.dispose(this.timer_);\n goog.messaging.BufferedChannel.base(this, 'disposeInternal');\n};\n","^<",1684857788697,"^=",["^3",["^1W","^G7","^>","^3X","^1X","^5S","^23","^G6"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^1W","^G7","^3X","^1X","^5S","^23","^G6"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.BufferedChannel"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.Timer","goog.dispose","goog.events","goog.log","goog.messaging.MessageChannel","goog.messaging.MultiChannel"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/bufferedchannel.js"],"^[",["^3",["^GF"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^1X","^1W","^5S","^23","^3X","^G7","^G6"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^G?"]],"^5","goog.messaging.portcaller.js","^6",["^7","goog/messaging/portcaller.js"],"^8","goog/messaging/portcaller.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The leaf node of a {@link goog.messaging.PortNetwork}. Callers\n * connect to the operator, and request connections with other contexts from it.\n */\n\ngoog.provide('goog.messaging.PortCaller');\n\ngoog.require('goog.Disposable');\ngoog.require('goog.async.Deferred');\ngoog.require('goog.dispose');\ngoog.require('goog.messaging.DeferredChannel');\ngoog.require('goog.messaging.PortChannel');\ngoog.require('goog.messaging.PortNetwork'); // interface\ngoog.require('goog.object');\ngoog.requireType('goog.messaging.MessageChannel');\n\n\n\n/**\n * The leaf node of a network.\n *\n * @param {!goog.messaging.MessageChannel} operatorPort The channel for\n * communicating with the operator. The other side of this channel should be\n * passed to {@link goog.messaging.PortOperator#addPort}. Must be either a\n * {@link goog.messaging.PortChannel} or a decorator wrapping a PortChannel;\n * in particular, it must be able to send and receive {@link MessagePort}s.\n * @constructor\n * @extends {goog.Disposable}\n * @implements {goog.messaging.PortNetwork}\n * @final\n */\ngoog.messaging.PortCaller = function(operatorPort) {\n 'use strict';\n goog.messaging.PortCaller.base(this, 'constructor');\n\n /**\n * The channel to the {@link goog.messaging.PortOperator} for this network.\n *\n * @type {!goog.messaging.MessageChannel}\n * @private\n */\n this.operatorPort_ = operatorPort;\n\n /**\n * The collection of channels for communicating with other contexts in the\n * network. Each value can contain a {@link goog.aync.Deferred} and/or a\n * {@link goog.messaging.MessageChannel}.\n *\n * If the value contains a Deferred, then the channel is a\n * {@link goog.messaging.DeferredChannel} wrapping that Deferred. The Deferred\n * will be resolved with a {@link goog.messaging.PortChannel} once we receive\n * the appropriate port from the operator. This is the situation when this\n * caller requests a connection to another context; the DeferredChannel is\n * used to queue up messages until we receive the port from the operator.\n *\n * If the value does not contain a Deferred, then the channel is simply a\n * {@link goog.messaging.PortChannel} communicating with the given context.\n * This is the situation when this context received a port for the other\n * context before it was requested.\n *\n * If a value exists for a given key, it must contain a channel, but it\n * doesn't necessarily contain a Deferred.\n *\n * @type {!Object<{deferred: goog.async.Deferred,\n * channel: !goog.messaging.MessageChannel}>}\n * @private\n */\n this.connections_ = {};\n\n this.operatorPort_.registerService(\n goog.messaging.PortNetwork.GRANT_CONNECTION_SERVICE,\n goog.bind(this.connectionGranted_, this), true /* opt_json */);\n};\ngoog.inherits(goog.messaging.PortCaller, goog.Disposable);\n\n\n/** @override */\ngoog.messaging.PortCaller.prototype.dial = function(name) {\n 'use strict';\n if (name in this.connections_) {\n return this.connections_[name].channel;\n }\n\n this.operatorPort_.send(\n goog.messaging.PortNetwork.REQUEST_CONNECTION_SERVICE, name);\n const deferred = new goog.async.Deferred();\n const channel = new goog.messaging.DeferredChannel(deferred);\n this.connections_[name] = {deferred: deferred, channel: channel};\n return channel;\n};\n\n\n/**\n * Registers a connection to another context in the network. This is called when\n * the operator sends us one end of a {@link MessageChannel}, either because\n * this caller requested a connection with another context, or because that\n * context requested a connection with this caller.\n *\n * It's possible that the remote context and this one request each other roughly\n * concurrently. The operator doesn't keep track of which contexts have been\n * connected, so it will create two separate {@link MessageChannel}s in this\n * case. However, the first channel created will reach both contexts first, so\n * we simply ignore all connections with a given context after the first.\n *\n * @param {!Object|string} message The name of the context\n * being connected and the port connecting the context.\n * @private\n */\ngoog.messaging.PortCaller.prototype.connectionGranted_ = function(message) {\n 'use strict';\n const args = /** @type {{name: string, port: MessagePort}} */ (message);\n const port = args['port'];\n const entry = this.connections_[args['name']];\n if (entry && (!entry.deferred || entry.deferred.hasFired())) {\n // If two PortCallers request one another at the same time, the operator may\n // send out a channel for connecting them multiple times. Since both callers\n // will receive the first channel's ports first, we can safely ignore and\n // close any future ports.\n port.close();\n } else if (!args['success']) {\n throw new Error(args['message']);\n } else {\n port.start();\n const channel = new goog.messaging.PortChannel(port);\n if (entry) {\n entry.deferred.callback(channel);\n } else {\n this.connections_[args['name']] = {channel: channel, deferred: null};\n }\n }\n};\n\n\n/** @override */\ngoog.messaging.PortCaller.prototype.disposeInternal = function() {\n 'use strict';\n goog.dispose(this.operatorPort_);\n goog.object.forEach(this.connections_, goog.dispose);\n delete this.operatorPort_;\n delete this.connections_;\n goog.messaging.PortCaller.base(this, 'disposeInternal');\n};\n","^<",1684857788697,"^=",["^3",["^=V","^G8","^G9","^>","^2F","^1X","^42","^5S"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^=V","^G8","^G9","^2F","^1X","^42","^5S"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.messaging.PortCaller"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.Disposable","goog.async.Deferred","goog.dispose","goog.messaging.DeferredChannel","goog.messaging.PortChannel","goog.messaging.PortNetwork","goog.object"],"^W",["goog.messaging.MessageChannel"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/messaging/portcaller.js"],"^[",["^3",["^G?"]],"^W",["^3",["^G7"]],"^10",true,"^11",true,"^12",["^>","^1X","^42","^5S","^G9","^G8","^=V","^2F"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.userAgent.platform"]],"^5","goog.useragent.platform.js","^6",["^7","goog/useragent/platform.js"],"^8","goog/useragent/platform.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for getting details about the user's platform.\n */\n\ngoog.provide('goog.userAgent.platform');\n\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\n\n\n/**\n * Detects the version of the OS/platform the browser is running in. Not\n * supported for Linux, where an empty string is returned.\n *\n * @private\n * @return {string} The platform version.\n */\ngoog.userAgent.platform.determineVersion_ = function() {\n 'use strict';\n var re;\n if (goog.userAgent.WINDOWS) {\n re = /Windows NT ([0-9.]+)/;\n var match = re.exec(goog.userAgent.getUserAgentString());\n if (match) {\n return match[1];\n } else {\n return '0';\n }\n } else if (goog.userAgent.MAC) {\n re = /1[0|1][_.][0-9_.]+/;\n var match = re.exec(goog.userAgent.getUserAgentString());\n // Note: some old versions of Camino do not report an OSX version.\n // Default to 10.\n return match ? match[0].replace(/_/g, '.') : '10';\n } else if (goog.userAgent.ANDROID) {\n re = /Android\\s+([^\\);]+)(\\)|;)/;\n var match = re.exec(goog.userAgent.getUserAgentString());\n return match ? match[1] : '';\n } else if (\n goog.userAgent.IPHONE || goog.userAgent.IPAD || goog.userAgent.IPOD) {\n re = /(?:iPhone|CPU)\\s+OS\\s+(\\S+)/;\n var match = re.exec(goog.userAgent.getUserAgentString());\n // Report the version as x.y.z and not x_y_z\n return match ? match[1].replace(/_/g, '.') : '';\n }\n\n return '';\n};\n\n\n/**\n * The version of the platform. We don't determine the version of Linux.\n * For Windows, we only look at the NT version. Non-NT-based versions\n * (e.g. 95, 98, etc.) are given version 0.0.\n * @type {string}\n */\ngoog.userAgent.platform.VERSION = goog.userAgent.platform.determineVersion_();\n\n\n/**\n * Whether the user agent platform version is higher or the same as the given\n * version.\n *\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the user agent platform version is higher or the\n * same as the given version.\n */\ngoog.userAgent.platform.isVersion = function(version) {\n 'use strict';\n return goog.string.compareVersions(\n goog.userAgent.platform.VERSION, version) >= 0;\n};\n","^<",1684857788697,"^=",["^3",["^2L","^>","^2T"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2L","^2T"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.userAgent.platform"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.string","goog.userAgent"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/platform.js"],"^[",["^3",["^GG"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2L","^2T"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.userAgent.product.isVersion"]],"^5","goog.useragent.product_isversion.js","^6",["^7","goog/useragent/product_isversion.js"],"^8","goog/useragent/product_isversion.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Functions for understanding the version of the browser.\n * This is pulled out of product.js to ensure that only builds that need\n * this functionality actually get it, without having to rely on the compiler\n * to strip out unneeded pieces.\n *\n * TODO(nnaze): Move to more appropriate filename/namespace.\n */\n\n\ngoog.provide('goog.userAgent.product.isVersion');\n\n\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\ngoog.require('goog.userAgent.product');\n\n\n/**\n * @return {string} The string that describes the version number of the user\n * agent product. This is a string rather than a number because it may\n * contain 'b', 'a', and so on.\n * @private\n */\ngoog.userAgent.product.determineVersion_ = function() {\n 'use strict';\n // All browsers have different ways to detect the version and they all have\n // different naming schemes.\n\n if (goog.userAgent.product.FIREFOX) {\n // Firefox/2.0.0.1 or Firefox/3.5.3\n return goog.userAgent.product.getFirstRegExpGroup_(/Firefox\\/([0-9.]+)/);\n }\n\n if (goog.userAgent.product.IE || goog.userAgent.product.EDGE ||\n goog.userAgent.product.OPERA) {\n return goog.userAgent.VERSION;\n }\n\n if (goog.userAgent.product.CHROME) {\n // CriOS is Chrome on iOS, but iPadOS 13+ spoofs macOS by default.\n // So it's possible that CriOS appears to be running on macOS.\n if (goog.labs.userAgent.platform.isIos() ||\n goog.labs.userAgent.platform.isMacintosh()) {\n // CriOS/56.0.2924.79\n const chromeIosVersion =\n goog.userAgent.product.getFirstRegExpGroup_(/CriOS\\/([0-9.]+)/);\n if (chromeIosVersion) {\n return chromeIosVersion;\n }\n }\n // Chrome/4.0.223.1\n return goog.userAgent.product.getFirstRegExpGroup_(/Chrome\\/([0-9.]+)/);\n }\n\n // This replicates legacy logic, which considered Safari and iOS to be\n // different products.\n if (goog.userAgent.product.SAFARI && !goog.labs.userAgent.platform.isIos()) {\n // Version/5.0.3\n //\n // NOTE: Before version 3, Safari did not report a product version number.\n // The product version number for these browsers will be the empty string.\n // They may be differentiated by WebKit version number in goog.userAgent.\n return goog.userAgent.product.getFirstRegExpGroup_(/Version\\/([0-9.]+)/);\n }\n\n if (goog.userAgent.product.IPHONE || goog.userAgent.product.IPAD) {\n // Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1\n // (KHTML, like Gecko) Version/3.0 Mobile/3A100a Safari/419.3\n // Version is the browser version, Mobile is the build number. We combine\n // the version string with the build number: 3.0.3A100a for the example.\n var arr =\n goog.userAgent.product.execRegExp_(/Version\\/(\\S+).*Mobile\\/(\\S+)/);\n if (arr) {\n return arr[1] + '.' + arr[2];\n }\n } else if (goog.userAgent.product.ANDROID) {\n // Mozilla/5.0 (Linux; U; Android 0.5; en-us) AppleWebKit/522+\n // (KHTML, like Gecko) Safari/419.3\n //\n // Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+\n // (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2\n //\n // Prefer Version number if present, else make do with the OS number\n var version =\n goog.userAgent.product.getFirstRegExpGroup_(/Android\\s+([0-9.]+)/);\n if (version) {\n return version;\n }\n\n return goog.userAgent.product.getFirstRegExpGroup_(/Version\\/([0-9.]+)/);\n }\n\n return '';\n};\n\n\n/**\n * Return the first group of the given regex.\n * @param {!RegExp} re Regular expression with at least one group.\n * @return {string} Contents of the first group or an empty string if no match.\n * @private\n */\ngoog.userAgent.product.getFirstRegExpGroup_ = function(re) {\n 'use strict';\n var arr = goog.userAgent.product.execRegExp_(re);\n return arr ? arr[1] : '';\n};\n\n\n/**\n * Run regexp's exec() on the userAgent string.\n * @param {!RegExp} re Regular expression.\n * @return {?IArrayLike} A result array, or null for no match.\n * @private\n */\ngoog.userAgent.product.execRegExp_ = function(re) {\n 'use strict';\n return re.exec(goog.userAgent.getUserAgentString());\n};\n\n\n/**\n * The version of the user agent. This is a string because it might contain\n * 'b' (as in beta) as well as multiple dots.\n * @type {string}\n */\ngoog.userAgent.product.VERSION = goog.userAgent.product.determineVersion_();\n\n\n/**\n * Whether the user agent product version is higher or the same as the given\n * version.\n *\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the user agent product version is higher or the\n * same as the given version.\n */\ngoog.userAgent.product.isVersion = function(version) {\n 'use strict';\n return goog.string.compareVersions(goog.userAgent.product.VERSION, version) >=\n 0;\n};\n","^<",1684857788697,"^=",["^3",["^5D","^2L","^>","^2T","^9H"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^5D","^2L","^2T","^9H"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.userAgent.product.isVersion"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.labs.userAgent.platform","goog.string","goog.userAgent","goog.userAgent.product"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/product_isversion.js"],"^[",["^3",["^GH"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^9H","^2L","^2T","^5D"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^5D"]],"^5","goog.useragent.product.js","^6",["^7","goog/useragent/product.js"],"^8","goog/useragent/product.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Detects the specific browser and not just the rendering engine.\n */\n\ngoog.provide('goog.userAgent.product');\n\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.userAgent');\n\n\n/**\n * @define {boolean} Whether the code is running on the Firefox web browser.\n */\ngoog.userAgent.product.ASSUME_FIREFOX =\n goog.define('goog.userAgent.product.ASSUME_FIREFOX', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the product is an\n * iPhone.\n */\ngoog.userAgent.product.ASSUME_IPHONE =\n goog.define('goog.userAgent.product.ASSUME_IPHONE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the product is an\n * iPad.\n */\ngoog.userAgent.product.ASSUME_IPAD =\n goog.define('goog.userAgent.product.ASSUME_IPAD', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the product is an\n * AOSP browser or WebView inside a pre KitKat Android phone or tablet.\n */\ngoog.userAgent.product.ASSUME_ANDROID =\n goog.define('goog.userAgent.product.ASSUME_ANDROID', false);\n\n\n/**\n * @define {boolean} Whether the code is running on the Chrome web browser on\n * any platform or AOSP browser or WebView in a KitKat+ Android phone or tablet.\n */\ngoog.userAgent.product.ASSUME_CHROME =\n goog.define('goog.userAgent.product.ASSUME_CHROME', false);\n\n\n/**\n * @define {boolean} Whether the code is running on the Safari web browser.\n */\ngoog.userAgent.product.ASSUME_SAFARI =\n goog.define('goog.userAgent.product.ASSUME_SAFARI', false);\n\n\n/**\n * Whether we know the product type at compile-time.\n * @type {boolean}\n * @private\n */\ngoog.userAgent.product.PRODUCT_KNOWN_ = goog.userAgent.ASSUME_IE ||\n goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_OPERA ||\n goog.userAgent.product.ASSUME_FIREFOX ||\n goog.userAgent.product.ASSUME_IPHONE ||\n goog.userAgent.product.ASSUME_IPAD ||\n goog.userAgent.product.ASSUME_ANDROID ||\n goog.userAgent.product.ASSUME_CHROME ||\n goog.userAgent.product.ASSUME_SAFARI;\n\n\n/**\n * Whether the code is running on the Opera web browser.\n * @type {boolean}\n */\ngoog.userAgent.product.OPERA = goog.userAgent.OPERA;\n\n\n/**\n * Whether the code is running on an IE web browser.\n * @type {boolean}\n */\ngoog.userAgent.product.IE = goog.userAgent.IE;\n\n\n/**\n * Whether the code is running on an Edge web browser (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.product.EDGE = goog.userAgent.EDGE;\n\n\n/**\n * Whether the code is running on the Firefox web browser.\n * @type {boolean}\n */\ngoog.userAgent.product.FIREFOX = goog.userAgent.product.PRODUCT_KNOWN_ ?\n goog.userAgent.product.ASSUME_FIREFOX :\n goog.labs.userAgent.browser.isFirefox();\n\n\n/**\n * Whether the user agent is an iPhone or iPod (as in iPod touch).\n * @return {boolean}\n * @private\n */\ngoog.userAgent.product.isIphoneOrIpod_ = function() {\n 'use strict';\n return goog.labs.userAgent.platform.isIphone() ||\n goog.labs.userAgent.platform.isIpod();\n};\n\n\n/**\n * Whether the code is running on an iPhone or iPod touch.\n *\n * iPod touch is considered an iPhone for legacy reasons.\n * @type {boolean}\n */\ngoog.userAgent.product.IPHONE = goog.userAgent.product.PRODUCT_KNOWN_ ?\n goog.userAgent.product.ASSUME_IPHONE :\n goog.userAgent.product.isIphoneOrIpod_();\n\n\n/**\n * Whether the code is running on an iPad.\n * @type {boolean}\n */\ngoog.userAgent.product.IPAD = goog.userAgent.product.PRODUCT_KNOWN_ ?\n goog.userAgent.product.ASSUME_IPAD :\n goog.labs.userAgent.platform.isIpad();\n\n\n/**\n * Whether the code is running on AOSP browser or WebView inside\n * a pre KitKat Android phone or tablet.\n * @type {boolean}\n */\ngoog.userAgent.product.ANDROID = goog.userAgent.product.PRODUCT_KNOWN_ ?\n goog.userAgent.product.ASSUME_ANDROID :\n goog.labs.userAgent.browser.isAndroidBrowser();\n\n\n/**\n * Whether the code is running on any Chromium-based web browser on any platform\n * or AOSP browser or WebView in a KitKat+ Android phone or tablet.\n * @type {boolean}\n */\ngoog.userAgent.product.CHROME = goog.userAgent.product.PRODUCT_KNOWN_ ?\n goog.userAgent.product.ASSUME_CHROME :\n goog.labs.userAgent.browser.isChrome();\n\n\n/**\n * @return {boolean} Whether the browser is Safari on desktop.\n * @private\n */\ngoog.userAgent.product.isSafariDesktop_ = function() {\n 'use strict';\n return goog.labs.userAgent.browser.isSafari() &&\n !goog.labs.userAgent.platform.isIos();\n};\n\n\n/**\n * Whether the code is running on the desktop Safari web browser.\n * Note: the legacy behavior here is only true for Safari not running\n * on iOS.\n * @type {boolean}\n */\ngoog.userAgent.product.SAFARI = goog.userAgent.product.PRODUCT_KNOWN_ ?\n goog.userAgent.product.ASSUME_SAFARI :\n goog.userAgent.product.isSafariDesktop_();\n","^<",1684857788697,"^=",["^3",["^>","^2T","^9H","^2:"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2T","^9H","^2:"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.userAgent.product"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.labs.userAgent.browser","goog.labs.userAgent.platform","goog.userAgent"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/product.js"],"^[",["^3",["^5D"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2:","^9H","^2T"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.userAgent.keyboard"]],"^5","goog.useragent.keyboard.js","^6",["^7","goog/useragent/keyboard.js"],"^8","goog/useragent/keyboard.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Constants for determining keyboard support.\n */\n\ngoog.provide('goog.userAgent.keyboard');\n\ngoog.require('goog.labs.userAgent.platform');\n\n\n/**\n * @define {boolean} Whether the user agent is running with in an environment\n * that should use Mac-based keyboard shortcuts (Meta instead of Ctrl, etc.).\n */\ngoog.userAgent.keyboard.ASSUME_MAC_KEYBOARD =\n goog.define('goog.userAgent.keyboard.ASSUME_MAC_KEYBOARD', false);\n\n\n/**\n * Determines whether Mac-based keyboard shortcuts should be used.\n * @return {boolean}\n * @private\n */\ngoog.userAgent.keyboard.determineMacKeyboard_ = function() {\n 'use strict';\n return goog.labs.userAgent.platform.isMacintosh() ||\n goog.labs.userAgent.platform.isIos();\n};\n\n\n/**\n * Whether the user agent is running in an environment that uses Mac-based\n * keyboard shortcuts.\n * @type {boolean}\n */\ngoog.userAgent.keyboard.MAC_KEYBOARD =\n goog.userAgent.keyboard.ASSUME_MAC_KEYBOARD ||\n goog.userAgent.keyboard.determineMacKeyboard_();\n","^<",1684857788697,"^=",["^3",["^>","^9H"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^9H"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.userAgent.keyboard"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.labs.userAgent.platform"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/keyboard.js"],"^[",["^3",["^GI"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^9H"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^2T"]],"^5","goog.useragent.useragent.js","^6",["^7","goog/useragent/useragent.js"],"^8","goog/useragent/useragent.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Rendering engine detection.\n * @see User agent strings\n * For information on the browser brand (such as Safari versus Chrome), see\n * goog.userAgent.product.\n * @see ../demos/useragent.html\n */\n\ngoog.provide('goog.userAgent');\n\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.labs.userAgent.util');\ngoog.require('goog.reflect');\ngoog.require('goog.string.internal');\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is IE.\n */\ngoog.userAgent.ASSUME_IE = goog.define('goog.userAgent.ASSUME_IE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is EDGE,\n * referring to EdgeHTML based Edge.\n */\ngoog.userAgent.ASSUME_EDGE = goog.define('goog.userAgent.ASSUME_EDGE', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is GECKO.\n */\ngoog.userAgent.ASSUME_GECKO = goog.define('goog.userAgent.ASSUME_GECKO', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is WEBKIT.\n */\ngoog.userAgent.ASSUME_WEBKIT =\n goog.define('goog.userAgent.ASSUME_WEBKIT', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is a\n * mobile device running WebKit e.g. iPhone or Android.\n */\ngoog.userAgent.ASSUME_MOBILE_WEBKIT =\n goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);\n\n\n/**\n * @define {boolean} Whether we know at compile-time that the browser is OPERA,\n * referring to Presto-based Opera.\n */\ngoog.userAgent.ASSUME_OPERA = goog.define('goog.userAgent.ASSUME_OPERA', false);\n\n\n/**\n * @define {boolean} Whether the\n * `goog.userAgent.isVersionOrHigher`\n * function will return true for any version.\n */\ngoog.userAgent.ASSUME_ANY_VERSION =\n goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);\n\n\n/**\n * Whether we know the browser engine at compile-time.\n * @type {boolean}\n * @private\n */\ngoog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE ||\n goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO ||\n goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT ||\n goog.userAgent.ASSUME_OPERA;\n\n\n/**\n * Returns the userAgent string for the current browser.\n *\n * @return {string} The userAgent string.\n */\ngoog.userAgent.getUserAgentString = function() {\n 'use strict';\n return goog.labs.userAgent.util.getUserAgent();\n};\n\n\n/**\n * @return {?Navigator} The native navigator object.\n */\ngoog.userAgent.getNavigatorTyped = function() {\n 'use strict';\n // Need a local navigator reference instead of using the global one,\n // to avoid the rare case where they reference different objects.\n // (in a WorkerPool, for example).\n return goog.global['navigator'] || null;\n};\n\n\n/**\n * TODO(nnaze): Change type to \"Navigator\" and update compilation targets.\n * @return {?Object} The native navigator object.\n */\ngoog.userAgent.getNavigator = function() {\n 'use strict';\n return goog.userAgent.getNavigatorTyped();\n};\n\n\n/**\n * Whether the user agent is Presto-based Opera.\n * @type {boolean}\n */\ngoog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_OPERA :\n goog.labs.userAgent.browser.isOpera();\n\n\n/**\n * Whether the user agent is Internet Explorer.\n * @type {boolean}\n */\ngoog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_IE :\n goog.labs.userAgent.browser.isIE();\n\n\n/**\n * Whether the user agent is Microsoft Edge (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_EDGE :\n goog.labs.userAgent.engine.isEdge();\n\n\n/**\n * Whether the user agent is MS Internet Explorer or MS Edge (EdgeHTML based).\n * @type {boolean}\n */\ngoog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;\n\n\n/**\n * Whether the user agent is Gecko. Gecko is the rendering engine used by\n * Mozilla, Firefox, and others.\n * @type {boolean}\n */\ngoog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_GECKO :\n goog.labs.userAgent.engine.isGecko();\n\n\n/**\n * Whether the user agent is WebKit. WebKit is the rendering engine that\n * Safari, Edge Chromium, Opera Chromium, Android and others use.\n * @type {boolean}\n */\ngoog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ?\n goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT :\n goog.labs.userAgent.engine.isWebKit();\n\n\n/**\n * Whether the user agent is running on a mobile device.\n *\n * This is a separate function so that the logic can be tested.\n *\n * TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().\n *\n * @return {boolean} Whether the user agent is running on a mobile device.\n * @private\n */\ngoog.userAgent.isMobile_ = function() {\n 'use strict';\n return goog.userAgent.WEBKIT &&\n goog.labs.userAgent.util.matchUserAgent('Mobile');\n};\n\n\n/**\n * Whether the user agent is running on a mobile device.\n *\n * TODO(nnaze): Consider deprecating MOBILE when labs.userAgent\n * is promoted as the gecko/webkit logic is likely inaccurate.\n *\n * @type {boolean}\n */\ngoog.userAgent.MOBILE =\n goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();\n\n\n/**\n * Used while transitioning code to use WEBKIT instead.\n * @type {boolean}\n * @deprecated Use {@link goog.userAgent.product.SAFARI} instead.\n * TODO(nicksantos): Delete this from goog.userAgent.\n */\ngoog.userAgent.SAFARI = goog.userAgent.WEBKIT;\n\n\n/**\n * @return {string} the platform (operating system) the user agent is running\n * on. Default to empty string because navigator.platform may not be defined\n * (on Rhino, for example).\n * @private\n */\ngoog.userAgent.determinePlatform_ = function() {\n 'use strict';\n var navigator = goog.userAgent.getNavigatorTyped();\n return navigator && navigator.platform || '';\n};\n\n\n/**\n * The platform (operating system) the user agent is running on. Default to\n * empty string because navigator.platform may not be defined (on Rhino, for\n * example).\n * @type {string}\n */\ngoog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Macintosh operating\n * system.\n */\ngoog.userAgent.ASSUME_MAC = goog.define('goog.userAgent.ASSUME_MAC', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Windows operating\n * system.\n */\ngoog.userAgent.ASSUME_WINDOWS =\n goog.define('goog.userAgent.ASSUME_WINDOWS', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a Linux operating\n * system.\n */\ngoog.userAgent.ASSUME_LINUX = goog.define('goog.userAgent.ASSUME_LINUX', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on a X11 windowing\n * system.\n */\ngoog.userAgent.ASSUME_X11 = goog.define('goog.userAgent.ASSUME_X11', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on Android.\n */\ngoog.userAgent.ASSUME_ANDROID =\n goog.define('goog.userAgent.ASSUME_ANDROID', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPhone.\n */\ngoog.userAgent.ASSUME_IPHONE =\n goog.define('goog.userAgent.ASSUME_IPHONE', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPad.\n */\ngoog.userAgent.ASSUME_IPAD = goog.define('goog.userAgent.ASSUME_IPAD', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on an iPod.\n */\ngoog.userAgent.ASSUME_IPOD = goog.define('goog.userAgent.ASSUME_IPOD', false);\n\n\n/**\n * @define {boolean} Whether the user agent is running on KaiOS.\n */\ngoog.userAgent.ASSUME_KAIOS = goog.define('goog.userAgent.ASSUME_KAIOS', false);\n\n\n/**\n * @type {boolean}\n * @private\n */\ngoog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC ||\n goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX ||\n goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID ||\n goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||\n goog.userAgent.ASSUME_IPOD;\n\n\n/**\n * Whether the user agent is running on a Macintosh operating system.\n * @type {boolean}\n */\ngoog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_MAC :\n goog.labs.userAgent.platform.isMacintosh();\n\n\n/**\n * Whether the user agent is running on a Windows operating system.\n * @type {boolean}\n */\ngoog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_WINDOWS :\n goog.labs.userAgent.platform.isWindows();\n\n\n/**\n * Whether the user agent is Linux per the legacy behavior of\n * goog.userAgent.LINUX, which considered ChromeOS to also be\n * Linux.\n * @return {boolean}\n * @private\n */\ngoog.userAgent.isLegacyLinux_ = function() {\n 'use strict';\n return goog.labs.userAgent.platform.isLinux() ||\n goog.labs.userAgent.platform.isChromeOS();\n};\n\n\n/**\n * Whether the user agent is running on a Linux operating system.\n *\n * Note that goog.userAgent.LINUX considers ChromeOS to be Linux,\n * while goog.labs.userAgent.platform considers ChromeOS and\n * Linux to be different OSes.\n *\n * @type {boolean}\n */\ngoog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_LINUX :\n goog.userAgent.isLegacyLinux_();\n\n\n/**\n * @return {boolean} Whether the user agent is an X11 windowing system.\n * @private\n */\ngoog.userAgent.isX11_ = function() {\n 'use strict';\n var navigator = goog.userAgent.getNavigatorTyped();\n return !!navigator &&\n goog.string.internal.contains(navigator['appVersion'] || '', 'X11');\n};\n\n\n/**\n * Whether the user agent is running on a X11 windowing system.\n * @type {boolean}\n */\ngoog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_X11 :\n goog.userAgent.isX11_();\n\n\n/**\n * Whether the user agent is running on Android.\n * @type {boolean}\n */\ngoog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_ANDROID :\n goog.labs.userAgent.platform.isAndroid();\n\n\n/**\n * Whether the user agent is running on an iPhone.\n * @type {boolean}\n */\ngoog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_IPHONE :\n goog.labs.userAgent.platform.isIphone();\n\n\n/**\n * Whether the user agent is running on an iPad.\n * @type {boolean}\n */\ngoog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_IPAD :\n goog.labs.userAgent.platform.isIpad();\n\n\n/**\n * Whether the user agent is running on an iPod.\n * @type {boolean}\n */\ngoog.userAgent.IPOD = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_IPOD :\n goog.labs.userAgent.platform.isIpod();\n\n\n/**\n * Whether the user agent is running on iOS.\n * @type {boolean}\n */\ngoog.userAgent.IOS = goog.userAgent.PLATFORM_KNOWN_ ?\n (goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||\n goog.userAgent.ASSUME_IPOD) :\n goog.labs.userAgent.platform.isIos();\n\n/**\n * Whether the user agent is running on KaiOS.\n * @type {boolean}\n */\ngoog.userAgent.KAIOS = goog.userAgent.PLATFORM_KNOWN_ ?\n goog.userAgent.ASSUME_KAIOS :\n goog.labs.userAgent.platform.isKaiOS();\n\n\n/**\n * @return {string} The string that describes the version number of the user\n * agent.\n * @private\n */\ngoog.userAgent.determineVersion_ = function() {\n 'use strict';\n // All browsers have different ways to detect the version and they all have\n // different naming schemes.\n // version is a string rather than a number because it may contain 'b', 'a',\n // and so on.\n var version = '';\n var arr = goog.userAgent.getVersionRegexResult_();\n if (arr) {\n version = arr ? arr[1] : '';\n }\n\n if (goog.userAgent.IE) {\n // IE9 can be in document mode 9 but be reporting an inconsistent user agent\n // version. If it is identifying as a version lower than 9 we take the\n // documentMode as the version instead. IE8 has similar behavior.\n // It is recommended to set the X-UA-Compatible header to ensure that IE9\n // uses documentMode 9.\n var docMode = goog.userAgent.getDocumentMode_();\n if (docMode != null && docMode > parseFloat(version)) {\n return String(docMode);\n }\n }\n\n return version;\n};\n\n\n/**\n * @return {?IArrayLike|undefined} The version regex matches from\n * parsing the user\n * agent string. These regex statements must be executed inline so they can\n * be compiled out by the closure compiler with the rest of the useragent\n * detection logic when ASSUME_* is specified.\n * @private\n */\ngoog.userAgent.getVersionRegexResult_ = function() {\n 'use strict';\n var userAgent = goog.userAgent.getUserAgentString();\n if (goog.userAgent.GECKO) {\n return /rv\\:([^\\);]+)(\\)|;)/.exec(userAgent);\n }\n if (goog.userAgent.EDGE) {\n return /Edge\\/([\\d\\.]+)/.exec(userAgent);\n }\n if (goog.userAgent.IE) {\n return /\\b(?:MSIE|rv)[: ]([^\\);]+)(\\)|;)/.exec(userAgent);\n }\n if (goog.userAgent.WEBKIT) {\n // WebKit/125.4\n return /WebKit\\/(\\S+)/.exec(userAgent);\n }\n if (goog.userAgent.OPERA) {\n // If none of the above browsers were detected but the browser is Opera, the\n // only string that is of interest is 'Version/'.\n return /(?:Version)[ \\/]?(\\S+)/.exec(userAgent);\n }\n return undefined;\n};\n\n\n/**\n * @return {number|undefined} Returns the document mode (for testing).\n * @private\n */\ngoog.userAgent.getDocumentMode_ = function() {\n 'use strict';\n // NOTE(user): goog.userAgent may be used in context where there is no DOM.\n var doc = goog.global['document'];\n return doc ? doc['documentMode'] : undefined;\n};\n\n\n/**\n * The version of the user agent. This is a string because it might contain\n * 'b' (as in beta) as well as multiple dots.\n * @type {string}\n */\ngoog.userAgent.VERSION = goog.userAgent.determineVersion_();\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string} v1 Version of first item.\n * @param {string} v2 Version of second item.\n *\n * @return {number} 1 if first argument is higher\n * 0 if arguments are equal\n * -1 if second argument is higher.\n * @deprecated Use goog.string.compareVersions.\n */\ngoog.userAgent.compare = function(v1, v2) {\n 'use strict';\n return goog.string.internal.compareVersions(v1, v2);\n};\n\n\n/**\n * Cache for {@link goog.userAgent.isVersionOrHigher}.\n * Calls to compareVersions are surprisingly expensive and, as a browser's\n * version number is unlikely to change during a session, we cache the results.\n * @const\n * @private\n */\ngoog.userAgent.isVersionOrHigherCache_ = {};\n\n\n/**\n * Whether the user agent version is higher or the same as the given version.\n * NOTE: When checking the version numbers for Firefox and Safari, be sure to\n * use the engine's version, not the browser's version number. For example,\n * Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11.\n * Opera and Internet Explorer versions match the product release number.
\n * @see \n * Webkit\n * @see Gecko\n *\n * @param {string|number} version The version to check.\n * @return {boolean} Whether the user agent version is higher or the same as\n * the given version.\n */\ngoog.userAgent.isVersionOrHigher = function(version) {\n 'use strict';\n return goog.userAgent.ASSUME_ANY_VERSION ||\n goog.reflect.cache(\n goog.userAgent.isVersionOrHigherCache_, version, function() {\n 'use strict';\n return goog.string.internal.compareVersions(\n goog.userAgent.VERSION, version) >= 0;\n });\n};\n\n\n/**\n * Whether the IE effective document mode is higher or the same as the given\n * document mode version.\n * NOTE: Only for IE, return false for another browser.\n *\n * @param {number} documentMode The document mode version to check.\n * @return {boolean} Whether the IE effective document mode is higher or the\n * same as the given version.\n */\ngoog.userAgent.isDocumentModeOrHigher = function(documentMode) {\n 'use strict';\n return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode;\n};\n\n\n/**\n * Deprecated alias to `goog.userAgent.isDocumentModeOrHigher`.\n * @param {number} version The version to check.\n * @return {boolean} Whether the IE effective document mode is higher or the\n * same as the given version.\n * @deprecated Use goog.userAgent.isDocumentModeOrHigher().\n */\ngoog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;\n\n\n/**\n * For IE version < 7, documentMode is undefined, so attempt to use the\n * CSS1Compat property to see if we are in standards mode. If we are in\n * standards mode, treat the browser version as the document mode. Otherwise,\n * IE is emulating version 5.\n *\n * NOTE(user): Support for IE < 7 is long gone, so this is now simplified.\n * It returns document.documentMode for IE and undefined for everything else.\n *\n * @type {number|undefined}\n * @const\n */\ngoog.userAgent.DOCUMENT_MODE = (function() {\n 'use strict';\n var doc = goog.global['document'];\n if (!doc || !goog.userAgent.IE) return undefined;\n // This must be an IE user agent.\n var documentMode = goog.userAgent.getDocumentMode_();\n if (documentMode) return documentMode;\n // The user agent version string begins with the major version.\n // Parse the major version and truncate anything following.\n var ieVersion = parseInt(goog.userAgent.VERSION, 10);\n return ieVersion || undefined;\n})();\n","^<",1684857788697,"^=",["^3",["^6R","^>","^9H","^28","^2:","^5H","^9I"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^6R","^9H","^28","^2:","^5H","^9I"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.userAgent"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.labs.userAgent.browser","goog.labs.userAgent.engine","goog.labs.userAgent.platform","goog.labs.userAgent.util","goog.reflect","goog.string.internal"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/useragent.js"],"^[",["^3",["^2T"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2:","^28","^9H","^9I","^6R","^5H"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.userAgent.jscript"]],"^5","goog.useragent.jscript.js","^6",["^7","goog/useragent/jscript.js"],"^8","goog/useragent/jscript.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Detection of JScript version.\n */\n\n\ngoog.provide('goog.userAgent.jscript');\n\ngoog.require('goog.string');\n\n\n/**\n * @define {boolean} True if it is known at compile time that the runtime\n * environment will not be using JScript.\n */\ngoog.userAgent.jscript.ASSUME_NO_JSCRIPT =\n goog.define('goog.userAgent.jscript.ASSUME_NO_JSCRIPT', false);\n\n\n/**\n * Whether we detect that the user agent is using Microsoft JScript.\n * @type {boolean}\n */\ngoog.userAgent.jscript.HAS_JSCRIPT = false;\n\n\n/**\n * The installed version of JScript.\n * @type {string}\n */\ngoog.userAgent.jscript.VERSION = '0';\n\n\n/**\n * Initializer for goog.userAgent.jscript. Detects if the user agent is using\n * Microsoft JScript and which version of it.\n *\n * This is a named function so that it can be stripped via the jscompiler\n * option for stripping types.\n * @package\n */\ngoog.userAgent.jscript.init = function() {\n 'use strict';\n var hasScriptEngine = 'ScriptEngine' in goog.global;\n goog.userAgent.jscript.HAS_JSCRIPT =\n hasScriptEngine && goog.global['ScriptEngine']() == 'JScript';\n if (goog.userAgent.jscript.HAS_JSCRIPT) {\n goog.userAgent.jscript.VERSION = goog.global['ScriptEngineMajorVersion']() +\n '.' + goog.global['ScriptEngineMinorVersion']() + '.' +\n goog.global['ScriptEngineBuildVersion']();\n }\n};\n\nif (!goog.userAgent.jscript.ASSUME_NO_JSCRIPT) {\n goog.userAgent.jscript.init();\n}\n\n/**\n * Whether the installed version of JScript is as new or newer than a given\n * version.\n * @param {string} version The version to check.\n * @return {boolean} Whether the installed version of JScript is as new or\n * newer than the given version.\n */\ngoog.userAgent.jscript.isVersion = function(version) {\n 'use strict';\n return goog.string.compareVersions(goog.userAgent.jscript.VERSION, version) >=\n 0;\n};\n","^<",1684857788697,"^=",["^3",["^2L","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2L"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.userAgent.jscript"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.string"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/jscript.js"],"^[",["^3",["^GJ"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2L"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.userAgentTestUtil.UserAgents","~$goog.userAgentTestUtil"]],"^5","goog.useragent.useragenttestutil.js","^6",["^7","goog/useragent/useragenttestutil.js"],"^8","goog/useragent/useragenttestutil.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Shared test function to reset the constants in\n * goog.userAgent.*\n */\n\ngoog.provide('goog.userAgentTestUtil');\ngoog.provide('goog.userAgentTestUtil.UserAgents');\n\ngoog.require('goog.labs.userAgent.browser');\ngoog.require('goog.labs.userAgent.engine');\ngoog.require('goog.labs.userAgent.platform');\ngoog.require('goog.object');\ngoog.require('goog.userAgent');\ngoog.require('goog.userAgent.keyboard');\ngoog.require('goog.userAgent.platform');\ngoog.require('goog.userAgent.product');\n/** @suppress {extraRequire} */\ngoog.require('goog.userAgent.product.isVersion');\n\ngoog.setTestOnly('goog.userAgentTestUtil');\n\n\n/**\n * Rerun the initialization code to set all of the goog.userAgent constants.\n * @suppress {accessControls}\n */\ngoog.userAgentTestUtil.reinitializeUserAgent = function() {\n 'use strict';\n // Unfortunately we can't isolate the useragent setting in a function\n // we can call, because things rely on it compiling to nothing when\n // one of the ASSUME flags is set, and the compiler isn't smart enough\n // to do that when the setting is done inside a function that's inlined.\n goog.userAgent.OPERA = goog.labs.userAgent.browser.isOpera();\n goog.userAgent.IE = goog.labs.userAgent.browser.isIE();\n goog.userAgent.EDGE = goog.labs.userAgent.engine.isEdge();\n goog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;\n goog.userAgent.GECKO = goog.labs.userAgent.engine.isGecko();\n goog.userAgent.WEBKIT = goog.labs.userAgent.engine.isWebKit();\n goog.userAgent.MOBILE = goog.userAgent.isMobile_();\n goog.userAgent.SAFARI = goog.userAgent.WEBKIT;\n\n // Platform in goog.userAgent.\n goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();\n\n goog.userAgent.MAC = goog.labs.userAgent.platform.isMacintosh();\n goog.userAgent.WINDOWS = goog.labs.userAgent.platform.isWindows();\n goog.userAgent.LINUX = goog.userAgent.isLegacyLinux_();\n goog.userAgent.X11 = goog.userAgent.isX11_();\n goog.userAgent.ANDROID = goog.labs.userAgent.platform.isAndroid();\n goog.userAgent.IPAD = goog.labs.userAgent.platform.isIpad();\n goog.userAgent.IPHONE = goog.labs.userAgent.platform.isIphone();\n goog.userAgent.IPOD = goog.labs.userAgent.platform.isIpod();\n goog.userAgent.KAIOS = goog.labs.userAgent.platform.isKaiOS();\n goog.userAgent.VERSION = goog.userAgent.determineVersion_();\n\n // Platform in goog.userAgent.platform.\n goog.userAgent.platform.VERSION = goog.userAgent.platform.determineVersion_();\n\n // Update goog.userAgent.product\n goog.userAgent.product.ANDROID =\n goog.labs.userAgent.browser.isAndroidBrowser();\n goog.userAgent.product.CHROME = goog.labs.userAgent.browser.isChrome();\n goog.userAgent.product.EDGE = goog.labs.userAgent.browser.isEdge();\n goog.userAgent.product.FIREFOX = goog.labs.userAgent.browser.isFirefox();\n goog.userAgent.product.IE = goog.labs.userAgent.browser.isIE();\n goog.userAgent.product.IPAD = goog.labs.userAgent.platform.isIpad();\n goog.userAgent.product.IPHONE = goog.userAgent.product.isIphoneOrIpod_();\n goog.userAgent.product.OPERA = goog.labs.userAgent.browser.isOpera();\n goog.userAgent.product.SAFARI = goog.userAgent.product.isSafariDesktop_();\n\n // Still uses its own implementation.\n goog.userAgent.product.VERSION = goog.userAgent.product.determineVersion_();\n\n // goog.userAgent.keyboard\n goog.userAgent.keyboard.MAC_KEYBOARD =\n goog.userAgent.keyboard.determineMacKeyboard_();\n\n // Reset cache so calls to isVersionOrHigher don't use cached version.\n goog.object.clear(goog.userAgent.isVersionOrHigherCache_);\n};\n\n\n/**\n * Browser definitions.\n * @enum {string}\n */\ngoog.userAgentTestUtil.UserAgents = {\n GECKO: 'GECKO',\n IE: 'IE',\n OPERA: 'OPERA',\n WEBKIT: 'WEBKIT',\n EDGE: 'EDGE'\n};\n\n\n/**\n * Return whether a given user agent has been detected.\n * @param {string} agent Value in UserAgents.\n * @return {boolean} Whether the user agent has been detected.\n */\ngoog.userAgentTestUtil.getUserAgentDetected = function(agent) {\n 'use strict';\n switch (agent) {\n case goog.userAgentTestUtil.UserAgents.GECKO:\n return goog.userAgent.GECKO;\n case goog.userAgentTestUtil.UserAgents.IE:\n return goog.userAgent.IE;\n case goog.userAgentTestUtil.UserAgents.EDGE:\n return goog.userAgent.EDGE;\n case goog.userAgentTestUtil.UserAgents.OPERA:\n return goog.userAgent.OPERA;\n case goog.userAgentTestUtil.UserAgents.WEBKIT:\n return goog.userAgent.WEBKIT;\n }\n\n throw new Error('Unrecognized user agent');\n};\n","^<",1684857788697,"^=",["^3",["^5D","^GG","^GI","^>","^2F","^2T","^9H","^28","^2:","^GH"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^5D","^GG","^GI","^2F","^2T","^9H","^28","^2:","^GH"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.userAgentTestUtil","goog.userAgentTestUtil.UserAgents"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.labs.userAgent.browser","goog.labs.userAgent.engine","goog.labs.userAgent.platform","goog.object","goog.userAgent","goog.userAgent.keyboard","goog.userAgent.platform","goog.userAgent.product","goog.userAgent.product.isVersion"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/useragenttestutil.js"],"^[",["^3",["^GK","^GL"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2:","^28","^9H","^2F","^2T","^GI","^GG","^5D","^GH"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.userAgent.adobeReader","^1Y","~$goog.userAgent.adobeReader","^U",true,"^5","goog.useragent.adobereader.js","^6",["^7","goog/useragent/adobereader.js"],"^8","goog/useragent/adobereader.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Detects the Adobe Reader PDF browser plugin.\n *\n * @see ../demos/useragent.html\n */\n\ngoog.module('goog.userAgent.adobeReader');\ngoog.module.declareLegacyNamespace();\n\nvar googString = goog.require('goog.string');\nvar userAgent = goog.require('goog.userAgent');\n\n\nvar version = '';\nif (userAgent.IE) {\n var detectOnIe = function(classId) {\n try {\n new ActiveXObject(classId);\n return true;\n } catch (ex) {\n return false;\n }\n };\n if (detectOnIe('AcroPDF.PDF.1')) {\n version = '7';\n } else if (detectOnIe('PDF.PdfCtrl.6')) {\n version = '6';\n }\n // TODO(chrisn): Add detection for previous versions if anyone needs them.\n} else {\n if (navigator.mimeTypes && navigator.mimeTypes.length > 0) {\n var mimeType = navigator.mimeTypes['application/pdf'];\n if (mimeType && mimeType.enabledPlugin) {\n var description = mimeType.enabledPlugin.description;\n if (description && description.indexOf('Adobe') != -1) {\n // Newer plugins do not include the version in the description, so we\n // default to 7.\n version = description.indexOf('Version') != -1 ?\n description.split('Version')[1] :\n '7';\n }\n }\n }\n}\n\n/**\n * Whether we detect the user has the Adobe Reader browser plugin installed.\n * @type {boolean}\n */\nexports.HAS_READER = !!version;\n\n\n/**\n * The version of the installed Adobe Reader plugin. Versions after 7\n * will all be reported as '7'.\n * @type {string}\n */\nexports.VERSION = version;\n\n\n/**\n * On certain combinations of platform/browser/plugin, a print dialog\n * can be shown for PDF files without a download dialog or making the\n * PDF visible to the user, by loading the PDF into a hidden iframe.\n *\n * Currently this variable is true if Adobe Reader version 6 or later\n * is detected on Windows.\n *\n * @type {boolean}\n */\nexports.SILENT_PRINT =\n userAgent.WINDOWS && googString.compareVersions(version, '6') >= 0;\n","^<",1684857788697,"^=",["^3",["^2L","^>","^2T"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2L","^2T"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es3","^T","goog.userAgent.adobeReader","^U",true,"^V",[],"^M",["goog.string","goog.userAgent"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/adobereader.js"],"^[",["^3",["^GM"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2L","^2T"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.userAgent.iphoto"]],"^5","goog.useragent.iphoto.js","^6",["^7","goog/useragent/iphoto.js"],"^8","goog/useragent/iphoto.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Newer versions of iPhoto include a Safari plugin which allows\n * the browser to detect if iPhoto is installed. Adapted from detection code\n * built into the Mac.com Gallery RSS feeds.\n * @see ../demos/useragent.html\n */\n\n\ngoog.provide('goog.userAgent.iphoto');\n\ngoog.require('goog.string');\ngoog.require('goog.userAgent');\n\n\n(function() {\n'use strict';\nvar hasIphoto = false;\nvar version = '';\n\n/**\n * The plugin description string contains the version number as in the form\n * 'iPhoto 700'. This returns just the version number as a dotted string,\n * e.g., '7.0.0', compatible with `goog.string.compareVersions`.\n * @param {string} desc The version string.\n * @return {string} The dotted version.\n */\nfunction getIphotoVersion(desc) {\n var matches = desc.match(/\\d/g);\n return matches.join('.');\n}\n\nif (goog.userAgent.WEBKIT && navigator.mimeTypes &&\n navigator.mimeTypes.length > 0) {\n var iphoto = navigator.mimeTypes['application/photo'];\n\n if (iphoto) {\n hasIphoto = true;\n var description = iphoto['description'];\n\n if (description) {\n version = getIphotoVersion(description);\n }\n }\n}\n\n/**\n * Whether we can detect that the user has iPhoto installed.\n * @type {boolean}\n */\ngoog.userAgent.iphoto.HAS_IPHOTO = hasIphoto;\n\n\n/**\n * The version of iPhoto installed if found.\n * @type {string}\n */\ngoog.userAgent.iphoto.VERSION = version;\n})();\n\n\n/**\n * Whether the installed version of iPhoto is as new or newer than a given\n * version.\n * @param {string} version The version to check.\n * @return {boolean} Whether the installed version of iPhoto is as new or newer\n * than a given version.\n */\ngoog.userAgent.iphoto.isVersion = function(version) {\n 'use strict';\n return goog.string.compareVersions(goog.userAgent.iphoto.VERSION, version) >=\n 0;\n};\n","^<",1684857788697,"^=",["^3",["^2L","^>","^2T"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2L","^2T"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.userAgent.iphoto"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.string","goog.userAgent"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/useragent/iphoto.js"],"^[",["^3",["^GN"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2L","^2T"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",[]],"^T","goog.loader.activeModuleManager","^1Y","~$goog.loader.activeModuleManager","^U",true,"^5","goog.loader.activemodulemanager.js","^6",["^7","goog/loader/activemodulemanager.js"],"^8","goog/loader/activemodulemanager.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview A singleton interface for managing JavaScript code modules.\n */\n\ngoog.module('goog.loader.activeModuleManager');\ngoog.module.declareLegacyNamespace();\n\nconst AbstractModuleManager = goog.require('goog.loader.AbstractModuleManager');\nconst asserts = goog.require('goog.asserts');\n\n/** @type {?AbstractModuleManager} */\nlet moduleManager = null;\n\n/** @type {?function(): !AbstractModuleManager} */\nlet getDefault = null;\n\n/** @type {!Array} */\nlet configureFunctions = [];\n\n/**\n * Applys a configuration function on moduleManager if it exists. Otherwise\n * store the configuration function inside of configureFunctions list so\n * that they can be applied when moduleManager is instantiated.\n * @param {function(!AbstractModuleManager)} configureFn\n */\nfunction configure(configureFn) {\n if (moduleManager) {\n configureFn(moduleManager);\n } else {\n configureFunctions.push(configureFn);\n }\n}\n\n/**\n * Gets the active module manager, instantiating one if necessary.\n * @return {!AbstractModuleManager}\n */\nfunction get() {\n if (!moduleManager && getDefault) {\n set(getDefault());\n }\n asserts.assert(\n moduleManager != null, 'The module manager has not yet been set.');\n return moduleManager;\n}\n\n/**\n * Sets the active module manager. This should never be used to override an\n * existing manager.\n *\n * @param {!AbstractModuleManager} newModuleManager\n */\nfunction set(newModuleManager) {\n asserts.assert(\n moduleManager == null, 'The module manager cannot be redefined.');\n moduleManager = newModuleManager;\n configureFunctions.forEach(configureFn => {\n configureFn(/** @type {!AbstractModuleManager} */ (moduleManager));\n });\n configureFunctions = [];\n}\n\n/**\n * Stores a callback that will be used to get an AbstractModuleManager instance\n * if set() is not called before the first get() call.\n * @param {function(): !AbstractModuleManager} fn\n */\nfunction setDefault(fn) {\n getDefault = fn;\n}\n\n/**\n * Method called just before module code is loaded.\n * @param {string} id Identifier of the module.\n */\nfunction beforeLoadModuleCode(id) {\n if (moduleManager) {\n moduleManager.beforeLoadModuleCode(id);\n }\n}\n\n/**\n * Records that the currently loading module was loaded. Also initiates loading\n * the next module if any module requests are queued. This method is called by\n * code that is generated and appended to each dynamic module's code at\n * compilation time.\n */\nfunction setLoaded() {\n if (moduleManager) {\n moduleManager.setLoaded();\n }\n}\n\n/**\n * Initialize the module manager.\n * @param {string=} info A string representation of the module dependency\n * graph, in the form: module1:dep1,dep2/module2:dep1,dep2 etc.\n * Where depX is the base-36 encoded position of the dep in the module list.\n * @param {!Array=} loadingModuleIds A list of moduleIds that\n * are currently being loaded.\n */\nfunction maybeInitialize(info, loadingModuleIds) {\n if (!moduleManager) {\n if (!getDefault) return;\n set(getDefault());\n }\n moduleManager.setAllModuleInfoString(info, loadingModuleIds);\n}\n\n/** Test-only method for removing the active module manager. */\nconst reset = function() {\n moduleManager = null;\n configureFunctions = [];\n};\n\nexports = {\n get,\n set,\n setDefault,\n beforeLoadModuleCode,\n setLoaded,\n maybeInitialize,\n reset,\n configure,\n};\n","^<",1684857788697,"^=",["^3",["^2?","~$goog.loader.AbstractModuleManager","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2?","^GP"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",[],"^S","es6","^T","goog.loader.activeModuleManager","^U",true,"^V",[],"^M",["goog.loader.AbstractModuleManager","goog.asserts"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/loader/activemodulemanager.js"],"^[",["^3",["^GO"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^GP","^2?"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^GP","~$goog.loader.AbstractModuleManager.CallbackType"]],"^5","goog.loader.abstractmodulemanager.js","^6",["^7","goog/loader/abstractmodulemanager.js"],"^8","goog/loader/abstractmodulemanager.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview The interface for module managers. The default implementation\n * is goog.module.ModuleManager.\n */\n\ngoog.provide('goog.loader.AbstractModuleManager');\ngoog.provide('goog.loader.AbstractModuleManager.CallbackType');\n\ngoog.require('goog.module.AbstractModuleLoader');\ngoog.require('goog.module.ModuleInfo');\ngoog.require('goog.module.ModuleLoadCallback');\ngoog.requireType('goog.html.TrustedResourceUrl');\ngoog.requireType('goog.module.BaseModule');\n\n\n\n/**\n * The ModuleManager keeps track of all modules in the environment.\n * Since modules may not have their code loaded, we must keep track of them.\n * @abstract\n * @constructor\n * @struct\n */\ngoog.loader.AbstractModuleManager = function() {\n 'use strict';\n /**\n * The module context needed for module initialization.\n * @private {?Object}\n */\n this.moduleContext_ = null;\n\n /**\n * A loader for the modules that implements loadModules(ids, moduleInfoMap,\n * opt_successFn, opt_errorFn, opt_timeoutFn, opt_forceReload) method.\n * @private {?goog.module.AbstractModuleLoader}\n */\n this.loader_ = null;\n};\n\n\n/**\n * The type of callbacks that can be registered with the module manager,.\n * @enum {string}\n */\ngoog.loader.AbstractModuleManager.CallbackType = {\n /**\n * Fired when an error has occurred.\n */\n ERROR: 'error',\n\n /**\n * Fired when it becomes idle and has no more module loads to process.\n */\n IDLE: 'idle',\n\n /**\n * Fired when it becomes active and has module loads to process.\n */\n ACTIVE: 'active',\n\n /**\n * Fired when it becomes idle and has no more user-initiated module loads to\n * process.\n */\n USER_IDLE: 'userIdle',\n\n /**\n * Fired when it becomes active and has user-initiated module loads to\n * process.\n */\n USER_ACTIVE: 'userActive'\n};\n\n\n/**\n * A non-HTTP status code indicating a corruption in loaded module.\n * This should be used by a ModuleLoader as a replacement for the HTTP code\n * given to the error handler function to indicated that the module was\n * corrupted.\n * This will set the forceReload flag on the loadModules method when retrying\n * module loading.\n * @type {number}\n */\ngoog.loader.AbstractModuleManager.CORRUPT_RESPONSE_STATUS_CODE = 8001;\n\n\n/**\n * Sets the batch mode as enabled or disabled for the module manager.\n * @param {boolean} enabled Whether the batch mode is to be enabled or not.\n */\ngoog.loader.AbstractModuleManager.prototype.setBatchModeEnabled = function(\n enabled) {};\n\n\n/**\n * Sets the concurrent loading mode as enabled or disabled for the module\n * manager. Requires a moduleloader implementation that supports concurrent\n * loads. The default {@see goog.module.ModuleLoader} does not.\n * @param {boolean} enabled\n */\ngoog.loader.AbstractModuleManager.prototype.setConcurrentLoadingEnabled =\n function(enabled) {};\n\n\n/**\n * Sets the module info for all modules. Should only be called once.\n *\n * @param {!Object>} infoMap An object that contains a mapping\n * from module id (String) to list of required module ids (Array).\n */\ngoog.loader.AbstractModuleManager.prototype.setAllModuleInfo = function(\n infoMap) {};\n\n\n/**\n * Sets the module info for all modules. Should only be called once. Also\n * marks modules that are currently being loaded.\n *\n * @param {string=} opt_info A string representation of the module dependency\n * graph, in the form: module1:dep1,dep2/module2:dep1,dep2 etc.\n * Where depX is the base-36 encoded position of the dep in the module list.\n * @param {!Array=} opt_loadingModuleIds A list of moduleIds that\n * are currently being loaded.\n */\ngoog.loader.AbstractModuleManager.prototype.setAllModuleInfoString = function(\n opt_info, opt_loadingModuleIds) {};\n\n\n/**\n * Gets a module info object by id.\n * @param {string} id A module identifier.\n * @return {!goog.module.ModuleInfo} The module info.\n * @abstract\n */\ngoog.loader.AbstractModuleManager.prototype.getModuleInfo = function(id) {};\n\n/**\n * Register an extra runtime module dependency. After an extra edge is added,\n * any subsequent calls to load or loadMultiple will fetch toModule if the\n * fromModule was loaded.\n *\n * The mechanism for this is implementation dependent. If the implementation\n * does not support extra edges, it will throw an error.\n * @param {string} fromModule The dependent module of the extra edge.\n * @param {string} toModule The module dependency of the extra edge.\n */\ngoog.loader.AbstractModuleManager.prototype.addExtraEdge = function(\n fromModule, toModule) {\n 'use strict';\n throw new Error('addExtraEdge is not implemented.');\n};\n\n/**\n * Remove an existing extra edge previously added by `addExtraEdge`.\n *\n * If the implementation does not support extra edges, it will throw an error.\n * @param {string} fromModule The dependent module of the extra edge.\n * @param {string} toModule The module dependency of the extra edge.\n */\ngoog.loader.AbstractModuleManager.prototype.removeExtraEdge = function(\n fromModule, toModule) {\n 'use strict';\n throw new Error('removeExtraEdge is not implemented.');\n};\n\n/**\n * Sets the module uris.\n * @param {!Object>} moduleUriMap\n * The map of id/uris pairs for each module.\n */\ngoog.loader.AbstractModuleManager.prototype.setModuleTrustedUris = function(\n moduleUriMap) {};\n\n\n/**\n * Gets the application-specific module loader.\n * @return {?goog.module.AbstractModuleLoader} the loader.\n */\ngoog.loader.AbstractModuleManager.prototype.getLoader = function() {\n 'use strict';\n return this.loader_;\n};\n\n\n/**\n * Sets the application-specific module loader.\n * @param {!goog.module.AbstractModuleLoader} loader\n */\ngoog.loader.AbstractModuleManager.prototype.setLoader = function(loader) {\n 'use strict';\n this.loader_ = loader;\n};\n\n\n/**\n * Gets the module context to use to initialize the module.\n * @return {?Object} The context.\n */\ngoog.loader.AbstractModuleManager.prototype.getModuleContext = function() {\n 'use strict';\n return this.moduleContext_;\n};\n\n\n/**\n * Sets the module context to use to initialize the module.\n * @param {!Object} context The context.\n */\ngoog.loader.AbstractModuleManager.prototype.setModuleContext = function(\n context) {\n 'use strict';\n this.moduleContext_ = context;\n};\n\n\n/**\n * Determines if the ModuleManager is active\n * @return {boolean} TRUE iff the ModuleManager is active (i.e., not idle).\n */\ngoog.loader.AbstractModuleManager.prototype.isActive = function() {\n 'use strict';\n return false;\n};\n\n\n/**\n * Determines if the ModuleManager is user active\n * @return {boolean} TRUE iff the ModuleManager is user active (i.e., not idle).\n */\ngoog.loader.AbstractModuleManager.prototype.isUserActive = function() {\n 'use strict';\n return false;\n};\n\n\n/**\n * Preloads a module after a short delay.\n *\n * @param {string} id The id of the module to preload.\n * @param {number=} opt_timeout The number of ms to wait before adding the\n * module id to the loading queue (defaults to 0 ms). Note that the module\n * will be loaded asynchronously regardless of the value of this parameter.\n * @return {!IThenable}\n * @abstract\n */\ngoog.loader.AbstractModuleManager.prototype.preloadModule = function(\n id, opt_timeout) {};\n\n\n/**\n * Prefetches a JavaScript module and its dependencies, which means that the\n * module will be downloaded, but not evaluated. To complete the module load,\n * the caller should also call load or execOnLoad after prefetching the module.\n *\n * @param {string} id The id of the module to prefetch.\n */\ngoog.loader.AbstractModuleManager.prototype.prefetchModule = function(id) {\n 'use strict';\n throw new Error('prefetchModule is not implemented.');\n};\n\n\n/**\n * Records that the currently loading module was loaded. Also initiates loading\n * the next module if any module requests are queued. This method is called by\n * code that is generated and appended to each dynamic module's code at\n * compilation time.\n *\n * @abstract\n */\ngoog.loader.AbstractModuleManager.prototype.setLoaded = function() {};\n\n\n/**\n * Gets whether a module is currently loading or in the queue, waiting to be\n * loaded.\n * @param {string} id A module id.\n * @return {boolean} TRUE iff the module is loading.\n * @abstract\n */\ngoog.loader.AbstractModuleManager.prototype.isModuleLoading = function(id) {};\n\n\n/**\n * Requests that a function be called once a particular module is loaded.\n * Client code can use this method to safely call into modules that may not yet\n * be loaded. For consistency, this method always calls the function\n * asynchronously -- even if the module is already loaded. Initiates loading of\n * the module if necessary, unless opt_noLoad is true.\n *\n * @param {string} moduleId A module id.\n * @param {!Function} fn Function to execute when the module has loaded.\n * @param {!Object=} opt_handler Optional handler under whose scope to execute\n * the callback.\n * @param {boolean=} opt_noLoad TRUE iff not to initiate loading of the module.\n * @param {boolean=} opt_userInitiated TRUE iff the loading of the module was\n * user initiated.\n * @param {boolean=} opt_preferSynchronous TRUE iff the function should be\n * executed synchronously if the module has already been loaded.\n * @return {!goog.module.ModuleLoadCallback} A callback wrapper that exposes\n * an abort and execute method.\n * @abstract\n */\ngoog.loader.AbstractModuleManager.prototype.execOnLoad = function(\n moduleId, fn, opt_handler, opt_noLoad, opt_userInitiated,\n opt_preferSynchronous) {};\n\n\n/**\n * Loads a module, returning an IThenable for keeping track of the result.\n *\n * @param {string} moduleId A module id.\n * @param {boolean=} opt_userInitiated If the load is a result of a user action.\n * @return {!IThenable} A deferred object.\n * @abstract\n */\ngoog.loader.AbstractModuleManager.prototype.load = function(\n moduleId, opt_userInitiated) {};\n\n\n/**\n * Loads a list of modules, returning a map of IThenables for keeping track of\n * the results.\n *\n * @param {!Array} moduleIds A list of module ids.\n * @param {boolean=} opt_userInitiated If the load is a result of a user action.\n * @return {!Object} A mapping from id (String)\n * to deferred objects that will callback or errback when the load for that\n * id is finished.\n * @abstract\n */\ngoog.loader.AbstractModuleManager.prototype.loadMultiple = function(\n moduleIds, opt_userInitiated) {};\n\n\n/**\n * Method called just before module code is loaded.\n * @param {string} id Identifier of the module.\n * @abstract\n */\ngoog.loader.AbstractModuleManager.prototype.beforeLoadModuleCode = function(\n id) {};\n\n\n/**\n * Register an initialization callback for the currently loading module. This\n * should only be called by script that is executed during the evaluation of\n * a module's javascript. This is almost equivalent to calling the function\n * inline, but ensures that all the code from the currently loading module\n * has been loaded. This makes it cleaner and more robust than calling the\n * function inline.\n *\n * If this function is called from the base module (the one that contains\n * the module manager code), the callback is held until #setAllModuleInfo\n * is called, or until #setModuleContext is called, whichever happens first.\n *\n * @param {!Function} fn A callback function that takes a single argument\n * which is the module context.\n * @param {!Object=} opt_handler Optional handler under whose scope to execute\n * the callback.\n */\ngoog.loader.AbstractModuleManager.prototype.registerInitializationCallback =\n function(fn, opt_handler) {};\n\n\n/**\n * Register a late initialization callback for the currently loading module.\n * Callbacks registered via this function are executed similar to\n * {@see registerInitializationCallback}, but they are fired after all\n * initialization callbacks are called.\n *\n * @param {!Function} fn A callback function that takes a single argument\n * which is the module context.\n * @param {!Object=} opt_handler Optional handler under whose scope to execute\n * the callback.\n */\ngoog.loader.AbstractModuleManager.prototype.registerLateInitializationCallback =\n function(fn, opt_handler) {};\n\n\n/**\n * Sets the constructor to use for the module object for the currently\n * loading module. The constructor should derive from\n * {@see goog.module.BaseModule}.\n * @param {function(new:goog.module.BaseModule)} fn The constructor function.\n */\ngoog.loader.AbstractModuleManager.prototype.setModuleConstructor = function(\n fn) {};\n\n\n/**\n * The function to call if the module manager is in error.\n * @param {!goog.loader.AbstractModuleManager.CallbackType|!Array<\n * !goog.loader.AbstractModuleManager.CallbackType>} types The callback\n * type.\n * @param {!Function} fn The function to register as a callback.\n */\ngoog.loader.AbstractModuleManager.prototype.registerCallback = function(\n types, fn) {};\n","^<",1684857788697,"^=",["^3",["~$goog.module.AbstractModuleLoader","~$goog.module.ModuleLoadCallback","~$goog.module.ModuleInfo","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^GR","^GS","^GT"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.loader.AbstractModuleManager","goog.loader.AbstractModuleManager.CallbackType"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.module.AbstractModuleLoader","goog.module.ModuleInfo","goog.module.ModuleLoadCallback"],"^W",["goog.html.TrustedResourceUrl","goog.module.BaseModule"],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/loader/abstractmodulemanager.js"],"^[",["^3",["^GP","^GQ"]],"^W",["^3",["^5>","~$goog.module.BaseModule"]],"^10",true,"^11",true,"^12",["^>","^GR","^GT","^GS"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^5H"]],"^5","goog.string.internal.js","^6",["^7","goog/string/internal.js"],"^8","goog/string/internal.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview String functions called from Closure packages that couldn't\n * depend on each other. Outside Closure, use goog.string function which\n * delegate to these.\n */\n\n\ngoog.provide('goog.string.internal');\n\n\n/**\n * Fast prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the start of `str`.\n * @return {boolean} True if `str` begins with `prefix`.\n * @see goog.string.startsWith\n */\ngoog.string.internal.startsWith = function(str, prefix) {\n 'use strict';\n return str.lastIndexOf(prefix, 0) == 0;\n};\n\n\n/**\n * Fast suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix`.\n * @see goog.string.endsWith\n */\ngoog.string.internal.endsWith = function(str, suffix) {\n 'use strict';\n const l = str.length - suffix.length;\n return l >= 0 && str.indexOf(suffix, l) == l;\n};\n\n\n/**\n * Case-insensitive prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the end of `str`.\n * @return {boolean} True if `str` begins with `prefix` (ignoring\n * case).\n * @see goog.string.caseInsensitiveStartsWith\n */\ngoog.string.internal.caseInsensitiveStartsWith = function(str, prefix) {\n 'use strict';\n return (\n goog.string.internal.caseInsensitiveCompare(\n prefix, str.slice(0, prefix.length)) == 0);\n};\n\n\n/**\n * Case-insensitive suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix` (ignoring\n * case).\n * @see goog.string.caseInsensitiveEndsWith\n */\ngoog.string.internal.caseInsensitiveEndsWith = function(str, suffix) {\n 'use strict';\n return (\n goog.string.internal.caseInsensitiveCompare(\n suffix, str.slice(str.length - suffix.length)) == 0);\n};\n\n\n/**\n * Case-insensitive equality checker.\n * @param {string} str1 First string to check.\n * @param {string} str2 Second string to check.\n * @return {boolean} True if `str1` and `str2` are the same string,\n * ignoring case.\n * @see goog.string.caseInsensitiveEquals\n */\ngoog.string.internal.caseInsensitiveEquals = function(str1, str2) {\n 'use strict';\n return str1.toLowerCase() == str2.toLowerCase();\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n * @see goog.string.isEmptyOrWhitespace\n */\ngoog.string.internal.isEmptyOrWhitespace = function(str) {\n 'use strict';\n // testing length == 0 first is actually slower in all browsers (about the\n // same in Opera).\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return /^[\\s\\xa0]*$/.test(str);\n};\n\n\n/**\n * Trims white spaces to the left and right of a string.\n * @param {string} str The string to trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.internal.trim =\n (goog.TRUSTED_SITE && String.prototype.trim) ? function(str) {\n 'use strict';\n return str.trim();\n } : function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s\n // character class (as required by section 7.2 of the ECMAScript spec),\n // we explicitly include it in the regexp to enforce consistent\n // cross-browser behavior.\n // NOTE: We don't use String#replace because it might have side effects\n // causing this function to not compile to 0 bytes.\n return /^[\\s\\xa0]*([\\s\\S]*?)[\\s\\xa0]*$/.exec(str)[1];\n };\n\n\n/**\n * A string comparator that ignores case.\n * -1 = str1 less than str2\n * 0 = str1 equals str2\n * 1 = str1 greater than str2\n *\n * @param {string} str1 The string to compare.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} The comparator result, as described above.\n * @see goog.string.caseInsensitiveCompare\n */\ngoog.string.internal.caseInsensitiveCompare = function(str1, str2) {\n 'use strict';\n const test1 = String(str1).toLowerCase();\n const test2 = String(str2).toLowerCase();\n\n if (test1 < test2) {\n return -1;\n } else if (test1 == test2) {\n return 0;\n } else {\n return 1;\n }\n};\n\n\n/**\n * Converts \\n to
s or
s.\n * @param {string} str The string in which to convert newlines.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} A copy of `str` with converted newlines.\n * @see goog.string.newLineToBr\n */\ngoog.string.internal.newLineToBr = function(str, opt_xml) {\n 'use strict';\n return str.replace(/(\\r\\n|\\r|\\n)/g, opt_xml ? '
' : '
');\n};\n\n\n/**\n * Escapes double quote '\"' and single quote '\\'' characters in addition to\n * '&', '<', and '>' so that a string can be included in an HTML tag attribute\n * value within double or single quotes.\n * @param {string} str string to be escaped.\n * @param {boolean=} opt_isLikelyToContainHtmlChars\n * @return {string} An escaped copy of `str`.\n * @see goog.string.htmlEscape\n */\ngoog.string.internal.htmlEscape = function(\n str, opt_isLikelyToContainHtmlChars) {\n 'use strict';\n if (opt_isLikelyToContainHtmlChars) {\n str = str.replace(goog.string.internal.AMP_RE_, '&')\n .replace(goog.string.internal.LT_RE_, '<')\n .replace(goog.string.internal.GT_RE_, '>')\n .replace(goog.string.internal.QUOT_RE_, '"')\n .replace(goog.string.internal.SINGLE_QUOTE_RE_, ''')\n .replace(goog.string.internal.NULL_RE_, '�');\n return str;\n\n } else {\n // quick test helps in the case when there are no chars to replace, in\n // worst case this makes barely a difference to the time taken\n if (!goog.string.internal.ALL_RE_.test(str)) return str;\n\n // str.indexOf is faster than regex.test in this case\n if (str.indexOf('&') != -1) {\n str = str.replace(goog.string.internal.AMP_RE_, '&');\n }\n if (str.indexOf('<') != -1) {\n str = str.replace(goog.string.internal.LT_RE_, '<');\n }\n if (str.indexOf('>') != -1) {\n str = str.replace(goog.string.internal.GT_RE_, '>');\n }\n if (str.indexOf('\"') != -1) {\n str = str.replace(goog.string.internal.QUOT_RE_, '"');\n }\n if (str.indexOf('\\'') != -1) {\n str = str.replace(goog.string.internal.SINGLE_QUOTE_RE_, ''');\n }\n if (str.indexOf('\\x00') != -1) {\n str = str.replace(goog.string.internal.NULL_RE_, '�');\n }\n return str;\n }\n};\n\n\n/**\n * Regular expression that matches an ampersand, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.AMP_RE_ = /&/g;\n\n\n/**\n * Regular expression that matches a less than sign, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.LT_RE_ = //g;\n\n\n/**\n * Regular expression that matches a double quote, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.QUOT_RE_ = /\"/g;\n\n\n/**\n * Regular expression that matches a single quote, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.SINGLE_QUOTE_RE_ = /'/g;\n\n\n/**\n * Regular expression that matches null character, for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.NULL_RE_ = /\\x00/g;\n\n\n/**\n * Regular expression that matches any character that needs to be escaped.\n * @const {!RegExp}\n * @private\n */\ngoog.string.internal.ALL_RE_ = /[\\x00&<>\"']/;\n\n\n/**\n * Do escaping of whitespace to preserve spatial formatting. We use character\n * entity #160 to make it safer for xml.\n * @param {string} str The string in which to escape whitespace.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} An escaped copy of `str`.\n * @see goog.string.whitespaceEscape\n */\ngoog.string.internal.whitespaceEscape = function(str, opt_xml) {\n 'use strict';\n // This doesn't use goog.string.preserveSpaces for backwards compatibility.\n return goog.string.internal.newLineToBr(\n str.replace(/ /g, '  '), opt_xml);\n};\n\n\n/**\n * Determines whether a string contains a substring.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n * @see goog.string.contains\n */\ngoog.string.internal.contains = function(str, subString) {\n 'use strict';\n return str.indexOf(subString) != -1;\n};\n\n\n/**\n * Determines whether a string contains a substring, ignoring case.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n * @see goog.string.caseInsensitiveContains\n */\ngoog.string.internal.caseInsensitiveContains = function(str, subString) {\n 'use strict';\n return goog.string.internal.contains(\n str.toLowerCase(), subString.toLowerCase());\n};\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string|number} version1 Version of first item.\n * @param {string|number} version2 Version of second item.\n *\n * @return {number} 1 if `version1` is higher.\n * 0 if arguments are equal.\n * -1 if `version2` is higher.\n * @see goog.string.compareVersions\n */\ngoog.string.internal.compareVersions = function(version1, version2) {\n 'use strict';\n let order = 0;\n // Trim leading and trailing whitespace and split the versions into\n // subversions.\n const v1Subs = goog.string.internal.trim(String(version1)).split('.');\n const v2Subs = goog.string.internal.trim(String(version2)).split('.');\n const subCount = Math.max(v1Subs.length, v2Subs.length);\n\n // Iterate over the subversions, as long as they appear to be equivalent.\n for (let subIdx = 0; order == 0 && subIdx < subCount; subIdx++) {\n let v1Sub = v1Subs[subIdx] || '';\n let v2Sub = v2Subs[subIdx] || '';\n\n do {\n // Split the subversions into pairs of numbers and qualifiers (like 'b').\n // Two different RegExp objects are use to make it clear the code\n // is side-effect free\n const v1Comp = /(\\d*)(\\D*)(.*)/.exec(v1Sub) || ['', '', '', ''];\n const v2Comp = /(\\d*)(\\D*)(.*)/.exec(v2Sub) || ['', '', '', ''];\n // Break if there are no more matches.\n if (v1Comp[0].length == 0 && v2Comp[0].length == 0) {\n break;\n }\n\n // Parse the numeric part of the subversion. A missing number is\n // equivalent to 0.\n const v1CompNum = v1Comp[1].length == 0 ? 0 : parseInt(v1Comp[1], 10);\n const v2CompNum = v2Comp[1].length == 0 ? 0 : parseInt(v2Comp[1], 10);\n\n // Compare the subversion components. The number has the highest\n // precedence. Next, if the numbers are equal, a subversion without any\n // qualifier is always higher than a subversion with any qualifier. Next,\n // the qualifiers are compared as strings.\n order = goog.string.internal.compareElements_(v1CompNum, v2CompNum) ||\n goog.string.internal.compareElements_(\n v1Comp[2].length == 0, v2Comp[2].length == 0) ||\n goog.string.internal.compareElements_(v1Comp[2], v2Comp[2]);\n // Stop as soon as an inequality is discovered.\n\n v1Sub = v1Comp[3];\n v2Sub = v2Comp[3];\n } while (order == 0);\n }\n\n return order;\n};\n\n\n/**\n * Compares elements of a version number.\n *\n * @param {string|number|boolean} left An element from a version number.\n * @param {string|number|boolean} right An element from a version number.\n *\n * @return {number} 1 if `left` is higher.\n * 0 if arguments are equal.\n * -1 if `right` is higher.\n * @private\n */\ngoog.string.internal.compareElements_ = function(left, right) {\n 'use strict';\n if (left < right) {\n return -1;\n } else if (left > right) {\n return 1;\n }\n return 0;\n};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.string.internal"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/string/internal.js"],"^[",["^3",["^5H"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.string.linkify"]],"^5","goog.string.linkify.js","^6",["^7","goog/string/linkify.js"],"^8","goog/string/linkify.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utility function for linkifying text.\n */\n\ngoog.provide('goog.string.linkify');\n\ngoog.require('goog.asserts');\ngoog.require('goog.html.SafeHtml');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.string');\ngoog.require('goog.string.Const');\n\n\n/**\n * Options bag for linkifyPlainTextAsHtml's second parameter.\n * @record\n */\ngoog.string.linkify.LinkifyOptions = class {\n constructor() {\n /**\n * HTML attributes to add to all links created. Default are `rel=nofollow`\n * and `target=_blank`. To clear these defaults attributes, set them\n * explicitly to '', i.e. `{rel: '', target: ''}`.\n * @const {!Object|undefined}\n */\n this.attributes;\n /**\n * Whether to preserve newlines with <br>.\n * @const {boolean|undefined}\n */\n this.preserveNewlines;\n /**\n * Whether to preserve spaces with non-breaking spaces and tabs with\n * <span style=\"white-space:pre\">\n * @const {boolean|undefined}\n */\n this.preserveSpacesAndTabs;\n }\n};\n\n\n/**\n * Takes a string of plain text and linkifies URLs and email addresses. For a\n * URL (unless opt_attributes is specified), the target of the link will be\n * _blank and it will have a rel=nofollow attribute applied to it so that links\n * created by linkify will not be of interest to search engines.\n * @param {string} text Plain text.\n * @param {!goog.string.linkify.LinkifyOptions=} opt_options Options bag.\n * @return {!goog.html.SafeHtml} Linkified HTML. Any text that is not part of a\n * link will be HTML-escaped.\n * @suppress {strictMissingProperties} opt_attributes type is a union\n */\ngoog.string.linkify.linkifyPlainTextAsHtml = function(text, opt_options) {\n 'use strict';\n const {attributes = {}, preserveNewlines, preserveSpacesAndTabs, ...rest} =\n opt_options || {};\n if (goog.DEBUG) {\n for (const key in rest) {\n if (rest.hasOwnProperty(key)) {\n goog.asserts.fail(`Unexpected option: ${key}`);\n }\n }\n }\n\n /**\n * @param {string} plainText\n * @return {!goog.html.SafeHtml} html\n */\n const htmlEscape = function(plainText) {\n if (preserveSpacesAndTabs) {\n const html = goog.html.SafeHtml.htmlEscape(plainText);\n let modifiedHtml =\n goog.html.SafeHtml\n .unwrap(html)\n // Leading space is converted into a non-breaking space, and\n // spaces following whitespace are converted into non-breaking\n // spaces. This must happen first, to ensure we preserve spaces\n // after newlines.\n .replace(/(^|[\\n\\r\\t\\ ])\\ /g, '$1 ')\n // Preserve tabs by using style=\"white-space:pre\"\n .replace(/(\\t+)/g, '$1');\n if (preserveNewlines) {\n modifiedHtml = goog.string.newLineToBr(modifiedHtml);\n }\n return goog.html.uncheckedconversions\n .safeHtmlFromStringKnownToSatisfyTypeContract(\n goog.string.Const.from('Escaped plain text'), modifiedHtml);\n } else if (preserveNewlines) {\n return goog.html.SafeHtml.htmlEscapePreservingNewlines(plainText);\n } else {\n return goog.html.SafeHtml.htmlEscape(plainText);\n }\n };\n\n // This shortcut makes linkifyPlainText ~10x faster if text doesn't contain\n // URLs or email addresses and adds insignificant performance penalty if it\n // does.\n if (text.indexOf('@') == -1 && text.indexOf('://') == -1 &&\n text.indexOf('www.') == -1 && text.indexOf('Www.') == -1 &&\n text.indexOf('WWW.') == -1) {\n return htmlEscape(text);\n }\n\n const attributesMap = {};\n for (let key in attributes) {\n if (!attributes[key]) {\n // Our API allows '' to omit the attribute, SafeHtml requires null.\n attributesMap[key] = null;\n } else {\n attributesMap[key] = attributes[key];\n }\n }\n // Set default options if they haven't been explicitly set.\n if (!('rel' in attributesMap)) {\n attributesMap['rel'] = 'nofollow';\n }\n if (!('target' in attributesMap)) {\n attributesMap['target'] = '_blank';\n }\n\n const output = [];\n // Return value is ignored.\n text.replace(\n goog.string.linkify.FIND_LINKS_RE_,\n function(part, before, original, email, protocol) {\n 'use strict';\n output.push(htmlEscape(before));\n if (!original) {\n return '';\n }\n let href = '';\n /** @type {string} */\n let linkText;\n /** @type {string} */\n let afterLink;\n if (email) {\n href = 'mailto:';\n linkText = email;\n afterLink = '';\n } else {\n // This is a full url link.\n if (!protocol) {\n href = 'http://';\n }\n const splitEndingPunctuation =\n original.match(goog.string.linkify.ENDS_WITH_PUNCTUATION_RE_);\n // An open paren in the link will often be matched with a close paren\n // at the end, so skip cutting off ending punctuation if\n // opening/closing parens are matched in the link. Same for curly\n // brackets. For example:\n // End symbol is linkified:\n // * http://en.wikipedia.org/wiki/Titanic_(1997_film)\n // * http://google.com/abc{arg=1}\n // e.g. needEndingPunctuationForBalance for split\n // 'http://google.com/abc{arg=', and '} is true.\n // End symbol is not linkified because there is no open parens to\n // close in the link itself, as the open parens occurs before the URL:\n // * (http://google.com/)\n // e.g. needEndingPunctuationForBalance for split 'http://google.com/\n // and ')' is false.\n function needEndingPunctuationForBalance(\n split, openSymbol, closeSymbol) {\n return goog.string.contains(split[2], closeSymbol) &&\n goog.string.countOf(split[1], openSymbol) >\n goog.string.countOf(split[1], closeSymbol);\n }\n if (splitEndingPunctuation &&\n !needEndingPunctuationForBalance(\n splitEndingPunctuation, '(', ')') &&\n !needEndingPunctuationForBalance(\n splitEndingPunctuation, '{', '}')) {\n linkText = splitEndingPunctuation[1];\n afterLink = splitEndingPunctuation[2];\n } else {\n linkText = original;\n afterLink = '';\n }\n }\n attributesMap['href'] = href + linkText;\n output.push(goog.html.SafeHtml.create('a', attributesMap, linkText));\n output.push(htmlEscape(afterLink));\n return '';\n });\n return goog.html.SafeHtml.concat(output);\n};\n\n\n/**\n * Gets the first URI in text.\n * @param {string} text Plain text.\n * @return {string} The first URL, or an empty string if not found.\n */\ngoog.string.linkify.findFirstUrl = function(text) {\n 'use strict';\n const link = text.match(goog.string.linkify.URL_RE_);\n return link != null ? link[0] : '';\n};\n\n\n/**\n * Gets the first email address in text.\n * @param {string} text Plain text.\n * @return {string} The first email address, or an empty string if not found.\n */\ngoog.string.linkify.findFirstEmail = function(text) {\n 'use strict';\n const email = text.match(goog.string.linkify.EMAIL_RE_);\n return email != null ? email[0] : '';\n};\n\n\n/**\n * If a series of these characters is at the end of a url, it will be considered\n * punctuation and not part of the url.\n * @type {string}\n * @const\n * @private\n */\ngoog.string.linkify.ENDING_PUNCTUATION_CHARS_ = '\\':;,\\\\.?}\\\\]\\\\)!';\n\n\n/**\n * @type {!RegExp}\n * @const\n * @private\n */\ngoog.string.linkify.ENDS_WITH_PUNCTUATION_RE_ = new RegExp(\n '^(.*?)([' + goog.string.linkify.ENDING_PUNCTUATION_CHARS_ + ']+)$');\n\n\n/**\n * Set of characters to be put into a regex character set (\"[...]\"), used to\n * match against a url hostname and everything after it. It includes, in order,\n * \\w which represents [a-zA-Z0-9_], \"#-;\" which represents the characters\n * \"#$%&'()*+,-./0123456789:;\" and the characters \"!=?@[\\]`{|}~\".\n * @type {string}\n * @const\n * @private\n */\ngoog.string.linkify.ACCEPTABLE_URL_CHARS_ = '\\\\w#-;!=?@\\\\[\\\\\\\\\\\\]_`{|}~';\n\n\n/**\n * List of all protocols patterns recognized in urls (mailto is handled in email\n * matching).\n * @type {!Array}\n * @const\n * @private\n */\ngoog.string.linkify.RECOGNIZED_PROTOCOLS_ = ['https?', 'ftp'];\n\n\n/**\n * Regular expression pattern that matches the beginning of an url.\n * Contains a catching group to capture the scheme.\n * @type {string}\n * @const\n * @private\n */\ngoog.string.linkify.PROTOCOL_START_ =\n '(' + goog.string.linkify.RECOGNIZED_PROTOCOLS_.join('|') + ')://';\n\n\n/**\n * Regular expression pattern that matches the beginning of a typical\n * http url without the http:// scheme.\n * @type {string}\n * @const\n * @private\n */\ngoog.string.linkify.WWW_START_ = 'www\\\\.';\n\n\n/**\n * Regular expression pattern that matches an url.\n * @type {string}\n * @const\n * @private\n */\ngoog.string.linkify.URL_RE_STRING_ =\n '(?:' + goog.string.linkify.PROTOCOL_START_ + '|' +\n goog.string.linkify.WWW_START_ + ')[' +\n goog.string.linkify.ACCEPTABLE_URL_CHARS_ + ']+';\n\n\n/**\n * Regular expression that matches an url. Case-insensitive.\n * @type {!RegExp}\n * @const\n * @private\n */\ngoog.string.linkify.URL_RE_ =\n new RegExp(goog.string.linkify.URL_RE_STRING_, 'i');\n\n\n/**\n * Regular expression pattern that matches a top level domain.\n * @type {string}\n * @const\n * @private\n */\ngoog.string.linkify.TOP_LEVEL_DOMAIN_ = '(?:com|org|net|edu|gov' +\n // from http://www.iana.org/gtld/gtld.htm\n '|aero|biz|cat|coop|info|int|jobs|mobi|museum|name|pro|travel' +\n '|arpa|asia|xxx' +\n // a two letter country code\n '|[a-z][a-z])\\\\b';\n\n\n/**\n * Regular expression pattern that matches an email.\n * Contains a catching group to capture the email without the optional \"mailto:\"\n * prefix.\n * @type {string}\n * @const\n * @private\n */\ngoog.string.linkify.EMAIL_RE_STRING_ =\n '(?:mailto:)?([\\\\w.!#$%&\\'*+-/=?^_`{|}~]+@[A-Za-z0-9.-]+\\\\.' +\n goog.string.linkify.TOP_LEVEL_DOMAIN_ + ')';\n\n\n/**\n * Regular expression that matches an email. Case-insensitive.\n * @type {!RegExp}\n * @const\n * @private\n */\ngoog.string.linkify.EMAIL_RE_ =\n new RegExp(goog.string.linkify.EMAIL_RE_STRING_, 'i');\n\n\n/**\n * Regular expression to match all the links (url or email) in a string.\n * First match is text before first link, might be empty string.\n * Second match is the original text that should be replaced by a link.\n * Third match is the email address in the case of an email.\n * Fourth match is the scheme of the url if specified.\n * @type {!RegExp}\n * @const\n * @private\n */\ngoog.string.linkify.FIND_LINKS_RE_ = new RegExp(\n // Match everything including newlines.\n '([\\\\S\\\\s]*?)(' +\n // Match email after a word break.\n '\\\\b' + goog.string.linkify.EMAIL_RE_STRING_ + '|' +\n // Match url after a word break.\n '\\\\b' + goog.string.linkify.URL_RE_STRING_ + '|$)',\n 'gi');\n","^<",1684857788697,"^=",["^3",["^2?","^2L","^>","^4C","^4D","^2O"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2?","^2L","^4C","^4D","^2O"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.string.linkify"],"^S","es9","^T",null,"^U",false,"^V",[],"^M",["goog.asserts","goog.html.SafeHtml","goog.html.uncheckedconversions","goog.string","goog.string.Const"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/string/linkify.js"],"^[",["^3",["^GV"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2?","^2O","^4C","^2L","^4D"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^2G"]],"^5","goog.string.stringbuffer.js","^6",["^7","goog/string/stringbuffer.js"],"^8","goog/string/stringbuffer.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utility for fast string concatenation.\n */\n\ngoog.provide('goog.string.StringBuffer');\n\n\n\n/**\n * Utility class to facilitate string concatenation.\n *\n * @param {*=} opt_a1 Optional first initial item to append.\n * @param {...*} var_args Other initial items to\n * append, e.g., new goog.string.StringBuffer('foo', 'bar').\n * @constructor\n */\ngoog.string.StringBuffer = function(opt_a1, var_args) {\n 'use strict';\n if (opt_a1 != null) {\n this.append.apply(this, arguments);\n }\n};\n\n\n/**\n * Internal buffer for the string to be concatenated.\n * @type {string}\n * @private\n */\ngoog.string.StringBuffer.prototype.buffer_ = '';\n\n\n/**\n * Sets the contents of the string buffer object, replacing what's currently\n * there.\n *\n * @param {*} s String to set.\n */\ngoog.string.StringBuffer.prototype.set = function(s) {\n 'use strict';\n this.buffer_ = '' + s;\n};\n\n\n/**\n * Appends one or more items to the buffer.\n *\n * Calling this with null, undefined, or empty arguments is an error.\n *\n * @param {*} a1 Required first string.\n * @param {*=} opt_a2 Optional second string.\n * @param {...?} var_args Other items to append,\n * e.g., sb.append('foo', 'bar', 'baz').\n * @return {!goog.string.StringBuffer} This same StringBuffer object.\n * @suppress {duplicate}\n */\ngoog.string.StringBuffer.prototype.append = function(a1, opt_a2, var_args) {\n 'use strict';\n // Use a1 directly to avoid arguments instantiation for single-arg case.\n this.buffer_ += String(a1);\n if (opt_a2 != null) { // second argument is undefined (null == undefined)\n for (let i = 1; i < arguments.length; i++) {\n this.buffer_ += arguments[i];\n }\n }\n return this;\n};\n\n\n/**\n * Clears the internal buffer.\n */\ngoog.string.StringBuffer.prototype.clear = function() {\n 'use strict';\n this.buffer_ = '';\n};\n\n\n/**\n * @return {number} the length of the current contents of the buffer.\n */\ngoog.string.StringBuffer.prototype.getLength = function() {\n 'use strict';\n return this.buffer_.length;\n};\n\n\n/**\n * @return {string} The concatenated string.\n * @override\n */\ngoog.string.StringBuffer.prototype.toString = function() {\n 'use strict';\n return this.buffer_;\n};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.string.StringBuffer"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/string/stringbuffer.js"],"^[",["^3",["^2G"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["~$goog.string.TypedString"]],"^5","goog.string.typedstring.js","^6",["^7","goog/string/typedstring.js"],"^8","goog/string/typedstring.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.string.TypedString');\n\n\n\n/**\n * Wrapper for strings that conform to a data type or language.\n *\n * Implementations of this interface are wrappers for strings, and typically\n * associate a type contract with the wrapped string. Concrete implementations\n * of this interface may choose to implement additional run-time type checking,\n * see for example `goog.html.SafeHtml`. If available, client code that\n * needs to ensure type membership of an object should use the type's function\n * to assert type membership, such as `goog.html.SafeHtml.unwrap`.\n * @interface\n */\ngoog.string.TypedString = function() {};\n\n\n/**\n * Interface marker of the TypedString interface.\n *\n * This property can be used to determine at runtime whether or not an object\n * implements this interface. All implementations of this interface set this\n * property to `true`.\n * @type {boolean}\n */\ngoog.string.TypedString.prototype.implementsGoogStringTypedString;\n\n\n/**\n * Retrieves this wrapped string's value.\n * @return {string} The wrapped string's value.\n */\ngoog.string.TypedString.prototype.getTypedStringValue;\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.string.TypedString"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/string/typedstring.js"],"^[",["^3",["^GW"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^85","~$goog.string.newlines.Line"]],"^5","goog.string.newlines.js","^6",["^7","goog/string/newlines.js"],"^8","goog/string/newlines.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for string newlines.\n */\n\n\n/**\n * Namespace for string utilities\n */\ngoog.provide('goog.string.newlines');\ngoog.provide('goog.string.newlines.Line');\n\n\n\n/**\n * Splits a string into lines, properly handling universal newlines.\n * @param {string} str String to split.\n * @param {boolean=} opt_keepNewlines Whether to keep the newlines in the\n * resulting strings. Defaults to false.\n * @return {!Array} String split into lines.\n */\ngoog.string.newlines.splitLines = function(str, opt_keepNewlines) {\n 'use strict';\n const lines = goog.string.newlines.getLines(str);\n return lines.map(function(line) {\n 'use strict';\n return opt_keepNewlines ? line.getFullLine() : line.getContent();\n });\n};\n\n\n\n/**\n * Line metadata class that records the start/end indicies of lines\n * in a string. Can be used to implement common newline use cases such as\n * splitLines() or determining line/column of an index in a string.\n * Also implements methods to get line contents.\n *\n * Indexes are expressed as string indicies into string.substring(), inclusive\n * at the start, exclusive at the end.\n *\n * Create an array of these with goog.string.newlines.getLines().\n * @param {string} string The original string.\n * @param {number} startLineIndex The index of the start of the line.\n * @param {number} endContentIndex The index of the end of the line, excluding\n * newlines.\n * @param {number} endLineIndex The index of the end of the line, index\n * newlines.\n * @constructor\n * @struct\n * @final\n */\ngoog.string.newlines.Line = function(\n string, startLineIndex, endContentIndex, endLineIndex) {\n 'use strict';\n /**\n * The original string.\n * @type {string}\n */\n this.string = string;\n\n /**\n * Index of the start of the line.\n * @type {number}\n */\n this.startLineIndex = startLineIndex;\n\n /**\n * Index of the end of the line, excluding any newline characters.\n * Index is the first character after the line, suitable for\n * String.substring().\n * @type {number}\n */\n this.endContentIndex = endContentIndex;\n\n /**\n * Index of the end of the line, excluding any newline characters.\n * Index is the first character after the line, suitable for\n * String.substring().\n * @type {number}\n */\n\n this.endLineIndex = endLineIndex;\n};\n\n\n/**\n * @return {string} The content of the line, excluding any newline characters.\n */\ngoog.string.newlines.Line.prototype.getContent = function() {\n 'use strict';\n return this.string.substring(this.startLineIndex, this.endContentIndex);\n};\n\n\n/**\n * @return {string} The full line, including any newline characters.\n */\ngoog.string.newlines.Line.prototype.getFullLine = function() {\n 'use strict';\n return this.string.substring(this.startLineIndex, this.endLineIndex);\n};\n\n\n/**\n * @return {string} The newline characters, if any ('\\n', \\r', '\\r\\n', '', etc).\n */\ngoog.string.newlines.Line.prototype.getNewline = function() {\n 'use strict';\n return this.string.substring(this.endContentIndex, this.endLineIndex);\n};\n\n\n/**\n * Splits a string into an array of line metadata.\n * @param {string} str String to split.\n * @return {!Array} Array of line metadata.\n */\ngoog.string.newlines.getLines = function(str) {\n 'use strict';\n // We use the constructor because literals are evaluated only once in\n // < ES 3.1.\n // See http://www.mail-archive.com/es-discuss@mozilla.org/msg01796.html\n const re = RegExp('\\r\\n|\\r|\\n', 'g');\n let sliceIndex = 0;\n let result;\n const lines = [];\n\n while (result = re.exec(str)) {\n const line = new goog.string.newlines.Line(\n str, sliceIndex, result.index, result.index + result[0].length);\n lines.push(line);\n\n // remember where to start the slice from\n sliceIndex = re.lastIndex;\n }\n\n // If the string does not end with a newline, add the last line.\n if (sliceIndex < str.length) {\n const line =\n new goog.string.newlines.Line(str, sliceIndex, str.length, str.length);\n lines.push(line);\n }\n\n return lines;\n};\n","^<",1684857788697,"^=",["^3",["^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",[]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.string.newlines","goog.string.newlines.Line"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",[],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/string/newlines.js"],"^[",["^3",["^85","^GX"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^4D"]],"^5","goog.string.const.js","^6",["^7","goog/string/const.js"],"^8","goog/string/const.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\ngoog.provide('goog.string.Const');\n\ngoog.require('goog.asserts');\ngoog.require('goog.string.TypedString');\n\n\n\n/**\n * Wrapper for compile-time-constant strings.\n *\n * Const is a wrapper for strings that can only be created from program\n * constants (i.e., string literals). This property relies on a custom Closure\n * compiler check that `goog.string.Const.from` is only invoked on\n * compile-time-constant expressions.\n *\n * Const is useful in APIs whose correct and secure use requires that certain\n * arguments are not attacker controlled: Compile-time constants are inherently\n * under the control of the application and not under control of external\n * attackers, and hence are safe to use in such contexts.\n *\n * Instances of this type must be created via its factory method\n * `goog.string.Const.from` and not by invoking its constructor. The\n * constructor intentionally takes no parameters and the type is immutable;\n * hence only a default instance corresponding to the empty string can be\n * obtained via constructor invocation. Use goog.string.Const.EMPTY\n * instead of using this constructor to get an empty Const string.\n *\n * @see goog.string.Const#from\n * @constructor\n * @final\n * @struct\n * @implements {goog.string.TypedString}\n * @param {Object=} opt_token package-internal implementation detail.\n * @param {string=} opt_content package-internal implementation detail.\n */\ngoog.string.Const = function(opt_token, opt_content) {\n 'use strict';\n /**\n * The wrapped value of this Const object. The field has a purposely ugly\n * name to make (non-compiled) code that attempts to directly access this\n * field stand out.\n * @private {string}\n */\n this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ =\n ((opt_token ===\n goog.string.Const.GOOG_STRING_CONSTRUCTOR_TOKEN_PRIVATE_) &&\n opt_content) ||\n '';\n\n /**\n * A type marker used to implement additional run-time type checking.\n * @see goog.string.Const#unwrap\n * @const {!Object}\n * @private\n */\n this.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ =\n goog.string.Const.TYPE_MARKER_;\n};\n\n\n/**\n * @override\n * @const\n */\ngoog.string.Const.prototype.implementsGoogStringTypedString = true;\n\n\n/**\n * Returns this Const's value as a string.\n *\n * IMPORTANT: In code where it is security-relevant that an object's type is\n * indeed `goog.string.Const`, use `goog.string.Const.unwrap`\n * instead of this method.\n *\n * @see goog.string.Const#unwrap\n * @override\n * @return {string}\n */\ngoog.string.Const.prototype.getTypedStringValue = function() {\n 'use strict';\n return this.stringConstValueWithSecurityContract__googStringSecurityPrivate_;\n};\n\n\nif (goog.DEBUG) {\n /**\n * Returns a debug-string representation of this value.\n *\n * To obtain the actual string value wrapped inside an object of this type,\n * use `goog.string.Const.unwrap`.\n *\n * @see goog.string.Const#unwrap\n * @override\n * @return {string}\n */\n goog.string.Const.prototype.toString = function() {\n 'use strict';\n return 'Const{' +\n this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ +\n '}';\n };\n}\n\n\n/**\n * Performs a runtime check that the provided object is indeed an instance\n * of `goog.string.Const`, and returns its value.\n * @param {!goog.string.Const} stringConst The object to extract from.\n * @return {string} The Const object's contained string, unless the run-time\n * type check fails. In that case, `unwrap` returns an innocuous\n * string, or, if assertions are enabled, throws\n * `goog.asserts.AssertionError`.\n */\ngoog.string.Const.unwrap = function(stringConst) {\n 'use strict';\n // Perform additional run-time type-checking to ensure that stringConst is\n // indeed an instance of the expected type. This provides some additional\n // protection against security bugs due to application code that disables type\n // checks.\n if (stringConst instanceof goog.string.Const &&\n stringConst.constructor === goog.string.Const &&\n stringConst.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ ===\n goog.string.Const.TYPE_MARKER_) {\n return stringConst\n .stringConstValueWithSecurityContract__googStringSecurityPrivate_;\n } else {\n goog.asserts.fail(\n 'expected object of type Const, got \\'' + stringConst + '\\'');\n return 'type_error:Const';\n }\n};\n\n\n/**\n * Creates a Const object from a compile-time constant string.\n *\n * It is illegal to invoke this function on an expression whose\n * compile-time-constant value cannot be determined by the Closure compiler.\n *\n * Correct invocations include,\n *
\n *   var s = goog.string.Const.from('hello');\n *   var t = goog.string.Const.from('hello' + 'world');\n * 
\n *\n * In contrast, the following are illegal:\n *
\n *   var s = goog.string.Const.from(getHello());\n *   var t = goog.string.Const.from('hello' + world);\n * 
\n *\n * @param {string} s A constant string from which to create a Const.\n * @return {!goog.string.Const} A Const object initialized to stringConst.\n */\ngoog.string.Const.from = function(s) {\n 'use strict';\n return new goog.string.Const(\n goog.string.Const.GOOG_STRING_CONSTRUCTOR_TOKEN_PRIVATE_, s);\n};\n\n/**\n * Type marker for the Const type, used to implement additional run-time\n * type checking.\n * @const {!Object}\n * @private\n */\ngoog.string.Const.TYPE_MARKER_ = {};\n\n/**\n * @type {!Object}\n * @private\n * @const\n */\ngoog.string.Const.GOOG_STRING_CONSTRUCTOR_TOKEN_PRIVATE_ = {};\n\n/**\n * A Const instance wrapping the empty string.\n * @const {!goog.string.Const}\n */\ngoog.string.Const.EMPTY = goog.string.Const.from('');\n","^<",1684857788697,"^=",["^3",["^2?","^GW","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2?","^GW"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.string.Const"],"^S","es3","^T",null,"^U",false,"^V",[],"^M",["goog.asserts","goog.string.TypedString"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/string/const.js"],"^[",["^3",["^4D"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2?","^GW"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^2M"]],"^5","goog.string.stringformat.js","^6",["^7","goog/string/stringformat.js"],"^8","goog/string/stringformat.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Implementation of sprintf-like, python-%-operator-like,\n * .NET-String.Format-like functionality. Uses JS string's replace method to\n * extract format specifiers and sends those specifiers to a handler function,\n * which then, based on conversion type part of the specifier, calls the\n * appropriate function to handle the specific conversion.\n * For specific functionality implemented, look at formatRe below, or look\n * at the tests.\n */\n\ngoog.provide('goog.string.format');\n\ngoog.require('goog.string');\n\n\n// TODO(johnlenz): goog.string.format should not accept undefined as a parameter\n/**\n * Performs sprintf-like conversion, i.e. puts the values in a template.\n * DO NOT use it instead of built-in conversions in simple cases such as\n * 'Cost: %.2f' as it would introduce unnecessary latency opposed to\n * 'Cost: ' + cost.toFixed(2).\n * @param {string} formatString Template string containing % specifiers.\n * @param {...(string|number|undefined)} var_args Values formatString is to\n * be filled with.\n * @return {string} Formatted string.\n */\ngoog.string.format = function(formatString, var_args) {\n 'use strict';\n // Convert the arguments to an array (MDC recommended way).\n const args = Array.prototype.slice.call(arguments);\n\n // Try to get the template.\n const template = args.shift();\n if (typeof template == 'undefined') {\n throw new Error('[goog.string.format] Template required');\n }\n\n // This re is used for matching, it also defines what is supported.\n const formatRe = /%([0\\-\\ \\+]*)(\\d+)?(\\.(\\d+))?([%sfdiu])/g;\n\n /**\n * Chooses which conversion function to call based on type conversion\n * specifier.\n * @param {string} match Contains the re matched string.\n * @param {string} flags Formatting flags.\n * @param {string} width Replacement string minimum width.\n * @param {string} dotp Matched precision including a dot.\n * @param {string} precision Specifies floating point precision.\n * @param {string} type Type conversion specifier.\n * @param {string} offset Matching location in the original string.\n * @param {string} wholeString Has the actualString being searched.\n * @return {string} Formatted parameter.\n */\n function replacerDemuxer(\n match, flags, width, dotp, precision, type, offset, wholeString) {\n // The % is too simple and doesn't take an argument.\n if (type == '%') {\n return '%';\n }\n\n // Try to get the actual value from parent function.\n const value = args.shift();\n\n // If we didn't get any arguments, fail.\n if (typeof value == 'undefined') {\n throw new Error('[goog.string.format] Not enough arguments');\n }\n\n // Patch the value argument to the beginning of our type specific call.\n arguments[0] = value;\n\n return goog.string.format.demuxes_[type].apply(null, arguments);\n }\n\n return template.replace(formatRe, replacerDemuxer);\n};\n\n\n/**\n * Contains various conversion functions (to be filled in later on).\n * @private {!Object}\n */\ngoog.string.format.demuxes_ = {};\n\n\n/**\n * Processes %s conversion specifier.\n * @param {string} value Contains the formatRe matched string.\n * @param {string} flags Formatting flags.\n * @param {string} width Replacement string minimum width.\n * @param {string} dotp Matched precision including a dot.\n * @param {string} precision Specifies floating point precision.\n * @param {string} type Type conversion specifier.\n * @param {string} offset Matching location in the original string.\n * @param {string} wholeString Has the actualString being searched.\n * @return {string} Replacement string.\n */\ngoog.string.format.demuxes_['s'] = function(\n value, flags, width, dotp, precision, type, offset, wholeString) {\n 'use strict';\n let replacement = value;\n // If no padding is necessary we're done.\n // The check for '' is necessary because Firefox incorrectly provides the\n // empty string instead of undefined for non-participating capture groups,\n // and isNaN('') == false.\n if (isNaN(width) || width == '' || replacement.length >= Number(width)) {\n return replacement;\n }\n\n // Otherwise we should find out where to put spaces.\n if (flags.indexOf('-', 0) > -1) {\n replacement = replacement +\n goog.string.repeat(' ', Number(width) - replacement.length);\n } else {\n replacement = goog.string.repeat(' ', Number(width) - replacement.length) +\n replacement;\n }\n return replacement;\n};\n\n\n/**\n * Processes %f conversion specifier.\n * @param {string} value Contains the formatRe matched string.\n * @param {string} flags Formatting flags.\n * @param {string} width Replacement string minimum width.\n * @param {string} dotp Matched precision including a dot.\n * @param {string} precision Specifies floating point precision.\n * @param {string} type Type conversion specifier.\n * @param {string} offset Matching location in the original string.\n * @param {string} wholeString Has the actualString being searched.\n * @return {string} Replacement string.\n */\ngoog.string.format.demuxes_['f'] = function(\n value, flags, width, dotp, precision, type, offset, wholeString) {\n 'use strict';\n let replacement = value.toString();\n\n // The check for '' is necessary because Firefox incorrectly provides the\n // empty string instead of undefined for non-participating capture groups,\n // and isNaN('') == false.\n if (!(isNaN(precision) || precision == '')) {\n replacement = parseFloat(value).toFixed(precision);\n }\n\n // Generates sign string that will be attached to the replacement.\n let sign;\n if (Number(value) < 0) {\n sign = '-';\n } else if (flags.indexOf('+') >= 0) {\n sign = '+';\n } else if (flags.indexOf(' ') >= 0) {\n sign = ' ';\n } else {\n sign = '';\n }\n\n if (Number(value) >= 0) {\n replacement = sign + replacement;\n }\n\n // If no padding is necessary we're done.\n if (isNaN(width) || replacement.length >= Number(width)) {\n return replacement;\n }\n\n // We need a clean signless replacement to start with\n replacement = isNaN(precision) ? Math.abs(Number(value)).toString() :\n Math.abs(Number(value)).toFixed(precision);\n\n const padCount = Number(width) - replacement.length - sign.length;\n\n // Find out which side to pad, and if it's left side, then which character to\n // pad, and set the sign on the left and padding in the middle.\n if (flags.indexOf('-', 0) >= 0) {\n replacement = sign + replacement + goog.string.repeat(' ', padCount);\n } else {\n // Decides which character to pad.\n const paddingChar = (flags.indexOf('0', 0) >= 0) ? '0' : ' ';\n replacement =\n sign + goog.string.repeat(paddingChar, padCount) + replacement;\n }\n\n return replacement;\n};\n\n\n/**\n * Processes %d conversion specifier.\n * @param {string} value Contains the formatRe matched string.\n * @param {string} flags Formatting flags.\n * @param {string} width Replacement string minimum width.\n * @param {string} dotp Matched precision including a dot.\n * @param {string} precision Specifies floating point precision.\n * @param {string} type Type conversion specifier.\n * @param {string} offset Matching location in the original string.\n * @param {string} wholeString Has the actualString being searched.\n * @return {string} Replacement string.\n */\ngoog.string.format.demuxes_['d'] = function(\n value, flags, width, dotp, precision, type, offset, wholeString) {\n 'use strict';\n return goog.string.format.demuxes_['f'](\n parseInt(value, 10) /* value */, flags, width, dotp, 0 /* precision */,\n type, offset, wholeString);\n};\n\n\n// These are additional aliases, for integer conversion.\ngoog.string.format.demuxes_['i'] = goog.string.format.demuxes_['d'];\ngoog.string.format.demuxes_['u'] = goog.string.format.demuxes_['d'];\n","^<",1684857788697,"^=",["^3",["^2L","^>"]],"^?",["^ ","^@","The Google Closure Library is a collection of JavaScript code\n designed for use with the Google Closure JavaScript Compiler.\n\n This non-official distribution was prepared by the ClojureScript\n team at http://clojure.org/","^A","^B","^C","^D","^E","Google Closure Library","^F","^G","^H","http://code.google.com/p/closure-library/","^I","^J","^K",["^G","0.0-20230227-c7c0a541"],"^L","0.0-20230227-c7c0a541"],"^M",["^3",["^2L"]],"^N",["^ ","^O",[],"^P",false,"^Q",[],"^R",[],"^2",["goog.string.format"],"^S","es6","^T",null,"^U",false,"^V",[],"^M",["goog.string"],"^W",[],"^X",false,"^Y",false],"^H",["^Z","jar:file:/home/chris/.m2/repository/org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar!/goog/string/stringformat.js"],"^[",["^3",["^2M"]],"^W",["^3",[]],"^10",true,"^11",true,"^12",["^>","^2L"]],["^ ","^1",["533ce2bdbb7925db781449abb6527af1e6c5e782"],"^2",["^3",["^2L","^4H"]],"^5","goog.string.string.js","^6",["^7","goog/string/string.js"],"^8","goog/string/string.js","^9","^:","^;","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for string manipulation.\n */\n\n\n/**\n * Namespace for string utilities\n */\ngoog.provide('goog.string');\ngoog.provide('goog.string.Unicode');\n\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.internal');\n\n\n/**\n * @define {boolean} Enables HTML escaping of lowercase letter \"e\" which helps\n * with detection of double-escaping as this letter is frequently used.\n */\ngoog.string.DETECT_DOUBLE_ESCAPING =\n goog.define('goog.string.DETECT_DOUBLE_ESCAPING', false);\n\n\n/**\n * @define {boolean} Whether to force non-dom html unescaping.\n */\ngoog.string.FORCE_NON_DOM_HTML_UNESCAPING =\n goog.define('goog.string.FORCE_NON_DOM_HTML_UNESCAPING', false);\n\n\n/**\n * Common Unicode string characters.\n * @enum {string}\n */\ngoog.string.Unicode = {\n NBSP: '\\xa0',\n ZERO_WIDTH_SPACE: '\\u200b' // This is equivalent to .\n};\n\n\n/**\n * Fast prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the start of `str`.\n * @return {boolean} True if `str` begins with `prefix`.\n */\ngoog.string.startsWith = goog.string.internal.startsWith;\n\n\n/**\n * Fast suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix`.\n */\ngoog.string.endsWith = goog.string.internal.endsWith;\n\n\n/**\n * Case-insensitive prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the end of `str`.\n * @return {boolean} True if `str` begins with `prefix` (ignoring\n * case).\n */\ngoog.string.caseInsensitiveStartsWith =\n goog.string.internal.caseInsensitiveStartsWith;\n\n\n/**\n * Case-insensitive suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix` (ignoring\n * case).\n */\ngoog.string.caseInsensitiveEndsWith =\n goog.string.internal.caseInsensitiveEndsWith;\n\n\n/**\n * Case-insensitive equality checker.\n * @param {string} str1 First string to check.\n * @param {string} str2 Second string to check.\n * @return {boolean} True if `str1` and `str2` are the same string,\n * ignoring case.\n */\ngoog.string.caseInsensitiveEquals = goog.string.internal.caseInsensitiveEquals;\n\n\n/**\n * Does simple python-style string substitution.\n * subs(\"foo%s hot%s\", \"bar\", \"dog\") becomes \"foobar hotdog\".\n * @param {string} str The string containing the pattern.\n * @param {...*} var_args The items to substitute into the pattern.\n * @return {string} A copy of `str` in which each occurrence of\n * {@code %s} has been replaced an argument from `var_args`.\n */\ngoog.string.subs = function(str, var_args) {\n 'use strict';\n const splitParts = str.split('%s');\n let returnString = '';\n\n const subsArguments = Array.prototype.slice.call(arguments, 1);\n while (subsArguments.length &&\n // Replace up to the last split part. We are inserting in the\n // positions between split parts.\n splitParts.length > 1) {\n returnString += splitParts.shift() + subsArguments.shift();\n }\n\n return returnString + splitParts.join('%s'); // Join unused '%s'\n};\n\n\n/**\n * Converts multiple whitespace chars (spaces, non-breaking-spaces, new lines\n * and tabs) to a single space, and strips leading and trailing whitespace.\n * @param {string} str Input string.\n * @return {string} A copy of `str` with collapsed whitespace.\n */\ngoog.string.collapseWhitespace = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/[\\s\\xa0]+/g, ' ').replace(/^\\s+|\\s+$/g, '');\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n */\ngoog.string.isEmptyOrWhitespace = goog.string.internal.isEmptyOrWhitespace;\n\n\n/**\n * Checks if a string is empty.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty.\n */\ngoog.string.isEmptyString = function(str) {\n 'use strict';\n return str.length == 0;\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n *\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace instead.\n */\ngoog.string.isEmpty = goog.string.isEmptyOrWhitespace;\n\n\n/**\n * Checks if a string is null, undefined, empty or contains only whitespaces.\n * @param {*} str The string to check.\n * @return {boolean} Whether `str` is null, undefined, empty, or\n * whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str))\n * instead.\n */\ngoog.string.isEmptyOrWhitespaceSafe = function(str) {\n 'use strict';\n return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str));\n};\n\n\n/**\n * Checks if a string is null, undefined, empty or contains only whitespaces.\n *\n * @param {*} str The string to check.\n * @return {boolean} Whether `str` is null, undefined, empty, or\n * whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace instead.\n */\ngoog.string.isEmptySafe = goog.string.isEmptyOrWhitespaceSafe;\n\n\n/**\n * Checks if a string is all breaking whitespace.\n * @param {string} str The string to check.\n * @return {boolean} Whether the string is all breaking whitespace.\n */\ngoog.string.isBreakingWhitespace = function(str) {\n 'use strict';\n return !/[^\\t\\n\\r ]/.test(str);\n};\n\n\n/**\n * Checks if a string contains all letters.\n * @param {string} str string to check.\n * @return {boolean} True if `str` consists entirely of letters.\n */\ngoog.string.isAlpha = function(str) {\n 'use strict';\n return !/[^a-zA-Z]/.test(str);\n};\n\n\n/**\n * Checks if a string contains only numbers.\n * @param {*} str string to check. If not a string, it will be\n * casted to one.\n * @return {boolean} True if `str` is numeric.\n */\ngoog.string.isNumeric = function(str) {\n 'use strict';\n return !/[^0-9]/.test(str);\n};\n\n\n/**\n * Checks if a string contains only numbers or letters.\n * @param {string} str string to check.\n * @return {boolean} True if `str` is alphanumeric.\n */\ngoog.string.isAlphaNumeric = function(str) {\n 'use strict';\n return !/[^a-zA-Z0-9]/.test(str);\n};\n\n\n/**\n * Checks if a character is a space character.\n * @param {string} ch Character to check.\n * @return {boolean} True if `ch` is a space.\n */\ngoog.string.isSpace = function(ch) {\n 'use strict';\n return ch == ' ';\n};\n\n\n/**\n * Checks if a character is a valid unicode character.\n * @param {string} ch Character to check.\n * @return {boolean} True if `ch` is a valid unicode character.\n */\ngoog.string.isUnicodeChar = function(ch) {\n 'use strict';\n return ch.length == 1 && ch >= ' ' && ch <= '~' ||\n ch >= '\\u0080' && ch <= '\\uFFFD';\n};\n\n\n/**\n * Takes a string and replaces newlines with a space. Multiple lines are\n * replaced with a single space.\n * @param {string} str The string from which to strip newlines.\n * @return {string} A copy of `str` stripped of newlines.\n */\ngoog.string.stripNewlines = function(str) {\n 'use strict';\n return str.replace(/(\\r\\n|\\r|\\n)+/g, ' ');\n};\n\n\n/**\n * Replaces Windows and Mac new lines with unix style: \\r or \\r\\n with \\n.\n * @param {string} str The string to in which to canonicalize newlines.\n * @return {string} `str` A copy of {@code} with canonicalized newlines.\n */\ngoog.string.canonicalizeNewlines = function(str) {\n 'use strict';\n return str.replace(/(\\r\\n|\\r|\\n)/g, '\\n');\n};\n\n\n/**\n * Normalizes whitespace in a string, replacing all whitespace chars with\n * a space.\n * @param {string} str The string in which to normalize whitespace.\n * @return {string} A copy of `str` with all whitespace normalized.\n */\ngoog.string.normalizeWhitespace = function(str) {\n 'use strict';\n return str.replace(/\\xa0|\\s/g, ' ');\n};\n\n\n/**\n * Normalizes spaces in a string, replacing all consecutive spaces and tabs\n * with a single space. Replaces non-breaking space with a space.\n * @param {string} str The string in which to normalize spaces.\n * @return {string} A copy of `str` with all consecutive spaces and tabs\n * replaced with a single space.\n */\ngoog.string.normalizeSpaces = function(str) {\n 'use strict';\n return str.replace(/\\xa0|[ \\t]+/g, ' ');\n};\n\n\n/**\n * Removes the breaking spaces from the left and right of the string and\n * collapses the sequences of breaking spaces in the middle into single spaces.\n * The original and the result strings render the same way in HTML.\n * @param {string} str A string in which to collapse spaces.\n * @return {string} Copy of the string with normalized breaking spaces.\n */\ngoog.string.collapseBreakingSpaces = function(str) {\n 'use strict';\n return str.replace(/[\\t\\r\\n ]+/g, ' ')\n .replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g, '');\n};\n\n\n/**\n * Trims white spaces to the left and right of a string.\n * @param {string} str The string to trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trim = goog.string.internal.trim;\n\n\n/**\n * Trims whitespaces at the left end of a string.\n * @param {string} str The string to left trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trimLeft = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/^[\\s\\xa0]+/, '');\n};\n\n\n/**\n * Trims whitespaces at the right end of a string.\n * @param {string} str The string to right trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trimRight = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/[\\s\\xa0]+$/, '');\n};\n\n\n/**\n * A string comparator that ignores case.\n * -1 = str1 less than str2\n * 0 = str1 equals str2\n * 1 = str1 greater than str2\n *\n * @param {string} str1 The string to compare.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} The comparator result, as described above.\n */\ngoog.string.caseInsensitiveCompare =\n goog.string.internal.caseInsensitiveCompare;\n\n\n/**\n * Compares two strings interpreting their numeric substrings as numbers.\n *\n * @param {string} str1 First string.\n * @param {string} str2 Second string.\n * @param {!RegExp} tokenizerRegExp Splits a string into substrings of\n * non-negative integers, non-numeric characters and optionally fractional\n * numbers starting with a decimal point.\n * @return {number} Negative if str1 < str2, 0 is str1 == str2, positive if\n * str1 > str2.\n * @private\n */\ngoog.string.numberAwareCompare_ = function(str1, str2, tokenizerRegExp) {\n 'use strict';\n if (str1 == str2) {\n return 0;\n }\n if (!str1) {\n return -1;\n }\n if (!str2) {\n return 1;\n }\n\n // Using match to split the entire string ahead of time turns out to be faster\n // for most inputs than using RegExp.exec or iterating over each character.\n const tokens1 = str1.toLowerCase().match(tokenizerRegExp);\n const tokens2 = str2.toLowerCase().match(tokenizerRegExp);\n\n const count = Math.min(tokens1.length, tokens2.length);\n\n for (let i = 0; i < count; i++) {\n const a = tokens1[i];\n const b = tokens2[i];\n\n // Compare pairs of tokens, returning if one token sorts before the other.\n if (a != b) {\n // Only if both tokens are integers is a special comparison required.\n // Decimal numbers are sorted as strings (e.g., '.09' < '.1').\n const num1 = parseInt(a, 10);\n if (!isNaN(num1)) {\n const num2 = parseInt(b, 10);\n if (!isNaN(num2) && num1 - num2) {\n return num1 - num2;\n }\n }\n return a < b ? -1 : 1;\n }\n }\n\n // If one string is a substring of the other, the shorter string sorts first.\n if (tokens1.length != tokens2.length) {\n return tokens1.length - tokens2.length;\n }\n\n // The two strings must be equivalent except for case (perfect equality is\n // tested at the head of the function.) Revert to default ASCII string\n // comparison to stabilize the sort.\n return str1 < str2 ? -1 : 1;\n};\n\n\n/**\n * String comparison function that handles non-negative integer numbers in a\n * way humans might expect. Using this function, the string 'File 2.jpg' sorts\n * before 'File 10.jpg', and 'Version 1.9' before 'Version 1.10'. The comparison\n * is mostly case-insensitive, though strings that are identical except for case\n * are sorted with the upper-case strings before lower-case.\n *\n * This comparison function is up to 50x slower than either the default or the\n * case-insensitive compare. It should not be used in time-critical code, but\n * should be fast enough to sort several hundred short strings (like filenames)\n * with a reasonable delay.\n *\n * @param {string} str1 The string to compare in a numerically sensitive way.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than\n * 0 if str1 > str2.\n */\ngoog.string.intAwareCompare = function(str1, str2) {\n 'use strict';\n return goog.string.numberAwareCompare_(str1, str2, /\\d+|\\D+/g);\n};\n\n\n/**\n * String comparison function that handles non-negative integer and fractional\n * numbers in a way humans might expect. Using this function, the string\n * 'File 2.jpg' sorts before 'File 10.jpg', and '3.14' before '3.2'. Equivalent\n * to {@link goog.string.intAwareCompare} apart from the way how it interprets\n * dots.\n *\n * @param {string} str1 The string to compare in a numerically sensitive way.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than\n * 0 if str1 > str2.\n */\ngoog.string.floatAwareCompare = function(str1, str2) {\n 'use strict';\n return goog.string.numberAwareCompare_(str1, str2, /\\d+|\\.\\d+|\\D+/g);\n};\n\n\n/**\n * Alias for {@link goog.string.floatAwareCompare}.\n *\n * @param {string} str1\n * @param {string} str2\n * @return {number}\n */\ngoog.string.numerateCompare = goog.string.floatAwareCompare;\n\n\n/**\n * URL-encodes a string\n * @param {*} str The string to url-encode.\n * @return {string} An encoded copy of `str` that is safe for urls.\n * Note that '#', ':', and other characters used to delimit portions\n * of URLs *will* be encoded.\n */\ngoog.string.urlEncode = function(str) {\n 'use strict';\n return encodeURIComponent(String(str));\n};\n\n\n/**\n * URL-decodes the string. We need to specially handle '+'s because\n * the javascript library doesn't convert them to spaces.\n * @param {string} str The string to url decode.\n * @return {string} The decoded `str`.\n */\ngoog.string.urlDecode = function(str) {\n 'use strict';\n return decodeURIComponent(str.replace(/\\+/g, ' '));\n};\n\n\n/**\n * Converts \\n to
s or
s.\n * @param {string} str The string in which to convert newlines.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} A copy of `str` with converted newlines.\n */\ngoog.string.newLineToBr = goog.string.internal.newLineToBr;\n\n\n/**\n * Escapes double quote '\"' and single quote '\\'' characters in addition to\n * '&', '<', and '>' so that a string can be included in an HTML tag attribute\n * value within double or single quotes.\n *\n * It should be noted that > doesn't need to be escaped for the HTML or XML to\n * be valid, but it has been decided to escape it for consistency with other\n * implementations.\n *\n * With goog.string.DETECT_DOUBLE_ESCAPING, this function escapes also the\n * lowercase letter \"e\".\n *\n * NOTE(user):\n * HtmlEscape is often called during the generation of large blocks of HTML.\n * Using statics for the regular expressions and strings is an optimization\n * that can more than half the amount of time IE spends in this function for\n * large apps, since strings and regexes both contribute to GC allocations.\n *\n * Testing for the presence of a character before escaping increases the number\n * of function calls, but actually provides a speed increase for the average\n * case -- since the average case often doesn't require the escaping of all 4\n * characters and indexOf() is much cheaper than replace().\n * The worst case does suffer slightly from the additional calls, therefore the\n * opt_isLikelyToContainHtmlChars option has been included for situations\n * where all 4 HTML entities are very likely to be present and need escaping.\n *\n * Some benchmarks (times tended to fluctuate +-0.05ms):\n * FireFox IE6\n * (no chars / average (mix of cases) / all 4 chars)\n * no checks 0.13 / 0.22 / 0.22 0.23 / 0.53 / 0.80\n * indexOf 0.08 / 0.17 / 0.26 0.22 / 0.54 / 0.84\n * indexOf + re test 0.07 / 0.17 / 0.28 0.19 / 0.50 / 0.85\n *\n * An additional advantage of checking if replace actually needs to be called\n * is a reduction in the number of object allocations, so as the size of the\n * application grows the difference between the various methods would increase.\n *\n * @param {string} str string to be escaped.\n * @param {boolean=} opt_isLikelyToContainHtmlChars Don't perform a check to see\n * if the character needs replacing - use this option if you expect each of\n * the characters to appear often. Leave false if you expect few html\n * characters to occur in your strings, such as if you are escaping HTML.\n * @return {string} An escaped copy of `str`.\n */\ngoog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {\n 'use strict';\n str = goog.string.internal.htmlEscape(str, opt_isLikelyToContainHtmlChars);\n if (goog.string.DETECT_DOUBLE_ESCAPING) {\n str = str.replace(goog.string.E_RE_, 'e');\n }\n return str;\n};\n\n\n/**\n * Regular expression that matches a lowercase letter \"e\", for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.E_RE_ = /e/g;\n\n\n/**\n * Unescapes an HTML string.\n *\n * @param {string} str The string to unescape.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapeEntities = function(str) {\n 'use strict';\n if (goog.string.contains(str, '&')) {\n // We are careful not to use a DOM if we do not have one or we explicitly\n // requested non-DOM html unescaping.\n if (!goog.string.FORCE_NON_DOM_HTML_UNESCAPING &&\n 'document' in goog.global) {\n return goog.string.unescapeEntitiesUsingDom_(str);\n } else {\n // Fall back on pure XML entities\n return goog.string.unescapePureXmlEntities_(str);\n }\n }\n return str;\n};\n\n\n/**\n * Unescapes a HTML string using the provided document.\n *\n * @param {string} str The string to unescape.\n * @param {!Document} document A document to use in escaping the string.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapeEntitiesWithDocument = function(str, document) {\n 'use strict';\n if (goog.string.contains(str, '&')) {\n return goog.string.unescapeEntitiesUsingDom_(str, document);\n }\n return str;\n};\n\n\n/**\n * Unescapes an HTML string using a DOM to resolve non-XML, non-numeric\n * entities. This function is XSS-safe and whitespace-preserving.\n * @private\n * @param {string} str The string to unescape.\n * @param {Document=} opt_document An optional document to use for creating\n * elements. If this is not specified then the default window.document\n * will be used.\n * @return {string} The unescaped `str` string.\n */\ngoog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) {\n 'use strict';\n /** @type {!Object} */\n const seen = {'&': '&', '<': '<', '>': '>', '"': '\"'};\n /** @type {!Element} */\n let div;\n if (opt_document) {\n div = opt_document.createElement('div');\n } else {\n div = goog.global.document.createElement('div');\n }\n // Match as many valid entity characters as possible. If the actual entity\n // happens to be shorter, it will still work as innerHTML will return the\n // trailing characters unchanged. Since the entity characters do not include\n // open angle bracket, there is no chance of XSS from the innerHTML use.\n // Since no whitespace is passed to innerHTML, whitespace is preserved.\n return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) {\n 'use strict';\n // Check for cached entity.\n let value = seen[s];\n if (value) {\n return value;\n }\n // Check for numeric entity.\n if (entity.charAt(0) == '#') {\n // Prefix with 0 so that hex entities (e.g. ) parse as hex numbers.\n const n = Number('0' + entity.slice(1));\n if (!isNaN(n)) {\n value = String.fromCharCode(n);\n }\n }\n // Fall back to innerHTML otherwise.\n if (!value) {\n // Append a non-entity character to avoid a bug in Webkit that parses\n // an invalid entity at the end of innerHTML text as the empty string.\n goog.dom.safe.setInnerHtml(\n div,\n goog.html.uncheckedconversions\n .safeHtmlFromStringKnownToSatisfyTypeContract(\n goog.string.Const.from('Single HTML entity.'), s + ' '));\n // Then remove the trailing character from the result.\n value = div.firstChild.nodeValue.slice(0, -1);\n }\n // Cache and return.\n return seen[s] = value;\n });\n};\n\n\n/**\n * Unescapes XML entities.\n * @private\n * @param {string} str The string to unescape.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapePureXmlEntities_ = function(str) {\n 'use strict';\n return str.replace(/&([^;]+);/g, function(s, entity) {\n 'use strict';\n switch (entity) {\n case 'amp':\n return '&';\n case 'lt':\n return '<';\n case 'gt':\n return '>';\n case 'quot':\n return '\"';\n default:\n if (entity.charAt(0) == '#') {\n // Prefix with 0 so that hex entities (e.g. ) parse as hex.\n const n = Number('0' + entity.slice(1));\n if (!isNaN(n)) {\n return String.fromCharCode(n);\n }\n }\n // For invalid entities we just return the entity\n return s;\n }\n });\n};\n\n\n/**\n * Regular expression that matches an HTML entity.\n * See also HTML5: Tokenization / Tokenizing character references.\n * @private\n * @type {!RegExp}\n */\ngoog.string.HTML_ENTITY_PATTERN_ = /&([^;\\s<&]+);?/g;\n\n\n/**\n * Do escaping of whitespace to preserve spatial formatting. We use character\n * entity #160 to make it safer for xml.\n * @param {string} str The string in which to escape whitespace.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} An escaped copy of `str`.\n */\ngoog.string.whitespaceEscape = function(str, opt_xml) {\n 'use strict';\n // This doesn't use goog.string.preserveSpaces for backwards compatibility.\n return goog.string.newLineToBr(str.replace(/ /g, '  '), opt_xml);\n};\n\n\n/**\n * Preserve spaces that would be otherwise collapsed in HTML by replacing them\n * with non-breaking space Unicode characters.\n * @param {string} str The string in which to preserve whitespace.\n * @return {string} A copy of `str` with preserved whitespace.\n */\ngoog.string.preserveSpaces = function(str) {\n 'use strict';\n return str.replace(/(^|[\\n ]) /g, '$1' + goog.string.Unicode.NBSP);\n};\n\n\n/**\n * Strip quote characters around a string. The second argument is a string of\n * characters to treat as quotes. This can be a single character or a string of\n * multiple character and in that case each of those are treated as possible\n * quote characters. For example:\n *\n *
\n * goog.string.stripQuotes('\"abc\"', '\"`') --> 'abc'\n * goog.string.stripQuotes('`abc`', '\"`') --> 'abc'\n * 
\n *\n * @param {string} str The string to strip.\n * @param {string} quoteChars The quote characters to strip.\n * @return {string} A copy of `str` without the quotes.\n */\ngoog.string.stripQuotes = function(str, quoteChars) {\n 'use strict';\n const length = quoteChars.length;\n for (let i = 0; i < length; i++) {\n const quoteChar = length == 1 ? quoteChars : quoteChars.charAt(i);\n if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) {\n return str.substring(1, str.length - 1);\n }\n }\n return str;\n};\n\n\n/**\n * Truncates a string to a certain length and adds '...' if necessary. The\n * length also accounts for the ellipsis, so a maximum length of 10 and a string\n * 'Hello World!' produces 'Hello W...'.\n * @param {string} str The string to truncate.\n * @param {number} chars Max number of characters.\n * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped\n * characters from being cut off in the middle.\n * @return {string} The truncated `str` string.\n */\ngoog.string.truncate = function(str, chars, opt_protectEscapedCharacters) {\n 'use strict';\n if (opt_protectEscapedCharacters) {\n str = goog.string.unescapeEntities(str);\n }\n\n if (str.length > chars) {\n str = str.substring(0, chars - 3) + '...';\n }\n\n if (opt_protectEscapedCharacters) {\n str = goog.string.htmlEscape(str);\n }\n\n return str;\n};\n\n\n/**\n * Truncate a string in the middle, adding \"...\" if necessary,\n * and favoring the beginning of the string.\n * @param {string} str The string to truncate the middle of.\n * @param {number} chars Max number of characters.\n * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped\n * characters from being cutoff in the middle.\n * @param {number=} opt_trailingChars Optional number of trailing characters to\n * leave at the end of the string, instead of truncating as close to the\n * middle as possible.\n * @return {string} A truncated copy of `str`.\n */\ngoog.string.truncateMiddle = function(\n str, chars, opt_protectEscapedCharacters, opt_trailingChars) {\n 'use strict';\n if (opt_protectEscapedCharacters) {\n str = goog.string.unescapeEntities(str);\n }\n\n if (opt_trailingChars && str.length > chars) {\n if (opt_trailingChars > chars) {\n opt_trailingChars = chars;\n }\n const endPoint = str.length - opt_trailingChars;\n const startPoint = chars - opt_trailingChars;\n str = str.substring(0, startPoint) + '...' + str.substring(endPoint);\n } else if (str.length > chars) {\n // Favor the beginning of the string:\n let half = Math.floor(chars / 2);\n const endPos = str.length - half;\n half += chars % 2;\n str = str.substring(0, half) + '...' + str.substring(endPos);\n }\n\n if (opt_protectEscapedCharacters) {\n str = goog.string.htmlEscape(str);\n }\n\n return str;\n};\n\n\n/**\n * Special chars that need to be escaped for goog.string.quote.\n * @private {!Object}\n */\ngoog.string.specialEscapeChars_ = {\n '\\0': '\\\\0',\n '\\b': '\\\\b',\n '\\f': '\\\\f',\n '\\n': '\\\\n',\n '\\r': '\\\\r',\n '\\t': '\\\\t',\n '\\x0B': '\\\\x0B', // '\\v' is not supported in JScript\n '\"': '\\\\\"',\n '\\\\': '\\\\\\\\',\n // To support the use case of embedding quoted strings inside of script\n // tags, we have to make sure HTML comments and opening/closing script tags do\n // not appear in the resulting string. The specific strings that must be\n // escaped are documented at:\n // https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements\n '<': '\\\\u003C' // NOTE: JSON.parse crashes on '\\\\x3c'.\n};\n\n\n/**\n * Character mappings used internally for goog.string.escapeChar.\n * @private {!Object}\n */\ngoog.string.jsEscapeCache_ = {\n '\\'': '\\\\\\''\n};\n\n\n/**\n * Encloses a string in double quotes and escapes characters so that the\n * string is a valid JS string. The resulting string is safe to embed in\n * `\\\">\",\n acceptable: [\n \"">\",\n \"">\",\n \"\\\">\",\n \"\\\">\",\n \"">\",\n ],\n name: \"img_malformed\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"img_onerror\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"img_quot\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"img_style\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"img_tab\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"input\"},\n {input: \"a>a>a>\",\n acceptable: [\n \"a>a>\",\n \"\",\n \"a>a>\",\n \"a>a>\",\n \"a>a>\",\n \"\",\n ],\n name: \"mess_of_anchors\"},\n {input: \"\\\">\",\n \"\\\">\\\">\",\n \"\\\">*/script>alert()</script>\",\n ],\n name: \"script_inception\"},\n {input: \"\",\n acceptable: [\n \"\",\n ],\n name: \"script_src\"},\n {input: \"\",\n acceptable: [\n \"\",\n ],\n name: \"script_title\"},\n {input: \"\",\n acceptable: [\n \"\",\n ],\n name: \"svg\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"unicode\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_html_plain\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_html_scriptinside\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_html_srcdoc\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_html_formaction\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_html_formmethod\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_html_pattern\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_html_defer\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_head_plain\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_head_scriptinside\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_head_srcdoc\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_head_formaction\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_head_formmethod\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_head_pattern\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_head_defer\"},\n {input: \"\",\n acceptable: [\n \"<title>\",\n \"\",\n \"<title/>\",\n \"<title />\",\n \"<table><title>\",\n \"</table>\",\n \"<TITLE />\",\n \"<TITLE>\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_title_srcdoc\"},\n {input: \"\",\n acceptable: [\n \"<title>\",\n \"\",\n \"<title/>\",\n \"<title />\",\n \"<table><title>
\",\n \"</table>\",\n \"<TITLE />\",\n \"<TITLE>\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_title_formaction\"},\n {input: \"\",\n acceptable: [\n \"<title>\",\n \"\",\n \"<title/>\",\n \"<title />\",\n \"<table><title>
\",\n \"</table>\",\n \"<TITLE />\",\n \"<TITLE>\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_title_formmethod\"},\n {input: \"\",\n acceptable: [\n \"<title>\",\n \"\",\n \"<title/>\",\n \"<title />\",\n \"<table><title>
\",\n \"</table>\",\n \"<TITLE />\",\n \"<TITLE>\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_title_pattern\"},\n {input: \"\",\n acceptable: [\n \"<title>\",\n \"\",\n \"<title/>\",\n \"<title />\",\n \"<table><title>
\",\n \"</table>\",\n \"<TITLE />\",\n \"<TITLE>\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_title_defer\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_base_plain\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_base_scriptinside\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_base_srcdoc\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_base_formaction\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_base_formmethod\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_base_pattern\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_base_defer\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_meta_plain\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_meta_scriptinside\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_meta_srcdoc\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_meta_formaction\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_meta_formmethod\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_meta_pattern\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_meta_defer\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_style_plain\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_style_scriptinside\"},\n {input: \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_style_srcdoc\"},\n {input: \"\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_style_formaction\"},\n {input: \"\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_style_formmethod\"},\n {input: \"\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_style_pattern\"},\n {input: \"\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_style_defer\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_body_plain\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_body_scriptinside\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_body_srcdoc\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_body_formaction\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_body_formmethod\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_body_pattern\"},\n {input: \"\",\n acceptable: [\n \"\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_body_defer\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_article_plain\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"
\",\n ],\n name: \"contract_article_scriptinside\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_article_srcdoc\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_article_formaction\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_article_formmethod\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_article_pattern\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_article_defer\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_section_plain\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n \"
\",\n \"
\",\n \"
\",\n ],\n name: \"contract_section_scriptinside\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_section_srcdoc\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_section_formaction\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_section_formmethod\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_section_pattern\"},\n {input: \"
\",\n acceptable: [\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"
\",\n \"\",\n \"\",\n \"\",\n ],\n name: \"contract_section_defer\"},\n {input: \"\",\n acceptable: [\n \"