@khanacademy/kas 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -77,8 +77,7 @@ import _ from 'underscore';
77
77
  */
78
78
  var parser$1 = function () {
79
79
  var o = function o(k, v, _o, l) {
80
- for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v) {
81
- }
80
+ for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v);
82
81
  return _o;
83
82
  },
84
83
  $V0 = [1, 11],
@@ -424,7 +423,7 @@ var parser$1 = function () {
424
423
  }
425
424
  },
426
425
  // resets the lexer, sets new input
427
- setInput: function setInput(input, yy) {
426
+ setInput: function (input, yy) {
428
427
  this.yy = yy || this.yy || {};
429
428
  this._input = input;
430
429
  this._more = this._backtrack = this.done = false;
@@ -444,7 +443,7 @@ var parser$1 = function () {
444
443
  return this;
445
444
  },
446
445
  // consumes and returns one char from the input
447
- input: function input() {
446
+ input: function () {
448
447
  var ch = this._input[0];
449
448
  this.yytext += ch;
450
449
  this.yyleng++;
@@ -465,7 +464,7 @@ var parser$1 = function () {
465
464
  return ch;
466
465
  },
467
466
  // unshifts one char (or a string) into the input
468
- unput: function unput(ch) {
467
+ unput: function (ch) {
469
468
  var len = ch.length;
470
469
  var lines = ch.split(/(?:\r\n?|\n)/g);
471
470
  this._input = ch + this._input;
@@ -492,12 +491,12 @@ var parser$1 = function () {
492
491
  return this;
493
492
  },
494
493
  // When called from action, caches matched text and appends it on next action
495
- more: function more() {
494
+ more: function () {
496
495
  this._more = true;
497
496
  return this;
498
497
  },
499
498
  // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
500
- reject: function reject() {
499
+ reject: function () {
501
500
  if (this.options.backtrack_lexer) {
502
501
  this._backtrack = true;
503
502
  } else {
@@ -510,16 +509,16 @@ var parser$1 = function () {
510
509
  return this;
511
510
  },
512
511
  // retain first n characters of the match
513
- less: function less(n) {
512
+ less: function (n) {
514
513
  this.unput(this.match.slice(n));
515
514
  },
516
515
  // displays already matched input, i.e. for error messages
517
- pastInput: function pastInput() {
516
+ pastInput: function () {
518
517
  var past = this.matched.substr(0, this.matched.length - this.match.length);
519
518
  return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
520
519
  },
521
520
  // displays upcoming input, i.e. for error messages
522
- upcomingInput: function upcomingInput() {
521
+ upcomingInput: function () {
523
522
  var next = this.match;
524
523
  if (next.length < 20) {
525
524
  next += this._input.substr(0, 20 - next.length);
@@ -527,13 +526,13 @@ var parser$1 = function () {
527
526
  return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
528
527
  },
529
528
  // displays the character position where the lexing error occurred, i.e. for error messages
530
- showPosition: function showPosition() {
529
+ showPosition: function () {
531
530
  var pre = this.pastInput();
532
531
  var c = new Array(pre.length + 1).join("-");
533
532
  return pre + this.upcomingInput() + "\n" + c + "^";
534
533
  },
535
534
  // test the lexed token: return FALSE when not a match, otherwise return token
536
- test_match: function test_match(match, indexed_rule) {
535
+ test_match: function (match, indexed_rule) {
537
536
  var token, lines, backup;
538
537
  if (this.options.backtrack_lexer) {
539
538
  // save context
@@ -599,7 +598,7 @@ var parser$1 = function () {
599
598
  return false;
600
599
  },
601
600
  // return next match in input
602
- next: function next() {
601
+ next: function () {
603
602
  if (this.done) {
604
603
  return this.EOF;
605
604
  }
@@ -750,7 +749,7 @@ var parser$1 = function () {
750
749
  parser.Parser = Parser;
751
750
  return new Parser();
752
751
  }();
753
- var unitParser = parser$1;
752
+ const unitParser = parser$1;
754
753
 
755
754
  // This is a @generated file
756
755
 
@@ -829,8 +828,7 @@ var unitParser = parser$1;
829
828
  */
830
829
  var parser = function () {
831
830
  var o = function o(k, v, _o, l) {
832
- for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v) {
833
- }
831
+ for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v);
834
832
  return _o;
835
833
  },
836
834
  $V0 = [1, 7],
@@ -2103,7 +2101,7 @@ var parser = function () {
2103
2101
  }
2104
2102
  },
2105
2103
  // resets the lexer, sets new input
2106
- setInput: function setInput(input, yy) {
2104
+ setInput: function (input, yy) {
2107
2105
  this.yy = yy || this.yy || {};
2108
2106
  this._input = input;
2109
2107
  this._more = this._backtrack = this.done = false;
@@ -2123,7 +2121,7 @@ var parser = function () {
2123
2121
  return this;
2124
2122
  },
2125
2123
  // consumes and returns one char from the input
2126
- input: function input() {
2124
+ input: function () {
2127
2125
  var ch = this._input[0];
2128
2126
  this.yytext += ch;
2129
2127
  this.yyleng++;
@@ -2144,7 +2142,7 @@ var parser = function () {
2144
2142
  return ch;
2145
2143
  },
2146
2144
  // unshifts one char (or a string) into the input
2147
- unput: function unput(ch) {
2145
+ unput: function (ch) {
2148
2146
  var len = ch.length;
2149
2147
  var lines = ch.split(/(?:\r\n?|\n)/g);
2150
2148
  this._input = ch + this._input;
@@ -2171,12 +2169,12 @@ var parser = function () {
2171
2169
  return this;
2172
2170
  },
2173
2171
  // When called from action, caches matched text and appends it on next action
2174
- more: function more() {
2172
+ more: function () {
2175
2173
  this._more = true;
2176
2174
  return this;
2177
2175
  },
2178
2176
  // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
2179
- reject: function reject() {
2177
+ reject: function () {
2180
2178
  if (this.options.backtrack_lexer) {
2181
2179
  this._backtrack = true;
2182
2180
  } else {
@@ -2189,16 +2187,16 @@ var parser = function () {
2189
2187
  return this;
2190
2188
  },
2191
2189
  // retain first n characters of the match
2192
- less: function less(n) {
2190
+ less: function (n) {
2193
2191
  this.unput(this.match.slice(n));
2194
2192
  },
2195
2193
  // displays already matched input, i.e. for error messages
2196
- pastInput: function pastInput() {
2194
+ pastInput: function () {
2197
2195
  var past = this.matched.substr(0, this.matched.length - this.match.length);
2198
2196
  return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
2199
2197
  },
2200
2198
  // displays upcoming input, i.e. for error messages
2201
- upcomingInput: function upcomingInput() {
2199
+ upcomingInput: function () {
2202
2200
  var next = this.match;
2203
2201
  if (next.length < 20) {
2204
2202
  next += this._input.substr(0, 20 - next.length);
@@ -2206,13 +2204,13 @@ var parser = function () {
2206
2204
  return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
2207
2205
  },
2208
2206
  // displays the character position where the lexing error occurred, i.e. for error messages
2209
- showPosition: function showPosition() {
2207
+ showPosition: function () {
2210
2208
  var pre = this.pastInput();
2211
2209
  var c = new Array(pre.length + 1).join("-");
2212
2210
  return pre + this.upcomingInput() + "\n" + c + "^";
2213
2211
  },
2214
2212
  // test the lexed token: return FALSE when not a match, otherwise return token
2215
- test_match: function test_match(match, indexed_rule) {
2213
+ test_match: function (match, indexed_rule) {
2216
2214
  var token, lines, backup;
2217
2215
  if (this.options.backtrack_lexer) {
2218
2216
  // save context
@@ -2278,7 +2276,7 @@ var parser = function () {
2278
2276
  return false;
2279
2277
  },
2280
2278
  // return next match in input
2281
- next: function next() {
2279
+ next: function () {
2282
2280
  if (this.done) {
2283
2281
  return this.EOF;
2284
2282
  }
@@ -2681,13 +2679,13 @@ _.extend(Expr.prototype, {
2681
2679
  // an array of the arguments to this node's immediate constructor
2682
2680
  args: abstract,
2683
2681
  // make a new node with the given arguments
2684
- construct: function construct(args) {
2682
+ construct: function (args) {
2685
2683
  var instance = new this.func();
2686
2684
  this.func.apply(instance, args);
2687
2685
  return instance;
2688
2686
  },
2689
2687
  // an abstraction for chainable, bottom-up recursion
2690
- recurse: function recurse(method) {
2688
+ recurse: function (method) {
2691
2689
  var passed = Array.prototype.slice.call(arguments, 1);
2692
2690
  var args = _.map(this.args(), function (arg) {
2693
2691
  return _.isString(arg) ? arg : arg[method].apply(arg, passed);
@@ -2697,7 +2695,7 @@ _.extend(Expr.prototype, {
2697
2695
  // evaluate numerically with given variable mapping
2698
2696
  eval: abstract,
2699
2697
  codegen: abstract,
2700
- compile: function compile() {
2698
+ compile: function () {
2701
2699
  var code = this.codegen();
2702
2700
  try {
2703
2701
  return new Function("vars", "return " + code + ";");
@@ -2712,7 +2710,7 @@ _.extend(Expr.prototype, {
2712
2710
  // returns a TeX string representing the expression
2713
2711
  tex: abstract,
2714
2712
  // returns a TeX string, modified by the given options
2715
- asTex: function asTex(options) {
2713
+ asTex: function (options) {
2716
2714
  options = options || {};
2717
2715
  _.defaults(options, {
2718
2716
  display: true,
@@ -2734,7 +2732,7 @@ _.extend(Expr.prototype, {
2734
2732
  },
2735
2733
  // returns the name of this expression's constructor as a string
2736
2734
  // only used for testing and debugging (the ugly regex is for IE8)
2737
- name: function name() {
2735
+ name: function () {
2738
2736
  if (this.func.name) {
2739
2737
  return this.func.name;
2740
2738
  } else {
@@ -2742,37 +2740,37 @@ _.extend(Expr.prototype, {
2742
2740
  }
2743
2741
  },
2744
2742
  // returns a string representing current node structure
2745
- repr: function repr() {
2743
+ repr: function () {
2746
2744
  return this.name() + "(" + _.map(this.args(), function (arg) {
2747
2745
  return _.isString(arg) ? arg : arg.repr();
2748
2746
  }).join(",") + ")";
2749
2747
  },
2750
2748
  // removes all negative signs
2751
- strip: function strip() {
2749
+ strip: function () {
2752
2750
  return this.recurse("strip");
2753
2751
  },
2754
2752
  // canonically reorders all commutative elements
2755
- normalize: function normalize() {
2753
+ normalize: function () {
2756
2754
  return this.recurse("normalize");
2757
2755
  },
2758
2756
  // expands the expression
2759
- expand: function expand() {
2757
+ expand: function () {
2760
2758
  return this.recurse("expand");
2761
2759
  },
2762
2760
  // naively factors out like terms
2763
- factor: function factor(options) {
2761
+ factor: function (options) {
2764
2762
  return this.recurse("factor", options);
2765
2763
  },
2766
2764
  // collect all like terms
2767
- collect: function collect(options) {
2765
+ collect: function (options) {
2768
2766
  return this.recurse("collect", options);
2769
2767
  },
2770
2768
  // strict syntactic equality check
2771
- equals: function equals(other) {
2769
+ equals: function (other) {
2772
2770
  return this.normalize().print() === other.normalize().print();
2773
2771
  },
2774
2772
  // expand and collect until the expression no longer changes
2775
- simplify: function simplify(options) {
2773
+ simplify: function (options) {
2776
2774
  options = _.extend({
2777
2775
  once: false
2778
2776
  }, options);
@@ -2804,31 +2802,31 @@ _.extend(Expr.prototype, {
2804
2802
  }
2805
2803
  },
2806
2804
  // check whether this expression is simplified
2807
- isSimplified: function isSimplified() {
2805
+ isSimplified: function () {
2808
2806
  return this.equals(this.simplify());
2809
2807
  },
2810
2808
  // return the child nodes of this node
2811
- exprArgs: function exprArgs() {
2809
+ exprArgs: function () {
2812
2810
  return _.filter(this.args(), function (arg) {
2813
2811
  return arg instanceof Expr;
2814
2812
  });
2815
2813
  },
2816
2814
  // return the variables (function and non) within the expression
2817
- getVars: function getVars(excludeFunc) {
2815
+ getVars: function (excludeFunc) {
2818
2816
  return _.uniq(_.flatten(_.invoke(this.exprArgs(), "getVars", excludeFunc))).sort();
2819
2817
  },
2820
- getConsts: function getConsts() {
2818
+ getConsts: function () {
2821
2819
  return _.uniq(_.flatten(_.invoke(this.exprArgs(), "getConsts"))).sort();
2822
2820
  },
2823
- getUnits: function getUnits() {
2821
+ getUnits: function () {
2824
2822
  return _.flatten(_.invoke(this.exprArgs(), "getUnits"));
2825
2823
  },
2826
2824
  // check whether this expression node is of a particular type
2827
- is: function is(func) {
2825
+ is: function (func) {
2828
2826
  return this instanceof func;
2829
2827
  },
2830
2828
  // check whether this expression has a particular node type
2831
- has: function has(func) {
2829
+ has: function (func) {
2832
2830
  if (this instanceof func) {
2833
2831
  return true;
2834
2832
  }
@@ -2838,26 +2836,26 @@ _.extend(Expr.prototype, {
2838
2836
  },
2839
2837
  // raise this expression to a given exponent
2840
2838
  // most useful for eventually implementing i^3 = -i, etc.
2841
- raiseToThe: function raiseToThe(exp) {
2839
+ raiseToThe: function (exp) {
2842
2840
  return new Pow(this, exp);
2843
2841
  },
2844
2842
  // does this expression have a specific rendering hint?
2845
2843
  // rendering hints are picked up while parsing, but are lost during transformations
2846
- isSubtract: function isSubtract() {
2844
+ isSubtract: function () {
2847
2845
  return false;
2848
2846
  },
2849
- isDivide: function isDivide() {
2847
+ isDivide: function () {
2850
2848
  return false;
2851
2849
  },
2852
- isRoot: function isRoot() {
2850
+ isRoot: function () {
2853
2851
  return false;
2854
2852
  },
2855
2853
  // whether this node needs an explicit multiplication sign if following a Num
2856
- needsExplicitMul: function needsExplicitMul() {
2854
+ needsExplicitMul: function () {
2857
2855
  return this.args()[0].needsExplicitMul();
2858
2856
  },
2859
2857
  // check that the variables in both expressions are the same
2860
- sameVars: function sameVars(other) {
2858
+ sameVars: function (other) {
2861
2859
  var vars1 = this.getVars();
2862
2860
  var vars2 = other.getVars();
2863
2861
 
@@ -2879,7 +2877,7 @@ _.extend(Expr.prototype, {
2879
2877
  // semantic equality check, call after sameVars() to avoid potential false positives
2880
2878
  // plug in random numbers for the variables in both expressions
2881
2879
  // if they both consistently evaluate the same, then they're the same
2882
- compare: function compare(other) {
2880
+ compare: function (other) {
2883
2881
  // equation comparisons are handled by Eq.compare()
2884
2882
  if (other instanceof Eq) {
2885
2883
  return false;
@@ -2967,7 +2965,7 @@ _.extend(Expr.prototype, {
2967
2965
  return true;
2968
2966
  },
2969
2967
  // evaluate as much of the expression as possible
2970
- partialEval: function partialEval(vars) {
2968
+ partialEval: function (vars) {
2971
2969
  if (this instanceof Unit) {
2972
2970
  return this;
2973
2971
  } else if (!this.has(Func)) {
@@ -2982,19 +2980,19 @@ _.extend(Expr.prototype, {
2982
2980
  // all negative signs are stripped and the expressions are converted to
2983
2981
  // a canonical commutative form
2984
2982
  // should only be done after compare() returns true to avoid false positives
2985
- sameForm: function sameForm(other) {
2983
+ sameForm: function (other) {
2986
2984
  return this.strip().equals(other.strip());
2987
2985
  },
2988
2986
  // returns the GCD of this expression and the given factor
2989
- findGCD: function findGCD(factor) {
2987
+ findGCD: function (factor) {
2990
2988
  return this.equals(factor) ? factor : Num.One;
2991
2989
  },
2992
2990
  // return this expression's denominator
2993
- getDenominator: function getDenominator() {
2991
+ getDenominator: function () {
2994
2992
  return Num.One;
2995
2993
  },
2996
2994
  // return this expression as a Mul
2997
- asMul: function asMul() {
2995
+ asMul: function () {
2998
2996
  return new Mul(Num.One, this);
2999
2997
  },
3000
2998
  // TODO(alex): rename to isDefinitePositive or similar?
@@ -3002,15 +3000,15 @@ _.extend(Expr.prototype, {
3002
3000
  isPositive: abstract,
3003
3001
  // TODO(alex): rename to hasNegativeSign or similar?
3004
3002
  // return whether this expression has a negative sign
3005
- isNegative: function isNegative() {
3003
+ isNegative: function () {
3006
3004
  return false;
3007
3005
  },
3008
3006
  // return a factor of this expression that is 100% positive
3009
- asPositiveFactor: function asPositiveFactor() {
3007
+ asPositiveFactor: function () {
3010
3008
  return this.isPositive() ? this : Num.One;
3011
3009
  },
3012
3010
  // return a copy of the expression with a new hint set (preserves hints)
3013
- addHint: function addHint(hint) {
3011
+ addHint: function (hint) {
3014
3012
  if (!hint) {
3015
3013
  return this;
3016
3014
  }
@@ -3023,15 +3021,15 @@ _.extend(Expr.prototype, {
3023
3021
  parens: false
3024
3022
  },
3025
3023
  // currently unused!
3026
- asExpr: function asExpr() {
3024
+ asExpr: function () {
3027
3025
  return this;
3028
3026
  },
3029
3027
  // complete parse by performing a few necessary transformations
3030
- completeParse: function completeParse() {
3028
+ completeParse: function () {
3031
3029
  return this.recurse("completeParse");
3032
3030
  },
3033
3031
  abs: abstract,
3034
- negate: function negate() {
3032
+ negate: function () {
3035
3033
  return new Mul(Num.Neg, this);
3036
3034
  }
3037
3035
  });
@@ -3040,21 +3038,21 @@ _.extend(Expr.prototype, {
3040
3038
  function Seq() {}
3041
3039
  Seq.prototype = new Expr();
3042
3040
  _.extend(Seq.prototype, {
3043
- args: function args() {
3041
+ args: function () {
3044
3042
  return this.terms;
3045
3043
  },
3046
- normalize: function normalize() {
3044
+ normalize: function () {
3047
3045
  var terms = _.sortBy(_.invoke(this.terms, "normalize"), function (term) {
3048
3046
  return term.print();
3049
3047
  });
3050
3048
  return new this.func(terms);
3051
3049
  },
3052
- expand: function expand() {
3050
+ expand: function () {
3053
3051
  return this.recurse("expand").flatten();
3054
3052
  },
3055
3053
  // partition the sequence into its numeric and non-numeric parts
3056
3054
  // makes no guarantees about the validity of either part!
3057
- partition: function partition() {
3055
+ partition: function () {
3058
3056
  var terms = _.groupBy(this.terms, function (term) {
3059
3057
  return term instanceof Num;
3060
3058
  });
@@ -3068,7 +3066,7 @@ _.extend(Seq.prototype, {
3068
3066
  },
3069
3067
  // ensure that sequences have 2+ terms and no nested sequences of the same type
3070
3068
  // this is a shallow flattening and will return a non-Seq if terms.length <= 1
3071
- flatten: function flatten() {
3069
+ flatten: function () {
3072
3070
  var type = this;
3073
3071
  var terms = _.reject(this.terms, function (term) {
3074
3072
  return term.equals(type.identity);
@@ -3093,14 +3091,14 @@ _.extend(Seq.prototype, {
3093
3091
  identity: undefined,
3094
3092
  // reduce a numeric sequence to a Num
3095
3093
  reduce: abstract,
3096
- isPositive: function isPositive() {
3094
+ isPositive: function () {
3097
3095
  var terms = _.invoke(this.terms, "collect");
3098
3096
  return _.all(_.invoke(terms, "isPositive"));
3099
3097
  },
3100
3098
  // return a new Seq with a given term replaced by a different term
3101
3099
  // (or array of terms). given term can be passed directly, or by index
3102
3100
  // if no new term is provided, the old one is simply removed
3103
- replace: function replace(oldTerm, newTerm) {
3101
+ replace: function (oldTerm, newTerm) {
3104
3102
  var index;
3105
3103
  if (oldTerm instanceof Expr) {
3106
3104
  index = _.indexOf(this.terms, oldTerm);
@@ -3117,10 +3115,10 @@ _.extend(Seq.prototype, {
3117
3115
  return new this.func(terms);
3118
3116
  },
3119
3117
  // syntactic sugar for replace()
3120
- remove: function remove(term) {
3118
+ remove: function (term) {
3121
3119
  return this.replace(term);
3122
3120
  },
3123
- getDenominator: function getDenominator() {
3121
+ getDenominator: function () {
3124
3122
  // TODO(alex): find and return LCM
3125
3123
  return new Mul(_.invoke(this.terms, "getDenominator")).flatten();
3126
3124
  }
@@ -3137,20 +3135,20 @@ function Add() {
3137
3135
  Add.prototype = new Seq();
3138
3136
  _.extend(Add.prototype, {
3139
3137
  func: Add,
3140
- eval: function _eval(vars, options) {
3138
+ eval: function (vars, options) {
3141
3139
  return _.reduce(this.terms, function (memo, term) {
3142
3140
  return memo + term.eval(vars, options);
3143
3141
  }, 0);
3144
3142
  },
3145
- codegen: function codegen() {
3143
+ codegen: function () {
3146
3144
  return _.map(this.terms, function (term) {
3147
3145
  return "(" + term.codegen() + ")";
3148
3146
  }).join(" + ") || "0";
3149
3147
  },
3150
- print: function print() {
3148
+ print: function () {
3151
3149
  return _.invoke(this.terms, "print").join("+");
3152
3150
  },
3153
- tex: function tex() {
3151
+ tex: function () {
3154
3152
  var tex = "";
3155
3153
  _.each(this.terms, function (term) {
3156
3154
  if (!tex || term.isSubtract()) {
@@ -3161,7 +3159,7 @@ _.extend(Add.prototype, {
3161
3159
  });
3162
3160
  return tex;
3163
3161
  },
3164
- collect: function collect(options) {
3162
+ collect: function (options) {
3165
3163
  var terms = _.invoke(this.terms, "collect", options);
3166
3164
 
3167
3165
  // [Expr expr, Num coefficient]
@@ -3195,7 +3193,7 @@ _.extend(Add.prototype, {
3195
3193
  },
3196
3194
  // naively factor out anything that is common to all terms
3197
3195
  // if options.keepNegative is specified, won't factor out a common -1
3198
- factor: function factor(options) {
3196
+ factor: function (options) {
3199
3197
  options = _.extend({
3200
3198
  keepNegative: false
3201
3199
  }, options);
@@ -3221,19 +3219,19 @@ _.extend(Add.prototype, {
3221
3219
  remainder = new Add(remainder).flatten();
3222
3220
  return Mul.createOrAppend(factors, remainder).flatten();
3223
3221
  },
3224
- reduce: function reduce(options) {
3222
+ reduce: function (options) {
3225
3223
  return _.reduce(this.terms, function (memo, term) {
3226
3224
  return memo.add(term, options);
3227
3225
  }, this.identity);
3228
3226
  },
3229
- needsExplicitMul: function needsExplicitMul() {
3227
+ needsExplicitMul: function () {
3230
3228
  return false;
3231
3229
  },
3232
- isNegative: function isNegative() {
3230
+ isNegative: function () {
3233
3231
  var terms = _.invoke(this.terms, "collect");
3234
3232
  return _.all(_.invoke(terms, "isNegative"));
3235
3233
  },
3236
- negate: function negate() {
3234
+ negate: function () {
3237
3235
  return new Add(_.invoke(this.terms, "negate"));
3238
3236
  }
3239
3237
  });
@@ -3249,22 +3247,22 @@ function Mul() {
3249
3247
  Mul.prototype = new Seq();
3250
3248
  _.extend(Mul.prototype, {
3251
3249
  func: Mul,
3252
- eval: function _eval(vars, options) {
3250
+ eval: function (vars, options) {
3253
3251
  return _.reduce(this.terms, function (memo, term) {
3254
3252
  return memo * term.eval(vars, options);
3255
3253
  }, 1);
3256
3254
  },
3257
- codegen: function codegen() {
3255
+ codegen: function () {
3258
3256
  return _.map(this.terms, function (term) {
3259
3257
  return "(" + term.codegen() + ")";
3260
3258
  }).join(" * ") || "0";
3261
3259
  },
3262
- print: function print() {
3260
+ print: function () {
3263
3261
  return _.map(this.terms, function (term) {
3264
3262
  return term instanceof Add ? "(" + term.print() + ")" : term.print();
3265
3263
  }).join("*");
3266
3264
  },
3267
- getUnits: function getUnits() {
3265
+ getUnits: function () {
3268
3266
  var tmUnits = _(this.terms).chain().map(function (term) {
3269
3267
  return term.getUnits();
3270
3268
  }).flatten().value();
@@ -3273,7 +3271,7 @@ _.extend(Mul.prototype, {
3273
3271
  },
3274
3272
  // since we don't care about commutativity, we can render a Mul any way we choose
3275
3273
  // so we follow convention: first any negatives, then any numbers, then everything else
3276
- tex: function tex() {
3274
+ tex: function () {
3277
3275
  var cdot = " \\cdot ";
3278
3276
  var terms = _.groupBy(this.terms, function (term) {
3279
3277
  if (term.isDivide()) {
@@ -3354,14 +3352,14 @@ _.extend(Mul.prototype, {
3354
3352
  return negatives + "\\frac{" + numerator + "}{" + denominator + "}";
3355
3353
  }
3356
3354
  },
3357
- strip: function strip() {
3355
+ strip: function () {
3358
3356
  var terms = _.map(this.terms, function (term) {
3359
3357
  return term instanceof Num ? term.abs() : term.strip();
3360
3358
  });
3361
3359
  return new Mul(terms).flatten();
3362
3360
  },
3363
3361
  // expand numerator and denominator separately
3364
- expand: function expand() {
3362
+ expand: function () {
3365
3363
  var isAdd = function isAdd(term) {
3366
3364
  return term instanceof Add;
3367
3365
  };
@@ -3408,7 +3406,7 @@ _.extend(Mul.prototype, {
3408
3406
  }
3409
3407
  return new Mul(normals.concat(inverses)).flatten();
3410
3408
  },
3411
- factor: function factor(options) {
3409
+ factor: function (options) {
3412
3410
  var factored = this.recurse("factor", options).flatten();
3413
3411
  if (!(factored instanceof Mul)) {
3414
3412
  return factored;
@@ -3438,7 +3436,7 @@ _.extend(Mul.prototype, {
3438
3436
  }
3439
3437
  return new Mul((grouped[false] || []).concat(rational)).flatten();
3440
3438
  },
3441
- collect: function collect(options) {
3439
+ collect: function (options) {
3442
3440
  var partitioned = this.recurse("collect", options).partition();
3443
3441
  var number = partitioned[0].reduce(options);
3444
3442
 
@@ -3569,14 +3567,14 @@ _.extend(Mul.prototype, {
3569
3567
  });
3570
3568
  return new Mul([number].concat(collected)).flatten();
3571
3569
  },
3572
- isSubtract: function isSubtract() {
3570
+ isSubtract: function () {
3573
3571
  return _.any(this.terms, function (term) {
3574
3572
  return term instanceof Num && term.hints.subtract;
3575
3573
  });
3576
3574
  },
3577
3575
  // factor a single -1 in to the Mul
3578
3576
  // combine with a Num if all Nums are positive, else add as a term
3579
- factorIn: function factorIn(hint) {
3577
+ factorIn: function (hint) {
3580
3578
  var partitioned = this.partition();
3581
3579
  var numbers = partitioned[0].terms;
3582
3580
  var fold = numbers.length && _.all(numbers, function (num) {
@@ -3595,7 +3593,7 @@ _.extend(Mul.prototype, {
3595
3593
  },
3596
3594
  // factor out a single hinted -1 (assume it is the division hint)
3597
3595
  // TODO(alex): make more general or rename to be more specific
3598
- factorOut: function factorOut() {
3596
+ factorOut: function () {
3599
3597
  var factored = false;
3600
3598
  var terms = _.compact(_.map(this.terms, function (term, i, list) {
3601
3599
  if (!factored && term instanceof Num && term.hints.divide) {
@@ -3611,18 +3609,18 @@ _.extend(Mul.prototype, {
3611
3609
  return new Mul(terms);
3612
3610
  }
3613
3611
  },
3614
- reduce: function reduce(options) {
3612
+ reduce: function (options) {
3615
3613
  return _.reduce(this.terms, function (memo, term) {
3616
3614
  return memo.mul(term, options);
3617
3615
  }, this.identity);
3618
3616
  },
3619
- findGCD: function findGCD(factor) {
3617
+ findGCD: function (factor) {
3620
3618
  return new Mul(_.invoke(this.terms, "findGCD", factor)).flatten();
3621
3619
  },
3622
- asMul: function asMul() {
3620
+ asMul: function () {
3623
3621
  return this;
3624
3622
  },
3625
- asPositiveFactor: function asPositiveFactor() {
3623
+ asPositiveFactor: function () {
3626
3624
  if (this.isPositive()) {
3627
3625
  return this;
3628
3626
  } else {
@@ -3630,13 +3628,13 @@ _.extend(Mul.prototype, {
3630
3628
  return new Mul(terms).flatten();
3631
3629
  }
3632
3630
  },
3633
- isNegative: function isNegative() {
3631
+ isNegative: function () {
3634
3632
  return _.any(_.invoke(this.collect().terms, "isNegative"));
3635
3633
  },
3636
- fold: function fold() {
3634
+ fold: function () {
3637
3635
  return Mul.fold(this);
3638
3636
  },
3639
- negate: function negate() {
3637
+ negate: function () {
3640
3638
  var isNum = function isNum(expr) {
3641
3639
  return expr instanceof Num;
3642
3640
  };
@@ -3653,7 +3651,7 @@ _.extend(Mul.prototype, {
3653
3651
  _.each([Add, Mul], function (type) {
3654
3652
  _.extend(type, {
3655
3653
  // create a new sequence unless left is already one (returns a copy)
3656
- createOrAppend: function createOrAppend(left, right) {
3654
+ createOrAppend: function (left, right) {
3657
3655
  if (left instanceof type) {
3658
3656
  return new type(left.terms.concat(right));
3659
3657
  } else {
@@ -3667,7 +3665,7 @@ _.extend(Mul, {
3667
3665
  // never fold into a Num that's already negative or a Mul that has a negative Num
3668
3666
  // an optional hint is kept track of to properly render user input
3669
3667
  // an empty hint means negation
3670
- handleNegative: function handleNegative(expr, hint) {
3668
+ handleNegative: function (expr, hint) {
3671
3669
  if (expr instanceof Num && expr.n > 0) {
3672
3670
  // e.g. - 2 -> -2
3673
3671
  var negated = expr.negate();
@@ -3685,7 +3683,7 @@ _.extend(Mul, {
3685
3683
  }
3686
3684
  },
3687
3685
  // division can create either a Rational or a Mul
3688
- handleDivide: function handleDivide(left, right) {
3686
+ handleDivide: function (left, right) {
3689
3687
  // dividing by a Mul is the same as repeated division by its terms
3690
3688
  if (right instanceof Mul) {
3691
3689
  var first = Mul.handleDivide(left, right.terms[0]);
@@ -3791,7 +3789,7 @@ _.extend(Mul, {
3791
3789
  // e.g. sin(x)*x -> sin(x)*x
3792
3790
  // e.g. sin(x)*(x) -> sin(x)*x
3793
3791
  // e.g. sin(x)*sin(y) -> sin(x)*sin(y)
3794
- fold: function fold(expr) {
3792
+ fold: function (expr) {
3795
3793
  if (expr instanceof Mul) {
3796
3794
  // assuming that this will be second to last
3797
3795
  var trigLog = _.find(_.initial(expr.terms), function (term) {
@@ -3851,10 +3849,10 @@ function Pow(base, exp) {
3851
3849
  Pow.prototype = new Expr();
3852
3850
  _.extend(Pow.prototype, {
3853
3851
  func: Pow,
3854
- args: function args() {
3852
+ args: function () {
3855
3853
  return [this.base, this.exp];
3856
3854
  },
3857
- eval: function _eval(vars, options) {
3855
+ eval: function (vars, options) {
3858
3856
  var evaledBase = this.base.eval(vars, options);
3859
3857
  var evaledExp = this.exp.eval(vars, options);
3860
3858
 
@@ -3889,7 +3887,7 @@ _.extend(Pow.prototype, {
3889
3887
  }
3890
3888
  return Math.pow(evaledBase, evaledExp);
3891
3889
  },
3892
- getUnits: function getUnits() {
3890
+ getUnits: function () {
3893
3891
  return this.base.getUnits().map(function (unit) {
3894
3892
  return {
3895
3893
  unit: unit.unit,
@@ -3897,17 +3895,17 @@ _.extend(Pow.prototype, {
3897
3895
  };
3898
3896
  }.bind(this));
3899
3897
  },
3900
- codegen: function codegen() {
3898
+ codegen: function () {
3901
3899
  return "Math.pow(" + this.base.codegen() + ", " + this.exp.codegen() + ")";
3902
3900
  },
3903
- print: function print() {
3901
+ print: function () {
3904
3902
  var base = this.base.print();
3905
3903
  if (this.base instanceof Seq || this.base instanceof Pow) {
3906
3904
  base = "(" + base + ")";
3907
3905
  }
3908
3906
  return base + "^(" + this.exp.print() + ")";
3909
3907
  },
3910
- tex: function tex() {
3908
+ tex: function () {
3911
3909
  if (this.isDivide()) {
3912
3910
  // e.g. x ^ -1 w/hint -> 1/x
3913
3911
  return "\\frac{1}{" + this.asDivide().tex() + "}";
@@ -3941,10 +3939,10 @@ _.extend(Pow.prototype, {
3941
3939
  return base + "^{" + this.exp.tex() + "}";
3942
3940
  }
3943
3941
  },
3944
- needsExplicitMul: function needsExplicitMul() {
3942
+ needsExplicitMul: function () {
3945
3943
  return this.isRoot() ? false : this.base.needsExplicitMul();
3946
3944
  },
3947
- expand: function expand() {
3945
+ expand: function () {
3948
3946
  var pow = this.recurse("expand");
3949
3947
  if (pow.base instanceof Mul) {
3950
3948
  // e.g. (ab)^c -> a^c*b^c
@@ -3998,7 +3996,7 @@ _.extend(Pow.prototype, {
3998
3996
  return pow;
3999
3997
  }
4000
3998
  },
4001
- factor: function factor() {
3999
+ factor: function () {
4002
4000
  var pow = this.recurse("factor");
4003
4001
  if (pow.base instanceof Mul) {
4004
4002
  var terms = _.map(pow.base.terms, function (term) {
@@ -4015,7 +4013,7 @@ _.extend(Pow.prototype, {
4015
4013
  return pow;
4016
4014
  }
4017
4015
  },
4018
- collect: function collect(options) {
4016
+ collect: function (options) {
4019
4017
  if (this.base instanceof Pow) {
4020
4018
  // collect this first to avoid having to deal with float precision
4021
4019
  // e.g. sqrt(2)^2 -> 2, not 2.0000000000000004
@@ -4075,14 +4073,14 @@ _.extend(Pow.prototype, {
4075
4073
  }
4076
4074
  },
4077
4075
  // checks whether this Pow represents user-entered division
4078
- isDivide: function isDivide() {
4076
+ isDivide: function () {
4079
4077
  var isDiv = function isDiv(arg) {
4080
4078
  return arg instanceof Num && arg.hints.divide;
4081
4079
  };
4082
4080
  return isDiv(this.exp) || this.exp instanceof Mul && _.any(this.exp.terms, isDiv);
4083
4081
  },
4084
4082
  // assuming this Pow represents user-entered division, returns the denominator
4085
- asDivide: function asDivide() {
4083
+ asDivide: function () {
4086
4084
  if (this.exp instanceof Num) {
4087
4085
  if (this.exp.eval() === -1) {
4088
4086
  return this.base;
@@ -4098,15 +4096,15 @@ _.extend(Pow.prototype, {
4098
4096
  error("called asDivide() on an Expr that wasn't a Num or Mul");
4099
4097
  }
4100
4098
  },
4101
- isRoot: function isRoot() {
4099
+ isRoot: function () {
4102
4100
  return this.exp instanceof Rational && this.exp.hints.root;
4103
4101
  },
4104
- isSquaredTrig: function isSquaredTrig() {
4102
+ isSquaredTrig: function () {
4105
4103
  return this.base instanceof Trig && !this.base.isInverse() && this.exp instanceof Num && this.exp.eval() === 2;
4106
4104
  },
4107
4105
  // extract whatever denominator makes sense, ignoring hints
4108
4106
  // if negative exponent, will recursively include the base's denominator as well
4109
- getDenominator: function getDenominator() {
4107
+ getDenominator: function () {
4110
4108
  if (this.exp instanceof Num && this.exp.eval() === -1) {
4111
4109
  return Mul.createOrAppend(this.base, this.base.getDenominator()).flatten();
4112
4110
  } else if (this.exp.isNegative()) {
@@ -4118,7 +4116,7 @@ _.extend(Pow.prototype, {
4118
4116
  return Num.One;
4119
4117
  }
4120
4118
  },
4121
- findGCD: function findGCD(factor) {
4119
+ findGCD: function (factor) {
4122
4120
  var base, exp;
4123
4121
  if (factor instanceof Pow) {
4124
4122
  base = factor.base;
@@ -4155,14 +4153,14 @@ _.extend(Pow.prototype, {
4155
4153
  }
4156
4154
  return Num.One;
4157
4155
  },
4158
- isPositive: function isPositive() {
4156
+ isPositive: function () {
4159
4157
  if (this.base.isPositive()) {
4160
4158
  return true;
4161
4159
  }
4162
4160
  var exp = this.exp.simplify();
4163
4161
  return exp instanceof Int && exp.eval() % 2 === 0;
4164
4162
  },
4165
- asPositiveFactor: function asPositiveFactor() {
4163
+ asPositiveFactor: function () {
4166
4164
  if (this.isPositive()) {
4167
4165
  return this;
4168
4166
  } else {
@@ -4182,10 +4180,10 @@ _.extend(Pow.prototype, {
4182
4180
  }
4183
4181
  });
4184
4182
  _.extend(Pow, {
4185
- sqrt: function sqrt(arg) {
4183
+ sqrt: function (arg) {
4186
4184
  return new Pow(arg, Num.Sqrt);
4187
4185
  },
4188
- nthroot: function nthroot(radicand, degree) {
4186
+ nthroot: function (radicand, degree) {
4189
4187
  var exp = Mul.fold(Mul.handleDivide(new Int(1), degree));
4190
4188
 
4191
4189
  // FIXME(johnsullivan): If oneOverDegree ends up being a pow object,
@@ -4202,16 +4200,16 @@ function Log(base, power) {
4202
4200
  Log.prototype = new Expr();
4203
4201
  _.extend(Log.prototype, {
4204
4202
  func: Log,
4205
- args: function args() {
4203
+ args: function () {
4206
4204
  return [this.base, this.power];
4207
4205
  },
4208
- eval: function _eval(vars, options) {
4206
+ eval: function (vars, options) {
4209
4207
  return Math.log(this.power.eval(vars, options)) / Math.log(this.base.eval(vars, options));
4210
4208
  },
4211
- codegen: function codegen() {
4209
+ codegen: function () {
4212
4210
  return "(Math.log(" + this.power.codegen() + ") / Math.log(" + this.base.codegen() + "))";
4213
4211
  },
4214
- print: function print() {
4212
+ print: function () {
4215
4213
  var power = "(" + this.power.print() + ")";
4216
4214
  if (this.isNatural()) {
4217
4215
  return "ln" + power;
@@ -4219,7 +4217,7 @@ _.extend(Log.prototype, {
4219
4217
  return "log_(" + this.base.print() + ") " + power;
4220
4218
  }
4221
4219
  },
4222
- tex: function tex() {
4220
+ tex: function () {
4223
4221
  var power = "(" + this.power.tex() + ")";
4224
4222
  if (this.isNatural()) {
4225
4223
  return "\\ln" + power;
@@ -4227,7 +4225,7 @@ _.extend(Log.prototype, {
4227
4225
  return "\\log_{" + this.base.tex() + "}" + power;
4228
4226
  }
4229
4227
  },
4230
- collect: function collect(options) {
4228
+ collect: function (options) {
4231
4229
  var log = this.recurse("collect", options);
4232
4230
  if (log.power instanceof Num && log.power.eval() === 1) {
4233
4231
  // e.g. ln(1) -> 0
@@ -4242,7 +4240,7 @@ _.extend(Log.prototype, {
4242
4240
  return log;
4243
4241
  }
4244
4242
  },
4245
- expand: function expand() {
4243
+ expand: function () {
4246
4244
  var log = this.recurse("expand");
4247
4245
  if (log.power instanceof Mul) {
4248
4246
  // might want behind super-simplify() flag
@@ -4268,7 +4266,7 @@ _.extend(Log.prototype, {
4268
4266
  hints: _.extend(Log.prototype.hints, {
4269
4267
  open: false
4270
4268
  }),
4271
- isPositive: function isPositive() {
4269
+ isPositive: function () {
4272
4270
  var log = this.collect();
4273
4271
  if (log.base instanceof Num && log.power instanceof Num) {
4274
4272
  return this.eval() > 0;
@@ -4276,21 +4274,21 @@ _.extend(Log.prototype, {
4276
4274
  return false;
4277
4275
  }
4278
4276
  },
4279
- needsExplicitMul: function needsExplicitMul() {
4277
+ needsExplicitMul: function () {
4280
4278
  return false;
4281
4279
  },
4282
- isNatural: function isNatural() {
4280
+ isNatural: function () {
4283
4281
  return this.base.equals(Const.e);
4284
4282
  }
4285
4283
  });
4286
4284
  _.extend(Log, {
4287
- natural: function natural() {
4285
+ natural: function () {
4288
4286
  return Const.e;
4289
4287
  },
4290
- common: function common() {
4288
+ common: function () {
4291
4289
  return Num.Ten;
4292
4290
  },
4293
- create: function create(base, power) {
4291
+ create: function (base, power) {
4294
4292
  var log = new Log(base, power);
4295
4293
  if (!power.hints.parens) {
4296
4294
  log = log.addHint("open");
@@ -4307,7 +4305,7 @@ function Trig(type, arg) {
4307
4305
  Trig.prototype = new Expr();
4308
4306
  _.extend(Trig.prototype, {
4309
4307
  func: Trig,
4310
- args: function args() {
4308
+ args: function () {
4311
4309
  return [this.type, this.arg];
4312
4310
  },
4313
4311
  functions: {
@@ -4315,7 +4313,7 @@ _.extend(Trig.prototype, {
4315
4313
  eval: Math.sin,
4316
4314
  codegen: "Math.sin((",
4317
4315
  tex: "\\sin",
4318
- expand: function expand() {
4316
+ expand: function () {
4319
4317
  return this;
4320
4318
  }
4321
4319
  },
@@ -4323,7 +4321,7 @@ _.extend(Trig.prototype, {
4323
4321
  eval: Math.cos,
4324
4322
  codegen: "Math.cos((",
4325
4323
  tex: "\\cos",
4326
- expand: function expand() {
4324
+ expand: function () {
4327
4325
  return this;
4328
4326
  }
4329
4327
  },
@@ -4331,37 +4329,37 @@ _.extend(Trig.prototype, {
4331
4329
  eval: Math.tan,
4332
4330
  codegen: "Math.tan((",
4333
4331
  tex: "\\tan",
4334
- expand: function expand() {
4332
+ expand: function () {
4335
4333
  return Mul.handleDivide(Trig.sin(this.arg), Trig.cos(this.arg));
4336
4334
  }
4337
4335
  },
4338
4336
  csc: {
4339
- eval: function _eval(arg) {
4337
+ eval: function (arg) {
4340
4338
  return 1 / Math.sin(arg);
4341
4339
  },
4342
4340
  codegen: "(1/Math.sin(",
4343
4341
  tex: "\\csc",
4344
- expand: function expand() {
4342
+ expand: function () {
4345
4343
  return Mul.handleDivide(Num.One, Trig.sin(this.arg));
4346
4344
  }
4347
4345
  },
4348
4346
  sec: {
4349
- eval: function _eval(arg) {
4347
+ eval: function (arg) {
4350
4348
  return 1 / Math.cos(arg);
4351
4349
  },
4352
4350
  codegen: "(1/Math.cos(",
4353
4351
  tex: "\\sec",
4354
- expand: function expand() {
4352
+ expand: function () {
4355
4353
  return Mul.handleDivide(Num.One, Trig.cos(this.arg));
4356
4354
  }
4357
4355
  },
4358
4356
  cot: {
4359
- eval: function _eval(arg) {
4357
+ eval: function (arg) {
4360
4358
  return 1 / Math.tan(arg);
4361
4359
  },
4362
4360
  codegen: "(1/Math.tan(",
4363
4361
  tex: "\\cot",
4364
- expand: function expand() {
4362
+ expand: function () {
4365
4363
  return Mul.handleDivide(Trig.cos(this.arg), Trig.sin(this.arg));
4366
4364
  }
4367
4365
  },
@@ -4381,114 +4379,114 @@ _.extend(Trig.prototype, {
4381
4379
  tex: "\\arctan"
4382
4380
  },
4383
4381
  arccsc: {
4384
- eval: function _eval(arg) {
4382
+ eval: function (arg) {
4385
4383
  return Math.asin(1 / arg);
4386
4384
  },
4387
4385
  codegen: "Math.asin(1/(",
4388
4386
  tex: "\\operatorname{arccsc}"
4389
4387
  },
4390
4388
  arcsec: {
4391
- eval: function _eval(arg) {
4389
+ eval: function (arg) {
4392
4390
  return Math.acos(1 / arg);
4393
4391
  },
4394
4392
  codegen: "Math.acos(1/(",
4395
4393
  tex: "\\operatorname{arcsec}"
4396
4394
  },
4397
4395
  arccot: {
4398
- eval: function _eval(arg) {
4396
+ eval: function (arg) {
4399
4397
  return Math.atan(1 / arg);
4400
4398
  },
4401
4399
  codegen: "Math.atan(1/(",
4402
4400
  tex: "\\operatorname{arccot}"
4403
4401
  },
4404
4402
  sinh: {
4405
- eval: function _eval(arg) {
4403
+ eval: function (arg) {
4406
4404
  return (Math.exp(arg) - Math.exp(-arg)) / 2;
4407
4405
  },
4408
- codegen: function codegen(argStr) {
4406
+ codegen: function (argStr) {
4409
4407
  return "((Math.exp(" + argStr + ") - Math.exp(-(" + argStr + "))) / 2)";
4410
4408
  },
4411
4409
  tex: "\\sinh",
4412
- expand: function expand() {
4410
+ expand: function () {
4413
4411
  return this;
4414
4412
  }
4415
4413
  },
4416
4414
  cosh: {
4417
- eval: function _eval(arg) {
4415
+ eval: function (arg) {
4418
4416
  return (Math.exp(arg) + Math.exp(-arg)) / 2;
4419
4417
  },
4420
- codegen: function codegen(argStr) {
4418
+ codegen: function (argStr) {
4421
4419
  return "((Math.exp(" + argStr + ") + Math.exp(-(" + argStr + "))) / 2)";
4422
4420
  },
4423
4421
  tex: "\\cosh",
4424
- expand: function expand() {
4422
+ expand: function () {
4425
4423
  return this;
4426
4424
  }
4427
4425
  },
4428
4426
  tanh: {
4429
- eval: function _eval(arg) {
4427
+ eval: function (arg) {
4430
4428
  return (Math.exp(arg) - Math.exp(-arg)) / (Math.exp(arg) + Math.exp(-arg));
4431
4429
  },
4432
- codegen: function codegen(argStr) {
4430
+ codegen: function (argStr) {
4433
4431
  return "(" + "(Math.exp(" + argStr + ") - Math.exp(-(" + argStr + ")))" + " / " + "(Math.exp(" + argStr + ") + Math.exp(-(" + argStr + ")))" + ")";
4434
4432
  },
4435
4433
  tex: "\\tanh",
4436
- expand: function expand() {
4434
+ expand: function () {
4437
4435
  return Mul.handleDivide(Trig.sinh(this.arg), Trig.cosh(this.arg));
4438
4436
  }
4439
4437
  },
4440
4438
  csch: {
4441
- eval: function _eval(arg) {
4439
+ eval: function (arg) {
4442
4440
  return 2 / (Math.exp(arg) - Math.exp(-arg));
4443
4441
  },
4444
- codegen: function codegen(argStr) {
4442
+ codegen: function (argStr) {
4445
4443
  return "(2 / (Math.exp(" + argStr + ") - Math.exp(-(" + argStr + "))))";
4446
4444
  },
4447
4445
  tex: "\\csch",
4448
- expand: function expand() {
4446
+ expand: function () {
4449
4447
  return Mul.handleDivide(Num.One, Trig.sinh(this.arg));
4450
4448
  }
4451
4449
  },
4452
4450
  sech: {
4453
- eval: function _eval(arg) {
4451
+ eval: function (arg) {
4454
4452
  return 2 / (Math.exp(arg) + Math.exp(-arg));
4455
4453
  },
4456
- codegen: function codegen(argStr) {
4454
+ codegen: function (argStr) {
4457
4455
  return "(2 / (Math.exp(" + argStr + ") + Math.exp(-(" + argStr + "))))";
4458
4456
  },
4459
4457
  tex: "\\sech",
4460
- expand: function expand() {
4458
+ expand: function () {
4461
4459
  return Mul.handleDivide(Num.One, Trig.cosh(this.arg));
4462
4460
  }
4463
4461
  },
4464
4462
  coth: {
4465
- eval: function _eval(arg) {
4463
+ eval: function (arg) {
4466
4464
  return (Math.exp(arg) + Math.exp(-arg)) / (Math.exp(arg) - Math.exp(-arg));
4467
4465
  },
4468
- codegen: function codegen(argStr) {
4466
+ codegen: function (argStr) {
4469
4467
  return "(" + "(Math.exp(" + argStr + ") + Math.exp(-(" + argStr + ")))" + " / " + "(Math.exp(" + argStr + ") - Math.exp(-(" + argStr + ")))" + ")";
4470
4468
  },
4471
4469
  tex: "\\coth",
4472
- expand: function expand() {
4470
+ expand: function () {
4473
4471
  return Mul.handleDivide(Trig.cosh(this.arg), Trig.sinh(this.arg));
4474
4472
  }
4475
4473
  }
4476
4474
  },
4477
- isEven: function isEven() {
4475
+ isEven: function () {
4478
4476
  return _.contains(["cos", "sec"], this.type);
4479
4477
  },
4480
- isInverse: function isInverse() {
4478
+ isInverse: function () {
4481
4479
  return this.type.indexOf("arc") === 0;
4482
4480
  },
4483
- isBasic: function isBasic() {
4481
+ isBasic: function () {
4484
4482
  return _.contains(["sin", "cos"], this.type);
4485
4483
  },
4486
- eval: function _eval(vars, options) {
4484
+ eval: function (vars, options) {
4487
4485
  var func = this.functions[this.type].eval;
4488
4486
  var arg = this.arg.eval(vars, options);
4489
4487
  return func(arg);
4490
4488
  },
4491
- codegen: function codegen() {
4489
+ codegen: function () {
4492
4490
  var func = this.functions[this.type].codegen;
4493
4491
  if (typeof func === "function") {
4494
4492
  return func(this.arg.codegen());
@@ -4498,10 +4496,10 @@ _.extend(Trig.prototype, {
4498
4496
  throw new Error("codegen not implemented for " + this.type);
4499
4497
  }
4500
4498
  },
4501
- print: function print() {
4499
+ print: function () {
4502
4500
  return this.type + "(" + this.arg.print() + ")";
4503
4501
  },
4504
- tex: function tex(options) {
4502
+ tex: function (options) {
4505
4503
  var func = this.functions[this.type].tex;
4506
4504
  var arg = "(" + this.arg.tex() + ")";
4507
4505
  return options && options.split ? [func, arg] : func + arg;
@@ -4509,7 +4507,7 @@ _.extend(Trig.prototype, {
4509
4507
  hints: _.extend(Trig.prototype.hints, {
4510
4508
  open: false
4511
4509
  }),
4512
- isPositive: function isPositive() {
4510
+ isPositive: function () {
4513
4511
  var trig = this.collect();
4514
4512
  if (trig.arg instanceof Num) {
4515
4513
  return this.eval() > 0;
@@ -4517,7 +4515,7 @@ _.extend(Trig.prototype, {
4517
4515
  return false;
4518
4516
  }
4519
4517
  },
4520
- completeParse: function completeParse() {
4518
+ completeParse: function () {
4521
4519
  if (this.exp) {
4522
4520
  var pow = new Pow(this, this.exp);
4523
4521
  this.exp = undefined;
@@ -4527,10 +4525,10 @@ _.extend(Trig.prototype, {
4527
4525
  }
4528
4526
  },
4529
4527
  // TODO(alex): does every new node type need to redefine these?
4530
- needsExplicitMul: function needsExplicitMul() {
4528
+ needsExplicitMul: function () {
4531
4529
  return false;
4532
4530
  },
4533
- expand: function expand() {
4531
+ expand: function () {
4534
4532
  var trig = this.recurse("expand");
4535
4533
  if (!trig.isInverse()) {
4536
4534
  // e.g. tan(x) -> sin(x)/cos(x)
@@ -4540,7 +4538,7 @@ _.extend(Trig.prototype, {
4540
4538
  return trig;
4541
4539
  }
4542
4540
  },
4543
- collect: function collect(options) {
4541
+ collect: function (options) {
4544
4542
  var trig = this.recurse("collect", options);
4545
4543
  if (!trig.isInverse() && trig.arg.isNegative()) {
4546
4544
  var arg;
@@ -4562,7 +4560,7 @@ _.extend(Trig.prototype, {
4562
4560
  }
4563
4561
  });
4564
4562
  _.extend(Trig, {
4565
- create: function create(pair, arg) {
4563
+ create: function (pair, arg) {
4566
4564
  var type = pair[0];
4567
4565
  var exp = pair[1];
4568
4566
  if (exp && exp.equals(Num.Neg)) {
@@ -4579,16 +4577,16 @@ _.extend(Trig, {
4579
4577
  }
4580
4578
  return trig;
4581
4579
  },
4582
- sin: function sin(arg) {
4580
+ sin: function (arg) {
4583
4581
  return new Trig("sin", arg);
4584
4582
  },
4585
- cos: function cos(arg) {
4583
+ cos: function (arg) {
4586
4584
  return new Trig("cos", arg);
4587
4585
  },
4588
- sinh: function sinh(arg) {
4586
+ sinh: function (arg) {
4589
4587
  return new Trig("sinh", arg);
4590
4588
  },
4591
- cosh: function cosh(arg) {
4589
+ cosh: function (arg) {
4592
4590
  return new Trig("cosh", arg);
4593
4591
  }
4594
4592
  });
@@ -4598,22 +4596,22 @@ function Abs(arg) {
4598
4596
  Abs.prototype = new Expr();
4599
4597
  _.extend(Abs.prototype, {
4600
4598
  func: Abs,
4601
- args: function args() {
4599
+ args: function () {
4602
4600
  return [this.arg];
4603
4601
  },
4604
- eval: function _eval(vars, options) {
4602
+ eval: function (vars, options) {
4605
4603
  return Math.abs(this.arg.eval(vars, options));
4606
4604
  },
4607
- codegen: function codegen() {
4605
+ codegen: function () {
4608
4606
  return "Math.abs(" + this.arg.codegen() + ")";
4609
4607
  },
4610
- print: function print() {
4608
+ print: function () {
4611
4609
  return "abs(" + this.arg.print() + ")";
4612
4610
  },
4613
- tex: function tex() {
4611
+ tex: function () {
4614
4612
  return "\\left|" + this.arg.tex() + "\\right|";
4615
4613
  },
4616
- collect: function collect(options) {
4614
+ collect: function (options) {
4617
4615
  var abs = this.recurse("collect", options);
4618
4616
  if (abs.arg.isPositive()) {
4619
4617
  // e.g. |2^x| -> 2^x
@@ -4642,7 +4640,7 @@ _.extend(Abs.prototype, {
4642
4640
  }
4643
4641
  },
4644
4642
  // this should definitely be behind a super-simplify flag
4645
- expand: function expand() {
4643
+ expand: function () {
4646
4644
  var abs = this.recurse("expand");
4647
4645
  if (abs.arg instanceof Mul) {
4648
4646
  // e.g. |xyz| -> |x|*|y|*|z|
@@ -4654,7 +4652,7 @@ _.extend(Abs.prototype, {
4654
4652
  return abs;
4655
4653
  }
4656
4654
  },
4657
- isPositive: function isPositive() {
4655
+ isPositive: function () {
4658
4656
  return true;
4659
4657
  }
4660
4658
  });
@@ -4668,13 +4666,13 @@ function Eq(left, type, right) {
4668
4666
  Eq.prototype = new Expr();
4669
4667
  _.extend(Eq.prototype, {
4670
4668
  func: Eq,
4671
- args: function args() {
4669
+ args: function () {
4672
4670
  return [this.left, this.type, this.right];
4673
4671
  },
4674
- needsExplicitMul: function needsExplicitMul() {
4672
+ needsExplicitMul: function () {
4675
4673
  return false;
4676
4674
  },
4677
- print: function print() {
4675
+ print: function () {
4678
4676
  return this.left.print() + this.type + this.right.print();
4679
4677
  },
4680
4678
  signs: {
@@ -4685,10 +4683,10 @@ _.extend(Eq.prototype, {
4685
4683
  "<=": " \\le ",
4686
4684
  ">=": " \\ge "
4687
4685
  },
4688
- tex: function tex() {
4686
+ tex: function () {
4689
4687
  return this.left.tex() + this.signs[this.type] + this.right.tex();
4690
4688
  },
4691
- normalize: function normalize() {
4689
+ normalize: function () {
4692
4690
  var eq = this.recurse("normalize");
4693
4691
  if (_.contains([">", ">="], eq.type)) {
4694
4692
  // inequalities should have the smaller side on the left
@@ -4701,7 +4699,7 @@ _.extend(Eq.prototype, {
4701
4699
  // the expression is normalized to a canonical form
4702
4700
  // e.g. y/2=x/4 -> y/2-x/4(=0) -> 2y-x(=0)
4703
4701
  // unless unfactored is specified, will then divide through
4704
- asExpr: function asExpr(unfactored) {
4702
+ asExpr: function (unfactored) {
4705
4703
  var isZero = function isZero(expr) {
4706
4704
  return expr instanceof Num && expr.isSimple() && expr.eval() === 0;
4707
4705
  };
@@ -4753,7 +4751,7 @@ _.extend(Eq.prototype, {
4753
4751
  // e.g. 2y-4x(=0) -> y-2x(=0)
4754
4752
  // TODO(alex): Make it an option to only divide by variables/expressions
4755
4753
  // guaranteed to be nonzero
4756
- divideThrough: function divideThrough(expr) {
4754
+ divideThrough: function (expr) {
4757
4755
  var isInequality = !this.isEquality();
4758
4756
  var simplified = expr.simplify({
4759
4757
  once: true
@@ -4809,10 +4807,10 @@ _.extend(Eq.prototype, {
4809
4807
  return dividedResult;
4810
4808
  }
4811
4809
  },
4812
- isEquality: function isEquality() {
4810
+ isEquality: function () {
4813
4811
  return _.contains(["=", "<>"], this.type);
4814
4812
  },
4815
- compare: function compare(other) {
4813
+ compare: function (other) {
4816
4814
  // expression comparisons are handled by Expr.compare()
4817
4815
  if (!(other instanceof Eq)) {
4818
4816
  return false;
@@ -4835,7 +4833,7 @@ _.extend(Eq.prototype, {
4835
4833
  }
4836
4834
  },
4837
4835
  // should only be done after compare() returns true to avoid false positives
4838
- sameForm: function sameForm(other) {
4836
+ sameForm: function (other) {
4839
4837
  var eq1 = this.normalize();
4840
4838
  var eq2 = other.normalize();
4841
4839
  var same = eq1.left.sameForm(eq2.left) && eq1.right.sameForm(eq2.right);
@@ -4848,7 +4846,7 @@ _.extend(Eq.prototype, {
4848
4846
  },
4849
4847
  // we don't want to override collect because it would turn y=x into y-x(=0)
4850
4848
  // instead, we ask if the equation was in that form, would it be simplified?
4851
- isSimplified: function isSimplified() {
4849
+ isSimplified: function () {
4852
4850
  var expr = this.asExpr( /* unfactored */true);
4853
4851
  var simplified = this.divideThrough(expr).simplify();
4854
4852
  return expr.equals(simplified) && this.left.isSimplified() && this.right.isSimplified();
@@ -4856,7 +4854,7 @@ _.extend(Eq.prototype, {
4856
4854
  });
4857
4855
  _.extend(Eq.prototype, {
4858
4856
  // Assumptions: Expression is of the form a+bx, and we solve for x
4859
- solveLinearEquationForVariable: function solveLinearEquationForVariable(variable) {
4857
+ solveLinearEquationForVariable: function (variable) {
4860
4858
  var expr = this.asExpr();
4861
4859
  if (!expr.is(Add) || expr.terms.length !== 2) {
4862
4860
  throw new Error("Can only handle linear equations of the form " + "a + bx (= 0)");
@@ -4880,10 +4878,10 @@ _.extend(Eq.prototype, {
4880
4878
  function Symbol() {}
4881
4879
  Symbol.prototype = new Expr();
4882
4880
  _.extend(Symbol.prototype, {
4883
- needsExplicitMul: function needsExplicitMul() {
4881
+ needsExplicitMul: function () {
4884
4882
  return false;
4885
4883
  },
4886
- findGCD: function findGCD(factor) {
4884
+ findGCD: function (factor) {
4887
4885
  if (factor instanceof Symbol || factor instanceof Num) {
4888
4886
  return this.equals(factor) ? this : Num.One;
4889
4887
  } else {
@@ -4900,16 +4898,16 @@ function Func(symbol, arg) {
4900
4898
  Func.prototype = new Symbol();
4901
4899
  _.extend(Func.prototype, {
4902
4900
  func: Func,
4903
- args: function args() {
4901
+ args: function () {
4904
4902
  return [this.symbol, this.arg];
4905
4903
  },
4906
- print: function print() {
4904
+ print: function () {
4907
4905
  return this.symbol + "(" + this.arg.print() + ")";
4908
4906
  },
4909
- tex: function tex() {
4907
+ tex: function () {
4910
4908
  return this.symbol + "(" + this.arg.tex() + ")";
4911
4909
  },
4912
- eval: function _eval(vars, options) {
4910
+ eval: function (vars, options) {
4913
4911
  var arg = this.arg;
4914
4912
  var func = vars[this.symbol];
4915
4913
  var newVars = _.extend(_.clone(vars), {
@@ -4922,20 +4920,20 @@ _.extend(Func.prototype, {
4922
4920
  // If parsedFunc isn't actually parsed, return its error
4923
4921
  return parsedFunc;
4924
4922
  },
4925
- codegen: function codegen() {
4923
+ codegen: function () {
4926
4924
  return 'vars["' + this.symbol + '"](' + this.arg.codegen() + ")";
4927
4925
  },
4928
- getUnits: function getUnits() {
4926
+ getUnits: function () {
4929
4927
  return this.arg.getUnits();
4930
4928
  },
4931
- getVars: function getVars(excludeFunc) {
4929
+ getVars: function (excludeFunc) {
4932
4930
  if (excludeFunc) {
4933
4931
  return this.arg.getVars();
4934
4932
  } else {
4935
4933
  return _.union(this.arg.getVars(), [this.symbol]).sort();
4936
4934
  }
4937
4935
  },
4938
- getConsts: function getConsts() {
4936
+ getConsts: function () {
4939
4937
  return this.arg.getConsts();
4940
4938
  }
4941
4939
  });
@@ -4948,16 +4946,16 @@ function Var(symbol, subscript) {
4948
4946
  Var.prototype = new Symbol();
4949
4947
  _.extend(Var.prototype, {
4950
4948
  func: Var,
4951
- args: function args() {
4949
+ args: function () {
4952
4950
  return [this.symbol, this.subscript];
4953
4951
  },
4954
- exprArgs: function exprArgs() {
4952
+ exprArgs: function () {
4955
4953
  return [];
4956
4954
  },
4957
- recurse: function recurse() {
4955
+ recurse: function () {
4958
4956
  return this;
4959
4957
  },
4960
- print: function print() {
4958
+ print: function () {
4961
4959
  var sub = "";
4962
4960
  if (this.subscript) {
4963
4961
  sub = "_(" + this.subscript.print() + ")";
@@ -4966,7 +4964,7 @@ _.extend(Var.prototype, {
4966
4964
  },
4967
4965
  // Provide a way to easily evalate expressions with the common case,
4968
4966
  // subscripts that consist of a single number or symbol e.g. x_a or x_42
4969
- prettyPrint: function prettyPrint() {
4967
+ prettyPrint: function () {
4970
4968
  var sub = this.subscript;
4971
4969
  if (sub && (sub instanceof Num || sub instanceof Symbol)) {
4972
4970
  return this.symbol + "_" + sub.print();
@@ -4974,7 +4972,7 @@ _.extend(Var.prototype, {
4974
4972
  return this.print();
4975
4973
  }
4976
4974
  },
4977
- tex: function tex() {
4975
+ tex: function () {
4978
4976
  var sub = "";
4979
4977
  if (this.subscript) {
4980
4978
  sub = "_{" + this.subscript.tex() + "}";
@@ -4982,19 +4980,19 @@ _.extend(Var.prototype, {
4982
4980
  var prefix = this.symbol.length > 1 ? "\\" : "";
4983
4981
  return prefix + this.symbol + sub;
4984
4982
  },
4985
- repr: function repr() {
4983
+ repr: function () {
4986
4984
  return "Var(" + this.print() + ")";
4987
4985
  },
4988
- eval: function _eval(vars, options) {
4986
+ eval: function (vars, options) {
4989
4987
  return vars[this.prettyPrint()];
4990
4988
  },
4991
- codegen: function codegen() {
4989
+ codegen: function () {
4992
4990
  return 'vars["' + this.prettyPrint() + '"]';
4993
4991
  },
4994
- getVars: function getVars() {
4992
+ getVars: function () {
4995
4993
  return [this.prettyPrint()];
4996
4994
  },
4997
- isPositive: function isPositive() {
4995
+ isPositive: function () {
4998
4996
  return false;
4999
4997
  }
5000
4998
  });
@@ -5006,47 +5004,47 @@ function Const(symbol) {
5006
5004
  Const.prototype = new Symbol();
5007
5005
  _.extend(Const.prototype, {
5008
5006
  func: Const,
5009
- args: function args() {
5007
+ args: function () {
5010
5008
  return [this.symbol];
5011
5009
  },
5012
- recurse: function recurse() {
5010
+ recurse: function () {
5013
5011
  return this;
5014
5012
  },
5015
- eval: function _eval(vars, options) {
5013
+ eval: function (vars, options) {
5016
5014
  if (this.symbol === "pi") {
5017
5015
  return Math.PI;
5018
5016
  } else if (this.symbol === "e") {
5019
5017
  return Math.E;
5020
5018
  }
5021
5019
  },
5022
- codegen: function codegen() {
5020
+ codegen: function () {
5023
5021
  if (this.symbol === "pi") {
5024
5022
  return "Math.PI";
5025
5023
  } else if (this.symbol === "e") {
5026
5024
  return "Math.E";
5027
5025
  }
5028
5026
  },
5029
- print: function print() {
5027
+ print: function () {
5030
5028
  return this.symbol;
5031
5029
  },
5032
- tex: function tex() {
5030
+ tex: function () {
5033
5031
  if (this.symbol === "pi") {
5034
5032
  return "\\pi ";
5035
5033
  } else if (this.symbol === "e") {
5036
5034
  return "e";
5037
5035
  }
5038
5036
  },
5039
- isPositive: function isPositive() {
5037
+ isPositive: function () {
5040
5038
  return this.eval() > 0;
5041
5039
  },
5042
- abs: function abs() {
5040
+ abs: function () {
5043
5041
  if (this.eval() > 0) {
5044
5042
  return this;
5045
5043
  } else {
5046
5044
  return Mul.handleNegative(this);
5047
5045
  }
5048
5046
  },
5049
- getConsts: function getConsts() {
5047
+ getConsts: function () {
5050
5048
  return [this.print()];
5051
5049
  }
5052
5050
  });
@@ -5057,16 +5055,16 @@ Const.pi = new Const("pi");
5057
5055
  function Num() {}
5058
5056
  Num.prototype = new Expr();
5059
5057
  _.extend(Num.prototype, {
5060
- repr: function repr() {
5058
+ repr: function () {
5061
5059
  return this.print();
5062
5060
  },
5063
- strip: function strip() {
5061
+ strip: function () {
5064
5062
  return this.abs();
5065
5063
  },
5066
- recurse: function recurse() {
5064
+ recurse: function () {
5067
5065
  return this;
5068
5066
  },
5069
- codegen: function codegen() {
5067
+ codegen: function () {
5070
5068
  return this.print();
5071
5069
  },
5072
5070
  // takes another Num and returns a new Num
@@ -5074,22 +5072,22 @@ _.extend(Num.prototype, {
5074
5072
  mul: abstract,
5075
5073
  // returns this Num's additive inverse
5076
5074
  negate: abstract,
5077
- isSubtract: function isSubtract() {
5075
+ isSubtract: function () {
5078
5076
  return this.hints.subtract;
5079
5077
  },
5080
5078
  // return the absolute value of the number
5081
5079
  abs: abstract,
5082
- needsExplicitMul: function needsExplicitMul() {
5080
+ needsExplicitMul: function () {
5083
5081
  return true;
5084
5082
  },
5085
5083
  findGCD: abstract,
5086
- isPositive: function isPositive() {
5084
+ isPositive: function () {
5087
5085
  return this.eval() > 0;
5088
5086
  },
5089
- isNegative: function isNegative() {
5087
+ isNegative: function () {
5090
5088
  return this.eval() < 0;
5091
5089
  },
5092
- asPositiveFactor: function asPositiveFactor() {
5090
+ asPositiveFactor: function () {
5093
5091
  return this.isPositive() ? this : this.abs();
5094
5092
  },
5095
5093
  // hints for interpreting and rendering user input
@@ -5105,7 +5103,7 @@ _.extend(Num.prototype, {
5105
5103
  // e.g. for reals, ints and floats are simple
5106
5104
  isSimple: abstract,
5107
5105
  // Based on http://stackoverflow.com/a/10454560/2571482
5108
- getDecimalPlaces: function getDecimalPlaces() {
5106
+ getDecimalPlaces: function () {
5109
5107
  var match = ("" + this.n).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
5110
5108
  if (match) {
5111
5109
  return Math.max(0,
@@ -5134,34 +5132,34 @@ function Rational(numerator, denominator) {
5134
5132
  Rational.prototype = new Num();
5135
5133
  _.extend(Rational.prototype, {
5136
5134
  func: Rational,
5137
- args: function args() {
5135
+ args: function () {
5138
5136
  return [this.n, this.d];
5139
5137
  },
5140
- eval: function _eval() {
5138
+ eval: function () {
5141
5139
  return this.n / this.d;
5142
5140
  },
5143
- print: function print() {
5141
+ print: function () {
5144
5142
  return this.n.toString() + "/" + this.d.toString();
5145
5143
  },
5146
- tex: function tex() {
5144
+ tex: function () {
5147
5145
  var tex = "\\frac{" + Math.abs(this.n).toString() + "}{" + this.d.toString() + "}";
5148
5146
  return this.n < 0 ? "-" + tex : tex;
5149
5147
  },
5150
- add: function add(num, options) {
5148
+ add: function (num, options) {
5151
5149
  if (num instanceof Rational) {
5152
5150
  return new Rational(this.n * num.d + this.d * num.n, this.d * num.d).collect();
5153
5151
  } else {
5154
5152
  return num.add(this, options);
5155
5153
  }
5156
5154
  },
5157
- mul: function mul(num, options) {
5155
+ mul: function (num, options) {
5158
5156
  if (num instanceof Rational) {
5159
5157
  return new Rational(this.n * num.n, this.d * num.d).collect();
5160
5158
  } else {
5161
5159
  return num.mul(this, options);
5162
5160
  }
5163
5161
  },
5164
- collect: function collect() {
5162
+ collect: function () {
5165
5163
  var gcd = Num.findGCD(this.n, this.d);
5166
5164
  var n = this.n / gcd;
5167
5165
  var d = this.d / gcd;
@@ -5171,13 +5169,13 @@ _.extend(Rational.prototype, {
5171
5169
  return new Rational(n, d);
5172
5170
  }
5173
5171
  },
5174
- negate: function negate() {
5172
+ negate: function () {
5175
5173
  return new Rational(-this.n, this.d);
5176
5174
  },
5177
- abs: function abs() {
5175
+ abs: function () {
5178
5176
  return new Rational(Math.abs(this.n), this.d);
5179
5177
  },
5180
- findGCD: function findGCD(factor) {
5178
+ findGCD: function (factor) {
5181
5179
  // Attempt to factor out common numerators and denominators to return
5182
5180
  // a Rational instead of a Float
5183
5181
  if (factor instanceof Rational) {
@@ -5194,7 +5192,7 @@ _.extend(Rational.prototype, {
5194
5192
  }
5195
5193
  },
5196
5194
  // for now, assuming that exp is a Num
5197
- raiseToThe: function raiseToThe(exp) {
5195
+ raiseToThe: function (exp) {
5198
5196
  if (exp instanceof Int) {
5199
5197
  var positive = exp.eval() > 0;
5200
5198
  var abs = exp.abs().eval();
@@ -5209,13 +5207,13 @@ _.extend(Rational.prototype, {
5209
5207
  return new Float(this.eval()).raiseToThe(exp);
5210
5208
  }
5211
5209
  },
5212
- getDenominator: function getDenominator() {
5210
+ getDenominator: function () {
5213
5211
  return new Int(this.d);
5214
5212
  },
5215
- isSimple: function isSimple() {
5213
+ isSimple: function () {
5216
5214
  return false;
5217
5215
  },
5218
- asRational: function asRational() {
5216
+ asRational: function () {
5219
5217
  return this;
5220
5218
  }
5221
5219
  });
@@ -5227,25 +5225,25 @@ function Int(number) {
5227
5225
  Int.prototype = new Rational(0, 1);
5228
5226
  _.extend(Int.prototype, {
5229
5227
  func: Int,
5230
- args: function args() {
5228
+ args: function () {
5231
5229
  return [this.n];
5232
5230
  },
5233
- print: function print() {
5231
+ print: function () {
5234
5232
  return this.n.toString();
5235
5233
  },
5236
- tex: function tex() {
5234
+ tex: function () {
5237
5235
  return this.n.toString();
5238
5236
  },
5239
- negate: function negate() {
5237
+ negate: function () {
5240
5238
  return new Int(-this.n);
5241
5239
  },
5242
- abs: function abs() {
5240
+ abs: function () {
5243
5241
  return new Int(Math.abs(this.n));
5244
5242
  },
5245
- isSimple: function isSimple() {
5243
+ isSimple: function () {
5246
5244
  return true;
5247
5245
  },
5248
- findGCD: function findGCD(factor) {
5246
+ findGCD: function (factor) {
5249
5247
  if (factor instanceof Int) {
5250
5248
  return new Int(Num.findGCD(this.n, factor.n));
5251
5249
  } else {
@@ -5254,7 +5252,7 @@ _.extend(Int.prototype, {
5254
5252
  }
5255
5253
  });
5256
5254
  _.extend(Int, {
5257
- create: function create(n) {
5255
+ create: function (n) {
5258
5256
  return new Int(n).addHint("entered");
5259
5257
  }
5260
5258
  });
@@ -5266,46 +5264,46 @@ function Float(number) {
5266
5264
  Float.prototype = new Num();
5267
5265
  _.extend(Float.prototype, {
5268
5266
  func: Float,
5269
- args: function args() {
5267
+ args: function () {
5270
5268
  return [this.n];
5271
5269
  },
5272
- eval: function _eval() {
5270
+ eval: function () {
5273
5271
  return this.n;
5274
5272
  },
5275
5273
  // TODO(alex): when we internationalize number parsing/display
5276
5274
  // we should make sure to use the appropriate decimal mark here
5277
- print: function print() {
5275
+ print: function () {
5278
5276
  return this.n.toString();
5279
5277
  },
5280
- tex: function tex() {
5278
+ tex: function () {
5281
5279
  return this.n.toString();
5282
5280
  },
5283
- add: function add(num, options) {
5281
+ add: function (num, options) {
5284
5282
  if (options && options.preciseFloats) {
5285
5283
  return Float.toDecimalPlaces(this.n + num.eval(), Math.max(this.getDecimalPlaces(), num.getDecimalPlaces()));
5286
5284
  } else {
5287
5285
  return new Float(this.n + num.eval()).collect();
5288
5286
  }
5289
5287
  },
5290
- mul: function mul(num, options) {
5288
+ mul: function (num, options) {
5291
5289
  if (options && options.preciseFloats) {
5292
5290
  return Float.toDecimalPlaces(this.n * num.eval(), this.getDecimalPlaces() + num.getDecimalPlaces());
5293
5291
  } else {
5294
5292
  return new Float(this.n * num.eval()).collect();
5295
5293
  }
5296
5294
  },
5297
- collect: function collect() {
5295
+ collect: function () {
5298
5296
  // We used to simplify Floats to Ints here whenever possible, but no
5299
5297
  // longer do so in order to preserve significant figures.
5300
5298
  return this;
5301
5299
  },
5302
- negate: function negate() {
5300
+ negate: function () {
5303
5301
  return new Float(-this.n);
5304
5302
  },
5305
- abs: function abs() {
5303
+ abs: function () {
5306
5304
  return new Float(Math.abs(this.n));
5307
5305
  },
5308
- findGCD: function findGCD(factor) {
5306
+ findGCD: function (factor) {
5309
5307
  if (factor instanceof Num) {
5310
5308
  return new Float(Num.findGCD(this.eval(), factor.eval())).collect();
5311
5309
  } else {
@@ -5313,7 +5311,7 @@ _.extend(Float.prototype, {
5313
5311
  }
5314
5312
  },
5315
5313
  // for now, assuming that exp is a Num
5316
- raiseToThe: function raiseToThe(exp, options) {
5314
+ raiseToThe: function (exp, options) {
5317
5315
  if (options && options.preciseFloats && exp instanceof Int && exp.n > 1) {
5318
5316
  return Float.toDecimalPlaces(new Pow(this, exp).eval(), this.getDecimalPlaces() * exp.n);
5319
5317
  } else {
@@ -5321,7 +5319,7 @@ _.extend(Float.prototype, {
5321
5319
  }
5322
5320
  },
5323
5321
  // only to be used on non-repeating decimals (e.g. user-provided)
5324
- asRational: function asRational() {
5322
+ asRational: function () {
5325
5323
  var parts = this.n.toString().split(".");
5326
5324
  if (parts.length === 1) {
5327
5325
  return new Rational(this.n, 1);
@@ -5331,27 +5329,27 @@ _.extend(Float.prototype, {
5331
5329
  return new Rational(numerator, denominator).collect();
5332
5330
  }
5333
5331
  },
5334
- getDenominator: function getDenominator() {
5332
+ getDenominator: function () {
5335
5333
  return this.asRational().getDenominator();
5336
5334
  },
5337
- isSimple: function isSimple() {
5335
+ isSimple: function () {
5338
5336
  return true;
5339
5337
  }
5340
5338
  });
5341
5339
  _.extend(Float, {
5342
- create: function create(n) {
5340
+ create: function (n) {
5343
5341
  return new Float(n).addHint("entered");
5344
5342
  },
5345
5343
  // Account for floating point imprecision by explicitly controlling the
5346
5344
  // number of decimal places in common operations (e.g. +, *, ^)
5347
- toDecimalPlaces: function toDecimalPlaces(n, places) {
5345
+ toDecimalPlaces: function (n, places) {
5348
5346
  return new Float(+n.toFixed(Math.min(places, 20))).collect();
5349
5347
  }
5350
5348
  });
5351
5349
 
5352
5350
  // static methods and fields that are best defined on Num
5353
5351
  _.extend(Num, {
5354
- negativeOne: function negativeOne(hint) {
5352
+ negativeOne: function (hint) {
5355
5353
  if (hint === "subtract") {
5356
5354
  return Num.Sub;
5357
5355
  } else if (hint === "divide") {
@@ -5361,7 +5359,7 @@ _.extend(Num, {
5361
5359
  }
5362
5360
  },
5363
5361
  // find the greatest common denominator
5364
- findGCD: function findGCD(a, b) {
5362
+ findGCD: function (a, b) {
5365
5363
  var mod;
5366
5364
  a = Math.abs(a);
5367
5365
  b = Math.abs(b);
@@ -5379,12 +5377,12 @@ _.extend(Num, {
5379
5377
  }
5380
5378
  return a;
5381
5379
  },
5382
- min: function min() {
5380
+ min: function () {
5383
5381
  return _.min(_.toArray(arguments), function (num) {
5384
5382
  return num.eval();
5385
5383
  });
5386
5384
  },
5387
- max: function max() {
5385
+ max: function () {
5388
5386
  return _.max(_.toArray(arguments), function (num) {
5389
5387
  return num.eval();
5390
5388
  });
@@ -5423,7 +5421,7 @@ parser.yy = {
5423
5421
  Float: Float,
5424
5422
  parseError: parseError,
5425
5423
  constants: ["e"],
5426
- symbolLexer: function symbolLexer(symbol) {
5424
+ symbolLexer: function (symbol) {
5427
5425
  if (_.contains(parser.yy.constants, symbol)) {
5428
5426
  return "CONST";
5429
5427
  } else if (_.contains(parser.yy.functions, symbol)) {
@@ -5433,7 +5431,7 @@ parser.yy = {
5433
5431
  }
5434
5432
  }
5435
5433
  };
5436
- var parse = function parse(input, options) {
5434
+ const parse = function parse(input, options) {
5437
5435
  try {
5438
5436
  if (options && options.functions) {
5439
5437
  // reserve the symbol "i" for complex numbers
@@ -5499,7 +5497,7 @@ var unprefixify = function unprefixify(symbol) {
5499
5497
  return new Unit(symbol);
5500
5498
  }
5501
5499
  };
5502
- var unitParse = function unitParse(input) {
5500
+ const unitParse = function unitParse(input) {
5503
5501
  try {
5504
5502
  var parseResult = unitParser.parse(input);
5505
5503
 
@@ -5555,13 +5553,13 @@ var unitParse = function unitParse(input) {
5555
5553
  };
5556
5554
  _.extend(Unit.prototype, {
5557
5555
  func: Unit,
5558
- args: function args() {
5556
+ args: function () {
5559
5557
  return [this.symbol];
5560
5558
  },
5561
- recurse: function recurse() {
5559
+ recurse: function () {
5562
5560
  return this;
5563
5561
  },
5564
- eval: function _eval(vars, options) {
5562
+ eval: function (vars, options) {
5565
5563
  // This is called when comparing units. A unit doesn't affect the
5566
5564
  // numerical value of its coefficient, so this needs to be 1.
5567
5565
  //
@@ -5571,23 +5569,23 @@ _.extend(Unit.prototype, {
5571
5569
  // However, there are a couple tests checking this.
5572
5570
  return 1;
5573
5571
  },
5574
- getUnits: function getUnits() {
5572
+ getUnits: function () {
5575
5573
  return [{
5576
5574
  unit: this.symbol,
5577
5575
  pow: 1
5578
5576
  }];
5579
5577
  },
5580
- codegen: function codegen() {
5578
+ codegen: function () {
5581
5579
  return "1";
5582
5580
  },
5583
- print: function print() {
5581
+ print: function () {
5584
5582
  return this.symbol;
5585
5583
  },
5586
- tex: function tex() {
5584
+ tex: function () {
5587
5585
  return this.symbol;
5588
5586
  },
5589
5587
  // Simplify units by replacing prefixes with multiplication
5590
- collect: function collect(options) {
5588
+ collect: function (options) {
5591
5589
  if (_(baseUnits).has(this.symbol)) {
5592
5590
  return this;
5593
5591
  } else if (_(derivedUnits).has(this.symbol)) {
@@ -5810,14 +5808,14 @@ var derivedUnits = {
5810
5808
  // other
5811
5809
  Hz: makeAlias("| / s", hasPrefixes)
5812
5810
  };
5813
- var Zero = Num.Zero;
5814
- var One = Num.One;
5811
+ const Zero = Num.Zero;
5812
+ const One = Num.One;
5815
5813
 
5816
5814
  /* eslint-disable */
5817
5815
 
5818
5816
  // Assumes that both expressions have already been parsed
5819
5817
  // TODO(alex): be able to pass a random() function to compare()
5820
- var compare = function compare(expr1, expr2, options) {
5818
+ const compare = function compare(expr1, expr2, options) {
5821
5819
  var defaults = {
5822
5820
  form: false,
5823
5821
  // Check that the two expressions have the same form