Source: Vector.js

'use strict';
const Vector = ( function(){
	const others = {
			0: [1,2],
			1: [2,0],
			2: [0,1]
		},
	 isNumber = ( a ) => { let t = Number( a ); return t === t; },
		attemptConversion = ( ...args ) => {
			if( args[0] instanceof Vector ) {
				return args[0].coords;
			}
			if( args[0].every( isNumber ) ) {
				return args[0].map( ( item, _ )=> {
					let res = Number( item );
					return typeof res === 'number' && res != res ? 0 : res;
				} );
			}
			if( args[0][0] instanceof Array && args[0][0].every( isNumber ) ) {
				return args[0][0].map( ( item, _ ) => {
					let res = Number( item );
					return typeof res === 'number' && res != res ? 0 : res;
				} );
			}
			return [0];
		};

	/**
   * The classical Vector class, with some extensions.  Vector does it's best to convert this to something useable, but it may not always find success. In this case, it returns `new Vector(0)`.
   * @class
   */
	class Vector {
		/**
		 * Constructs a new Vector instance
		 * @constructs Vector
		 * @param {*} args The coordinates of the vector.
		 */
		constructor( ...args ) {
			let coords;
			coords = attemptConversion( args );
			Object.assign( this, {
				coords
			} );
		}
		/**
		 * Find the [Cross Product](https://en.wikipedia.org/wiki/Cross_product) of two vectors. The resulting vector is at 90 degree angles to the other two.
		 * @param {Vector} vector1 The first vector.
		 * @param {Vector} vector2 The second vector.
		 * @returns {Vector} The resulting cross product.
		 * @memberof Vector
		 */
		static crossProduct( vector1 = new Vector( 0, 0, 0 ), vector2 = new Vector( 0, 0, 0 ) ) {
			let firstCoords = [...vector1.coords],
				otherCoords = [...vector2.coords],
				greatest = Math.max( firstCoords.length, otherCoords.length );
			if( greatest > 3 ) {
			  throw Error( 'All vectors must be 3D or less.' );
			}
			[firstCoords, otherCoords].forEach( ( item ) => {
				while( item.length < greatest ) {
					item.push( 0 );
				}
			} );
			let product = new Vector( ...Array( 3 ).fill( undefined ).map( ( _, index ) => {
			  let _others = others[index];
			  return firstCoords[_others[0]] * otherCoords[_others[1]] - firstCoords[_others[1]] * otherCoords[_others[0]];
			} ) );
			return product;
		}
		/**
		 * Find the [Dot Product](https://en.wikipedia.org/wiki/Dot_product) of two vectors.
		 * @param {Vector} vector1 The first vector.
		 * @param {Vector} vector2 The second vector.
		 * @returns {number} The resulting dot product.
		 * @meberof Vector
		 */
		static dotProduct( vector1 = new Vector( 0 ), vector2 = new Vector( 0 ) ) {
			let firstCoords = [...vector1.coords],
				otherCoords = [...vector2.coords],
				greatest = Math.max( firstCoords.length, otherCoords.length );
			[firstCoords, otherCoords].forEach( ( item ) => {
				while( item.length < greatest ) {
					item.push( 0 );
				}
			} );
			let result = Array( greatest ).fill( undefined ).map( ( _, index ) => {
			  return firstCoords[index] * otherCoords[index];
			} ).reduce( ( a,b )=> a + b );
			return result;
		}
		/**
		 * Finds the [Taxicab Distance]{@link https://en.wikipedia.org/wiki/Taxicab_geometry} between two vectors.
		 * @param {Vector} [vector1=Vector(0)] The first vector in the distance calculation.
		 * @param {Vector} [vector2=Vector(0)] The second vector in the distance calculation.
		 * @returns {number} The taxicab distance between the two vectors
		 * @memberof Vector
		 */
		static taxicabDistance( vector1 = new Vector( 0 ), vector2 = new Vector( 0 ) ) {
			let firstCoords = [...vector1.coords],
				otherCoords = [...vector2.coords],
				greatest = Math.max( firstCoords.length, otherCoords.length );
			[firstCoords, otherCoords].forEach( ( item ) => {
				while( item.length < greatest ) {
					item.push( 0 );
				}
			} );
			let difference = Array( greatest ).fill( undefined ).map( ( i, index ) => {
					return Math.abs( firstCoords[index] - otherCoords[index] );
				} ).reduce( ( a,b ) => a + b ),
				distance = difference;
			return distance;
		}
		/**
		 * Finds the Euclidean distance between two vectors.
		 * @param {Vector} [vector1=Vector(0)] The first vector in the distance calculation.
		 * @param {Vector} [vector2=Vector(0)] The second vector in the distance calculation.
		 * @returns {number} The resulting distance.
		 * @memberof Vector
		 */
		static linearDistance( vector1 = new Vector( 0 ),vector2 = new Vector( 0 ) ) {
			let firstCoords = [...vector1.coords],
				otherCoords = [...vector2.coords],
				greatest = Math.max( firstCoords.length, otherCoords.length );

			[firstCoords, otherCoords].forEach( ( item ) => {
				while( item.length < greatest ) {
					item.push( 0 );
				}
			} );

			let difference = Array( greatest ).fill( undefined ).map( ( item, index ) => {
					return Math.abs( firstCoords[index] - otherCoords[index] );
				} ).reduce( ( a,b ) => a + b ),
				distance = Math.sqrt( difference );
			return distance;
		}
		/**
		 * Add a vector to another vector
		 * @param {Vector} vector The vector to add.
		 * @returns {Vector} The resulting vector.
		 * @memberof Vector
		 */
		addVector( vector ) {
			if( !( vector instanceof Vector ) ) {
				throw TypeError( 'Vector.prototype.addVector expects a vector' );
			}
			let ownCoords = Object.assign( [], this.coords ),
				otherCoords = Object.assign( [], vector.coords ),
				newLength = Math.max( ownCoords.length, otherCoords.length );

			[ownCoords, otherCoords].forEach( ( item ) => {
				while( item.length < newLength ) {
					item.push( 0 );
				}
			} );

			this.coords = Array( newLength ).fill( undefined ).map( ( item, index ) => {
				return ownCoords[index] + otherCoords[index];
			} );
			return this;
		}
		static equals( vector1, vector2 ) {
			if( !( vector1 instanceof Vector ) && !( vector2 instanceof Vector ) ) {
				throw TypeError( 'Vector.prototype.addVector expects a vector' );
			}
			let firstCoords = [...vector1.coords],
				otherCoords = [...vector2.coords];
			if( firstCoords.length !== otherCoords.length ) {
				return false;
			}

			// They're both equal  length, so it doesn't matter which one we pick.
			let len = firstCoords.length;
			while( --len ) {
				if( firstCoords[len] !== otherCoords[len] ) {
					return false;
				}
			}
			return true;
		}
	}
	return Vector;
} )();
if ( ( 0,eval )( 'this' ).XtraUtils && ( 0,eval )( 'this' ).XtraUtils.Utility ) {
	let _global = ( 0,eval )( 'this' );
	_global.XtraUtils.Vector = new _global.XtraUtils.Utility( Vector );
} else {
	console.warn( 'XtraUtils is not defined. For more details, please visit ' +
						   'https://github.com/FreezePhoenix/XtraUtils/. If your issue still occurs, submit an issue here:' +
						   'https://github.com/FreezePhoenix/XtraUtils/issues/new' );
}