mathjs 14.9.1 → 15.1.0

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.
Files changed (146) hide show
  1. package/HISTORY.md +35 -0
  2. package/README.md +1 -1
  3. package/lib/browser/math.js +1 -1
  4. package/lib/browser/math.js.LICENSE.txt +2 -2
  5. package/lib/browser/math.js.map +1 -1
  6. package/lib/cjs/core/config.js +5 -1
  7. package/lib/cjs/core/function/config.js +4 -0
  8. package/lib/cjs/entry/dependenciesAny/dependenciesBernoulli.generated.js +25 -0
  9. package/lib/cjs/entry/dependenciesAny/dependenciesConstantNode.generated.js +2 -0
  10. package/lib/cjs/entry/dependenciesAny/dependenciesEqual.generated.js +0 -2
  11. package/lib/cjs/entry/dependenciesAny/dependenciesIsBounded.generated.js +17 -0
  12. package/lib/cjs/entry/dependenciesAny/dependenciesIsFinite.generated.js +21 -0
  13. package/lib/cjs/entry/dependenciesAny/dependenciesIsInteger.generated.js +2 -0
  14. package/lib/cjs/entry/dependenciesAny/dependenciesSimplifyConstant.generated.js +2 -0
  15. package/lib/cjs/entry/dependenciesAny/dependenciesSize.generated.js +0 -2
  16. package/lib/cjs/entry/dependenciesAny/dependenciesUnitClass.generated.js +0 -2
  17. package/lib/cjs/entry/dependenciesAny/dependenciesZeta.generated.js +2 -0
  18. package/lib/cjs/entry/dependenciesAny.generated.js +21 -0
  19. package/lib/cjs/entry/dependenciesNumber/dependenciesBernoulli.generated.js +21 -0
  20. package/lib/cjs/entry/dependenciesNumber/dependenciesConstantNode.generated.js +2 -0
  21. package/lib/cjs/entry/dependenciesNumber/dependenciesIsBounded.generated.js +17 -0
  22. package/lib/cjs/entry/dependenciesNumber/dependenciesIsFinite.generated.js +21 -0
  23. package/lib/cjs/entry/dependenciesNumber/dependenciesSimplifyConstant.generated.js +2 -0
  24. package/lib/cjs/entry/dependenciesNumber/dependenciesSize.generated.js +0 -2
  25. package/lib/cjs/entry/dependenciesNumber/dependenciesZeta.generated.js +2 -0
  26. package/lib/cjs/entry/dependenciesNumber.generated.js +21 -0
  27. package/lib/cjs/entry/impureFunctionsAny.generated.js +223 -218
  28. package/lib/cjs/entry/impureFunctionsNumber.generated.js +82 -77
  29. package/lib/cjs/entry/pureFunctionsAny.generated.js +717 -702
  30. package/lib/cjs/entry/pureFunctionsNumber.generated.js +155 -142
  31. package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +6 -0
  32. package/lib/cjs/expression/embeddedDocs/function/combinatorics/stirlingS2.js +2 -2
  33. package/lib/cjs/expression/embeddedDocs/function/probability/bernoulli.js +14 -0
  34. package/lib/cjs/expression/embeddedDocs/function/utils/isBounded.js +14 -0
  35. package/lib/cjs/expression/embeddedDocs/function/utils/isFinite.js +14 -0
  36. package/lib/cjs/expression/embeddedDocs/function/utils/isNaN.js +1 -1
  37. package/lib/cjs/expression/embeddedDocs/function/utils/isNumeric.js +1 -1
  38. package/lib/cjs/expression/node/AccessorNode.js +36 -7
  39. package/lib/cjs/expression/node/ConstantNode.js +4 -4
  40. package/lib/cjs/expression/node/FunctionNode.js +20 -5
  41. package/lib/cjs/expression/node/IndexNode.js +1 -1
  42. package/lib/cjs/expression/parse.js +74 -46
  43. package/lib/cjs/factoriesAny.js +21 -0
  44. package/lib/cjs/factoriesNumber.js +23 -2
  45. package/lib/cjs/function/algebra/simplifyConstant.js +3 -2
  46. package/lib/cjs/function/algebra/sylvester.js +6 -5
  47. package/lib/cjs/function/arithmetic/nthRoots.js +5 -1
  48. package/lib/cjs/function/logical/nullish.js +2 -2
  49. package/lib/cjs/function/matrix/column.js +2 -1
  50. package/lib/cjs/function/matrix/dot.js +4 -9
  51. package/lib/cjs/function/matrix/flatten.js +6 -3
  52. package/lib/cjs/function/matrix/kron.js +31 -30
  53. package/lib/cjs/function/matrix/row.js +2 -1
  54. package/lib/cjs/function/matrix/size.js +11 -17
  55. package/lib/cjs/function/matrix/subset.js +21 -11
  56. package/lib/cjs/function/probability/bernoulli.js +108 -0
  57. package/lib/cjs/function/relational/equal.js +2 -3
  58. package/lib/cjs/function/special/zeta.js +3 -2
  59. package/lib/cjs/function/utils/isBounded.js +54 -0
  60. package/lib/cjs/function/utils/isFinite.js +50 -0
  61. package/lib/cjs/function/utils/isInteger.js +7 -15
  62. package/lib/cjs/function/utils/isNaN.js +1 -1
  63. package/lib/cjs/function/utils/isNumeric.js +1 -1
  64. package/lib/cjs/header.js +2 -2
  65. package/lib/cjs/json/replacer.js +1 -1
  66. package/lib/cjs/plain/number/probability.js +2 -2
  67. package/lib/cjs/plain/number/trigonometry.js +1 -1
  68. package/lib/cjs/type/fraction/function/fraction.js +1 -1
  69. package/lib/cjs/type/matrix/DenseMatrix.js +52 -41
  70. package/lib/cjs/type/matrix/MatrixIndex.js +19 -20
  71. package/lib/cjs/type/matrix/SparseMatrix.js +37 -11
  72. package/lib/cjs/type/unit/Unit.js +12 -8
  73. package/lib/cjs/utils/number.js +7 -7
  74. package/lib/cjs/utils/optimizeCallback.js +13 -1
  75. package/lib/cjs/version.js +1 -1
  76. package/lib/esm/core/config.js +5 -1
  77. package/lib/esm/core/function/config.js +4 -0
  78. package/lib/esm/entry/dependenciesAny/dependenciesBernoulli.generated.js +18 -0
  79. package/lib/esm/entry/dependenciesAny/dependenciesConstantNode.generated.js +2 -0
  80. package/lib/esm/entry/dependenciesAny/dependenciesEqual.generated.js +0 -2
  81. package/lib/esm/entry/dependenciesAny/dependenciesIsBounded.generated.js +10 -0
  82. package/lib/esm/entry/dependenciesAny/dependenciesIsFinite.generated.js +14 -0
  83. package/lib/esm/entry/dependenciesAny/dependenciesIsInteger.generated.js +2 -0
  84. package/lib/esm/entry/dependenciesAny/dependenciesSimplifyConstant.generated.js +2 -0
  85. package/lib/esm/entry/dependenciesAny/dependenciesSize.generated.js +0 -2
  86. package/lib/esm/entry/dependenciesAny/dependenciesUnitClass.generated.js +0 -2
  87. package/lib/esm/entry/dependenciesAny/dependenciesZeta.generated.js +2 -0
  88. package/lib/esm/entry/dependenciesAny.generated.js +3 -0
  89. package/lib/esm/entry/dependenciesNumber/dependenciesBernoulli.generated.js +14 -0
  90. package/lib/esm/entry/dependenciesNumber/dependenciesConstantNode.generated.js +2 -0
  91. package/lib/esm/entry/dependenciesNumber/dependenciesIsBounded.generated.js +10 -0
  92. package/lib/esm/entry/dependenciesNumber/dependenciesIsFinite.generated.js +14 -0
  93. package/lib/esm/entry/dependenciesNumber/dependenciesSimplifyConstant.generated.js +2 -0
  94. package/lib/esm/entry/dependenciesNumber/dependenciesSize.generated.js +0 -2
  95. package/lib/esm/entry/dependenciesNumber/dependenciesZeta.generated.js +2 -0
  96. package/lib/esm/entry/dependenciesNumber.generated.js +3 -0
  97. package/lib/esm/entry/impureFunctionsAny.generated.js +225 -220
  98. package/lib/esm/entry/impureFunctionsNumber.generated.js +84 -79
  99. package/lib/esm/entry/pureFunctionsAny.generated.js +714 -699
  100. package/lib/esm/entry/pureFunctionsNumber.generated.js +154 -141
  101. package/lib/esm/expression/embeddedDocs/embeddedDocs.js +6 -0
  102. package/lib/esm/expression/embeddedDocs/function/combinatorics/stirlingS2.js +2 -2
  103. package/lib/esm/expression/embeddedDocs/function/probability/bernoulli.js +8 -0
  104. package/lib/esm/expression/embeddedDocs/function/utils/isBounded.js +8 -0
  105. package/lib/esm/expression/embeddedDocs/function/utils/isFinite.js +8 -0
  106. package/lib/esm/expression/embeddedDocs/function/utils/isNaN.js +1 -1
  107. package/lib/esm/expression/embeddedDocs/function/utils/isNumeric.js +1 -1
  108. package/lib/esm/expression/node/AccessorNode.js +36 -7
  109. package/lib/esm/expression/node/ConstantNode.js +4 -4
  110. package/lib/esm/expression/node/FunctionNode.js +20 -5
  111. package/lib/esm/expression/node/IndexNode.js +1 -1
  112. package/lib/esm/expression/parse.js +74 -46
  113. package/lib/esm/factoriesAny.js +3 -0
  114. package/lib/esm/factoriesNumber.js +3 -0
  115. package/lib/esm/function/algebra/simplifyConstant.js +3 -2
  116. package/lib/esm/function/algebra/sylvester.js +6 -5
  117. package/lib/esm/function/arithmetic/nthRoots.js +5 -1
  118. package/lib/esm/function/logical/nullish.js +2 -2
  119. package/lib/esm/function/matrix/column.js +2 -1
  120. package/lib/esm/function/matrix/dot.js +4 -9
  121. package/lib/esm/function/matrix/flatten.js +6 -3
  122. package/lib/esm/function/matrix/kron.js +31 -30
  123. package/lib/esm/function/matrix/row.js +2 -1
  124. package/lib/esm/function/matrix/size.js +11 -17
  125. package/lib/esm/function/matrix/subset.js +21 -11
  126. package/lib/esm/function/probability/bernoulli.js +102 -0
  127. package/lib/esm/function/relational/equal.js +2 -3
  128. package/lib/esm/function/special/zeta.js +3 -2
  129. package/lib/esm/function/utils/isBounded.js +48 -0
  130. package/lib/esm/function/utils/isFinite.js +44 -0
  131. package/lib/esm/function/utils/isInteger.js +7 -15
  132. package/lib/esm/function/utils/isNaN.js +1 -1
  133. package/lib/esm/function/utils/isNumeric.js +1 -1
  134. package/lib/esm/json/replacer.js +1 -1
  135. package/lib/esm/plain/number/probability.js +2 -2
  136. package/lib/esm/plain/number/trigonometry.js +1 -1
  137. package/lib/esm/type/fraction/function/fraction.js +1 -1
  138. package/lib/esm/type/matrix/DenseMatrix.js +52 -41
  139. package/lib/esm/type/matrix/MatrixIndex.js +20 -21
  140. package/lib/esm/type/matrix/SparseMatrix.js +37 -11
  141. package/lib/esm/type/unit/Unit.js +12 -8
  142. package/lib/esm/utils/number.js +7 -7
  143. package/lib/esm/utils/optimizeCallback.js +13 -1
  144. package/lib/esm/version.js +1 -1
  145. package/package.json +8 -8
  146. package/types/index.d.ts +535 -223
@@ -38,8 +38,13 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
38
38
  * @param {Node} object The object from which to retrieve
39
39
  * a property or subset.
40
40
  * @param {IndexNode} index IndexNode containing ranges
41
+ * @param {boolean} [optionalChaining=false]
42
+ * Optional property, if the accessor was written as optional-chaining
43
+ * using `a?.b`, or `a?.["b"] with bracket notation.
44
+ * Forces evaluate to undefined if the given object is undefined or null.
41
45
  */
42
46
  constructor(object, index) {
47
+ let optionalChaining = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
43
48
  super();
44
49
  if (!(0, _is.isNode)(object)) {
45
50
  throw new TypeError('Node expected for parameter "object"');
@@ -49,6 +54,7 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
49
54
  }
50
55
  this.object = object;
51
56
  this.index = index;
57
+ this.optionalChaining = optionalChaining;
52
58
  }
53
59
 
54
60
  // readonly property name
@@ -82,15 +88,36 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
82
88
  _compile(math, argNames) {
83
89
  const evalObject = this.object._compile(math, argNames);
84
90
  const evalIndex = this.index._compile(math, argNames);
91
+ const optionalChaining = this.optionalChaining;
92
+ const prevOptionalChaining = (0, _is.isAccessorNode)(this.object) && this.object.optionalChaining;
85
93
  if (this.index.isObjectProperty()) {
86
94
  const prop = this.index.getObjectProperty();
87
95
  return function evalAccessorNode(scope, args, context) {
96
+ const ctx = context || {};
97
+ const object = evalObject(scope, args, ctx);
98
+ if (optionalChaining && object == null) {
99
+ ctx.optionalShortCircuit = true;
100
+ return undefined;
101
+ }
102
+ if (prevOptionalChaining && ctx !== null && ctx !== void 0 && ctx.optionalShortCircuit) {
103
+ return undefined;
104
+ }
105
+
88
106
  // get a property from an object evaluated using the scope.
89
- return (0, _customs.getSafeProperty)(evalObject(scope, args, context), prop);
107
+ return (0, _customs.getSafeProperty)(object, prop);
90
108
  };
91
109
  } else {
92
110
  return function evalAccessorNode(scope, args, context) {
93
- const object = evalObject(scope, args, context);
111
+ const ctx = context || {};
112
+ const object = evalObject(scope, args, ctx);
113
+ if (optionalChaining && object == null) {
114
+ ctx.optionalShortCircuit = true;
115
+ return undefined;
116
+ }
117
+ if (prevOptionalChaining && ctx !== null && ctx !== void 0 && ctx.optionalShortCircuit) {
118
+ return undefined;
119
+ }
120
+
94
121
  // we pass just object here instead of context:
95
122
  const index = evalIndex(scope, args, object);
96
123
  return access(object, index);
@@ -114,7 +141,7 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
114
141
  * @returns {AccessorNode} Returns a transformed copy of the node
115
142
  */
116
143
  map(callback) {
117
- return new AccessorNode(this._ifNode(callback(this.object, 'object', this)), this._ifNode(callback(this.index, 'index', this)));
144
+ return new AccessorNode(this._ifNode(callback(this.object, 'object', this)), this._ifNode(callback(this.index, 'index', this)), this.optionalChaining);
118
145
  }
119
146
 
120
147
  /**
@@ -122,7 +149,7 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
122
149
  * @return {AccessorNode}
123
150
  */
124
151
  clone() {
125
- return new AccessorNode(this.object, this.index);
152
+ return new AccessorNode(this.object, this.index, this.optionalChaining);
126
153
  }
127
154
 
128
155
  /**
@@ -135,7 +162,8 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
135
162
  if (needParenthesis(this.object)) {
136
163
  object = '(' + object + ')';
137
164
  }
138
- return object + this.index.toString(options);
165
+ const optionalChaining = this.optionalChaining ? this.index.dotNotation ? '?' : '?.' : '';
166
+ return object + optionalChaining + this.index.toString(options);
139
167
  }
140
168
 
141
169
  /**
@@ -172,7 +200,8 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
172
200
  return {
173
201
  mathjs: name,
174
202
  object: this.object,
175
- index: this.index
203
+ index: this.index,
204
+ optionalChaining: this.optionalChaining
176
205
  };
177
206
  }
178
207
 
@@ -185,7 +214,7 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
185
214
  * @returns {AccessorNode}
186
215
  */
187
216
  static fromJSON(json) {
188
- return new AccessorNode(json.object, json.index);
217
+ return new AccessorNode(json.object, json.index, json.optionalChaining);
189
218
  }
190
219
  }
191
220
  (0, _defineProperty2.default)(AccessorNode, "name", name);
@@ -11,10 +11,11 @@ var _is = require("../../utils/is.js");
11
11
  var _latex = require("../../utils/latex.js");
12
12
  var _factory = require("../../utils/factory.js");
13
13
  const name = 'ConstantNode';
14
- const dependencies = ['Node'];
14
+ const dependencies = ['Node', 'isBounded'];
15
15
  const createConstantNode = exports.createConstantNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
16
16
  let {
17
- Node
17
+ Node,
18
+ isBounded
18
19
  } = _ref;
19
20
  class ConstantNode extends Node {
20
21
  /**
@@ -157,8 +158,7 @@ const createConstantNode = exports.createConstantNode = /* #__PURE__ */(0, _fact
157
158
  case 'number':
158
159
  case 'BigNumber':
159
160
  {
160
- const finite = type === 'BigNumber' ? this.value.isFinite() : isFinite(this.value);
161
- if (!finite) {
161
+ if (!isBounded(this.value)) {
162
162
  return this.value.valueOf() < 0 ? '-\\infty' : '\\infty';
163
163
  }
164
164
  const index = value.toLowerCase().indexOf('e');
@@ -107,7 +107,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
107
107
  * the arguments, typically a SymbolNode or AccessorNode
108
108
  * @param {./Node[]} args
109
109
  */
110
- constructor(fn, args) {
110
+ constructor(fn, args, optional) {
111
111
  super();
112
112
  if (typeof fn === 'string') {
113
113
  fn = new SymbolNode(fn);
@@ -118,8 +118,13 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
118
118
  if (!Array.isArray(args) || !args.every(_is.isNode)) {
119
119
  throw new TypeError('Array containing Nodes expected for parameter "args"');
120
120
  }
121
+ const optionalType = typeof optional;
122
+ if (!(optionalType === 'undefined' || optionalType === 'boolean')) {
123
+ throw new TypeError('optional flag, if specified, must be boolean');
124
+ }
121
125
  this.fn = fn;
122
126
  this.args = args || [];
127
+ this.optional = !!optional;
123
128
  }
124
129
 
125
130
  // readonly property name
@@ -149,6 +154,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
149
154
  _compile(math, argNames) {
150
155
  // compile arguments
151
156
  const evalArgs = this.args.map(arg => arg._compile(math, argNames));
157
+ const fromOptionalChaining = this.optional || (0, _is.isAccessorNode)(this.fn) && this.fn.optionalChaining;
152
158
  if ((0, _is.isSymbolNode)(this.fn)) {
153
159
  const name = this.fn.name;
154
160
  if (!argNames[name]) {
@@ -162,10 +168,8 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
162
168
  value = scope.get(name);
163
169
  } else if (name in math) {
164
170
  value = (0, _customs.getSafeProperty)(math, name);
165
- } else {
166
- return FunctionNode.onUndefinedFunction(name);
167
- }
168
- if (typeof value === 'function') {
171
+ } else if (fromOptionalChaining) value = undefined;else return FunctionNode.onUndefinedFunction(name);
172
+ if (typeof value === 'function' || fromOptionalChaining && value === undefined) {
169
173
  return value;
170
174
  }
171
175
  throw new TypeError(`'${name}' is not a function; its value is:\n ${strin(value)}`);
@@ -192,17 +196,20 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
192
196
  case 0:
193
197
  return function evalFunctionNode(scope, args, context) {
194
198
  const fn = resolveFn(scope);
199
+ if (fromOptionalChaining && fn === undefined) return undefined;
195
200
  return fn();
196
201
  };
197
202
  case 1:
198
203
  return function evalFunctionNode(scope, args, context) {
199
204
  const fn = resolveFn(scope);
205
+ if (fromOptionalChaining && fn === undefined) return undefined;
200
206
  const evalArg0 = evalArgs[0];
201
207
  return fn(evalArg0(scope, args, context));
202
208
  };
203
209
  case 2:
204
210
  return function evalFunctionNode(scope, args, context) {
205
211
  const fn = resolveFn(scope);
212
+ if (fromOptionalChaining && fn === undefined) return undefined;
206
213
  const evalArg0 = evalArgs[0];
207
214
  const evalArg1 = evalArgs[1];
208
215
  return fn(evalArg0(scope, args, context), evalArg1(scope, args, context));
@@ -210,6 +217,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
210
217
  default:
211
218
  return function evalFunctionNode(scope, args, context) {
212
219
  const fn = resolveFn(scope);
220
+ if (fromOptionalChaining && fn === undefined) return undefined;
213
221
  const values = evalArgs.map(evalArg => evalArg(scope, args, context));
214
222
  return fn(...values);
215
223
  };
@@ -220,6 +228,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
220
228
  const rawArgs = this.args;
221
229
  return function evalFunctionNode(scope, args, context) {
222
230
  const fn = (0, _customs.getSafeProperty)(args, name);
231
+ if (fromOptionalChaining && fn === undefined) return undefined;
223
232
  if (typeof fn !== 'function') {
224
233
  throw new TypeError(`Argument '${name}' was not a function; received: ${strin(fn)}`);
225
234
  }
@@ -241,6 +250,11 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
241
250
  const rawArgs = this.args;
242
251
  return function evalFunctionNode(scope, args, context) {
243
252
  const object = evalObject(scope, args, context);
253
+
254
+ // Optional chaining: if the base object is nullish, short-circuit to undefined
255
+ if (fromOptionalChaining && (object == null || object[prop] === undefined)) {
256
+ return undefined;
257
+ }
244
258
  const fn = (0, _customs.getSafeMethod)(object, prop);
245
259
  if (fn !== null && fn !== void 0 && fn.rawArgs) {
246
260
  // "Raw" evaluation
@@ -260,6 +274,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
260
274
  const rawArgs = this.args;
261
275
  return function evalFunctionNode(scope, args, context) {
262
276
  const fn = evalFn(scope, args, context);
277
+ if (fromOptionalChaining && fn === undefined) return undefined;
263
278
  if (typeof fn !== 'function') {
264
279
  throw new TypeError(`Expression '${fnExpr}' did not evaluate to a function; value is:` + `\n ${strin(fn)}`);
265
280
  }
@@ -86,7 +86,7 @@ const createIndexNode = exports.createIndexNode = /* #__PURE__ */(0, _factory.fa
86
86
  if (!(0, _is.isMatrix)(context) && !(0, _is.isArray)(context) && !(0, _is.isString)(context)) {
87
87
  throw new TypeError('Cannot resolve "end": ' + 'context must be a Matrix, Array, or string but is ' + (0, _is.typeOf)(context));
88
88
  }
89
- const s = size(context).valueOf();
89
+ const s = size(context);
90
90
  const childArgs = Object.create(args);
91
91
  childArgs.end = s[i];
92
92
  return _evalDimension(scope, childArgs, context);
@@ -136,6 +136,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
136
136
  '=': true,
137
137
  ':': true,
138
138
  '?': true,
139
+ '?.': true,
139
140
  '??': true,
140
141
  '==': true,
141
142
  '!=': true,
@@ -302,7 +303,9 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
302
303
  }
303
304
 
304
305
  // check for delimiters consisting of 2 characters
305
- if (c2.length === 2 && DELIMITERS[c2]) {
306
+ // Special case: the check for '?.' is to prevent a case like 'a?.3:.7' from being interpreted as optional chaining
307
+ // TODO: refactor the tokenization into some better way to deal with cases like 'a?.3:.7', see https://github.com/josdejong/mathjs/pull/3584
308
+ if (c2.length === 2 && DELIMITERS[c2] && (c2 !== '?.' || !parse.isDigit(state.expression.charAt(state.index + 2)))) {
306
309
  state.tokenType = TOKENTYPE.DELIMITER;
307
310
  state.token = c2;
308
311
  next(state);
@@ -329,7 +332,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
329
332
  next(state);
330
333
  state.token += currentCharacter(state);
331
334
  next(state);
332
- while (parse.isHexDigit(currentCharacter(state))) {
335
+ while (parse.isAlpha(currentCharacter(state), prevCharacter(state), nextCharacter(state)) || parse.isDigit(currentCharacter(state))) {
333
336
  state.token += currentCharacter(state);
334
337
  next(state);
335
338
  }
@@ -338,7 +341,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
338
341
  state.token += '.';
339
342
  next(state);
340
343
  // get the digits after the radix
341
- while (parse.isHexDigit(currentCharacter(state))) {
344
+ while (parse.isAlpha(currentCharacter(state), prevCharacter(state), nextCharacter(state)) || parse.isDigit(currentCharacter(state))) {
342
345
  state.token += currentCharacter(state);
343
346
  next(state);
344
347
  }
@@ -544,15 +547,6 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
544
547
  return c >= '0' && c <= '9';
545
548
  };
546
549
 
547
- /**
548
- * checks if the given char c is a hex digit
549
- * @param {string} c a string with one character
550
- * @return {boolean}
551
- */
552
- parse.isHexDigit = function isHexDigit(c) {
553
- return c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';
554
- };
555
-
556
550
  /**
557
551
  * Start of the parse levels below, in order of precedence
558
552
  * @return {Node} node
@@ -656,6 +650,9 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
656
650
  return new AssignmentNode(new SymbolNode(name), value);
657
651
  } else if ((0, _is.isAccessorNode)(node)) {
658
652
  // parse a matrix subset assignment like 'A[1,2] = 4'
653
+ if (node.optionalChaining) {
654
+ throw createSyntaxError(state, 'Cannot assign to optional chain');
655
+ }
659
656
  getTokenSkipNewline(state);
660
657
  value = parseAssignment(state);
661
658
  return new AssignmentNode(node.object, node.index, value);
@@ -941,7 +938,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
941
938
  */
942
939
  function parseAddSubtract(state) {
943
940
  let node, name, fn, params;
944
- node = parseMultiplyDivideModulusPercentage(state);
941
+ node = parseMultiplyDivideModulus(state);
945
942
  const operators = {
946
943
  '+': 'add',
947
944
  '-': 'subtract'
@@ -950,7 +947,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
950
947
  name = state.token;
951
948
  fn = operators[name];
952
949
  getTokenSkipNewline(state);
953
- const rightNode = parseMultiplyDivideModulusPercentage(state);
950
+ const rightNode = parseMultiplyDivideModulus(state);
954
951
  if (rightNode.isPercentage) {
955
952
  params = [node, new OperatorNode('*', 'multiply', [node, rightNode])];
956
953
  } else {
@@ -962,11 +959,11 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
962
959
  }
963
960
 
964
961
  /**
965
- * multiply, divide, modulus, percentage
962
+ * multiply, divide, modulus
966
963
  * @return {Node} node
967
964
  * @private
968
965
  */
969
- function parseMultiplyDivideModulusPercentage(state) {
966
+ function parseMultiplyDivideModulus(state) {
970
967
  let node, last, name, fn;
971
968
  node = parseImplicitMultiplication(state);
972
969
  last = node;
@@ -984,23 +981,8 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
984
981
  name = state.token;
985
982
  fn = operators[name];
986
983
  getTokenSkipNewline(state);
987
- if (name === '%' && state.tokenType === TOKENTYPE.DELIMITER && state.token !== '(') {
988
- // If the expression contains only %, then treat that as /100
989
- if (state.token !== '' && operators[state.token]) {
990
- const left = new OperatorNode('/', 'divide', [node, new ConstantNode(100)], false, true);
991
- name = state.token;
992
- fn = operators[name];
993
- getTokenSkipNewline(state);
994
- last = parseImplicitMultiplication(state);
995
- node = new OperatorNode(name, fn, [left, last]);
996
- } else {
997
- node = new OperatorNode('/', 'divide', [node, new ConstantNode(100)], false, true);
998
- }
999
- // return node
1000
- } else {
1001
- last = parseImplicitMultiplication(state);
1002
- node = new OperatorNode(name, fn, [node, last]);
1003
- }
984
+ last = parseImplicitMultiplication(state);
985
+ node = new OperatorNode(name, fn, [node, last]);
1004
986
  } else {
1005
987
  break;
1006
988
  }
@@ -1043,7 +1025,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1043
1025
  * @private
1044
1026
  */
1045
1027
  function parseRule2(state) {
1046
- let node = parseUnary(state);
1028
+ let node = parseUnaryPercentage(state);
1047
1029
  let last = node;
1048
1030
  const tokenStates = [];
1049
1031
  while (true) {
@@ -1065,7 +1047,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1065
1047
  // Rewind once and build the "number / number" node; the symbol will be consumed later
1066
1048
  (0, _extends2.default)(state, tokenStates.pop());
1067
1049
  tokenStates.pop();
1068
- last = parseUnary(state);
1050
+ last = parseUnaryPercentage(state);
1069
1051
  node = new OperatorNode('/', 'divide', [node, last]);
1070
1052
  } else {
1071
1053
  // Not a match, so rewind
@@ -1085,6 +1067,34 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1085
1067
  return node;
1086
1068
  }
1087
1069
 
1070
+ /**
1071
+ * Unary percentage operator (treated as `value / 100`)
1072
+ * @return {Node} node
1073
+ * @private
1074
+ */
1075
+ function parseUnaryPercentage(state) {
1076
+ let node = parseUnary(state);
1077
+ if (state.token === '%') {
1078
+ const previousState = (0, _extends2.default)({}, state);
1079
+ getTokenSkipNewline(state);
1080
+ // We need to decide if this is a unary percentage % or binary modulo %
1081
+ // So we attempt to parse a unary expression at this point.
1082
+ // If it fails, then the only possibility is that this is a unary percentage.
1083
+ // If it succeeds, then we presume that this must be binary modulo, since the
1084
+ // only things that parseUnary can handle are _higher_ precedence than unary %.
1085
+ try {
1086
+ parseUnary(state);
1087
+ // Not sure if we could somehow use the result of that parseUnary? Without
1088
+ // further analysis/testing, safer just to discard and let the parse proceed
1089
+ (0, _extends2.default)(state, previousState);
1090
+ } catch (_unused) {
1091
+ // Not seeing a term at this point, so was a unary %
1092
+ node = new OperatorNode('/', 'divide', [node, new ConstantNode(100)], false, true);
1093
+ }
1094
+ }
1095
+ return node;
1096
+ }
1097
+
1088
1098
  /**
1089
1099
  * Unary plus and minus, and logical and bitwise not
1090
1100
  * @return {Node} node
@@ -1257,9 +1267,9 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1257
1267
 
1258
1268
  /**
1259
1269
  * parse accessors:
1260
- * - function invocation in round brackets (...), for example sqrt(2)
1261
- * - index enclosed in square brackets [...], for example A[2,3]
1262
- * - dot notation for properties, like foo.bar
1270
+ * - function invocation in round brackets (...), for example sqrt(2) or sqrt?.(2) with optional chaining
1271
+ * - index enclosed in square brackets [...], for example A[2,3] or A?.[2,3] with optional chaining
1272
+ * - dot notation for properties, like foo.bar or foo?.bar with optional chaining
1263
1273
  * @param {Object} state
1264
1274
  * @param {Node} node Node on which to apply the parameters. If there
1265
1275
  * are no parameters in the expression, the node
@@ -1271,12 +1281,27 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1271
1281
  */
1272
1282
  function parseAccessors(state, node, types) {
1273
1283
  let params;
1274
- while ((state.token === '(' || state.token === '[' || state.token === '.') && (!types || types.includes(state.token))) {
1284
+
1285
+ // Iterate and handle chained accessors, including repeated optional chaining
1286
+ while (true) {
1275
1287
  // eslint-disable-line no-unmodified-loop-condition
1288
+ // Track whether an optional chaining operator precedes the next accessor
1289
+ let optional = false;
1290
+
1291
+ // Consume an optional chaining operator if present
1292
+ if (state.token === '?.') {
1293
+ optional = true;
1294
+ // consume the '?.' token
1295
+ getToken(state);
1296
+ }
1297
+ const hasNextAccessor = (state.token === '(' || state.token === '[' || state.token === '.') && (!types || types.includes(state.token));
1298
+ if (!(optional || hasNextAccessor)) {
1299
+ break;
1300
+ }
1276
1301
  params = [];
1277
1302
  if (state.token === '(') {
1278
- if ((0, _is.isSymbolNode)(node) || (0, _is.isAccessorNode)(node)) {
1279
- // function invocation like fn(2, 3) or obj.fn(2, 3)
1303
+ if (optional || (0, _is.isSymbolNode)(node) || (0, _is.isAccessorNode)(node)) {
1304
+ // function invocation: fn(2, 3) or obj.fn(2, 3) or (anything)?.(2, 3)
1280
1305
  openParams(state);
1281
1306
  getToken(state);
1282
1307
  if (state.token !== ')') {
@@ -1294,7 +1319,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1294
1319
  }
1295
1320
  closeParams(state);
1296
1321
  getToken(state);
1297
- node = new FunctionNode(node, params);
1322
+ node = new FunctionNode(node, params, optional);
1298
1323
  } else {
1299
1324
  // implicit multiplication like (2+3)(4+5) or sqrt(2)(1+2)
1300
1325
  // don't parse it here but let it be handled by parseImplicitMultiplication
@@ -1320,18 +1345,21 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1320
1345
  }
1321
1346
  closeParams(state);
1322
1347
  getToken(state);
1323
- node = new AccessorNode(node, new IndexNode(params));
1348
+ node = new AccessorNode(node, new IndexNode(params), optional);
1324
1349
  } else {
1325
1350
  // dot notation like variable.prop
1326
- getToken(state);
1351
+ // consume the `.` (if it was ?., already consumed):
1352
+ if (!optional) getToken(state);
1327
1353
  const isPropertyName = state.tokenType === TOKENTYPE.SYMBOL || state.tokenType === TOKENTYPE.DELIMITER && state.token in NAMED_DELIMITERS;
1328
1354
  if (!isPropertyName) {
1329
- throw createSyntaxError(state, 'Property name expected after dot');
1355
+ let message = 'Property name expected after ';
1356
+ message += optional ? 'optional chain' : 'dot';
1357
+ throw createSyntaxError(state, message);
1330
1358
  }
1331
1359
  params.push(new ConstantNode(state.token));
1332
1360
  getToken(state);
1333
1361
  const dotNotation = true;
1334
- node = new AccessorNode(node, new IndexNode(params, dotNotation));
1362
+ node = new AccessorNode(node, new IndexNode(params, dotNotation), optional);
1335
1363
  }
1336
1364
  }
1337
1365
  return node;
@@ -153,6 +153,12 @@ Object.defineProperty(exports, "createBellNumbers", {
153
153
  return _bellNumbers.createBellNumbers;
154
154
  }
155
155
  });
156
+ Object.defineProperty(exports, "createBernoulli", {
157
+ enumerable: true,
158
+ get: function () {
159
+ return _bernoulli.createBernoulli;
160
+ }
161
+ });
156
162
  Object.defineProperty(exports, "createBigNumberClass", {
157
163
  enumerable: true,
158
164
  get: function () {
@@ -939,6 +945,18 @@ Object.defineProperty(exports, "createInvmod", {
939
945
  return _invmod.createInvmod;
940
946
  }
941
947
  });
948
+ Object.defineProperty(exports, "createIsBounded", {
949
+ enumerable: true,
950
+ get: function () {
951
+ return _isBounded.createIsBounded;
952
+ }
953
+ });
954
+ Object.defineProperty(exports, "createIsFinite", {
955
+ enumerable: true,
956
+ get: function () {
957
+ return _isFinite.createIsFinite;
958
+ }
959
+ });
942
960
  Object.defineProperty(exports, "createIsInteger", {
943
961
  enumerable: true,
944
962
  get: function () {
@@ -2215,6 +2233,8 @@ var _hasNumericValue = require("./function/utils/hasNumericValue.js");
2215
2233
  var _isPositive = require("./function/utils/isPositive.js");
2216
2234
  var _isZero = require("./function/utils/isZero.js");
2217
2235
  var _isNaN = require("./function/utils/isNaN.js");
2236
+ var _isBounded = require("./function/utils/isBounded.js");
2237
+ var _isFinite = require("./function/utils/isFinite.js");
2218
2238
  var _typeOf = require("./function/utils/typeOf.js");
2219
2239
  var _equalScalar = require("./function/relational/equalScalar.js");
2220
2240
  var _SparseMatrix = require("./type/matrix/SparseMatrix.js");
@@ -2443,6 +2463,7 @@ var _variance = require("./function/statistics/variance.js");
2443
2463
  var _quantileSeq = require("./function/statistics/quantileSeq.js");
2444
2464
  var _std = require("./function/statistics/std.js");
2445
2465
  var _corr = require("./function/statistics/corr.js");
2466
+ var _bernoulli = require("./function/probability/bernoulli.js");
2446
2467
  var _combinations = require("./function/probability/combinations.js");
2447
2468
  var _combinationsWithRep = require("./function/probability/combinationsWithRep.js");
2448
2469
  var _gamma = require("./function/probability/gamma.js");
@@ -31,6 +31,12 @@ Object.defineProperty(exports, "createBellNumbers", {
31
31
  return _bellNumbers.createBellNumbers;
32
32
  }
33
33
  });
34
+ Object.defineProperty(exports, "createBernoulli", {
35
+ enumerable: true,
36
+ get: function () {
37
+ return _bernoulli.createBernoulli;
38
+ }
39
+ });
34
40
  Object.defineProperty(exports, "createBigint", {
35
41
  enumerable: true,
36
42
  get: function () {
@@ -303,6 +309,18 @@ Object.defineProperty(exports, "createInfinity", {
303
309
  return _constants.createInfinity;
304
310
  }
305
311
  });
312
+ Object.defineProperty(exports, "createIsBounded", {
313
+ enumerable: true,
314
+ get: function () {
315
+ return _isBounded.createIsBounded;
316
+ }
317
+ });
318
+ Object.defineProperty(exports, "createIsFinite", {
319
+ enumerable: true,
320
+ get: function () {
321
+ return _isFinite.createIsFinite;
322
+ }
323
+ });
306
324
  exports.createIsNegative = exports.createIsNaN = exports.createIsInteger = void 0;
307
325
  Object.defineProperty(exports, "createIsNumeric", {
308
326
  enumerable: true,
@@ -354,8 +372,7 @@ Object.defineProperty(exports, "createLargerEq", {
354
372
  return _largerEq.createLargerEqNumber;
355
373
  }
356
374
  });
357
- exports.createLeftShift = exports.createLcm = void 0;
358
- exports.createLog2 = exports.createLog1p = exports.createLog10 = exports.createLog = exports.createLgamma = void 0;
375
+ exports.createLog2 = exports.createLog1p = exports.createLog10 = exports.createLog = exports.createLgamma = exports.createLeftShift = exports.createLcm = void 0;
359
376
  Object.defineProperty(exports, "createMad", {
360
377
  enumerable: true,
361
378
  get: function () {
@@ -853,6 +870,7 @@ var _map = require("./function/matrix/map.js");
853
870
  var _range = require("./function/matrix/range.js");
854
871
  var _size = require("./function/matrix/size.js");
855
872
  var _partitionSelect = require("./function/matrix/partitionSelect.js");
873
+ var _bernoulli = require("./function/probability/bernoulli.js");
856
874
  var _combinationsWithRep = require("./function/probability/combinationsWithRep.js");
857
875
  var _factorial = require("./function/probability/factorial.js");
858
876
  var _multinomial = require("./function/probability/multinomial.js");
@@ -904,6 +922,8 @@ var _varianceTransform = require("./expression/transform/variance.transform.js")
904
922
  var _clone = require("./function/utils/clone.js");
905
923
  var _isNumeric = require("./function/utils/isNumeric.js");
906
924
  var _hasNumericValue = require("./function/utils/hasNumericValue.js");
925
+ var _isBounded = require("./function/utils/isBounded.js");
926
+ var _isFinite = require("./function/utils/isFinite.js");
907
927
  var _typeOf = require("./function/utils/typeOf.js");
908
928
  var _isPrime = require("./function/utils/isPrime.js");
909
929
  var _numeric = require("./function/utils/numeric.js");
@@ -986,6 +1006,7 @@ const createSubset = exports.createSubset = /* #__PURE__ */(0, _factory.factory)
986
1006
  // TODO: create range implementation for range?
987
1007
 
988
1008
  // probability
1009
+
989
1010
  const createCombinations = exports.createCombinations = createNumberFactory('combinations', _index.combinationsNumber);
990
1011
  const createGamma = exports.createGamma = createNumberFactory('gamma', _index.gammaNumber);
991
1012
  const createLgamma = exports.createLgamma = createNumberFactory('lgamma', _index.lgammaNumber);
@@ -10,13 +10,14 @@ var _number = require("../../utils/number.js");
10
10
  var _util = require("./simplify/util.js");
11
11
  var _noop = require("../../utils/noop.js");
12
12
  const name = 'simplifyConstant';
13
- const dependencies = ['typed', 'config', 'mathWithTransform', 'matrix', '?fraction', '?bignumber', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'SymbolNode'];
13
+ const dependencies = ['typed', 'config', 'mathWithTransform', 'matrix', 'isBounded', '?fraction', '?bignumber', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'SymbolNode'];
14
14
  const createSimplifyConstant = exports.createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
15
15
  let {
16
16
  typed,
17
17
  config,
18
18
  mathWithTransform,
19
19
  matrix,
20
+ isBounded,
20
21
  fraction,
21
22
  bignumber,
22
23
  AccessorNode,
@@ -134,7 +135,7 @@ const createSimplifyConstant = exports.createSimplifyConstant = /* #__PURE__ */(
134
135
  // and when both numerator and denominator are small enough
135
136
  function _exactFraction(n, options) {
136
137
  const exactFractions = options && options.exactFractions !== false;
137
- if (exactFractions && isFinite(n) && fraction) {
138
+ if (exactFractions && isBounded(n) && fraction) {
138
139
  const f = fraction(n);
139
140
  const fractionsLimit = options && typeof options.fractionsLimit === 'number' ? options.fractionsLimit : Infinity; // no limit by default
140
141
 
@@ -23,7 +23,8 @@ const createSylvester = exports.createSylvester = /* #__PURE__ */(0, _factory.fa
23
23
  subtract,
24
24
  identity,
25
25
  lusolve,
26
- abs
26
+ abs,
27
+ config
27
28
  } = _ref;
28
29
  /**
29
30
  *
@@ -94,7 +95,7 @@ const createSylvester = exports.createSylvester = /* #__PURE__ */(0, _factory.fa
94
95
  const vc = (a, b) => concat(a, b, 0);
95
96
  for (let k = 0; k < n; k++) {
96
97
  if (k < n - 1 && abs(subset(G, index(k + 1, k))) > 1e-5) {
97
- let RHS = vc(subset(D, index(all, k)), subset(D, index(all, k + 1)));
98
+ let RHS = vc(subset(D, index(all, [k])), subset(D, index(all, [k + 1])));
98
99
  for (let j = 0; j < k; j++) {
99
100
  RHS = add(RHS, vc(multiply(y[j], subset(G, index(j, k))), multiply(y[j], subset(G, index(j, k + 1)))));
100
101
  }
@@ -104,11 +105,11 @@ const createSylvester = exports.createSylvester = /* #__PURE__ */(0, _factory.fa
104
105
  const gmm = multiply(identity(m), multiply(-1, subset(G, index(k + 1, k + 1))));
105
106
  const LHS = vc(hc(add(F, gkk), gmk), hc(gkm, add(F, gmm)));
106
107
  const yAux = lusolve(LHS, RHS);
107
- y[k] = yAux.subset(index(range(0, m), 0));
108
- y[k + 1] = yAux.subset(index(range(m, 2 * m), 0));
108
+ y[k] = yAux.subset(index(range(0, m), [0]));
109
+ y[k + 1] = yAux.subset(index(range(m, 2 * m), [0]));
109
110
  k++;
110
111
  } else {
111
- let RHS = subset(D, index(all, k));
112
+ let RHS = subset(D, index(all, [k]));
112
113
  for (let j = 0; j < k; j++) {
113
114
  RHS = add(RHS, multiply(y[j], subset(G, index(j, k))));
114
115
  }