spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[documentation, ts cleanup] cleaning up some ts issues, adding documentation
author
Ben Vogt <[email protected]>
date
2017-09-04 15:42:17
stats
33 file(s) changed, 1265 insertions(+), 1188 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/Convert.js
dist/Formulas/Date.js
dist/Formulas/Range.js
dist/Formulas/Statistical.js
dist/Utilities/CriteriaFunctionFactory.js
dist/Utilities/ObjectFromPairs.js
dist/Utilities/Serializer.js
dist/Utilities/TypeConverter.js
docs.sh
src/Cell.ts
src/Errors.ts
src/Formulas.ts
src/Formulas/AllFormulas.ts
src/Formulas/Convert.ts
src/Formulas/Date.ts
src/Formulas/Engineering.ts
src/Formulas/Financial.ts
src/Formulas/Info.ts
src/Formulas/Logical.ts
src/Formulas/Math.ts
src/Formulas/Range.ts
src/Formulas/Statistical.ts
src/Formulas/Text.ts
src/Sheet.ts
src/Utilities/ArgsChecker.ts
src/Utilities/CriteriaFunctionFactory.ts
src/Utilities/Filter.ts
src/Utilities/MathHelpers.ts
src/Utilities/ObjectFromPairs.ts
src/Utilities/Serializer.ts
src/Utilities/TypeConverter.ts
   1diff --git a/DOCS.md b/DOCS.md
   2index af7be95..3e408c8 100644
   3--- a/DOCS.md
   4+++ b/DOCS.md
   5@@ -3,7 +3,7 @@
   6 ## Convert
   7 
   8 
   9-### DATE 
  10+### TO_DATE 
  11 
  12 ```
  13   Converts a number to a Date. 
  14@@ -12,7 +12,7 @@
  15 @constructor
  16 ```
  17 
  18-### DOLLARS 
  19+### TO_DOLLARS 
  20 
  21 ```
  22   Converts a number to a Dollar value. 
  23@@ -21,13 +21,13 @@
  24 @constructor
  25 ```
  26 
  27-### PERCENT 
  28+### TO_PERCENT 
  29 
  30 ```
  31   Converts a number to a percent value where 1 = 100
  32 ```
  33 
  34-### TEXT 
  35+### TO_TEXT 
  36 
  37 ```
  38   Converts a number to a text value 
  39@@ -204,7 +204,7 @@
  40 @constructor
  41 ```
  42 
  43-### TWORKDAYS 
  44+### NETWORKDAYS 
  45 
  46 ```
  47   Returns the number of net working days between two provided days. 
  48@@ -215,7 +215,7 @@
  49 @constructor
  50 ```
  51 
  52-### INTL 
  53+### TWORKDAYS$INTL 
  54 
  55 ```
  56   Returns the number of networking days between two provided days excluding specified weekend days and holidays. 
  57@@ -265,7 +265,7 @@
  58 @constructor
  59 ```
  60 
  61-### INTL 
  62+### WORKDAY$INTL 
  63 
  64 ```
  65   Calculates the date after a specified number of workdays excluding specified weekend days and holidays. 
  66@@ -1334,7 +1334,7 @@
  67 @constructor
  68 ```
  69 
  70-### NDBETWEEN 
  71+### RANDBETWEEN 
  72 
  73 ```
  74   Returns a uniformly random integer between two values, inclusive on high and low. Values with decimal parts may be used for low andor high; this will cause the least and greatest possible values to be the next integer greater than low andor the next integer less than high, respectively. 
  75@@ -1420,7 +1420,7 @@
  76 @constructor
  77 ```
  78 
  79-### UNTUNIQUE 
  80+### COUNTUNIQUE 
  81 
  82 ```
  83   Counts the number of unique values in a list of specified values and ranges. 
  84@@ -1429,7 +1429,7 @@
  85 @constructor
  86 ```
  87 
  88-### UMPRODUCT 
  89+### SUMPRODUCT 
  90 
  91 ```
  92   Calculates the sum of the products of corresponding entries in two equal-sized arrays or ranges. 
  93@@ -1494,7 +1494,7 @@
  94 @constructor
  95 ```
  96 
  97-### ACTDOUBLE 
  98+### FACTDOUBLE 
  99 
 100 ```
 101   Calculates the double-factorial of a number. 
 102@@ -1503,7 +1503,7 @@
 103 @constructor
 104 ```
 105 
 106-### PERCENT 
 107+### UNARY_PERCENT 
 108 
 109 ```
 110   Returns a value as a percentage where 100 is 1.0, and 0 is 0. 
 111@@ -1512,7 +1512,7 @@
 112 @constructor
 113 ```
 114 
 115-### LTINOMIAL 
 116+### MULTINOMIAL 
 117 
 118 ```
 119   Returns the factorial of the sum of the arguments divided by the product of the factorials of the arguments. 
 120@@ -1633,7 +1633,7 @@
 121 @constructor
 122 ```
 123 
 124-### EFTTAILED 
 125+### IST$LEFTTAILED 
 126 
 127 ```
 128   Calculates the left-tailed F probability distribution (degree of diversity) for two data sets with given input x. Alternately called Fisher-Snedecor distribution or Snecdor's F distribution. 
 129@@ -1739,7 +1739,7 @@
 130 @constructor
 131 ```
 132 
 133-### ERCENTILE 
 134+### PERCENTILE 
 135 
 136 ```
 137   Returns the value at a given percentile of a set of data. 
 138@@ -1813,7 +1813,7 @@
 139 @constructor
 140 ```
 141 
 142-### ANDARDIZE 
 143+### STANDARDIZE 
 144 
 145 ```
 146   Returns the normalized equivalent of a random variable given mean and standard deviation of the distribution. 
 147@@ -1883,7 +1883,7 @@
 148 @constructor
 149 ```
 150 
 151-### RCENTRANK 
 152+### PERCENTRANK 
 153 
 154 ```
 155   Returns the percentage rank (percentile) of the given value in a sample. Functions the same as PERCENTRANK.INC. 
 156@@ -1894,7 +1894,7 @@
 157 @constructor
 158 ```
 159 
 160-### EXC 
 161+### ERCENTRANK$EXC 
 162 
 163 ```
 164   Returns the percentage rank (percentile) from 0 to 1 exclusive for a value in a sample. 
 165@@ -1946,7 +1946,7 @@
 166 @constructor
 167 ```
 168 
 169-### BINOMDIST 
 170+### NEGBINOMDIST 
 171 
 172 ```
 173   Returns the negative binomial distribution. 
 174@@ -1975,7 +1975,7 @@
 175 @constructor
 176 ```
 177 
 178-### ONFIDENCE 
 179+### CONFIDENCE 
 180 
 181 ```
 182   Returns the (1-alpha) confidence interval for a normal distribution. 
 183@@ -2126,7 +2126,7 @@
 184 @constructor
 185 ```
 186 
 187-### AVG 
 188+### RANK$AVG 
 189 
 190 ```
 191   Returns the position of a given entry in the entire list, measured either from top to bottom or bottom to top. If more than one value exists in the same data-set, the average range of the values will be returned. 
 192@@ -2137,7 +2137,7 @@
 193 @constructor
 194 ```
 195 
 196-### EQ 
 197+### RANK$EQ 
 198 
 199 ```
 200   Returns the position of a given entry in the entire list, measured either from top to bottom or bottom to top. If there is more than one entry of the same value in the dataset, the top rank of the entries will be returned. 
 201@@ -2148,7 +2148,7 @@
 202 @constructor
 203 ```
 204 
 205-### GNORMDIST 
 206+### LOGNORMDIST 
 207 
 208 ```
 209   Returns the cumulative lognormal distribution for the given number. 
 210@@ -2210,7 +2210,7 @@
 211 @constructor TODO: At some point this needs to return a more complex type than Array. Needs to return a type that has a dimension.
 212 ```
 213 
 214-### NCATENATE 
 215+### CONCATENATE 
 216 
 217 ```
 218   Appends strings to one another. 
 219diff --git a/TODO.md b/TODO.md
 220index 3c0b6e0..07d1804 100644
 221--- a/TODO.md
 222+++ b/TODO.md
 223@@ -5,10 +5,6 @@
 224 Instead of having non-primitives, (i.e. Date, DateTime, Time, Dollar), cells should have formats based on the highest-order type that was used during the compilation and execution of a cell's dependency. For example, `DATE` might return a number, but the cell that called `DATE` would be aware of it calling a formula that returns an non-primitive type, and would display the returned number as a Date. If you're using `DATE` in conjunction with `DOLLAR` it would still display the returned value as a Date. The hierarchy would look like: [Date, DateTime, Time, Dollar, number, boolean, string]. Advantages to this would include not having to cast down when using primitive operators, and flexibility in display. It would also simplify the types themselves, by having types be constants and just having helpers to convert, display, and do normal operations with them. Requires changes to `TO_DATE`, `TO_PERCENT`, `TO_DOLLAR`, and `TO_TEXT`.
 225 
 226 
 227-### Sheet should automatically parse some values, unless told otherwise.
 228-When entering raw values into cells, if the value is a string, the Sheet should automatically attempt to convert to a number. For example, `= 10e2` should be be evaluated with a RegEx and converted to a number. See `Sheet.helper.number`.
 229-
 230-
 231 ### Cell.rawFormulaText does not get reset when updating a cell for the second time.
 232 
 233 
 234diff --git a/dist/Formulas/Convert.js b/dist/Formulas/Convert.js
 235index 424289a..cf4870d 100644
 236--- a/dist/Formulas/Convert.js
 237+++ b/dist/Formulas/Convert.js
 238@@ -31,7 +31,7 @@ var TO_DOLLARS = function (value) {
 239 };
 240 exports.TO_DOLLARS = TO_DOLLARS;
 241 /**
 242- * Converts a number to a percent value where 1 = 100%
 243+ * Converts a number to a percent value where 1 = 100 percent.
 244  * @param value - Value to convert. If the input is a number, will return as a percent value. If value is non-numeric,
 245  * will return value unchanged.
 246  * @returns {any}
 247diff --git a/dist/Formulas/Date.js b/dist/Formulas/Date.js
 248index bbbfdd2..934aa36 100644
 249--- a/dist/Formulas/Date.js
 250+++ b/dist/Formulas/Date.js
 251@@ -815,7 +815,7 @@ var WORKDAY = function (startDate, numberOfDays, holidays) {
 252     ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "WORKDAY");
 253     startDate = TypeConverter_1.TypeConverter.firstValueAsDateNumber(startDate, true);
 254     numberOfDays = TypeConverter_1.TypeConverter.firstValueAsNumber(numberOfDays);
 255-    var hasHolidays = (cleanHolidays !== undefined);
 256+    var hasHolidays = (holidays !== undefined);
 257     var cleanHolidays = [];
 258     if (hasHolidays !== undefined) {
 259         if (holidays instanceof Array) {
 260diff --git a/dist/Formulas/Range.js b/dist/Formulas/Range.js
 261index dba186f..baf1ff6 100644
 262--- a/dist/Formulas/Range.js
 263+++ b/dist/Formulas/Range.js
 264@@ -102,7 +102,7 @@ var GROWTH = function (knownY, knownX, newX, shouldUseConstant) {
 265     var avg_y = 0;
 266     var avg_xy = 0;
 267     var avg_xx = 0;
 268-    for (i = 0; i < n; i++) {
 269+    for (var i = 0; i < n; i++) {
 270         var x = knownX[i];
 271         var y = Math.log(knownY[i]);
 272         avg_x += x;
 273@@ -127,7 +127,7 @@ var GROWTH = function (knownY, knownX, newX, shouldUseConstant) {
 274     }
 275     // Compute and return result array:
 276     var new_y = [];
 277-    for (i = 0; i < newX.length; i++) {
 278+    for (var i = 0; i < newX.length; i++) {
 279         new_y.push(Math.exp(alpha + beta * newX[i]));
 280     }
 281     return new_y;
 282diff --git a/dist/Formulas/Statistical.js b/dist/Formulas/Statistical.js
 283index b5d50de..a24f626 100644
 284--- a/dist/Formulas/Statistical.js
 285+++ b/dist/Formulas/Statistical.js
 286@@ -27,7 +27,7 @@ var DEVSQ = function () {
 287         count++;
 288     }
 289     var mean = result / count;
 290-    var result = 0;
 291+    result = 0;
 292     for (var i = 0; i < range.length; i++) {
 293         result += Math.pow((TypeConverter_1.TypeConverter.valueToNumber(range[i]) - mean), 2);
 294     }
 295@@ -75,9 +75,9 @@ var MEDIAN = function () {
 296         if (sortedArray.length === 2) {
 297             return AVERAGE(sortedArray[0], sortedArray[1]);
 298         }
 299-        var top = sortedArray[sortedArray.length / 2];
 300+        var top_1 = sortedArray[sortedArray.length / 2];
 301         var bottom = sortedArray[(sortedArray.length / 2) - 1];
 302-        return AVERAGE(top, bottom);
 303+        return AVERAGE(top_1, bottom);
 304     }
 305     else {
 306         // odd number of values
 307@@ -1380,12 +1380,12 @@ var CONFIDENCE = function (alpha, standDev, size) {
 308         return -1.41421356237309505 * std * _erfcinv(2 * p) + m;
 309     }
 310     function _sumsqerr(arr) {
 311-        var mean = mean(arr);
 312+        var m = MathHelpers_1.mean(arr);
 313         var sum = 0;
 314         var i = arr.length;
 315         var tmp;
 316         while (--i >= 0) {
 317-            tmp = arr[i] - mean;
 318+            tmp = arr[i] - m;
 319             sum += tmp * tmp;
 320         }
 321         return sum;
 322@@ -1489,7 +1489,7 @@ var COVAR = function (dataY, dataX) {
 323     dataY = Filter_1.Filter.flattenAndThrow(dataY).map(TypeConverter_1.TypeConverter.valueToNumber);
 324     dataX = Filter_1.Filter.flattenAndThrow(dataX).map(TypeConverter_1.TypeConverter.valueToNumber);
 325     if (dataX.length !== dataY.length) {
 326-        throw new Errors_1.NAError("COVAR has mismatched argument count " + dataY.length + " vs " + dataX.length + ".");
 327+        throw new Errors_1.NAError("COlet has mismatched argument count " + dataY.length + " vs " + dataX.length + ".");
 328     }
 329     var mean1 = MathHelpers_1.mean(dataY);
 330     var mean2 = MathHelpers_1.mean(dataX);
 331@@ -1647,7 +1647,7 @@ var VAR = function () {
 332     var range = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber);
 333     var n = range.length;
 334     if (n < 2) {
 335-        throw new Errors_1.DivZeroError("Evaluation of function VAR caused a divide by zero error.");
 336+        throw new Errors_1.DivZeroError("Evaluation of function let caused a divide by zero error.");
 337     }
 338     var sigma = 0;
 339     var count = 0;
 340diff --git a/dist/Utilities/CriteriaFunctionFactory.js b/dist/Utilities/CriteriaFunctionFactory.js
 341index 6788961..a1519ca 100644
 342--- a/dist/Utilities/CriteriaFunctionFactory.js
 343+++ b/dist/Utilities/CriteriaFunctionFactory.js
 344@@ -46,19 +46,19 @@ var CriteriaFunctionFactory = (function () {
 345             };
 346         }
 347         else if (typeof criteria === "string") {
 348-            var comparisonMatches = criteria.match(/^\s*(<=|>=|=|<>|>|<)\s*(-)?\s*(\$)?\s*([0-9]+([,.][0-9]+)?)\s*$/);
 349-            if (comparisonMatches !== null && comparisonMatches.length >= 6 && comparisonMatches[4] !== undefined) {
 350+            var comparisonMatches_1 = criteria.match(/^\s*(<=|>=|=|<>|>|<)\s*(-)?\s*(\$)?\s*([0-9]+([,.][0-9]+)?)\s*$/);
 351+            if (comparisonMatches_1 !== null && comparisonMatches_1.length >= 6 && comparisonMatches_1[4] !== undefined) {
 352                 criteriaEvaluation = function (x) {
 353-                    return eval(x + comparisonMatches[1] + (comparisonMatches[2] === undefined ? "" : "-") + comparisonMatches[4]);
 354+                    return eval(x + comparisonMatches_1[1] + (comparisonMatches_1[2] === undefined ? "" : "-") + comparisonMatches_1[4]);
 355                 };
 356-                if (comparisonMatches[1] === "=") {
 357+                if (comparisonMatches_1[1] === "=") {
 358                     criteriaEvaluation = function (x) {
 359-                        return eval(x + "===" + (comparisonMatches[2] === undefined ? "" : "-") + comparisonMatches[4]);
 360+                        return eval(x + "===" + (comparisonMatches_1[2] === undefined ? "" : "-") + comparisonMatches_1[4]);
 361                     };
 362                 }
 363-                if (comparisonMatches[1] === "<>") {
 364+                if (comparisonMatches_1[1] === "<>") {
 365                     criteriaEvaluation = function (x) {
 366-                        return eval(x + "!==" + (comparisonMatches[2] === undefined ? "" : "-") + comparisonMatches[4]);
 367+                        return eval(x + "!==" + (comparisonMatches_1[2] === undefined ? "" : "-") + comparisonMatches_1[4]);
 368                     };
 369                 }
 370             }
 371diff --git a/dist/Utilities/ObjectFromPairs.js b/dist/Utilities/ObjectFromPairs.js
 372index 757dd8c..0960b63 100644
 373--- a/dist/Utilities/ObjectFromPairs.js
 374+++ b/dist/Utilities/ObjectFromPairs.js
 375@@ -4,9 +4,9 @@ exports.__esModule = true;
 376  * Static class for building objects using variables as keys. Mostly used in situations where we want to build objects
 377  * with similar key structures inside of arrays.
 378  * ```
 379- * var m = "key";
 380- * var n = "another"
 381- * var x = [
 382+ * let m = "key";
 383+ * let n = "another"
 384+ * let x = [
 385  *   ObjectFromPairs.of([
 386  *     m, 1,
 387  *     n, 2
 388diff --git a/dist/Utilities/Serializer.js b/dist/Utilities/Serializer.js
 389index 1e94aa9..7028479 100644
 390--- a/dist/Utilities/Serializer.js
 391+++ b/dist/Utilities/Serializer.js
 392@@ -7,8 +7,7 @@ var Serializer = (function () {
 393     function Serializer() {
 394     }
 395     Serializer.serialize = function (value) {
 396-        var t = typeof value;
 397-        return "<" + t + ": " + value + ">";
 398+        return "<" + (typeof value) + ": " + value + ">";
 399     };
 400     return Serializer;
 401 }());
 402diff --git a/dist/Utilities/TypeConverter.js b/dist/Utilities/TypeConverter.js
 403index aaa86a1..bbb88f3 100644
 404--- a/dist/Utilities/TypeConverter.js
 405+++ b/dist/Utilities/TypeConverter.js
 406@@ -55,6 +55,12 @@ var TIMESTAMP = DateRegExBuilder_1.DateRegExBuilder.DateRegExBuilder()
 407 var FIRST_YEAR = 1900;
 408 // The year 2000.
 409 var Y2K_YEAR = 2000;
 410+function isUndefined(x) {
 411+    return x === undefined;
 412+}
 413+function isDefined(x) {
 414+    return x !== undefined;
 415+}
 416 /**
 417  * Matches a timestamp string, adding the units to the moment passed in.
 418  * @param timestampString to parse. ok formats: "10am", "10:10", "10:10am", "10:10:10", "10:10:10am", etc.
 419@@ -341,14 +347,7 @@ var TypeConverter = (function () {
 420      * @returns {number} or undefined
 421      */
 422     TypeConverter.stringToNumber = function (value) {
 423-        function isUndefined(x) {
 424-            return x === undefined;
 425-        }
 426-        function isDefined(x) {
 427-            return x !== undefined;
 428-        }
 429-        // var NUMBER_REGEX = /^ *(\+|\-)? *(\$)? *(\+|\-)? *((\d+)?(,\d{3})?(,\d{3})?(,\d{3})?(,\d{3})?)? *(\.)? *(\d*)? *(e|E)? *(\d*)? *(%)? *$/;
 430-        var NUMBER_REGEX = /^ *(\+|\-)? *(\$)? *(\+|\-)? *((\d+)?(,\d{3})?(,\d{3})?(,\d{3})?(,\d{3})?)? *(\.)? *(\d*)? *(e|E)? *(\+|\-)? *(\d*)? *(%)? *$/;
 431+        var NUMBER_REGEX = /^ *([\+/-])? *(\$)? *([\+/-])? *((\d+)?(,\d{3})?(,\d{3})?(,\d{3})?(,\d{3})?)? *(\.)? *(\d*)? *(e|E)? *([\+/-])? *(\d*)? *(%)? *$/;
 432         var matches = value.match(NUMBER_REGEX);
 433         if (matches !== null) {
 434             var firstSign = matches[1];
 435diff --git a/docs.sh b/docs.sh
 436index 18506ae..18cf707 100755
 437--- a/docs.sh
 438+++ b/docs.sh
 439@@ -50,7 +50,7 @@ function process_line() {
 440       CURRENT_BLOCK=$(printf "$CURRENT_BLOCK" | paste -sd " " - | sed -e $'s/@/\\\n@/g')
 441 
 442       # Grab the function name
 443-      FUNCTION_NAME=$(echo "$LINE" | grep -oE '[A-Z0-9]{1,9}\s')
 444+      FUNCTION_NAME=$(echo "$LINE" | grep -oE '[A-Z0-9_\$]{1,14}\s')
 445 
 446       # Build the finalized block
 447       FINALIZED_BLOCK="\n### ${FUNCTION_NAME}\n${FINALIZED_BLOCK}"
 448diff --git a/src/Cell.ts b/src/Cell.ts
 449index 89d781e..5557686 100644
 450--- a/src/Cell.ts
 451+++ b/src/Cell.ts
 452@@ -20,7 +20,7 @@ class Cell {
 453    * @param id key of the cell in A1-format.
 454    */
 455   constructor(id: string) {
 456-    var key = parseKey(id);
 457+    let key = parseKey(id);
 458 
 459     this.id = id;
 460     this.row = key.y;
 461@@ -32,7 +32,7 @@ class Cell {
 462    * @param dependencies to merge with existing dependencies.
 463    */
 464   updateDependencies(dependencies: Array<string>) {
 465-    for (var index in dependencies) {
 466+    for (let index in dependencies) {
 467       if (this.dependencies.indexOf(dependencies[index]) === -1) {
 468         this.dependencies.push(dependencies[index]);
 469       }
 470@@ -182,7 +182,7 @@ class Cell {
 471    * @constructor
 472    */
 473   static BuildFrom(id: string, value: any) : Cell {
 474-    var cell = new Cell(id);
 475+    let cell = new Cell(id);
 476     cell.setValue(value);
 477     return cell;
 478   }
 479@@ -190,7 +190,7 @@ class Cell {
 480 
 481 function toNum(chr) {
 482   chr = chr.replace(/\$/g, '');
 483-  var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;
 484+  let base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;
 485   for (i = 0, j = chr.length - 1; i < chr.length; i += 1, j -= 1) {
 486     result += Math.pow(base.length, j) * (base.indexOf(chr[i]) + 1);
 487   }
 488@@ -201,7 +201,7 @@ function toNum(chr) {
 489 }
 490 
 491 function parseKey(cell) {
 492-  var num = cell.match(/\d+$/),
 493+  let num = cell.match(/\d+$/),
 494     alpha = cell.replace(num, '');
 495 
 496   return {
 497diff --git a/src/Errors.ts b/src/Errors.ts
 498index b838c6f..d84bb72 100644
 499--- a/src/Errors.ts
 500+++ b/src/Errors.ts
 501@@ -1,10 +1,10 @@
 502-var NULL_ERROR = "#NULL!";
 503-var DIV_ZERO_ERROR = "#DIV/0!";
 504-var VALUE_ERROR = "#VALUE!";
 505-var REF_ERROR = "#REF!";
 506-var NAME_ERROR = "#NAME!";
 507-var NUM_ERROR = "#NUM!";
 508-var NA_ERROR = "#N/A";
 509+let NULL_ERROR = "#NULL!";
 510+let DIV_ZERO_ERROR = "#DIV/0!";
 511+let VALUE_ERROR = "#VALUE!";
 512+let REF_ERROR = "#REF!";
 513+let NAME_ERROR = "#NAME!";
 514+let NUM_ERROR = "#NUM!";
 515+let NA_ERROR = "#N/A";
 516 
 517 class NullError extends Error {
 518   constructor(message: string) {
 519diff --git a/src/Formulas.ts b/src/Formulas.ts
 520index 78ea988..ea0cdb9 100644
 521--- a/src/Formulas.ts
 522+++ b/src/Formulas.ts
 523@@ -1,6 +1,6 @@
 524 import * as AllFormulas from "./Formulas/AllFormulas";
 525 
 526-var Formulas = {
 527+let Formulas = {
 528   exists: function(fn: string) {
 529     return ((fn in AllFormulas) || (fn in AllFormulas.__COMPLEX));
 530   },
 531diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
 532index 2b4100e..34966f8 100644
 533--- a/src/Formulas/AllFormulas.ts
 534+++ b/src/Formulas/AllFormulas.ts
 535@@ -251,7 +251,7 @@ import {
 536 } from "./Date"
 537 
 538 // Using alias to bind dot-notation function names.
 539-var __COMPLEX = {
 540+let __COMPLEX = {
 541   "F.DIST": FDIST$LEFTTAILED,
 542   "NETWORKDAYS.INTL": NETWORKDAYS$INTL,
 543   "WORKDAY.INTL": WORKDAY$INTL,
 544diff --git a/src/Formulas/Convert.ts b/src/Formulas/Convert.ts
 545index a362fa0..b299cee 100644
 546--- a/src/Formulas/Convert.ts
 547+++ b/src/Formulas/Convert.ts
 548@@ -12,9 +12,9 @@ import {
 549  * @returns {any}
 550  * @constructor
 551  */
 552-var TO_DATE = function (value) {
 553+let TO_DATE = function (value) {
 554   ArgsChecker.checkLength(arguments, 1, "TO_DATE");
 555-  var v = TypeConverter.firstValue(value);
 556+  let v = TypeConverter.firstValue(value);
 557   if (typeof v === "number") {
 558     return TypeConverter.valueToDateNumber(v);
 559   }
 560@@ -28,20 +28,20 @@ var TO_DATE = function (value) {
 561  * @returns {any}
 562  * @constructor
 563  */
 564-var TO_DOLLARS = function (value) {
 565+let TO_DOLLARS = function (value) {
 566   ArgsChecker.checkLength(arguments, 1, "TO_DOLLAR");
 567   return TypeConverter.firstValue(value);
 568 };
 569 
 570 
 571 /**
 572- * Converts a number to a percent value where 1 = 100%
 573+ * Converts a number to a percent value where 1 = 100 percent.
 574  * @param value - Value to convert. If the input is a number, will return as a percent value. If value is non-numeric,
 575  * will return value unchanged.
 576  * @returns {any}
 577  * @constructor
 578  */
 579-var TO_PERCENT = function (value) {
 580+let TO_PERCENT = function (value) {
 581   ArgsChecker.checkLength(arguments, 1, "TO_PERCENT");
 582   return TypeConverter.firstValue(value);
 583 };
 584@@ -52,9 +52,9 @@ var TO_PERCENT = function (value) {
 585  * @returns {any}
 586  * @constructor
 587  */
 588-var TO_TEXT = function (value) {
 589+let TO_TEXT = function (value) {
 590   ArgsChecker.checkLength(arguments, 1, "TO_TEXT");
 591-  var v = TypeConverter.firstValue(value);
 592+  let v = TypeConverter.firstValue(value);
 593   return TypeConverter.valueToString(v);
 594 };
 595 
 596diff --git a/src/Formulas/Date.ts b/src/Formulas/Date.ts
 597index 687ffa8..b85a570 100644
 598--- a/src/Formulas/Date.ts
 599+++ b/src/Formulas/Date.ts
 600@@ -20,18 +20,18 @@ import {
 601  * @returns {number} newly created date.
 602  * @constructor
 603  */
 604-var DATE = function (year, month, day) : number {
 605+let DATE = function (year, month, day) : number {
 606   const FIRST_YEAR = 1900;
 607   ArgsChecker.checkLength(arguments, 3, "DATE");
 608   year = Math.abs(Math.floor(TypeConverter.firstValueAsNumber(year))); // No negative values for year
 609   month = Math.floor(TypeConverter.firstValueAsNumber(month)) - 1; // Months are between 0 and 11.
 610   day = Math.floor(TypeConverter.firstValueAsNumber(day)) - 1; // Days are also zero-indexed.
 611-  var m = moment.utc(TypeConverter.ORIGIN_MOMENT)
 612+  let m = moment.utc(TypeConverter.ORIGIN_MOMENT)
 613     .add(2, "days")
 614     .add(year < FIRST_YEAR ? year : year - FIRST_YEAR, 'years') // If the value is less than 1900, assume 1900 as start index for year
 615     .add(month, 'months')
 616     .add(day, 'days');
 617-  var dateAsNumber = TypeConverter.momentToDayNumber(m);
 618+  let dateAsNumber = TypeConverter.momentToDayNumber(m);
 619   if (dateAsNumber < 0) {
 620     throw new NumError("DATE evaluates to an out of range value " + dateAsNumber
 621       + ". It should be greater than or equal to 0.");
 622@@ -47,10 +47,10 @@ var DATE = function (year, month, day) : number {
 623  * @returns {number} of days since 1900/1/1, inclusively.
 624  * @constructor
 625  */
 626-var DATEVALUE = function (dateString) : number {
 627+let DATEVALUE = function (dateString) : number {
 628   ArgsChecker.checkLength(arguments, 1, "DATEVALUE");
 629   dateString = TypeConverter.firstValueAsString(dateString);
 630-  var dateAsNumber;
 631+  let dateAsNumber;
 632   try {
 633     dateAsNumber = TypeConverter.stringToDateNumber(dateString);
 634   } catch (e) {
 635@@ -69,9 +69,9 @@ var DATEVALUE = function (dateString) : number {
 636  * @returns {number} date a specified number of months before or after another date
 637  * @constructor
 638  */
 639-var EDATE = function (startDate, months) : number {
 640+let EDATE = function (startDate, months) : number {
 641   ArgsChecker.checkLength(arguments, 2, "EDATE");
 642-  var startDateNumber = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
 643+  let startDateNumber = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
 644   if (startDateNumber < 0) {
 645     throw new NumError("Function EDATE parameter 1 value is " + startDateNumber+ ". It should be greater than or equal to 0.");
 646   }
 647@@ -91,9 +91,9 @@ var EDATE = function (startDate, months) : number {
 648  * @returns {number} the last day of a month
 649  * @constructor
 650  */
 651-var EOMONTH = function (startDate, months) : number {
 652+let EOMONTH = function (startDate, months) : number {
 653   ArgsChecker.checkLength(arguments, 2, "EOMONTH");
 654-  var startDateNumber = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
 655+  let startDateNumber = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
 656   if (startDateNumber < 0) {
 657     throw new NumError("Function EOMONTH parameter 1 value is " + startDateNumber + ". It should be greater than or equal to 0.");
 658   }
 659@@ -112,7 +112,7 @@ var EOMONTH = function (startDate, months) : number {
 660  * @returns {number} day of the month
 661  * @constructor
 662  */
 663-var DAY = function (date) : number {
 664+let DAY = function (date) : number {
 665   ArgsChecker.checkLength(arguments, 1, "DAY");
 666   date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 667   if (date < 0) {
 668@@ -129,7 +129,7 @@ var DAY = function (date) : number {
 669  * @returns {number} of days between start_date and end_date
 670  * @constructor
 671  */
 672-var DAYS = function (endDate, startDate) : number {
 673+let DAYS = function (endDate, startDate) : number {
 674   ArgsChecker.checkLength(arguments, 2, "DAYS");
 675   endDate = TypeConverter.firstValueAsDateNumber(endDate, true); // tell firstValueAsDateNumber to coerce boolean
 676   startDate = TypeConverter.firstValueAsDateNumber(startDate, true); // tell firstValueAsDateNumber to coerce boolean
 677@@ -153,15 +153,15 @@ var DAYS = function (endDate, startDate) : number {
 678  * @returns {number} of days between two dates
 679  * @constructor
 680  */
 681-var DAYS360 = function (startDate, endDate, methodToUse?) : number {
 682+let DAYS360 = function (startDate, endDate, methodToUse?) : number {
 683   ArgsChecker.checkLengthWithin(arguments, 2, 3, "DAYS360");
 684   startDate = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(startDate, true)); // tell firstValueAsDateNumber to coerce boolean
 685   endDate = TypeConverter.numberToMoment(TypeConverter.firstValueAsDateNumber(endDate, true)); // tell firstValueAsDateNumber to coerce boolean
 686   methodToUse = methodToUse ? TypeConverter.firstValueAsBoolean(methodToUse) : false;
 687-  var smd = 31;
 688-  var emd = 31;
 689-  var sd = startDate.date();
 690-  var ed = endDate.date();
 691+  let smd = 31;
 692+  let emd = 31;
 693+  let sd = startDate.date();
 694+  let ed = endDate.date();
 695   if (methodToUse) {
 696     sd = (sd === 31) ? 30 : sd;
 697     ed = (ed === 31) ? 30 : ed;
 698@@ -189,7 +189,7 @@ var DAYS360 = function (startDate, endDate, methodToUse?) : number {
 699  * @returns {number} month of the year that the input date falls on.
 700  * @constructor
 701  */
 702-var MONTH = function (date) : number {
 703+let MONTH = function (date) : number {
 704   ArgsChecker.checkLength(arguments, 1, "MONTH");
 705   date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 706   if (date < 0) {
 707@@ -206,7 +206,7 @@ var MONTH = function (date) : number {
 708  * @returns {number} year of the input date
 709  * @constructor
 710  */
 711-var YEAR = function (date) : number {
 712+let YEAR = function (date) : number {
 713   ArgsChecker.checkLength(arguments, 1, "YEAR");
 714   date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 715   if (date < 0) {
 716@@ -228,14 +228,14 @@ var YEAR = function (date) : number {
 717  * @returns {number} day of week
 718  * @constructor
 719  */
 720-var WEEKDAY = function (date, offsetType?) : number {
 721+let WEEKDAY = function (date, offsetType?) : number {
 722   ArgsChecker.checkLengthWithin(arguments, 1, 2, "WEEKDAY");
 723   date = TypeConverter.firstValueAsDateNumber(date, true); // tell firstValueAsDateNumber to coerce boolean
 724   offsetType = offsetType ? TypeConverter.firstValueAsNumber(offsetType) : 1;
 725   if (date < 0) {
 726     throw new NumError("Function WEEKDAY parameter 1 value is " + date + ". It should be greater than or equal to 0.");
 727   }
 728-  var day = TypeConverter.numberToMoment(date).day();
 729+  let day = TypeConverter.numberToMoment(date).day();
 730   if (offsetType === 1) {
 731     return day + 1;
 732   } else if (offsetType === 2) {
 733@@ -270,12 +270,12 @@ var WEEKDAY = function (date, offsetType?) : number {
 734  * @returns {number} representing week number of year.
 735  * @constructor
 736  */
 737-var WEEKNUM = function (date, shiftType?) : number {
 738+let WEEKNUM = function (date, shiftType?) : number {
 739   // Given a moment, an array of days of the week for shifting, will calculate the week number.
 740   function calculateWeekNum(dm : moment.Moment, shifterArray : Array<number>) : number {
 741-    var startOfYear = moment.utc(dm).startOf("year");
 742-    var weeksCount = 1;
 743-    var d = moment.utc(dm).startOf("year").add(6 - shifterArray[startOfYear.day()], "days");
 744+    let startOfYear = moment.utc(dm).startOf("year");
 745+    let weeksCount = 1;
 746+    let d = moment.utc(dm).startOf("year").add(6 - shifterArray[startOfYear.day()], "days");
 747     while (d.isBefore(dm)) {
 748       d.add(7, "days");
 749       weeksCount++;
 750@@ -289,9 +289,9 @@ var WEEKNUM = function (date, shiftType?) : number {
 751   if (date < 0) {
 752     throw new NumError("Function YEAR parameter 1 value is " + date + ". It should be greater than or equal to 0.");
 753   }
 754-  var dm = TypeConverter.numberToMoment(date);
 755-  var week = dm.week();
 756-  var dayOfWeek = dm.day(); // between 1 and 7, inclusively
 757+  let dm = TypeConverter.numberToMoment(date);
 758+  let week = dm.week();
 759+  let dayOfWeek = dm.day(); // between 1 and 7, inclusively
 760   if (shiftType === 1) {
 761     // If this weekYear is not the same as the year, then we're technically in "week 53"
 762     // See https://momentjs.com/docs/#/get-set/week-year/ for more info.
 763@@ -354,14 +354,14 @@ var WEEKNUM = function (date, shiftType?) : number {
 764  * @returns {number} number of days, months, or years between two dates.
 765  * @constructor
 766  */
 767-var DATEDIF = function (startDate, endDate, unit) : number {
 768+let DATEDIF = function (startDate, endDate, unit) : number {
 769   ArgsChecker.checkLength(arguments, 3, "DATEDIF");
 770   startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 771   endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
 772   unit = TypeConverter.firstValueAsString(unit);
 773-  var unitClean = unit.toUpperCase();
 774-  var startMoment = TypeConverter.numberToMoment(startDate);
 775-  var endMoment = TypeConverter.numberToMoment(endDate);
 776+  let unitClean = unit.toUpperCase();
 777+  let startMoment = TypeConverter.numberToMoment(startDate);
 778+  let endMoment = TypeConverter.numberToMoment(endDate);
 779 
 780   if (startDate > endDate) {
 781     throw new NumError("Function DATEDIF parameter 1 (" + startDate.toString() +
 782@@ -375,28 +375,28 @@ var DATEDIF = function (startDate, endDate, unit) : number {
 783   } else if (unitClean === "D") {
 784     return endDate - startDate;
 785   } else if (unitClean === "MD") {
 786-    var s = startMoment;
 787+    let s = startMoment;
 788     while(s.isBefore(endMoment)) {
 789       s.add(1, "month");
 790     }
 791     s.subtract(1, "month");
 792-    var days = endMoment.diff(s, "days");
 793+    let days = endMoment.diff(s, "days");
 794     return s.date() === endMoment.date() ? 0 : days;
 795   } else if (unitClean === "YM") {
 796-    var s = startMoment;
 797+    let s = startMoment;
 798     while(s.isBefore(endMoment)) {
 799       s.add(1, "year");
 800     }
 801     s.subtract(1, "year");
 802-    var months = Math.floor(endMoment.diff(s, "months"));
 803+    let months = Math.floor(endMoment.diff(s, "months"));
 804     return months === 12 ? 0 : months;
 805   } else if (unitClean === "YD") {
 806-    var s = startMoment;
 807+    let s = startMoment;
 808     while(s.isBefore(endMoment)) {
 809       s.add(1, "year");
 810     }
 811     s.subtract(1, "year");
 812-    var days = Math.floor(endMoment.diff(s, "days"));
 813+    let days = Math.floor(endMoment.diff(s, "days"));
 814     return days >= 365 ? 0 : days;
 815   } else {
 816     throw new NumError("Function DATEDIF parameter 3 value is " + unit +
 817@@ -423,37 +423,37 @@ var DATEDIF = function (startDate, endDate, unit) : number {
 818  * @returns {number}the number of years, including fractional years, between two dates
 819  * @constructor
 820  */
 821-var YEARFRAC = function (startDate, endDate, dayCountConvention?) : number {
 822+let YEARFRAC = function (startDate, endDate, dayCountConvention?) : number {
 823   ArgsChecker.checkLengthWithin(arguments, 2, 3, "YEARFRAC");
 824   startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 825   endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
 826   dayCountConvention = dayCountConvention ? TypeConverter.firstValueAsNumber(dayCountConvention) : 0;
 827 
 828-  var s = TypeConverter.numberToMoment(startDate);
 829-  var e = TypeConverter.numberToMoment(endDate);
 830+  let s = TypeConverter.numberToMoment(startDate);
 831+  let e = TypeConverter.numberToMoment(endDate);
 832   if (e.isBefore(s)) {
 833-    var me = moment.utc(e);
 834+    let me = moment.utc(e);
 835     e = moment.utc(s);
 836     s = me;
 837   }
 838-  var syear = s.year();
 839-  var smonth = s.month();
 840-  var sday = s.date();
 841-  var eyear = e.year();
 842-  var emonth = e.month();
 843-  var eday = e.date();
 844+  let syear = s.year();
 845+  let smonth = s.month();
 846+  let sday = s.date();
 847+  let eyear = e.year();
 848+  let emonth = e.month();
 849+  let eday = e.date();
 850 
 851 
 852-  var feb29Between = function (date1, date2) {
 853+  let feb29Between = function (date1, date2) {
 854     // Requires year2 == (year1 + 1) or year2 == year1
 855     // Returns TRUE if February 29 is between the two dates (date1 may be February 29), with two possibilities:
 856     // year1 is a leap year and date1 <= February 29 of year1
 857     // year2 is a leap year and date2 > February 29 of year2
 858-    var mar1year1 = moment.utc(new Date(date1.year(), 2, 1));
 859+    let mar1year1 = moment.utc(new Date(date1.year(), 2, 1));
 860     if (moment.utc([date1.year()]).isLeapYear() && date1.diff(mar1year1) < 0 && date2.diff(mar1year1) >= 0) {
 861       return true;
 862     }
 863-    var mar1year2 = moment.utc(new Date(date2.year(), 2, 1));
 864+    let mar1year2 = moment.utc(new Date(date2.year(), 2, 1));
 865     if (moment.utc([date2.year()]).isLeapYear() && date2.diff(mar1year2) >= 0 && date1.diff(mar1year2) < 0) {
 866       return true;
 867     }
 868@@ -480,7 +480,7 @@ var YEARFRAC = function (startDate, endDate, dayCountConvention?) : number {
 869       return Math.abs(((eday + emonth * 30 + eyear * 360) - (sday + smonth * 30 + syear * 360)) / 360);
 870     // Actual/actual
 871     case 1:
 872-      var ylength = 365;
 873+      let ylength = 365;
 874       if (syear === eyear || ((syear + 1) === eyear) && ((smonth > emonth) || ((smonth === emonth) && (sday >= eday)))) {
 875         if (syear === eyear && moment.utc([syear]).isLeapYear()) {
 876           ylength = 366;
 877@@ -489,9 +489,9 @@ var YEARFRAC = function (startDate, endDate, dayCountConvention?) : number {
 878         }
 879         return Math.abs((endDate - startDate) / ylength);
 880       } else {
 881-        var years = (eyear - syear) + 1;
 882-        var days = moment.utc([eyear+1]).startOf("year").diff(moment.utc([syear]).startOf("year"), 'days');
 883-        var average = days / years;
 884+        let years = (eyear - syear) + 1;
 885+        let days = moment.utc([eyear+1]).startOf("year").diff(moment.utc([syear]).startOf("year"), 'days');
 886+        let average = days / years;
 887         return Math.abs((endDate - startDate) / average);
 888       }
 889     // Actual/360
 890@@ -518,7 +518,7 @@ var YEARFRAC = function (startDate, endDate, dayCountConvention?) : number {
 891  * @returns {number} representing the fraction of a 24-hour day
 892  * @constructor
 893  */
 894-var TIMEVALUE = function (timeString) : number {
 895+let TIMEVALUE = function (timeString) : number {
 896   ArgsChecker.checkLength(arguments, 1, "TIMEVALUE");
 897   timeString = TypeConverter.firstValueAsString(timeString);
 898   try {
 899@@ -537,13 +537,13 @@ const MILLISECONDS_IN_DAY = 86400000;
 900  * @returns {number}
 901  * @constructor
 902  */
 903-var HOUR = function (time) : number {
 904+let HOUR = function (time) : number {
 905   ArgsChecker.checkLength(arguments, 1, "HOUR");
 906   time = TypeConverter.firstValueAsTimestampNumber(time);
 907   if (time % 1 === 0) {
 908     return 0;
 909   }
 910-  var m = moment.utc([1900]).add(time * MILLISECONDS_IN_DAY, "milliseconds");
 911+  let m = moment.utc([1900]).add(time * MILLISECONDS_IN_DAY, "milliseconds");
 912   return m.hour();
 913 };
 914 
 915@@ -555,13 +555,13 @@ var HOUR = function (time) : number {
 916  * @returns {number} minute of the time passed in.
 917  * @constructor
 918  */
 919-var MINUTE = function (time) : number {
 920+let MINUTE = function (time) : number {
 921   ArgsChecker.checkLength(arguments, 1, "MINUTE");
 922   time = TypeConverter.firstValueAsTimestampNumber(time);
 923   if (time % 1 === 0) {
 924     return 0;
 925   }
 926-  var m = moment.utc([1900]).add(time * MILLISECONDS_IN_DAY, "milliseconds");
 927+  let m = moment.utc([1900]).add(time * MILLISECONDS_IN_DAY, "milliseconds");
 928   return m.minute();
 929 };
 930 
 931@@ -572,13 +572,13 @@ var MINUTE = function (time) : number {
 932  * @returns {number} second component of a specific time.
 933  * @constructor
 934  */
 935-var SECOND = function (time) : number {
 936+let SECOND = function (time) : number {
 937   ArgsChecker.checkLength(arguments, 1, "SECOND");
 938   time = TypeConverter.firstValueAsTimestampNumber(time);
 939   if (time % 1 === 0) {
 940     return 0;
 941   }
 942-  var m = moment.utc([1900]).add(time * MILLISECONDS_IN_DAY, "milliseconds");
 943+  let m = moment.utc([1900]).add(time * MILLISECONDS_IN_DAY, "milliseconds");
 944   return m.second();
 945 };
 946 
 947@@ -594,18 +594,18 @@ var SECOND = function (time) : number {
 948  * @returns {number} the number of net working days between two provided dates.
 949  * @constructor
 950  */
 951-var NETWORKDAYS = function (startDate, endDate, holidays?) : number {
 952+let NETWORKDAYS = function (startDate, endDate, holidays?) : number {
 953   ArgsChecker.checkLengthWithin(arguments, 2, 3, "NETWORKDAYS");
 954   startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
 955   endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
 956-  var hasHolidays = (holidays !== undefined);
 957-  var cleanHolidays = [];
 958+  let hasHolidays = (holidays !== undefined);
 959+  let cleanHolidays = [];
 960   if (hasHolidays) {
 961     holidays = (holidays instanceof Array) ? holidays : [holidays];
 962     if (holidays.length === 0) {
 963       throw new RefError("Reference does not exist.");
 964     }
 965-    for (var holidayDateValue of holidays) {
 966+    for (let holidayDateValue of holidays) {
 967       if (typeof holidayDateValue === "number") {
 968         cleanHolidays.push(holidayDateValue);
 969       } else {
 970@@ -615,18 +615,18 @@ var NETWORKDAYS = function (startDate, endDate, holidays?) : number {
 971     }
 972   }
 973   // Handle cases in which the start date is not before the end date.
 974-  var didSwap = startDate > endDate;
 975+  let didSwap = startDate > endDate;
 976   if (didSwap) {
 977-    var swap = endDate;
 978+    let swap = endDate;
 979     endDate = startDate;
 980     startDate = swap;
 981   }
 982 
 983-  var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
 984-  var weekendDays = [6, 0]; // Default weekend_days.
 985-  var days = endDate - startDate + 1;
 986-  var networkDays = days;
 987-  var j = 0;
 988+  let countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
 989+  let weekendDays = [6, 0]; // Default weekend_days.
 990+  let days = endDate - startDate + 1;
 991+  let networkDays = days;
 992+  let j = 0;
 993   while (j < days) {
 994     if (weekendDays.indexOf(countMoment.day()) >= 0) {
 995       networkDays--;
 996@@ -661,11 +661,11 @@ var NETWORKDAYS = function (startDate, endDate, holidays?) : number {
 997  * @returns {number} of networking days between two provided days
 998  * @constructor
 999  */
1000-var NETWORKDAYS$INTL = function (startDate, endDate, weekend?, holidays?) : number {
1001+let NETWORKDAYS$INTL = function (startDate, endDate, weekend?, holidays?) : number {
1002   ArgsChecker.checkLengthWithin(arguments, 2, 4, "NETWORKDAYS$INTL");
1003   startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
1004   endDate = TypeConverter.firstValueAsDateNumber(endDate, true);
1005-  var weekendDays = [];
1006+  let weekendDays = [];
1007   if (weekend !== undefined) {
1008     weekend = TypeConverter.firstValue(weekend);
1009     if (typeof weekend === "string") {
1010@@ -673,8 +673,8 @@ var NETWORKDAYS$INTL = function (startDate, endDate, weekend?, holidays?) : numb
1011         throw new NumError("Function NETWORKDAYS.INTL parameter 3 requires a number in the format '0000011'. "
1012             + "Actual value is '" + weekend + "'");
1013       }
1014-      var ws = weekend.split("");
1015-      for (var i = 0; i < ws.length; i++) {
1016+      let ws = weekend.split("");
1017+      for (let i = 0; i < ws.length; i++) {
1018         if (ws[i] === "1") {
1019           weekendDays.push(i === 6 ? 0 : i + 1);
1020         }
1021@@ -712,13 +712,13 @@ var NETWORKDAYS$INTL = function (startDate, endDate, weekend?, holidays?) : numb
1022   } else {
1023     weekendDays = [0, 6];
1024   }
1025-  var hasHolidays = holidays !== undefined;
1026-  var cleanHolidays = [];
1027+  let hasHolidays = holidays !== undefined;
1028+  let cleanHolidays = [];
1029   if (hasHolidays) {
1030     if (holidays === 0) {
1031       throw new RefError("Reference does not exist.");
1032     }
1033-    for (var holidayDateValue of holidays) {
1034+    for (let holidayDateValue of holidays) {
1035       if (typeof holidayDateValue === "number") {
1036         cleanHolidays.push(holidayDateValue);
1037       } else {
1038@@ -728,17 +728,17 @@ var NETWORKDAYS$INTL = function (startDate, endDate, weekend?, holidays?) : numb
1039     }
1040   }
1041   // Handle cases in which the start date is not before the end date.
1042-  var didSwap = startDate > endDate;
1043+  let didSwap = startDate > endDate;
1044   if (didSwap) {
1045-    var swap = endDate;
1046+    let swap = endDate;
1047     endDate = startDate;
1048     startDate = swap;
1049   }
1050 
1051-  var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
1052-  var days = endDate - startDate + 1;
1053-  var networkDays = days;
1054-  var j = 0;
1055+  let countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
1056+  let days = endDate - startDate + 1;
1057+  let networkDays = days;
1058+  let j = 0;
1059   while (j < days) {
1060     if (weekendDays.indexOf(countMoment.day()) >= 0) {
1061       networkDays--;
1062@@ -760,7 +760,7 @@ var NETWORKDAYS$INTL = function (startDate, endDate, weekend?, holidays?) : numb
1063  * @returns {number} representing the current date and time.
1064  * @constructor
1065  */
1066-var NOW = function () : number {
1067+let NOW = function () : number {
1068   ArgsChecker.checkLength(arguments, 0, "NOW");
1069   return TypeConverter.momentToNumber(moment.utc());
1070 };
1071@@ -770,7 +770,7 @@ var NOW = function () : number {
1072  * @returns {number} today
1073  * @constructor
1074  */
1075-var TODAY = function () : number {
1076+let TODAY = function () : number {
1077   ArgsChecker.checkLength(arguments, 0, "TODAY");
1078   return TypeConverter.momentToNumber(moment.utc().startOf("day"));
1079 };
1080@@ -785,12 +785,12 @@ var TODAY = function () : number {
1081  * @returns {number} time of day
1082  * @constructor
1083  */
1084-var TIME = function (hours, minutes, seconds) : number {
1085+let TIME = function (hours, minutes, seconds) : number {
1086   ArgsChecker.checkLength(arguments, 3, "TIME");
1087   hours = Math.floor(TypeConverter.firstValueAsNumber(hours));
1088   minutes = Math.floor(TypeConverter.firstValueAsNumber(minutes));
1089   seconds = Math.floor(TypeConverter.firstValueAsNumber(seconds));
1090-  var e = TypeConverter.unitsToTimeNumber(hours, minutes, seconds);
1091+  let e = TypeConverter.unitsToTimeNumber(hours, minutes, seconds);
1092   if (e < 0) {
1093     throw new NumError("TIME evaluates to an out of range value " + e + ". It should be greater than or equal to 0.");
1094   }
1095@@ -810,18 +810,18 @@ var TIME = function (hours, minutes, seconds) : number {
1096  * @returns {number} end date after a specified number of working days.
1097  * @constructor
1098  */
1099-var WORKDAY = function (startDate, numberOfDays, holidays?) : number {
1100+let WORKDAY = function (startDate, numberOfDays, holidays?) : number {
1101   ArgsChecker.checkLengthWithin(arguments, 2, 3, "WORKDAY");
1102   startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
1103   numberOfDays = TypeConverter.firstValueAsNumber(numberOfDays);
1104-  var hasHolidays = (cleanHolidays !== undefined);
1105-  var cleanHolidays = [];
1106+  let hasHolidays = (holidays !== undefined);
1107+  let cleanHolidays = [];
1108   if (hasHolidays !== undefined) {
1109     if (holidays instanceof Array) {
1110       if (holidays.length === 0) {
1111         throw new RefError("Reference does not exist.");
1112       }
1113-      for (var holidayDateValue of holidays) {
1114+      for (let holidayDateValue of holidays) {
1115         if (typeof holidayDateValue === "number") {
1116           cleanHolidays.push(holidayDateValue);
1117         } else {
1118@@ -834,9 +834,9 @@ var WORKDAY = function (startDate, numberOfDays, holidays?) : number {
1119     }
1120   }
1121 
1122-  var weekendDays = [0, 6];
1123-  var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
1124-  var j = 0;
1125+  let weekendDays = [0, 6];
1126+  let countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
1127+  let j = 0;
1128   while (j < numberOfDays) {
1129     countMoment.add(1, 'days');
1130     if (weekendDays.indexOf(countMoment.day()) < 0 && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
1131@@ -862,11 +862,11 @@ var WORKDAY = function (startDate, numberOfDays, holidays?) : number {
1132  * @returns {number}
1133  * @constructor
1134  */
1135-var WORKDAY$INTL = function (startDate, numberOfDays, weekend?, holidays?) : number {
1136+let WORKDAY$INTL = function (startDate, numberOfDays, weekend?, holidays?) : number {
1137   ArgsChecker.checkLengthWithin(arguments, 2, 3, "WORKDAY$INTL");
1138   startDate = TypeConverter.firstValueAsDateNumber(startDate, true);
1139   numberOfDays = TypeConverter.firstValueAsNumber(numberOfDays);
1140-  var weekendDays = [];
1141+  let weekendDays = [];
1142   if (weekend !== undefined) {
1143     weekend = TypeConverter.firstValue(weekend);
1144     if (typeof weekend === "string") {
1145@@ -874,8 +874,8 @@ var WORKDAY$INTL = function (startDate, numberOfDays, weekend?, holidays?) : num
1146         throw new NumError("Function WORKDAY.INTL parameter 3 requires a number in the format '0000011'. "
1147           + "Actual value is '" + weekend + "'");
1148       }
1149-      var ws = weekend.split("");
1150-      for (var i = 0; i < ws.length; i++) {
1151+      let ws = weekend.split("");
1152+      for (let i = 0; i < ws.length; i++) {
1153         if (ws[i] === "1") {
1154           weekendDays.push(i === 6 ? 0 : i + 1);
1155         }
1156@@ -913,14 +913,14 @@ var WORKDAY$INTL = function (startDate, numberOfDays, weekend?, holidays?) : num
1157   } else {
1158     weekendDays = [0, 6];
1159   }
1160-  var hasHolidays = (holidays !== undefined);
1161-  var cleanHolidays = [];
1162+  let hasHolidays = (holidays !== undefined);
1163+  let cleanHolidays = [];
1164   if (hasHolidays) {
1165     if (holidays instanceof Array) {
1166       if (holidays.length === 0) {
1167         throw new RefError("Reference does not exist.");
1168       }
1169-      for (var holidayDateValue of holidays) {
1170+      for (let holidayDateValue of holidays) {
1171         if (typeof holidayDateValue === "number") {
1172           cleanHolidays.push(holidayDateValue);
1173         } else {
1174@@ -932,8 +932,8 @@ var WORKDAY$INTL = function (startDate, numberOfDays, weekend?, holidays?) : num
1175       cleanHolidays.push(TypeConverter.valueToNumber(holidays));
1176     }
1177   }
1178-  var countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
1179-  var j = 0;
1180+  let countMoment = moment.utc(TypeConverter.numberToMoment(startDate));
1181+  let j = 0;
1182   while (j < numberOfDays) {
1183     countMoment.add(1, 'days');
1184     if (weekendDays.indexOf(countMoment.day()) < 0 && cleanHolidays.indexOf(TypeConverter.momentToDayNumber(countMoment)) < 0) {
1185diff --git a/src/Formulas/Engineering.ts b/src/Formulas/Engineering.ts
1186index 3c3e226..874aa68 100644
1187--- a/src/Formulas/Engineering.ts
1188+++ b/src/Formulas/Engineering.ts
1189@@ -17,12 +17,12 @@ import {
1190  * @returns {number}
1191  * @constructor
1192  */
1193-var BIN2DEC = function (signedBinaryNumber) : number {
1194+let BIN2DEC = function (signedBinaryNumber) : number {
1195   ArgsChecker.checkLength(arguments, 1, "BIN2DEC");
1196   if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
1197     throw new ValueError("Function BIN2DEC parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
1198   }
1199-  var n = TypeConverter.firstValueAsString(signedBinaryNumber);
1200+  let n = TypeConverter.firstValueAsString(signedBinaryNumber);
1201   if (!(/^[01]{1,10}$/).test(n)) {
1202     throw new NumError("Input for BIN2DEC ('" + n + "') is not a valid binary representation.");
1203   }
1204@@ -43,13 +43,13 @@ var BIN2DEC = function (signedBinaryNumber) : number {
1205  * @returns {string} string representation of a signed hexadecimal
1206  * @constructor
1207  */
1208-var BIN2HEX = function (signedBinaryNumber, significantDigits?) : string {
1209+let BIN2HEX = function (signedBinaryNumber, significantDigits?) : string {
1210   ArgsChecker.checkLengthWithin(arguments, 1, 2, "BIN2HEX");
1211   if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
1212     throw new ValueError("Function BIN2HEX parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
1213   }
1214-  var n = TypeConverter.firstValueAsString(signedBinaryNumber);
1215-  var p = 10;
1216+  let n = TypeConverter.firstValueAsString(signedBinaryNumber);
1217+  let p = 10;
1218   if (significantDigits !== undefined) {
1219     p = TypeConverter.firstValueAsNumber(significantDigits);
1220   }
1221@@ -66,12 +66,12 @@ var BIN2HEX = function (signedBinaryNumber, significantDigits?) : string {
1222   }
1223   p = Math.floor(p);
1224   // Convert decimal number to hexadecimal
1225-  var result = parseInt(n.toString(), 2).toString(16).toUpperCase();
1226+  let result = parseInt(n.toString(), 2).toString(16).toUpperCase();
1227   if (p === 10) {
1228     return result;
1229   }
1230-  var str = "";
1231-  for (var i = 0; i < p - result.length; i++) {
1232+  let str = "";
1233+  for (let i = 0; i < p - result.length; i++) {
1234     str += "0";
1235   }
1236   return str + result;
1237@@ -89,13 +89,13 @@ var BIN2HEX = function (signedBinaryNumber, significantDigits?) : string {
1238  * @returns {string} number in octal format
1239  * @constructor
1240  */
1241-var BIN2OCT = function (signedBinaryNumber, significantDigits?) : string {
1242+let BIN2OCT = function (signedBinaryNumber, significantDigits?) : string {
1243   ArgsChecker.checkLengthWithin(arguments, 1, 2, "BIN2OCT");
1244   if (typeof TypeConverter.firstValue(signedBinaryNumber) === "boolean") {
1245     throw new ValueError("Function BIN2OCT parameter 1 expects text values. But '" + signedBinaryNumber + "' is a boolean and cannot be coerced to a text.");
1246   }
1247-  var n = TypeConverter.firstValueAsString(signedBinaryNumber);
1248-  var p = 10;
1249+  let n = TypeConverter.firstValueAsString(signedBinaryNumber);
1250+  let p = 10;
1251   if (significantDigits !== undefined) {
1252     p = TypeConverter.firstValueAsNumber(significantDigits);
1253   }
1254@@ -111,13 +111,13 @@ var BIN2OCT = function (signedBinaryNumber, significantDigits?) : string {
1255     throw new NumError("Function BIN2OCT parameter 2 value is " + p + ". Valid values are between 1 and 10 inclusive.");
1256   }
1257   p = Math.floor(p);
1258-  var result = parseInt(n.toString(), 2).toString(8);
1259+  let result = parseInt(n.toString(), 2).toString(8);
1260   if (p === 10) {
1261     return result;
1262   }
1263   if (p >= result.length) {
1264-    var str = "";
1265-    for (var i = 0; i < p - result.length - 1; i++) {
1266+    let str = "";
1267+    for (let i = 0; i < p - result.length - 1; i++) {
1268       str += "0";
1269     }
1270     return str + result;
1271@@ -134,17 +134,17 @@ var BIN2OCT = function (signedBinaryNumber, significantDigits?) : string {
1272  * @returns {string} octal string representation of the decimal number
1273  * @constructor
1274  */
1275-var DEC2OCT = function (decimalDumber, significantDigits?) : string {
1276+let DEC2OCT = function (decimalDumber, significantDigits?) : string {
1277   ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2OCT");
1278-  var n = TypeConverter.firstValueAsNumber(decimalDumber);
1279+  let n = TypeConverter.firstValueAsNumber(decimalDumber);
1280   if (n < 0) {
1281     n = Math.ceil(n);
1282   }
1283   if (n > 0) {
1284     n = Math.floor(n);
1285   }
1286-  var p = 10;
1287-  var placesPresent = false;
1288+  let p = 10;
1289+  let placesPresent = false;
1290   if (significantDigits !== undefined) {
1291     p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1292     placesPresent = true;
1293@@ -160,12 +160,12 @@ var DEC2OCT = function (decimalDumber, significantDigits?) : string {
1294   }
1295 
1296   // Convert decimal number to hexadecimal
1297-  var result = parseInt(n.toString(), 10).toString(8).toUpperCase();
1298+  let result = parseInt(n.toString(), 10).toString(8).toUpperCase();
1299   if (!placesPresent) {
1300     return result;
1301   }
1302-  var str = "";
1303-  for (var i = 0; i < p - result.length; i++) {
1304+  let str = "";
1305+  for (let i = 0; i < p - result.length; i++) {
1306     str += "0";
1307   }
1308   return str + result.toUpperCase();
1309@@ -182,17 +182,17 @@ var DEC2OCT = function (decimalDumber, significantDigits?) : string {
1310  * @returns {string} hexadecimal string representation of the decimal number
1311  * @constructor
1312  */
1313-var DEC2HEX = function (decimalDumber, significantDigits?) : string {
1314+let DEC2HEX = function (decimalDumber, significantDigits?) : string {
1315   ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2HEX");
1316-  var n = TypeConverter.firstValueAsNumber(decimalDumber);
1317+  let n = TypeConverter.firstValueAsNumber(decimalDumber);
1318   if (n < 0) {
1319     n = Math.ceil(n);
1320   }
1321   if (n > 0) {
1322     n = Math.floor(n);
1323   }
1324-  var p = 10;
1325-  var placesPresent = false;
1326+  let p = 10;
1327+  let placesPresent = false;
1328   if (significantDigits !== undefined) {
1329     p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1330     placesPresent = true;
1331@@ -209,12 +209,12 @@ var DEC2HEX = function (decimalDumber, significantDigits?) : string {
1332   }
1333 
1334   // Convert decimal number to hexadecimal
1335-  var result = parseInt(n.toString(), 10).toString(16).toUpperCase();
1336+  let result = parseInt(n.toString(), 10).toString(16).toUpperCase();
1337   if (!placesPresent) {
1338     return result;
1339   }
1340-  var str = "";
1341-  for (var i = 0; i < p - result.length; i++) {
1342+  let str = "";
1343+  for (let i = 0; i < p - result.length; i++) {
1344     str += "0";
1345   }
1346   return str + result;
1347@@ -230,9 +230,9 @@ var DEC2HEX = function (decimalDumber, significantDigits?) : string {
1348  * @returns {string} signed binary string representation of the input decimal number.
1349  * @constructor
1350  */
1351-var DEC2BIN = function (decimalDumber, significantDigits?) : string {
1352+let DEC2BIN = function (decimalDumber, significantDigits?) : string {
1353   ArgsChecker.checkLengthWithin(arguments, 1, 2, "DEC2BIN");
1354-  var n = TypeConverter.firstValueAsNumber(decimalDumber);
1355+  let n = TypeConverter.firstValueAsNumber(decimalDumber);
1356   if (n < 0) {
1357     n = Math.ceil(n);
1358   }
1359@@ -242,8 +242,8 @@ var DEC2BIN = function (decimalDumber, significantDigits?) : string {
1360   if (n === 0 || n === 1) {
1361     return n.toString();
1362   }
1363-  var p = 10;
1364-  var placesPresent = false;
1365+  let p = 10;
1366+  let placesPresent = false;
1367   if (significantDigits !== undefined) {
1368     p = Math.floor(TypeConverter.firstValueAsNumber(significantDigits));
1369     placesPresent = true;
1370@@ -258,28 +258,28 @@ var DEC2BIN = function (decimalDumber, significantDigits?) : string {
1371 
1372   // Ignore places and return a 10-character binary number if number is negative
1373   if (n < 0) {
1374-    var count = (9 - (512 + n).toString(2).length);
1375-    var st = "";
1376-    for (var i = 0; i < count; i++) {
1377+    let count = (9 - (512 + n).toString(2).length);
1378+    let st = "";
1379+    for (let i = 0; i < count; i++) {
1380       st += "0";
1381     }
1382     return "1" + st + (512 + n).toString(2);
1383   }
1384 
1385   // Convert decimal number to binary
1386-  var result = parseInt(n.toString(), 10).toString(2);
1387+  let result = parseInt(n.toString(), 10).toString(2);
1388 
1389   // Pad return value with leading 0s (zeros) if necessary
1390   if (p >= result.length) {
1391-    var str = "";
1392-    for (var i = 0; i < (p - result.length); i++) {
1393+    let str = "";
1394+    for (let i = 0; i < (p - result.length); i++) {
1395       str += "0";
1396     }
1397-    var workingString = str + result;
1398+    let workingString = str + result;
1399     if (!placesPresent) {
1400-      var returnString = "";
1401-      for (var i = 0; i < workingString.length; i++) {
1402-        var char = workingString[i];
1403+      let returnString = "";
1404+      for (let i = 0; i < workingString.length; i++) {
1405+        let char = workingString[i];
1406         if (char === "1") {
1407           break;
1408         }
1409@@ -298,7 +298,7 @@ var DEC2BIN = function (decimalDumber, significantDigits?) : string {
1410  * @returns {number} 1 if they're equal, 0 if they're not equal.
1411  * @constructor
1412  */
1413-var DELTA = function (one, two?) : number {
1414+let DELTA = function (one, two?) : number {
1415   ArgsChecker.checkLengthWithin(arguments, 1, 2, "DELTA");
1416   if (two === undefined) {
1417     return TypeConverter.valueToNumber(one) === 0 ? 1 : 0;
1418diff --git a/src/Formulas/Financial.ts b/src/Formulas/Financial.ts
1419index 9f826c3..04f613c 100644
1420--- a/src/Formulas/Financial.ts
1421+++ b/src/Formulas/Financial.ts
1422@@ -25,7 +25,7 @@ import {Filter} from "../Utilities/Filter";
1423  * @returns {number} depreciation of an asset for a specified period
1424  * @constructor
1425  */
1426-var DDB = function (cost, salvage, life, period, factor?) : number {
1427+let DDB = function (cost, salvage, life, period, factor?) : number {
1428   ArgsChecker.checkLengthWithin(arguments, 4, 5, "DDB");
1429   cost = TypeConverter.firstValueAsNumber(cost);
1430   salvage = TypeConverter.firstValueAsNumber(salvage);
1431@@ -57,9 +57,9 @@ var DDB = function (cost, salvage, life, period, factor?) : number {
1432     return 0;
1433   }
1434 
1435-  var total = 0;
1436-  var current = 0;
1437-  for (var i = 1; i <= period; i++) {
1438+  let total = 0;
1439+  let current = 0;
1440+  for (let i = 1; i <= period; i++) {
1441     current = Math.min((cost - total) * (factor / checkForDevideByZero(life)), (cost - salvage - total));
1442     total += current;
1443   }
1444@@ -77,7 +77,7 @@ var DDB = function (cost, salvage, life, period, factor?) : number {
1445  * @returns {number} depreciated value
1446  * @constructor
1447  */
1448-var DB = function (cost, salvage, life, period, month) : number {
1449+let DB = function (cost, salvage, life, period, month) : number {
1450   ArgsChecker.checkLengthWithin(arguments, 4, 5, "DB");
1451   cost = TypeConverter.firstValueAsNumber(cost);
1452   salvage = TypeConverter.firstValueAsNumber(salvage);
1453@@ -114,12 +114,12 @@ var DB = function (cost, salvage, life, period, month) : number {
1454   if (cost === 0 && salvage !== 0) {
1455     throw new DivZeroError("Evaluation of function DB cause a divide by zero error.")
1456   }
1457-  var rate = (1 - Math.pow(salvage / cost, 1 / life));
1458-  var initial = cost * rate * month / 12;
1459-  var total = initial;
1460-  var current = 0;
1461-  var ceiling = (period === life) ? life - 1 : period;
1462-  for (var i = 2; i <= ceiling; i++) {
1463+  let rate = (1 - Math.pow(salvage / cost, 1 / life));
1464+  let initial = cost * rate * month / 12;
1465+  let total = initial;
1466+  let current = 0;
1467+  let ceiling = (period === life) ? life - 1 : period;
1468+  for (let i = 2; i <= ceiling; i++) {
1469     current = (cost - total) * rate;
1470     total += current;
1471   }
1472@@ -140,13 +140,13 @@ var DB = function (cost, salvage, life, period, month) : number {
1473  * @returns {number} dollars
1474  * @constructor
1475  */
1476-var DOLLAR = function (number, places?) : number {
1477+let DOLLAR = function (number, places?) : number {
1478   ArgsChecker.checkLengthWithin(arguments, 1, 2, "DOLLAR");
1479-  var v = TypeConverter.firstValueAsNumber(number);
1480+  let v = TypeConverter.firstValueAsNumber(number);
1481   places = places !== undefined ? TypeConverter.firstValueAsNumber(places) : 2;
1482-  var sign = (v > 0) ? 1 : -1;
1483-  var divisor = sign * (Math.floor(Math.abs(v) * Math.pow(10, places)));
1484-  var pow = Math.pow(10, places);
1485+  let sign = (v > 0) ? 1 : -1;
1486+  let divisor = sign * (Math.floor(Math.abs(v) * Math.pow(10, places)));
1487+  let pow = Math.pow(10, places);
1488   if (pow === 0 && divisor !== 0) {
1489     throw new DivZeroError("Evaluation of function DOLLAR cause a divide by zero error.")
1490   }
1491@@ -161,16 +161,16 @@ var DOLLAR = function (number, places?) : number {
1492  * @returns {number} decimal value.
1493  * @constructor
1494  */
1495-var DOLLARDE = function (fractionalPrice, unit) : number {
1496+let DOLLARDE = function (fractionalPrice, unit) : number {
1497   ArgsChecker.checkLength(arguments, 2, "DOLLARDE");
1498-  var dollar = TypeConverter.firstValueAsNumber(fractionalPrice);
1499-  var fraction = Math.floor(TypeConverter.firstValueAsNumber(unit));
1500+  let dollar = TypeConverter.firstValueAsNumber(fractionalPrice);
1501+  let fraction = Math.floor(TypeConverter.firstValueAsNumber(unit));
1502   if (fraction === 0) {
1503     throw new DivZeroError("Function DOLLARDE parameter 2 cannot be zero.");
1504   }
1505-  var result = parseInt(dollar.toString(), 10);
1506+  let result = parseInt(dollar.toString(), 10);
1507   result += (dollar % 1) * Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN10)) / fraction;
1508-  var power = Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN2) + 1);
1509+  let power = Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN2) + 1);
1510   if (power === 0) {
1511     throw new DivZeroError("Evaluation of function DOLLARDE cause a divide by zero error.")
1512   }
1513@@ -186,14 +186,14 @@ var DOLLARDE = function (fractionalPrice, unit) : number {
1514  * @returns {number} price quotation as decimal fraction.
1515  * @constructor
1516  */
1517-var DOLLARFR = function (decimalPrice, unit) : number {
1518+let DOLLARFR = function (decimalPrice, unit) : number {
1519   ArgsChecker.checkLength(arguments, 2, "DOLLARFR");
1520   decimalPrice = TypeConverter.firstValueAsNumber(decimalPrice);
1521   unit = Math.floor(TypeConverter.firstValueAsNumber(unit));
1522   if (unit === 0) {
1523     throw new DivZeroError("Function DOLLARFR parameter 2 cannot be zero.");
1524   }
1525-  var result = parseInt(decimalPrice.toString(), 10);
1526+  let result = parseInt(decimalPrice.toString(), 10);
1527   result += (decimalPrice % 1) * Math.pow(10, -Math.ceil(Math.log(unit) / Math.LN10)) * unit;
1528   return result;
1529 };
1530@@ -206,10 +206,10 @@ var DOLLARFR = function (decimalPrice, unit) : number {
1531  * @returns {number} annual effective interest rate
1532  * @constructor
1533  */
1534-var EFFECT = function (nominalRate, periodsPerYear) : number {
1535+let EFFECT = function (nominalRate, periodsPerYear) : number {
1536   ArgsChecker.checkLength(arguments, 2, "EFFECT");
1537-  var rate = TypeConverter.firstValueAsNumber(nominalRate);
1538-  var periods = TypeConverter.firstValueAsNumber(periodsPerYear);
1539+  let rate = TypeConverter.firstValueAsNumber(nominalRate);
1540+  let periods = TypeConverter.firstValueAsNumber(periodsPerYear);
1541   if (rate <= 0) {
1542     throw new NumError("Function EFFECT parameter 1 value is " + rate + ". It should be greater than to 0");
1543   }
1544@@ -233,18 +233,18 @@ var EFFECT = function (nominalRate, periodsPerYear) : number {
1545  * @returns {number}
1546  * @constructor
1547  */
1548-var PMT = function (rate, periods, presentValue, futureValue?, endOrBeginning?) : number {
1549+let PMT = function (rate, periods, presentValue, futureValue?, endOrBeginning?) : number {
1550   ArgsChecker.checkLengthWithin(arguments, 3, 5, "PMT");
1551   rate = TypeConverter.firstValueAsNumber(rate);
1552   periods = TypeConverter.firstValueAsNumber(periods);
1553   presentValue = TypeConverter.firstValueAsNumber(presentValue);
1554   futureValue = futureValue ? TypeConverter.firstValueAsNumber(futureValue) : 0;
1555   endOrBeginning = endOrBeginning ? TypeConverter.firstValueAsNumber(endOrBeginning) : 0;
1556-  var result;
1557+  let result;
1558   if (rate === 0) {
1559     result = (presentValue + futureValue) / periods;
1560   } else {
1561-    var term = Math.pow(1 + rate, periods);
1562+    let term = Math.pow(1 + rate, periods);
1563     if (endOrBeginning) {
1564       result = (futureValue * rate / (term - 1) + presentValue * rate / (1 - 1 / term)) / (1 + rate);
1565     } else {
1566@@ -265,18 +265,18 @@ var PMT = function (rate, periods, presentValue, futureValue?, endOrBeginning?)
1567  * @returns {number}
1568  * @constructor
1569  */
1570-var FV = function (rate, periods, payment, value?, type?) {
1571+let FV = function (rate, periods, payment, value?, type?) {
1572   ArgsChecker.checkLengthWithin(arguments, 3, 5, "FV");
1573   rate = TypeConverter.firstValueAsNumber(rate);
1574   periods = TypeConverter.firstValueAsNumber(periods);
1575   payment = TypeConverter.firstValueAsNumber(payment);
1576   value = (typeof value === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(value);
1577   type = (typeof type === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(type);
1578-  var result;
1579+  let result;
1580   if (rate === 0) {
1581     result = value + payment * periods;
1582   } else {
1583-    var term = Math.pow(1 + rate, periods);
1584+    let term = Math.pow(1 + rate, periods);
1585     if (type === 0) {
1586       result = value * term + payment * (term - 1) / rate;
1587     } else {
1588@@ -300,26 +300,26 @@ var FV = function (rate, periods, payment, value?, type?) {
1589  * @returns {number} cumulative principal
1590  * @constructor
1591  */
1592-var CUMPRINC = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPeriod, endOrBeginning) : number {
1593+let CUMPRINC = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPeriod, endOrBeginning) : number {
1594   ArgsChecker.checkLength(arguments, 6, "CUMPRINC");
1595   rate = TypeConverter.firstValueAsNumber(rate);
1596-  var periods = TypeConverter.firstValueAsNumber(numberOfPeriods);
1597-  var value = TypeConverter.firstValueAsNumber(presentValue);
1598-  var start = TypeConverter.firstValueAsNumber(firstPeriod);
1599+  let periods = TypeConverter.firstValueAsNumber(numberOfPeriods);
1600+  let value = TypeConverter.firstValueAsNumber(presentValue);
1601+  let start = TypeConverter.firstValueAsNumber(firstPeriod);
1602   if (start < 1) {
1603     throw new NumError("Function CUMPRINC parameter 4 value is " + start + ". It should be greater than or equal to 1.");
1604   }
1605-  var end = TypeConverter.firstValueAsNumber(lastPeriod);
1606+  let end = TypeConverter.firstValueAsNumber(lastPeriod);
1607   if (end < 1) {
1608     throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to 1.");
1609   }
1610   if (end < start) {
1611     throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to " + start + ".");
1612   }
1613-  var type = TypeConverter.firstValueAsBoolean(endOrBeginning);
1614+  let type = TypeConverter.firstValueAsBoolean(endOrBeginning);
1615 
1616-  var payment = PMT(rate, periods, value, 0, type);
1617-  var principal = 0;
1618+  let payment = PMT(rate, periods, value, 0, type);
1619+  let principal = 0;
1620   if (start === 1) {
1621     if (type) {
1622       principal = payment;
1623@@ -328,7 +328,7 @@ var CUMPRINC = function (rate, numberOfPeriods, presentValue, firstPeriod, lastP
1624     }
1625     start++;
1626   }
1627-  for (var i = start; i <= end; i++) {
1628+  for (let i = start; i <= end; i++) {
1629     if (type) {
1630       principal += payment - (FV(rate, i - 2, payment, value, 1) - payment) * rate;
1631     } else {
1632@@ -352,26 +352,26 @@ var CUMPRINC = function (rate, numberOfPeriods, presentValue, firstPeriod, lastP
1633  * @returns {number} cumulative interest
1634  * @constructor
1635  */
1636-var CUMIPMT = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPeriod, endOrBeginning) : number {
1637+let CUMIPMT = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPeriod, endOrBeginning) : number {
1638   ArgsChecker.checkLength(arguments, 6, "CUMIPMT");
1639   rate = TypeConverter.firstValueAsNumber(rate);
1640-  var periods = TypeConverter.firstValueAsNumber(numberOfPeriods);
1641-  var value = TypeConverter.firstValueAsNumber(presentValue);
1642-  var start = TypeConverter.firstValueAsNumber(firstPeriod);
1643+  let periods = TypeConverter.firstValueAsNumber(numberOfPeriods);
1644+  let value = TypeConverter.firstValueAsNumber(presentValue);
1645+  let start = TypeConverter.firstValueAsNumber(firstPeriod);
1646   if (start < 1) {
1647     throw new NumError("Function CUMPRINC parameter 4 value is " + start + ". It should be greater than or equal to 1.");
1648   }
1649-  var end = TypeConverter.firstValueAsNumber(lastPeriod);
1650+  let end = TypeConverter.firstValueAsNumber(lastPeriod);
1651   if (end < 1) {
1652     throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to 1.");
1653   }
1654   if (end < start) {
1655     throw new NumError("Function CUMPRINC parameter 5 value is " + end + ". It should be greater than or equal to " + start + ".");
1656   }
1657-  var type = TypeConverter.firstValueAsBoolean(endOrBeginning);
1658+  let type = TypeConverter.firstValueAsBoolean(endOrBeginning);
1659 
1660-  var payment = PMT(rate, periods, value, 0, type);
1661-  var interest = 0;
1662+  let payment = PMT(rate, periods, value, 0, type);
1663+  let interest = 0;
1664   if (start === 1) {
1665     if (!type) {
1666       interest = -value;
1667@@ -380,7 +380,7 @@ var CUMIPMT = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPe
1668       start++;
1669     }
1670   }
1671-  for (var i = start; i <= end; i++) {
1672+  for (let i = start; i <= end; i++) {
1673     if (type) {
1674       interest += FV(rate, i - 2, payment, value, 1) - payment;
1675     } else {
1676@@ -411,7 +411,7 @@ var CUMIPMT = function (rate, numberOfPeriods, presentValue, firstPeriod, lastPe
1677  * TODO: This function is based off of the open-source versions I was able to dig up online. We should implement a
1678  * TODO:     second version that is closer to what MSExcel does and is named something like `ACCRINT.MS`.
1679  */
1680-var ACCRINT = function (issue, firstPayment, settlement, rate, redemption, frequency, dayCountConvention?) {
1681+let ACCRINT = function (issue, firstPayment, settlement, rate, redemption, frequency, dayCountConvention?) {
1682   ArgsChecker.checkLengthWithin(arguments, 6, 7, "ACCRINT");
1683   issue = TypeConverter.firstValueAsDateNumber(issue);
1684   // "firstPayment" param is only here to check for errors for GS implementation.
1685@@ -437,7 +437,7 @@ var ACCRINT = function (issue, firstPayment, settlement, rate, redemption, frequ
1686   frequency = TypeConverter.firstValueAsNumber(frequency);
1687   // dayCountConvention, aka "basis"
1688   dayCountConvention = dayCountConvention !== undefined ? TypeConverter.firstValueAsNumber(dayCountConvention) : 1;
1689-  var factor = YEARFRAC(issue, settlement, dayCountConvention);
1690+  let factor = YEARFRAC(issue, settlement, dayCountConvention);
1691   return redemption * rate * factor;
1692 };
1693 
1694@@ -453,7 +453,7 @@ var ACCRINT = function (issue, firstPayment, settlement, rate, redemption, frequ
1695  * @returns {number}
1696  * @constructor
1697  */
1698-var SYD = function (cost, salvage, life, period) {
1699+let SYD = function (cost, salvage, life, period) {
1700   ArgsChecker.checkLength(arguments, 4, "SYD");
1701   cost = TypeConverter.firstValueAsNumber(cost);
1702   salvage = TypeConverter.firstValueAsNumber(salvage);
1703@@ -482,7 +482,7 @@ var SYD = function (cost, salvage, life, period) {
1704  * @returns {number}
1705  * @constructor
1706  */
1707-var SLN = function (cost, salvage, life) {
1708+let SLN = function (cost, salvage, life) {
1709   ArgsChecker.checkLength(arguments, 3, "SYD");
1710   cost = TypeConverter.firstValueAsNumber(cost);
1711   salvage = TypeConverter.firstValueAsNumber(salvage);
1712@@ -502,9 +502,9 @@ var SLN = function (cost, salvage, life) {
1713  * @constructor
1714  * TODO: This function can return results that are prone to floating point precision errors.
1715  */
1716-var NPV = function (rate, ...values) {
1717+let NPV = function (rate, ...values) {
1718   ArgsChecker.checkAtLeastLength(arguments, 2, "NPV");
1719-  var range = Filter.flattenAndThrow(values).map(function (value) {
1720+  let range = Filter.flattenAndThrow(values).map(function (value) {
1721     try {
1722       return TypeConverter.valueToNumber(value);
1723     } catch (e) {
1724@@ -512,8 +512,8 @@ var NPV = function (rate, ...values) {
1725           + " and cannot be coerced to a number.")
1726     }
1727   });
1728-  var value = 0;
1729-  for (var i = 0; i < range.length; i++) {
1730+  let value = 0;
1731+  for (let i = 0; i < range.length; i++) {
1732     value += range[i] / Math.pow(1 + rate, i);
1733   }
1734   return value;
1735@@ -531,20 +531,20 @@ var NPV = function (rate, ...values) {
1736  * @returns {number}
1737  * @constructor
1738  */
1739-var NPER = function (rate, payment, present, future?, type?) {
1740+let NPER = function (rate, payment, present, future?, type?) {
1741   ArgsChecker.checkLengthWithin(arguments, 3, 5, "NPER");
1742   rate = TypeConverter.firstValueAsNumber(rate);
1743   payment = TypeConverter.firstValueAsNumber(payment);
1744   present = TypeConverter.firstValueAsNumber(present);
1745   type = (typeof type === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(type);
1746   future = (typeof future === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(future);
1747-  var num = payment * (1 + rate * type) - future * rate;
1748-  var den = (present * rate + payment * (1 + rate * type));
1749+  let num = payment * (1 + rate * type) - future * rate;
1750+  let den = (present * rate + payment * (1 + rate * type));
1751   if (den === 0) {
1752     throw new DivZeroError("Evaluation of function NPER cause a divide by zero error.");
1753   }
1754-  var div = Math.log(1 + rate);
1755-  var logNumDen = Math.log(num / den);
1756+  let div = Math.log(1 + rate);
1757+  let logNumDen = Math.log(num / den);
1758   if (isNaN(logNumDen)) {
1759     throw new NumError("Parameters given function NPER are not possible.");
1760   }
1761@@ -558,7 +558,7 @@ var NPER = function (rate, payment, present, future?, type?) {
1762  * @returns {number}
1763  * @constructor
1764  */
1765-var NOMINAL =  function (rate, periods) {
1766+let NOMINAL =  function (rate, periods) {
1767   ArgsChecker.checkLength(arguments, 2, "NOMINAL");
1768   rate = TypeConverter.firstValueAsNumber(rate);
1769   periods = Math.round(TypeConverter.firstValueAsNumber(periods));
1770@@ -579,18 +579,18 @@ var NOMINAL =  function (rate, periods) {
1771  * @constructor
1772  * TODO: This relies on NPV and will therefore be prone to floating-point errors.
1773  */
1774-var MIRR = function (values, financeRate, reinvestRate) {
1775+let MIRR = function (values, financeRate, reinvestRate) {
1776   ArgsChecker.checkLength(arguments, 3, "MIRR");
1777   values = Filter.flattenAndThrow(values).filter(function (value) {
1778     return (typeof value !== "string");
1779   }).map(function (value) {
1780     return TypeConverter.valueToNumber(value);
1781   });
1782-  var n = values.length;
1783+  let n = values.length;
1784 
1785-  var payments = [];
1786-  var incomes = [];
1787-  for (var i = 0; i < n; i++) {
1788+  let payments = [];
1789+  let incomes = [];
1790+  for (let i = 0; i < n; i++) {
1791     if (values[i] < 0) {
1792       payments.push(values[i]);
1793     } else {
1794@@ -601,8 +601,8 @@ var MIRR = function (values, financeRate, reinvestRate) {
1795     throw new DivZeroError("For MIRR, the values must include positive and negative numbers.");
1796   }
1797 
1798-  var num = -NPV(reinvestRate, incomes) * Math.pow(1 + reinvestRate, n - 1);
1799-  var den = NPV(financeRate, payments) * (1 + financeRate);
1800+  let num = -NPV(reinvestRate, incomes) * Math.pow(1 + reinvestRate, n - 1);
1801+  let den = NPV(financeRate, payments) * (1 + financeRate);
1802   return Math.pow(num / den, 1 / (n - 1)) - 1;
1803 };
1804 
1805@@ -618,7 +618,7 @@ var MIRR = function (values, financeRate, reinvestRate) {
1806  * @returns {number}
1807  * @constructor
1808  */
1809-var IRR =  function (values, guess?) {
1810+let IRR =  function (values, guess?) {
1811   ArgsChecker.checkLengthWithin(arguments, 1, 2, "IRR");
1812   values = Filter.flattenAndThrow(values).filter(function (value) {
1813     return (typeof value !== "string");
1814@@ -626,15 +626,15 @@ var IRR =  function (values, guess?) {
1815     return TypeConverter.valueToNumber(value);
1816   });
1817   guess = (guess === undefined) ? 0.1 : TypeConverter.firstValueAsNumber(guess);
1818-  var min = -1.0;
1819-  var max = 10.0;
1820-  var val;
1821-  var counter = 1;
1822+  let min = -1.0;
1823+  let max = 10.0;
1824+  let val;
1825+  let counter = 1;
1826   const MAX_ITERATIONS = 500000;
1827   do {
1828     guess = (min + max) / 2;
1829     val = 0;
1830-    for (var j = 0; j < values.length; j++) {
1831+    for (let j = 0; j < values.length; j++) {
1832       val += values[j] / Math.pow((1 + guess), j);
1833     }
1834     if (val > 0) {
1835@@ -659,7 +659,7 @@ var IRR =  function (values, guess?) {
1836  * @returns {number}
1837  * @constructor
1838  */
1839-var IPMT = function (rate, period, periods, present, future?, type?) {
1840+let IPMT = function (rate, period, periods, present, future?, type?) {
1841   ArgsChecker.checkLengthWithin(arguments, 4, 6, "IPMT");
1842   rate = TypeConverter.firstValueAsNumber(rate);
1843   period = TypeConverter.firstValueAsNumber(period);
1844@@ -667,8 +667,8 @@ var IPMT = function (rate, period, periods, present, future?, type?) {
1845   present = TypeConverter.firstValueAsNumber(present);
1846   future = (typeof future === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(future);
1847   type = (typeof type === 'undefined') ? 0 : TypeConverter.firstValueAsNumber(type);
1848-  var payment = PMT(rate, periods, present, future, type);
1849-  var interest;
1850+  let payment = PMT(rate, periods, present, future, type);
1851+  let interest;
1852   if (period === 1) {
1853     if (type === 1) {
1854       interest = 0;
1855@@ -699,7 +699,7 @@ var IPMT = function (rate, period, periods, present, future?, type?) {
1856  * @returns {number}
1857  * @constructor
1858  */
1859-var PPMT = function (rate, period, periods, present, future?, type?) {
1860+let PPMT = function (rate, period, periods, present, future?, type?) {
1861   ArgsChecker.checkLengthWithin(arguments, 4, 6, "PPMT");
1862   rate = TypeConverter.firstValueAsNumber(rate);
1863   period = TypeConverter.firstValueAsNumber(period);
1864diff --git a/src/Formulas/Info.ts b/src/Formulas/Info.ts
1865index 6831656..582549d 100644
1866--- a/src/Formulas/Info.ts
1867+++ b/src/Formulas/Info.ts
1868@@ -18,7 +18,7 @@ import {Filter} from "../Utilities/Filter";
1869  * Returns the "value not available" error, "#N/A".
1870  * @constructor
1871  */
1872-var NA = function () {
1873+let NA = function () {
1874   ArgsChecker.checkLength(arguments, 1, "NA");
1875   throw new NAError("NA Error thrown.");
1876 };
1877@@ -30,7 +30,7 @@ var NA = function () {
1878  * @returns {boolean}.
1879  * @constructor
1880  */
1881-var ISTEXT =  function (value) {
1882+let ISTEXT =  function (value) {
1883   ArgsChecker.checkLength(arguments, 1, "ISTEXT");
1884   return typeof TypeConverter.firstValue(value) === "string";
1885 };
1886@@ -42,7 +42,7 @@ var ISTEXT =  function (value) {
1887  * @returns {boolean}.
1888  * @constructor
1889  */
1890-var ISNONTEXT = function (value) {
1891+let ISNONTEXT = function (value) {
1892   ArgsChecker.checkLength(arguments, 1, "ISNONTEXT");
1893   return typeof TypeConverter.firstValue(value) !== "string";
1894 };
1895@@ -54,7 +54,7 @@ var ISNONTEXT = function (value) {
1896  * @returns {boolean}
1897  * @constructor
1898  */
1899-var ISLOGICAL = function (value) {
1900+let ISLOGICAL = function (value) {
1901   ArgsChecker.checkLength(arguments, 1, "ISLOGICAL");
1902   return typeof TypeConverter.firstValue(value) === "boolean";
1903 };
1904@@ -66,7 +66,7 @@ var ISLOGICAL = function (value) {
1905  * @returns {boolean}
1906  * @constructor
1907  */
1908-var ISNUMBER = function (value) {
1909+let ISNUMBER = function (value) {
1910   ArgsChecker.checkLength(arguments, 1, "ISNUMBER");
1911   return typeof TypeConverter.firstValue(value) === "number";
1912 };
1913@@ -79,7 +79,7 @@ var ISNUMBER = function (value) {
1914  * @returns {boolean}
1915  * @constructor
1916  */
1917-var ISEMAIL = function (value) {
1918+let ISEMAIL = function (value) {
1919   ArgsChecker.checkLength(arguments, 1, "ISEMAIL");
1920   if (typeof value !== "string") {
1921     return false;
1922@@ -95,10 +95,10 @@ var ISEMAIL = function (value) {
1923  * @returns {boolean}
1924  * @constructor
1925  */
1926-var ISURL = function (value) {
1927+let ISURL = function (value) {
1928   ArgsChecker.checkLength(arguments, 1, "ISURL");
1929   value = TypeConverter.firstValueAsString(value);
1930-  var matches = value.match(/(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);
1931+  let matches = value.match(/(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);
1932   if (/[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i.test(value)) {
1933     return false;
1934   }
1935@@ -108,8 +108,8 @@ var ISURL = function (value) {
1936   if (/%[0-9a-f](:?[^0-9a-f]|$)/i.test(value)) {
1937     return false;
1938   }
1939-  var authority = matches[2];
1940-  var path = matches[3];
1941+  let authority = matches[2];
1942+  let path = matches[3];
1943   if (!(path.length >= 0)) {
1944     return false;
1945   }
1946@@ -131,7 +131,7 @@ var ISURL = function (value) {
1947  * @returns {number}
1948  * @constructor
1949  */
1950-var N = function (value) {
1951+let N = function (value) {
1952   ArgsChecker.checkLength(arguments, 1, "N");
1953   return TypeConverter.firstValueAsNumber(value);
1954 };
1955@@ -144,7 +144,7 @@ var N = function (value) {
1956  * @returns {boolean}
1957  * @constructor
1958  */
1959-var ISREF = function (value) {
1960+let ISREF = function (value) {
1961   ArgsChecker.checkLength(arguments, 1, "ISREF");
1962   return TypeConverter.firstValue(value) instanceof Cell;
1963 };
1964@@ -160,7 +160,7 @@ var ISREF = function (value) {
1965  * Parser/Sheet. Otherwise the errors thrown by nested formulas break through. Eg: `=ERRORTYPE(NA())`, NA bubbles up.
1966  * Once this is done, we should test it inside SheetFormulaTest.ts
1967  */
1968-var ERRORTYPE = function (value) {
1969+let ERRORTYPE = function (value) {
1970   ArgsChecker.checkLength(arguments, 1, "ERRORTYPE");
1971   value = TypeConverter.firstValue(value);
1972   if (value instanceof Cell) {
1973@@ -203,7 +203,7 @@ var ERRORTYPE = function (value) {
1974  * @returns {boolean}
1975  * @constructor
1976  */
1977-var ISBLANK = function (value) {
1978+let ISBLANK = function (value) {
1979   ArgsChecker.checkLength(arguments, 1, "ISBLANK");
1980   if (value instanceof Cell) {
1981     return value.isBlank();
1982@@ -221,7 +221,7 @@ var ISBLANK = function (value) {
1983  * @constructor
1984  * TODO: This formula needs to be called from inside a try-catch-block in the Sheet/Parser, like ERROR.TYPE.
1985  */
1986-var ISERR = function (value) {
1987+let ISERR = function (value) {
1988   ArgsChecker.checkLength(arguments, 1, "ISERR");
1989   if (value instanceof Cell) {
1990     if (value.hasError()) {
1991@@ -243,7 +243,7 @@ var ISERR = function (value) {
1992  * @constructor
1993  * TODO: This formula needs to be called from inside a try-catch-block in the Sheet/Parser, like ERROR.TYPE.
1994  */
1995-var ISERROR = function (value) {
1996+let ISERROR = function (value) {
1997   ArgsChecker.checkLength(arguments, 1, "ISERROR");
1998   try {
1999     value = TypeConverter.firstValue(value);
2000@@ -265,7 +265,7 @@ var ISERROR = function (value) {
2001  * @constructor
2002  * TODO: This formula needs to be called from inside a try-catch-block in the Sheet/Parser, like ERROR.TYPE.
2003  */
2004-var ISNA = function (value) {
2005+let ISNA = function (value) {
2006   ArgsChecker.checkLength(arguments, 1, "ISNA");
2007   try {
2008     value = TypeConverter.firstValue(value);
2009@@ -293,7 +293,7 @@ var ISNA = function (value) {
2010  * @constructor
2011  * TODO: This formula needs to be called from inside a try-catch-block in the Sheet/Parser, like ERROR.TYPE.
2012  */
2013-var IFERROR = function (value, valueIfError?) {
2014+let IFERROR = function (value, valueIfError?) {
2015   ArgsChecker.checkLengthWithin(arguments, 1, 2, "IFERROR");
2016   if (value instanceof Cell && valueIfError === undefined) {
2017     return ISERROR(value) ? new Cell(value.getId()) : value;
2018@@ -309,7 +309,7 @@ var IFERROR = function (value, valueIfError?) {
2019  * @returns {number}
2020  * @constructor
2021  */
2022-var TYPE = function (value) {
2023+let TYPE = function (value) {
2024   ArgsChecker.checkLengthWithin(arguments, 1, 2, "TYPE");
2025   if (value instanceof Cell) {
2026     if (value.hasError()) {
2027@@ -344,7 +344,7 @@ var TYPE = function (value) {
2028  * @param cell - Cell, defaults to the cell calling this formula, when used in the context of a spreadsheet.
2029  * @constructor
2030  */
2031-var COLUMN =  function (cell) {
2032+let COLUMN =  function (cell) {
2033   ArgsChecker.checkLength(arguments, 1, "COLUMN");
2034   if (!(cell instanceof Cell)) {
2035     throw new NAError("Argument must be a range or reference.");
2036@@ -358,7 +358,7 @@ var COLUMN =  function (cell) {
2037  * @param cell - Cell, defaults to the cell calling this formula, when used in the context of a spreadsheet.
2038  * @constructor
2039  */
2040-var ROW =  function (cell) {
2041+let ROW =  function (cell) {
2042   ArgsChecker.checkLength(arguments, 1, "ROW");
2043   if (!(cell instanceof Cell)) {
2044     throw new NAError("Argument must be a range or reference.");
2045diff --git a/src/Formulas/Logical.ts b/src/Formulas/Logical.ts
2046index 38aec2b..4ac715a 100644
2047--- a/src/Formulas/Logical.ts
2048+++ b/src/Formulas/Logical.ts
2049@@ -17,10 +17,10 @@ import {
2050  * @returns {boolean} if all values are logically true.
2051  * @constructor
2052  */
2053-var AND = function (...values) {
2054+let AND = function (...values) {
2055   ArgsChecker.checkAtLeastLength(values, 1, "AND");
2056-  var result = true;
2057-  for (var i = 0; i < values.length; i++) {
2058+  let result = true;
2059+  for (let i = 0; i < values.length; i++) {
2060     if (typeof values[i] === "string") {
2061       throw new ValueError("AND expects boolean values. But '" + values[i]
2062           + "' is a text and cannot be coerced to a boolean.")
2063@@ -44,7 +44,7 @@ var AND = function (...values) {
2064  * @returns {boolean}
2065  * @constructor
2066  */
2067-var EXACT = function (one, two) {
2068+let EXACT = function (one, two) {
2069   ArgsChecker.checkLength(arguments, 2, "EXACT");
2070   one = TypeConverter.firstValue(one);
2071   two = TypeConverter.firstValue(two);
2072@@ -56,7 +56,7 @@ var EXACT = function (one, two) {
2073  * @returns {boolean} true boolean
2074  * @constructor
2075  */
2076-var TRUE = function () : boolean {
2077+let TRUE = function () : boolean {
2078   ArgsChecker.checkLength(arguments, 0, "TRUE");
2079   return true;
2080 };
2081@@ -66,7 +66,7 @@ var TRUE = function () : boolean {
2082  * @returns {boolean} false boolean
2083  * @constructor
2084  */
2085-var FALSE = function () : boolean {
2086+let FALSE = function () : boolean {
2087   ArgsChecker.checkLength(arguments, 0, "FALSE");
2088   return false;
2089 };
2090@@ -77,7 +77,7 @@ var FALSE = function () : boolean {
2091  * @returns {boolean} opposite of a logical value input
2092  * @constructor
2093  */
2094-var NOT = function (value) : boolean {
2095+let NOT = function (value) : boolean {
2096   ArgsChecker.checkLength(arguments, 1, "NOT");
2097   if (typeof(value) === "boolean") {
2098     return !value;
2099@@ -108,9 +108,9 @@ var NOT = function (value) : boolean {
2100  * @returns {boolean}
2101  * @constructor
2102  */
2103-var OR = function (...values) {
2104+let OR = function (...values) {
2105   ArgsChecker.checkAtLeastLength(values, 1, "OR");
2106-  for (var i = 0; i < values.length; i++) {
2107+  for (let i = 0; i < values.length; i++) {
2108     if (values[i] instanceof Array) {
2109       if (values[i].length === 0) {
2110         throw new RefError("Reference does not exist.");
2111@@ -131,10 +131,10 @@ var OR = function (...values) {
2112  * @returns {boolean} returns true if only one input is considered logically true.
2113  * @constructor
2114  */
2115-var XOR = function (...values) {
2116+let XOR = function (...values) {
2117   ArgsChecker.checkAtLeastLength(values, 1, "XOR");
2118-  var alreadyTruthy = false;
2119-  for (var i = 0; i < values.length; i++) {
2120+  let alreadyTruthy = false;
2121+  for (let i = 0; i < values.length; i++) {
2122     if (values[i] instanceof Array) {
2123       if (values[i].length === 0) {
2124         throw new RefError("Reference does not exist.");
2125diff --git a/src/Formulas/Math.ts b/src/Formulas/Math.ts
2126index 6b77ebf..667e1ef 100644
2127--- a/src/Formulas/Math.ts
2128+++ b/src/Formulas/Math.ts
2129@@ -31,7 +31,7 @@ import {
2130  * @returns {number} greatest common divisor.
2131  * @constructor
2132  */
2133-var GCD = function (...values) {
2134+let GCD = function (...values) {
2135   ArgsChecker.checkAtLeastLength(arguments, 1, "ABS");
2136   // Credits: Andrew Pociu
2137   for (var r, a, i = values.length - 1, result = values[i]; i;) {
2138@@ -49,10 +49,10 @@ var GCD = function (...values) {
2139  * @returns {number}
2140  * @constructor
2141  */
2142-var LCM =  function (...values) {
2143+let LCM =  function (...values) {
2144   ArgsChecker.checkAtLeastLength(arguments, 1, "LCM");
2145   // Credits: Jonas Raoni Soares Silva
2146-  var o = Filter.flatten(values);
2147+  let o = Filter.flatten(values);
2148   for (var i, j, n, d, r = 1; (n = o.pop()) !== undefined;) {
2149     while (n > 1) {
2150       if (n % 2) {
2151@@ -73,9 +73,9 @@ var LCM =  function (...values) {
2152  * @returns {number}
2153  * @constructor
2154  */
2155-var GAMMALN = function (value) {
2156+let GAMMALN = function (value) {
2157   ArgsChecker.checkLength(arguments, 1, "GAMMALN");
2158-  var x =  TypeConverter.firstValueAsNumber(value);
2159+  let x =  TypeConverter.firstValueAsNumber(value);
2160   if (x <= 0) {
2161     throw new NumError("Function GAMMALN parameter 1 value is " + x + ". It should be greater than 0.");
2162   }
2163@@ -88,9 +88,9 @@ var GAMMALN = function (value) {
2164  * @returns {number} absolute value
2165  * @constructor
2166  */
2167-var ABS = function (value) {
2168+let ABS = function (value) {
2169   ArgsChecker.checkLength(arguments, 1, "ABS");
2170-  var v = TypeConverter.valueToNumber(value);
2171+  let v = TypeConverter.valueToNumber(value);
2172   return Math.abs(v);
2173 };
2174 
2175@@ -100,7 +100,7 @@ var ABS = function (value) {
2176  * @returns {number} inverse cosine of value
2177  * @constructor
2178  */
2179-var ACOS = function (value) {
2180+let ACOS = function (value) {
2181   ArgsChecker.checkLength(arguments, 1, "ACOS");
2182   value = TypeConverter.valueToNumber(value);
2183   if (value === -1) {
2184@@ -117,7 +117,7 @@ var ACOS = function (value) {
2185  * @returns {number} to find the inverse hyperbolic cosine for.
2186  * @constructor
2187  */
2188-var ACOSH = function (value) {
2189+let ACOSH = function (value) {
2190   ArgsChecker.checkLength(arguments, 1, "ACOSH");
2191   value = TypeConverter.valueToNumber(value);
2192   if (value < 1) {
2193@@ -132,7 +132,7 @@ var ACOSH = function (value) {
2194  * @returns {number} hyperbolic arc-cotangent
2195  * @constructor
2196  */
2197-var ACOTH = function (value) {
2198+let ACOTH = function (value) {
2199   ArgsChecker.checkLength(arguments, 1, "ACOTH");
2200   value = TypeConverter.valueToNumber(value);
2201   if (value <= 1 && value >= -1) {
2202@@ -147,7 +147,7 @@ var ACOTH = function (value) {
2203  * @returns {number} inverse sine of input value
2204  * @constructor
2205  */
2206-var ASIN = function (value) {
2207+let ASIN = function (value) {
2208   ArgsChecker.checkLength(arguments, 1, "ASIN");
2209   value = TypeConverter.valueToNumber(value);
2210   if (value === -1) {
2211@@ -164,7 +164,7 @@ var ASIN = function (value) {
2212  * @returns {number} inverse hyperbolic sine of input
2213  * @constructor
2214  */
2215-var ASINH = function (value) {
2216+let ASINH = function (value) {
2217   ArgsChecker.checkLength(arguments, 1, "ASINH");
2218   value = TypeConverter.valueToNumber(value);
2219   return Math.log(value + Math.sqrt(value * value + 1));
2220@@ -177,7 +177,7 @@ var ASINH = function (value) {
2221  * @returns {number} inverse tangent of input value
2222  * @constructor
2223  */
2224-var ATAN = function (value) {
2225+let ATAN = function (value) {
2226   ArgsChecker.checkLength(arguments, 1, "ATAN");
2227   value = TypeConverter.valueToNumber(value);
2228   if (value === -1) {
2229@@ -196,7 +196,7 @@ var ATAN = function (value) {
2230  * @returns {number} angle in radians
2231  * @constructor
2232  */
2233-var ATAN2 = function (x, y) {
2234+let ATAN2 = function (x, y) {
2235   ArgsChecker.checkLength(arguments, 2, "ATAN2");
2236   x = TypeConverter.valueToNumber(x);
2237   y = TypeConverter.valueToNumber(y);
2238@@ -213,7 +213,7 @@ var ATAN2 = function (x, y) {
2239  * @returns {number} inverse hyperbolic tangent of input
2240  * @constructor
2241  */
2242-var ATANH = function (value) : number {
2243+let ATANH = function (value) : number {
2244   ArgsChecker.checkLength(arguments, 1, "ATANH");
2245   value = TypeConverter.valueToNumber(value);
2246   if (value >= 1 || value <= -1) {
2247@@ -231,9 +231,9 @@ var ATANH = function (value) : number {
2248  * @returns {number} next greatest even number
2249  * @constructor
2250  */
2251-var EVEN = function (value) : number {
2252+let EVEN = function (value) : number {
2253   ArgsChecker.checkLength(arguments, 1, "EVEN");
2254-  var X = TypeConverter.firstValueAsNumber(value);
2255+  let X = TypeConverter.firstValueAsNumber(value);
2256   return X % 2 === 1 ? X + 1 : X;
2257 };
2258 
2259@@ -244,10 +244,10 @@ var EVEN = function (value) : number {
2260  * @returns {number}
2261  * @constructor
2262  */
2263-var MOD = function (dividend, divisor) : number {
2264+let MOD = function (dividend, divisor) : number {
2265   ArgsChecker.checkLength(arguments, 2, "MOD");
2266-  var oneN = TypeConverter.valueToNumber(dividend);
2267-  var twoN =  TypeConverter.valueToNumber(divisor);
2268+  let oneN = TypeConverter.valueToNumber(dividend);
2269+  let twoN =  TypeConverter.valueToNumber(divisor);
2270   if (twoN === 0) {
2271     throw new DivZeroError("Function MOD parameter 2 cannot be zero.");
2272   }
2273@@ -261,9 +261,9 @@ var MOD = function (dividend, divisor) : number {
2274  * @returns {number} value to round up to next greatest odd number.
2275  * @constructor
2276  */
2277-var ODD = function (value) : number {
2278+let ODD = function (value) : number {
2279   ArgsChecker.checkLength(arguments, 1, "ODD");
2280-  var X = TypeConverter.firstValueAsNumber(value);
2281+  let X = TypeConverter.firstValueAsNumber(value);
2282   return X % 2 === 1 ? X : X + 1;
2283 };
2284 
2285@@ -274,10 +274,10 @@ var ODD = function (value) : number {
2286  * @returns {number} resulting number
2287  * @constructor
2288  */
2289-var POWER = function (base, exponent) : number {
2290+let POWER = function (base, exponent) : number {
2291   ArgsChecker.checkLength(arguments, 2, "POWER");
2292-  var n = TypeConverter.firstValueAsNumber(base);
2293-  var p = TypeConverter.firstValueAsNumber(exponent);
2294+  let n = TypeConverter.firstValueAsNumber(base);
2295+  let p = TypeConverter.firstValueAsNumber(exponent);
2296   return Math.pow(n, p);
2297 };
2298 
2299@@ -287,10 +287,10 @@ var POWER = function (base, exponent) : number {
2300  * @returns {number} The sum of the series
2301  * @constructor
2302  */
2303-var SUM = function (...values) : number {
2304+let SUM = function (...values) : number {
2305   ArgsChecker.checkAtLeastLength(values, 1, "SUM");
2306-  var result = 0;
2307-  for (var i = 0; i < values.length; i++) {
2308+  let result = 0;
2309+  for (let i = 0; i < values.length; i++) {
2310     if (values[i] instanceof Array) {
2311       result = result + SUM.apply(this, values[i]);
2312     } else {
2313@@ -309,9 +309,9 @@ var SUM = function (...values) : number {
2314  * @returns {number} square root
2315  * @constructor
2316  */
2317-var SQRT = function (value) : number {
2318+let SQRT = function (value) : number {
2319   ArgsChecker.checkLength(arguments, 1, "SQRT");
2320-  var x = TypeConverter.firstValueAsNumber(value);
2321+  let x = TypeConverter.firstValueAsNumber(value);
2322   if (x < 0) {
2323     throw new ValueError("Function SQRT parameter 1 value is " + x + ". It should be greater than or equal to 0.");
2324   }
2325@@ -324,9 +324,9 @@ var SQRT = function (value) : number {
2326  * @returns {number} the positive square root of the product of Pi and the given positive number.
2327  * @constructor
2328  */
2329-var SQRTPI = function (value) : number{
2330+let SQRTPI = function (value) : number{
2331   ArgsChecker.checkLength(arguments, 1, "SQRTPI");
2332-  var n = TypeConverter.firstValueAsNumber(value);
2333+  let n = TypeConverter.firstValueAsNumber(value);
2334   if (n < 0) {
2335     throw new NumError("Function SQRTPI parameter 1 value is " + n + ". It should be greater than or equal to 0.");
2336   }
2337@@ -339,9 +339,9 @@ var SQRTPI = function (value) : number{
2338  * @returns {number} cosine of angle
2339  * @constructor
2340  */
2341-var COS = function (value) : number {
2342+let COS = function (value) : number {
2343   ArgsChecker.checkLength(arguments, 1, "COS");
2344-  var r = TypeConverter.firstValueAsNumber(value);
2345+  let r = TypeConverter.firstValueAsNumber(value);
2346   return Math.cos(r);
2347 };
2348 
2349@@ -351,9 +351,9 @@ var COS = function (value) : number {
2350  * @returns {number} the hyperbolic cosine of the input
2351  * @constructor
2352  */
2353-var COSH = function (value) : number {
2354+let COSH = function (value) : number {
2355   ArgsChecker.checkLength(arguments, 1, "COSH");
2356-  var r = TypeConverter.firstValueAsNumber(value);
2357+  let r = TypeConverter.firstValueAsNumber(value);
2358   return Math["cosh"](r);
2359 };
2360 
2361@@ -363,9 +363,9 @@ var COSH = function (value) : number {
2362  * @returns {number} cotangent
2363  * @constructor
2364  */
2365-var COT = function (value) : number {
2366+let COT = function (value) : number {
2367   ArgsChecker.checkLength(arguments, 1, "COT");
2368-  var x = TypeConverter.firstValueAsNumber(value);
2369+  let x = TypeConverter.firstValueAsNumber(value);
2370   if (x === 0) {
2371     throw new DivZeroError("Evaluation of function COT caused a divide by zero error.");
2372   }
2373@@ -378,9 +378,9 @@ var COT = function (value) : number {
2374  * @returns {number} hyperbolic cotangent
2375  * @constructor
2376  */
2377-var COTH = function (value) : number {
2378+let COTH = function (value) : number {
2379   ArgsChecker.checkLength(arguments, 1, "COTH");
2380-  var x = TypeConverter.firstValueAsNumber(value);
2381+  let x = TypeConverter.firstValueAsNumber(value);
2382   if (x === 0) {
2383     throw new DivZeroError("Evaluation of function COTH caused a divide by zero error.");
2384   }
2385@@ -393,9 +393,9 @@ var COTH = function (value) : number {
2386  * @returns {number} Rounded number
2387  * @constructor
2388  */
2389-var INT = function (value) : number {
2390+let INT = function (value) : number {
2391   ArgsChecker.checkLength(arguments, 1, "INT");
2392-  var x = TypeConverter.firstValueAsNumber(value);
2393+  let x = TypeConverter.firstValueAsNumber(value);
2394   return Math.floor(x);
2395 };
2396 
2397@@ -406,12 +406,12 @@ var INT = function (value) : number {
2398  * @returns {boolean} whether this value is even or not
2399  * @constructor
2400  */
2401-var ISEVEN = function (value) : boolean {
2402+let ISEVEN = function (value) : boolean {
2403   ArgsChecker.checkLength(arguments, 1, "ISEVEN");
2404   if (value === "") {
2405     throw new ValueError("Function ISEVEN parameter 1 expects boolean values. But '" + value + "' is a text and cannot be coerced to a boolean.");
2406   }
2407-  var x = TypeConverter.firstValueAsNumber(value);
2408+  let x = TypeConverter.firstValueAsNumber(value);
2409   return Math.floor(x) % 2 === 0;
2410 };
2411 
2412@@ -422,12 +422,12 @@ var ISEVEN = function (value) : boolean {
2413  * @returns {boolean} whether this value is odd or not
2414  * @constructor
2415  */
2416-var ISODD = function (value) : boolean {
2417+let ISODD = function (value) : boolean {
2418   ArgsChecker.checkLength(arguments, 1, "ISODD");
2419   if (value === "") {
2420     throw new ValueError("Function ISODD parameter 1 expects boolean values. But '" + value + "' is a text and cannot be coerced to a boolean.");
2421   }
2422-  var x = TypeConverter.firstValueAsNumber(value);
2423+  let x = TypeConverter.firstValueAsNumber(value);
2424   return Math.floor(x) % 2 === 1;
2425 };
2426 
2427@@ -437,9 +437,9 @@ var ISODD = function (value) : boolean {
2428  * @returns {number} Sine of angle.
2429  * @constructor
2430  */
2431-var SIN = function (value) {
2432+let SIN = function (value) {
2433   ArgsChecker.checkLength(arguments, 1, "SIN");
2434-  var rad = TypeConverter.firstValueAsNumber(value);
2435+  let rad = TypeConverter.firstValueAsNumber(value);
2436   return rad === Math.PI ? 0 : Math.sin(rad);
2437 };
2438 
2439@@ -449,9 +449,9 @@ var SIN = function (value) {
2440  * @returns {number} hyperbolic sine
2441  * @constructor
2442  */
2443-var SINH = function (value) : number {
2444+let SINH = function (value) : number {
2445   ArgsChecker.checkLength(arguments, 1, "SINH");
2446-  var rad = TypeConverter.firstValueAsNumber(value);
2447+  let rad = TypeConverter.firstValueAsNumber(value);
2448   return Math["sinh"](rad);
2449 };
2450 
2451@@ -460,7 +460,7 @@ var SINH = function (value) : number {
2452  * @returns {number} Pi.
2453  * @constructor
2454  */
2455-var PI = function () {
2456+let PI = function () {
2457   ArgsChecker.checkLength(arguments, 0, "SINH");
2458   return Math.PI;
2459 };
2460@@ -471,14 +471,14 @@ var PI = function () {
2461  * @returns {number} logarithm of the number, in base 10.
2462  * @constructor
2463  */
2464-var LOG10 = function (value) : number {
2465+let LOG10 = function (value) : number {
2466   ArgsChecker.checkLength(arguments, 1, "LOG10");
2467-  var n = TypeConverter.firstValueAsNumber(value);
2468+  let n = TypeConverter.firstValueAsNumber(value);
2469   if (n < 1) {
2470     throw new NumError("Function LOG10 parameter 1 value is " + n + ". It should be greater than 0.");
2471   }
2472-  var ln = Math.log(n);
2473-  var lb = Math.log(10);
2474+  let ln = Math.log(n);
2475+  let lb = Math.log(10);
2476   return ln / lb;
2477 };
2478 
2479@@ -489,18 +489,18 @@ var LOG10 = function (value) : number {
2480  * @returns {number}
2481  * @constructor
2482  */
2483-var LOG = function (value, base) : number {
2484+let LOG = function (value, base) : number {
2485   ArgsChecker.checkAtLeastLength(arguments, 2, "LOG");
2486-  var n = TypeConverter.firstValueAsNumber(value);
2487-  var b = TypeConverter.firstValueAsNumber(base);
2488+  let n = TypeConverter.firstValueAsNumber(value);
2489+  let b = TypeConverter.firstValueAsNumber(base);
2490   if (b < 1) {
2491     throw new NumError("Function LOG parameter 2 value is " + b + ". It should be greater than 0.");
2492   }
2493   if (b < 2) {
2494     throw new DivZeroError("Evaluation of function LOG caused a divide by zero error.");
2495   }
2496-  var ln = Math.log(n);
2497-  var lb = Math.log(b);
2498+  let ln = Math.log(n);
2499+  let lb = Math.log(b);
2500   if (lb === 0) {
2501     throw new DivZeroError("Evaluation of function LOG caused a divide by zero error.");
2502   }
2503@@ -513,9 +513,9 @@ var LOG = function (value, base) : number {
2504  * @returns {number} logarithm calculated
2505  * @constructor
2506  */
2507-var LN = function (value) : number {
2508+let LN = function (value) : number {
2509   ArgsChecker.checkLength(arguments, 1, "LN");
2510-  var n = TypeConverter.firstValueAsNumber(value);
2511+  let n = TypeConverter.firstValueAsNumber(value);
2512   if (n < 1) {
2513     throw new NumError("Function LN parameter 1 value is " + n + ". It should be greater than 0.");
2514   }
2515@@ -528,9 +528,9 @@ var LN = function (value) : number {
2516  * @returns {number} tangent in radians
2517  * @constructor
2518  */
2519-var TAN = function (value) : number {
2520+let TAN = function (value) : number {
2521   ArgsChecker.checkLength(arguments, 1, "TAN");
2522-  var rad = TypeConverter.firstValueAsNumber(value);
2523+  let rad = TypeConverter.firstValueAsNumber(value);
2524   return rad === Math.PI ? 0 : Math.tan(rad);
2525 };
2526 
2527@@ -540,9 +540,9 @@ var TAN = function (value) : number {
2528  * @returns {number} hyperbolic tangent
2529  * @constructor
2530  */
2531-var TANH = function (value) : number {
2532+let TANH = function (value) : number {
2533   ArgsChecker.checkLength(arguments, 1, "TANH");
2534-  var rad = TypeConverter.firstValueAsNumber(value);
2535+  let rad = TypeConverter.firstValueAsNumber(value);
2536   return Math["tanh"](rad);
2537 };
2538 
2539@@ -553,17 +553,17 @@ var TANH = function (value) : number {
2540  * @returns {number}
2541  * @constructor
2542  */
2543-var CEILING = function (value, factor?) : number {
2544+let CEILING = function (value, factor?) : number {
2545   ArgsChecker.checkLengthWithin(arguments, 1, 2, "CEILING");
2546-  var num = TypeConverter.firstValueAsNumber(value);
2547+  let num = TypeConverter.firstValueAsNumber(value);
2548   if (factor === undefined) {
2549     return Math.ceil(num);
2550   }
2551-  var significance = TypeConverter.firstValueAsNumber(factor);
2552+  let significance = TypeConverter.firstValueAsNumber(factor);
2553   if (significance === 0) {
2554     throw new DivZeroError("Function CEILING parameter 2 cannot be zero.");
2555   }
2556-  var precision = -Math.floor(Math.log(significance) / Math.log(10));
2557+  let precision = -Math.floor(Math.log(significance) / Math.log(10));
2558   if (num >= 0) {
2559     return ROUND(Math.ceil(num / significance) * significance, precision);
2560   } else {
2561@@ -578,18 +578,18 @@ var CEILING = function (value, factor?) : number {
2562  * @returns {number}
2563  * @constructor
2564  */
2565-var FLOOR = function (value, factor?) : number {
2566+let FLOOR = function (value, factor?) : number {
2567   ArgsChecker.checkLengthWithin(arguments, 1, 2, "FLOOR");
2568-  var num = TypeConverter.firstValueAsNumber(value);
2569+  let num = TypeConverter.firstValueAsNumber(value);
2570   if (factor === undefined) {
2571     return Math.floor(num);
2572   }
2573-  var significance = TypeConverter.firstValueAsNumber(factor);
2574+  let significance = TypeConverter.firstValueAsNumber(factor);
2575   if (significance === 0) {
2576     throw new DivZeroError("Function FLOOR parameter 2 cannot be zero.");
2577   }
2578   significance = significance ? Math.abs(significance) : 1;
2579-  var precision = -Math.floor(Math.log(significance) / Math.log(10));
2580+  let precision = -Math.floor(Math.log(significance) / Math.log(10));
2581   if (num >= 0) {
2582     return ROUND(Math.floor(num / significance) * significance, precision);
2583   }
2584@@ -604,7 +604,7 @@ var FLOOR = function (value, factor?) : number {
2585  * @returns one value if a logical expression is TRUE and another if it is FALSE.
2586  * @constructor
2587  */
2588-var IF = function (logicalExpression, valueIfTrue, valueIfFalse) : any {
2589+let IF = function (logicalExpression, valueIfTrue, valueIfFalse) : any {
2590   ArgsChecker.checkLength(arguments, 3, "IF");
2591   if (logicalExpression instanceof Array) {
2592     if (logicalExpression.length === 0) {
2593@@ -628,16 +628,16 @@ var IF = function (logicalExpression, valueIfTrue, valueIfFalse) : any {
2594  * @returns {number}
2595  * @constructor
2596  */
2597-var COUNTIF = function (range, criteria) {
2598+let COUNTIF = function (range, criteria) {
2599   ArgsChecker.checkLength(arguments, 2, "COUNTIF");
2600   if (!(range instanceof Array)) {
2601     range = [range];
2602   }
2603-  var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criteria);
2604+  let criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criteria);
2605 
2606-  var count = 0;
2607-  for (var i = 0; i < range.length; i++) {
2608-    var x = range[i];
2609+  let count = 0;
2610+  for (let i = 0; i < range.length; i++) {
2611+    let x = range[i];
2612     if (x instanceof Array) {
2613       count = count + COUNTIF.apply(this, [x, criteria]);
2614     } else if (criteriaEvaluation(x)) {
2615@@ -655,18 +655,18 @@ var COUNTIF = function (range, criteria) {
2616  * @returns {number} count
2617  * @constructor
2618  */
2619-var COUNTIFS = function (...values) {
2620+let COUNTIFS = function (...values) {
2621   ArgsChecker.checkAtLeastLength(values, 2, "COUNTIFS");
2622-  var criteriaEvaluationFunctions = values.map(function (criteria, index) {
2623+  let criteriaEvaluationFunctions = values.map(function (criteria, index) {
2624     if (index % 2 === 1) {
2625       return CriteriaFunctionFactory.createCriteriaFunction(criteria);
2626     } else {
2627       return function () {return false;}
2628     }
2629   });
2630-  var filteredValues = [];
2631+  let filteredValues = [];
2632   // Flatten arrays/ranges
2633-  for (var x = 0; x < values.length; x++) {
2634+  for (let x = 0; x < values.length; x++) {
2635     // If this is an array/range parameter
2636     if (x % 2 === 0) {
2637       filteredValues.push(Filter.flatten(values[x]));
2638@@ -674,16 +674,16 @@ var COUNTIFS = function (...values) {
2639       filteredValues.push(values[x]);
2640     }
2641   }
2642-  var count = 0;
2643+  let count = 0;
2644   // For every value in the range
2645-  for (var i = 0; i < filteredValues[0].length; i++) {
2646+  for (let i = 0; i < filteredValues[0].length; i++) {
2647     // Check for criteria eval for other ranges and other criteria pairs.
2648-    var otherCriteriaEvaluationSuccessfulSoFar = true;
2649-    for (var x = 0; x < filteredValues.length; x += 2) {
2650+    let otherCriteriaEvaluationSuccessfulSoFar = true;
2651+    for (let x = 0; x < filteredValues.length; x += 2) {
2652       if (filteredValues[x].length < filteredValues[0].length) {
2653         throw new ValueError("Array arguments to COUNTIFS are of different size.");
2654       }
2655-      var criteriaEvaluation = criteriaEvaluationFunctions[x+1];
2656+      let criteriaEvaluation = criteriaEvaluationFunctions[x+1];
2657       if (otherCriteriaEvaluationSuccessfulSoFar) {
2658         if (!criteriaEvaluation(filteredValues[x][i])) { // evaluate THIS value with x+1 index, which is criteria.
2659           otherCriteriaEvaluationSuccessfulSoFar = false;
2660@@ -705,10 +705,10 @@ var COUNTIFS = function (...values) {
2661  * @returns {number}
2662  * @constructor
2663  */
2664-var ROUND = function (value, places) {
2665+let ROUND = function (value, places) {
2666   ArgsChecker.checkLength(arguments, 2, "ROUND");
2667-  var n = TypeConverter.firstValueAsNumber(value);
2668-  var d = TypeConverter.firstValueAsNumber(places);
2669+  let n = TypeConverter.firstValueAsNumber(value);
2670+  let d = TypeConverter.firstValueAsNumber(places);
2671   return Math.round(n * Math.pow(10, d)) / Math.pow(10, d);
2672 };
2673 
2674@@ -719,13 +719,13 @@ var ROUND = function (value, places) {
2675  * @returns {number}
2676  * @constructor
2677  */
2678-var ROUNDDOWN = function (value, places?) {
2679+let ROUNDDOWN = function (value, places?) {
2680   ArgsChecker.checkLengthWithin(arguments, 1, 2, "ROUNDDOWN");
2681-  var n = TypeConverter.firstValueAsNumber(value);
2682+  let n = TypeConverter.firstValueAsNumber(value);
2683   if (places === undefined) {
2684     return Math.floor(n);
2685   }
2686-  var d = TypeConverter.firstValueAsNumber(places);
2687+  let d = TypeConverter.firstValueAsNumber(places);
2688   return Math.floor(n * Math.pow(10, d)) / Math.pow(10, d);
2689 };
2690 
2691@@ -736,13 +736,13 @@ var ROUNDDOWN = function (value, places?) {
2692  * @returns {number}
2693  * @constructor
2694  */
2695-var ROUNDUP = function (value, places?) {
2696+let ROUNDUP = function (value, places?) {
2697   ArgsChecker.checkLengthWithin(arguments, 1, 2, "ROUNDUP");
2698-  var n = TypeConverter.firstValueAsNumber(value);
2699+  let n = TypeConverter.firstValueAsNumber(value);
2700   if (places === undefined) {
2701     return Math.ceil(n);
2702   }
2703-  var d = TypeConverter.firstValueAsNumber(places);
2704+  let d = TypeConverter.firstValueAsNumber(places);
2705   return Math.ceil(n * Math.pow(10, d)) / Math.pow(10, d);
2706 };
2707 
2708@@ -757,14 +757,14 @@ var ROUNDUP = function (value, places?) {
2709  * @returns {number}
2710  * @constructor
2711  */
2712-var SUMIF = function (range, criteria, sumRange?) {
2713+let SUMIF = function (range, criteria, sumRange?) {
2714   ArgsChecker.checkLengthWithin(arguments, 2, 3, "SUMIF");
2715 
2716-  var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criteria);
2717+  let criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criteria);
2718 
2719-  var sum = 0;
2720-  for (var i = 0; i < range.length; i++) {
2721-    var x = range[i];
2722+  let sum = 0;
2723+  for (let i = 0; i < range.length; i++) {
2724+    let x = range[i];
2725     if (x instanceof Array) {
2726       sum += SUMIF.apply(this, [x, criteria]);
2727     } else {
2728@@ -787,17 +787,17 @@ var SUMIF = function (range, criteria, sumRange?) {
2729  * @returns {number} the sum of the squares if the input.
2730  * @constructor
2731  */
2732-var SUMSQ = function (...values) {
2733+let SUMSQ = function (...values) {
2734   ArgsChecker.checkAtLeastLength(values, 1, "SUMSQ");
2735-  var result = 0;
2736-  for (var i = 0; i < values.length; i++) {
2737+  let result = 0;
2738+  for (let i = 0; i < values.length; i++) {
2739     if (values[i] instanceof Array) {
2740       if (values[i].length === 0) {
2741         throw new RefError("Reference does not exist.");
2742       }
2743       result = result + SUMSQ.apply(this, Filter.filterOutNonNumberValues(values[i]));
2744     } else {
2745-      var n = TypeConverter.valueToNumber(values[i]);
2746+      let n = TypeConverter.valueToNumber(values[i]);
2747       result = result + (n * n);
2748     }
2749   }
2750@@ -811,10 +811,10 @@ var SUMSQ = function (...values) {
2751  * @param factor2 - The second multiplicand.
2752  * @constructor
2753  */
2754-var MULTIPLY = function (factor1, factor2) {
2755+let MULTIPLY = function (factor1, factor2) {
2756   ArgsChecker.checkLength(arguments, 2, "MULTIPLY");
2757-  var x = TypeConverter.firstValueAsNumber(factor1);
2758-  var y = TypeConverter.firstValueAsNumber(factor1);
2759+  let x = TypeConverter.firstValueAsNumber(factor1);
2760+  let y = TypeConverter.firstValueAsNumber(factor1);
2761   return x * y;
2762 };
2763 
2764@@ -826,10 +826,10 @@ var MULTIPLY = function (factor1, factor2) {
2765  * @returns {number}
2766  * @constructor
2767  */
2768-var MINUS = function (one, two) {
2769+let MINUS = function (one, two) {
2770   ArgsChecker.checkLength(arguments, 2, "MINUS");
2771-  var x = TypeConverter.firstValueAsNumber(one);
2772-  var y = TypeConverter.firstValueAsNumber(two);
2773+  let x = TypeConverter.firstValueAsNumber(one);
2774+  let y = TypeConverter.firstValueAsNumber(two);
2775   return x - y;
2776 };
2777 
2778@@ -841,10 +841,10 @@ var MINUS = function (one, two) {
2779  * @returns {boolean} true if values are equal, false if they are not equal.
2780  * @constructor
2781  */
2782-var EQ = function (one, two) {
2783+let EQ = function (one, two) {
2784   ArgsChecker.checkLength(arguments, 2, "EQ");
2785-  var x = TypeConverter.firstValue(one);
2786-  var y = TypeConverter.firstValue(two);
2787+  let x = TypeConverter.firstValue(one);
2788+  let y = TypeConverter.firstValue(two);
2789   return x === y;
2790 };
2791 
2792@@ -857,10 +857,10 @@ var EQ = function (one, two) {
2793  * @returns {boolean}
2794  * @constructor
2795  */
2796-var GT = function (one, two) {
2797+let GT = function (one, two) {
2798   ArgsChecker.checkLength(arguments, 2, "GT");
2799-  var x = TypeConverter.firstValue(one);
2800-  var y = TypeConverter.firstValue(two);
2801+  let x = TypeConverter.firstValue(one);
2802+  let y = TypeConverter.firstValue(two);
2803   return x > y;
2804 };
2805 
2806@@ -873,10 +873,10 @@ var GT = function (one, two) {
2807  * @returns {boolean}
2808  * @constructor
2809  */
2810-var GTE = function (one, two) {
2811+let GTE = function (one, two) {
2812   ArgsChecker.checkLength(arguments, 2, "GTE");
2813-  var x = TypeConverter.firstValue(one);
2814-  var y = TypeConverter.firstValue(two);
2815+  let x = TypeConverter.firstValue(one);
2816+  let y = TypeConverter.firstValue(two);
2817   return x >= y;
2818 };
2819 
2820@@ -889,10 +889,10 @@ var GTE = function (one, two) {
2821  * @returns {boolean}
2822  * @constructor
2823  */
2824-var LT = function (one, two) {
2825+let LT = function (one, two) {
2826   ArgsChecker.checkLength(arguments, 2, "LT");
2827-  var x = TypeConverter.firstValue(one);
2828-  var y = TypeConverter.firstValue(two);
2829+  let x = TypeConverter.firstValue(one);
2830+  let y = TypeConverter.firstValue(two);
2831   return x < y;
2832 };
2833 
2834@@ -904,10 +904,10 @@ var LT = function (one, two) {
2835  * @param two - The second value.
2836  * @constructor
2837  */
2838-var LTE = function (one, two) {
2839+let LTE = function (one, two) {
2840   ArgsChecker.checkLength(arguments, 2, "LTE");
2841-  var x = TypeConverter.firstValue(one);
2842-  var y = TypeConverter.firstValue(two);
2843+  let x = TypeConverter.firstValue(one);
2844+  let y = TypeConverter.firstValue(two);
2845   return x <= y;
2846 };
2847 
2848@@ -919,10 +919,10 @@ var LTE = function (one, two) {
2849  * @returns {boolean}
2850  * @constructor
2851  */
2852-var NE =  function (one, two) {
2853+let NE =  function (one, two) {
2854   ArgsChecker.checkLength(arguments, 2, "NE");
2855-  var x = TypeConverter.firstValue(one);
2856-  var y = TypeConverter.firstValue(two);
2857+  let x = TypeConverter.firstValue(one);
2858+  let y = TypeConverter.firstValue(two);
2859   return x !== y;
2860 };
2861 
2862@@ -934,10 +934,10 @@ var NE =  function (one, two) {
2863  * @returns {number} result of dividend / divisor.
2864  * @constructor
2865  */
2866-var DIVIDE = function (dividend, divisor) {
2867+let DIVIDE = function (dividend, divisor) {
2868   ArgsChecker.checkLength(arguments, 2, "DIVIDE");
2869-  var x = TypeConverter.firstValueAsNumber(dividend);
2870-  var y = TypeConverter.firstValueAsNumber(divisor);
2871+  let x = TypeConverter.firstValueAsNumber(dividend);
2872+  let y = TypeConverter.firstValueAsNumber(divisor);
2873   if (y < 0) {
2874     throw new DivZeroError("Function DIVIDE parameter 2 cannot be zero.");
2875   }
2876@@ -950,7 +950,7 @@ var DIVIDE = function (dividend, divisor) {
2877  * @returns {number}
2878  * @constructor
2879  */
2880-var RAND = function () {
2881+let RAND = function () {
2882   ArgsChecker.checkLength(arguments, 0, "RAND");
2883   return Math.random();
2884 };
2885@@ -965,7 +965,7 @@ var RAND = function () {
2886  * @returns {number} between low and high.
2887  * @constructor
2888  */
2889-var RANDBETWEEN = function (low, high) {
2890+let RANDBETWEEN = function (low, high) {
2891   ArgsChecker.checkLength(arguments, 2, "RAND");
2892   low = Math.floor(TypeConverter.firstValueAsNumber(low));
2893   high = Math.ceil(TypeConverter.firstValueAsNumber(high));
2894@@ -973,7 +973,7 @@ var RANDBETWEEN = function (low, high) {
2895     throw new NumError("Function RANDBETWEEN parameter 2 value is " + low + ". It should be greater than or equal to "
2896       + high + ".");
2897   }
2898-  var diff = Math.abs(low - high);
2899+  let diff = Math.abs(low - high);
2900   return Math.round(low + (Math.random() * diff));
2901 };
2902 
2903@@ -984,9 +984,9 @@ var RANDBETWEEN = function (low, high) {
2904  * @returns {number} `-1` if it is negative, `1` if positive, and `0` if it is zero.
2905  * @constructor
2906  */
2907-var SIGN =  function (value) {
2908+let SIGN =  function (value) {
2909   ArgsChecker.checkLength(arguments, 1, "SIGN");
2910-  var x = TypeConverter.firstValueAsNumber(value);
2911+  let x = TypeConverter.firstValueAsNumber(value);
2912   if (x === 0) {
2913     return 0;
2914   }
2915@@ -1005,14 +1005,14 @@ var SIGN =  function (value) {
2916  * @returns {number} after truncation
2917  * @constructor
2918  */
2919-var TRUNC = function (value, places?) : number {
2920+let TRUNC = function (value, places?) : number {
2921   ArgsChecker.checkLengthWithin(arguments, 1, 2, "TRUNC");
2922-  var n = TypeConverter.firstValueAsNumber(value);
2923-  var digits = 0;
2924+  let n = TypeConverter.firstValueAsNumber(value);
2925+  let digits = 0;
2926   if (places !== undefined) {
2927     digits = TypeConverter.firstValueAsNumber(places);
2928   }
2929-  var sign = (n > 0) ? 1 : -1;
2930+  let sign = (n > 0) ? 1 : -1;
2931   return sign * (Math.floor(Math.abs(n) * Math.pow(10, digits))) / Math.pow(10, digits);
2932 };
2933 
2934@@ -1023,9 +1023,9 @@ var TRUNC = function (value, places?) : number {
2935  * @returns {number} radians
2936  * @constructor
2937  */
2938-var RADIANS = function (angle) {
2939+let RADIANS = function (angle) {
2940   ArgsChecker.checkLength(arguments, 1, "RADIANS");
2941-  var d = TypeConverter.firstValueAsNumber(angle);
2942+  let d = TypeConverter.firstValueAsNumber(angle);
2943   return d * Math.PI / 180;
2944 };
2945 
2946@@ -1035,9 +1035,9 @@ var RADIANS = function (angle) {
2947  * @returns {number} degrees
2948  * @constructor
2949  */
2950-var DEGREES = function (angle) {
2951+let DEGREES = function (angle) {
2952   ArgsChecker.checkLength(arguments, 1, "DEGREES");
2953-  var r = TypeConverter.firstValueAsNumber(angle);
2954+  let r = TypeConverter.firstValueAsNumber(angle);
2955   return r * 180 / Math.PI;
2956 };
2957 
2958@@ -1048,9 +1048,9 @@ var DEGREES = function (angle) {
2959  * @returns {number} complementary Gauss error function of a value
2960  * @constructor
2961  */
2962-var ERFC = function (value) {
2963+let ERFC = function (value) {
2964   ArgsChecker.checkLength(arguments, 1, "ERFC");
2965-  var v = TypeConverter.firstValueAsNumber(value);
2966+  let v = TypeConverter.firstValueAsNumber(value);
2967   return v === 0 ? 1 : 1 - erf(v);
2968 };
2969 
2970@@ -1063,10 +1063,10 @@ var ERFC = function (value) {
2971  * @returns {number} error function integrated between lower_limit and upper_limit
2972  * @constructor
2973  */
2974-var ERF = function (lowerLimit, upperLimit?) : number {
2975+let ERF = function (lowerLimit, upperLimit?) : number {
2976   ArgsChecker.checkLengthWithin(arguments, 1, 2, "ERF");
2977-  var lower = TypeConverter.firstValueAsNumber(lowerLimit);
2978-  var upper = upperLimit !== undefined ? TypeConverter.firstValueAsNumber(upperLimit) : 0;
2979+  let lower = TypeConverter.firstValueAsNumber(lowerLimit);
2980+  let upper = upperLimit !== undefined ? TypeConverter.firstValueAsNumber(upperLimit) : 0;
2981   return upperLimit === undefined ? erf(lower) : erf(upper) - erf(lower);
2982 };
2983 
2984@@ -1080,15 +1080,15 @@ var ERF = function (lowerLimit, upperLimit?) : number {
2985  * @returns {number} sum of the sums of the squares
2986  * @constructor
2987  */
2988-var SUMX2PY2 = function (arrayX, arrayY) : number {
2989+let SUMX2PY2 = function (arrayX, arrayY) : number {
2990   ArgsChecker.checkLength(arguments, 2, "SUMX2PY2");
2991-  var arrOne = Filter.flattenAndThrow(arrayX);
2992-  var arrTwo = Filter.flattenAndThrow(arrayY);
2993+  let arrOne = Filter.flattenAndThrow(arrayX);
2994+  let arrTwo = Filter.flattenAndThrow(arrayY);
2995   if (arrOne.length !== arrTwo.length) {
2996     throw new NAError("Array arguments to SUMX2PY2 are of different size.");
2997   }
2998-  var result = 0;
2999-  for (var i = 0; i < arrOne.length; i++) {
3000+  let result = 0;
3001+  for (let i = 0; i < arrOne.length; i++) {
3002     // If either values at this index are anything but numbers, skip them. This is the behavior in GS at least.
3003     if (typeof arrOne[i] === "number" && typeof arrTwo[i] === "number") {
3004       result += arrOne[i] * arrOne[i] + arrTwo[i] * arrTwo[i];
3005@@ -1106,15 +1106,15 @@ var SUMX2PY2 = function (arrayX, arrayY) : number {
3006  * @returns {number} sum of the differences of the squares
3007  * @constructor
3008  */
3009-var SUMX2MY2 = function (arrayX, arrayY) : number {
3010+let SUMX2MY2 = function (arrayX, arrayY) : number {
3011   ArgsChecker.checkLength(arguments, 2, "SUMX2MY2");
3012-  var arrOne = Filter.flattenAndThrow(arrayX);
3013-  var arrTwo = Filter.flattenAndThrow(arrayY);
3014+  let arrOne = Filter.flattenAndThrow(arrayX);
3015+  let arrTwo = Filter.flattenAndThrow(arrayY);
3016   if (arrOne.length !== arrTwo.length) {
3017     throw new NAError("Array arguments to SUMX2MY2 are of different size.");
3018   }
3019-  var result = 0;
3020-  for (var i = 0; i < arrOne.length; i++) {
3021+  let result = 0;
3022+  for (let i = 0; i < arrOne.length; i++) {
3023     // If either values at this index are anything but numbers, skip them. This is the behavior in GS at least.
3024     if (typeof arrOne[i] === "number" && typeof arrTwo[i] === "number") {
3025       result += arrOne[i] * arrOne[i] - arrTwo[i] * arrTwo[i];
3026@@ -1125,16 +1125,16 @@ var SUMX2MY2 = function (arrayX, arrayY) : number {
3027 
3028 
3029 // Private function that will recursively generate an array of the unique primitives
3030-var _countUnique = function (values: Array<any>) : Object {
3031-  var uniques = {};
3032-  for (var i = 0; i < values.length; i++) {
3033+let _countUnique = function (values: Array<any>) : Object {
3034+  let uniques = {};
3035+  for (let i = 0; i < values.length; i++) {
3036     if (Array.isArray(values[i])) {
3037       // For some reasons an empty range is converted to a range with a single empty string in it.
3038       if (values[i].length === 0) {
3039         values[i] = [""];
3040       }
3041-      var uniquesOfArray = _countUnique(values[i]);
3042-      for (var key in uniquesOfArray) {
3043+      let uniquesOfArray = _countUnique(values[i]);
3044+      for (let key in uniquesOfArray) {
3045         uniques[key] = true;
3046       }
3047     } else {
3048@@ -1151,10 +1151,10 @@ var _countUnique = function (values: Array<any>) : Object {
3049  * @returns {number} of unique values passed in.
3050  * @constructor
3051  */
3052-var COUNTUNIQUE = function (...values) : number {
3053+let COUNTUNIQUE = function (...values) : number {
3054   ArgsChecker.checkAtLeastLength(values, 1, "COUNTUNIQUE");
3055 
3056-  var uniques = _countUnique(values);
3057+  let uniques = _countUnique(values);
3058   return Object.keys(uniques).length;
3059 };
3060 
3061@@ -1166,18 +1166,18 @@ var COUNTUNIQUE = function (...values) : number {
3062  * @returns {number} sum of the products
3063  * @constructor
3064  */
3065-var SUMPRODUCT = function (...values) : number {
3066+let SUMPRODUCT = function (...values) : number {
3067   ArgsChecker.checkAtLeastLength(values, 1, "SUMPRODUCT");
3068   // Ensuring that all values are array values
3069-  for (var x = 0; x < values.length; x++) {
3070+  for (let x = 0; x < values.length; x++) {
3071     if (!Array.isArray(values[x])) {
3072       values[x] = [values[x]];
3073     }
3074   }
3075 
3076   // Flatten any nested ranges (arrays) and check for mismatched range sizes
3077-  var flattenedValues = [Filter.flattenAndThrow(values[0])];
3078-  for (var x = 1; x < values.length; x++) {
3079+  let flattenedValues = [Filter.flattenAndThrow(values[0])];
3080+  for (let x = 1; x < values.length; x++) {
3081     flattenedValues.push(Filter.flattenAndThrow(values[x]));
3082     if (flattenedValues[x].length !== flattenedValues[0].length) {
3083       throw new ValueError("SUMPRODUCT has mismatched range sizes. Expected count: "
3084@@ -1186,10 +1186,10 @@ var SUMPRODUCT = function (...values) : number {
3085   }
3086 
3087   // Do the actual math
3088-  var result = 0;
3089-  for (var i = 0; i < flattenedValues[0].length; i++) {
3090-    var product = 1;
3091-    for (var x = 0; x < flattenedValues.length; x++) {
3092+  let result = 0;
3093+  for (let i = 0; i < flattenedValues[0].length; i++) {
3094+    let product = 1;
3095+    for (let x = 0; x < flattenedValues.length; x++) {
3096       product *= TypeConverter.valueToNumberGracefully(flattenedValues[x][i]);
3097     }
3098     result += product;
3099@@ -1205,12 +1205,12 @@ var SUMPRODUCT = function (...values) : number {
3100  * @returns {number} number of ways
3101  * @constructor
3102  */
3103-var COMBIN = function (m, k) : number {
3104+let COMBIN = function (m, k) : number {
3105   ArgsChecker.checkLength(arguments, 2, "COMBIN");
3106 
3107-  var MEMOIZED_FACT = [];
3108+  let MEMOIZED_FACT = [];
3109   function fact(number) {
3110-    var n = Math.floor(number);
3111+    let n = Math.floor(number);
3112     if (n === 0 || n === 1) {
3113       return 1;
3114     } else if (MEMOIZED_FACT[n] > 0) {
3115@@ -1220,15 +1220,15 @@ var COMBIN = function (m, k) : number {
3116       return MEMOIZED_FACT[n];
3117     }
3118   }
3119-  var n = TypeConverter.firstValueAsNumber(m);
3120-  var c = TypeConverter.firstValueAsNumber(k);
3121+  let n = TypeConverter.firstValueAsNumber(m);
3122+  let c = TypeConverter.firstValueAsNumber(k);
3123   if (n < c) {
3124     throw new NumError("Function COMBIN parameter 2 value is "
3125       + c + ". It should be less than or equal to value of Function COMBIN parameter 1 with " + n + ".");
3126   }
3127   n = Math.floor(n);
3128   c = Math.floor(c);
3129-  var div = fact(c) * fact(n - c);
3130+  let div = fact(c) * fact(n - c);
3131   if (div === 0) {
3132     throw new DivZeroError("Evaluation of function COMBIN caused a divide by zero error.");
3133   }
3134@@ -1240,11 +1240,11 @@ var COMBIN = function (m, k) : number {
3135  * @param values - values or range of values to multiply by each other.
3136  * @constructor
3137  */
3138-var PRODUCT =  function (...values) {
3139+let PRODUCT =  function (...values) {
3140   ArgsChecker.checkAtLeastLength(values, 2, "PRODUCT");
3141-  var value = 1;
3142-  var numbers = Filter.flattenAndThrow(values);
3143-  for (var i = 0; i < numbers.length; i++) {
3144+  let value = 1;
3145+  let numbers = Filter.flattenAndThrow(values);
3146+  for (let i = 0; i < numbers.length; i++) {
3147     value *= TypeConverter.valueToNumber(numbers[i]);
3148   }
3149   return value;
3150@@ -1258,10 +1258,10 @@ var PRODUCT =  function (...values) {
3151  * @returns {number}
3152  * @constructor
3153  */
3154-var QUOTIENT = function (dividend, divisor) {
3155+let QUOTIENT = function (dividend, divisor) {
3156   ArgsChecker.checkLength(arguments, 2, "QUOTIENT");
3157-  var dv = TypeConverter.firstValueAsNumber(dividend);
3158-  var ds = TypeConverter.firstValueAsNumber(divisor);
3159+  let dv = TypeConverter.firstValueAsNumber(dividend);
3160+  let ds = TypeConverter.firstValueAsNumber(divisor);
3161   if (ds === 0) {
3162     throw new DivZeroError("Function QUOTIENT parameter 2 cannot be zero.");
3163   }
3164@@ -1275,7 +1275,7 @@ var QUOTIENT = function (dividend, divisor) {
3165  * @returns any value
3166  * @constructor
3167  */
3168-var UPLUS = function (value) : any {
3169+let UPLUS = function (value) : any {
3170   ArgsChecker.checkLength(arguments, 1, "UPLUS");
3171   return TypeConverter.firstValue(value);
3172 };
3173@@ -1287,9 +1287,9 @@ var UPLUS = function (value) : any {
3174  * @returns {number}
3175  * @constructor
3176  */
3177-var UMINUS = function (value) {
3178+let UMINUS = function (value) {
3179   ArgsChecker.checkLength(arguments, 1, "UMINUS");
3180-  var n = TypeConverter.firstValueAsNumber(value);
3181+  let n = TypeConverter.firstValueAsNumber(value);
3182   return n * -1;
3183 };
3184 
3185@@ -1301,10 +1301,10 @@ var UMINUS = function (value) {
3186  * @returns {number}
3187  * @constructor
3188  */
3189-var MROUND = function (value, factor) {
3190+let MROUND = function (value, factor) {
3191   ArgsChecker.checkLength(arguments, 2, "MROUND");
3192-  var v = TypeConverter.firstValueAsNumber(value);
3193-  var f = TypeConverter.firstValueAsNumber(factor);
3194+  let v = TypeConverter.firstValueAsNumber(value);
3195+  let f = TypeConverter.firstValueAsNumber(factor);
3196   if (v * f < 0) {
3197     throw new NumError("Parameters of MROUND must have same signs (both positive or both negative).");
3198   }
3199@@ -1321,9 +1321,9 @@ var MROUND = function (value, factor) {
3200  * @returns {number}
3201  * @constructor
3202  */
3203-var FACTDOUBLE = function (value) {
3204+let FACTDOUBLE = function (value) {
3205   ArgsChecker.checkLength(arguments, 1, "FACTDOUBLE");
3206-  var n = Math.floor(TypeConverter.firstValueAsNumber(value));
3207+  let n = Math.floor(TypeConverter.firstValueAsNumber(value));
3208   function factDoublePrivate(n) {
3209     if (n <= 0) {
3210       return 1;
3211@@ -1347,7 +1347,7 @@ var FACTDOUBLE = function (value) {
3212  * @returns {number}
3213  * @constructor
3214  */
3215-var UNARY_PERCENT = function (value) {
3216+let UNARY_PERCENT = function (value) {
3217   ArgsChecker.checkLength(arguments, 1, "UNARY_PERCENT");
3218   return TypeConverter.firstValueAsNumber(value) / 100;
3219 };
3220@@ -1359,12 +1359,12 @@ var UNARY_PERCENT = function (value) {
3221  * @returns {number}
3222  * @constructor
3223  */
3224-var MULTINOMIAL = function (...values) {
3225+let MULTINOMIAL = function (...values) {
3226   ArgsChecker.checkAtLeastLength(values, 1, "MULTINOMIAL");
3227   values = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber);
3228-  var memoizeFact = [];
3229+  let memoizeFact = [];
3230   function _fact(value) {
3231-    var n = Math.floor(value);
3232+    let n = Math.floor(value);
3233     if (n === 0 || n === 1) {
3234       return 1;
3235     } else if (memoizeFact[n] > 0) {
3236@@ -1374,9 +1374,9 @@ var MULTINOMIAL = function (...values) {
3237       return memoizeFact[n];
3238     }
3239   }
3240-  var sum = 0;
3241-  var divisor = 1;
3242-  for (var i = 0; i < values.length; i++) {
3243+  let sum = 0;
3244+  let divisor = 1;
3245+  for (let i = 0; i < values.length; i++) {
3246     sum += arguments[i];
3247     divisor *= _fact(values[i]);
3248   }
3249diff --git a/src/Formulas/Range.ts b/src/Formulas/Range.ts
3250index 9d4a21a..44961f2 100644
3251--- a/src/Formulas/Range.ts
3252+++ b/src/Formulas/Range.ts
3253@@ -23,7 +23,7 @@ import {
3254  * @constructor
3255  * TODO: Returns ColumnArray (values stacked in Y-direction)
3256  */
3257-var FREQUENCY = function (range, bins) : Array<number> {
3258+let FREQUENCY = function (range, bins) : Array<number> {
3259   ArgsChecker.checkLength(arguments, 2, "FREQUENCY");
3260   if (!Array.isArray(bins)) {
3261     bins = [bins];
3262@@ -42,12 +42,12 @@ var FREQUENCY = function (range, bins) : Array<number> {
3263     return a - b;
3264   });
3265 
3266-  var n = range.length;
3267-  var b = bins.length;
3268-  var r = [];
3269-  for (var i = 0; i <= b; i++) {
3270+  let n = range.length;
3271+  let b = bins.length;
3272+  let r = [];
3273+  for (let i = 0; i <= b; i++) {
3274     r[i] = 0;
3275-    for (var j = 0; j < n; j++) {
3276+    for (let j = 0; j < n; j++) {
3277       if (i === 0) {
3278         if (range[j] <= bins[0]) {
3279           r[0] += 1;
3280@@ -80,7 +80,7 @@ var FREQUENCY = function (range, bins) : Array<number> {
3281  * @constructor
3282  * TODO: Returns RowArray (values stacked in X-direction)
3283  */
3284-var GROWTH = function (knownY, knownX?, newX?, shouldUseConstant?) {
3285+let GROWTH = function (knownY, knownX?, newX?, shouldUseConstant?) {
3286   ArgsChecker.checkLengthWithin(arguments, 1, 4, "GROWTH");
3287   // Credits: Ilmari Karonen, FormulaJs (https://github.com/sutoiku/formula.js/)
3288 
3289@@ -95,13 +95,13 @@ var GROWTH = function (knownY, knownX?, newX?, shouldUseConstant?) {
3290   // Default values for optional parameters:
3291   if (arguments.length < 2) {
3292     knownX = [];
3293-    for (var i = 1; i <= knownY.length; i++) {
3294+    for (let i = 1; i <= knownY.length; i++) {
3295       knownX.push(i);
3296     }
3297   }
3298   if (arguments.length < 3) {
3299     newX = [];
3300-    for (var i = 1; i <= knownY.length; i++) {
3301+    for (let i = 1; i <= knownY.length; i++) {
3302       newX.push(i);
3303     }
3304   }
3305@@ -110,14 +110,14 @@ var GROWTH = function (knownY, knownX?, newX?, shouldUseConstant?) {
3306   }
3307 
3308   // Calculate sums over the data:
3309-  var n = knownY.length;
3310-  var avg_x = 0;
3311-  var avg_y = 0;
3312-  var avg_xy = 0;
3313-  var avg_xx = 0;
3314-  for (i = 0; i < n; i++) {
3315-    var x = knownX[i];
3316-    var y = Math.log(knownY[i]);
3317+  let n = knownY.length;
3318+  let avg_x = 0;
3319+  let avg_y = 0;
3320+  let avg_xy = 0;
3321+  let avg_xx = 0;
3322+  for (let i = 0; i < n; i++) {
3323+    let x = knownX[i];
3324+    let y = Math.log(knownY[i]);
3325     avg_x += x;
3326     avg_y += y;
3327     avg_xy += x * y;
3328@@ -129,8 +129,8 @@ var GROWTH = function (knownY, knownX?, newX?, shouldUseConstant?) {
3329   avg_xx /= n;
3330 
3331   // Compute linear regression coefficients:
3332-  var beta;
3333-  var alpha;
3334+  let beta;
3335+  let alpha;
3336   if (shouldUseConstant) {
3337     beta = (avg_xy - avg_x * avg_y) / (avg_xx - avg_x * avg_x);
3338     alpha = avg_y - beta * avg_x;
3339@@ -140,8 +140,8 @@ var GROWTH = function (knownY, knownX?, newX?, shouldUseConstant?) {
3340   }
3341 
3342   // Compute and return result array:
3343-  var new_y = [];
3344-  for (i = 0; i < newX.length; i++) {
3345+  let new_y = [];
3346+  for (let i = 0; i < newX.length; i++) {
3347     new_y.push(Math.exp(alpha + beta * newX[i]));
3348   }
3349   return new_y;
3350@@ -154,12 +154,12 @@ var GROWTH = function (knownY, knownX?, newX?, shouldUseConstant?) {
3351  * @returns {number[]}
3352  * @constructor
3353  */
3354-var LINEST = function (dataY, dataX) {
3355+let LINEST = function (dataY, dataX) {
3356   ArgsChecker.checkLength(arguments, 2, "LINEST");
3357-  var rangeY = Filter.flattenAndThrow(dataY).map(function (value) {
3358+  let rangeY = Filter.flattenAndThrow(dataY).map(function (value) {
3359     return TypeConverter.valueToNumber(value);
3360   });
3361-  var rangeX = Filter.flattenAndThrow(dataX).map(function (value) {
3362+  let rangeX = Filter.flattenAndThrow(dataX).map(function (value) {
3363     return TypeConverter.valueToNumber(value);
3364   });
3365 
3366@@ -170,17 +170,17 @@ var LINEST = function (dataY, dataX) {
3367     throw new NAError("LINEST requires more data points. Expected: 2, found: " + rangeY.length + ".");
3368   }
3369 
3370-  var xMean = mean(rangeX);
3371-  var yMean = mean(rangeY);
3372-  var n = rangeX.length;
3373-  var num = 0;
3374-  var den = 0;
3375-  for (var i = 0; i < n; i++) {
3376+  let xMean = mean(rangeX);
3377+  let yMean = mean(rangeY);
3378+  let n = rangeX.length;
3379+  let num = 0;
3380+  let den = 0;
3381+  for (let i = 0; i < n; i++) {
3382     num += (rangeX[i] - xMean) * (rangeY[i] - yMean);
3383     den += Math.pow(rangeX[i] - xMean, 2);
3384   }
3385-  var m = num / den;
3386-  var b = yMean - m * xMean;
3387+  let m = num / den;
3388+  let b = yMean - m * xMean;
3389   return [m, b];
3390 };
3391 
3392diff --git a/src/Formulas/Statistical.ts b/src/Formulas/Statistical.ts
3393index fb2054a..41776e1 100644
3394--- a/src/Formulas/Statistical.ts
3395+++ b/src/Formulas/Statistical.ts
3396@@ -39,18 +39,18 @@ import {
3397  * @returns {number} sum of squares of deviations
3398  * @constructor
3399  */
3400-var DEVSQ = function (...values) : number {
3401+let DEVSQ = function (...values) : number {
3402   ArgsChecker.checkAtLeastLength(values, 1, "DEVSQ");
3403-  var range = Filter.flattenAndThrow(values);
3404-  var result = 0;
3405-  var count = 0;
3406-  for (var i = 0; i < range.length; i++) {
3407+  let range = Filter.flattenAndThrow(values);
3408+  let result = 0;
3409+  let count = 0;
3410+  for (let i = 0; i < range.length; i++) {
3411     result = result + TypeConverter.valueToNumber(range[i]);
3412     count++;
3413   }
3414-  var mean = result / count;
3415-  var result = 0;
3416-  for (var i = 0; i < range.length; i++) {
3417+  let mean = result / count;
3418+  result = 0;
3419+  for (let i = 0; i < range.length; i++) {
3420     result += Math.pow((TypeConverter.valueToNumber(range[i]) - mean), 2);
3421   }
3422   return result;
3423@@ -62,23 +62,23 @@ var DEVSQ = function (...values) : number {
3424  * @returns {number} the median value of the dataset
3425  * @constructor
3426  */
3427-var MEDIAN = function (...values) : number {
3428+let MEDIAN = function (...values) : number {
3429   ArgsChecker.checkAtLeastLength(values, 1, "MEDIAN");
3430-  var sortedArray = [];
3431+  let sortedArray = [];
3432   values.forEach(function (currentValue) {
3433     if (currentValue instanceof Array) {
3434       if (currentValue.length === 0) {
3435         throw new RefError("Reference does not exist.");
3436       }
3437-      var filtered = Filter.filterOutStringValues(currentValue);
3438+      let filtered = Filter.filterOutStringValues(currentValue);
3439       sortedArray = sortedArray.concat(filtered);
3440     } else {
3441       sortedArray.push(TypeConverter.valueToNumber(currentValue));
3442     }
3443   });
3444   sortedArray = sortedArray.sort(function (a, b) {
3445-    var aN = TypeConverter.valueToNumber(a);
3446-    var bN = TypeConverter.valueToNumber(b);
3447+    let aN = TypeConverter.valueToNumber(a);
3448+    let bN = TypeConverter.valueToNumber(b);
3449     return aN - bN;
3450   });
3451   if (sortedArray.length === 1) {
3452@@ -92,8 +92,8 @@ var MEDIAN = function (...values) : number {
3453     if (sortedArray.length === 2) {
3454       return AVERAGE(sortedArray[0], sortedArray[1]);
3455     }
3456-    var top = sortedArray[sortedArray.length / 2];
3457-    var bottom = sortedArray[(sortedArray.length / 2) - 1];
3458+    let top = sortedArray[sortedArray.length / 2];
3459+    let bottom = sortedArray[(sortedArray.length / 2) - 1];
3460     return AVERAGE(top, bottom);
3461   } else {
3462     // odd number of values
3463@@ -107,16 +107,16 @@ var MEDIAN = function (...values) : number {
3464  * @returns {number} the average value of this dataset.
3465  * @constructor
3466  */
3467-var AVERAGE = function (...values) : number {
3468+let AVERAGE = function (...values) : number {
3469   ArgsChecker.checkAtLeastLength(values, 1, "AVERAGE");
3470-  var result = 0;
3471-  var count = 0;
3472-  for (var i = 0; i < values.length; i++) {
3473+  let result = 0;
3474+  let count = 0;
3475+  for (let i = 0; i < values.length; i++) {
3476     if (values[i] instanceof Array) {
3477       if (values[i].length === 0) {
3478         throw new RefError("Reference does not exist.");
3479       }
3480-      var filtered = Filter.filterOutStringValues(values[i]);
3481+      let filtered = Filter.filterOutStringValues(values[i]);
3482       result = result + SUM.apply(this, filtered);
3483       count += filtered.length;
3484     } else {
3485@@ -133,14 +133,14 @@ var AVERAGE = function (...values) : number {
3486  * @returns {number} average of the magnitudes of deviations of data from a dataset's mean
3487  * @constructor
3488  */
3489-var AVEDEV = function (...values) {
3490+let AVEDEV = function (...values) {
3491   ArgsChecker.checkAtLeastLength(values, 1, "AVEDEV");
3492 
3493   // Sort to array-values, and non-array-values
3494-  var arrayValues = [];
3495-  var nonArrayValues = [];
3496-  for (var i = 0; i < values.length; i++) {
3497-    var X = values[i];
3498+  let arrayValues = [];
3499+  let nonArrayValues = [];
3500+  for (let i = 0; i < values.length; i++) {
3501+    let X = values[i];
3502     if (X instanceof Array) {
3503       if (X.length === 0) {
3504         throw new RefError("Reference does not exist.");
3505@@ -152,23 +152,23 @@ var AVEDEV = function (...values) {
3506   }
3507 
3508   // Remove string values from array-values, but not from non-array-values, and concat.
3509-  var flatValues = Filter.filterOutStringValues(Filter.flatten(arrayValues)).map(function (value) {
3510+  let flatValues = Filter.filterOutStringValues(Filter.flatten(arrayValues)).map(function (value) {
3511     return TypeConverter.valueToNumber(value);
3512   }).concat(nonArrayValues);
3513 
3514   // Calculating mean
3515-  var result = 0;
3516-  var count = 0;
3517-  for (var i = 0; i < flatValues.length; i++) {
3518+  let result = 0;
3519+  let count = 0;
3520+  for (let i = 0; i < flatValues.length; i++) {
3521     result = result + TypeConverter.valueToNumber(flatValues[i]);
3522     count++;
3523   }
3524   if (count === 0) {
3525     throw new DivZeroError("Evaluation of function AVEDEV caused a devide by zero error.");
3526   }
3527-  var mean = result / count;
3528+  let mean = result / count;
3529 
3530-  for (var i = 0; i < flatValues.length; i++) {
3531+  for (let i = 0; i < flatValues.length; i++) {
3532     flatValues[i] = ABS(TypeConverter.valueToNumber(flatValues[i]) - mean);
3533   }
3534   return SUM(flatValues) / flatValues.length;
3535@@ -180,16 +180,16 @@ var AVEDEV = function (...values) {
3536  * @returns {number} the numerical average value in a dataset
3537  * @constructor
3538  */
3539-var AVERAGEA = function (...values) {
3540+let AVERAGEA = function (...values) {
3541   ArgsChecker.checkAtLeastLength(values, 1, "AVERAGEA");
3542-  var result = 0;
3543-  var count = 0;
3544-  for (var i = 0; i < values.length; i++) {
3545+  let result = 0;
3546+  let count = 0;
3547+  for (let i = 0; i < values.length; i++) {
3548     if (values[i] instanceof Array) {
3549       if (values[i].length === 0) {
3550         throw new RefError("Reference does not exist.");
3551       }
3552-      var filtered = Filter.stringValuesToZeros(values[i]);
3553+      let filtered = Filter.stringValuesToZeros(values[i]);
3554       result = result + SUM.apply(this, filtered);
3555       count += filtered.length;
3556     } else {
3557@@ -212,7 +212,7 @@ var AVERAGEA = function (...values) {
3558  * @returns {number} the Pearson product-moment correlation coefficient.
3559  * @constructor
3560  */
3561-var CORREL = function (dataY, dataX) : number {
3562+let CORREL = function (dataY, dataX) : number {
3563   ArgsChecker.checkLength(arguments, 2, "CORREL");
3564   if (!Array.isArray(dataY)) {
3565     dataY = [dataY];
3566@@ -223,10 +223,10 @@ var CORREL = function (dataY, dataX) : number {
3567   if (dataY.length !== dataX.length) {
3568     throw new NAError("CORREL has mismatched argument count " + dataY + " vs " + dataX + ".");
3569   }
3570-  var arr1 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(dataY));
3571-  var arr2 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(dataX));
3572-  var stdevArr1 = stdev(arr1, 1);
3573-  var stdevArr2 = stdev(arr2, 1);
3574+  let arr1 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(dataY));
3575+  let arr2 = Filter.filterOutNonNumberValues(Filter.flattenAndThrow(dataX));
3576+  let stdevArr1 = stdev(arr1, 1);
3577+  let stdevArr2 = stdev(arr2, 1);
3578   if (stdevArr1 === 0 || stdevArr2 === 0) {
3579     throw new DivZeroError("Evaluation of function CORREL caused a divide by zero error.");
3580   }
3581@@ -241,7 +241,7 @@ var CORREL = function (dataY, dataX) : number {
3582  * @returns {number} the Pearson product-moment correlation coefficient.
3583  * @constructor
3584  */
3585-var PEARSON = function (dataY, dataX) {
3586+let PEARSON = function (dataY, dataX) {
3587   ArgsChecker.checkLength(arguments, 2, "PEARSON");
3588   return CORREL.apply(this, [dataY, dataX]);
3589 };
3590@@ -255,7 +255,7 @@ var PEARSON = function (dataY, dataX) {
3591  * @returns {number} value of the exponential distribution function.
3592  * @constructor
3593  */
3594-var EXPONDIST = function (x, lambda, cumulative) : number {
3595+let EXPONDIST = function (x, lambda, cumulative) : number {
3596   ArgsChecker.checkLength(arguments, 3, "EXPONDIST");
3597   function cdf(x, rate) {
3598     return x < 0 ? 0 : 1 - Math.exp(-rate * x);
3599@@ -284,16 +284,16 @@ var EXPONDIST = function (x, lambda, cumulative) : number {
3600  * @constructor
3601  * TODO: This function should be stricter in its return type.
3602  */
3603-var FDIST$LEFTTAILED = function (x, degreesFreedom1, degreesFreedom2, cumulative) : number|undefined|boolean {
3604+let FDIST$LEFTTAILED = function (x, degreesFreedom1, degreesFreedom2, cumulative) : number|undefined|boolean {
3605   ArgsChecker.checkLength(arguments, 4, "FDIST$LEFTTAILED");
3606 
3607   x = TypeConverter.firstValueAsNumber(x);
3608   if (x < 0) {
3609     throw new NumError("Function F.DIST parameter 1 value is " + x + ". It should be greater than or equal to 0.");
3610   }
3611-  var d1 = TypeConverter.firstValueAsNumber(degreesFreedom1);
3612-  var d2 = TypeConverter.firstValueAsNumber(degreesFreedom2);
3613-  var cum = TypeConverter.firstValueAsBoolean(cumulative);
3614+  let d1 = TypeConverter.firstValueAsNumber(degreesFreedom1);
3615+  let d2 = TypeConverter.firstValueAsNumber(degreesFreedom2);
3616+  let cum = TypeConverter.firstValueAsBoolean(cumulative);
3617   return (cum) ? cdf(x, d1, d2) : pdf(x, d1, d2);
3618 };
3619 
3620@@ -307,7 +307,7 @@ var FDIST$LEFTTAILED = function (x, degreesFreedom1, degreesFreedom2, cumulative
3621  * @returns {number} inverse of the (right-tailed) F probability distribution
3622  * @constructor
3623  */
3624-var FINV = function (probability, degFreedom1, degFreedom2) : number {
3625+let FINV = function (probability, degFreedom1, degFreedom2) : number {
3626   ArgsChecker.checkLength(arguments, 3, "FINV");
3627 
3628   probability = TypeConverter.firstValueAsNumber(probability);
3629@@ -315,8 +315,8 @@ var FINV = function (probability, degFreedom1, degFreedom2) : number {
3630     throw new NumError("Function FINV parameter 1 value is " + probability
3631       + ". It should be greater than or equal to 0, and less than 1.")
3632   }
3633-  var d1 = TypeConverter.firstValueAsNumber(degFreedom1);
3634-  var d2 = TypeConverter.firstValueAsNumber(degFreedom2);
3635+  let d1 = TypeConverter.firstValueAsNumber(degFreedom1);
3636+  let d2 = TypeConverter.firstValueAsNumber(degFreedom2);
3637   return inv(1.0 - probability, d1, d2);
3638 };
3639 
3640@@ -326,9 +326,9 @@ var FINV = function (probability, degFreedom1, degFreedom2) : number {
3641  * @returns {number} Fisher transformation
3642  * @constructor
3643  */
3644-var FISHER = function (value) : number {
3645+let FISHER = function (value) : number {
3646   ArgsChecker.checkLength(arguments, 1, "FISHER");
3647-  var x = TypeConverter.firstValueAsNumber(value);
3648+  let x = TypeConverter.firstValueAsNumber(value);
3649   if (x <= -1 || x >= 1) {
3650     throw new NumError("Function FISHER parameter 1 value is " + x + ". Valid values are between -1 and 1 exclusive.");
3651   }
3652@@ -341,10 +341,10 @@ var FISHER = function (value) : number {
3653  * @returns {number} inverse Fisher transformation
3654  * @constructor
3655  */
3656-var FISHERINV = function (value) : number {
3657+let FISHERINV = function (value) : number {
3658   ArgsChecker.checkLength(arguments, 1, "FISHERINV");
3659-  var y = TypeConverter.firstValueAsNumber(value);
3660-  var e2y = Math.exp(2 * y);
3661+  let y = TypeConverter.firstValueAsNumber(value);
3662+  let e2y = Math.exp(2 * y);
3663   return (e2y - 1) / (e2y + 1);
3664 };
3665 
3666@@ -354,15 +354,15 @@ var FISHERINV = function (value) : number {
3667  * @returns {number} the maximum value of the dataset
3668  * @constructor
3669  */
3670-var MAX = function (...values) {
3671+let MAX = function (...values) {
3672   ArgsChecker.checkAtLeastLength(values, 1, "MAX");
3673-  var maxSoFar = -Infinity;
3674-  for (var i = 0; i < values.length; i++) {
3675+  let maxSoFar = -Infinity;
3676+  for (let i = 0; i < values.length; i++) {
3677     if (values[i] instanceof Array) {
3678       if (values[i].length === 0) {
3679         throw new RefError("Reference does not exist.");
3680       }
3681-      var filtered = Filter.filterOutStringValues(values[i]);
3682+      let filtered = Filter.filterOutStringValues(values[i]);
3683       if (filtered.length !== 0) {
3684         maxSoFar = Math.max(MAX.apply(this, filtered), maxSoFar);
3685       }
3686@@ -379,16 +379,16 @@ var MAX = function (...values) {
3687  * @returns {number} maximum value of the dataset
3688  * @constructor
3689  */
3690-var MAXA = function (...values) : number {
3691+let MAXA = function (...values) : number {
3692   ArgsChecker.checkAtLeastLength(values, 1, "MAXA");
3693-  var maxSoFar = -Infinity;
3694-  var filteredValues = Filter.stringValuesToZeros(values);
3695-  for (var i = 0; i < filteredValues.length; i++) {
3696+  let maxSoFar = -Infinity;
3697+  let filteredValues = Filter.stringValuesToZeros(values);
3698+  for (let i = 0; i < filteredValues.length; i++) {
3699     if (filteredValues[i] instanceof Array) {
3700       if (values[i].length === 0) {
3701         throw new RefError("Reference does not exist.");
3702       }
3703-      var filtered = Filter.stringValuesToZeros(filteredValues[i]);
3704+      let filtered = Filter.stringValuesToZeros(filteredValues[i]);
3705       if (filtered.length !== 0) {
3706         maxSoFar = Math.max(MAXA.apply(this, filtered), maxSoFar);
3707       }
3708@@ -406,15 +406,15 @@ var MAXA = function (...values) : number {
3709  * @returns {number} the minimum value of the dataset
3710  * @constructor
3711  */
3712-var MIN = function (...values) {
3713+let MIN = function (...values) {
3714   ArgsChecker.checkAtLeastLength(values, 1, "MIN");
3715-  var minSoFar = Infinity;
3716-  for (var i = 0; i < values.length; i++) {
3717+  let minSoFar = Infinity;
3718+  for (let i = 0; i < values.length; i++) {
3719     if (values[i] instanceof Array) {
3720       if (values[i].length === 0) {
3721         throw new RefError("Reference does not exist.");
3722       }
3723-      var filtered = Filter.filterOutStringValues(values[i]);
3724+      let filtered = Filter.filterOutStringValues(values[i]);
3725       if (filtered.length !== 0) {
3726         minSoFar = Math.min(MIN.apply(this, filtered), minSoFar);
3727       }
3728@@ -432,7 +432,7 @@ var MIN = function (...values) {
3729  * @returns {number} the minimum value in the dataset
3730  * @constructor
3731  */
3732-var MINA = function (...values) : number {
3733+let MINA = function (...values) : number {
3734   ArgsChecker.checkAtLeastLength(values, 1, "MINA");
3735   return MIN.apply(this, values);
3736 };
3737@@ -448,15 +448,15 @@ var MINA = function (...values) : number {
3738  * @constructor
3739  * TODO: This needs to also accept a third parameter "average_range"
3740  */
3741-var AVERAGEIF = function (criteriaRange, criterion, averageRange?) {
3742+let AVERAGEIF = function (criteriaRange, criterion, averageRange?) {
3743   ArgsChecker.checkLength(arguments, 2, "AVERAGEIF");
3744-  var range = Filter.flatten(criteriaRange);
3745-  var criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criterion);
3746+  let range = Filter.flatten(criteriaRange);
3747+  let criteriaEvaluation = CriteriaFunctionFactory.createCriteriaFunction(criterion);
3748 
3749-  var result = 0;
3750-  var count = 0;
3751-  for (var i = 0; i < range.length; i++) {
3752-    var val = TypeConverter.valueToNumber(range[i]);
3753+  let result = 0;
3754+  let count = 0;
3755+  for (let i = 0; i < range.length; i++) {
3756+    let val = TypeConverter.valueToNumber(range[i]);
3757     if (criteriaEvaluation(val)) {
3758       result = result + val;
3759       count++;
3760@@ -475,10 +475,10 @@ var AVERAGEIF = function (criteriaRange, criterion, averageRange?) {
3761  * @returns {number} number of numeric values in a dataset.
3762  * @constructor
3763  */
3764-var COUNT = function (...values) : number {
3765+let COUNT = function (...values) : number {
3766   ArgsChecker.checkAtLeastLength(values, 1, "COUNT");
3767-  var count = 0;
3768-  for (var i = 0; i < values.length; i++) {
3769+  let count = 0;
3770+  for (let i = 0; i < values.length; i++) {
3771     if (values[i] instanceof Array) {
3772       if (values[i].length > 0) {
3773         count += COUNT.apply(this, values[i]);
3774@@ -496,10 +496,10 @@ var COUNT = function (...values) : number {
3775  * @returns {number} number of values in a dataset.
3776  * @constructor
3777  */
3778-var COUNTA = function (...values) : number {
3779+let COUNTA = function (...values) : number {
3780   ArgsChecker.checkAtLeastLength(values, 1, "COUNTA");
3781-  var count = 0;
3782-  for (var i = 0; i < values.length; i++) {
3783+  let count = 0;
3784+  for (let i = 0; i < values.length; i++) {
3785     if (values[i] instanceof Array) {
3786       if (values[i].length > 0) {
3787         count += COUNTA.apply(this, values[i]);
3788@@ -521,21 +521,21 @@ var COUNTA = function (...values) : number {
3789  * @returns {number}
3790  * @constructor
3791  */
3792-var PERCENTILE =  function (data, percent) {
3793+let PERCENTILE =  function (data, percent) {
3794   ArgsChecker.checkLength(arguments, 2, "PERCENTILE");
3795-  var p = TypeConverter.firstValueAsNumber(percent);
3796+  let p = TypeConverter.firstValueAsNumber(percent);
3797   if (p < 0 || p > 1) {
3798     throw new NumError("Function PERCENTILE parameter 2 value " + p + " is out of range.");
3799   }
3800-  var range = Filter.flattenAndThrow(data).sort(function (a, b) {
3801+  let range = Filter.flattenAndThrow(data).sort(function (a, b) {
3802     return a - b;
3803   }).map(function (value) {
3804     return TypeConverter.valueToNumber(value);
3805   });
3806 
3807-  var n = range.length;
3808-  var l = p * (n - 1);
3809-  var fl = Math.floor(l);
3810+  let n = range.length;
3811+  let l = p * (n - 1);
3812+  let fl = Math.floor(l);
3813   return cleanFloat((l === fl) ? range[l] : range[fl] + (l - fl) * (range[fl + 1] - range[fl]));
3814 };
3815 
3816@@ -547,15 +547,15 @@ var PERCENTILE =  function (data, percent) {
3817  * percent mark, 3 returns 75 percent mark, 4 returns 100 percent mark.
3818  * @constructor
3819  */
3820-var QUARTILE = function (data, quartile) {
3821+let QUARTILE = function (data, quartile) {
3822   ArgsChecker.checkLength(arguments, 2, "QUARTILE");
3823-  var q = TypeConverter.firstValueAsNumber(quartile);
3824+  let q = TypeConverter.firstValueAsNumber(quartile);
3825   if (q < 0 || q > 4) {
3826     throw new NumError("Function QUARTILE parameter 2 value " + q + " is out of range.");
3827   }
3828 
3829 
3830-  var range = Filter.flattenAndThrow(data).sort(function (a, b) {
3831+  let range = Filter.flattenAndThrow(data).sort(function (a, b) {
3832     return a - b;
3833   }).map(function (value) {
3834     return TypeConverter.valueToNumber(value);
3835@@ -583,15 +583,15 @@ var QUARTILE = function (data, quartile) {
3836  * @returns {number}
3837  * @constructor
3838  */
3839-var STDEV = function (...values) {
3840+let STDEV = function (...values) {
3841   ArgsChecker.checkAtLeastLength(arguments, 1, "STDEV");
3842-  var range = Filter.flattenAndThrow(values);
3843-  var n = range.length;
3844-  var sigma = 0;
3845-  var count = 0;
3846-  var mean = AVERAGE(range);
3847-  for (var i = 0; i < n; i++) {
3848-    var value = TypeConverter.firstValue(range[i]);
3849+  let range = Filter.flattenAndThrow(values);
3850+  let n = range.length;
3851+  let sigma = 0;
3852+  let count = 0;
3853+  let mean = AVERAGE(range);
3854+  for (let i = 0; i < n; i++) {
3855+    let value = TypeConverter.firstValue(range[i]);
3856     if (typeof value !== "string") {
3857       sigma += Math.pow(TypeConverter.valueToNumber(value) - mean, 2);
3858       count++;
3859@@ -608,15 +608,15 @@ var STDEV = function (...values) {
3860  * @returns {number}
3861  * @constructor
3862  */
3863-var STDEVA = function (...values) {
3864+let STDEVA = function (...values) {
3865   ArgsChecker.checkAtLeastLength(arguments, 1, "STDEVA");
3866-  var range = Filter.flattenAndThrow(values).map(function (value) {
3867+  let range = Filter.flattenAndThrow(values).map(function (value) {
3868     return TypeConverter.firstValueAsNumber(value);
3869   });
3870-  var n = range.length;
3871-  var sigma = 0;
3872-  var m = mean(range);
3873-  for (var i = 0; i < n; i++) {
3874+  let n = range.length;
3875+  let sigma = 0;
3876+  let m = mean(range);
3877+  for (let i = 0; i < n; i++) {
3878     sigma += Math.pow(range[i] - m, 2);
3879   }
3880   return Math.sqrt(sigma / (n - 1));
3881@@ -630,15 +630,15 @@ var STDEVA = function (...values) {
3882  * @returns {number}
3883  * @constructor
3884  */
3885-var STDEVP = function (...values) {
3886+let STDEVP = function (...values) {
3887   ArgsChecker.checkAtLeastLength(arguments, 1, "STDEVP");
3888-  var range = Filter.flattenAndThrow(values);
3889-  var n = range.length;
3890-  var sigma = 0;
3891-  var count = 0;
3892-  var m = AVERAGE(range);
3893-  for (var i = 0; i < n; i++) {
3894-    var value = TypeConverter.firstValue(range[i]);
3895+  let range = Filter.flattenAndThrow(values);
3896+  let n = range.length;
3897+  let sigma = 0;
3898+  let count = 0;
3899+  let m = AVERAGE(range);
3900+  for (let i = 0; i < n; i++) {
3901+    let value = TypeConverter.firstValue(range[i]);
3902     if (typeof value !== "string") {
3903       sigma += Math.pow(value - m, 2);
3904       count++;
3905@@ -655,17 +655,17 @@ var STDEVP = function (...values) {
3906  * @returns {number}
3907  * @constructor
3908  */
3909-var STDEVPA = function (...values) {
3910+let STDEVPA = function (...values) {
3911   ArgsChecker.checkAtLeastLength(arguments, 1, "STDEVPA");
3912-  var range = Filter.flattenAndThrow(values).map(function (value) {
3913+  let range = Filter.flattenAndThrow(values).map(function (value) {
3914     return TypeConverter.firstValueAsNumber(value);
3915   });
3916-  var n = range.length;
3917-  var sigma = 0;
3918-  var count = 0;
3919-  var m = AVERAGE(range);
3920-  for (var i = 0; i < n; i++) {
3921-    var value = TypeConverter.firstValue(range[i]);
3922+  let n = range.length;
3923+  let sigma = 0;
3924+  let count = 0;
3925+  let m = AVERAGE(range);
3926+  for (let i = 0; i < n; i++) {
3927+    let value = TypeConverter.firstValue(range[i]);
3928     if (typeof value !== "string") {
3929       sigma += Math.pow(value - m, 2);
3930       count++;
3931@@ -682,16 +682,16 @@ var STDEVPA = function (...values) {
3932  * @returns {number}
3933  * @constructor
3934  */
3935-var TRIMMEAN = function (range, percent) {
3936+let TRIMMEAN = function (range, percent) {
3937   ArgsChecker.checkLength(arguments, 2, "TRIMMEAN");
3938-  var p = TypeConverter.firstValueAsNumber(percent);
3939+  let p = TypeConverter.firstValueAsNumber(percent);
3940   if (p < 0) {
3941     throw new NumError("Function TRIMMEAN parameter 2 value is " + p + ". It should be greater than or equal to 0.");
3942   }
3943   if (p >= 1) {
3944     throw new NumError("Function TRIMMEAN parameter 2 value is " + p + ". It should be less than 1.");
3945   }
3946-  var data = Filter.flattenAndThrow(range).sort(function (a, b) {
3947+  let data = Filter.flattenAndThrow(range).sort(function (a, b) {
3948     return a - b;
3949   }).map(function (value) {
3950     return TypeConverter.valueToNumber(value);
3951@@ -701,8 +701,8 @@ var TRIMMEAN = function (range, percent) {
3952     throw new RefError("TRIMMEAN has no valid input data.");
3953   }
3954 
3955-  var trim = FLOOR(data.length * p, 2) / 2;
3956-  var tmp = data.slice(trim, data.length);
3957+  let trim = FLOOR(data.length * p, 2) / 2;
3958+  let tmp = data.slice(trim, data.length);
3959   return mean(tmp.slice(0, tmp.length - trim));
3960 };
3961 
3962@@ -713,14 +713,14 @@ var TRIMMEAN = function (range, percent) {
3963  * @param rangeX - The range or array representing the independent data.
3964  * @constructor
3965  */
3966-var SLOPE = function (rangeY, rangeX) {
3967+let SLOPE = function (rangeY, rangeX) {
3968   ArgsChecker.checkLength(arguments, 2, "SLOPE");
3969-  var dataX = Filter.flattenAndThrow(rangeX).filter(function (value) {
3970+  let dataX = Filter.flattenAndThrow(rangeX).filter(function (value) {
3971     return typeof value !== "string";
3972   }).map(function (value) {
3973     return TypeConverter.valueToNumber(value);
3974   });
3975-  var dataY = Filter.flattenAndThrow(rangeY).filter(function (value) {
3976+  let dataY = Filter.flattenAndThrow(rangeY).filter(function (value) {
3977     return typeof value !== "string";
3978   }).map(function (value) {
3979     return TypeConverter.valueToNumber(value);
3980@@ -728,12 +728,12 @@ var SLOPE = function (rangeY, rangeX) {
3981   if (dataX.length !== dataY.length) {
3982     throw new NAError("SLOPE has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
3983   }
3984-  var xmean = mean(dataX);
3985-  var ymean = mean(dataY);
3986-  var n = dataX.length;
3987-  var num = 0;
3988-  var den = 0;
3989-  for (var i = 0; i < n; i++) {
3990+  let xmean = mean(dataX);
3991+  let ymean = mean(dataY);
3992+  let n = dataX.length;
3993+  let num = 0;
3994+  let den = 0;
3995+  for (let i = 0; i < n; i++) {
3996     num += (dataX[i] - xmean) * (dataY[i] - ymean);
3997     den += Math.pow(dataX[i] - xmean, 2);
3998   }
3999@@ -752,7 +752,7 @@ var SLOPE = function (rangeY, rangeX) {
4000  * @returns {number}
4001  * @constructor
4002  */
4003-var STANDARDIZE = function (value, meanValue, std) {
4004+let STANDARDIZE = function (value, meanValue, std) {
4005   ArgsChecker.checkLength(arguments, 3, "STANDARDIZE");
4006   value = TypeConverter.firstValueAsNumber(value);
4007   meanValue = TypeConverter.firstValueAsNumber(meanValue);
4008@@ -770,9 +770,9 @@ var STANDARDIZE = function (value, meanValue, std) {
4009  * @param n - N in 'Nth'.
4010  * @constructor
4011  */
4012-var SMALL =  function (range, n) {
4013+let SMALL =  function (range, n) {
4014   ArgsChecker.checkLength(arguments, 2, "SMALL");
4015-  var data = Filter.flattenAndThrow(range).filter(function (value) {
4016+  let data = Filter.flattenAndThrow(range).filter(function (value) {
4017     return typeof value != "string";
4018   }).map(function (value) {
4019     return TypeConverter.valueToNumber(value);
4020@@ -792,9 +792,9 @@ var SMALL =  function (range, n) {
4021  * @param n - N in 'Nth'.
4022  * @constructor
4023  */
4024-var LARGE =  function (range, n) {
4025+let LARGE =  function (range, n) {
4026   ArgsChecker.checkLength(arguments, 2, "LARGE");
4027-  var data = Filter.flattenAndThrow(range).filter(function (value) {
4028+  let data = Filter.flattenAndThrow(range).filter(function (value) {
4029     return typeof value != "string";
4030   }).map(function (value) {
4031     return TypeConverter.valueToNumber(value);
4032@@ -814,9 +814,9 @@ var LARGE =  function (range, n) {
4033  * @returns {number}
4034  * @constructor
4035  */
4036-var KURT = function (...values) {
4037+let KURT = function (...values) {
4038   ArgsChecker.checkAtLeastLength(values, 4, "KURT");
4039-  var range = Filter.flattenAndThrow(values).filter(function (value) {
4040+  let range = Filter.flattenAndThrow(values).filter(function (value) {
4041     return typeof value !== "string";
4042   }).map(function (value) {
4043     return TypeConverter.valueToNumber(value);
4044@@ -824,10 +824,10 @@ var KURT = function (...values) {
4045   if (range.length < 4) {
4046     throw new DivZeroError("KURT requires more values in range. Expected: 4, found: " + range.length + ".");
4047   }
4048-  var m = mean(range);
4049-  var n = range.length;
4050-  var sigma = 0;
4051-  for (var i = 0; i < n; i++) {
4052+  let m = mean(range);
4053+  let n = range.length;
4054+  let sigma = 0;
4055+  for (let i = 0; i < n; i++) {
4056     sigma += Math.pow(range[i] - m, 4);
4057   }
4058   sigma = sigma / Math.pow(stdev(range, true), 4);
4059@@ -843,14 +843,14 @@ var KURT = function (...values) {
4060  * @returns {number}
4061  * @constructor
4062  */
4063-var INTERCEPT = function (rangeY, rangeX) {
4064+let INTERCEPT = function (rangeY, rangeX) {
4065   ArgsChecker.checkLength(arguments, 2, "INTERCEPT");
4066-  var dataX = Filter.flattenAndThrow(rangeX).filter(function (value) {
4067+  let dataX = Filter.flattenAndThrow(rangeX).filter(function (value) {
4068     return typeof value !== "string";
4069   }).map(function (value) {
4070     return TypeConverter.valueToNumber(value);
4071   });
4072-  var dataY = Filter.flattenAndThrow(rangeY).filter(function (value) {
4073+  let dataY = Filter.flattenAndThrow(rangeY).filter(function (value) {
4074     return typeof value !== "string";
4075   }).map(function (value) {
4076     return TypeConverter.valueToNumber(value);
4077@@ -860,19 +860,19 @@ var INTERCEPT = function (rangeY, rangeX) {
4078     throw new NAError("INTERCEPT has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
4079   }
4080 
4081-  var xMean = mean(dataX);
4082-  var yMean = mean(dataY);
4083-  var n = dataX.length;
4084-  var num = 0;
4085-  var den = 0;
4086-  for (var i = 0; i < n; i++) {
4087+  let xMean = mean(dataX);
4088+  let yMean = mean(dataY);
4089+  let n = dataX.length;
4090+  let num = 0;
4091+  let den = 0;
4092+  for (let i = 0; i < n; i++) {
4093     num += (dataX[i] - xMean) * (dataY[i] - yMean);
4094     den += Math.pow(dataX[i] - xMean, 2);
4095   }
4096   if (den === 0) {
4097     throw new DivZeroError("Evaluation of function INTERCEPT caused a divide by zero error.");
4098   }
4099-  var b = num / den;
4100+  let b = num / den;
4101   return yMean - b * xMean;
4102 };
4103 
4104@@ -887,15 +887,15 @@ var INTERCEPT = function (rangeY, rangeX) {
4105  * TODO: This formula will fail to parse since the first argument is followed by an argument that is an array.
4106  * TODO (continued) This is a known issue.
4107  */
4108-var FORECAST = function (x, rangeY, rangeX) {
4109+let FORECAST = function (x, rangeY, rangeX) {
4110   ArgsChecker.checkLength(arguments, 3, "FORECAST");
4111   x =  TypeConverter.firstValueAsNumber(x);
4112-  var dataX = Filter.flattenAndThrow(rangeX).filter(function (value) {
4113+  let dataX = Filter.flattenAndThrow(rangeX).filter(function (value) {
4114     return typeof value !== "string";
4115   }).map(function (value) {
4116     return TypeConverter.valueToNumber(value);
4117   });
4118-  var dataY = Filter.flattenAndThrow(rangeY).filter(function (value) {
4119+  let dataY = Filter.flattenAndThrow(rangeY).filter(function (value) {
4120     return typeof value !== "string";
4121   }).map(function (value) {
4122     return TypeConverter.valueToNumber(value);
4123@@ -905,20 +905,20 @@ var FORECAST = function (x, rangeY, rangeX) {
4124     throw new NAError("FORECAST has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
4125   }
4126 
4127-  var xMean = mean(dataX);
4128-  var yMean = mean(dataY);
4129-  var n = dataX.length;
4130-  var num = 0;
4131-  var den = 0;
4132-  for (var i = 0; i < n; i++) {
4133+  let xMean = mean(dataX);
4134+  let yMean = mean(dataY);
4135+  let n = dataX.length;
4136+  let num = 0;
4137+  let den = 0;
4138+  for (let i = 0; i < n; i++) {
4139     num += (dataX[i] - xMean) * (dataY[i] - yMean);
4140     den += Math.pow(dataX[i] - xMean, 2);
4141   }
4142   if (den === 0) {
4143     throw new DivZeroError("Evaluation of function FORECAST caused a divide by zero error.");
4144   }
4145-  var b = num / den;
4146-  var a = yMean - b * xMean;
4147+  let b = num / den;
4148+  let a = yMean - b * xMean;
4149   return a + b * x;
4150 };
4151 
4152@@ -931,7 +931,7 @@ var FORECAST = function (x, rangeY, rangeX) {
4153  * @returns {number}
4154  * @constructor
4155  */
4156-var POISSON = function (x, meanValue, cumulative?) {
4157+let POISSON = function (x, meanValue, cumulative?) {
4158   ArgsChecker.checkLengthWithin(arguments, 2, 3, "POISSON");
4159   x = TypeConverter.firstValueAsNumber(x);
4160   meanValue = TypeConverter.firstValueAsNumber(meanValue);
4161@@ -951,7 +951,7 @@ var POISSON = function (x, meanValue, cumulative?) {
4162     return Math.pow(l, k) * Math.exp(-l) / factorial(k);
4163   }
4164   function poissonCDF(x, l) {
4165-    var sumarr = [],
4166+    let sumarr = [],
4167       k = 0;
4168     if (x < 0) return 0;
4169     for (; k <= x; k++) {
4170@@ -972,15 +972,15 @@ var POISSON = function (x, meanValue, cumulative?) {
4171  * @returns {number}
4172  * @constructor
4173  */
4174-var PERCENTRANK = function (data, x, significance?) {
4175+let PERCENTRANK = function (data, x, significance?) {
4176   ArgsChecker.checkLengthWithin(arguments, 2, 3, "PERCENTRANK");
4177   data = Filter.flattenAndThrow(data).map(TypeConverter.valueToNumber).sort(function (a, b) {
4178     return a - b;
4179   });
4180   x = TypeConverter.firstValueAsNumber(x);
4181-  var uniques = Filter.unique(data);
4182-  var n = data.length;
4183-  var m = uniques.length;
4184+  let uniques = Filter.unique(data);
4185+  let n = data.length;
4186+  let m = uniques.length;
4187   if (x < uniques[0] || x > uniques[m - 1]) {
4188     throw new NAError("PERCENTRANK does not have valid input data.");
4189   }
4190@@ -988,10 +988,10 @@ var PERCENTRANK = function (data, x, significance?) {
4191     return 1;
4192   }
4193   significance = (typeof significance === 'undefined') ? 3 : TypeConverter.firstValueAsNumber(significance);
4194-  var power = Math.pow(10, significance);
4195-  var result = 0;
4196-  var match = false;
4197-  var i = 0;
4198+  let power = Math.pow(10, significance);
4199+  let result = 0;
4200+  let match = false;
4201+  let i = 0;
4202   while (!match && i < m) {
4203     if (x === uniques[i]) {
4204       result = data.indexOf(uniques[i]) / (n - 1);
4205@@ -1002,7 +1002,7 @@ var PERCENTRANK = function (data, x, significance?) {
4206     }
4207     i++;
4208   }
4209-  var v = Math.floor(result * power) / power;
4210+  let v = Math.floor(result * power) / power;
4211   if (isNaN(v)) {
4212     throw new NAError("PERCENTRANK does not have valid input data.");
4213   }
4214@@ -1018,15 +1018,15 @@ var PERCENTRANK = function (data, x, significance?) {
4215  * @returns {number}
4216  * @constructor
4217  */
4218-var PERCENTRANK$EXC = function (data, x, significance?) {
4219+let PERCENTRANK$EXC = function (data, x, significance?) {
4220   ArgsChecker.checkLengthWithin(arguments, 2, 3, "PERCENTRANK.EXC");
4221   data = Filter.flattenAndThrow(data).map(TypeConverter.valueToNumber).sort(function (a, b) {
4222     return a - b;
4223   });
4224   x = TypeConverter.firstValueAsNumber(x);
4225-  var uniques = Filter.unique(data);
4226-  var n = data.length;
4227-  var m = uniques.length;
4228+  let uniques = Filter.unique(data);
4229+  let n = data.length;
4230+  let m = uniques.length;
4231   if (x < uniques[0] || x > uniques[m - 1]) {
4232     throw new NAError("PERCENTRANK.EXC does not have valid input data.");
4233   }
4234@@ -1034,10 +1034,10 @@ var PERCENTRANK$EXC = function (data, x, significance?) {
4235     return 1;
4236   }
4237   significance = (typeof significance === 'undefined') ? 3 : TypeConverter.firstValueAsNumber(significance);
4238-  var power = Math.pow(10, significance);
4239-  var result = 0;
4240-  var match = false;
4241-  var i = 0;
4242+  let power = Math.pow(10, significance);
4243+  let result = 0;
4244+  let match = false;
4245+  let i = 0;
4246   while (!match && i < m) {
4247     if (x === uniques[i]) {
4248       result = (data.indexOf(uniques[i]) + 1) / (n + 1);
4249@@ -1048,7 +1048,7 @@ var PERCENTRANK$EXC = function (data, x, significance?) {
4250     }
4251     i++;
4252   }
4253-  var v = Math.floor(result * power) / power;
4254+  let v = Math.floor(result * power) / power;
4255   if (isNaN(v)) {
4256     throw new NAError("PERCENTRANK.EXC does not have valid input data.");
4257   }
4258@@ -1062,15 +1062,15 @@ var PERCENTRANK$EXC = function (data, x, significance?) {
4259  * @returns {number}
4260  * @constructor
4261  */
4262-var NORMSINV = function (probability) {
4263+let NORMSINV = function (probability) {
4264   ArgsChecker.checkLength(arguments, 1, "NORMSINV");
4265   probability =  TypeConverter.firstValueAsNumber(probability);
4266   function erfc(x) {
4267     return 1 - erf(x);
4268   }
4269   function erfcinv(p) {
4270-    var j = 0;
4271-    var x, err, t, pp;
4272+    let j = 0;
4273+    let x, err, t, pp;
4274     if (p >= 2)
4275       return -100;
4276     if (p <= 0)
4277@@ -1111,7 +1111,7 @@ function _pdf(x, meanVal, std) {
4278  * @returns {number}
4279  * @constructor
4280  */
4281-var NORMSDIST = function (z) {
4282+let NORMSDIST = function (z) {
4283   ArgsChecker.checkLength(arguments, 1, "NORMSDIST");
4284   z = TypeConverter.firstValueAsNumber(z);
4285   return _cdf(z, 0, 1);
4286@@ -1127,7 +1127,7 @@ var NORMSDIST = function (z) {
4287  * @returns {number}
4288  * @constructor
4289  */
4290-var NORMDIST =  function (x, meanValue, standDev, cumulative) {
4291+let NORMDIST =  function (x, meanValue, standDev, cumulative) {
4292   ArgsChecker.checkLength(arguments, 4, "NORMDIST");
4293   x = TypeConverter.firstValueAsNumber(x);
4294   meanValue = TypeConverter.firstValueAsNumber(meanValue);
4295@@ -1147,10 +1147,10 @@ var NORMDIST =  function (x, meanValue, standDev, cumulative) {
4296  * @returns {number}
4297  * @constructor
4298  */
4299-var NORMINV = function (probability, meanVal, standDev) {
4300+let NORMINV = function (probability, meanVal, standDev) {
4301   ArgsChecker.checkLength(arguments, 3, "NORMINV");
4302   function erf(x) {
4303-    var cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,
4304+    let cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,
4305       -9.561514786808631e-3, -9.46595344482036e-4, 3.66839497852761e-4,
4306       4.2523324806907e-5, -2.0278578112534e-5, -1.624290004647e-6,
4307       1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8,
4308@@ -1160,11 +1160,11 @@ var NORMINV = function (probability, meanVal, standDev) {
4309       -1.12708e-13, 3.81e-16, 7.106e-15,
4310       -1.523e-15, -9.4e-17, 1.21e-16,
4311       -2.8e-17];
4312-    var j = cof.length - 1;
4313-    var isneg = false;
4314-    var d = 0;
4315-    var dd = 0;
4316-    var t, ty, tmp, res;
4317+    let j = cof.length - 1;
4318+    let isneg = false;
4319+    let d = 0;
4320+    let dd = 0;
4321+    let t, ty, tmp, res;
4322 
4323     if (x < 0) {
4324       x = -x;
4325@@ -1187,8 +1187,8 @@ var NORMINV = function (probability, meanVal, standDev) {
4326     return 1 - erf(x);
4327   }
4328   function erfcinv(p) {
4329-    var j = 0;
4330-    var x, err, t, pp;
4331+    let j = 0;
4332+    let x, err, t, pp;
4333     if (p >= 2)
4334       return -100;
4335     if (p <= 0)
4336@@ -1228,16 +1228,16 @@ var NORMINV = function (probability, meanVal, standDev) {
4337  * @returns {number}
4338  * @constructor
4339  */
4340-var NEGBINOMDIST = function (k, r, p) {
4341+let NEGBINOMDIST = function (k, r, p) {
4342   ArgsChecker.checkLength(arguments, 3, "NEGBINOMDIST");
4343   function _gammaln(x) {
4344-    var j = 0;
4345-    var cof = [
4346+    let j = 0;
4347+    let cof = [
4348       76.18009172947146, -86.50532032941677, 24.01409824083091,
4349       -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5
4350     ];
4351-    var ser = 1.000000000190015;
4352-    var xx, y, tmp;
4353+    let ser = 1.000000000190015;
4354+    let xx, y, tmp;
4355     tmp = (y = xx = x) + 5.5;
4356     tmp -= (xx + 0.5) * Math.log(tmp);
4357     for (; j < 6; j++)
4358@@ -1288,11 +1288,11 @@ var NEGBINOMDIST = function (k, r, p) {
4359  * @returns {number}
4360  * @constructor
4361  */
4362-var GEOMEAN  = function (...values) {
4363+let GEOMEAN  = function (...values) {
4364   ArgsChecker.checkAtLeastLength(arguments, 1, "GEOMEAN");
4365   function _product(arr) {
4366-    var prod = 1;
4367-    var i = arr.length;
4368+    let prod = 1;
4369+    let i = arr.length;
4370     while (--i >= 0) {
4371       prod *= arr[i];
4372     }
4373@@ -1314,17 +1314,17 @@ var GEOMEAN  = function (...values) {
4374  * @returns {number}
4375  * @constructor
4376  */
4377-var HARMEAN = function (...values) {
4378+let HARMEAN = function (...values) {
4379   ArgsChecker.checkAtLeastLength(arguments, 1, "HARMEAN");
4380-  var range = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber).map(function (value) {
4381+  let range = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber).map(function (value) {
4382     if (value <=0) {
4383       throw new NumError("HARMEAN requires inputs greater than 0, but one of the values entered is " + value + ".");
4384     }
4385     return value;
4386   });
4387-  var n = range.length;
4388-  var den = 0;
4389-  for (var i = 0; i < n; i++) {
4390+  let n = range.length;
4391+  let den = 0;
4392+  for (let i = 0; i < n; i++) {
4393     den += 1 / range[i];
4394   }
4395   return n / den;
4396@@ -1339,7 +1339,7 @@ var HARMEAN = function (...values) {
4397  * @returns {number}
4398  * @constructor
4399  */
4400-var CONFIDENCE = function (alpha, standDev, size) {
4401+let CONFIDENCE = function (alpha, standDev, size) {
4402   ArgsChecker.checkLength(arguments, 3, "CONFIDENCE");
4403   alpha = TypeConverter.firstValueAsNumber(alpha);
4404   standDev = TypeConverter.firstValueAsNumber(standDev);
4405@@ -1358,8 +1358,8 @@ var CONFIDENCE = function (alpha, standDev, size) {
4406     return 1 - erf(x);
4407   }
4408   function _erfcinv(p) {
4409-    var j = 0;
4410-    var x, err, t, pp;
4411+    let j = 0;
4412+    let x, err, t, pp;
4413     if (p >= 2)
4414       return -100;
4415     if (p <= 0)
4416@@ -1378,12 +1378,12 @@ var CONFIDENCE = function (alpha, standDev, size) {
4417     return -1.41421356237309505 * std * _erfcinv(2 * p) + m;
4418   }
4419   function _sumsqerr(arr) {
4420-    var mean = mean(arr);
4421-    var sum = 0;
4422-    var i = arr.length;
4423-    var tmp;
4424+    let m = mean(arr);
4425+    let sum = 0;
4426+    let i = arr.length;
4427+    let tmp;
4428     while (--i >= 0) {
4429-      tmp = arr[i] - mean;
4430+      tmp = arr[i] - m;
4431       sum += tmp * tmp;
4432     }
4433     return sum;
4434@@ -1392,8 +1392,8 @@ var CONFIDENCE = function (alpha, standDev, size) {
4435     return _sumsqerr(arr) / (arr.length - (flag ? 1 : 0));
4436   }
4437   function _normalci(...values) {
4438-      var ans = new Array(2);
4439-      var change;
4440+      let ans = new Array(2);
4441+      let change;
4442     if (values.length === 4) {
4443       change = Math.abs(_normalInv(values[1] / 2, 0, 1) *
4444         values[2] / Math.sqrt(values[3]));
4445@@ -1418,14 +1418,14 @@ var CONFIDENCE = function (alpha, standDev, size) {
4446  * @returns {number}
4447  * @constructor
4448  */
4449-var BINOMDIST = function (successes, trials, probability, cumulative) {
4450+let BINOMDIST = function (successes, trials, probability, cumulative) {
4451   ArgsChecker.checkLength(arguments, 4, "BINOMDIST");
4452   successes = TypeConverter.firstValueAsNumber(successes);
4453   trials = TypeConverter.firstValueAsNumber(trials);
4454   probability = TypeConverter.firstValueAsNumber(probability);
4455   cumulative = TypeConverter.firstValueAsNumber(cumulative);
4456   function _binomialCDF(x, n, p) {
4457-    var binomarr = [],
4458+    let binomarr = [],
4459       k = 0;
4460     if (x < 0) {
4461       return 0;
4462@@ -1480,18 +1480,18 @@ var BINOMDIST = function (successes, trials, probability, cumulative) {
4463  * @returns {number}
4464  * @constructor
4465  */
4466-var COVAR = function (dataY, dataX) {
4467+let COVAR = function (dataY, dataX) {
4468   ArgsChecker.checkLength(arguments, 2, "COVAR");
4469   dataY = Filter.flattenAndThrow(dataY).map(TypeConverter.valueToNumber);
4470   dataX = Filter.flattenAndThrow(dataX).map(TypeConverter.valueToNumber);
4471   if (dataX.length !== dataY.length) {
4472-    throw new NAError("COVAR has mismatched argument count " + dataY.length + " vs " + dataX.length + ".");
4473+    throw new NAError("COlet has mismatched argument count " + dataY.length + " vs " + dataX.length + ".");
4474   }
4475-  var mean1 = mean(dataY);
4476-  var mean2 = mean(dataX);
4477-  var result = 0;
4478-  var n = dataY.length;
4479-  for (var i = 0; i < n; i++) {
4480+  let mean1 = mean(dataY);
4481+  let mean2 = mean(dataX);
4482+  let result = 0;
4483+  let n = dataY.length;
4484+  for (let i = 0; i < n; i++) {
4485     result += (dataY[i] - mean1) * (dataX[i] - mean2);
4486   }
4487   return result / n;
4488@@ -1508,7 +1508,7 @@ var COVAR = function (dataY, dataX) {
4489  * @returns {number}
4490  * @constructor
4491  */
4492-var WEIBULL = function (x, shape, scale, cumulative) {
4493+let WEIBULL = function (x, shape, scale, cumulative) {
4494   ArgsChecker.checkLength(arguments, 4, "WEIBULL");
4495   x = TypeConverter.firstValueAsNumber(x);
4496   if (x < 0) {
4497@@ -1534,18 +1534,18 @@ var WEIBULL = function (x, shape, scale, cumulative) {
4498  * @returns {number}
4499  * @constructor
4500  */
4501-var VARPA = function (...values) {
4502+let VARPA = function (...values) {
4503   ArgsChecker.checkAtLeastLength(arguments, 1, "VARPA");
4504-  var range = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber);
4505-  var n = range.length;
4506+  let range = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber);
4507+  let n = range.length;
4508   if (n < 2) {
4509     throw new DivZeroError("Evaluation of function VARP caused a divide by zero error.");
4510   }
4511-  var sigma = 0;
4512-  var count = 0;
4513-  var mean = AVERAGEA(range);
4514-  for (var i = 0; i < n; i++) {
4515-    var el = range[i];
4516+  let sigma = 0;
4517+  let count = 0;
4518+  let mean = AVERAGEA(range);
4519+  for (let i = 0; i < n; i++) {
4520+    let el = range[i];
4521     if (typeof el === 'number') {
4522       sigma += Math.pow(el - mean, 2);
4523     } else if (el === true) {
4524@@ -1568,17 +1568,17 @@ var VARPA = function (...values) {
4525  * @returns {number}
4526  * @constructor
4527  */
4528-var VARP =  function (...values) {
4529+let VARP =  function (...values) {
4530   ArgsChecker.checkAtLeastLength(arguments, 1, "VARP");
4531-  var range = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber);
4532-  var n = range.length;
4533+  let range = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber);
4534+  let n = range.length;
4535   if (n < 2) {
4536     throw new DivZeroError("Evaluation of function VARP caused a divide by zero error.");
4537   }
4538-  var sigma = 0;
4539-  var count = 0;
4540-  var mean = AVERAGE(range);
4541-  for (var i = 0; i < n; i++) {
4542+  let sigma = 0;
4543+  let count = 0;
4544+  let mean = AVERAGE(range);
4545+  for (let i = 0; i < n; i++) {
4546     sigma += Math.pow(range[i] - mean, 2);
4547     count++;
4548   }
4549@@ -1592,18 +1592,18 @@ var VARP =  function (...values) {
4550  * @returns {number}
4551  * @constructor
4552  */
4553-var VARA = function (...values) {
4554+let VARA = function (...values) {
4555   ArgsChecker.checkAtLeastLength(arguments, 1, "VARA");
4556-  var range = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber);
4557-  var n = range.length;
4558+  let range = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber);
4559+  let n = range.length;
4560   if (n < 2) {
4561     throw new DivZeroError("Evaluation of function VARA caused a divide by zero error.");
4562   }
4563-  var sigma = 0;
4564-  var count = 0;
4565-  var mean = AVERAGEA(range);
4566-  for (var i = 0; i < n; i++) {
4567-    var el = range[i];
4568+  let sigma = 0;
4569+  let count = 0;
4570+  let mean = AVERAGEA(range);
4571+  for (let i = 0; i < n; i++) {
4572+    let el = range[i];
4573     if (typeof el === 'number') {
4574       sigma += Math.pow(el - mean, 2);
4575     } else if (el === true) {
4576@@ -1625,17 +1625,17 @@ var VARA = function (...values) {
4577  * @param values - Values in sample.
4578  * @constructor
4579